|
|
1.1 root 1: /*
2: * Copyright (c) 1985, 1989 Regents of the University of California.
3: * All rights reserved.
4: *
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.
16: */
17:
18: #ifndef lint
19: static char sccsid[] = "@(#)cmds.c 5.14.1.2 (Berkeley) 3/1/89";
20: #endif /* not lint */
21:
22: /*
23: * FTP User Program -- Command Routines.
24: */
25: #include <wait.h>
26:
27: #include <stdio.h>
28: #include <errno.h>
29: #include <ctype.h>
30: #include <time.h>
31: #include <string.h>
32:
33: #include "ftp.h"
34:
35: #include "ftp_var.h"
36:
37:
38: extern char *globerr;
39: extern char **glob();
40: extern char *home;
41: extern char *remglob();
42: extern char *getenv();
43: extern char reply_string[];
44:
45: char *mname;
46: char *dotrans(), *domap();
47:
48: /*
49: * Connect to peer server and
50: * auto-login, if possible.
51: */
52: setpeer(argc, argv)
53: int argc;
54: char *argv[];
55: {
56: char *host, *hookup();
57:
58: if (connected) {
59: printf("Already connected to %s, use close first.\n",
60: hostname);
61: code = -1;
62: return;
63: }
64: if (argc < 2) {
65: (void) strcat(line, " ");
66: printf("(to) ");
67: safegets(&line[strlen(line)], sizeof(line)-strlen(line));
68: makeargv();
69: argc = margc;
70: argv = margv;
71: }
72: if (argc > 3) {
73: printf("usage: %s host-name\n", argv[0]);
74: code = -1;
75: return;
76: }
77: host = hookup(argv[1]);
78: if (host) {
79: connected = 1;
80: if (autologin) {
81: int overbose;
82:
83: (void) login(argv[1]);
84: #if defined(unix) && NBBY == 8
85: /*
86: * this ifdef is to keep someone form "porting" this to an incompatible
87: * system and not checking this out. This way they have to think about it.
88: */
89: overbose = verbose;
90: if (debug == 0)
91: verbose = -1;
92: if (command("SYST") == COMPLETE && overbose) {
93: register char *cp, c;
94: cp = strchr(reply_string+4, ' ');
95: if (cp == NULL)
96: cp = strchr(reply_string+4, '\r');
97: if (cp) {
98: if (cp[-1] == '.')
99: cp--;
100: c = *cp;
101: *cp = '\0';
102: }
103:
104: printf("Remote system type is %s.\n",
105: reply_string+4);
106: if (cp)
107: *cp = c;
108: }
109: if (!strncmp(reply_string, "215 UNIX Type: L8", 17)) {
110: setbinary();
111: if (overbose)
112: printf("Using %s mode to transfer files.\n",
113: typename);
114: } else if (overbose &&
115: !strncmp(reply_string, "215 TOPS20", 10)) {
116: printf(
117: "Remember to set tenex mode when transfering binary files from this machine.\n");
118: }
119: verbose = overbose;
120: #endif /* unix */
121: }
122: }
123: }
124:
125: struct types {
126: char *t_name;
127: char *t_mode;
128: int t_type;
129: char *t_arg;
130: } types[] = {
131: { "ascii", "A", TYPE_A, 0 },
132: { "binary", "I", TYPE_I, 0 },
133: { "image", "I", TYPE_I, 0 },
134: { "ebcdic", "E", TYPE_E, 0 },
135: { "tenex", "L", TYPE_L, bytename },
136: 0
137: };
138:
139: /*
140: * Set transfer type.
141: */
142: settype(argc, argv)
143: char *argv[];
144: {
145: register struct types *p;
146: int comret;
147:
148: if (argc > 2) {
149: char *sep;
150:
151: printf("usage: %s [", argv[0]);
152: sep = " ";
153: for (p = types; p->t_name; p++) {
154: printf("%s%s", sep, p->t_name);
155: if (*sep == ' ')
156: sep = " | ";
157: }
158: printf(" ]\n");
159: code = -1;
160: return;
161: }
162: if (argc < 2) {
163: printf("Using %s mode to transfer files.\n", typename);
164: code = 0;
165: return;
166: }
167: for (p = types; p->t_name; p++)
168: if (strcmp(argv[1], p->t_name) == 0)
169: break;
170: if (p->t_name == 0) {
171: printf("%s: unknown mode\n", argv[1]);
172: code = -1;
173: return;
174: }
175: if ((p->t_arg != NULL) && (*(p->t_arg) != '\0'))
176: comret = command ("TYPE %s %s", p->t_mode, p->t_arg);
177: else
178: comret = command("TYPE %s", p->t_mode);
179: if (comret == COMPLETE) {
180: (void) strcpy(typename, p->t_name);
181: type = p->t_type;
182: }
183: }
184:
185: /*
186: * Set binary transfer type.
187: */
188: /*VARARGS*/
189: setbinary()
190: {
191:
192: call(settype, "type", "binary", 0);
193: }
194:
195: /*
196: * Set ascii transfer type.
197: */
198: /*VARARGS*/
199: setascii()
200: {
201:
202: call(settype, "type", "ascii", 0);
203: }
204:
205: /*
206: * Set tenex transfer type.
207: */
208: /*VARARGS*/
209: settenex()
210: {
211:
212: call(settype, "type", "tenex", 0);
213: }
214:
215: /*
216: * Set ebcdic transfer type.
217: */
218: /*VARARGS*/
219: setebcdic()
220: {
221:
222: call(settype, "type", "ebcdic", 0);
223: }
224:
225: /*
226: * Set file transfer mode.
227: */
228: /*ARGSUSED*/
229: setmode(argc, argv)
230: char *argv[];
231: {
232:
233: printf("We only support %s mode, sorry.\n", modename);
234: code = -1;
235: }
236:
237: /*
238: * Set file transfer format.
239: */
240: /*ARGSUSED*/
241: setform(argc, argv)
242: char *argv[];
243: {
244:
245: printf("We only support %s format, sorry.\n", formname);
246: code = -1;
247: }
248:
249: /*
250: * Set file transfer structure.
251: */
252: /*ARGSUSED*/
253: setstruct(argc, argv)
254: char *argv[];
255: {
256:
257: printf("We only support %s structure, sorry.\n", structname);
258: code = -1;
259: }
260:
261: /*
262: * Send a single file.
263: */
264: put(argc, argv)
265: int argc;
266: char *argv[];
267: {
268: char *cmd;
269: int loc = 0;
270: char *oldargv1;
271:
272: if (argc == 2) {
273: argc++;
274: argv[2] = argv[1];
275: loc++;
276: }
277: if (argc < 2) {
278: (void) strcat(line, " ");
279: printf("(local-file) ");
280: safegets(&line[strlen(line)], sizeof(line)-strlen(line));
281: makeargv();
282: argc = margc;
283: argv = margv;
284: }
285: if (argc < 2) {
286: usage:
287: printf("usage:%s local-file remote-file\n", argv[0]);
288: code = -1;
289: return;
290: }
291: if (argc < 3) {
292: (void) strcat(line, " ");
293: printf("(remote-file) ");
294: safegets(&line[strlen(line)], sizeof(line)-strlen(line));
295: makeargv();
296: argc = margc;
297: argv = margv;
298: }
299: if (argc < 3)
300: goto usage;
301: oldargv1 = argv[1];
302: if (!globulize(&argv[1])) {
303: code = -1;
304: return;
305: }
306: /*
307: * If "globulize" modifies argv[1], and argv[2] is a copy of
308: * the old argv[1], make it a copy of the new argv[1].
309: */
310: if (argv[1] != oldargv1 && argv[2] == oldargv1) {
311: argv[2] = argv[1];
312: }
313: cmd = (argv[0][0] == 'a') ? "APPE" : ((sunique) ? "STOU" : "STOR");
314: if (loc && ntflag) {
315: argv[2] = dotrans(argv[2]);
316: }
317: if (loc && mapflag) {
318: argv[2] = domap(argv[2]);
319: }
320: sendrequest(cmd, argv[1], argv[2]);
321: }
322:
323: /*
324: * Send multiple files.
325: */
326: mput(argc, argv)
327: char *argv[];
328: {
329: register int i;
330: char *tp;
331: int ointer;
332:
333: if (argc < 2) {
334: (void) strcat(line, " ");
335: printf("(local-files) ");
336: safegets(&line[strlen(line)], sizeof(line)-strlen(line));
337: makeargv();
338: argc = margc;
339: argv = margv;
340: }
341: if (argc < 2) {
342: printf("usage:%s local-files\n", argv[0]);
343: code = -1;
344: return;
345: }
346: mname = argv[0];
347: mflag = 1;
348: if (proxy) {
349: char *cp, *tp2, tmpbuf[MAXPATHLEN];
350:
351: while ((cp = remglob(argv,0)) != NULL) {
352: if (*cp == 0) {
353: mflag = 0;
354: continue;
355: }
356: if (mflag && confirm(argv[0], cp)) {
357: tp = cp;
358: if (mcase) {
359: while (*tp && !islower(*tp)) {
360: tp++;
361: }
362: if (!*tp) {
363: tp = cp;
364: tp2 = tmpbuf;
365: while ((*tp2 = *tp) != NULL) {
366: if (isupper(*tp2)) {
367: *tp2 = 'a' + *tp2 - 'A';
368: }
369: tp++;
370: tp2++;
371: }
372: }
373: tp = tmpbuf;
374: }
375: if (ntflag) {
376: tp = dotrans(tp);
377: }
378: if (mapflag) {
379: tp = domap(tp);
380: }
381: sendrequest((sunique) ? "STOU" : "STOR", cp,tp);
382: if (!mflag && fromatty) {
383: ointer = interactive;
384: interactive = 1;
385: if (confirm("Continue with","mput")) {
386: mflag++;
387: }
388: interactive = ointer;
389: }
390: }
391: }
392: mflag = 0;
393: return;
394: }
395: for (i = 1; i < argc; i++) {
396: register char **cpp, **gargs;
397:
398: if (!doglob) {
399: if (mflag && confirm(argv[0], argv[i])) {
400: tp = (ntflag) ? dotrans(argv[i]) : argv[i];
401: tp = (mapflag) ? domap(tp) : tp;
402: sendrequest((sunique) ? "STOU" : "STOR",
403: argv[i], tp);
404: if (!mflag && fromatty) {
405: ointer = interactive;
406: interactive = 1;
407: if (confirm("Continue with","mput")) {
408: mflag++;
409: }
410: interactive = ointer;
411: }
412: }
413: continue;
414: }
415: gargs = glob(argv[i]);
416: if (globerr != NULL) {
417: printf("%s\n", globerr);
418: if (gargs) {
419: blkfree(gargs);
420: free(gargs);
421: }
422: continue;
423: }
424: for (cpp = gargs; cpp && *cpp != NULL; cpp++) {
425: if (mflag && confirm(argv[0], *cpp)) {
426: tp = (ntflag) ? dotrans(*cpp) : *cpp;
427: tp = (mapflag) ? domap(tp) : tp;
428: sendrequest((sunique) ? "STOU" : "STOR",
429: *cpp, tp);
430: if (!mflag && fromatty) {
431: ointer = interactive;
432: interactive = 1;
433: if (confirm("Continue with","mput")) {
434: mflag++;
435: }
436: interactive = ointer;
437: }
438: }
439: }
440: if (gargs != NULL) {
441: blkfree(gargs);
442: free(gargs);
443: }
444: }
445: mflag = 0;
446: }
447:
448:
449: /*
450: * Receive one file.
451: */
452: get(argc, argv)
453: char *argv[];
454: {
455: int loc = 0;
456:
457: if (argc == 2) {
458: argc++;
459: argv[2] = argv[1];
460: loc++;
461: }
462: if (argc < 2) {
463: (void) strcat(line, " ");
464: printf("(remote-file) ");
465: safegets(&line[strlen(line)], sizeof(line)-strlen(line));
466: makeargv();
467: argc = margc;
468: argv = margv;
469: }
470: if (argc < 2) {
471: usage:
472: printf("usage: %s remote-file [ local-file ]\n", argv[0]);
473: code = -1;
474: return;
475: }
476: if (argc < 3) {
477: (void) strcat(line, " ");
478: printf("(local-file) ");
479: safegets(&line[strlen(line)], sizeof(line)-strlen(line));
480: makeargv();
481: argc = margc;
482: argv = margv;
483: }
484: if (argc < 3)
485: goto usage;
486: if (!globulize(&argv[2])) {
487: code = -1;
488: return;
489: }
490: if (loc && mcase) {
491: char *tp = argv[1], *tp2, tmpbuf[MAXPATHLEN];
492:
493: while (*tp && !islower(*tp)) {
494: tp++;
495: }
496: if (!*tp) {
497: tp = argv[2];
498: tp2 = tmpbuf;
499: while ((*tp2 = *tp) != NULL) {
500: if (isupper(*tp2)) {
501: *tp2 = 'a' + *tp2 - 'A';
502: }
503: tp++;
504: tp2++;
505: }
506: argv[2] = tmpbuf;
507: }
508: }
509: if (loc && ntflag)
510: argv[2] = dotrans(argv[2]);
511: if (loc && mapflag)
512: argv[2] = domap(argv[2]);
513: recvrequest("RETR", argv[2], argv[1], "w");
514: }
515:
516: /*
517: * Get multiple files.
518: */
519: mget(argc, argv)
520: char *argv[];
521: {
522: char *cp, *tp, *tp2, tmpbuf[MAXPATHLEN];
523: int ointer;
524:
525: if (argc < 2) {
526: (void) strcat(line, " ");
527: printf("(remote-files) ");
528: safegets(&line[strlen(line)], sizeof(line)-strlen(line));
529: makeargv();
530: argc = margc;
531: argv = margv;
532: }
533: if (argc < 2) {
534: printf("usage:%s remote-files\n", argv[0]);
535: code = -1;
536: return;
537: }
538: mname = argv[0];
539: mflag = 1;
540: while ((cp = remglob(argv,proxy)) != NULL) {
541: if (*cp == '\0') {
542: mflag = 0;
543: continue;
544: }
545: if (mflag && confirm(argv[0], cp)) {
546: tp = cp;
547: if (mcase) {
548: while (*tp && !islower(*tp)) {
549: tp++;
550: }
551: if (!*tp) {
552: tp = cp;
553: tp2 = tmpbuf;
554: while ((*tp2 = *tp) != NULL) {
555: if (isupper(*tp2)) {
556: *tp2 = 'a' + *tp2 - 'A';
557: }
558: tp++;
559: tp2++;
560: }
561: }
562: tp = tmpbuf;
563: }
564: if (ntflag) {
565: tp = dotrans(tp);
566: }
567: if (mapflag) {
568: tp = domap(tp);
569: }
570: recvrequest("RETR", tp, cp, "w");
571: if (!mflag && fromatty) {
572: ointer = interactive;
573: interactive = 1;
574: if (confirm("Continue with","mget")) {
575: mflag++;
576: }
577: interactive = ointer;
578: }
579: }
580: }
581: mflag = 0;
582: }
583:
584: char *
585: remglob(argv,doswitch)
586: char *argv[];
587: int doswitch;
588: {
589: char temp[16];
590: static char buf[MAXPATHLEN];
591: static FILE *ftemp = NULL;
592: static char **args;
593: int oldverbose, oldhash;
594: char *cp, *mode;
595:
596: if (!mflag) {
597: if (!doglob) {
598: args = NULL;
599: }
600: else {
601: if (ftemp) {
602: (void) fclose(ftemp);
603: ftemp = NULL;
604: }
605: }
606: return(NULL);
607: }
608: if (!doglob) {
609: if (args == NULL)
610: args = argv;
611: if ((cp = *++args) == NULL)
612: args = NULL;
613: return (cp);
614: }
615: if (ftemp == NULL) {
616: (void) strcpy(temp, "/tmp/ftpXXXXXX");
617: (void) mktemp(temp);
618: oldverbose = verbose, verbose = 0;
619: oldhash = hash, hash = 0;
620: if (doswitch) {
621: pswitch(!proxy);
622: }
623: for (mode = "w"; *++argv != NULL; mode = "a")
624: recvrequest ("NLST", temp, *argv, mode);
625: if (doswitch) {
626: pswitch(!proxy);
627: }
628: verbose = oldverbose; hash = oldhash;
629: ftemp = fopen(temp, "r");
630: (void) unlink(temp);
631: if (ftemp == NULL) {
632: printf("can't find list of remote files, oops\n");
633: return (NULL);
634: }
635: }
636: if (fgets(buf, sizeof (buf), ftemp) == NULL) {
637: (void) fclose(ftemp), ftemp = NULL;
638: return (NULL);
639: }
640: if ((cp = strchr(buf, '\n')) != NULL)
641: *cp = '\0';
642: return (buf);
643: }
644:
645: char *
646: onoff(bool)
647: int bool;
648: {
649:
650: return (bool ? "on" : "off");
651: }
652:
653: /*
654: * Show status.
655: */
656: /*ARGSUSED*/
657: status(argc, argv)
658: char *argv[];
659: {
660: int i;
661:
662: if (connected)
663: printf("Connected to %s.\n", hostname);
664: else
665: printf("Not connected.\n");
666: if (!proxy) {
667: pswitch(1);
668: if (connected) {
669: printf("Connected for proxy commands to %s.\n", hostname);
670: }
671: else {
672: printf("No proxy connection.\n");
673: }
674: pswitch(0);
675: }
676: printf("Mode: %s; Type: %s; Form: %s; Structure: %s\n",
677: modename, typename, formname, structname);
678: printf("Verbose: %s; Bell: %s; Prompting: %s; Globbing: %s\n",
679: onoff(verbose), onoff(bell), onoff(interactive),
680: onoff(doglob));
681: printf("Store unique: %s; Receive unique: %s\n", onoff(sunique),
682: onoff(runique));
683: printf("Case: %s; CR stripping: %s\n",onoff(mcase),onoff(crflag));
684: if (ntflag) {
685: printf("Ntrans: (in) %s (out) %s\n", ntin,ntout);
686: }
687: else {
688: printf("Ntrans: off\n");
689: }
690: if (mapflag) {
691: printf("Nmap: (in) %s (out) %s\n", mapin, mapout);
692: }
693: else {
694: printf("Nmap: off\n");
695: }
696: printf("Hash mark printing: %s; Use of PORT cmds: %s\n",
697: onoff(hash), onoff(sendport));
698: if (macnum > 0) {
699: printf("Macros:\n");
700: for (i=0; i<macnum; i++) {
701: printf("\t%s\n",macros[i].mac_name);
702: }
703: }
704: code = 0;
705: }
706:
707: /*
708: * Set beep on cmd completed mode.
709: */
710: /*VARARGS*/
711: setbell()
712: {
713:
714: bell = !bell;
715: printf("Bell mode %s.\n", onoff(bell));
716: code = bell;
717: }
718:
719: /*
720: * Turn on packet tracing.
721: */
722: /*VARARGS*/
723: settrace()
724: {
725:
726: trace = !trace;
727: printf("Packet tracing %s.\n", onoff(trace));
728: code = trace;
729: }
730:
731: /*
732: * Toggle hash mark printing during transfers.
733: */
734: /*VARARGS*/
735: sethash()
736: {
737:
738: hash = !hash;
739: printf("Hash mark printing %s", onoff(hash));
740: code = hash;
741: if (hash)
742: printf(" (%d bytes/hash mark)", BUFSIZ);
743: printf(".\n");
744: }
745:
746: /*
747: * Turn on printing of server echo's.
748: */
749: /*VARARGS*/
750: setverbose()
751: {
752:
753: verbose = !verbose;
754: printf("Verbose mode %s.\n", onoff(verbose));
755: code = verbose;
756: }
757:
758: /*
759: * Toggle PORT cmd use before each data connection.
760: */
761: /*VARARGS*/
762: setport()
763: {
764:
765: sendport = !sendport;
766: printf("Use of PORT cmds %s.\n", onoff(sendport));
767: code = sendport;
768: }
769:
770: /*
771: * Turn on interactive prompting
772: * during mget, mput, and mdelete.
773: */
774: /*VARARGS*/
775: setprompt()
776: {
777:
778: interactive = !interactive;
779: printf("Interactive mode %s.\n", onoff(interactive));
780: code = interactive;
781: }
782:
783: /*
784: * Toggle metacharacter interpretation
785: * on local file names.
786: */
787: /*VARARGS*/
788: setglob()
789: {
790:
791: doglob = !doglob;
792: printf("Globbing %s.\n", onoff(doglob));
793: code = doglob;
794: }
795:
796: /*
797: * Set debugging mode on/off and/or
798: * set level of debugging.
799: */
800: /*VARARGS*/
801: setdebug(argc, argv)
802: char *argv[];
803: {
804: int val;
805:
806: if (argc > 1) {
807: val = atoi(argv[1]);
808: if (val < 0) {
809: printf("%s: bad debugging value.\n", argv[1]);
810: code = -1;
811: return;
812: }
813: } else
814: val = !debug;
815: debug = val;
816: #ifdef REMOVE
817: if (debug)
818: options |= SO_DEBUG;
819: else
820: options &= ~SO_DEBUG;
821: #endif
822: printf("Debugging %s (debug=%d).\n", onoff(debug), debug);
823: code = debug > 0;
824: }
825:
826: /*
827: * Set current working directory
828: * on remote machine.
829: */
830: cd(argc, argv)
831: char *argv[];
832: {
833:
834: if (argc < 2) {
835: (void) strcat(line, " ");
836: printf("(remote-directory) ");
837: safegets(&line[strlen(line)], sizeof(line)-strlen(line));
838: makeargv();
839: argc = margc;
840: argv = margv;
841: }
842: if (argc < 2) {
843: printf("usage:%s remote-directory\n", argv[0]);
844: code = -1;
845: return;
846: }
847: (void) command("CWD %s", argv[1]);
848: }
849:
850: /*
851: * Set current working directory
852: * on local machine.
853: */
854: lcd(argc, argv)
855: char *argv[];
856: {
857: char buf[MAXPATHLEN];
858:
859: if (argc < 2)
860: argc++, argv[1] = home;
861: if (argc != 2) {
862: printf("usage:%s local-directory\n", argv[0]);
863: code = -1;
864: return;
865: }
866: if (!globulize(&argv[1])) {
867: code = -1;
868: return;
869: }
870: if (chdir(argv[1]) < 0) {
871: perror(argv[1]);
872: code = -1;
873: return;
874: }
875: printf("Local directory now %s\n", getwd(buf));
876: code = 0;
877: }
878:
879: /*
880: * Delete a single file.
881: */
882: delete(argc, argv)
883: char *argv[];
884: {
885:
886: if (argc < 2) {
887: (void) strcat(line, " ");
888: printf("(remote-file) ");
889: safegets(&line[strlen(line)], sizeof(line)-strlen(line));
890: makeargv();
891: argc = margc;
892: argv = margv;
893: }
894: if (argc < 2) {
895: printf("usage:%s remote-file\n", argv[0]);
896: code = -1;
897: return;
898: }
899: (void) command("DELE %s", argv[1]);
900: }
901:
902: /*
903: * Delete multiple files.
904: */
905: mdelete(argc, argv)
906: char *argv[];
907: {
908: char *cp;
909: int ointer;
910:
911: if (argc < 2) {
912: (void) strcat(line, " ");
913: printf("(remote-files) ");
914: safegets(&line[strlen(line)], sizeof(line)-strlen(line));
915: makeargv();
916: argc = margc;
917: argv = margv;
918: }
919: if (argc < 2) {
920: printf("usage:%s remote-files\n", argv[0]);
921: code = -1;
922: return;
923: }
924: mname = argv[0];
925: mflag = 1;
926: while ((cp = remglob(argv,0)) != NULL) {
927: if (*cp == '\0') {
928: mflag = 0;
929: continue;
930: }
931: if (mflag && confirm(argv[0], cp)) {
932: (void) command("DELE %s", cp);
933: if (!mflag && fromatty) {
934: ointer = interactive;
935: interactive = 1;
936: if (confirm("Continue with", "mdelete")) {
937: mflag++;
938: }
939: interactive = ointer;
940: }
941: }
942: }
943: mflag = 0;
944: }
945:
946: /*
947: * Rename a remote file.
948: */
949: renamefile(argc, argv)
950: char *argv[];
951: {
952:
953: if (argc < 2) {
954: (void) strcat(line, " ");
955: printf("(from-name) ");
956: safegets(&line[strlen(line)], sizeof(line)-strlen(line));
957: makeargv();
958: argc = margc;
959: argv = margv;
960: }
961: if (argc < 2) {
962: usage:
963: printf("%s from-name to-name\n", argv[0]);
964: code = -1;
965: return;
966: }
967: if (argc < 3) {
968: (void) strcat(line, " ");
969: printf("(to-name) ");
970: safegets(&line[strlen(line)], sizeof(line)-strlen(line));
971: makeargv();
972: argc = margc;
973: argv = margv;
974: }
975: if (argc < 3)
976: goto usage;
977: if (command("RNFR %s", argv[1]) == CONTINUE)
978: (void) command("RNTO %s", argv[2]);
979: }
980:
981: /*
982: * Get a directory listing
983: * of remote files.
984: */
985: ls(argc, argv)
986: char *argv[];
987: {
988: char *cmd;
989:
990: if (argc < 2)
991: argc++, argv[1] = NULL;
992: if (argc < 3)
993: argc++, argv[2] = "-";
994: if (argc > 3) {
995: printf("usage: %s remote-directory local-file\n", argv[0]);
996: code = -1;
997: return;
998: }
999: cmd = argv[0][0] != 'n' ? "NLST" : "LIST"; /* stub: this is wrong*/
1000: if (strcmp(argv[2], "-") && !globulize(&argv[2])) {
1001: code = -1;
1002: return;
1003: }
1004: if (strcmp(argv[2], "-") && *argv[2] != '|')
1005: if (!globulize(&argv[2]) || !confirm("output to local-file:", argv[2])) {
1006: code = -1;
1007: return;
1008: }
1009: recvrequest(cmd, argv[2], argv[1], "w");
1010: }
1011:
1012: /*
1013: * Get a directory listing
1014: * of multiple remote files.
1015: */
1016: mls(argc, argv)
1017: char *argv[];
1018: {
1019: char *cmd, mode[1], *dest;
1020: int ointer, i;
1021:
1022: if (argc < 2) {
1023: (void) strcat(line, " ");
1024: printf("(remote-files) ");
1025: safegets(&line[strlen(line)], sizeof(line)-strlen(line));
1026: makeargv();
1027: argc = margc;
1028: argv = margv;
1029: }
1030: if (argc < 3) {
1031: (void) strcat(line, " ");
1032: printf("(local-file) ");
1033: safegets(&line[strlen(line)], sizeof(line)-strlen(line));
1034: makeargv();
1035: argc = margc;
1036: argv = margv;
1037: }
1038: if (argc < 3) {
1039: printf("usage:%s remote-files local-file\n", argv[0]);
1040: code = -1;
1041: return;
1042: }
1043: dest = argv[argc - 1];
1044: argv[argc - 1] = NULL;
1045: if (strcmp(dest, "-") && *dest != '|')
1046: if (!globulize(&dest) || !confirm("output to local-file:", dest)) {
1047: code = -1;
1048: return;
1049: }
1050: cmd = argv[0][1] == 'l' ? "NLST" : "LIST";
1051: mname = argv[0];
1052: mflag = 1;
1053: for (i = 1; mflag && i < argc-1; ++i) {
1054: *mode = (i == 1) ? 'w' : 'a';
1055: recvrequest(cmd, dest, argv[i], mode);
1056: if (!mflag && fromatty) {
1057: ointer = interactive;
1058: interactive = 1;
1059: if (confirm("Continue with", argv[0])) {
1060: mflag ++;
1061: }
1062: interactive = ointer;
1063: }
1064: }
1065: mflag = 0;
1066: }
1067:
1068: /*
1069: * Do a shell escape
1070: */
1071: /*ARGSUSED*/
1072: shell(argc, argv)
1073: char *argv[];
1074: {
1075: int pid;
1076: char shellnam[40], *shell, *namep;
1077: union wait status;
1078:
1079: if ((pid = fork()) == 0) {
1080: for (pid = 3; pid < 20; pid++)
1081: (void) close(pid);
1082: shell = getenv("SHELL");
1083: if (shell == NULL)
1084: shell = "/bin/sh";
1085: namep = strrchr(shell,'/');
1086: if (namep == NULL)
1087: namep = shell;
1088: (void) strcpy(shellnam,"-");
1089: (void) strcat(shellnam, ++namep);
1090: if (strcmp(namep, "sh") != 0)
1091: shellnam[0] = '+';
1092: if (debug) {
1093: printf ("%s\n", shell);
1094: (void) fflush (stdout);
1095: }
1096: if (argc > 1) {
1097: execl(shell,shellnam,"-c",altarg,(char *)0);
1098: }
1099: else {
1100: execl(shell,shellnam,(char *)0);
1101: }
1102: perror(shell);
1103: code = -1;
1104: exit(1);
1105: }
1106: if (pid > 0)
1107: while (wait(&status) != pid)
1108: ;
1109: if (pid == -1) {
1110: perror("Try again later");
1111: code = -1;
1112: }
1113: else {
1114: code = 0;
1115: }
1116: return (0);
1117: }
1118:
1119: /*
1120: * Send new user information (re-login)
1121: */
1122: user(argc, argv)
1123: int argc;
1124: char **argv;
1125: {
1126: char acct[80], *getpass();
1127: int n, aflag = 0;
1128:
1129: if (argc < 2) {
1130: (void) strcat(line, " ");
1131: printf("(username) ");
1132: safegets(&line[strlen(line)], sizeof(line)-strlen(line));
1133: makeargv();
1134: argc = margc;
1135: argv = margv;
1136: }
1137: if (argc > 4) {
1138: printf("usage: %s username [password] [account]\n", argv[0]);
1139: code = -1;
1140: return (0);
1141: }
1142: n = command("USER %s", argv[1]);
1143: if (n == CONTINUE) {
1144: if (argc < 3 )
1145: argv[2] = getpass("Password: "), argc++;
1146: n = command("PASS %s", argv[2]);
1147: }
1148: if (n == CONTINUE) {
1149: if (argc < 4) {
1150: printf("Account: "); (void) fflush(stdout);
1151: (void) fgets(acct, sizeof(acct) - 1, stdin);
1152: acct[strlen(acct) - 1] = '\0';
1153: argv[3] = acct; argc++;
1154: }
1155: n = command("ACCT %s", argv[3]);
1156: aflag++;
1157: }
1158: if (n != COMPLETE) {
1159: fprintf(stdout, "Login failed.\n");
1160: return (0);
1161: }
1162: if (!aflag && argc == 4) {
1163: (void) command("ACCT %s", argv[3]);
1164: }
1165: return (1);
1166: }
1167:
1168: /*
1169: * Print working directory.
1170: */
1171: /*VARARGS*/
1172: pwd()
1173: {
1174:
1175: (void) command("PWD");
1176: }
1177:
1178: /*
1179: * Make a directory.
1180: */
1181: makedir(argc, argv)
1182: char *argv[];
1183: {
1184:
1185: if (argc < 2) {
1186: (void) strcat(line, " ");
1187: printf("(directory-name) ");
1188: safegets(&line[strlen(line)], sizeof(line)-strlen(line));
1189: makeargv();
1190: argc = margc;
1191: argv = margv;
1192: }
1193: if (argc < 2) {
1194: printf("usage: %s directory-name\n", argv[0]);
1195: code = -1;
1196: return;
1197: }
1198: (void) command("MKD %s", argv[1]);
1199: }
1200:
1201: /*
1202: * Remove a directory.
1203: */
1204: removedir(argc, argv)
1205: char *argv[];
1206: {
1207:
1208: if (argc < 2) {
1209: (void) strcat(line, " ");
1210: printf("(directory-name) ");
1211: safegets(&line[strlen(line)], sizeof(line)-strlen(line));
1212: makeargv();
1213: argc = margc;
1214: argv = margv;
1215: }
1216: if (argc < 2) {
1217: printf("usage: %s directory-name\n", argv[0]);
1218: code = -1;
1219: return;
1220: }
1221: (void) command("RMD %s", argv[1]);
1222: }
1223:
1224: /*
1225: * Send a line, verbatim, to the remote machine.
1226: */
1227: quote(argc, argv)
1228: char *argv[];
1229: {
1230: int i;
1231: char buf[BUFSIZ];
1232:
1233: if (argc < 2) {
1234: (void) strcat(line, " ");
1235: printf("(command line to send) ");
1236: safegets(&line[strlen(line)], sizeof(line)-strlen(line));
1237: makeargv();
1238: argc = margc;
1239: argv = margv;
1240: }
1241: if (argc < 2) {
1242: printf("usage: %s line-to-send\n", argv[0]);
1243: code = -1;
1244: return;
1245: }
1246: (void) strcpy(buf, argv[1]);
1247: for (i = 2; i < argc; i++) {
1248: (void) strcat(buf, " ");
1249: (void) strcat(buf, argv[i]);
1250: }
1251: if (command(buf) == PRELIM) {
1252: while (getreply(0) == PRELIM);
1253: }
1254: }
1255:
1256: /*
1257: * Ask the other side for help.
1258: */
1259: rmthelp(argc, argv)
1260: char *argv[];
1261: {
1262: int oldverbose = verbose;
1263:
1264: verbose = 1;
1265: (void) command(argc == 1 ? "HELP" : "HELP %s", argv[1]);
1266: verbose = oldverbose;
1267: }
1268:
1269: /*
1270: * Terminate session and exit.
1271: */
1272: /*VARARGS*/
1273: quit()
1274: {
1275:
1276: if (connected)
1277: disconnect();
1278: pswitch(1);
1279: if (connected) {
1280: disconnect();
1281: }
1282: exit(0);
1283: }
1284:
1285: /*
1286: * Terminate session, but don't exit.
1287: */
1288: disconnect()
1289: {
1290: extern FILE *cout;
1291: extern int data;
1292:
1293: if (!connected)
1294: return;
1295: (void) command("QUIT");
1296: if (cout) {
1297: (void) fclose(cout);
1298: }
1299: cout = NULL;
1300: connected = 0;
1301: data = -1;
1302: if (!proxy) {
1303: macnum = 0;
1304: }
1305: }
1306:
1307: confirm(cmd, file)
1308: char *cmd, *file;
1309: {
1310: char line[BUFSIZ];
1311:
1312: if (!interactive)
1313: return (1);
1314: printf("%s %s? ", cmd, file);
1315: (void) fflush(stdout);
1316: safegets(line, sizeof(line));
1317: return (*line != 'n' && *line != 'N');
1318: }
1319:
1320: fatal(msg)
1321: char *msg;
1322: {
1323:
1324: fprintf(stderr, "ftp: %s\n", msg);
1325: exit(1);
1326: }
1327:
1328: /*
1329: * Glob a local file name specification with
1330: * the expectation of a single return value.
1331: * Can't control multiple values being expanded
1332: * from the expression, we return only the first.
1333: */
1334: globulize(cpp)
1335: char **cpp;
1336: {
1337: char **globbed;
1338:
1339: if (!doglob)
1340: return (1);
1341: globbed = glob(*cpp);
1342: if (globerr != NULL) {
1343: printf("%s: %s\n", *cpp, globerr);
1344: if (globbed) {
1345: blkfree(globbed);
1346: free(globbed);
1347: }
1348: return (0);
1349: }
1350: if (globbed) {
1351: *cpp = *globbed++;
1352: /* don't waste too much memory */
1353: if (*globbed) {
1354: blkfree(globbed);
1355: free(globbed);
1356: }
1357: }
1358: return (1);
1359: }
1360:
1361: account(argc,argv)
1362: int argc;
1363: char **argv;
1364: {
1365: char acct[50], *getpass(), *ap;
1366:
1367: if (argc > 1) {
1368: ++argv;
1369: --argc;
1370: (void) strncpy(acct,*argv,49);
1371: acct[49] = '\0';
1372: while (argc > 1) {
1373: --argc;
1374: ++argv;
1375: (void) strncat(acct,*argv, 49-strlen(acct));
1376: }
1377: ap = acct;
1378: }
1379: else {
1380: ap = getpass("Account:");
1381: }
1382: (void) command("ACCT %s", ap);
1383: }
1384:
1385: proxabort()
1386: {
1387: extern int proxy;
1388:
1389: if (!proxy) {
1390: pswitch(1);
1391: }
1392: if (connected) {
1393: proxflag = 1;
1394: }
1395: else {
1396: proxflag = 0;
1397: }
1398: pswitch(0);
1399: }
1400:
1401: doproxy(argc,argv)
1402: int argc;
1403: char *argv[];
1404: {
1405: register struct cmd *c;
1406: struct cmd *getcmd();
1407: extern struct cmd cmdtab[];
1408:
1409: if (argc < 2) {
1410: (void) strcat(line, " ");
1411: printf("(command) ");
1412: safegets(&line[strlen(line)], sizeof(line)-strlen(line));
1413: makeargv();
1414: argc = margc;
1415: argv = margv;
1416: }
1417: if (argc < 2) {
1418: printf("usage:%s command\n", argv[0]);
1419: code = -1;
1420: return;
1421: }
1422: c = getcmd(argv[1]);
1423: if (c == (struct cmd *) -1) {
1424: printf("?Ambiguous command\n");
1425: (void) fflush(stdout);
1426: code = -1;
1427: return;
1428: }
1429: if (c == 0) {
1430: printf("?Invalid command\n");
1431: (void) fflush(stdout);
1432: code = -1;
1433: return;
1434: }
1435: if (!c->c_proxy) {
1436: printf("?Invalid proxy command\n");
1437: (void) fflush(stdout);
1438: code = -1;
1439: return;
1440: }
1441: pswitch(1);
1442: if (c->c_conn && !connected) {
1443: printf("Not connected\n");
1444: (void) fflush(stdout);
1445: pswitch(0);
1446: code = -1;
1447: return;
1448: }
1449: (*c->c_handler)(argc-1, argv+1);
1450: if (connected) {
1451: proxflag = 1;
1452: }
1453: else {
1454: proxflag = 0;
1455: }
1456: pswitch(0);
1457: }
1458:
1459: setcase()
1460: {
1461: mcase = !mcase;
1462: printf("Case mapping %s.\n", onoff(mcase));
1463: code = mcase;
1464: }
1465:
1466: setcr()
1467: {
1468: crflag = !crflag;
1469: printf("Carriage Return stripping %s.\n", onoff(crflag));
1470: code = crflag;
1471: }
1472:
1473: setntrans(argc,argv)
1474: int argc;
1475: char *argv[];
1476: {
1477: if (argc == 1) {
1478: ntflag = 0;
1479: printf("Ntrans off.\n");
1480: code = ntflag;
1481: return;
1482: }
1483: ntflag++;
1484: code = ntflag;
1485: (void) strncpy(ntin, argv[1], 16);
1486: ntin[16] = '\0';
1487: if (argc == 2) {
1488: ntout[0] = '\0';
1489: return;
1490: }
1491: (void) strncpy(ntout, argv[2], 16);
1492: ntout[16] = '\0';
1493: }
1494:
1495: char *
1496: dotrans(name)
1497: char *name;
1498: {
1499: static char new[MAXPATHLEN];
1500: char *cp1, *cp2 = new;
1501: register int i, ostop, found;
1502:
1503: for (ostop = 0; *(ntout + ostop) && ostop < 16; ostop++);
1504: for (cp1 = name; *cp1; cp1++) {
1505: found = 0;
1506: for (i = 0; *(ntin + i) && i < 16; i++) {
1507: if (*cp1 == *(ntin + i)) {
1508: found++;
1509: if (i < ostop) {
1510: *cp2++ = *(ntout + i);
1511: }
1512: break;
1513: }
1514: }
1515: if (!found) {
1516: *cp2++ = *cp1;
1517: }
1518: }
1519: *cp2 = '\0';
1520: return(new);
1521: }
1522:
1523: setnmap(argc, argv)
1524: int argc;
1525: char *argv[];
1526: {
1527: char *cp;
1528:
1529: if (argc == 1) {
1530: mapflag = 0;
1531: printf("Nmap off.\n");
1532: code = mapflag;
1533: return;
1534: }
1535: if (argc < 3) {
1536: (void) strcat(line, " ");
1537: printf("(mapout) ");
1538: safegets(&line[strlen(line)], sizeof(line)-strlen(line));
1539: makeargv();
1540: argc = margc;
1541: argv = margv;
1542: }
1543: if (argc < 3) {
1544: printf("Usage: %s [mapin mapout]\n",argv[0]);
1545: code = -1;
1546: return;
1547: }
1548: mapflag = 1;
1549: code = 1;
1550: cp = strchr(altarg, ' ');
1551: if (proxy) {
1552: while(*++cp == ' ');
1553: altarg = cp;
1554: cp = strchr(altarg, ' ');
1555: }
1556: *cp = '\0';
1557: (void) strncpy(mapin, altarg, MAXPATHLEN - 1);
1558: while (*++cp == ' ');
1559: (void) strncpy(mapout, cp, MAXPATHLEN - 1);
1560: }
1561:
1562: char *
1563: domap(name)
1564: char *name;
1565: {
1566: static char new[MAXPATHLEN];
1567: register char *cp1 = name, *cp2 = mapin;
1568: char *tp[9], *te[9];
1569: int i, toks[9], toknum = 0, match = 1;
1570:
1571: for (i=0; i < 9; ++i) {
1572: toks[i] = 0;
1573: }
1574: while (match && *cp1 && *cp2) {
1575: switch (*cp2) {
1576: case '\\':
1577: if (*++cp2 != *cp1) {
1578: match = 0;
1579: }
1580: break;
1581: case '$':
1582: if (*(cp2+1) >= '1' && (*cp2+1) <= '9') {
1583: if (*cp1 != *(++cp2+1)) {
1584: toks[toknum = *cp2 - '1']++;
1585: tp[toknum] = cp1;
1586: while (*++cp1 && *(cp2+1)
1587: != *cp1);
1588: te[toknum] = cp1;
1589: }
1590: cp2++;
1591: break;
1592: }
1593: /* FALLTHROUGH */
1594: default:
1595: if (*cp2 != *cp1) {
1596: match = 0;
1597: }
1598: break;
1599: }
1600: if (match && *cp1) {
1601: cp1++;
1602: }
1603: if (match && *cp2) {
1604: cp2++;
1605: }
1606: }
1607: if (!match && *cp1) /* last token mismatch */
1608: {
1609: toks[toknum] = 0;
1610: }
1611: cp1 = new;
1612: *cp1 = '\0';
1613: cp2 = mapout;
1614: while (*cp2) {
1615: match = 0;
1616: switch (*cp2) {
1617: case '\\':
1618: if (*(cp2 + 1)) {
1619: *cp1++ = *++cp2;
1620: }
1621: break;
1622: case '[':
1623: LOOP:
1624: if (*++cp2 == '$' && isdigit(*(cp2+1))) {
1625: if (*++cp2 == '0') {
1626: char *cp3 = name;
1627:
1628: while (*cp3) {
1629: *cp1++ = *cp3++;
1630: }
1631: match = 1;
1632: }
1633: else if (toks[toknum = *cp2 - '1']) {
1634: char *cp3 = tp[toknum];
1635:
1636: while (cp3 != te[toknum]) {
1637: *cp1++ = *cp3++;
1638: }
1639: match = 1;
1640: }
1641: }
1642: else {
1643: while (*cp2 && *cp2 != ',' &&
1644: *cp2 != ']') {
1645: if (*cp2 == '\\') {
1646: cp2++;
1647: }
1648: else if (*cp2 == '$' &&
1649: isdigit(*(cp2+1))) {
1650: if (*++cp2 == '0') {
1651: char *cp3 = name;
1652:
1653: while (*cp3) {
1654: *cp1++ = *cp3++;
1655: }
1656: }
1657: else if (toks[toknum =
1658: *cp2 - '1']) {
1659: char *cp3=tp[toknum];
1660:
1661: while (cp3 !=
1662: te[toknum]) {
1663: *cp1++ = *cp3++;
1664: }
1665: }
1666: }
1667: else if (*cp2) {
1668: *cp1++ = *cp2++;
1669: }
1670: }
1671: if (!*cp2) {
1672: printf("nmap: unbalanced brackets\n");
1673: return(name);
1674: }
1675: match = 1;
1676: cp2--;
1677: }
1678: if (match) {
1679: while (*++cp2 && *cp2 != ']') {
1680: if (*cp2 == '\\' && *(cp2 + 1)) {
1681: cp2++;
1682: }
1683: }
1684: if (!*cp2) {
1685: printf("nmap: unbalanced brackets\n");
1686: return(name);
1687: }
1688: break;
1689: }
1690: switch (*++cp2) {
1691: case ',':
1692: goto LOOP;
1693: case ']':
1694: break;
1695: default:
1696: cp2--;
1697: goto LOOP;
1698: }
1699: break;
1700: case '$':
1701: if (isdigit(*(cp2 + 1))) {
1702: if (*++cp2 == '0') {
1703: char *cp3 = name;
1704:
1705: while (*cp3) {
1706: *cp1++ = *cp3++;
1707: }
1708: }
1709: else if (toks[toknum = *cp2 - '1']) {
1710: char *cp3 = tp[toknum];
1711:
1712: while (cp3 != te[toknum]) {
1713: *cp1++ = *cp3++;
1714: }
1715: }
1716: break;
1717: }
1718: /* intentional drop through */
1719: default:
1720: *cp1++ = *cp2;
1721: break;
1722: }
1723: cp2++;
1724: }
1725: *cp1 = '\0';
1726: if (!*new) {
1727: return(name);
1728: }
1729: return(new);
1730: }
1731:
1732: setsunique()
1733: {
1734: sunique = !sunique;
1735: printf("Store unique %s.\n", onoff(sunique));
1736: code = sunique;
1737: }
1738:
1739: setrunique()
1740: {
1741: runique = !runique;
1742: printf("Receive unique %s.\n", onoff(runique));
1743: code = runique;
1744: }
1745:
1746: /* change directory to perent directory */
1747: cdup()
1748: {
1749: (void) command("CDUP");
1750: }
1751:
1752:
1753: /* show remote system type */
1754: syst()
1755: {
1756: (void) command("SYST");
1757: }
1758:
1759: macdef(argc, argv)
1760: int argc;
1761: char *argv[];
1762: {
1763: char *tmp;
1764: int c;
1765:
1766: if (macnum == 16) {
1767: printf("Limit of 16 macros have already been defined\n");
1768: code = -1;
1769: return;
1770: }
1771: if (argc < 2) {
1772: (void) strcat(line, " ");
1773: printf("(macro name) ");
1774: safegets(&line[strlen(line)], sizeof(line)-strlen(line));
1775: makeargv();
1776: argc = margc;
1777: argv = margv;
1778: }
1779: if (argc != 2) {
1780: printf("Usage: %s macro_name\n",argv[0]);
1781: code = -1;
1782: return;
1783: }
1784: if (interactive) {
1785: printf("Enter macro line by line, terminating it with a null line\n");
1786: }
1787: (void) strncpy(macros[macnum].mac_name, argv[1], 8);
1788: if (macnum == 0) {
1789: macros[macnum].mac_start = macbuf;
1790: }
1791: else {
1792: macros[macnum].mac_start = macros[macnum - 1].mac_end + 1;
1793: }
1794: tmp = macros[macnum].mac_start;
1795: while (tmp != macbuf+4096) {
1796: if ((c = getchar()) == EOF) {
1797: printf("macdef:end of file encountered\n");
1798: code = -1;
1799: return;
1800: }
1801: if ((*tmp = c) == '\n') {
1802: if (tmp == macros[macnum].mac_start) {
1803: macros[macnum++].mac_end = tmp;
1804: code = 0;
1805: return;
1806: }
1807: if (*(tmp-1) == '\0') {
1808: macros[macnum++].mac_end = tmp - 1;
1809: code = 0;
1810: return;
1811: }
1812: *tmp = '\0';
1813: }
1814: tmp++;
1815: }
1816: while (1) {
1817: while ((c = getchar()) != '\n' && c != EOF)
1818: /* LOOP */;
1819: if (c == EOF || getchar() == '\n') {
1820: printf("Macro not defined - 4k buffer exceeded\n");
1821: code = -1;
1822: return;
1823: }
1824: }
1825: }
1826:
1827: /*
1828: * get size of file on remote machine
1829: */
1830: sizecmd(argc, argv)
1831: char *argv[];
1832: {
1833:
1834: if (argc < 2) {
1835: (void) strcat(line, " ");
1836: printf("(filename) ");
1837: safegets(&line[strlen(line)], sizeof(line)-strlen(line));
1838: makeargv();
1839: argc = margc;
1840: argv = margv;
1841: }
1842: if (argc < 2) {
1843: printf("usage:%s filename\n", argv[0]);
1844: code = -1;
1845: return;
1846: }
1847: (void) command("SIZE %s", argv[1]);
1848: }
1849:
1850: /*
1851: * get last modification time of file on remote machine
1852: */
1853: modtime(argc, argv)
1854: char *argv[];
1855: {
1856: int overbose;
1857:
1858: if (argc < 2) {
1859: (void) strcat(line, " ");
1860: printf("(filename) ");
1861: safegets(&line[strlen(line)], sizeof(line)-strlen(line));
1862: makeargv();
1863: argc = margc;
1864: argv = margv;
1865: }
1866: if (argc < 2) {
1867: printf("usage:%s filename\n", argv[0]);
1868: code = -1;
1869: return;
1870: }
1871: overbose = verbose;
1872: if (debug == 0)
1873: verbose = -1;
1874: if (command("MDTM %s", argv[1]) == COMPLETE) {
1875: int yy, mo, day, hour, min, sec;
1876: sscanf(reply_string, "%*s %04d%02d%02d%02d%02d%02d", &yy, &mo,
1877: &day, &hour, &min, &sec);
1878: /* might want to print this in local time */
1879: printf("%s\t%02d/%02d/%04d %02d:%02d:%02d GMT\n", argv[1],
1880: mo, day, yy, hour, min, sec);
1881: } else
1882: fputs(reply_string, stdout);
1883: verbose = overbose;
1884: }
1885:
1886: /*
1887: * show status on remote machine
1888: */
1889: rmtstatus(argc, argv)
1890: char *argv[];
1891: {
1892: (void) command(argc > 1 ? "STAT %s" : "STAT" , argv[1]);
1893: }
1894:
1895:
1896: /*
1897: * a safe version of gets
1898: */
1899: safegets(bp, n)
1900: char *bp;
1901: int n;
1902: {
1903: char *cp;
1904:
1905: if(fgets(bp, n, stdin)==NULL)
1906: return NULL;
1907: for(cp=bp; *cp; cp++)
1908: if(*cp=='\r' || *cp =='\n'){
1909: *cp = 0;
1910: break;
1911: }
1912: return bp;
1913: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.