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