|
|
1.1 root 1: /*
2: * FTP User Program -- Command Routines.
3: */
4: #include <sys/types.h>
5: #include <signal.h>
6: #include <stdio.h>
7: #include <errno.h>
8: #include "ftp.h"
9: #include "ftp_var.h"
10: #include <pwd.h>
11:
12: int autologin = 1;
13:
14: /*
15: * Connect to peer server and
16: * auto-login, if possible.
17: */
18: setpeer(argc, argv)
19: int argc;
20: char *argv[];
21: {
22: char *host, *hookup();
23: int port;
24:
25: if (connected) {
26: printf("Already connected to %s, use disconnect first.\n",
27: hostname);
28: return;
29: }
30: if (argc < 2) {
31: strcat(line, " ");
32: printf("(to) ");
33: gets(&line[strlen(line)]);
34: makeargv();
35: argc = margc;
36: argv = margv;
37: }
38: if (argc > 3) {
39: printf("usage: %s host-name [port]\n", argv[0]);
40: return;
41: }
42: port = sp->port;
43: if (argc > 2) {
44: port = atoi(argv[2]);
45: if (port <= 0) {
46: printf("%s: bad port number-- %s\n", argv[1], argv[2]);
47: printf ("usage: %s host-name [port]\n", argv[0]);
48: return;
49: }
50: port = htons(port);
51: }
52: host = hookup(argv[1], port);
53: if (host) {
54: connected = 1;
55: if (autologin)
56: login(host);
57: }
58: }
59:
60: struct types {
61: char *t_name;
62: char *t_mode;
63: int t_type;
64: char *t_arg;
65: } types[] = {
66: { "ascii", "A", TYPE_A, 0 },
67: { "binary", "I", TYPE_I, 0 },
68: { "image", "I", TYPE_I, 0 },
69: { "ebcdic", "E", TYPE_E, 0 },
70: { "tenex", "L", TYPE_L, bytename },
71: 0
72: };
73:
74: /*
75: * Set transfer type.
76: */
77: settype(argc, argv)
78: char *argv[];
79: {
80: register struct types *p;
81: int comret;
82:
83: if (argc > 2) {
84: char *sep;
85:
86: printf("usage: %s [", argv[0]);
87: sep = " ";
88: for (p = types; p->t_name; p++) {
89: printf("%s%s", sep, p->t_name);
90: if (*sep == ' ')
91: sep = " | ";
92: }
93: printf(" ]\n");
94: return;
95: }
96: if (argc < 2) {
97: printf("Using %s mode to transfer files.\n", typename);
98: return;
99: }
100: for (p = types; p->t_name; p++)
101: if (strcmp(argv[1], p->t_name) == 0)
102: break;
103: if (p->t_name == 0) {
104: printf("%s: unknown mode\n", argv[1]);
105: return;
106: }
107: if ((p->t_arg != NULL) && (*(p->t_arg) != '\0'))
108: comret = command ("TYPE %s %s", p->t_mode, p->t_arg);
109: else
110: comret = command("TYPE %s", p->t_mode);
111: if (comret == COMPLETE) {
112: strcpy(typename, p->t_name);
113: type = p->t_type;
114: }
115: }
116:
117: /*
118: * Set binary transfer type.
119: */
120: /*VARARGS*/
121: setbinary()
122: {
123:
124: call(settype, "type", "binary", 0);
125: }
126:
127: /*
128: * Set ascii transfer type.
129: */
130: /*VARARGS*/
131: setascii()
132: {
133:
134: call(settype, "type", "ascii", 0);
135: }
136:
137: /*
138: * Set tenex transfer type.
139: */
140: /*VARARGS*/
141: settenex()
142: {
143:
144: call(settype, "type", "tenex", 0);
145: }
146:
147: /*
148: * Set ebcdic transfer type.
149: */
150: /*VARARGS*/
151: setebcdic()
152: {
153:
154: call(settype, "type", "ebcdic", 0);
155: }
156:
157: /*
158: * Set file transfer mode.
159: */
160: setmode(argc, argv)
161: char *argv[];
162: {
163:
164: printf("We only support %s mode, sorry.\n", modename);
165: }
166:
167: /*
168: * Set file transfer format.
169: */
170: setform(argc, argv)
171: char *argv[];
172: {
173:
174: printf("We only support %s format, sorry.\n", formname);
175: }
176:
177: /*
178: * Set file transfer structure.
179: */
180: setstruct(argc, argv)
181: char *argv[];
182: {
183:
184: printf("We only support %s structure, sorry.\n", structname);
185: }
186:
187: /*
188: * Send a single file.
189: */
190: put(argc, argv)
191: char *argv[];
192: {
193: int fd;
194: register int n, addr;
195: register char *cp, *targ;
196:
197: if (!connected) {
198: printf("Not connected.\n");
199: return;
200: }
201: if (argc == 2)
202: argc++, argv[2] = argv[1];
203: if (argc < 2) {
204: strcat(line, " ");
205: printf("(local-file) ");
206: gets(&line[strlen(line)]);
207: makeargv();
208: argc = margc;
209: argv = margv;
210: }
211: if (argc < 2) {
212: usage:
213: printf("%s local-file remote-file\n", argv[0]);
214: return;
215: }
216: if (argc < 3) {
217: strcat(line, " ");
218: printf("(remote-file) ");
219: gets(&line[strlen(line)]);
220: makeargv();
221: argc = margc;
222: argv = margv;
223: }
224: if (argc < 3)
225: goto usage;
226: sendrequest("STOR", argv[1], argv[2]);
227: }
228:
229: /*
230: * Receive a single file.
231: */
232: get(argc, argv)
233: char *argv[];
234: {
235: int fd;
236: register int n, addr;
237: register char *cp;
238: char *src;
239:
240: if (!connected) {
241: printf("Not connected.\n");
242: return;
243: }
244: if (argc == 2)
245: argc++, argv[2] = argv[1];
246: if (argc < 2) {
247: strcat(line, " ");
248: printf("(remote-file) ");
249: gets(&line[strlen(line)]);
250: makeargv();
251: argc = margc;
252: argv = margv;
253: }
254: if (argc < 2) {
255: usage:
256: printf("%s remote-file local-file\n", argv[0]);
257: return;
258: }
259: if (argc < 3) {
260: strcat(line, " ");
261: printf("(local-file) ");
262: gets(&line[strlen(line)]);
263: makeargv();
264: argc = margc;
265: argv = margv;
266: }
267: if (argc < 3)
268: goto usage;
269: recvrequest("RETR", argv[2], argv[1]);
270: }
271:
272: char *
273: onoff(bool)
274: int bool;
275: {
276:
277: return (bool ? "on" : "off");
278: }
279:
280: /*
281: * Show status.
282: */
283: status(argc, argv)
284: char *argv[];
285: {
286:
287: if (connected)
288: printf("Connected to %s.\n", hostname);
289: else
290: printf("Not connected.\n");
291: printf("Mode: %s; Type: %s; Form: %s; Structure: %s\n",
292: modename, typename, formname, structname);
293: printf("Verbose: %s; Bell: %s; Prompting: %s\n",
294: onoff(verbose), onoff(bell), onoff(interactive));
295: }
296:
297: /*
298: * Set beep on cmd completed mode.
299: */
300: /*VARARGS*/
301: setbell()
302: {
303:
304: bell = !bell;
305: printf("Bell mode %s.\n", onoff(bell));
306: }
307:
308: /*
309: * Turn on packet tracing.
310: */
311: /*VARARGS*/
312: settrace()
313: {
314:
315: trace = !trace;
316: printf("Packet tracing %s.\n", onoff(trace));
317: }
318:
319: /*
320: * Turn on printing of server echo's.
321: */
322: /*VARARGS*/
323: setverbose()
324: {
325:
326: verbose = !verbose;
327: printf("Verbose mode %s.\n", onoff(verbose));
328: }
329:
330: /*
331: * Turn on interactive prompting
332: * during mget, mput, and mdelete.
333: */
334: /*VARARGS*/
335: setprompt()
336: {
337:
338: interactive = !interactive;
339: printf("Interactive mode %s.\n", onoff(interactive));
340: }
341:
342: /*
343: * Set debugging mode on/off and/or
344: * set level of debugging.
345: */
346: /*VARARGS*/
347: setdebug(argc, argv)
348: char *argv[];
349: {
350: int val;
351:
352: if (argc > 1) {
353: val = atoi(argv[1]);
354: if (val < 0) {
355: printf("%s: bad debugging value.\n", argv[1]);
356: return;
357: }
358: } else
359: val = !debug;
360: debug = val;
361: printf("Debugging %s (debug=%d).\n", onoff(debug), debug);
362: }
363:
364: /*
365: * Set current working directory
366: * on remote machine.
367: */
368: cd(argc, argv)
369: char *argv[];
370: {
371:
372: if (!connected) {
373: printf("Not connected.\n");
374: return;
375: }
376: if (argc < 2) {
377: strcat(line, " ");
378: printf("(remote-directory) ");
379: gets(&line[strlen(line)]);
380: makeargv();
381: argc = margc;
382: argv = margv;
383: }
384: if (argc < 2) {
385: printf("%s remote-directory\n", argv[0]);
386: return;
387: }
388: (void) command("CWD %s", argv[1]);
389: }
390:
391: /*
392: * Set current working directory
393: * on local machine.
394: */
395: lcd(argc, argv)
396: char *argv[];
397: {
398: static struct passwd *pw = NULL;
399: struct passwd *getpwnam(), *getpwuid();
400:
401: if (argc < 2) {
402: if (pw == NULL) {
403: pw = getpwnam(getlogin());
404: if (pw == NULL)
405: pw = getpwuid(getuid());
406: }
407: if (pw == NULL) {
408: printf("ftp: can't find home directory.\n");
409: return;
410: }
411: argc++, argv[1] = pw->pw_dir;
412: }
413: if (argc != 2) {
414: printf("%s local-directory\n", argv[0]);
415: return;
416: }
417: if (chdir(argv[1]) < 0)
418: perror(argv[1]);
419: }
420:
421: /*
422: * Delete a single file.
423: */
424: delete(argc, argv)
425: char *argv[];
426: {
427:
428: if (argc < 2) {
429: strcat(line, " ");
430: printf("(remote-file) ");
431: gets(&line[strlen(line)]);
432: makeargv();
433: argc = margc;
434: argv = margv;
435: }
436: if (argc < 2) {
437: printf("%s remote-file\n", argv[0]);
438: return;
439: }
440: (void) command("DELE %s", argv[1]);
441: }
442:
443: /*
444: * Rename a remote file.
445: */
446: renamefile(argc, argv)
447: char *argv[];
448: {
449:
450: if (argc < 2) {
451: strcat(line, " ");
452: printf("(from-name) ");
453: gets(&line[strlen(line)]);
454: makeargv();
455: argc = margc;
456: argv = margv;
457: }
458: if (argc < 2) {
459: usage:
460: printf("%s from-name to-name\n", argv[0]);
461: return;
462: }
463: if (argc < 3) {
464: strcat(line, " ");
465: printf("(to-name) ");
466: gets(&line[strlen(line)]);
467: makeargv();
468: argc = margc;
469: argv = margv;
470: }
471: if (argc < 3)
472: goto usage;
473: if (command("RNFR %s", argv[1]) == CONTINUE)
474: (void) command("RNTO %s", argv[2]);
475: }
476:
477: /*
478: * Get a directory listing
479: * of remote files.
480: */
481: ls(argc, argv)
482: char *argv[];
483: {
484: char *cmd;
485:
486: if (argc < 2)
487: argc++, argv[1] = NULL;
488: if (argc < 3)
489: argc++, argv[2] = "-";
490: if (argc > 3) {
491: printf("usage: %s remote-directory local-file\n", argv[0]);
492: return;
493: }
494: cmd = argv[0][0] == 'l' ? "NLST" : "LIST";
495: recvrequest(cmd, argv[2], argv[1]);
496: }
497:
498: /*
499: * Do a shell escape
500: */
501: shell(argc, argv)
502: char *argv[];
503: {
504:
505: printf("Sorry, this function is unimplemented.\n");
506: }
507:
508: /*
509: * Send new user information (re-login)
510: */
511: user(argc, argv)
512: int argc;
513: char **argv;
514: {
515: char acct[80], *getpass();
516: int n;
517:
518: if (argc < 2) {
519: strcat(line, " ");
520: printf("(username) ");
521: gets(&line[strlen(line)]);
522: makeargv();
523: argc = margc;
524: argv = margv;
525: }
526: if (argc > 4) {
527: printf("usage: %s username [password] [account]\n", argv[0]);
528: return;
529: }
530: n = command("USER %s", argv[1]);
531: if (n == CONTINUE) {
532: if (argc < 3 )
533: argv[2] = getpass("Password: "), argc++;
534: n = command("PASS %s", argv[2]);
535: }
536: if (n == CONTINUE) {
537: if (argc < 4) {
538: printf("Account: "); (void) fflush(stdout);
539: (void) fgets(acct, sizeof(acct) - 1, stdin);
540: acct[strlen(acct) - 1] = '\0';
541: argv[3] = acct; argc++;
542: }
543: n = command("ACCT %s", acct);
544: }
545: if (n != COMPLETE) {
546: fprintf(stderr, "Login failed.\n");
547: return (0);
548: }
549: return (1);
550: }
551:
552: /*
553: * Print working directory.
554: */
555: /*VARARGS*/
556: pwd()
557: {
558: if (!connected) {
559: printf("Not connected.\n");
560: return;
561: }
562: (void) command("XPWD");
563: }
564:
565: /*
566: * Make a directory.
567: */
568: makedir(argc, argv)
569: char *argv[];
570: {
571:
572: if (argc < 2) {
573: strcat(line, " ");
574: printf("(directory-name) ");
575: gets(&line[strlen(line)]);
576: makeargv();
577: argc = margc;
578: argv = margv;
579: }
580: if (argc < 2) {
581: printf("%s directory-name\n", argv[0]);
582: return;
583: }
584: (void) command("XMKD %s", argv[1]);
585: }
586:
587: /*
588: * Remove a directory.
589: */
590: removedir(argc, argv)
591: char *argv[];
592: {
593:
594: if (argc < 2) {
595: strcat(line, " ");
596: printf("(directory-name) ");
597: gets(&line[strlen(line)]);
598: makeargv();
599: argc = margc;
600: argv = margv;
601: }
602: if (argc < 2) {
603: printf("%s directory-name\n", argv[0]);
604: return;
605: }
606: (void) command("XRMD %s", argv[1]);
607: }
608:
609: /*
610: * Send a line, verbatim, to the remote machine.
611: */
612: quote(argc, argv)
613: char *argv[];
614: {
615: int i;
616: char buf[BUFSIZ];
617:
618: if (argc < 2) {
619: strcat(line, " ");
620: printf("(command line to send) ");
621: gets(&line[strlen(line)]);
622: makeargv();
623: argc = margc;
624: argv = margv;
625: }
626: if (argc < 2) {
627: printf("usage: %s line-to-send\n", argv[0]);
628: return;
629: }
630: strcpy(buf, argv[1]);
631: for (i = 2; i < argc; i++) {
632: strcat(buf, " ");
633: strcat(buf, argv[i]);
634: }
635: (void) command(buf);
636: }
637:
638: /*
639: * Ask the other side for help.
640: */
641: rmthelp(argc, argv)
642: char *argv[];
643: {
644: int oldverbose = verbose;
645:
646: verbose = 1;
647: (void) command(argc == 1 ? "HELP" : "HELP %s", argv[1]);
648: verbose = oldverbose;
649: }
650:
651: /*
652: * Terminate session and exit.
653: */
654: /*VARARGS*/
655: quit()
656: {
657:
658: disconnect();
659: exit(0);
660: }
661:
662: /*
663: * Terminate session, but don't exit.
664: */
665: disconnect()
666: {
667: extern FILE *cout;
668: extern int data;
669:
670: if (!connected)
671: return;
672: (void) command("QUIT");
673: (void) fclose(cout);
674: cout = NULL;
675: connected = 0;
676: data = -1;
677: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.