2 * Copyright (c) 1985, 1989 Regents of the University of California.
5 * Redistribution and use in source and binary forms are permitted
6 * provided that the above copyright notice and this paragraph are
7 * duplicated in all such forms and that any documentation,
8 * advertising materials, and other materials related to such
9 * distribution and use acknowledge that the software was developed
10 * by the University of California, Berkeley. The name of the
11 * University may not be used to endorse or promote products derived
12 * from this software without specific prior written permission.
13 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
19 static char sccsid
[] = "@(#)cmds.c 5.18 (Berkeley) 4/20/89";
23 * FTP User Program -- Command Routines.
25 //#include <sys/param.h>
26 //#include <sys/wait.h>
29 #include <sys/socket.h>
31 #include <netinet/in.h>
45 #include "pathnames.h"
46 #include "prototypes.h"
50 static const char *remglob(const char *argv
[], int doswitch
);
52 extern off_t restart_point
;
53 extern char reply_string
[];
57 const char *dotrans(const char *name
);
58 const char *domap(const char *name
);
61 extern char *hostname
;
64 * Connect to peer server and
65 * auto-login, if possible.
67 void setpeer(int argc
, const char *argv
[])
72 printf("Already connected to %s, use close first.\n",
74 (void) fflush(stdout
);
79 (void) strcat(line
, " ");
81 (void) fflush(stdout
);
82 (void) gets(&line
[strlen(line
)]);
88 printf("usage: %s host-name [port]\n", argv
[0]);
89 (void) fflush(stdout
);
94 portnum
= atoi(argv
[2]);
96 printf("%s: bad port number-- %s\n", argv
[1], argv
[2]);
97 printf ("usage: %s host-name [port]\n", argv
[0]);
98 (void) fflush(stdout
);
102 portnum
= htons(portnum
);
104 host
= hookup(argv
[1], portnum
);
106 #if defined(unix) && NBBY == 8
111 (void) login(argv
[1]);
113 #if defined(unix) && NBBY == 8
115 * this ifdef is to keep someone form "porting" this to an incompatible
116 * system and not checking this out. This way they have to think about it.
122 if (command("SYST") == COMPLETE
&& overbose
) {
123 register char *cp
, c
;
124 cp
= index(reply_string
+4, ' ');
126 cp
= index(reply_string
+4, '\r');
134 printf("Remote system type is %s.\n",
139 if (!strncmp(reply_string
, "215 UNIX Type: L8", 17)) {
141 /* allbinary = 1; this violates the RFC */
143 printf("Using %s mode to transfer files.\n",
145 } else if (overbose
&&
146 !strncmp(reply_string
, "215 TOPS20", 10)) {
148 "Remember to set tenex mode when transfering binary files from this machine.\n");
153 (void) fflush(stdout
);
162 { "ascii", "A", TYPE_A
, 0 },
163 { "binary", "I", TYPE_I
, 0 },
164 { "image", "I", TYPE_I
, 0 },
165 { "ebcdic", "E", TYPE_E
, 0 },
166 { "tenex", "L", TYPE_L
, bytename
},
173 void settype(int argc
, const char *argv
[])
175 register struct types
*p
;
181 printf("usage: %s [", argv
[0]);
183 for (p
= types
; p
->t_name
; p
++) {
184 printf("%s%s", sep
, p
->t_name
);
189 (void) fflush(stdout
);
194 printf("Using %s mode to transfer files.\n", typename
);
195 (void) fflush(stdout
);
199 for (p
= types
; p
->t_name
; p
++)
200 if (strcmp(argv
[1], p
->t_name
) == 0)
202 if (p
->t_name
== 0) {
203 printf("%s: unknown mode\n", argv
[1]);
204 (void) fflush(stdout
);
208 if ((p
->t_arg
!= NULL
) && (*(p
->t_arg
) != '\0'))
209 comret
= command ("TYPE %s %s", p
->t_mode
, p
->t_arg
);
211 comret
= command("TYPE %s", p
->t_mode
);
212 if (comret
== COMPLETE
) {
213 (void) strcpy(typename
, p
->t_name
);
218 const char *stype
[] = {
225 * Set binary transfer type.
228 void setbinary(int argc
, const char *argv
[])
235 * Set ascii transfer type.
238 void setascii(int argc
, const char *argv
[])
245 * Set tenex transfer type.
248 void settenex(int argc
, const char *argv
[])
255 * Set ebcdic transfer type.
265 * Set file transfer mode.
269 void fsetmode(int argc
, const char *argv
[])
272 printf("We only support %s mode, sorry.\n", modename
);
273 (void) fflush(stdout
);
279 * Set file transfer format.
282 void setform(int argc
, const char *argv
[])
285 printf("We only support %s format, sorry.\n", formname
);
286 (void) fflush(stdout
);
291 * Set file transfer structure.
294 void setstruct(int argc
, const char *argv
[])
297 printf("We only support %s structure, sorry.\n", structname
);
298 (void) fflush(stdout
);
303 * Send a single file.
305 void put(int argc
, const char *argv
[])
309 const char *oldargv1
, *oldargv2
;
317 (void) strcat(line
, " ");
318 printf("(local-file) ");
319 (void) fflush(stdout
);
320 (void) gets(&line
[strlen(line
)]);
327 printf("usage:%s local-file remote-file\n", argv
[0]);
328 (void) fflush(stdout
);
333 (void) strcat(line
, " ");
334 printf("(remote-file) ");
335 (void) fflush(stdout
);
336 (void) gets(&line
[strlen(line
)]);
345 if (!globulize(&argv
[1])) {
350 * If "globulize" modifies argv[1], and argv[2] is a copy of
351 * the old argv[1], make it a copy of the new argv[1].
353 if (argv
[1] != oldargv1
&& argv
[2] == oldargv1
) {
356 cmd
= (argv
[0][0] == 'a') ? "APPE" : ((sunique
) ? "STOU" : "STOR");
358 argv
[2] = dotrans(argv
[2]);
360 if (loc
&& mapflag
) {
361 argv
[2] = domap(argv
[2]);
363 sendrequest(cmd
, argv
[1], argv
[2],
364 argv
[1] != oldargv1
|| argv
[2] != oldargv2
);
368 * Send multiple files.
370 void mput(int argc
, const char *argv
[])
374 extern jmp_buf jabort
;
378 (void) strcat(line
, " ");
379 printf("(local-files) ");
380 (void) fflush(stdout
);
381 (void) gets(&line
[strlen(line
)]);
387 printf("usage:%s local-files\n", argv
[0]);
388 (void) fflush(stdout
);
394 // oldintr = signal(SIGINT, mabort);
395 (void) setjmp(jabort
);
398 char *tp2
, tmpbuf
[MAXPATHLEN
];
400 while ((cp
= remglob(argv
,0)) != NULL
) {
405 if (mflag
&& confirm(argv
[0], cp
)) {
408 while (*tp
&& !islower(*tp
)) {
414 while ((*tp2
= *tp
)) {
416 *tp2
= 'a' + *tp2
- 'A';
430 sendrequest((sunique
) ? "STOU" : "STOR",
431 cp
, tp
, cp
!= tp
|| !interactive
);
432 if (!mflag
&& fromatty
) {
433 ointer
= interactive
;
435 if (confirm("Continue with","mput")) {
438 interactive
= ointer
;
442 // (void) signal(SIGINT, oldintr);
446 for (i
= 1; i
< argc
; i
++) {
447 register char **cpp
, **gargs
;
450 if (mflag
&& confirm(argv
[0], argv
[i
])) {
451 tp
= (ntflag
) ? dotrans(argv
[i
]) : argv
[i
];
452 tp
= (mapflag
) ? domap(tp
) : tp
;
453 sendrequest((sunique
) ? "STOU" : "STOR",
454 argv
[i
], tp
, tp
!= argv
[i
] || !interactive
);
455 if (!mflag
&& fromatty
) {
456 ointer
= interactive
;
458 if (confirm("Continue with","mput")) {
461 interactive
= ointer
;
466 gargs
= glob(argv
[i
]);
467 if (globerr
!= NULL
) {
468 printf("%s\n", globerr
);
469 (void) fflush(stdout
);
476 for (cpp
= gargs
; cpp
&& *cpp
!= NULL
; cpp
++) {
477 if (mflag
&& confirm(argv
[0], *cpp
)) {
478 tp
= (ntflag
) ? dotrans(*cpp
) : *cpp
;
479 tp
= (mapflag
) ? domap(tp
) : tp
;
480 sendrequest((sunique
) ? "STOU" : "STOR",
481 *cpp
, tp
, *cpp
!= tp
|| !interactive
);
482 if (!mflag
&& fromatty
) {
483 ointer
= interactive
;
485 if (confirm("Continue with","mput")) {
488 interactive
= ointer
;
497 // (void) signal(SIGINT, oldintr);
501 void reget(int argc
, const char *argv
[])
503 (void) getit(argc
, argv
, 1, "r+w");
506 void get(int argc
, const char *argv
[])
508 (void) getit(argc
, argv
, 0, restart_point
? "r+w" : "w" );
514 int getit(int argc
, const char *argv
[], int restartit
, const char *mode
)
517 const char *oldargv1
, *oldargv2
;
525 (void) strcat(line
, " ");
526 printf("(remote-file) ");
527 (void) fflush(stdout
);
528 (void) gets(&line
[strlen(line
)]);
535 printf("usage: %s remote-file [ local-file ]\n", argv
[0]);
536 (void) fflush(stdout
);
541 (void) strcat(line
, " ");
542 printf("(local-file) ");
543 (void) fflush(stdout
);
544 (void) gets(&line
[strlen(line
)]);
553 if (!globulize(&argv
[2])) {
558 const char *tp
= argv
[1];
559 char *tp2
, tmpbuf
[MAXPATHLEN
];
561 while (*tp
&& !islower(*tp
)) {
567 while ((*tp2
= *tp
)) {
569 *tp2
= 'a' + *tp2
- 'A';
578 argv
[2] = dotrans(argv
[2]);
580 argv
[2] = domap(argv
[2]);
585 ret
= stat(argv
[2], &stbuf
);
586 if (restartit
== 1) {
591 restart_point
= stbuf
.st_size
;
599 if (command("MDTM %s", argv
[1]) == COMPLETE
) {
600 int yy
, mo
, day
, hour
, min
, sec
;
604 "%*s %04d%02d%02d%02d%02d%02d",
605 &yy
, &mo
, &day
, &hour
, &min
, &sec
);
606 tm
= gmtime(&stbuf
.st_mtime
);
608 if (tm
->tm_year
> yy
%100)
610 else if (tm
->tm_year
== yy
%100) {
613 } else if (tm
->tm_mon
== mo
) {
614 if (tm
->tm_mday
> day
)
616 } else if (tm
->tm_mday
== day
) {
617 if (tm
->tm_hour
> hour
)
619 } else if (tm
->tm_hour
== hour
) {
620 if (tm
->tm_min
> min
)
622 } else if (tm
->tm_min
== min
) {
623 if (tm
->tm_sec
> sec
)
627 printf("%s\n", reply_string
);
628 (void) fflush(stdout
);
636 recvrequest("RETR", argv
[2], argv
[1], mode
,
637 argv
[1] != oldargv1
|| argv
[2] != oldargv2
);
647 extern jmp_buf jabort
;
650 (void) fflush(stdout
);
651 if (mflag
&& fromatty
) {
652 ointer
= interactive
;
654 if (confirm("Continue with", mname
)) {
655 interactive
= ointer
;
658 interactive
= ointer
;
666 * Get multiple files.
668 void mget(int argc
, const char *argv
[])
671 char *tp2
, tmpbuf
[MAXPATHLEN
];
673 extern jmp_buf jabort
;
676 (void) strcat(line
, " ");
677 printf("(remote-files) ");
678 (void) fflush(stdout
);
679 (void) gets(&line
[strlen(line
)]);
685 printf("usage:%s remote-files\n", argv
[0]);
686 (void) fflush(stdout
);
692 // oldintr = signal(SIGINT,mabort);
693 (void) setjmp(jabort
);
694 while ((cp
= remglob(argv
,proxy
)) != NULL
) {
699 if (mflag
&& confirm(argv
[0], cp
)) {
702 while (*tp
&& !islower(*tp
)) {
708 while ((*tp2
= *tp
)) {
710 *tp2
= 'a' + *tp2
- 'A';
724 recvrequest("RETR", tp
, cp
, "w",
725 tp
!= cp
|| !interactive
);
726 if (!mflag
&& fromatty
) {
727 ointer
= interactive
;
729 if (confirm("Continue with","mget")) {
732 interactive
= ointer
;
736 // (void) signal(SIGINT,oldintr);
741 remglob(const char *argv
[], int doswitch
)
744 static char buf
[MAXPATHLEN
];
745 static FILE *ftemp
= NULL
;
746 static const char **args
;
747 int oldverbose
, oldhash
;
758 (void) fclose(ftemp
);
767 if ((cp
= *++args
) == NULL
)
772 (void) strcpy(temp
, _PATH_TMP
);
774 oldverbose
= verbose
, verbose
= 0;
775 oldhash
= hash
, hash
= 0;
779 for (mode
= "w"; *++argv
!= NULL
; mode
= "a")
780 recvrequest ("NLST", temp
, *argv
, mode
, 0);
784 verbose
= oldverbose
; hash
= oldhash
;
785 ftemp
= fopen(temp
, "r");
788 printf("can't find list of remote files, oops\n");
789 (void) fflush(stdout
);
793 if (fgets(buf
, sizeof (buf
), ftemp
) == NULL
) {
794 (void) fclose(ftemp
), ftemp
= NULL
;
797 if ((terminator
= index(buf
, '\n')) != NULL
)
805 return (bool ? "on" : "off");
812 void status(int argc
, const char *argv
[])
817 printf("Connected to %s.\n", hostname
);
819 printf("Not connected.\n");
823 printf("Connected for proxy commands to %s.\n", hostname
);
826 printf("No proxy connection.\n");
830 printf("Mode: %s; Type: %s; Form: %s; Structure: %s\n",
831 modename
, typename
, formname
, structname
);
832 printf("Verbose: %s; Bell: %s; Prompting: %s; Globbing: %s\n",
833 onoff(verbose
), onoff(bell
), onoff(interactive
),
835 printf("Store unique: %s; Receive unique: %s\n", onoff(sunique
),
837 printf("Case: %s; CR stripping: %s\n",onoff(mcase
),onoff(crflag
));
839 printf("Ntrans: (in) %s (out) %s\n", ntin
,ntout
);
842 printf("Ntrans: off\n");
845 printf("Nmap: (in) %s (out) %s\n", mapin
, mapout
);
848 printf("Nmap: off\n");
850 printf("Hash mark printing: %s; Use of PORT cmds: %s\n",
851 onoff(hash
), onoff(sendport
));
854 for (i
=0; i
<macnum
; i
++) {
855 printf("\t%s\n",macros
[i
].mac_name
);
858 (void) fflush(stdout
);
863 * Set beep on cmd completed mode.
866 void setbell(int argc
, const char *argv
[])
870 printf("Bell mode %s.\n", onoff(bell
));
871 (void) fflush(stdout
);
876 * Turn on packet tracing.
879 void settrace(int argc
, const char *argv
[])
883 printf("Packet tracing %s.\n", onoff(trace
));
884 (void) fflush(stdout
);
889 * Toggle hash mark printing during transfers.
892 void sethash(int argc
, const char *argv
[])
896 printf("Hash mark printing %s", onoff(hash
));
899 printf(" (%d bytes/hash mark)", 1024);
901 (void) fflush(stdout
);
905 * Turn on printing of server echo's.
908 void setverbose(int argc
, const char *argv
[])
912 printf("Verbose mode %s.\n", onoff(verbose
));
913 (void) fflush(stdout
);
918 * Toggle PORT cmd use before each data connection.
921 void setport(int argc
, const char *argv
[])
924 sendport
= !sendport
;
925 printf("Use of PORT cmds %s.\n", onoff(sendport
));
926 (void) fflush(stdout
);
931 * Turn on interactive prompting
932 * during mget, mput, and mdelete.
935 void setprompt(int argc
, const char *argv
[])
938 interactive
= !interactive
;
939 printf("Interactive mode %s.\n", onoff(interactive
));
940 (void) fflush(stdout
);
945 * Toggle metacharacter interpretation
946 * on local file names.
949 void setglob(int argc
, const char *argv
[])
953 printf("Globbing %s.\n", onoff(doglob
));
954 (void) fflush(stdout
);
959 * Set debugging mode on/off and/or
960 * set level of debugging.
963 void setdebug(int argc
, const char *argv
[])
970 printf("%s: bad debugging value.\n", argv
[1]);
971 (void) fflush(stdout
);
981 options
&= ~SO_DEBUG
;
982 printf("Debugging %s (debug=%d).\n", onoff(debug
), debug
);
983 (void) fflush(stdout
);
988 * Set current working directory
991 void cd(int argc
, const char *argv
[])
995 (void) strcat(line
, " ");
996 printf("(remote-directory) ");
997 (void) fflush(stdout
);
998 (void) gets(&line
[strlen(line
)]);
1004 printf("usage:%s remote-directory\n", argv
[0]);
1005 (void) fflush(stdout
);
1009 if (command("CWD %s", argv
[1]) == ERROR
&& code
== 500) {
1011 printf("CWD command not recognized, trying XCWD\n");
1012 (void) fflush(stdout
);
1014 (void) command("XCWD %s", argv
[1]);
1019 * Set current working directory
1022 void lcd(int argc
, const char *argv
[])
1024 char buf
[MAXPATHLEN
];
1027 argc
++, argv
[1] = home
;
1029 printf("usage:%s local-directory\n", argv
[0]);
1030 (void) fflush(stdout
);
1034 if (!globulize(&argv
[1])) {
1038 if (chdir(argv
[1]) < 0) {
1043 printf("Local directory now %s\n", getcwd(buf
,sizeof(buf
)));
1044 (void) fflush(stdout
);
1049 * Delete a single file.
1051 void delete(int argc
, const char *argv
[])
1055 (void) strcat(line
, " ");
1056 printf("(remote-file) ");
1057 (void) fflush(stdout
);
1058 (void) gets(&line
[strlen(line
)]);
1064 printf("usage:%s remote-file\n", argv
[0]);
1065 (void) fflush(stdout
);
1069 (void) command("DELE %s", argv
[1]);
1073 * Delete multiple files.
1075 void mdelete(int argc
, const char *argv
[])
1079 extern jmp_buf jabort
;
1082 (void) strcat(line
, " ");
1083 printf("(remote-files) ");
1084 (void) fflush(stdout
);
1085 (void) gets(&line
[strlen(line
)]);
1091 printf("usage:%s remote-files\n", argv
[0]);
1092 (void) fflush(stdout
);
1098 // oldintr = signal(SIGINT, mabort);
1099 (void) setjmp(jabort
);
1100 while ((cp
= remglob(argv
,0)) != NULL
) {
1105 if (mflag
&& confirm(argv
[0], cp
)) {
1106 (void) command("DELE %s", cp
);
1107 if (!mflag
&& fromatty
) {
1108 ointer
= interactive
;
1110 if (confirm("Continue with", "mdelete")) {
1113 interactive
= ointer
;
1117 // (void) signal(SIGINT, oldintr);
1122 * Rename a remote file.
1124 void renamefile(int argc
, const char *argv
[])
1128 (void) strcat(line
, " ");
1129 printf("(from-name) ");
1130 (void) fflush(stdout
);
1131 (void) gets(&line
[strlen(line
)]);
1138 printf("%s from-name to-name\n", argv
[0]);
1139 (void) fflush(stdout
);
1144 (void) strcat(line
, " ");
1145 printf("(to-name) ");
1146 (void) fflush(stdout
);
1147 (void) gets(&line
[strlen(line
)]);
1154 if (command("RNFR %s", argv
[1]) == CONTINUE
)
1155 (void) command("RNTO %s", argv
[2]);
1159 * Get a directory listing
1162 void ls(int argc
, const char *argv
[])
1167 argc
++, argv
[1] = NULL
;
1169 argc
++, argv
[2] = "-";
1171 printf("usage: %s remote-directory local-file\n", argv
[0]);
1172 (void) fflush(stdout
);
1176 cmd
= argv
[0][0] == 'n' ? "NLST" : "LIST";
1177 // cmd = argv[0][0] == 'n' ? "NLST -CF" : "NLST -CF";
1178 if (strcmp(argv
[2], "-") && !globulize(&argv
[2])) {
1182 if (strcmp(argv
[2], "-") && *argv
[2] != '|')
1183 if (!globulize(&argv
[2]) || !confirm("output to local-file:", argv
[2])) {
1187 recvrequest(cmd
, argv
[2], argv
[1], "w", 0);
1191 * Get a directory listing
1192 * of multiple remote files.
1194 void mls(int argc
, const char *argv
[])
1196 const char *cmd
, *dest
;
1199 extern jmp_buf jabort
;
1202 (void) strcat(line
, " ");
1203 printf("(remote-files) ");
1204 (void) fflush(stdout
);
1205 (void) gets(&line
[strlen(line
)]);
1211 (void) strcat(line
, " ");
1212 printf("(local-file) ");
1213 (void) fflush(stdout
);
1214 (void) gets(&line
[strlen(line
)]);
1220 printf("usage:%s remote-files local-file\n", argv
[0]);
1221 (void) fflush(stdout
);
1225 dest
= argv
[argc
- 1];
1226 argv
[argc
- 1] = NULL
;
1227 if (strcmp(dest
, "-") && *dest
!= '|')
1228 if (!globulize(&dest
) || !confirm("output to local-file:", dest
)) {
1232 cmd
= argv
[0][1] == 'l' ? "NLST" : "LIST";
1235 // oldintr = signal(SIGINT, mabort);
1236 (void) setjmp(jabort
);
1237 for (i
= 1; mflag
&& i
< argc
-1; ++i
) {
1238 *mode
= (i
== 1) ? 'w' : 'a';
1239 recvrequest(cmd
, dest
, argv
[i
], mode
, 0);
1240 if (!mflag
&& fromatty
) {
1241 ointer
= interactive
;
1243 if (confirm("Continue with", argv
[0])) {
1246 interactive
= ointer
;
1249 // (void) signal(SIGINT, oldintr);
1257 void shell(int argc
, const char *argv
[])
1261 sig_t (*old1
)(), (*old2
)();
1262 char shellnam
[40], *shell
, *namep
;
1265 old1
= signal (SIGINT
, SIG_IGN
);
1266 old2
= signal (SIGQUIT
, SIG_IGN
);
1267 if ((pid
= fork()) == 0) {
1268 for (pid
= 3; pid
< 20; pid
++)
1270 (void) signal(SIGINT
, SIG_DFL
);
1271 (void) signal(SIGQUIT
, SIG_DFL
);
1272 shell
= getenv("SHELL");
1274 shell
= _PATH_BSHELL
;
1275 namep
= rindex(shell
,'/');
1278 (void) strcpy(shellnam
,"-");
1279 (void) strcat(shellnam
, ++namep
);
1280 if (strcmp(namep
, "sh") != 0)
1283 printf ("%s\n", shell
);
1284 (void) fflush (stdout
);
1287 execl(shell
,shellnam
,"-c",altarg
,(char *)0);
1290 execl(shell
,shellnam
,(char *)0);
1297 while (wait(&status
) != pid
)
1299 (void) signal(SIGINT
, old1
);
1300 (void) signal(SIGQUIT
, old2
);
1302 perror("Try again later");
1311 char ShellCmd
[MAX_PATH
];
1312 char CmdLine
[MAX_PATH
];
1314 PROCESS_INFORMATION ProcessInformation
;
1316 STARTUPINFO StartupInfo
;
1317 char ShellName
[] = "COMSPEC";
1320 NumBytes
= GetEnvironmentVariable( ShellName
, ShellCmd
, MAX_PATH
);
1328 strcpy( CmdLine
, ShellCmd
);
1332 strncat(CmdLine
, " /C", MAX_PATH
);
1335 for (i
=1; i
<argc
; i
++)
1337 strncat(CmdLine
, " ", MAX_PATH
);
1338 strncat(CmdLine
, argv
[i
], MAX_PATH
);
1341 StartupInfo
.cb
= sizeof( StartupInfo
);
1342 StartupInfo
.lpReserved
= NULL
;
1343 StartupInfo
.lpDesktop
= NULL
;
1344 StartupInfo
.lpTitle
= NULL
;
1345 StartupInfo
.dwX
= 0;
1346 StartupInfo
.dwY
= 0;
1347 StartupInfo
.dwXSize
= 0;
1348 StartupInfo
.dwYSize
= 0;
1349 StartupInfo
.dwFlags
= 0;
1350 StartupInfo
.wShowWindow
= 0;
1351 StartupInfo
.cbReserved2
= 0;
1352 StartupInfo
.lpReserved2
= NULL
;
1354 Result
= CreateProcess( AppName
, // cmd name
1355 CmdLine
, // cmd line arguments
1357 NULL
, // security attributes
1358 FALSE
, // inherit flags
1359 0, // Creation flags
1360 NULL
, // Environment
1361 NULL
, // Current directory
1362 &StartupInfo
, // Startup info structure
1363 &ProcessInformation
); // processInfo structure
1367 WaitForSingleObject( ProcessInformation
.hProcess
, 0xffffffff);
1369 CloseHandle( ProcessInformation
.hProcess
);
1374 * Send new user information (re-login)
1376 void user(int argc
, const char *argv
[])
1378 char acct
[80], *getpass();
1382 (void) strcat(line
, " ");
1383 printf("(username) ");
1384 (void) fflush(stdout
);
1385 (void) gets(&line
[strlen(line
)]);
1391 printf("usage: %s username [password] [account]\n", argv
[0]);
1392 (void) fflush(stdout
);
1396 n
= command("USER %s", argv
[1]);
1397 if (n
== CONTINUE
) {
1399 argv
[2] = getpass("Password: "), argc
++;
1400 n
= command("PASS %s", argv
[2]);
1402 if (n
== CONTINUE
) {
1404 printf("Account: "); (void) fflush(stdout
);
1405 (void) fflush(stdout
);
1406 (void) fgets(acct
, sizeof(acct
) - 1, stdin
);
1407 acct
[strlen(acct
) - 1] = '\0';
1408 argv
[3] = acct
; argc
++;
1410 n
= command("ACCT %s", argv
[3]);
1413 if (n
!= COMPLETE
) {
1414 fprintf(stdout
, "Login failed.\n");
1415 (void) fflush(stdout
);
1418 if (!aflag
&& argc
== 4) {
1419 (void) command("ACCT %s", argv
[3]);
1424 * Print working directory.
1427 void pwd(int argc
, const char *argv
[])
1429 int oldverbose
= verbose
;
1432 * If we aren't verbose, this doesn't do anything!
1435 if (command("PWD") == ERROR
&& code
== 500) {
1436 printf("PWD command not recognized, trying XPWD\n");
1437 (void) fflush(stdout
);
1438 (void) command("XPWD");
1440 verbose
= oldverbose
;
1446 void makedir(int argc
, const char *argv
[])
1450 (void) strcat(line
, " ");
1451 printf("(directory-name) ");
1452 (void) fflush(stdout
);
1453 (void) gets(&line
[strlen(line
)]);
1459 printf("usage: %s directory-name\n", argv
[0]);
1460 (void) fflush(stdout
);
1464 if (command("MKD %s", argv
[1]) == ERROR
&& code
== 500) {
1466 printf("MKD command not recognized, trying XMKD\n");
1467 (void) fflush(stdout
);
1469 (void) command("XMKD %s", argv
[1]);
1474 * Remove a directory.
1476 void removedir(int argc
, const char *argv
[])
1480 (void) strcat(line
, " ");
1481 printf("(directory-name) ");
1482 (void) fflush(stdout
);
1483 (void) gets(&line
[strlen(line
)]);
1489 printf("usage: %s directory-name\n", argv
[0]);
1490 (void) fflush(stdout
);
1494 if (command("RMD %s", argv
[1]) == ERROR
&& code
== 500) {
1496 printf("RMD command not recognized, trying XRMD\n");
1497 (void) fflush(stdout
);
1499 (void) command("XRMD %s", argv
[1]);
1504 * Send a line, verbatim, to the remote machine.
1506 void quote(int argc
, const char *argv
[])
1512 (void) strcat(line
, " ");
1513 printf("(command line to send) ");
1514 (void) fflush(stdout
);
1515 (void) gets(&line
[strlen(line
)]);
1521 printf("usage: %s line-to-send\n", argv
[0]);
1522 (void) fflush(stdout
);
1526 (void) strcpy(buf
, argv
[1]);
1527 for (i
= 2; i
< argc
; i
++) {
1528 (void) strcat(buf
, " ");
1529 (void) strcat(buf
, argv
[i
]);
1531 if (command(buf
) == PRELIM
) {
1532 while (getreply(0) == PRELIM
);
1537 * Send a SITE command to the remote machine. The line
1538 * is sent almost verbatim to the remote machine, the
1539 * first argument is changed to SITE.
1541 void site(int argc
, const char *argv
[])
1547 (void) strcat(line
, " ");
1548 printf("(arguments to SITE command) ");
1549 (void) fflush(stdout
);
1550 (void) gets(&line
[strlen(line
)]);
1556 printf("usage: %s line-to-send\n", argv
[0]);
1557 (void) fflush(stdout
);
1561 (void) strcpy(buf
, "SITE ");
1562 (void) strcat(buf
, argv
[1]);
1563 for (i
= 2; i
< argc
; i
++) {
1564 (void) strcat(buf
, " ");
1565 (void) strcat(buf
, argv
[i
]);
1567 if (command(buf
) == PRELIM
) {
1568 while (getreply(0) == PRELIM
);
1572 void do_chmod(int argc
, const char *argv
[])
1575 printf("usage: %s mode file-name\n", argv
[0]);
1576 (void) fflush(stdout
);
1581 (void) strcat(line
, " ");
1582 printf("(mode and file-name) ");
1583 (void) fflush(stdout
);
1584 (void) gets(&line
[strlen(line
)]);
1590 printf("usage: %s mode file-name\n", argv
[0]);
1591 (void) fflush(stdout
);
1595 (void)command("SITE CHMOD %s %s", argv
[1], argv
[2]);
1598 void do_umask(int argc
, const char *argv
[])
1600 int oldverbose
= verbose
;
1603 (void) command(argc
== 1 ? "SITE UMASK" : "SITE UMASK %s", argv
[1]);
1604 verbose
= oldverbose
;
1607 void idle(int argc
, const char *argv
[])
1609 int oldverbose
= verbose
;
1612 (void) command(argc
== 1 ? "SITE IDLE" : "SITE IDLE %s", argv
[1]);
1613 verbose
= oldverbose
;
1617 * Ask the other side for help.
1619 void rmthelp(int argc
, const char *argv
[])
1621 int oldverbose
= verbose
;
1624 (void) command(argc
== 1 ? "HELP" : "HELP %s", argv
[1]);
1625 verbose
= oldverbose
;
1629 * Terminate session and exit.
1632 void quit(int argc
, const char *argv
[])
1635 disconnect(0, NULL
);
1638 disconnect(0, NULL
);
1644 * Terminate session, but don't exit.
1646 void disconnect(int argc
, const char *argv
[])
1653 (void) command("QUIT");
1662 int confirm(const char *cmd
, const char *file
)
1668 printf("%s %s? ", cmd
, file
);
1669 (void) fflush(stdout
);
1671 return (*line
!= 'n' && *line
!= 'N');
1675 static void fatal(const char *msg
)
1678 fprintf(stderr
, "ftp: %s\n", msg
);
1684 * Glob a local file name specification with
1685 * the expectation of a single return value.
1686 * Can't control multiple values being expanded
1687 * from the expression, we return only the first.
1689 int globulize(const char **cpp
)
1695 globbed
= glob(*cpp
);
1696 if (globerr
!= NULL
) {
1697 printf("%s: %s\n", *cpp
, globerr
);
1698 (void) fflush(stdout
);
1701 free((char *)globbed
);
1707 /* don't waste too much memory */
1710 free((char *)globbed
);
1716 void account(int argc
, const char *argv
[])
1718 char acct
[50], *getpass(), *ap
;
1723 (void) strncpy(acct
,*argv
,49);
1728 (void) strncat(acct
,*argv
, 49-strlen(acct
));
1733 ap
= getpass("Account:");
1735 (void) command("ACCT %s", ap
);
1756 longjmp(abortprox
,1);
1760 void doproxy(int argc
, const char *argv
[])
1762 register struct cmd
*c
;
1763 struct cmd
*getcmd();
1764 // extern struct cmd cmdtab[];
1765 extern jmp_buf abortprox
;
1768 (void) strcat(line
, " ");
1769 printf("(command) ");
1770 (void) fflush(stdout
);
1771 (void) gets(&line
[strlen(line
)]);
1777 printf("usage:%s command\n", argv
[0]);
1778 (void) fflush(stdout
);
1782 c
= getcmd(argv
[1]);
1783 if (c
== (struct cmd
*) -1) {
1784 printf("?Ambiguous command\n");
1785 (void) fflush(stdout
);
1790 printf("?Invalid command\n");
1791 (void) fflush(stdout
);
1796 printf("?Invalid proxy command\n");
1797 (void) fflush(stdout
);
1801 if (setjmp(abortprox
)) {
1805 // oldintr = signal(SIGINT, proxabort);
1807 if (c
->c_conn
&& !connected
) {
1808 printf("Not connected\n");
1809 (void) fflush(stdout
);
1811 // (void) signal(SIGINT, oldintr);
1815 (*c
->c_handler
)(argc
-1, argv
+1);
1823 // (void) signal(SIGINT, oldintr);
1826 void setcase(int argc
, const char *argv
[])
1829 printf("Case mapping %s.\n", onoff(mcase
));
1830 (void) fflush(stdout
);
1834 void setcr(int argc
, const char *argv
[])
1837 printf("Carriage Return stripping %s.\n", onoff(crflag
));
1838 (void) fflush(stdout
);
1842 void setntrans(int argc
, const char *argv
[])
1846 printf("Ntrans off.\n");
1847 (void) fflush(stdout
);
1853 (void) strncpy(ntin
, argv
[1], 16);
1859 (void) strncpy(ntout
, argv
[2], 16);
1864 dotrans(const char *name
)
1866 static char new[MAXPATHLEN
];
1869 register int i
, ostop
, found
;
1871 for (ostop
= 0; *(ntout
+ ostop
) && ostop
< 16; ostop
++);
1872 for (cp1
= name
; *cp1
; cp1
++) {
1874 for (i
= 0; *(ntin
+ i
) && i
< 16; i
++) {
1875 if (*cp1
== *(ntin
+ i
)) {
1878 *cp2
++ = *(ntout
+ i
);
1891 void setpassive(int argc
, const char *argv
[])
1893 passivemode
= !passivemode
;
1894 printf("Passive mode %s.\n", onoff(passivemode
));
1895 (void) fflush(stdout
);
1899 void setnmap(int argc
, const char *argv
[])
1905 printf("Nmap off.\n");
1906 (void) fflush(stdout
);
1911 (void) strcat(line
, " ");
1912 printf("(mapout) ");
1913 (void) fflush(stdout
);
1914 (void) gets(&line
[strlen(line
)]);
1920 printf("Usage: %s [mapin mapout]\n",argv
[0]);
1921 (void) fflush(stdout
);
1927 cp
= index(altarg
, ' ');
1929 while(*++cp
== ' ');
1931 cp
= index(altarg
, ' ');
1934 (void) strncpy(mapin
, altarg
, MAXPATHLEN
- 1);
1935 while (*++cp
== ' ');
1936 (void) strncpy(mapout
, cp
, MAXPATHLEN
- 1);
1940 domap(const char *name
)
1942 static char new[MAXPATHLEN
];
1943 const char *cp1
= name
;
1944 char *cpn
, *cp2
= mapin
;
1945 const char *tp
[9], *te
[9];
1946 int i
, toks
[9], toknum
= 0, match
= 1;
1948 for (i
=0; i
< 9; ++i
) {
1951 while (match
&& *cp1
&& *cp2
) {
1954 if (*++cp2
!= *cp1
) {
1959 if (*(cp2
+1) >= '1' && (*cp2
+1) <= '9') {
1960 if (*cp1
!= *(++cp2
+1)) {
1961 toks
[toknum
= *cp2
- '1']++;
1963 while (*++cp1
&& *(cp2
+1)
1977 if (match
&& *cp1
) {
1980 if (match
&& *cp2
) {
1984 if (!match
&& *cp1
) /* last token mismatch */
2002 if (*++cp2
== '$' && isdigit(*(cp2
+1))) {
2003 if (*++cp2
== '0') {
2004 const char *cp3
= name
;
2011 else if (toks
[toknum
= *cp2
- '1']) {
2012 const char *cp3
= tp
[toknum
];
2014 while (cp3
!= te
[toknum
]) {
2021 while (*cp2
&& *cp2
!= ',' &&
2026 else if (*cp2
== '$' &&
2027 isdigit(*(cp2
+1))) {
2028 if (*++cp2
== '0') {
2029 const char *cp3
= name
;
2035 else if (toks
[toknum
=
2037 const char *cp3
=tp
[toknum
];
2050 printf("nmap: unbalanced brackets\n");
2051 (void) fflush(stdout
);
2058 while (*++cp2
&& *cp2
!= ']') {
2059 if (*cp2
== '\\' && *(cp2
+ 1)) {
2064 printf("nmap: unbalanced brackets\n");
2065 (void) fflush(stdout
);
2081 if (isdigit(*(cp2
+ 1))) {
2082 if (*++cp2
== '0') {
2083 const char *cp3
= name
;
2089 else if (toks
[toknum
= *cp2
- '1']) {
2090 const char *cp3
= tp
[toknum
];
2092 while (cp3
!= te
[toknum
]) {
2098 /* intentional drop through */
2112 void setsunique(int argc
, const char *argv
[])
2115 printf("Store unique %s.\n", onoff(sunique
));
2116 (void) fflush(stdout
);
2120 void setrunique(int argc
, const char *argv
[])
2123 printf("Receive unique %s.\n", onoff(runique
));
2124 (void) fflush(stdout
);
2128 /* change directory to perent directory */
2129 void cdup(int argc
, const char *argv
[])
2131 if (command("CDUP") == ERROR
&& code
== 500) {
2133 printf("CDUP command not recognized, trying XCUP\n");
2134 (void) fflush(stdout
);
2136 (void) command("XCUP");
2140 /* restart transfer at specific point */
2141 void restart(int argc
, const char *argv
[])
2144 printf("restart: offset not specified\n");
2146 restart_point
= atol(argv
[1]);
2147 printf("restarting at %ld. %s\n", restart_point
,
2148 "execute get, put or append to initiate transfer");
2150 (void) fflush(stdout
);
2153 /* show remote system type */
2154 void syst(int argc
, const char *argv
[])
2156 (void) command("SYST");
2159 void macdef(int argc
, const char *argv
[])
2165 printf("Limit of 16 macros have already been defined\n");
2166 (void) fflush(stdout
);
2171 (void) strcat(line
, " ");
2172 printf("(macro name) ");
2173 (void) fflush(stdout
);
2174 (void) gets(&line
[strlen(line
)]);
2180 printf("Usage: %s macro_name\n",argv
[0]);
2181 (void) fflush(stdout
);
2186 printf("Enter macro line by line, terminating it with a null line\n");
2187 (void) fflush(stdout
);
2189 (void) strncpy(macros
[macnum
].mac_name
, argv
[1], 8);
2191 macros
[macnum
].mac_start
= macbuf
;
2194 macros
[macnum
].mac_start
= macros
[macnum
- 1].mac_end
+ 1;
2196 tmp
= macros
[macnum
].mac_start
;
2197 while (tmp
!= macbuf
+4096) {
2198 if ((c
= getchar()) == EOF
) {
2199 printf("macdef:end of file encountered\n");
2200 (void) fflush(stdout
);
2204 if ((*tmp
= c
) == '\n') {
2205 if (tmp
== macros
[macnum
].mac_start
) {
2206 macros
[macnum
++].mac_end
= tmp
;
2210 if (*(tmp
-1) == '\0') {
2211 macros
[macnum
++].mac_end
= tmp
- 1;
2220 while ((c
= getchar()) != '\n' && c
!= EOF
)
2222 if (c
== EOF
|| getchar() == '\n') {
2223 printf("Macro not defined - 4k buffer exceeded\n");
2224 (void) fflush(stdout
);
2232 * get size of file on remote machine
2234 void sizecmd(int argc
, const char *argv
[])
2238 (void) strcat(line
, " ");
2239 printf("(filename) ");
2240 (void) fflush(stdout
);
2241 (void) gets(&line
[strlen(line
)]);
2247 printf("usage:%s filename\n", argv
[0]);
2248 (void) fflush(stdout
);
2252 (void) command("SIZE %s", argv
[1]);
2256 * get last modification time of file on remote machine
2258 void modtime(int argc
, const char *argv
[])
2263 (void) strcat(line
, " ");
2264 printf("(filename) ");
2265 (void) fflush(stdout
);
2266 (void) gets(&line
[strlen(line
)]);
2272 printf("usage:%s filename\n", argv
[0]);
2273 (void) fflush(stdout
);
2280 if (command("MDTM %s", argv
[1]) == COMPLETE
) {
2281 int yy
, mo
, day
, hour
, min
, sec
;
2282 sscanf(reply_string
, "%*s %04d%02d%02d%02d%02d%02d", &yy
, &mo
,
2283 &day
, &hour
, &min
, &sec
);
2284 /* might want to print this in local time */
2285 printf("%s\t%02d/%02d/%04d %02d:%02d:%02d GMT\n", argv
[1],
2286 mo
, day
, yy
, hour
, min
, sec
);
2288 printf("%s\n", reply_string
);
2290 (void) fflush(stdout
);
2294 * show status on reomte machine
2296 void rmtstatus(int argc
, const char *argv
[])
2298 (void) command(argc
> 1 ? "STAT %s" : "STAT" , argv
[1]);
2302 * get file if modtime is more recent than current file
2304 void newer(int argc
, const char *argv
[])
2306 if (getit(argc
, argv
, -1, "w")) {
2307 printf("Local file \"%s\" is newer than remote file \"%s\"\n",
2309 (void) fflush(stdout
);