Annotation of src/usr.bin/ftp/cmds.c, Revision 1.79
1.79 ! lukem 1: /* $NetBSD: cmds.c,v 1.78 1999/11/09 22:03:49 lukem Exp $ */
1.39 thorpej 2:
3: /*-
1.70 lukem 4: * Copyright (c) 1996-1999 The NetBSD Foundation, Inc.
1.39 thorpej 5: * All rights reserved.
6: *
7: * This code is derived from software contributed to The NetBSD Foundation
1.70 lukem 8: * by Luke Mewburn.
9: *
10: * This code is derived from software contributed to The NetBSD Foundation
1.39 thorpej 11: * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
12: * NASA Ames Research Center.
13: *
14: * Redistribution and use in source and binary forms, with or without
15: * modification, are permitted provided that the following conditions
16: * are met:
17: * 1. Redistributions of source code must retain the above copyright
18: * notice, this list of conditions and the following disclaimer.
19: * 2. Redistributions in binary form must reproduce the above copyright
20: * notice, this list of conditions and the following disclaimer in the
21: * documentation and/or other materials provided with the distribution.
22: * 3. All advertising materials mentioning features or use of this software
23: * must display the following acknowledgement:
24: * This product includes software developed by the NetBSD
25: * Foundation, Inc. and its contributors.
26: * 4. Neither the name of The NetBSD Foundation nor the names of its
27: * contributors may be used to endorse or promote products derived
28: * from this software without specific prior written permission.
29: *
30: * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
31: * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
32: * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
33: * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
34: * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
35: * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
36: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
37: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
38: * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
39: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
40: * POSSIBILITY OF SUCH DAMAGE.
41: */
1.8 tls 42:
1.1 cgd 43: /*
1.4 cgd 44: * Copyright (c) 1985, 1989, 1993, 1994
45: * The Regents of the University of California. All rights reserved.
1.1 cgd 46: *
47: * Redistribution and use in source and binary forms, with or without
48: * modification, are permitted provided that the following conditions
49: * are met:
50: * 1. Redistributions of source code must retain the above copyright
51: * notice, this list of conditions and the following disclaimer.
52: * 2. Redistributions in binary form must reproduce the above copyright
53: * notice, this list of conditions and the following disclaimer in the
54: * documentation and/or other materials provided with the distribution.
55: * 3. All advertising materials mentioning features or use of this software
56: * must display the following acknowledgement:
57: * This product includes software developed by the University of
58: * California, Berkeley and its contributors.
59: * 4. Neither the name of the University nor the names of its contributors
60: * may be used to endorse or promote products derived from this software
61: * without specific prior written permission.
62: *
63: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
64: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
65: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
66: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
67: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
68: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
69: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
70: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
71: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
72: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
73: * SUCH DAMAGE.
74: */
75:
1.65 lukem 76: /*
77: * Copyright (C) 1997 and 1998 WIDE Project.
78: * All rights reserved.
79: *
80: * Redistribution and use in source and binary forms, with or without
81: * modification, are permitted provided that the following conditions
82: * are met:
83: * 1. Redistributions of source code must retain the above copyright
84: * notice, this list of conditions and the following disclaimer.
85: * 2. Redistributions in binary form must reproduce the above copyright
86: * notice, this list of conditions and the following disclaimer in the
87: * documentation and/or other materials provided with the distribution.
88: * 3. Neither the name of the project nor the names of its contributors
89: * may be used to endorse or promote products derived from this software
90: * without specific prior written permission.
91: *
92: * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
93: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
94: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
95: * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
96: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
97: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
98: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
99: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
100: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
101: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
102: * SUCH DAMAGE.
103: */
104:
1.25 lukem 105: #include <sys/cdefs.h>
1.1 cgd 106: #ifndef lint
1.8 tls 107: #if 0
108: static char sccsid[] = "@(#)cmds.c 8.6 (Berkeley) 10/9/94";
109: #else
1.79 ! lukem 110: __RCSID("$NetBSD: cmds.c,v 1.78 1999/11/09 22:03:49 lukem Exp $");
1.8 tls 111: #endif
1.1 cgd 112: #endif /* not lint */
113:
114: /*
115: * FTP User Program -- Command Routines.
116: */
1.16 lukem 117: #include <sys/types.h>
118: #include <sys/socket.h>
119: #include <sys/stat.h>
1.1 cgd 120: #include <sys/wait.h>
121: #include <arpa/ftp.h>
122:
1.4 cgd 123: #include <ctype.h>
124: #include <err.h>
125: #include <glob.h>
1.42 lukem 126: #include <limits.h>
1.4 cgd 127: #include <netdb.h>
1.67 lukem 128: #include <paths.h>
1.1 cgd 129: #include <stdio.h>
1.4 cgd 130: #include <stdlib.h>
131: #include <string.h>
1.35 kleink 132: #include <time.h>
1.4 cgd 133: #include <unistd.h>
1.1 cgd 134:
135: #include "ftp_var.h"
136:
137: struct types {
138: char *t_name;
139: char *t_mode;
140: int t_type;
141: char *t_arg;
142: } types[] = {
143: { "ascii", "A", TYPE_A, 0 },
144: { "binary", "I", TYPE_I, 0 },
145: { "image", "I", TYPE_I, 0 },
146: { "ebcdic", "E", TYPE_E, 0 },
147: { "tenex", "L", TYPE_L, bytename },
1.4 cgd 148: { NULL }
1.1 cgd 149: };
150:
1.74 lukem 151: sigjmp_buf jabort;
152: char *mname;
153:
154: static int confirm __P((const char *, const char *));
155:
156: static int
157: confirm(cmd, file)
158: const char *cmd, *file;
159: {
160: char line[BUFSIZ];
161:
162: if (!interactive || confirmrest)
163: return (1);
164: while (1) {
165: fprintf(ttyout, "%s %s [anpqy?]? ", cmd, file);
166: (void)fflush(ttyout);
167: if (fgets(line, sizeof(line), stdin) == NULL) {
168: mflag = 0;
169: fprintf(ttyout, "\nEOF received; %s aborted\n", mname);
170: clearerr(stdin);
171: return (0);
172: }
173: switch (tolower(*line)) {
174: case 'a':
175: confirmrest = 1;
176: fprintf(ttyout,
177: "Prompting off for duration of %s.\n", cmd);
178: break;
179: case 'p':
180: interactive = 0;
181: fputs("Interactive mode: off.\n", ttyout);
182: break;
183: case 'q':
184: mflag = 0;
1.76 lukem 185: fprintf(ttyout, "%s aborted.\n", mname);
1.75 lukem 186: /* FALLTHROUGH */
187: case 'n':
1.74 lukem 188: return (0);
189: case '?':
190: fprintf(ttyout,
1.76 lukem 191: " confirmation options:\n"
1.74 lukem 192: "\ta answer `yes' for the duration of %s\n"
193: "\tn answer `no' for this file\n"
194: "\tp turn off `prompt' mode\n"
195: "\tq stop the current %s\n"
196: "\ty answer `yes' for this file\n"
197: "\t? this help list\n",
198: cmd, cmd);
1.75 lukem 199: continue; /* back to while(1) */
1.74 lukem 200: }
1.75 lukem 201: return (1);
1.74 lukem 202: }
203: /* NOTREACHED */
204: }
205:
1.1 cgd 206: /*
207: * Set transfer type.
208: */
1.4 cgd 209: void
1.1 cgd 210: settype(argc, argv)
211: int argc;
212: char *argv[];
213: {
1.4 cgd 214: struct types *p;
1.1 cgd 215: int comret;
216:
1.76 lukem 217: if ((argc == 0 && argv != NULL) || argc > 2) {
1.1 cgd 218: char *sep;
219:
1.37 lukem 220: fprintf(ttyout, "usage: %s [", argv[0]);
1.1 cgd 221: sep = " ";
222: for (p = types; p->t_name; p++) {
1.37 lukem 223: fprintf(ttyout, "%s%s", sep, p->t_name);
1.1 cgd 224: sep = " | ";
225: }
1.37 lukem 226: fputs(" ]\n", ttyout);
1.1 cgd 227: code = -1;
228: return;
229: }
230: if (argc < 2) {
1.37 lukem 231: fprintf(ttyout, "Using %s mode to transfer files.\n", typename);
1.1 cgd 232: code = 0;
233: return;
234: }
235: for (p = types; p->t_name; p++)
236: if (strcmp(argv[1], p->t_name) == 0)
237: break;
238: if (p->t_name == 0) {
1.37 lukem 239: fprintf(ttyout, "%s: unknown mode.\n", argv[1]);
1.1 cgd 240: code = -1;
241: return;
242: }
243: if ((p->t_arg != NULL) && (*(p->t_arg) != '\0'))
1.19 lukem 244: comret = command("TYPE %s %s", p->t_mode, p->t_arg);
1.1 cgd 245: else
246: comret = command("TYPE %s", p->t_mode);
247: if (comret == COMPLETE) {
1.63 lukem 248: (void)strlcpy(typename, p->t_name, sizeof(typename));
1.1 cgd 249: curtype = type = p->t_type;
250: }
251: }
252:
253: /*
254: * Internal form of settype; changes current type in use with server
255: * without changing our notion of the type for data transfers.
256: * Used to change to and from ascii for listings.
257: */
1.4 cgd 258: void
1.1 cgd 259: changetype(newtype, show)
260: int newtype, show;
261: {
1.4 cgd 262: struct types *p;
1.1 cgd 263: int comret, oldverbose = verbose;
264:
265: if (newtype == 0)
266: newtype = TYPE_I;
267: if (newtype == curtype)
268: return;
269: if (debug == 0 && show == 0)
270: verbose = 0;
271: for (p = types; p->t_name; p++)
272: if (newtype == p->t_type)
273: break;
274: if (p->t_name == 0) {
1.19 lukem 275: warnx("internal error: unknown type %d.", newtype);
1.1 cgd 276: return;
277: }
278: if (newtype == TYPE_L && bytename[0] != '\0')
279: comret = command("TYPE %s %s", p->t_mode, bytename);
280: else
281: comret = command("TYPE %s", p->t_mode);
282: if (comret == COMPLETE)
283: curtype = newtype;
284: verbose = oldverbose;
285: }
286:
287: char *stype[] = {
288: "type",
289: "",
290: 0
291: };
292:
293: /*
294: * Set binary transfer type.
295: */
296: /*VARARGS*/
1.4 cgd 297: void
298: setbinary(argc, argv)
299: int argc;
1.10 lukem 300: char *argv[];
1.1 cgd 301: {
1.4 cgd 302:
1.76 lukem 303: if (argc == 0 && argv != NULL) {
304: fprintf(ttyout, "usage: %s\n", argv[0]);
305: code = -1;
306: return;
307: }
1.1 cgd 308: stype[1] = "binary";
309: settype(2, stype);
310: }
311:
312: /*
313: * Set ascii transfer type.
314: */
315: /*VARARGS*/
1.4 cgd 316: void
317: setascii(argc, argv)
318: int argc;
319: char *argv[];
1.1 cgd 320: {
1.4 cgd 321:
1.76 lukem 322: if (argc == 0 && argv != NULL) {
323: fprintf(ttyout, "usage: %s\n", argv[0]);
324: code = -1;
325: return;
326: }
1.1 cgd 327: stype[1] = "ascii";
328: settype(2, stype);
329: }
330:
331: /*
332: * Set tenex transfer type.
333: */
334: /*VARARGS*/
1.4 cgd 335: void
336: settenex(argc, argv)
337: int argc;
338: char *argv[];
1.1 cgd 339: {
1.4 cgd 340:
1.76 lukem 341: if (argc == 0 && argv != NULL) {
342: fprintf(ttyout, "usage: %s\n", argv[0]);
343: code = -1;
344: return;
345: }
1.1 cgd 346: stype[1] = "tenex";
347: settype(2, stype);
348: }
349:
350: /*
351: * Set file transfer mode.
352: */
353: /*ARGSUSED*/
1.4 cgd 354: void
355: setftmode(argc, argv)
1.1 cgd 356: int argc;
357: char *argv[];
358: {
359:
1.76 lukem 360: if ((argc == 0 && argv != NULL) || argc != 2) {
361: fprintf(ttyout, "usage: %s mode-name\n", argv[0]);
362: code = -1;
363: return;
364: }
1.37 lukem 365: fprintf(ttyout, "We only support %s mode, sorry.\n", modename);
1.1 cgd 366: code = -1;
367: }
368:
369: /*
370: * Set file transfer format.
371: */
372: /*ARGSUSED*/
1.4 cgd 373: void
1.1 cgd 374: setform(argc, argv)
375: int argc;
376: char *argv[];
377: {
378:
1.76 lukem 379: if ((argc == 0 && argv != NULL) || argc != 2) {
380: fprintf(ttyout, "usage: %s format\n", argv[0]);
381: code = -1;
382: return;
383: }
1.37 lukem 384: fprintf(ttyout, "We only support %s format, sorry.\n", formname);
1.1 cgd 385: code = -1;
386: }
387:
388: /*
389: * Set file transfer structure.
390: */
391: /*ARGSUSED*/
1.4 cgd 392: void
1.1 cgd 393: setstruct(argc, argv)
394: int argc;
395: char *argv[];
396: {
397:
1.76 lukem 398: if ((argc == 0 && argv != NULL) || argc != 2) {
399: fprintf(ttyout, "usage: %s struct-mode\n", argv[0]);
400: code = -1;
401: return;
402: }
1.37 lukem 403: fprintf(ttyout, "We only support %s structure, sorry.\n", structname);
1.1 cgd 404: code = -1;
405: }
406:
407: /*
408: * Send a single file.
409: */
1.4 cgd 410: void
1.1 cgd 411: put(argc, argv)
412: int argc;
413: char *argv[];
414: {
415: char *cmd;
416: int loc = 0;
1.63 lukem 417: char *locfile, *remfile;
1.1 cgd 418:
419: if (argc == 2) {
420: argc++;
421: argv[2] = argv[1];
422: loc++;
423: }
1.76 lukem 424: if ((argc == 0 && argv != NULL) ||
425: (argc == 1 && !another(&argc, &argv, "local-file")))
1.1 cgd 426: goto usage;
1.10 lukem 427: if ((argc < 3 && !another(&argc, &argv, "remote-file")) || argc > 3) {
1.1 cgd 428: usage:
1.76 lukem 429: fprintf(ttyout, "usage: %s local-file [remote-file]\n",
1.37 lukem 430: argv[0]);
1.1 cgd 431: code = -1;
432: return;
433: }
1.63 lukem 434: if ((locfile = globulize(argv[1])) == NULL) {
1.1 cgd 435: code = -1;
436: return;
437: }
1.63 lukem 438: remfile = argv[2];
439: if (loc) /* If argv[2] is a copy of the old argv[1], update it */
440: remfile = locfile;
1.1 cgd 441: cmd = (argv[0][0] == 'a') ? "APPE" : ((sunique) ? "STOU" : "STOR");
1.63 lukem 442: if (loc && ntflag)
443: remfile = dotrans(remfile);
444: if (loc && mapflag)
445: remfile = domap(remfile);
446: sendrequest(cmd, locfile, remfile,
447: locfile != argv[1] || remfile != argv[2]);
448: free(locfile);
1.1 cgd 449: }
450:
451: /*
452: * Send multiple files.
453: */
1.4 cgd 454: void
1.1 cgd 455: mput(argc, argv)
456: int argc;
1.10 lukem 457: char *argv[];
1.1 cgd 458: {
1.4 cgd 459: int i;
1.1 cgd 460: sig_t oldintr;
461: int ointer;
462: char *tp;
463:
1.76 lukem 464: if ((argc == 0 && argv != NULL) ||
465: (argc == 1 && !another(&argc, &argv, "local-files"))) {
1.37 lukem 466: fprintf(ttyout, "usage: %s local-files\n", argv[0]);
1.1 cgd 467: code = -1;
468: return;
469: }
470: mname = argv[0];
471: mflag = 1;
1.72 lukem 472: oldintr = xsignal(SIGINT, mintr);
473: if (sigsetjmp(jabort, 1))
474: mabort();
1.1 cgd 475: if (proxy) {
1.63 lukem 476: char *cp;
1.1 cgd 477:
1.19 lukem 478: while ((cp = remglob(argv, 0, NULL)) != NULL) {
1.76 lukem 479: if (*cp == '\0' || !connected) {
1.1 cgd 480: mflag = 0;
481: continue;
482: }
483: if (mflag && confirm(argv[0], cp)) {
484: tp = cp;
1.63 lukem 485: if (mcase)
486: tp = docase(tp);
487: if (ntflag)
1.1 cgd 488: tp = dotrans(tp);
1.63 lukem 489: if (mapflag)
1.1 cgd 490: tp = domap(tp);
491: sendrequest((sunique) ? "STOU" : "STOR",
492: cp, tp, cp != tp || !interactive);
493: if (!mflag && fromatty) {
494: ointer = interactive;
495: interactive = 1;
1.10 lukem 496: if (confirm("Continue with", "mput")) {
1.1 cgd 497: mflag++;
498: }
499: interactive = ointer;
500: }
501: }
502: }
1.72 lukem 503: goto cleanupmput;
1.1 cgd 504: }
1.76 lukem 505: for (i = 1; i < argc && connected; i++) {
1.9 lukem 506: char **cpp;
1.4 cgd 507: glob_t gl;
508: int flags;
1.1 cgd 509:
510: if (!doglob) {
511: if (mflag && confirm(argv[0], argv[i])) {
512: tp = (ntflag) ? dotrans(argv[i]) : argv[i];
513: tp = (mapflag) ? domap(tp) : tp;
514: sendrequest((sunique) ? "STOU" : "STOR",
515: argv[i], tp, tp != argv[i] || !interactive);
516: if (!mflag && fromatty) {
517: ointer = interactive;
518: interactive = 1;
1.10 lukem 519: if (confirm("Continue with", "mput")) {
1.1 cgd 520: mflag++;
521: }
522: interactive = ointer;
523: }
524: }
525: continue;
526: }
1.4 cgd 527:
528: memset(&gl, 0, sizeof(gl));
1.38 kleink 529: flags = GLOB_BRACE|GLOB_NOCHECK|GLOB_TILDE;
1.4 cgd 530: if (glob(argv[i], flags, NULL, &gl) || gl.gl_pathc == 0) {
531: warnx("%s: not found", argv[i]);
532: globfree(&gl);
1.1 cgd 533: continue;
534: }
1.76 lukem 535: for (cpp = gl.gl_pathv; cpp && *cpp != NULL && connected;
536: cpp++) {
1.1 cgd 537: if (mflag && confirm(argv[0], *cpp)) {
538: tp = (ntflag) ? dotrans(*cpp) : *cpp;
539: tp = (mapflag) ? domap(tp) : tp;
540: sendrequest((sunique) ? "STOU" : "STOR",
541: *cpp, tp, *cpp != tp || !interactive);
542: if (!mflag && fromatty) {
543: ointer = interactive;
544: interactive = 1;
1.10 lukem 545: if (confirm("Continue with", "mput")) {
1.1 cgd 546: mflag++;
547: }
548: interactive = ointer;
549: }
550: }
551: }
1.4 cgd 552: globfree(&gl);
1.1 cgd 553: }
1.72 lukem 554: cleanupmput:
1.62 lukem 555: (void)xsignal(SIGINT, oldintr);
1.1 cgd 556: mflag = 0;
557: }
558:
1.4 cgd 559: void
1.1 cgd 560: reget(argc, argv)
561: int argc;
562: char *argv[];
563: {
1.4 cgd 564:
1.19 lukem 565: (void)getit(argc, argv, 1, "r+w");
1.1 cgd 566: }
567:
1.4 cgd 568: void
1.1 cgd 569: get(argc, argv)
570: int argc;
571: char *argv[];
572: {
1.4 cgd 573:
1.19 lukem 574: (void)getit(argc, argv, 0, restart_point ? "r+w" : "w" );
1.1 cgd 575: }
576:
577: /*
578: * Receive one file.
579: */
1.4 cgd 580: int
1.1 cgd 581: getit(argc, argv, restartit, mode)
582: int argc;
583: char *argv[];
1.4 cgd 584: int restartit;
1.10 lukem 585: const char *mode;
1.1 cgd 586: {
587: int loc = 0;
1.27 lukem 588: int rval = 0;
1.63 lukem 589: char *remfile, *locfile, *olocfile;
1.1 cgd 590:
591: if (argc == 2) {
592: argc++;
593: argv[2] = argv[1];
594: loc++;
595: }
1.76 lukem 596: if ((argc == 0 && argv != NULL) ||
597: (argc == 1 && !another(&argc, &argv, "remote-file")))
1.1 cgd 598: goto usage;
1.10 lukem 599: if ((argc < 3 && !another(&argc, &argv, "local-file")) || argc > 3) {
1.1 cgd 600: usage:
1.76 lukem 601: fprintf(ttyout, "usage: %s remote-file [local-file]\n",
1.37 lukem 602: argv[0]);
1.1 cgd 603: code = -1;
604: return (0);
605: }
1.63 lukem 606: remfile = argv[1];
607: if ((olocfile = globulize(argv[2])) == NULL) {
1.1 cgd 608: code = -1;
609: return (0);
610: }
1.63 lukem 611: locfile = olocfile;
612: if (loc && mcase)
613: locfile = docase(locfile);
1.1 cgd 614: if (loc && ntflag)
1.63 lukem 615: locfile = dotrans(locfile);
1.1 cgd 616: if (loc && mapflag)
1.63 lukem 617: locfile = domap(locfile);
1.1 cgd 618: if (restartit) {
619: struct stat stbuf;
620: int ret;
621:
1.63 lukem 622: ret = stat(locfile, &stbuf);
1.1 cgd 623: if (restartit == 1) {
624: if (ret < 0) {
1.63 lukem 625: warn("local: %s", locfile);
1.27 lukem 626: goto freegetit;
1.1 cgd 627: }
628: restart_point = stbuf.st_size;
629: } else {
630: if (ret == 0) {
1.10 lukem 631: time_t mtime;
1.1 cgd 632:
1.13 lukem 633: mtime = remotemodtime(argv[1], 0);
1.10 lukem 634: if (mtime == -1)
1.27 lukem 635: goto freegetit;
636: if (stbuf.st_mtime >= mtime) {
637: rval = 1;
638: goto freegetit;
639: }
1.1 cgd 640: }
641: }
642: }
643:
1.63 lukem 644: recvrequest("RETR", locfile, remfile, mode,
645: remfile != argv[1] || locfile != argv[2], loc);
1.1 cgd 646: restart_point = 0;
1.27 lukem 647: freegetit:
1.63 lukem 648: (void)free(olocfile);
1.27 lukem 649: return (rval);
1.1 cgd 650: }
651:
1.4 cgd 652: /* ARGSUSED */
1.1 cgd 653: void
1.72 lukem 654: mintr(signo)
1.4 cgd 655: int signo;
1.1 cgd 656: {
1.72 lukem 657:
658: alarmtimer(0);
1.74 lukem 659: if (fromatty)
660: write(fileno(ttyout), "\n", 1);
1.72 lukem 661: siglongjmp(jabort, 1);
662: }
663:
664: void
665: mabort()
666: {
1.10 lukem 667: int ointer, oconf;
1.1 cgd 668:
669: if (mflag && fromatty) {
670: ointer = interactive;
1.10 lukem 671: oconf = confirmrest;
1.1 cgd 672: interactive = 1;
1.10 lukem 673: confirmrest = 0;
1.1 cgd 674: if (confirm("Continue with", mname)) {
675: interactive = ointer;
1.10 lukem 676: confirmrest = oconf;
1.72 lukem 677: return;
1.1 cgd 678: }
679: interactive = ointer;
1.10 lukem 680: confirmrest = oconf;
1.1 cgd 681: }
682: mflag = 0;
683: }
684:
685: /*
686: * Get multiple files.
687: */
1.4 cgd 688: void
1.1 cgd 689: mget(argc, argv)
690: int argc;
1.10 lukem 691: char *argv[];
1.1 cgd 692: {
693: sig_t oldintr;
1.4 cgd 694: int ch, ointer;
1.1 cgd 695: char *cp, *tp, *tp2, tmpbuf[MAXPATHLEN];
696:
1.76 lukem 697: if ((argc == 0 && argv != NULL) ||
698: (argc == 1 && !another(&argc, &argv, "remote-files"))) {
1.37 lukem 699: fprintf(ttyout, "usage: %s remote-files\n", argv[0]);
1.1 cgd 700: code = -1;
701: return;
702: }
703: mname = argv[0];
704: mflag = 1;
1.72 lukem 705: oldintr = xsignal(SIGINT, mintr);
706: if (sigsetjmp(jabort, 1))
707: mabort();
1.19 lukem 708: while ((cp = remglob(argv, proxy, NULL)) != NULL) {
1.76 lukem 709: if (*cp == '\0' || !connected) {
1.1 cgd 710: mflag = 0;
711: continue;
712: }
713: if (mflag && confirm(argv[0], cp)) {
714: tp = cp;
715: if (mcase) {
1.24 pk 716: for (tp2 = tmpbuf; (ch = *tp++) != 0; )
1.4 cgd 717: *tp2++ = isupper(ch) ? tolower(ch) : ch;
1.7 jtc 718: *tp2 = '\0';
1.1 cgd 719: tp = tmpbuf;
720: }
721: if (ntflag) {
722: tp = dotrans(tp);
723: }
724: if (mapflag) {
725: tp = domap(tp);
726: }
727: recvrequest("RETR", tp, cp, "w",
1.27 lukem 728: tp != cp || !interactive, 1);
1.1 cgd 729: if (!mflag && fromatty) {
730: ointer = interactive;
731: interactive = 1;
1.10 lukem 732: if (confirm("Continue with", "mget")) {
1.1 cgd 733: mflag++;
734: }
735: interactive = ointer;
736: }
737: }
738: }
1.62 lukem 739: (void)xsignal(SIGINT, oldintr);
1.1 cgd 740: mflag = 0;
741: }
742:
743: char *
744: onoff(bool)
745: int bool;
746: {
747:
748: return (bool ? "on" : "off");
749: }
750:
751: /*
752: * Show status.
753: */
754: /*ARGSUSED*/
1.4 cgd 755: void
1.1 cgd 756: status(argc, argv)
757: int argc;
758: char *argv[];
759: {
760: int i;
761:
1.76 lukem 762: if (argc == 0 && argv != NULL) {
763: fprintf(ttyout, "usage: %s\n", argv[0]);
764: code = -1;
765: return;
766: }
1.1 cgd 767: if (connected)
1.37 lukem 768: fprintf(ttyout, "Connected %sto %s.\n",
1.23 lukem 769: connected == -1 ? "and logged in" : "", hostname);
1.1 cgd 770: else
1.37 lukem 771: fputs("Not connected.\n", ttyout);
1.1 cgd 772: if (!proxy) {
773: pswitch(1);
774: if (connected) {
1.37 lukem 775: fprintf(ttyout, "Connected for proxy commands to %s.\n",
1.10 lukem 776: hostname);
1.1 cgd 777: }
778: else {
1.37 lukem 779: fputs("No proxy connection.\n", ttyout);
1.1 cgd 780: }
781: pswitch(0);
782: }
1.54 itojun 783: fprintf(ttyout, "Gate ftp: %s, server %s, port %s.\n", onoff(gatemode),
784: *gateserver ? gateserver : "(none)", gateport);
1.76 lukem 785: fprintf(ttyout, "Passive mode: %s; fallback to active mode: %s.\n",
786: onoff(passivemode), onoff(activefallback));
1.37 lukem 787: fprintf(ttyout, "Mode: %s; Type: %s; Form: %s; Structure: %s.\n",
788: modename, typename, formname, structname);
789: fprintf(ttyout, "Verbose: %s; Bell: %s; Prompting: %s; Globbing: %s.\n",
790: onoff(verbose), onoff(bell), onoff(interactive), onoff(doglob));
791: fprintf(ttyout, "Store unique: %s; Receive unique: %s.\n",
792: onoff(sunique), onoff(runique));
793: fprintf(ttyout, "Preserve modification times: %s.\n", onoff(preserve));
794: fprintf(ttyout, "Case: %s; CR stripping: %s.\n", onoff(mcase),
795: onoff(crflag));
1.1 cgd 796: if (ntflag) {
1.37 lukem 797: fprintf(ttyout, "Ntrans: (in) %s (out) %s\n", ntin, ntout);
1.1 cgd 798: }
799: else {
1.37 lukem 800: fputs("Ntrans: off.\n", ttyout);
1.1 cgd 801: }
802: if (mapflag) {
1.37 lukem 803: fprintf(ttyout, "Nmap: (in) %s (out) %s\n", mapin, mapout);
1.1 cgd 804: }
805: else {
1.37 lukem 806: fputs("Nmap: off.\n", ttyout);
1.1 cgd 807: }
1.37 lukem 808: fprintf(ttyout,
809: "Hash mark printing: %s; Mark count: %d; Progress bar: %s.\n",
1.11 lukem 810: onoff(hash), mark, onoff(progress));
1.52 lukem 811: fprintf(ttyout,
812: "Get transfer rate throttle: %s; maximum: %d; increment %d.\n",
813: onoff(rate_get), rate_get, rate_get_incr);
814: fprintf(ttyout,
815: "Put transfer rate throttle: %s; maximum: %d; increment %d.\n",
816: onoff(rate_put), rate_put, rate_put_incr);
1.58 lukem 817: fprintf(ttyout,
818: "Socket buffer sizes: send %d, receive %d.\n",
819: sndbuf_size, rcvbuf_size);
1.37 lukem 820: fprintf(ttyout, "Use of PORT cmds: %s.\n", onoff(sendport));
1.68 lukem 821: fprintf(ttyout, "Use of EPSV/EPRT cmds for IPv4: %s%s.\n", onoff(epsv4),
822: epsv4bad ? " (disabled for this connection)" : "");
1.69 lukem 823: fprintf(ttyout, "Command line editing: %s.\n",
824: #ifdef NO_EDITCOMPLETE
825: "support not compiled in"
826: #else /* !def NO_EDITCOMPLETE */
827: onoff(editing)
828: #endif /* !def NO_EDITCOMPLETE */
829: );
1.78 lukem 830: fprintf(ttyout, "Version: %s %s\n", FTP_PRODUCT, FTP_VERSION);
1.1 cgd 831: if (macnum > 0) {
1.37 lukem 832: fputs("Macros:\n", ttyout);
1.1 cgd 833: for (i=0; i<macnum; i++) {
1.37 lukem 834: fprintf(ttyout, "\t%s\n", macros[i].mac_name);
1.1 cgd 835: }
836: }
837: code = 0;
838: }
839:
840: /*
1.10 lukem 841: * Toggle a variable
842: */
843: int
844: togglevar(argc, argv, var, mesg)
845: int argc;
846: char *argv[];
847: int *var;
848: const char *mesg;
849: {
1.76 lukem 850: if (argc == 1) {
1.10 lukem 851: *var = !*var;
852: } else if (argc == 2 && strcasecmp(argv[1], "on") == 0) {
853: *var = 1;
854: } else if (argc == 2 && strcasecmp(argv[1], "off") == 0) {
855: *var = 0;
856: } else {
1.37 lukem 857: fprintf(ttyout, "usage: %s [ on | off ]\n", argv[0]);
1.19 lukem 858: return (-1);
1.10 lukem 859: }
1.46 lukem 860: if (mesg)
1.37 lukem 861: fprintf(ttyout, "%s %s.\n", mesg, onoff(*var));
1.19 lukem 862: return (*var);
1.10 lukem 863: }
864:
865: /*
1.1 cgd 866: * Set beep on cmd completed mode.
867: */
868: /*VARARGS*/
1.4 cgd 869: void
870: setbell(argc, argv)
871: int argc;
872: char *argv[];
1.1 cgd 873: {
874:
1.10 lukem 875: code = togglevar(argc, argv, &bell, "Bell mode");
1.1 cgd 876: }
877:
1.16 lukem 878: /*
879: * Set command line editing
880: */
881: /*VARARGS*/
882: void
883: setedit(argc, argv)
884: int argc;
885: char *argv[];
886: {
887:
1.69 lukem 888: #ifdef NO_EDITCOMPLETE
1.76 lukem 889: if (argc == 0 && argv != NULL) {
890: fprintf(ttyout, "usage: %s\n", argv[0]);
891: code = -1;
892: return;
893: }
1.69 lukem 894: if (verbose)
895: fputs("Editing support not compiled in; ignoring command.\n",
896: ttyout);
897: #else /* !def NO_EDITCOMPLETE */
1.16 lukem 898: code = togglevar(argc, argv, &editing, "Editing mode");
1.22 lukem 899: controlediting();
1.69 lukem 900: #endif /* !def NO_EDITCOMPLETE */
1.16 lukem 901: }
902:
1.1 cgd 903: /*
904: * Turn on packet tracing.
905: */
906: /*VARARGS*/
1.4 cgd 907: void
908: settrace(argc, argv)
909: int argc;
910: char *argv[];
1.1 cgd 911: {
912:
1.10 lukem 913: code = togglevar(argc, argv, &trace, "Packet tracing");
1.1 cgd 914: }
915:
916: /*
1.9 lukem 917: * Toggle hash mark printing during transfers, or set hash mark bytecount.
1.1 cgd 918: */
919: /*VARARGS*/
1.4 cgd 920: void
921: sethash(argc, argv)
922: int argc;
923: char *argv[];
1.1 cgd 924: {
1.10 lukem 925: if (argc == 1)
1.9 lukem 926: hash = !hash;
1.10 lukem 927: else if (argc != 2) {
1.37 lukem 928: fprintf(ttyout, "usage: %s [ on | off | bytecount ]\n",
929: argv[0]);
1.10 lukem 930: code = -1;
931: return;
932: } else if (strcasecmp(argv[1], "on") == 0)
933: hash = 1;
934: else if (strcasecmp(argv[1], "off") == 0)
935: hash = 0;
936: else {
1.31 lukem 937: int nmark;
938:
1.52 lukem 939: nmark = strsuftoi(argv[1]);
940: if (nmark < 1) {
1.37 lukem 941: fprintf(ttyout, "mark: bad bytecount value `%s'.\n",
942: argv[1]);
1.10 lukem 943: code = -1;
944: return;
1.9 lukem 945: }
1.10 lukem 946: mark = nmark;
947: hash = 1;
1.9 lukem 948: }
1.37 lukem 949: fprintf(ttyout, "Hash mark printing %s", onoff(hash));
1.10 lukem 950: if (hash)
1.37 lukem 951: fprintf(ttyout, " (%d bytes/hash mark)", mark);
952: fputs(".\n", ttyout);
1.44 lukem 953: if (hash)
954: progress = 0;
1.10 lukem 955: code = hash;
1.1 cgd 956: }
957:
958: /*
959: * Turn on printing of server echo's.
960: */
961: /*VARARGS*/
1.4 cgd 962: void
963: setverbose(argc, argv)
964: int argc;
965: char *argv[];
1.1 cgd 966: {
967:
1.10 lukem 968: code = togglevar(argc, argv, &verbose, "Verbose mode");
1.1 cgd 969: }
970:
971: /*
1.54 itojun 972: * Toggle PORT/LPRT cmd use before each data connection.
1.1 cgd 973: */
974: /*VARARGS*/
1.4 cgd 975: void
976: setport(argc, argv)
977: int argc;
978: char *argv[];
1.1 cgd 979: {
980:
1.54 itojun 981: code = togglevar(argc, argv, &sendport, "Use of PORT/LPRT cmds");
1.1 cgd 982: }
983:
984: /*
1.11 lukem 985: * Toggle transfer progress bar.
986: */
987: /*VARARGS*/
988: void
989: setprogress(argc, argv)
990: int argc;
991: char *argv[];
992: {
993:
994: code = togglevar(argc, argv, &progress, "Progress bar");
1.44 lukem 995: if (progress)
996: hash = 0;
1.11 lukem 997: }
998:
999: /*
1.27 lukem 1000: * Turn on interactive prompting during mget, mput, and mdelete.
1.1 cgd 1001: */
1002: /*VARARGS*/
1.4 cgd 1003: void
1004: setprompt(argc, argv)
1005: int argc;
1006: char *argv[];
1.1 cgd 1007: {
1008:
1.10 lukem 1009: code = togglevar(argc, argv, &interactive, "Interactive mode");
1.1 cgd 1010: }
1011:
1012: /*
1.27 lukem 1013: * Toggle gate-ftp mode, or set gate-ftp server
1014: */
1015: /*VARARGS*/
1016: void
1017: setgate(argc, argv)
1018: int argc;
1019: char *argv[];
1020: {
1021: static char gsbuf[MAXHOSTNAMELEN];
1022:
1.76 lukem 1023: if ((argc == 0 && argv != NULL) || argc > 3) {
1.37 lukem 1024: fprintf(ttyout,
1.76 lukem 1025: "usage: %s [ on | off | gateserver [port] ]\n", argv[0]);
1.27 lukem 1026: code = -1;
1027: return;
1028: } else if (argc < 2) {
1029: gatemode = !gatemode;
1030: } else {
1031: if (argc == 2 && strcasecmp(argv[1], "on") == 0)
1032: gatemode = 1;
1033: else if (argc == 2 && strcasecmp(argv[1], "off") == 0)
1034: gatemode = 0;
1035: else {
1.59 lukem 1036: if (argc == 3)
1.54 itojun 1037: gateport = strdup(argv[2]);
1.63 lukem 1038: (void)strlcpy(gsbuf, argv[1], sizeof(gsbuf));
1.27 lukem 1039: gateserver = gsbuf;
1040: gatemode = 1;
1041: }
1042: }
1043: if (gatemode && (gateserver == NULL || *gateserver == '\0')) {
1.37 lukem 1044: fprintf(ttyout,
1.27 lukem 1045: "Disabling gate-ftp mode - no gate-ftp server defined.\n");
1046: gatemode = 0;
1047: } else {
1.54 itojun 1048: fprintf(ttyout, "Gate ftp: %s, server %s, port %s.\n",
1.37 lukem 1049: onoff(gatemode), *gateserver ? gateserver : "(none)",
1.54 itojun 1050: gateport);
1.27 lukem 1051: }
1052: code = gatemode;
1053: }
1054:
1055: /*
1056: * Toggle metacharacter interpretation on local file names.
1.1 cgd 1057: */
1058: /*VARARGS*/
1.4 cgd 1059: void
1060: setglob(argc, argv)
1061: int argc;
1062: char *argv[];
1.1 cgd 1063: {
1.9 lukem 1064:
1.10 lukem 1065: code = togglevar(argc, argv, &doglob, "Globbing");
1066: }
1067:
1068: /*
1.40 lukem 1069: * Toggle preserving modification times on retrieved files.
1.10 lukem 1070: */
1071: /*VARARGS*/
1072: void
1073: setpreserve(argc, argv)
1074: int argc;
1075: char *argv[];
1076: {
1077:
1078: code = togglevar(argc, argv, &preserve, "Preserve modification times");
1.1 cgd 1079: }
1080:
1081: /*
1.27 lukem 1082: * Set debugging mode on/off and/or set level of debugging.
1.1 cgd 1083: */
1084: /*VARARGS*/
1.4 cgd 1085: void
1.1 cgd 1086: setdebug(argc, argv)
1087: int argc;
1088: char *argv[];
1089: {
1.76 lukem 1090: if ((argc == 0 && argv != NULL) || argc > 2) {
1.37 lukem 1091: fprintf(ttyout, "usage: %s [ on | off | debuglevel ]\n",
1092: argv[0]);
1.10 lukem 1093: code = -1;
1094: return;
1095: } else if (argc == 2) {
1096: if (strcasecmp(argv[1], "on") == 0)
1097: debug = 1;
1098: else if (strcasecmp(argv[1], "off") == 0)
1099: debug = 0;
1100: else {
1.52 lukem 1101: int val;
1.25 lukem 1102:
1.52 lukem 1103: val = strsuftoi(argv[1]);
1104: if (val < 0) {
1.37 lukem 1105: fprintf(ttyout, "%s: bad debugging value.\n",
1106: argv[1]);
1.10 lukem 1107: code = -1;
1108: return;
1109: }
1.52 lukem 1110: debug = val;
1.1 cgd 1111: }
1112: } else
1.11 lukem 1113: debug = !debug;
1.1 cgd 1114: if (debug)
1115: options |= SO_DEBUG;
1116: else
1117: options &= ~SO_DEBUG;
1.37 lukem 1118: fprintf(ttyout, "Debugging %s (debug=%d).\n", onoff(debug), debug);
1.1 cgd 1119: code = debug > 0;
1120: }
1121:
1122: /*
1.27 lukem 1123: * Set current working directory on remote machine.
1.1 cgd 1124: */
1.4 cgd 1125: void
1.1 cgd 1126: cd(argc, argv)
1127: int argc;
1128: char *argv[];
1129: {
1.16 lukem 1130: int r;
1.1 cgd 1131:
1.76 lukem 1132: if ((argc == 1 && !another(&argc, &argv, "remote-directory")) ||
1133: (argc == 0 && argv != NULL) || argc > 2) {
1.37 lukem 1134: fprintf(ttyout, "usage: %s remote-directory\n", argv[0]);
1.1 cgd 1135: code = -1;
1136: return;
1137: }
1.17 veego 1138: r = command("CWD %s", argv[1]);
1.16 lukem 1139: if (r == ERROR && code == 500) {
1.1 cgd 1140: if (verbose)
1.37 lukem 1141: fputs("CWD command not recognized, trying XCWD.\n",
1142: ttyout);
1.16 lukem 1143: r = command("XCWD %s", argv[1]);
1.1 cgd 1144: }
1.79 ! lukem 1145: if (r == COMPLETE) {
1.16 lukem 1146: dirchange = 1;
1.79 ! lukem 1147: updateremotepwd();
! 1148: }
1.1 cgd 1149: }
1150:
1151: /*
1.27 lukem 1152: * Set current working directory on local machine.
1.1 cgd 1153: */
1.4 cgd 1154: void
1.1 cgd 1155: lcd(argc, argv)
1156: int argc;
1157: char *argv[];
1158: {
1159: char buf[MAXPATHLEN];
1.63 lukem 1160: char *locdir;
1.1 cgd 1161:
1.76 lukem 1162: code = -1;
1163: if (argc == 1) {
1.64 lukem 1164: argc++;
1165: argv[1] = home;
1166: }
1.1 cgd 1167: if (argc != 2) {
1.76 lukem 1168: fprintf(ttyout, "usage: %s [local-directory]\n", argv[0]);
1.1 cgd 1169: return;
1170: }
1.76 lukem 1171: if ((locdir = globulize(argv[1])) == NULL)
1.1 cgd 1172: return;
1.76 lukem 1173: if (chdir(locdir) < 0)
1.63 lukem 1174: warn("local: %s", locdir);
1.76 lukem 1175: else {
1176: if (getcwd(buf, sizeof(buf)) != NULL) {
1.37 lukem 1177: fprintf(ttyout, "Local directory now %s\n", buf);
1.76 lukem 1178: code = 0;
1179: } else
1.63 lukem 1180: warn("getcwd: %s", locdir);
1.1 cgd 1181: }
1.63 lukem 1182: (void)free(locdir);
1.1 cgd 1183: }
1184:
1185: /*
1186: * Delete a single file.
1187: */
1.4 cgd 1188: void
1.1 cgd 1189: delete(argc, argv)
1190: int argc;
1191: char *argv[];
1192: {
1193:
1.76 lukem 1194: if ((argc == 1 && !another(&argc, &argv, "remote-file")) ||
1195: (argc == 0 && argv != NULL) || argc > 2) {
1.37 lukem 1196: fprintf(ttyout, "usage: %s remote-file\n", argv[0]);
1.1 cgd 1197: code = -1;
1198: return;
1199: }
1.19 lukem 1200: (void)command("DELE %s", argv[1]);
1.1 cgd 1201: }
1202:
1203: /*
1204: * Delete multiple files.
1205: */
1.4 cgd 1206: void
1.1 cgd 1207: mdelete(argc, argv)
1208: int argc;
1.10 lukem 1209: char *argv[];
1.1 cgd 1210: {
1211: sig_t oldintr;
1212: int ointer;
1213: char *cp;
1214:
1.76 lukem 1215: if ((argc == 1 && !another(&argc, &argv, "remote-files")) ||
1216: (argc == 0 && argv != NULL)) {
1217: fprintf(ttyout, "usage: %s [remote-files]\n", argv[0]);
1.1 cgd 1218: code = -1;
1219: return;
1220: }
1221: mname = argv[0];
1222: mflag = 1;
1.72 lukem 1223: oldintr = xsignal(SIGINT, mintr);
1224: if (sigsetjmp(jabort, 1))
1225: mabort();
1.19 lukem 1226: while ((cp = remglob(argv, 0, NULL)) != NULL) {
1.1 cgd 1227: if (*cp == '\0') {
1228: mflag = 0;
1229: continue;
1230: }
1231: if (mflag && confirm(argv[0], cp)) {
1.19 lukem 1232: (void)command("DELE %s", cp);
1.1 cgd 1233: if (!mflag && fromatty) {
1234: ointer = interactive;
1235: interactive = 1;
1236: if (confirm("Continue with", "mdelete")) {
1237: mflag++;
1238: }
1239: interactive = ointer;
1240: }
1241: }
1242: }
1.62 lukem 1243: (void)xsignal(SIGINT, oldintr);
1.1 cgd 1244: mflag = 0;
1245: }
1246:
1247: /*
1248: * Rename a remote file.
1249: */
1.4 cgd 1250: void
1.1 cgd 1251: renamefile(argc, argv)
1252: int argc;
1253: char *argv[];
1254: {
1255:
1.76 lukem 1256: if ((argc == 0 && argv != NULL) ||
1257: (argc == 1 && !another(&argc, &argv, "from-name")))
1.1 cgd 1258: goto usage;
1.10 lukem 1259: if ((argc < 3 && !another(&argc, &argv, "to-name")) || argc > 3) {
1.1 cgd 1260: usage:
1.37 lukem 1261: fprintf(ttyout, "usage: %s from-name to-name\n", argv[0]);
1.1 cgd 1262: code = -1;
1263: return;
1264: }
1265: if (command("RNFR %s", argv[1]) == CONTINUE)
1.19 lukem 1266: (void)command("RNTO %s", argv[2]);
1.1 cgd 1267: }
1268:
1269: /*
1.27 lukem 1270: * Get a directory listing of remote files.
1.1 cgd 1271: */
1.4 cgd 1272: void
1.1 cgd 1273: ls(argc, argv)
1274: int argc;
1275: char *argv[];
1276: {
1.10 lukem 1277: const char *cmd;
1.63 lukem 1278: char *remdir, *locfile;
1279: int freelocfile, pagecmd;
1.1 cgd 1280:
1.63 lukem 1281: remdir = NULL;
1282: locfile = "-";
1283: freelocfile = pagecmd = 0;
1284: /*
1285: * assume all `pager' versions of the commands
1286: * are the only ones that start with `p'
1287: */
1288: if (argv[0][0] == 'p')
1289: pagecmd = 1;
1.76 lukem 1290: if (argc == 0 && argv != NULL)
1291: goto usage;
1.63 lukem 1292:
1293: cmd = "NLST";
1294: if (strcmp(argv[0] + pagecmd, "dir") == 0)
1295: cmd = "LIST";
1296:
1297: if (argc > 1)
1298: remdir = argv[1];
1299: if (argc > 2)
1300: locfile = argv[2];
1301: if (argc > 3 || (pagecmd && argc > 2)) {
1.76 lukem 1302: usage:
1.63 lukem 1303: if (pagecmd)
1304: fprintf(ttyout,
1305: "usage: %s [remote-directory]\n", argv[0]);
1306: else
1307: fprintf(ttyout,
1308: "usage: %s [remote-directory [local-file]]\n",
1309: argv[0]);
1.1 cgd 1310: code = -1;
1.63 lukem 1311: goto freels;
1.1 cgd 1312: }
1.63 lukem 1313:
1314: if (pagecmd) {
1315: char *p;
1316: int len;
1317:
1.76 lukem 1318: p = getoptionvalue("pager");
1319: if (EMPTYSTRING(p))
1320: p = DEFAULTPAGER;
1.63 lukem 1321: len = strlen(p) + 2;
1322: locfile = xmalloc(len);
1323: locfile[0] = '|';
1324: (void)strlcpy(locfile + 1, p, len - 1);
1325: freelocfile = 1;
1326: } else if ((strcmp(locfile, "-") != 0) && *locfile != '|') {
1327: if ((locfile = globulize(locfile)) == NULL ||
1328: !confirm("output to local-file:", locfile)) {
1.1 cgd 1329: code = -1;
1.27 lukem 1330: goto freels;
1.63 lukem 1331: }
1332: freelocfile = 1;
1.1 cgd 1333: }
1.63 lukem 1334: recvrequest(cmd, locfile, remdir, "w", 0, 0);
1.27 lukem 1335: freels:
1.63 lukem 1336: if (freelocfile && locfile)
1337: (void)free(locfile);
1.1 cgd 1338: }
1339:
1340: /*
1.27 lukem 1341: * Get a directory listing of multiple remote files.
1.1 cgd 1342: */
1.4 cgd 1343: void
1.1 cgd 1344: mls(argc, argv)
1345: int argc;
1.10 lukem 1346: char *argv[];
1.1 cgd 1347: {
1348: sig_t oldintr;
1349: int ointer, i;
1.25 lukem 1350: int dolist;
1.27 lukem 1351: char mode[1], *dest, *odest;
1.1 cgd 1352:
1.76 lukem 1353: if (argc == 0 && argv != NULL)
1354: goto usage;
1.1 cgd 1355: if (argc < 2 && !another(&argc, &argv, "remote-files"))
1356: goto usage;
1357: if (argc < 3 && !another(&argc, &argv, "local-file")) {
1358: usage:
1.37 lukem 1359: fprintf(ttyout, "usage: %s remote-files local-file\n", argv[0]);
1.1 cgd 1360: code = -1;
1361: return;
1362: }
1.27 lukem 1363: odest = dest = argv[argc - 1];
1.1 cgd 1364: argv[argc - 1] = NULL;
1365: if (strcmp(dest, "-") && *dest != '|')
1.63 lukem 1366: if (((dest = globulize(dest)) == NULL) ||
1.1 cgd 1367: !confirm("output to local-file:", dest)) {
1368: code = -1;
1369: return;
1370: }
1.25 lukem 1371: dolist = strcmp(argv[0], "mls");
1.1 cgd 1372: mname = argv[0];
1373: mflag = 1;
1.72 lukem 1374: oldintr = xsignal(SIGINT, mintr);
1375: if (sigsetjmp(jabort, 1))
1376: mabort();
1.76 lukem 1377: for (i = 1; mflag && i < argc-1 && connected; i++) {
1.1 cgd 1378: *mode = (i == 1) ? 'w' : 'a';
1.27 lukem 1379: recvrequest(dolist ? "LIST" : "NLST", dest, argv[i], mode,
1380: 0, 0);
1.1 cgd 1381: if (!mflag && fromatty) {
1382: ointer = interactive;
1383: interactive = 1;
1384: if (confirm("Continue with", argv[0])) {
1385: mflag ++;
1386: }
1387: interactive = ointer;
1388: }
1389: }
1.62 lukem 1390: (void)xsignal(SIGINT, oldintr);
1.1 cgd 1391: mflag = 0;
1.27 lukem 1392: if (dest != odest) /* free up after globulize() */
1393: free(dest);
1.1 cgd 1394: }
1395:
1396: /*
1397: * Do a shell escape
1398: */
1399: /*ARGSUSED*/
1.4 cgd 1400: void
1.1 cgd 1401: shell(argc, argv)
1402: int argc;
1.10 lukem 1403: char *argv[];
1.1 cgd 1404: {
1.4 cgd 1405: pid_t pid;
1.71 lukem 1406: sig_t old1;
1.13 lukem 1407: char shellnam[MAXPATHLEN], *shell, *namep;
1.29 lukem 1408: int wait_status;
1.1 cgd 1409:
1.76 lukem 1410: if (argc == 0 && argv != NULL) {
1411: fprintf(ttyout, "usage: %s [command [args]]\n", argv[0]);
1412: code = -1;
1413: return;
1414: }
1.62 lukem 1415: old1 = xsignal(SIGINT, SIG_IGN);
1.1 cgd 1416: if ((pid = fork()) == 0) {
1417: for (pid = 3; pid < 20; pid++)
1.19 lukem 1418: (void)close(pid);
1.62 lukem 1419: (void)xsignal(SIGINT, SIG_DFL);
1.1 cgd 1420: shell = getenv("SHELL");
1421: if (shell == NULL)
1422: shell = _PATH_BSHELL;
1.10 lukem 1423: namep = strrchr(shell, '/');
1.1 cgd 1424: if (namep == NULL)
1425: namep = shell;
1.71 lukem 1426: else
1427: namep++;
1428: (void)strlcpy(shellnam, namep, sizeof(shellnam));
1.1 cgd 1429: if (debug) {
1.37 lukem 1430: fputs(shell, ttyout);
1431: putc('\n', ttyout);
1.1 cgd 1432: }
1433: if (argc > 1) {
1.10 lukem 1434: execl(shell, shellnam, "-c", altarg, (char *)0);
1.1 cgd 1435: }
1436: else {
1.10 lukem 1437: execl(shell, shellnam, (char *)0);
1.1 cgd 1438: }
1.4 cgd 1439: warn("%s", shell);
1.1 cgd 1440: code = -1;
1441: exit(1);
1.4 cgd 1442: }
1.1 cgd 1443: if (pid > 0)
1.29 lukem 1444: while (wait(&wait_status) != pid)
1.1 cgd 1445: ;
1.62 lukem 1446: (void)xsignal(SIGINT, old1);
1.1 cgd 1447: if (pid == -1) {
1.19 lukem 1448: warn("Try again later");
1.1 cgd 1449: code = -1;
1.76 lukem 1450: } else
1.1 cgd 1451: code = 0;
1452: }
1453:
1454: /*
1455: * Send new user information (re-login)
1456: */
1.4 cgd 1457: void
1.1 cgd 1458: user(argc, argv)
1459: int argc;
1.10 lukem 1460: char *argv[];
1.1 cgd 1461: {
1.4 cgd 1462: char acct[80];
1.1 cgd 1463: int n, aflag = 0;
1464:
1.76 lukem 1465: if (argc == 0 && argv != NULL)
1466: goto usage;
1.1 cgd 1467: if (argc < 2)
1.19 lukem 1468: (void)another(&argc, &argv, "username");
1.1 cgd 1469: if (argc < 2 || argc > 4) {
1.76 lukem 1470: usage:
1471: fprintf(ttyout, "usage: %s username [password [account]]\n",
1.37 lukem 1472: argv[0]);
1.1 cgd 1473: code = -1;
1.4 cgd 1474: return;
1.1 cgd 1475: }
1476: n = command("USER %s", argv[1]);
1477: if (n == CONTINUE) {
1.49 lukem 1478: if (argc < 3) {
1479: argv[2] = getpass("Password: ");
1480: argc++;
1481: }
1.1 cgd 1482: n = command("PASS %s", argv[2]);
1483: }
1484: if (n == CONTINUE) {
1485: if (argc < 4) {
1.37 lukem 1486: (void)fputs("Account: ", ttyout);
1487: (void)fflush(ttyout);
1.49 lukem 1488: if (fgets(acct, sizeof(acct) - 1, stdin) == NULL) {
1489: fprintf(ttyout,
1490: "\nEOF received; login aborted.\n");
1.74 lukem 1491: clearerr(stdin);
1.49 lukem 1492: code = -1;
1493: return;
1494: }
1.1 cgd 1495: acct[strlen(acct) - 1] = '\0';
1496: argv[3] = acct; argc++;
1497: }
1498: n = command("ACCT %s", argv[3]);
1499: aflag++;
1500: }
1501: if (n != COMPLETE) {
1.37 lukem 1502: fputs("Login failed.\n", ttyout);
1.4 cgd 1503: return;
1.1 cgd 1504: }
1505: if (!aflag && argc == 4) {
1.19 lukem 1506: (void)command("ACCT %s", argv[3]);
1.1 cgd 1507: }
1.23 lukem 1508: connected = -1;
1.1 cgd 1509: }
1510:
1511: /*
1.10 lukem 1512: * Print working directory on remote machine.
1.1 cgd 1513: */
1514: /*VARARGS*/
1.4 cgd 1515: void
1516: pwd(argc, argv)
1517: int argc;
1518: char *argv[];
1.1 cgd 1519: {
1520: int oldverbose = verbose;
1521:
1.76 lukem 1522: if (argc == 0 && argv != NULL) {
1523: fprintf(ttyout, "usage: %s\n", argv[0]);
1524: code = -1;
1525: return;
1526: }
1.1 cgd 1527: /*
1528: * If we aren't verbose, this doesn't do anything!
1529: */
1530: verbose = 1;
1531: if (command("PWD") == ERROR && code == 500) {
1.37 lukem 1532: fputs("PWD command not recognized, trying XPWD.\n", ttyout);
1.19 lukem 1533: (void)command("XPWD");
1.1 cgd 1534: }
1535: verbose = oldverbose;
1536: }
1537:
1538: /*
1.10 lukem 1539: * Print working directory on local machine.
1540: */
1541: void
1542: lpwd(argc, argv)
1543: int argc;
1544: char *argv[];
1545: {
1546: char buf[MAXPATHLEN];
1547:
1.76 lukem 1548: if (argc == 0 && argv != NULL) {
1549: fprintf(ttyout, "usage: %s\n", argv[0]);
1550: code = -1;
1551: return;
1552: }
1553: if (getcwd(buf, sizeof(buf)) != NULL) {
1.37 lukem 1554: fprintf(ttyout, "Local directory %s\n", buf);
1.76 lukem 1555: code = 0;
1556: } else {
1.18 lukem 1557: warn("getcwd");
1.76 lukem 1558: code = -1;
1559: }
1.10 lukem 1560: }
1561:
1562: /*
1.1 cgd 1563: * Make a directory.
1564: */
1.4 cgd 1565: void
1.1 cgd 1566: makedir(argc, argv)
1567: int argc;
1568: char *argv[];
1569: {
1570:
1.76 lukem 1571: if ((argc == 1 && !another(&argc, &argv, "directory-name")) ||
1572: (argc == 0 && argv != NULL) || argc > 2) {
1.37 lukem 1573: fprintf(ttyout, "usage: %s directory-name\n", argv[0]);
1.1 cgd 1574: code = -1;
1575: return;
1576: }
1577: if (command("MKD %s", argv[1]) == ERROR && code == 500) {
1578: if (verbose)
1.37 lukem 1579: fputs("MKD command not recognized, trying XMKD.\n",
1580: ttyout);
1.19 lukem 1581: (void)command("XMKD %s", argv[1]);
1.1 cgd 1582: }
1583: }
1584:
1585: /*
1586: * Remove a directory.
1587: */
1.4 cgd 1588: void
1.1 cgd 1589: removedir(argc, argv)
1590: int argc;
1591: char *argv[];
1592: {
1593:
1.76 lukem 1594: if ((argc == 1 && !another(&argc, &argv, "directory-name")) ||
1595: (argc == 0 && argv != NULL) || argc > 2) {
1.37 lukem 1596: fprintf(ttyout, "usage: %s directory-name\n", argv[0]);
1.1 cgd 1597: code = -1;
1598: return;
1599: }
1600: if (command("RMD %s", argv[1]) == ERROR && code == 500) {
1601: if (verbose)
1.37 lukem 1602: fputs("RMD command not recognized, trying XRMD.\n",
1603: ttyout);
1.19 lukem 1604: (void)command("XRMD %s", argv[1]);
1.1 cgd 1605: }
1606: }
1607:
1608: /*
1609: * Send a line, verbatim, to the remote machine.
1610: */
1.4 cgd 1611: void
1.1 cgd 1612: quote(argc, argv)
1613: int argc;
1614: char *argv[];
1615: {
1616:
1.76 lukem 1617: if ((argc == 1 && !another(&argc, &argv, "command line to send")) ||
1618: (argc == 0 && argv != NULL)) {
1.37 lukem 1619: fprintf(ttyout, "usage: %s line-to-send\n", argv[0]);
1.1 cgd 1620: code = -1;
1621: return;
1622: }
1623: quote1("", argc, argv);
1624: }
1625:
1626: /*
1627: * Send a SITE command to the remote machine. The line
1628: * is sent verbatim to the remote machine, except that the
1629: * word "SITE" is added at the front.
1630: */
1.4 cgd 1631: void
1.1 cgd 1632: site(argc, argv)
1633: int argc;
1634: char *argv[];
1635: {
1636:
1.76 lukem 1637: if ((argc == 1 && !another(&argc, &argv, "arguments to SITE command"))
1638: || (argc == 0 && argv != NULL)) {
1.37 lukem 1639: fprintf(ttyout, "usage: %s line-to-send\n", argv[0]);
1.1 cgd 1640: code = -1;
1641: return;
1642: }
1643: quote1("SITE ", argc, argv);
1644: }
1645:
1646: /*
1647: * Turn argv[1..argc) into a space-separated string, then prepend initial text.
1648: * Send the result as a one-line command and get response.
1649: */
1.4 cgd 1650: void
1.1 cgd 1651: quote1(initial, argc, argv)
1.10 lukem 1652: const char *initial;
1.1 cgd 1653: int argc;
1.10 lukem 1654: char *argv[];
1.1 cgd 1655: {
1.63 lukem 1656: int i;
1.1 cgd 1657: char buf[BUFSIZ]; /* must be >= sizeof(line) */
1658:
1.63 lukem 1659: (void)strlcpy(buf, initial, sizeof(buf));
1660: for (i = 1; i < argc; i++) {
1661: (void)strlcat(buf, argv[i], sizeof(buf));
1662: if (i < (argc - 1))
1663: (void)strlcat(buf, " ", sizeof(buf));
1.1 cgd 1664: }
1.43 lukem 1665: if (command("%s", buf) == PRELIM) {
1.4 cgd 1666: while (getreply(0) == PRELIM)
1667: continue;
1.1 cgd 1668: }
1669: }
1670:
1.4 cgd 1671: void
1.1 cgd 1672: do_chmod(argc, argv)
1673: int argc;
1674: char *argv[];
1675: {
1676:
1.76 lukem 1677: if ((argc == 0 && argv != NULL) ||
1678: (argc == 1 && !another(&argc, &argv, "mode")))
1.1 cgd 1679: goto usage;
1.76 lukem 1680: if ((argc < 3 && !another(&argc, &argv, "remote-file")) || argc > 3) {
1.1 cgd 1681: usage:
1.76 lukem 1682: fprintf(ttyout, "usage: %s mode remote-file\n", argv[0]);
1.1 cgd 1683: code = -1;
1684: return;
1685: }
1.19 lukem 1686: (void)command("SITE CHMOD %s %s", argv[1], argv[2]);
1.1 cgd 1687: }
1688:
1.4 cgd 1689: void
1.1 cgd 1690: do_umask(argc, argv)
1691: int argc;
1692: char *argv[];
1693: {
1694: int oldverbose = verbose;
1695:
1.76 lukem 1696: if (argc == 0 && argv != NULL) {
1697: fprintf(ttyout, "usage: %s [umask]\n", argv[0]);
1698: code = -1;
1699: return;
1700: }
1.1 cgd 1701: verbose = 1;
1.19 lukem 1702: (void)command(argc == 1 ? "SITE UMASK" : "SITE UMASK %s", argv[1]);
1.1 cgd 1703: verbose = oldverbose;
1704: }
1705:
1.4 cgd 1706: void
1.62 lukem 1707: idlecmd(argc, argv)
1.1 cgd 1708: int argc;
1709: char *argv[];
1710: {
1711: int oldverbose = verbose;
1712:
1.76 lukem 1713: if (argc != 2) {
1714: fprintf(ttyout, "usage: %s [seconds]\n", argv[0]);
1715: code = -1;
1716: return;
1717: }
1.1 cgd 1718: verbose = 1;
1.19 lukem 1719: (void)command(argc == 1 ? "SITE IDLE" : "SITE IDLE %s", argv[1]);
1.1 cgd 1720: verbose = oldverbose;
1721: }
1722:
1723: /*
1724: * Ask the other side for help.
1725: */
1.4 cgd 1726: void
1.1 cgd 1727: rmthelp(argc, argv)
1728: int argc;
1729: char *argv[];
1730: {
1731: int oldverbose = verbose;
1732:
1.76 lukem 1733: if (argc == 0 && argv != NULL) {
1734: fprintf(ttyout, "usage: %s\n", argv[0]);
1735: code = -1;
1736: return;
1737: }
1.1 cgd 1738: verbose = 1;
1.19 lukem 1739: (void)command(argc == 1 ? "HELP" : "HELP %s", argv[1]);
1.1 cgd 1740: verbose = oldverbose;
1741: }
1742:
1743: /*
1744: * Terminate session and exit.
1745: */
1746: /*VARARGS*/
1.4 cgd 1747: void
1748: quit(argc, argv)
1749: int argc;
1750: char *argv[];
1.1 cgd 1751: {
1752:
1.76 lukem 1753: if (argc == 0 && argv != NULL) {
1754: fprintf(ttyout, "usage: %s\n", argv[0]);
1755: code = -1;
1756: return;
1757: }
1.1 cgd 1758: if (connected)
1.76 lukem 1759: disconnect(0, NULL);
1.1 cgd 1760: pswitch(1);
1.76 lukem 1761: if (connected)
1762: disconnect(0, NULL);
1.1 cgd 1763: exit(0);
1764: }
1765:
1766: /*
1767: * Terminate session, but don't exit.
1768: */
1.4 cgd 1769: void
1770: disconnect(argc, argv)
1771: int argc;
1772: char *argv[];
1.1 cgd 1773: {
1774:
1.76 lukem 1775: if (argc == 0 && argv != NULL) {
1776: fprintf(ttyout, "usage: %s\n", argv[0]);
1777: code = -1;
1778: return;
1779: }
1.1 cgd 1780: if (!connected)
1781: return;
1.19 lukem 1782: (void)command("QUIT");
1.76 lukem 1783: cleanuppeer();
1.1 cgd 1784: }
1785:
1.4 cgd 1786: void
1.10 lukem 1787: account(argc, argv)
1.1 cgd 1788: int argc;
1.10 lukem 1789: char *argv[];
1.1 cgd 1790: {
1.13 lukem 1791: char *ap;
1.1 cgd 1792:
1.76 lukem 1793: if ((argc == 0 && argv != NULL) || argc > 2) {
1.37 lukem 1794: fprintf(ttyout, "usage: %s [password]\n", argv[0]);
1.13 lukem 1795: code = -1;
1796: return;
1.1 cgd 1797: }
1.13 lukem 1798: else if (argc == 2)
1799: ap = argv[1];
1800: else
1.1 cgd 1801: ap = getpass("Account:");
1.19 lukem 1802: (void)command("ACCT %s", ap);
1.1 cgd 1803: }
1804:
1.73 lukem 1805: sigjmp_buf abortprox;
1.1 cgd 1806:
1807: void
1.19 lukem 1808: proxabort(notused)
1809: int notused;
1.1 cgd 1810: {
1811:
1.18 lukem 1812: alarmtimer(0);
1.1 cgd 1813: if (!proxy) {
1814: pswitch(1);
1815: }
1816: if (connected) {
1817: proxflag = 1;
1818: }
1819: else {
1820: proxflag = 0;
1821: }
1822: pswitch(0);
1.72 lukem 1823: siglongjmp(abortprox, 1);
1.1 cgd 1824: }
1825:
1.4 cgd 1826: void
1827: doproxy(argc, argv)
1.1 cgd 1828: int argc;
1829: char *argv[];
1830: {
1.4 cgd 1831: struct cmd *c;
1.14 lukem 1832: int cmdpos;
1.1 cgd 1833: sig_t oldintr;
1834:
1.76 lukem 1835: if ((argc == 0 && argv != NULL) ||
1836: (argc == 1 && !another(&argc, &argv, "command"))) {
1.37 lukem 1837: fprintf(ttyout, "usage: %s command\n", argv[0]);
1.1 cgd 1838: code = -1;
1839: return;
1840: }
1841: c = getcmd(argv[1]);
1842: if (c == (struct cmd *) -1) {
1.37 lukem 1843: fputs("?Ambiguous command.\n", ttyout);
1.1 cgd 1844: code = -1;
1845: return;
1846: }
1847: if (c == 0) {
1.37 lukem 1848: fputs("?Invalid command.\n", ttyout);
1.1 cgd 1849: code = -1;
1850: return;
1851: }
1852: if (!c->c_proxy) {
1.37 lukem 1853: fputs("?Invalid proxy command.\n", ttyout);
1.1 cgd 1854: code = -1;
1855: return;
1856: }
1.72 lukem 1857: if (sigsetjmp(abortprox, 1)) {
1.1 cgd 1858: code = -1;
1859: return;
1860: }
1.62 lukem 1861: oldintr = xsignal(SIGINT, proxabort);
1.1 cgd 1862: pswitch(1);
1863: if (c->c_conn && !connected) {
1.37 lukem 1864: fputs("Not connected.\n", ttyout);
1.1 cgd 1865: pswitch(0);
1.62 lukem 1866: (void)xsignal(SIGINT, oldintr);
1.1 cgd 1867: code = -1;
1868: return;
1869: }
1.14 lukem 1870: cmdpos = strcspn(line, " \t");
1871: if (cmdpos > 0) /* remove leading "proxy " from input buffer */
1872: memmove(line, line + cmdpos + 1, strlen(line) - cmdpos + 1);
1.1 cgd 1873: (*c->c_handler)(argc-1, argv+1);
1874: if (connected) {
1875: proxflag = 1;
1876: }
1877: else {
1878: proxflag = 0;
1879: }
1880: pswitch(0);
1.62 lukem 1881: (void)xsignal(SIGINT, oldintr);
1.1 cgd 1882: }
1883:
1.4 cgd 1884: void
1885: setcase(argc, argv)
1886: int argc;
1887: char *argv[];
1.1 cgd 1888: {
1.4 cgd 1889:
1.10 lukem 1890: code = togglevar(argc, argv, &mcase, "Case mapping");
1.1 cgd 1891: }
1892:
1.63 lukem 1893: /*
1894: * convert the given name to lower case if it's all upper case, into
1895: * a static buffer which is returned to the caller
1896: */
1897: char *
1898: docase(name)
1899: char *name;
1900: {
1901: static char new[MAXPATHLEN];
1902: int i, dochange;
1903:
1904: dochange = 1;
1905: for (i = 0; name[i] != '\0' && i < sizeof(new) - 1; i++) {
1906: new[i] = name[i];
1907: if (islower((unsigned char)new[i]))
1908: dochange = 0;
1909: }
1910: new[i] = '\0';
1911:
1912: if (dochange) {
1913: for (i = 0; new[i] != '\0'; i++)
1914: if (isupper((unsigned char)new[i]))
1915: new[i] = tolower(new[i]);
1916: }
1917: return (new);
1918: }
1919:
1.4 cgd 1920: void
1921: setcr(argc, argv)
1922: int argc;
1923: char *argv[];
1.1 cgd 1924: {
1.4 cgd 1925:
1.10 lukem 1926: code = togglevar(argc, argv, &crflag, "Carriage Return stripping");
1.1 cgd 1927: }
1928:
1.4 cgd 1929: void
1.10 lukem 1930: setntrans(argc, argv)
1.1 cgd 1931: int argc;
1932: char *argv[];
1933: {
1.76 lukem 1934:
1935: if ((argc == 0 && argv != NULL) || argc > 3) {
1936: fprintf(ttyout, "usage: %s [inchars [outchars]]\n", argv[0]);
1937: code = -1;
1938: return;
1939: }
1.1 cgd 1940: if (argc == 1) {
1941: ntflag = 0;
1.37 lukem 1942: fputs("Ntrans off.\n", ttyout);
1.1 cgd 1943: code = ntflag;
1944: return;
1945: }
1946: ntflag++;
1947: code = ntflag;
1.63 lukem 1948: (void)strlcpy(ntin, argv[1], sizeof(ntin));
1.1 cgd 1949: if (argc == 2) {
1950: ntout[0] = '\0';
1951: return;
1952: }
1.63 lukem 1953: (void)strlcpy(ntout, argv[2], sizeof(ntout));
1.1 cgd 1954: }
1955:
1956: char *
1957: dotrans(name)
1958: char *name;
1959: {
1960: static char new[MAXPATHLEN];
1961: char *cp1, *cp2 = new;
1.4 cgd 1962: int i, ostop, found;
1.1 cgd 1963:
1.4 cgd 1964: for (ostop = 0; *(ntout + ostop) && ostop < 16; ostop++)
1965: continue;
1.1 cgd 1966: for (cp1 = name; *cp1; cp1++) {
1967: found = 0;
1968: for (i = 0; *(ntin + i) && i < 16; i++) {
1969: if (*cp1 == *(ntin + i)) {
1970: found++;
1971: if (i < ostop) {
1972: *cp2++ = *(ntout + i);
1973: }
1974: break;
1975: }
1976: }
1977: if (!found) {
1978: *cp2++ = *cp1;
1979: }
1980: }
1981: *cp2 = '\0';
1.4 cgd 1982: return (new);
1.1 cgd 1983: }
1984:
1.4 cgd 1985: void
1.1 cgd 1986: setnmap(argc, argv)
1987: int argc;
1988: char *argv[];
1989: {
1990: char *cp;
1991:
1992: if (argc == 1) {
1993: mapflag = 0;
1.37 lukem 1994: fputs("Nmap off.\n", ttyout);
1.1 cgd 1995: code = mapflag;
1996: return;
1997: }
1.76 lukem 1998: if ((argc == 0 && argv != NULL) ||
1999: (argc < 3 && !another(&argc, &argv, "mapout")) || argc > 3) {
1.37 lukem 2000: fprintf(ttyout, "usage: %s [mapin mapout]\n", argv[0]);
1.1 cgd 2001: code = -1;
2002: return;
2003: }
2004: mapflag = 1;
2005: code = 1;
1.4 cgd 2006: cp = strchr(altarg, ' ');
1.1 cgd 2007: if (proxy) {
1.4 cgd 2008: while(*++cp == ' ')
2009: continue;
1.1 cgd 2010: altarg = cp;
1.4 cgd 2011: cp = strchr(altarg, ' ');
1.1 cgd 2012: }
2013: *cp = '\0';
1.63 lukem 2014: (void)strlcpy(mapin, altarg, MAXPATHLEN);
1.4 cgd 2015: while (*++cp == ' ')
2016: continue;
1.63 lukem 2017: (void)strlcpy(mapout, cp, MAXPATHLEN);
1.1 cgd 2018: }
2019:
2020: char *
2021: domap(name)
2022: char *name;
2023: {
2024: static char new[MAXPATHLEN];
1.4 cgd 2025: char *cp1 = name, *cp2 = mapin;
1.1 cgd 2026: char *tp[9], *te[9];
2027: int i, toks[9], toknum = 0, match = 1;
2028:
2029: for (i=0; i < 9; ++i) {
2030: toks[i] = 0;
2031: }
2032: while (match && *cp1 && *cp2) {
2033: switch (*cp2) {
2034: case '\\':
2035: if (*++cp2 != *cp1) {
2036: match = 0;
2037: }
2038: break;
2039: case '$':
2040: if (*(cp2+1) >= '1' && (*cp2+1) <= '9') {
2041: if (*cp1 != *(++cp2+1)) {
2042: toks[toknum = *cp2 - '1']++;
2043: tp[toknum] = cp1;
2044: while (*++cp1 && *(cp2+1)
2045: != *cp1);
2046: te[toknum] = cp1;
2047: }
2048: cp2++;
2049: break;
2050: }
2051: /* FALLTHROUGH */
2052: default:
2053: if (*cp2 != *cp1) {
2054: match = 0;
2055: }
2056: break;
2057: }
2058: if (match && *cp1) {
2059: cp1++;
2060: }
2061: if (match && *cp2) {
2062: cp2++;
2063: }
2064: }
2065: if (!match && *cp1) /* last token mismatch */
2066: {
2067: toks[toknum] = 0;
2068: }
2069: cp1 = new;
2070: *cp1 = '\0';
2071: cp2 = mapout;
2072: while (*cp2) {
2073: match = 0;
2074: switch (*cp2) {
2075: case '\\':
2076: if (*(cp2 + 1)) {
2077: *cp1++ = *++cp2;
2078: }
2079: break;
2080: case '[':
2081: LOOP:
1.36 christos 2082: if (*++cp2 == '$' &&
2083: isdigit((unsigned char)*(cp2+1))) {
1.1 cgd 2084: if (*++cp2 == '0') {
2085: char *cp3 = name;
2086:
2087: while (*cp3) {
2088: *cp1++ = *cp3++;
2089: }
2090: match = 1;
2091: }
2092: else if (toks[toknum = *cp2 - '1']) {
2093: char *cp3 = tp[toknum];
2094:
2095: while (cp3 != te[toknum]) {
2096: *cp1++ = *cp3++;
2097: }
2098: match = 1;
2099: }
2100: }
2101: else {
1.9 lukem 2102: while (*cp2 && *cp2 != ',' &&
1.1 cgd 2103: *cp2 != ']') {
2104: if (*cp2 == '\\') {
2105: cp2++;
2106: }
2107: else if (*cp2 == '$' &&
1.36 christos 2108: isdigit((unsigned char)*(cp2+1))) {
1.1 cgd 2109: if (*++cp2 == '0') {
2110: char *cp3 = name;
2111:
2112: while (*cp3) {
2113: *cp1++ = *cp3++;
2114: }
2115: }
2116: else if (toks[toknum =
2117: *cp2 - '1']) {
2118: char *cp3=tp[toknum];
2119:
2120: while (cp3 !=
2121: te[toknum]) {
2122: *cp1++ = *cp3++;
2123: }
2124: }
2125: }
2126: else if (*cp2) {
2127: *cp1++ = *cp2++;
2128: }
2129: }
2130: if (!*cp2) {
1.37 lukem 2131: fputs(
2132: "nmap: unbalanced brackets.\n",
2133: ttyout);
1.4 cgd 2134: return (name);
1.1 cgd 2135: }
2136: match = 1;
2137: cp2--;
2138: }
2139: if (match) {
2140: while (*++cp2 && *cp2 != ']') {
2141: if (*cp2 == '\\' && *(cp2 + 1)) {
2142: cp2++;
2143: }
2144: }
2145: if (!*cp2) {
1.37 lukem 2146: fputs(
2147: "nmap: unbalanced brackets.\n",
2148: ttyout);
1.4 cgd 2149: return (name);
1.1 cgd 2150: }
2151: break;
2152: }
2153: switch (*++cp2) {
2154: case ',':
2155: goto LOOP;
2156: case ']':
2157: break;
2158: default:
2159: cp2--;
2160: goto LOOP;
2161: }
2162: break;
2163: case '$':
1.36 christos 2164: if (isdigit((unsigned char)*(cp2 + 1))) {
1.1 cgd 2165: if (*++cp2 == '0') {
2166: char *cp3 = name;
2167:
2168: while (*cp3) {
2169: *cp1++ = *cp3++;
2170: }
2171: }
2172: else if (toks[toknum = *cp2 - '1']) {
2173: char *cp3 = tp[toknum];
2174:
2175: while (cp3 != te[toknum]) {
2176: *cp1++ = *cp3++;
2177: }
2178: }
2179: break;
2180: }
2181: /* intentional drop through */
2182: default:
2183: *cp1++ = *cp2;
2184: break;
2185: }
2186: cp2++;
2187: }
2188: *cp1 = '\0';
2189: if (!*new) {
1.4 cgd 2190: return (name);
1.1 cgd 2191: }
1.4 cgd 2192: return (new);
1.1 cgd 2193: }
2194:
1.4 cgd 2195: void
1.5 cgd 2196: setpassive(argc, argv)
2197: int argc;
2198: char *argv[];
2199: {
2200:
1.76 lukem 2201: if (argc == 1) {
2202: passivemode = !passivemode;
2203: activefallback = passivemode;
2204: } else if (argc != 2) {
2205: passiveusage:
2206: fprintf(ttyout, "usage: %s [ on | off | auto ]\n", argv[0]);
2207: code = -1;
2208: return;
2209: } else if (strcasecmp(argv[1], "on") == 0) {
2210: passivemode = 1;
2211: activefallback = 0;
2212: } else if (strcasecmp(argv[1], "off") == 0) {
2213: passivemode = 0;
2214: activefallback = 0;
2215: } else if (strcasecmp(argv[1], "auto") == 0) {
2216: passivemode = 1;
2217: activefallback = 1;
2218: } else
2219: goto passiveusage;
2220: fprintf(ttyout, "Passive mode: %s; fallback to active mode: %s.\n",
2221: onoff(passivemode), onoff(activefallback));
2222: code = passivemode;
1.5 cgd 2223: }
2224:
2225: void
1.68 lukem 2226: setepsv4(argc, argv)
2227: int argc;
2228: char *argv[];
2229: {
2230:
2231: code = togglevar(argc, argv, &epsv4,
2232: verbose ? "EPSV/EPRT on IPv4" : NULL);
2233: epsv4bad = 0;
2234: }
2235:
2236: void
1.4 cgd 2237: setsunique(argc, argv)
2238: int argc;
2239: char *argv[];
1.1 cgd 2240: {
1.4 cgd 2241:
1.10 lukem 2242: code = togglevar(argc, argv, &sunique, "Store unique");
1.1 cgd 2243: }
2244:
1.4 cgd 2245: void
2246: setrunique(argc, argv)
2247: int argc;
2248: char *argv[];
1.1 cgd 2249: {
1.4 cgd 2250:
1.10 lukem 2251: code = togglevar(argc, argv, &runique, "Receive unique");
1.1 cgd 2252: }
2253:
1.52 lukem 2254: int
2255: parserate(argc, argv, cmdlineopt)
2256: int argc;
2257: char *argv[];
2258: int cmdlineopt;
2259: {
2260: int dir, max, incr, showonly;
2261: sig_t oldusr1, oldusr2;
2262:
2263: if (argc > 4 || (argc < (cmdlineopt ? 3 : 2))) {
2264: usage:
2265: if (cmdlineopt)
2266: fprintf(ttyout,
1.66 lukem 2267: "usage: %s (all|get|put),maximum-bytes[,increment-bytes]]\n",
1.52 lukem 2268: argv[0]);
2269: else
2270: fprintf(ttyout,
1.66 lukem 2271: "usage: %s (all|get|put) [maximum-bytes [increment-bytes]]\n",
1.52 lukem 2272: argv[0]);
2273: return -1;
2274: }
2275: dir = max = incr = showonly = 0;
1.76 lukem 2276: #define RATE_GET 1
2277: #define RATE_PUT 2
2278: #define RATE_ALL (RATE_GET | RATE_PUT)
1.52 lukem 2279:
2280: if (strcasecmp(argv[1], "all") == 0)
2281: dir = RATE_ALL;
2282: else if (strcasecmp(argv[1], "get") == 0)
2283: dir = RATE_GET;
2284: else if (strcasecmp(argv[1], "put") == 0)
2285: dir = RATE_PUT;
2286: else
2287: goto usage;
2288:
2289: if (argc >= 3) {
2290: if ((max = strsuftoi(argv[2])) < 0)
2291: goto usage;
2292: } else
2293: showonly = 1;
2294:
2295: if (argc == 4) {
2296: if ((incr = strsuftoi(argv[3])) <= 0)
2297: goto usage;
2298: } else
2299: incr = DEFAULTINCR;
2300:
1.62 lukem 2301: oldusr1 = xsignal(SIGUSR1, SIG_IGN);
2302: oldusr2 = xsignal(SIGUSR2, SIG_IGN);
1.52 lukem 2303: if (dir & RATE_GET) {
2304: if (!showonly) {
2305: rate_get = max;
2306: rate_get_incr = incr;
2307: }
2308: if (!cmdlineopt || verbose)
2309: fprintf(ttyout,
1.53 lukem 2310: "Get transfer rate throttle: %s; maximum: %d; increment %d.\n",
1.52 lukem 2311: onoff(rate_get), rate_get, rate_get_incr);
2312: }
2313: if (dir & RATE_PUT) {
2314: if (!showonly) {
2315: rate_put = max;
2316: rate_put_incr = incr;
2317: }
2318: if (!cmdlineopt || verbose)
2319: fprintf(ttyout,
1.53 lukem 2320: "Put transfer rate throttle: %s; maximum: %d; increment %d.\n",
1.52 lukem 2321: onoff(rate_put), rate_put, rate_put_incr);
2322: }
1.62 lukem 2323: (void)xsignal(SIGUSR1, oldusr1);
2324: (void)xsignal(SIGUSR2, oldusr2);
1.52 lukem 2325: return 0;
2326: }
2327:
2328: void
2329: setrate(argc, argv)
2330: int argc;
2331: char *argv[];
2332: {
2333:
2334: code = parserate(argc, argv, 0);
2335: }
2336:
1.16 lukem 2337: /* change directory to parent directory */
1.4 cgd 2338: void
2339: cdup(argc, argv)
2340: int argc;
2341: char *argv[];
1.1 cgd 2342: {
1.16 lukem 2343: int r;
1.4 cgd 2344:
1.76 lukem 2345: if (argc == 0 && argv != NULL) {
2346: fprintf(ttyout, "usage: %s\n", argv[0]);
2347: code = -1;
2348: return;
2349: }
1.16 lukem 2350: r = command("CDUP");
2351: if (r == ERROR && code == 500) {
1.1 cgd 2352: if (verbose)
1.37 lukem 2353: fputs("CDUP command not recognized, trying XCUP.\n",
2354: ttyout);
1.16 lukem 2355: r = command("XCUP");
1.1 cgd 2356: }
1.79 ! lukem 2357: if (r == COMPLETE) {
1.16 lukem 2358: dirchange = 1;
1.79 ! lukem 2359: updateremotepwd();
! 2360: }
1.1 cgd 2361: }
2362:
1.27 lukem 2363: /*
2364: * Restart transfer at specific point
2365: */
1.4 cgd 2366: void
1.1 cgd 2367: restart(argc, argv)
2368: int argc;
2369: char *argv[];
2370: {
1.4 cgd 2371:
1.76 lukem 2372: if ((argc == 0 && argv != NULL) || argc > 2) {
1.37 lukem 2373: fprintf(ttyout, "usage: %s [restart_point]\n", argv[0]);
1.31 lukem 2374: code = -1;
2375: return;
2376: }
2377: if (argc == 2) {
1.60 lukem 2378: off_t rp;
1.31 lukem 2379: char *ep;
2380:
1.36 christos 2381: #ifndef NO_QUAD
1.31 lukem 2382: rp = strtoq(argv[1], &ep, 10);
1.36 christos 2383: #else
2384: rp = strtol(argv[1], &ep, 10);
2385: #endif
1.31 lukem 2386: if (rp < 0 || *ep != '\0')
1.37 lukem 2387: fprintf(ttyout, "restart: Invalid offset `%s'\n",
2388: argv[1]);
1.31 lukem 2389: else
2390: restart_point = rp;
1.1 cgd 2391: }
1.31 lukem 2392: if (restart_point == 0)
1.37 lukem 2393: fputs("No restart point defined.\n", ttyout);
1.31 lukem 2394: else
1.37 lukem 2395: fprintf(ttyout,
1.36 christos 2396: #ifndef NO_QUAD
1.61 lukem 2397: "Restarting at %lld for next get, put or append\n",
1.31 lukem 2398: (long long)restart_point);
1.36 christos 2399: #else
1.37 lukem 2400: "Restarting at %ld for next get, put or append\n",
1.36 christos 2401: (long)restart_point);
2402: #endif
1.1 cgd 2403: }
2404:
1.47 lukem 2405: /*
1.27 lukem 2406: * Show remote system type
2407: */
1.4 cgd 2408: void
2409: syst(argc, argv)
2410: int argc;
2411: char *argv[];
1.1 cgd 2412: {
1.4 cgd 2413:
1.76 lukem 2414: if (argc == 0 && argv != NULL) {
2415: fprintf(ttyout, "usage: %s\n", argv[0]);
2416: code = -1;
2417: return;
2418: }
1.19 lukem 2419: (void)command("SYST");
1.1 cgd 2420: }
2421:
1.4 cgd 2422: void
1.1 cgd 2423: macdef(argc, argv)
2424: int argc;
2425: char *argv[];
2426: {
2427: char *tmp;
2428: int c;
2429:
1.76 lukem 2430: if (argc == 0 && argv != NULL)
2431: goto usage;
1.1 cgd 2432: if (macnum == 16) {
1.37 lukem 2433: fputs("Limit of 16 macros have already been defined.\n",
2434: ttyout);
1.1 cgd 2435: code = -1;
2436: return;
2437: }
1.10 lukem 2438: if ((argc < 2 && !another(&argc, &argv, "macro name")) || argc > 2) {
1.76 lukem 2439: usage:
1.37 lukem 2440: fprintf(ttyout, "usage: %s macro_name\n", argv[0]);
1.1 cgd 2441: code = -1;
2442: return;
2443: }
1.19 lukem 2444: if (interactive)
1.37 lukem 2445: fputs(
2446: "Enter macro line by line, terminating it with a null line.\n",
2447: ttyout);
1.63 lukem 2448: (void)strlcpy(macros[macnum].mac_name, argv[1],
2449: sizeof(macros[macnum].mac_name));
1.19 lukem 2450: if (macnum == 0)
1.1 cgd 2451: macros[macnum].mac_start = macbuf;
1.19 lukem 2452: else
1.1 cgd 2453: macros[macnum].mac_start = macros[macnum - 1].mac_end + 1;
2454: tmp = macros[macnum].mac_start;
2455: while (tmp != macbuf+4096) {
2456: if ((c = getchar()) == EOF) {
1.37 lukem 2457: fputs("macdef: end of file encountered.\n", ttyout);
1.1 cgd 2458: code = -1;
2459: return;
2460: }
2461: if ((*tmp = c) == '\n') {
2462: if (tmp == macros[macnum].mac_start) {
2463: macros[macnum++].mac_end = tmp;
2464: code = 0;
2465: return;
2466: }
2467: if (*(tmp-1) == '\0') {
2468: macros[macnum++].mac_end = tmp - 1;
2469: code = 0;
2470: return;
2471: }
2472: *tmp = '\0';
2473: }
2474: tmp++;
2475: }
2476: while (1) {
2477: while ((c = getchar()) != '\n' && c != EOF)
2478: /* LOOP */;
2479: if (c == EOF || getchar() == '\n') {
1.37 lukem 2480: fputs("Macro not defined - 4K buffer exceeded.\n",
2481: ttyout);
1.1 cgd 2482: code = -1;
2483: return;
2484: }
2485: }
2486: }
2487:
2488: /*
1.27 lukem 2489: * Get size of file on remote machine
1.1 cgd 2490: */
1.4 cgd 2491: void
1.1 cgd 2492: sizecmd(argc, argv)
2493: int argc;
2494: char *argv[];
2495: {
1.11 lukem 2496: off_t size;
1.1 cgd 2497:
1.76 lukem 2498: if ((argc == 1 && !another(&argc, &argv, "remote-file")) ||
2499: (argc == 0 && argv != NULL) || argc > 2) {
2500: fprintf(ttyout, "usage: %s remote-file\n", argv[0]);
1.1 cgd 2501: code = -1;
2502: return;
2503: }
1.13 lukem 2504: size = remotesize(argv[1], 1);
1.11 lukem 2505: if (size != -1)
1.37 lukem 2506: fprintf(ttyout,
1.36 christos 2507: #ifndef NO_QUAD
1.61 lukem 2508: "%s\t%lld\n", argv[1], (long long)size);
1.36 christos 2509: #else
1.37 lukem 2510: "%s\t%ld\n", argv[1], (long)size);
1.36 christos 2511: #endif
1.76 lukem 2512: code = (size > 0);
1.10 lukem 2513: }
2514:
2515: /*
1.27 lukem 2516: * Get last modification time of file on remote machine
1.10 lukem 2517: */
2518: void
2519: modtime(argc, argv)
2520: int argc;
2521: char *argv[];
2522: {
2523: time_t mtime;
2524:
1.76 lukem 2525: if ((argc == 1 && !another(&argc, &argv, "remote-file")) ||
2526: (argc == 0 && argv != NULL) || argc > 2) {
2527: fprintf(ttyout, "usage: %s remote-file\n", argv[0]);
1.10 lukem 2528: code = -1;
2529: return;
2530: }
1.13 lukem 2531: mtime = remotemodtime(argv[1], 1);
1.10 lukem 2532: if (mtime != -1)
1.37 lukem 2533: fprintf(ttyout, "%s\t%s", argv[1], asctime(localtime(&mtime)));
1.76 lukem 2534: code = (mtime > 0);
1.1 cgd 2535: }
2536:
2537: /*
1.27 lukem 2538: * Show status on remote machine
1.1 cgd 2539: */
1.4 cgd 2540: void
1.1 cgd 2541: rmtstatus(argc, argv)
2542: int argc;
2543: char *argv[];
2544: {
1.4 cgd 2545:
1.76 lukem 2546: if (argc == 0 && argv != NULL) {
2547: fprintf(ttyout, "usage: %s [remote-file]\n", argv[0]);
2548: code = -1;
2549: return;
2550: }
1.19 lukem 2551: (void)command(argc > 1 ? "STAT %s" : "STAT" , argv[1]);
1.1 cgd 2552: }
2553:
2554: /*
1.27 lukem 2555: * Get file if modtime is more recent than current file
1.1 cgd 2556: */
1.4 cgd 2557: void
1.1 cgd 2558: newer(argc, argv)
2559: int argc;
2560: char *argv[];
2561: {
1.4 cgd 2562:
1.1 cgd 2563: if (getit(argc, argv, -1, "w"))
1.37 lukem 2564: fprintf(ttyout,
2565: "Local file \"%s\" is newer than remote file \"%s\".\n",
2566: argv[2], argv[1]);
1.19 lukem 2567: }
2568:
2569: /*
1.76 lukem 2570: * Display one local file through $PAGER.
1.19 lukem 2571: */
2572: void
1.63 lukem 2573: lpage(argc, argv)
1.19 lukem 2574: int argc;
2575: char *argv[];
2576: {
1.63 lukem 2577: int len;
2578: char *p, *pager, *locfile;
1.19 lukem 2579:
1.76 lukem 2580: if ((argc == 0 && argv != NULL) ||
2581: (argc == 1 && !another(&argc, &argv, "local-file")) || argc > 2) {
2582: fprintf(ttyout, "usage: %s local-file\n", argv[0]);
1.19 lukem 2583: code = -1;
2584: return;
2585: }
1.63 lukem 2586: if ((locfile = globulize(argv[1])) == NULL) {
2587: code = -1;
2588: return;
2589: }
1.76 lukem 2590: p = getoptionvalue("pager");
2591: if (EMPTYSTRING(p))
2592: p = DEFAULTPAGER;
1.63 lukem 2593: len = strlen(p) + strlen(locfile) + 2;
2594: pager = xmalloc(len);
2595: (void)strlcpy(pager, p, len);
2596: (void)strlcat(pager, " ", len);
2597: (void)strlcat(pager, locfile, len);
2598: system(pager);
1.76 lukem 2599: code = 0;
1.63 lukem 2600: (void)free(pager);
2601: (void)free(locfile);
2602: }
2603:
2604: /*
1.76 lukem 2605: * Display one remote file through $PAGER.
1.63 lukem 2606: */
2607: void
2608: page(argc, argv)
2609: int argc;
2610: char *argv[];
2611: {
2612: int ohash, orestart_point, overbose, len;
2613: char *p, *pager;
2614:
1.76 lukem 2615: if ((argc == 0 && argv != NULL) ||
2616: (argc == 1 && !another(&argc, &argv, "remote-file")) || argc > 2) {
2617: fprintf(ttyout, "usage: %s remote-file\n", argv[0]);
1.19 lukem 2618: code = -1;
2619: return;
2620: }
1.76 lukem 2621: p = getoptionvalue("pager");
2622: if (EMPTYSTRING(p))
2623: p = DEFAULTPAGER;
1.49 lukem 2624: len = strlen(p) + 2;
2625: pager = xmalloc(len);
1.57 lukem 2626: pager[0] = '|';
1.63 lukem 2627: (void)strlcpy(pager + 1, p, len - 1);
1.19 lukem 2628:
2629: ohash = hash;
1.37 lukem 2630: orestart_point = restart_point;
1.19 lukem 2631: overbose = verbose;
1.37 lukem 2632: hash = restart_point = verbose = 0;
1.27 lukem 2633: recvrequest("RETR", pager, argv[1], "r+w", 1, 0);
1.19 lukem 2634: hash = ohash;
1.37 lukem 2635: restart_point = orestart_point;
1.19 lukem 2636: verbose = overbose;
1.63 lukem 2637: (void)free(pager);
1.39 thorpej 2638: }
2639:
2640: /*
1.58 lukem 2641: * Set the socket send or receive buffer size.
1.39 thorpej 2642: */
2643: void
1.58 lukem 2644: setxferbuf(argc, argv)
1.39 thorpej 2645: int argc;
2646: char *argv[];
2647: {
1.58 lukem 2648: int size, dir;
1.39 thorpej 2649:
2650: if (argc != 2) {
1.58 lukem 2651: usage:
2652: fprintf(ttyout, "usage: %s size\n", argv[0]);
1.39 thorpej 2653: code = -1;
2654: return;
2655: }
1.58 lukem 2656: if (strcasecmp(argv[0], "sndbuf") == 0)
2657: dir = RATE_PUT;
2658: else if (strcasecmp(argv[0], "rcvbuf") == 0)
2659: dir = RATE_GET;
2660: else if (strcasecmp(argv[0], "xferbuf") == 0)
2661: dir = RATE_ALL;
1.39 thorpej 2662: else
1.58 lukem 2663: goto usage;
1.39 thorpej 2664:
1.58 lukem 2665: if ((size = strsuftoi(argv[1])) == -1)
2666: goto usage;
1.39 thorpej 2667:
1.58 lukem 2668: if (size == 0) {
2669: fprintf(ttyout, "%s: size must be positive.\n", argv[0]);
2670: goto usage;
1.39 thorpej 2671: }
2672:
1.58 lukem 2673: if (dir & RATE_PUT)
2674: sndbuf_size = size;
2675: if (dir & RATE_GET)
2676: rcvbuf_size = size;
2677: fprintf(ttyout, "Socket buffer sizes: send %d, receive %d.\n",
2678: sndbuf_size, rcvbuf_size);
1.76 lukem 2679: code = 0;
2680: }
2681:
2682: /*
2683: * Set or display options (defaults are provided by various env vars)
2684: */
2685: void
2686: setoption(argc, argv)
2687: int argc;
2688: char *argv[];
2689: {
2690: struct option *o;
2691:
2692: code = -1;
2693: if ((argc == 0 && argv != NULL) || (argc != 1 && argc != 3)) {
2694: fprintf(ttyout, "usage: %s [option value]\n", argv[0]);
2695: return;
2696: }
2697:
2698: #define OPTIONINDENT ((int) sizeof("http_proxy"))
2699: if (argc == 1) {
2700: for (o = optiontab; o->name != NULL; o++) {
2701: fprintf(ttyout, "%-*s\t%s\n", OPTIONINDENT,
2702: o->name, o->value ? o->value : "");
2703: }
2704: } else {
2705: o = getoption(argv[1]);
2706: if (o == NULL) {
2707: fprintf(ttyout, "No such option `%s'.\n", argv[1]);
2708: return;
2709: }
2710: FREEPTR(o->value);
2711: o->value = xstrdup(argv[2]);
2712: if (verbose)
2713: fprintf(ttyout, "Setting `%s' to `%s'.\n",
2714: o->name, o->value);
2715: }
2716: code = 0;
2717: }
2718:
2719: /*
2720: * Unset an option
2721: */
2722: void
2723: unsetoption(argc, argv)
2724: int argc;
2725: char *argv[];
2726: {
2727: struct option *o;
2728:
2729: code = -1;
2730: if ((argc == 0 && argv != NULL) || argc != 2) {
2731: fprintf(ttyout, "usage: %s option\n", argv[0]);
2732: return;
2733: }
2734:
2735: o = getoption(argv[1]);
2736: if (o == NULL) {
2737: fprintf(ttyout, "No such option `%s'.\n", argv[1]);
2738: return;
2739: }
2740: FREEPTR(o->value);
2741: fprintf(ttyout, "Unsetting `%s'.\n", o->name);
2742: code = 0;
1.1 cgd 2743: }
CVSweb <webmaster@jp.NetBSD.org>