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

Defined functions

account defined in line 1353; used 2 times
cd defined in line 817; used 2 times
cdup defined in line 1748; used 2 times
confirm defined in line 1303; used 13 times
delete defined in line 869; used 2 times
disconnect defined in line 1284; used 6 times
domap defined in line 1567; used 7 times
doproxy defined in line 1397; used 2 times
dotrans defined in line 1500; used 7 times
fatal defined in line 1316; used 2 times
get defined in line 415; used 3 times
globulize defined in line 1330; used 5 times
lcd defined in line 841; used 2 times
ls defined in line 976; used 3 times
mabort defined in line 481; used 8 times
macdef defined in line 1753; used 2 times
makedir defined in line 1177; used 2 times
mdelete defined in line 892; used 2 times
mget defined in line 504; used 2 times
mls defined in line 1002; used 3 times
mput defined in line 289; used 2 times
onoff defined in line 634; used 22 times
proxabort defined in line 1380; used 2 times
put defined in line 227; used 4 times
pwd defined in line 1168; used 2 times
quit defined in line 1269; used 4 times
quote defined in line 1223; used 2 times
remglob defined in line 573; used 5 times
removedir defined in line 1200; used 2 times
renamefile defined in line 940; used 2 times
rmthelp defined in line 1255; used 2 times
setascii defined in line 162; used 10 times
setbell defined in line 700; used 2 times
setbinary defined in line 152; used 13 times
setcase defined in line 1464; used 2 times
setcr defined in line 1471; used 2 times
setdebug defined in line 790; used 2 times
setebcdic defined in line 182; used 11 times
setform defined in line 204; used 2 times
setglob defined in line 777; used 2 times
sethash defined in line 724; used 2 times
setmode defined in line 192; used 2 times
setnmap defined in line 1528; used 2 times
setntrans defined in line 1478; used 2 times
setpeer defined in line 43; used 3 times
setport defined in line 751; used 2 times
setprompt defined in line 764; used 2 times
setrunique defined in line 1740; used 2 times
setstruct defined in line 216; used 2 times
setsunique defined in line 1733; used 2 times
settenex defined in line 172; used 13 times
settrace defined in line 712; used 2 times
settype defined in line 105; used 6 times
setverbose defined in line 739; used 2 times
shell defined in line 1062; used 12 times
status defined in line 646; used 4 times
user defined in line 1118; used 2 times

Defined variables

abortprox defined in line 1378; used 3 times
jabort defined in line 36; used 11 times
mname defined in line 35; used 5 times
sccsid defined in line 8; never used
types defined in line 93; used 2 times

Defined struct's

types defined in line 88; used 2 times
  • in line 108(2)
Last modified: 1986-03-07
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 6622
Valid CSS Valid XHTML 1.0 Strict