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 extern char *remglob();
51 extern char *getenv();
53 extern off_t restart_point
;
54 extern char reply_string
[];
58 const char *dotrans(), *domap();
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(argc
, argv
)
176 register struct types
*p
;
182 printf("usage: %s [", argv
[0]);
184 for (p
= types
; p
->t_name
; p
++) {
185 printf("%s%s", sep
, p
->t_name
);
190 (void) fflush(stdout
);
195 printf("Using %s mode to transfer files.\n", typename
);
196 (void) fflush(stdout
);
200 for (p
= types
; p
->t_name
; p
++)
201 if (strcmp(argv
[1], p
->t_name
) == 0)
203 if (p
->t_name
== 0) {
204 printf("%s: unknown mode\n", argv
[1]);
205 (void) fflush(stdout
);
209 if ((p
->t_arg
!= NULL
) && (*(p
->t_arg
) != '\0'))
210 comret
= command ("TYPE %s %s", p
->t_mode
, p
->t_arg
);
212 comret
= command("TYPE %s", p
->t_mode
);
213 if (comret
== COMPLETE
) {
214 (void) strcpy(typename
, p
->t_name
);
219 const char *stype
[] = {
226 * Set binary transfer type.
236 * Set ascii transfer type.
246 * Set tenex transfer type.
256 * Set ebcdic transfer type.
266 * Set file transfer mode.
270 void fsetmode(argc
, argv
)
274 printf("We only support %s mode, sorry.\n", modename
);
275 (void) fflush(stdout
);
281 * Set file transfer format.
284 void setform(argc
, argv
)
288 printf("We only support %s format, sorry.\n", formname
);
289 (void) fflush(stdout
);
294 * Set file transfer structure.
297 void setstruct(argc
, argv
)
301 printf("We only support %s structure, sorry.\n", structname
);
302 (void) fflush(stdout
);
307 * Send a single file.
315 const char *oldargv1
, *oldargv2
;
323 (void) strcat(line
, " ");
324 printf("(local-file) ");
325 (void) fflush(stdout
);
326 (void) gets(&line
[strlen(line
)]);
333 printf("usage:%s local-file remote-file\n", argv
[0]);
334 (void) fflush(stdout
);
339 (void) strcat(line
, " ");
340 printf("(remote-file) ");
341 (void) fflush(stdout
);
342 (void) gets(&line
[strlen(line
)]);
351 if (!globulize(&argv
[1])) {
356 * If "globulize" modifies argv[1], and argv[2] is a copy of
357 * the old argv[1], make it a copy of the new argv[1].
359 if (argv
[1] != oldargv1
&& argv
[2] == oldargv1
) {
362 cmd
= (argv
[0][0] == 'a') ? "APPE" : ((sunique
) ? "STOU" : "STOR");
364 argv
[2] = dotrans(argv
[2]);
366 if (loc
&& mapflag
) {
367 argv
[2] = domap(argv
[2]);
369 sendrequest(cmd
, argv
[1], argv
[2],
370 argv
[1] != oldargv1
|| argv
[2] != oldargv2
);
374 * Send multiple files.
376 void mput(argc
, argv
)
381 extern jmp_buf jabort
;
385 (void) strcat(line
, " ");
386 printf("(local-files) ");
387 (void) fflush(stdout
);
388 (void) gets(&line
[strlen(line
)]);
394 printf("usage:%s local-files\n", argv
[0]);
395 (void) fflush(stdout
);
401 // oldintr = signal(SIGINT, mabort);
402 (void) setjmp(jabort
);
404 char *cp
, *tp2
, tmpbuf
[MAXPATHLEN
];
406 while ((cp
= remglob(argv
,0)) != NULL
) {
411 if (mflag
&& confirm(argv
[0], cp
)) {
414 while (*tp
&& !islower(*tp
)) {
420 while ((*tp2
= *tp
)) {
422 *tp2
= 'a' + *tp2
- 'A';
436 sendrequest((sunique
) ? "STOU" : "STOR",
437 cp
, tp
, cp
!= tp
|| !interactive
);
438 if (!mflag
&& fromatty
) {
439 ointer
= interactive
;
441 if (confirm("Continue with","mput")) {
444 interactive
= ointer
;
448 // (void) signal(SIGINT, oldintr);
452 for (i
= 1; i
< argc
; i
++) {
453 register char **cpp
, **gargs
;
456 if (mflag
&& confirm(argv
[0], argv
[i
])) {
457 tp
= (ntflag
) ? dotrans(argv
[i
]) : argv
[i
];
458 tp
= (mapflag
) ? domap(tp
) : tp
;
459 sendrequest((sunique
) ? "STOU" : "STOR",
460 argv
[i
], tp
, tp
!= argv
[i
] || !interactive
);
461 if (!mflag
&& fromatty
) {
462 ointer
= interactive
;
464 if (confirm("Continue with","mput")) {
467 interactive
= ointer
;
472 gargs
= glob(argv
[i
]);
473 if (globerr
!= NULL
) {
474 printf("%s\n", globerr
);
475 (void) fflush(stdout
);
482 for (cpp
= gargs
; cpp
&& *cpp
!= NULL
; cpp
++) {
483 if (mflag
&& confirm(argv
[0], *cpp
)) {
484 tp
= (ntflag
) ? dotrans(*cpp
) : *cpp
;
485 tp
= (mapflag
) ? domap(tp
) : tp
;
486 sendrequest((sunique
) ? "STOU" : "STOR",
487 *cpp
, tp
, *cpp
!= tp
|| !interactive
);
488 if (!mflag
&& fromatty
) {
489 ointer
= interactive
;
491 if (confirm("Continue with","mput")) {
494 interactive
= ointer
;
503 // (void) signal(SIGINT, oldintr);
507 void reget(argc
, argv
)
510 (void) getit(argc
, argv
, 1, "r+w");
516 (void) getit(argc
, argv
, 0, restart_point
? "r+w" : "w" );
522 int getit(argc
, argv
, restartit
, mode
)
527 const char *oldargv1
, *oldargv2
;
535 (void) strcat(line
, " ");
536 printf("(remote-file) ");
537 (void) fflush(stdout
);
538 (void) gets(&line
[strlen(line
)]);
545 printf("usage: %s remote-file [ local-file ]\n", argv
[0]);
546 (void) fflush(stdout
);
551 (void) strcat(line
, " ");
552 printf("(local-file) ");
553 (void) fflush(stdout
);
554 (void) gets(&line
[strlen(line
)]);
563 if (!globulize(&argv
[2])) {
568 const char *tp
= argv
[1];
569 char *tp2
, tmpbuf
[MAXPATHLEN
];
571 while (*tp
&& !islower(*tp
)) {
577 while ((*tp2
= *tp
)) {
579 *tp2
= 'a' + *tp2
- 'A';
588 argv
[2] = dotrans(argv
[2]);
590 argv
[2] = domap(argv
[2]);
595 ret
= stat(argv
[2], &stbuf
);
596 if (restartit
== 1) {
601 restart_point
= stbuf
.st_size
;
609 if (command("MDTM %s", argv
[1]) == COMPLETE
) {
610 int yy
, mo
, day
, hour
, min
, sec
;
614 "%*s %04d%02d%02d%02d%02d%02d",
615 &yy
, &mo
, &day
, &hour
, &min
, &sec
);
616 tm
= gmtime(&stbuf
.st_mtime
);
618 if (tm
->tm_year
> yy
%100)
620 else if (tm
->tm_year
== yy
%100) {
623 } else if (tm
->tm_mon
== mo
) {
624 if (tm
->tm_mday
> day
)
626 } else if (tm
->tm_mday
== day
) {
627 if (tm
->tm_hour
> hour
)
629 } else if (tm
->tm_hour
== hour
) {
630 if (tm
->tm_min
> min
)
632 } else if (tm
->tm_min
== min
) {
633 if (tm
->tm_sec
> sec
)
637 printf("%s\n", reply_string
);
638 (void) fflush(stdout
);
646 recvrequest("RETR", argv
[2], argv
[1], mode
,
647 argv
[1] != oldargv1
|| argv
[2] != oldargv2
);
657 extern jmp_buf jabort
;
660 (void) fflush(stdout
);
661 if (mflag
&& fromatty
) {
662 ointer
= interactive
;
664 if (confirm("Continue with", mname
)) {
665 interactive
= ointer
;
668 interactive
= ointer
;
676 * Get multiple files.
678 void mget(argc
, argv
)
682 char *tp2
, tmpbuf
[MAXPATHLEN
];
684 extern jmp_buf jabort
;
687 (void) strcat(line
, " ");
688 printf("(remote-files) ");
689 (void) fflush(stdout
);
690 (void) gets(&line
[strlen(line
)]);
696 printf("usage:%s remote-files\n", argv
[0]);
697 (void) fflush(stdout
);
703 // oldintr = signal(SIGINT,mabort);
704 (void) setjmp(jabort
);
705 while ((cp
= remglob(argv
,proxy
)) != NULL
) {
710 if (mflag
&& confirm(argv
[0], cp
)) {
713 while (*tp
&& !islower(*tp
)) {
719 while ((*tp2
= *tp
)) {
721 *tp2
= 'a' + *tp2
- 'A';
735 recvrequest("RETR", tp
, cp
, "w",
736 tp
!= cp
|| !interactive
);
737 if (!mflag
&& fromatty
) {
738 ointer
= interactive
;
740 if (confirm("Continue with","mget")) {
743 interactive
= ointer
;
747 // (void) signal(SIGINT,oldintr);
752 remglob(argv
,doswitch
)
757 static char buf
[MAXPATHLEN
];
758 static FILE *ftemp
= NULL
;
760 int oldverbose
, oldhash
;
770 (void) fclose(ftemp
);
779 if ((cp
= *++args
) == NULL
)
784 (void) strcpy(temp
, _PATH_TMP
);
786 oldverbose
= verbose
, verbose
= 0;
787 oldhash
= hash
, hash
= 0;
791 for (mode
= "w"; *++argv
!= NULL
; mode
= "a")
792 recvrequest ("NLST", temp
, *argv
, mode
, 0);
796 verbose
= oldverbose
; hash
= oldhash
;
797 ftemp
= fopen(temp
, "r");
800 printf("can't find list of remote files, oops\n");
801 (void) fflush(stdout
);
805 if (fgets(buf
, sizeof (buf
), ftemp
) == NULL
) {
806 (void) fclose(ftemp
), ftemp
= NULL
;
809 if ((cp
= index(buf
, '\n')) != NULL
)
819 return (bool ? "on" : "off");
826 void status(argc
, argv
)
832 printf("Connected to %s.\n", hostname
);
834 printf("Not connected.\n");
838 printf("Connected for proxy commands to %s.\n", hostname
);
841 printf("No proxy connection.\n");
845 printf("Mode: %s; Type: %s; Form: %s; Structure: %s\n",
846 modename
, typename
, formname
, structname
);
847 printf("Verbose: %s; Bell: %s; Prompting: %s; Globbing: %s\n",
848 onoff(verbose
), onoff(bell
), onoff(interactive
),
850 printf("Store unique: %s; Receive unique: %s\n", onoff(sunique
),
852 printf("Case: %s; CR stripping: %s\n",onoff(mcase
),onoff(crflag
));
854 printf("Ntrans: (in) %s (out) %s\n", ntin
,ntout
);
857 printf("Ntrans: off\n");
860 printf("Nmap: (in) %s (out) %s\n", mapin
, mapout
);
863 printf("Nmap: off\n");
865 printf("Hash mark printing: %s; Use of PORT cmds: %s\n",
866 onoff(hash
), onoff(sendport
));
869 for (i
=0; i
<macnum
; i
++) {
870 printf("\t%s\n",macros
[i
].mac_name
);
873 (void) fflush(stdout
);
878 * Set beep on cmd completed mode.
885 printf("Bell mode %s.\n", onoff(bell
));
886 (void) fflush(stdout
);
891 * Turn on packet tracing.
898 printf("Packet tracing %s.\n", onoff(trace
));
899 (void) fflush(stdout
);
904 * Toggle hash mark printing during transfers.
911 printf("Hash mark printing %s", onoff(hash
));
914 printf(" (%d bytes/hash mark)", 1024);
916 (void) fflush(stdout
);
920 * Turn on printing of server echo's.
927 printf("Verbose mode %s.\n", onoff(verbose
));
928 (void) fflush(stdout
);
933 * Toggle PORT cmd use before each data connection.
939 sendport
= !sendport
;
940 printf("Use of PORT cmds %s.\n", onoff(sendport
));
941 (void) fflush(stdout
);
946 * Turn on interactive prompting
947 * during mget, mput, and mdelete.
953 interactive
= !interactive
;
954 printf("Interactive mode %s.\n", onoff(interactive
));
955 (void) fflush(stdout
);
960 * Toggle metacharacter interpretation
961 * on local file names.
968 printf("Globbing %s.\n", onoff(doglob
));
969 (void) fflush(stdout
);
974 * Set debugging mode on/off and/or
975 * set level of debugging.
978 void setdebug(argc
, argv
)
986 printf("%s: bad debugging value.\n", argv
[1]);
987 (void) fflush(stdout
);
997 options
&= ~SO_DEBUG
;
998 printf("Debugging %s (debug=%d).\n", onoff(debug
), debug
);
999 (void) fflush(stdout
);
1004 * Set current working directory
1005 * on remote machine.
1012 (void) strcat(line
, " ");
1013 printf("(remote-directory) ");
1014 (void) fflush(stdout
);
1015 (void) gets(&line
[strlen(line
)]);
1021 printf("usage:%s remote-directory\n", argv
[0]);
1022 (void) fflush(stdout
);
1026 if (command("CWD %s", argv
[1]) == ERROR
&& code
== 500) {
1028 printf("CWD command not recognized, trying XCWD\n");
1029 (void) fflush(stdout
);
1031 (void) command("XCWD %s", argv
[1]);
1036 * Set current working directory
1039 void lcd(argc
, argv
)
1042 char buf
[MAXPATHLEN
];
1045 argc
++, argv
[1] = home
;
1047 printf("usage:%s local-directory\n", argv
[0]);
1048 (void) fflush(stdout
);
1052 if (!globulize(&argv
[1])) {
1056 if (chdir(argv
[1]) < 0) {
1061 printf("Local directory now %s\n", getcwd(buf
,sizeof(buf
)));
1062 (void) fflush(stdout
);
1067 * Delete a single file.
1069 void delete(argc
, argv
)
1074 (void) strcat(line
, " ");
1075 printf("(remote-file) ");
1076 (void) fflush(stdout
);
1077 (void) gets(&line
[strlen(line
)]);
1083 printf("usage:%s remote-file\n", argv
[0]);
1084 (void) fflush(stdout
);
1088 (void) command("DELE %s", argv
[1]);
1092 * Delete multiple files.
1094 void mdelete(argc
, argv
)
1099 extern jmp_buf jabort
;
1102 (void) strcat(line
, " ");
1103 printf("(remote-files) ");
1104 (void) fflush(stdout
);
1105 (void) gets(&line
[strlen(line
)]);
1111 printf("usage:%s remote-files\n", argv
[0]);
1112 (void) fflush(stdout
);
1118 // oldintr = signal(SIGINT, mabort);
1119 (void) setjmp(jabort
);
1120 while ((cp
= remglob(argv
,0)) != NULL
) {
1125 if (mflag
&& confirm(argv
[0], cp
)) {
1126 (void) command("DELE %s", cp
);
1127 if (!mflag
&& fromatty
) {
1128 ointer
= interactive
;
1130 if (confirm("Continue with", "mdelete")) {
1133 interactive
= ointer
;
1137 // (void) signal(SIGINT, oldintr);
1142 * Rename a remote file.
1144 void renamefile(argc
, argv
)
1149 (void) strcat(line
, " ");
1150 printf("(from-name) ");
1151 (void) fflush(stdout
);
1152 (void) gets(&line
[strlen(line
)]);
1159 printf("%s from-name to-name\n", argv
[0]);
1160 (void) fflush(stdout
);
1165 (void) strcat(line
, " ");
1166 printf("(to-name) ");
1167 (void) fflush(stdout
);
1168 (void) gets(&line
[strlen(line
)]);
1175 if (command("RNFR %s", argv
[1]) == CONTINUE
)
1176 (void) command("RNTO %s", argv
[2]);
1180 * Get a directory listing
1189 argc
++, argv
[1] = NULL
;
1191 argc
++, argv
[2] = "-";
1193 printf("usage: %s remote-directory local-file\n", argv
[0]);
1194 (void) fflush(stdout
);
1198 cmd
= argv
[0][0] == 'n' ? "NLST" : "LIST";
1199 // cmd = argv[0][0] == 'n' ? "NLST -CF" : "NLST -CF";
1200 if (strcmp(argv
[2], "-") && !globulize(&argv
[2])) {
1204 if (strcmp(argv
[2], "-") && *argv
[2] != '|')
1205 if (!globulize(&argv
[2]) || !confirm("output to local-file:", argv
[2])) {
1209 recvrequest(cmd
, argv
[2], argv
[1], "w", 0);
1213 * Get a directory listing
1214 * of multiple remote files.
1216 void mls(argc
, argv
)
1219 const char *cmd
, *dest
;
1222 extern jmp_buf jabort
;
1225 (void) strcat(line
, " ");
1226 printf("(remote-files) ");
1227 (void) fflush(stdout
);
1228 (void) gets(&line
[strlen(line
)]);
1234 (void) strcat(line
, " ");
1235 printf("(local-file) ");
1236 (void) fflush(stdout
);
1237 (void) gets(&line
[strlen(line
)]);
1243 printf("usage:%s remote-files local-file\n", argv
[0]);
1244 (void) fflush(stdout
);
1248 dest
= argv
[argc
- 1];
1249 argv
[argc
- 1] = NULL
;
1250 if (strcmp(dest
, "-") && *dest
!= '|')
1251 if (!globulize(&dest
) || !confirm("output to local-file:", dest
)) {
1255 cmd
= argv
[0][1] == 'l' ? "NLST" : "LIST";
1258 // oldintr = signal(SIGINT, mabort);
1259 (void) setjmp(jabort
);
1260 for (i
= 1; mflag
&& i
< argc
-1; ++i
) {
1261 *mode
= (i
== 1) ? 'w' : 'a';
1262 recvrequest(cmd
, dest
, argv
[i
], mode
, 0);
1263 if (!mflag
&& fromatty
) {
1264 ointer
= interactive
;
1266 if (confirm("Continue with", argv
[0])) {
1269 interactive
= ointer
;
1272 // (void) signal(SIGINT, oldintr);
1280 void shell(argc
, argv
)
1285 sig_t (*old1
)(), (*old2
)();
1286 char shellnam
[40], *shell
, *namep
;
1289 old1
= signal (SIGINT
, SIG_IGN
);
1290 old2
= signal (SIGQUIT
, SIG_IGN
);
1291 if ((pid
= fork()) == 0) {
1292 for (pid
= 3; pid
< 20; pid
++)
1294 (void) signal(SIGINT
, SIG_DFL
);
1295 (void) signal(SIGQUIT
, SIG_DFL
);
1296 shell
= getenv("SHELL");
1298 shell
= _PATH_BSHELL
;
1299 namep
= rindex(shell
,'/');
1302 (void) strcpy(shellnam
,"-");
1303 (void) strcat(shellnam
, ++namep
);
1304 if (strcmp(namep
, "sh") != 0)
1307 printf ("%s\n", shell
);
1308 (void) fflush (stdout
);
1311 execl(shell
,shellnam
,"-c",altarg
,(char *)0);
1314 execl(shell
,shellnam
,(char *)0);
1321 while (wait(&status
) != pid
)
1323 (void) signal(SIGINT
, old1
);
1324 (void) signal(SIGQUIT
, old2
);
1326 perror("Try again later");
1335 char ShellCmd
[MAX_PATH
];
1336 char CmdLine
[MAX_PATH
];
1338 PROCESS_INFORMATION ProcessInformation
;
1340 STARTUPINFO StartupInfo
;
1341 char ShellName
[] = "COMSPEC";
1344 NumBytes
= GetEnvironmentVariable( ShellName
, ShellCmd
, MAX_PATH
);
1352 strcpy( CmdLine
, ShellCmd
);
1356 strncat(CmdLine
, " /C", MAX_PATH
);
1359 for (i
=1; i
<argc
; i
++)
1361 strncat(CmdLine
, " ", MAX_PATH
);
1362 strncat(CmdLine
, argv
[i
], MAX_PATH
);
1365 StartupInfo
.cb
= sizeof( StartupInfo
);
1366 StartupInfo
.lpReserved
= NULL
;
1367 StartupInfo
.lpDesktop
= NULL
;
1368 StartupInfo
.lpTitle
= NULL
;
1369 StartupInfo
.dwX
= 0;
1370 StartupInfo
.dwY
= 0;
1371 StartupInfo
.dwXSize
= 0;
1372 StartupInfo
.dwYSize
= 0;
1373 StartupInfo
.dwFlags
= 0;
1374 StartupInfo
.wShowWindow
= 0;
1375 StartupInfo
.cbReserved2
= 0;
1376 StartupInfo
.lpReserved2
= NULL
;
1378 Result
= CreateProcess( AppName
, // cmd name
1379 CmdLine
, // cmd line arguments
1381 NULL
, // security attributes
1382 FALSE
, // inherit flags
1383 0, // Creation flags
1384 NULL
, // Environment
1385 NULL
, // Current directory
1386 &StartupInfo
, // Startup info structure
1387 &ProcessInformation
); // processInfo structure
1391 WaitForSingleObject( ProcessInformation
.hProcess
, 0xffffffff);
1393 CloseHandle( ProcessInformation
.hProcess
);
1398 * Send new user information (re-login)
1400 void user(argc
, argv
)
1404 char acct
[80], *getpass();
1408 (void) strcat(line
, " ");
1409 printf("(username) ");
1410 (void) fflush(stdout
);
1411 (void) gets(&line
[strlen(line
)]);
1417 printf("usage: %s username [password] [account]\n", argv
[0]);
1418 (void) fflush(stdout
);
1422 n
= command("USER %s", argv
[1]);
1423 if (n
== CONTINUE
) {
1425 argv
[2] = getpass("Password: "), argc
++;
1426 n
= command("PASS %s", argv
[2]);
1428 if (n
== CONTINUE
) {
1430 printf("Account: "); (void) fflush(stdout
);
1431 (void) fflush(stdout
);
1432 (void) fgets(acct
, sizeof(acct
) - 1, stdin
);
1433 acct
[strlen(acct
) - 1] = '\0';
1434 argv
[3] = acct
; argc
++;
1436 n
= command("ACCT %s", argv
[3]);
1439 if (n
!= COMPLETE
) {
1440 fprintf(stdout
, "Login failed.\n");
1441 (void) fflush(stdout
);
1444 if (!aflag
&& argc
== 4) {
1445 (void) command("ACCT %s", argv
[3]);
1450 * Print working directory.
1455 int oldverbose
= verbose
;
1458 * If we aren't verbose, this doesn't do anything!
1461 if (command("PWD") == ERROR
&& code
== 500) {
1462 printf("PWD command not recognized, trying XPWD\n");
1463 (void) fflush(stdout
);
1464 (void) command("XPWD");
1466 verbose
= oldverbose
;
1472 void makedir(argc
, argv
)
1477 (void) strcat(line
, " ");
1478 printf("(directory-name) ");
1479 (void) fflush(stdout
);
1480 (void) gets(&line
[strlen(line
)]);
1486 printf("usage: %s directory-name\n", argv
[0]);
1487 (void) fflush(stdout
);
1491 if (command("MKD %s", argv
[1]) == ERROR
&& code
== 500) {
1493 printf("MKD command not recognized, trying XMKD\n");
1494 (void) fflush(stdout
);
1496 (void) command("XMKD %s", argv
[1]);
1501 * Remove a directory.
1503 void removedir(argc
, argv
)
1508 (void) strcat(line
, " ");
1509 printf("(directory-name) ");
1510 (void) fflush(stdout
);
1511 (void) gets(&line
[strlen(line
)]);
1517 printf("usage: %s directory-name\n", argv
[0]);
1518 (void) fflush(stdout
);
1522 if (command("RMD %s", argv
[1]) == ERROR
&& code
== 500) {
1524 printf("RMD command not recognized, trying XRMD\n");
1525 (void) fflush(stdout
);
1527 (void) command("XRMD %s", argv
[1]);
1532 * Send a line, verbatim, to the remote machine.
1534 void quote(argc
, argv
)
1541 (void) strcat(line
, " ");
1542 printf("(command line to send) ");
1543 (void) fflush(stdout
);
1544 (void) gets(&line
[strlen(line
)]);
1550 printf("usage: %s line-to-send\n", argv
[0]);
1551 (void) fflush(stdout
);
1555 (void) strcpy(buf
, argv
[1]);
1556 for (i
= 2; i
< argc
; i
++) {
1557 (void) strcat(buf
, " ");
1558 (void) strcat(buf
, argv
[i
]);
1560 if (command(buf
) == PRELIM
) {
1561 while (getreply(0) == PRELIM
);
1566 * Send a SITE command to the remote machine. The line
1567 * is sent almost verbatim to the remote machine, the
1568 * first argument is changed to SITE.
1571 void site(argc
, argv
)
1578 (void) strcat(line
, " ");
1579 printf("(arguments to SITE command) ");
1580 (void) fflush(stdout
);
1581 (void) gets(&line
[strlen(line
)]);
1587 printf("usage: %s line-to-send\n", argv
[0]);
1588 (void) fflush(stdout
);
1592 (void) strcpy(buf
, "SITE ");
1593 (void) strcat(buf
, argv
[1]);
1594 for (i
= 2; i
< argc
; i
++) {
1595 (void) strcat(buf
, " ");
1596 (void) strcat(buf
, argv
[i
]);
1598 if (command(buf
) == PRELIM
) {
1599 while (getreply(0) == PRELIM
);
1603 void do_chmod(argc
, argv
)
1607 printf("usage: %s mode file-name\n", argv
[0]);
1608 (void) fflush(stdout
);
1613 (void) strcat(line
, " ");
1614 printf("(mode and file-name) ");
1615 (void) fflush(stdout
);
1616 (void) gets(&line
[strlen(line
)]);
1622 printf("usage: %s mode file-name\n", argv
[0]);
1623 (void) fflush(stdout
);
1627 (void)command("SITE CHMOD %s %s", argv
[1], argv
[2]);
1630 void do_umask(argc
, argv
)
1633 int oldverbose
= verbose
;
1636 (void) command(argc
== 1 ? "SITE UMASK" : "SITE UMASK %s", argv
[1]);
1637 verbose
= oldverbose
;
1640 void idle(argc
, argv
)
1643 int oldverbose
= verbose
;
1646 (void) command(argc
== 1 ? "SITE IDLE" : "SITE IDLE %s", argv
[1]);
1647 verbose
= oldverbose
;
1651 * Ask the other side for help.
1653 void rmthelp(argc
, argv
)
1656 int oldverbose
= verbose
;
1659 (void) command(argc
== 1 ? "HELP" : "HELP %s", argv
[1]);
1660 verbose
= oldverbose
;
1664 * Terminate session and exit.
1680 * Terminate session, but don't exit.
1689 (void) command("QUIT");
1698 int confirm(cmd
, file
)
1699 const char *cmd
, *file
;
1705 printf("%s %s? ", cmd
, file
);
1706 (void) fflush(stdout
);
1708 return (*line
!= 'n' && *line
!= 'N');
1712 static void fatal(msg
)
1716 fprintf(stderr
, "ftp: %s\n", msg
);
1722 * Glob a local file name specification with
1723 * the expectation of a single return value.
1724 * Can't control multiple values being expanded
1725 * from the expression, we return only the first.
1734 globbed
= glob(*cpp
);
1735 if (globerr
!= NULL
) {
1736 printf("%s: %s\n", *cpp
, globerr
);
1737 (void) fflush(stdout
);
1740 free((char *)globbed
);
1746 /* don't waste too much memory */
1749 free((char *)globbed
);
1755 void account(argc
,argv
)
1759 char acct
[50], *getpass(), *ap
;
1764 (void) strncpy(acct
,*argv
,49);
1769 (void) strncat(acct
,*argv
, 49-strlen(acct
));
1774 ap
= getpass("Account:");
1776 (void) command("ACCT %s", ap
);
1797 longjmp(abortprox
,1);
1801 void doproxy(argc
,argv
)
1805 register struct cmd
*c
;
1806 struct cmd
*getcmd();
1807 // extern struct cmd cmdtab[];
1808 extern jmp_buf abortprox
;
1811 (void) strcat(line
, " ");
1812 printf("(command) ");
1813 (void) fflush(stdout
);
1814 (void) gets(&line
[strlen(line
)]);
1820 printf("usage:%s command\n", argv
[0]);
1821 (void) fflush(stdout
);
1825 c
= getcmd(argv
[1]);
1826 if (c
== (struct cmd
*) -1) {
1827 printf("?Ambiguous command\n");
1828 (void) fflush(stdout
);
1833 printf("?Invalid command\n");
1834 (void) fflush(stdout
);
1839 printf("?Invalid proxy command\n");
1840 (void) fflush(stdout
);
1844 if (setjmp(abortprox
)) {
1848 // oldintr = signal(SIGINT, proxabort);
1850 if (c
->c_conn
&& !connected
) {
1851 printf("Not connected\n");
1852 (void) fflush(stdout
);
1854 // (void) signal(SIGINT, oldintr);
1858 (*c
->c_handler
)(argc
-1, argv
+1);
1866 // (void) signal(SIGINT, oldintr);
1872 printf("Case mapping %s.\n", onoff(mcase
));
1873 (void) fflush(stdout
);
1880 printf("Carriage Return stripping %s.\n", onoff(crflag
));
1881 (void) fflush(stdout
);
1885 void setntrans(argc
,argv
)
1891 printf("Ntrans off.\n");
1892 (void) fflush(stdout
);
1898 (void) strncpy(ntin
, argv
[1], 16);
1904 (void) strncpy(ntout
, argv
[2], 16);
1912 static char new[MAXPATHLEN
];
1915 register int i
, ostop
, found
;
1917 for (ostop
= 0; *(ntout
+ ostop
) && ostop
< 16; ostop
++);
1918 for (cp1
= name
; *cp1
; cp1
++) {
1920 for (i
= 0; *(ntin
+ i
) && i
< 16; i
++) {
1921 if (*cp1
== *(ntin
+ i
)) {
1924 *cp2
++ = *(ntout
+ i
);
1939 setpassive(argc
, argv
)
1943 passivemode
= !passivemode
;
1944 printf("Passive mode %s.\n", onoff(passivemode
));
1945 (void) fflush(stdout
);
1949 void setnmap(argc
, argv
)
1957 printf("Nmap off.\n");
1958 (void) fflush(stdout
);
1963 (void) strcat(line
, " ");
1964 printf("(mapout) ");
1965 (void) fflush(stdout
);
1966 (void) gets(&line
[strlen(line
)]);
1972 printf("Usage: %s [mapin mapout]\n",argv
[0]);
1973 (void) fflush(stdout
);
1979 cp
= index(altarg
, ' ');
1981 while(*++cp
== ' ');
1983 cp
= index(altarg
, ' ');
1986 (void) strncpy(mapin
, altarg
, MAXPATHLEN
- 1);
1987 while (*++cp
== ' ');
1988 (void) strncpy(mapout
, cp
, MAXPATHLEN
- 1);
1995 static char new[MAXPATHLEN
];
1996 const char *cp1
= name
;
1997 char *cpn
, *cp2
= mapin
;
1998 const char *tp
[9], *te
[9];
1999 int i
, toks
[9], toknum
= 0, match
= 1;
2001 for (i
=0; i
< 9; ++i
) {
2004 while (match
&& *cp1
&& *cp2
) {
2007 if (*++cp2
!= *cp1
) {
2012 if (*(cp2
+1) >= '1' && (*cp2
+1) <= '9') {
2013 if (*cp1
!= *(++cp2
+1)) {
2014 toks
[toknum
= *cp2
- '1']++;
2016 while (*++cp1
&& *(cp2
+1)
2030 if (match
&& *cp1
) {
2033 if (match
&& *cp2
) {
2037 if (!match
&& *cp1
) /* last token mismatch */
2055 if (*++cp2
== '$' && isdigit(*(cp2
+1))) {
2056 if (*++cp2
== '0') {
2057 const char *cp3
= name
;
2064 else if (toks
[toknum
= *cp2
- '1']) {
2065 const char *cp3
= tp
[toknum
];
2067 while (cp3
!= te
[toknum
]) {
2074 while (*cp2
&& *cp2
!= ',' &&
2079 else if (*cp2
== '$' &&
2080 isdigit(*(cp2
+1))) {
2081 if (*++cp2
== '0') {
2082 const char *cp3
= name
;
2088 else if (toks
[toknum
=
2090 const char *cp3
=tp
[toknum
];
2103 printf("nmap: unbalanced brackets\n");
2104 (void) fflush(stdout
);
2111 while (*++cp2
&& *cp2
!= ']') {
2112 if (*cp2
== '\\' && *(cp2
+ 1)) {
2117 printf("nmap: unbalanced brackets\n");
2118 (void) fflush(stdout
);
2134 if (isdigit(*(cp2
+ 1))) {
2135 if (*++cp2
== '0') {
2136 const char *cp3
= name
;
2142 else if (toks
[toknum
= *cp2
- '1']) {
2143 const char *cp3
= tp
[toknum
];
2145 while (cp3
!= te
[toknum
]) {
2151 /* intentional drop through */
2168 printf("Store unique %s.\n", onoff(sunique
));
2169 (void) fflush(stdout
);
2176 printf("Receive unique %s.\n", onoff(runique
));
2177 (void) fflush(stdout
);
2181 /* change directory to perent directory */
2184 if (command("CDUP") == ERROR
&& code
== 500) {
2186 printf("CDUP command not recognized, trying XCUP\n");
2187 (void) fflush(stdout
);
2189 (void) command("XCUP");
2193 /* restart transfer at specific point */
2194 void restart(argc
, argv
)
2200 printf("restart: offset not specified\n");
2202 restart_point
= atol(argv
[1]);
2203 printf("restarting at %ld. %s\n", restart_point
,
2204 "execute get, put or append to initiate transfer");
2206 (void) fflush(stdout
);
2209 /* show remote system type */
2212 (void) command("SYST");
2215 void macdef(argc
, argv
)
2223 printf("Limit of 16 macros have already been defined\n");
2224 (void) fflush(stdout
);
2229 (void) strcat(line
, " ");
2230 printf("(macro name) ");
2231 (void) fflush(stdout
);
2232 (void) gets(&line
[strlen(line
)]);
2238 printf("Usage: %s macro_name\n",argv
[0]);
2239 (void) fflush(stdout
);
2244 printf("Enter macro line by line, terminating it with a null line\n");
2245 (void) fflush(stdout
);
2247 (void) strncpy(macros
[macnum
].mac_name
, argv
[1], 8);
2249 macros
[macnum
].mac_start
= macbuf
;
2252 macros
[macnum
].mac_start
= macros
[macnum
- 1].mac_end
+ 1;
2254 tmp
= macros
[macnum
].mac_start
;
2255 while (tmp
!= macbuf
+4096) {
2256 if ((c
= getchar()) == EOF
) {
2257 printf("macdef:end of file encountered\n");
2258 (void) fflush(stdout
);
2262 if ((*tmp
= c
) == '\n') {
2263 if (tmp
== macros
[macnum
].mac_start
) {
2264 macros
[macnum
++].mac_end
= tmp
;
2268 if (*(tmp
-1) == '\0') {
2269 macros
[macnum
++].mac_end
= tmp
- 1;
2278 while ((c
= getchar()) != '\n' && c
!= EOF
)
2280 if (c
== EOF
|| getchar() == '\n') {
2281 printf("Macro not defined - 4k buffer exceeded\n");
2282 (void) fflush(stdout
);
2290 * get size of file on remote machine
2292 void sizecmd(argc
, argv
)
2297 (void) strcat(line
, " ");
2298 printf("(filename) ");
2299 (void) fflush(stdout
);
2300 (void) gets(&line
[strlen(line
)]);
2306 printf("usage:%s filename\n", argv
[0]);
2307 (void) fflush(stdout
);
2311 (void) command("SIZE %s", argv
[1]);
2315 * get last modification time of file on remote machine
2317 void modtime(argc
, argv
)
2323 (void) strcat(line
, " ");
2324 printf("(filename) ");
2325 (void) fflush(stdout
);
2326 (void) gets(&line
[strlen(line
)]);
2332 printf("usage:%s filename\n", argv
[0]);
2333 (void) fflush(stdout
);
2340 if (command("MDTM %s", argv
[1]) == COMPLETE
) {
2341 int yy
, mo
, day
, hour
, min
, sec
;
2342 sscanf(reply_string
, "%*s %04d%02d%02d%02d%02d%02d", &yy
, &mo
,
2343 &day
, &hour
, &min
, &sec
);
2344 /* might want to print this in local time */
2345 printf("%s\t%02d/%02d/%04d %02d:%02d:%02d GMT\n", argv
[1],
2346 mo
, day
, yy
, hour
, min
, sec
);
2348 printf("%s\n", reply_string
);
2350 (void) fflush(stdout
);
2354 * show status on reomte machine
2356 void rmtstatus(argc
, argv
)
2359 (void) command(argc
> 1 ? "STAT %s" : "STAT" , argv
[1]);
2363 * get file if modtime is more recent than current file
2365 void newer(argc
, argv
)
2368 if (getit(argc
, argv
, -1, "w")) {
2369 printf("Local file \"%s\" is newer than remote file \"%s\"\n",
2371 (void) fflush(stdout
);