# 2.11BSD#431 - /usr/src/ucb/ftp/ftp.c

##### Functions

    abortpt           X
    abortrecv         X
    abortsend         X
    cmdabort          X
    command           X
    dataconn          X
    empty             X
    getreply          X
    gunique           X
    hookup            X
    initconn          X
    login             X
    proxtrans         X
    psabort           X
    pswitch           X
    ptransfer         X
    recvrequest       X
    reset             X
    sendrequest       X
    tvsub             X

##### Variables

    abrtflag          X
    allbinary         X
    connected         X
    data              X
    data_addr         X
    hisctladdr        X
    myctladdr         X
    ptabflg           X
    ptabort           X
    ptflag            X
    recvabort         X
    reply_string      X
    restart_point     X
    sendabort         X
    sendport          X

##### Macros

    FD_CLR            X
    FD_ISSET          X
    FD_SET            X
    FD_SETSIZE        X
    FD_ZERO           X
    HASHBYTES         X
    MAXHOSTNAMELEN    X
    NBBY              X
    NFDBITS           X
    UC                X
    howmany           X
    nz                X

##### struct's

    comvars           X

       1: /*
       2:  * Copyright (c) 1985, 1989 Regents of the University of California.
       3:  * All rights reserved.
       4:  *
       5:  * Redistribution and use in source and binary forms are permitted
       6:  * provided that the above copyright notice and this paragraph are
       7:  * duplicated in all such forms and that any documentation,
       8:  * advertising materials, and other materials related to such
       9:  * distribution and use acknowledge that the software was developed
      10:  * by the University of California, Berkeley.  The name of the
      11:  * University may not be used to endorse or promote products derived
      12:  * from this software without specific prior written permission.
      13:  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
      14:  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
      15:  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
      16:  */
      17:
      18: #if !defined(lint) && defined(DOSCCS)
      19: static char sccsid[] = "@(#)ftp.c	5.28.1 (2.11BSD) 1997/10/2";
      20: #endif
      21:
      22: #include <sys/param.h>
      23: #include <sys/stat.h>
      24: #include <sys/ioctl.h>
      25: #include <sys/socket.h>
      26: #include <sys/time.h>
      27: #include <sys/file.h>
      28:
      29: #include <netinet/in.h>
      30: #include <arpa/ftp.h>
      31: #include <arpa/telnet.h>
      32: #include <arpa/inet.h>
      33:
      34: #include <stdio.h>
      35: #include <signal.h>
      36: #include <errno.h>
      37: #include <netdb.h>
      38: #include <fcntl.h>
      39: #include <pwd.h>
      40: #include <unistd.h>
      41: #include <varargs.h>
      42:
      43: #include "ftp_var.h"
      44:
      45: #ifndef MAXHOSTNAMELEN
      46: #define MAXHOSTNAMELEN 64
      47: #endif
      48:
      49: #ifdef sun
      50: /* FD_SET wasn't defined until 4.0. its a cheap test for uid_t  presence */
      51: #ifndef FD_SET
      52: #define NBBY    8       /* number of bits in a byte */
      53: /*
      54:  * Select uses bit masks of file descriptors in longs.
      55:  * These macros manipulate such bit fields (the filesystem macros use chars).
      56:  * FD_SETSIZE may be defined by the user, but the default here
      57:  * should be >= NOFILE (param.h).
      58:  */
      59: #ifndef FD_SETSIZE
      60: #define FD_SETSIZE  256
      61: #endif
      62:
      63: typedef long    fd_mask;
      64: #define NFDBITS (sizeof(fd_mask) * NBBY)    /* bits per mask */
      65: #ifndef howmany
      66: #define howmany(x, y)   (((x)+((y)-1))/(y))
      67: #endif
      68:
      69: #define FD_SET(n, p)    ((p)->fds_bits[(n)/NFDBITS] |= (1 << ((n) % NFDBITS)))
      70: #define FD_CLR(n, p)    ((p)->fds_bits[(n)/NFDBITS] &= ~(1 << ((n) % NFDBITS)))
      71: #define FD_ISSET(n, p)  ((p)->fds_bits[(n)/NFDBITS] & (1 << ((n) % NFDBITS)))
      72: #define FD_ZERO(p)  bzero((char *)(p), sizeof(*(p)))
      73:
      74: typedef int uid_t;
      75: typedef int gid_t;
      76: #endif
      77: #endif
      78:
      79: struct  sockaddr_in hisctladdr;
      80: struct  sockaddr_in data_addr;
      81: int data = -1;
      82: int abrtflag = 0;
      83: int ptflag = 0;
      84: int connected;
      85: int allbinary;
      86: struct  sockaddr_in myctladdr;
      87: uid_t   getuid();
      88: off_t   restart_point = 0;
      89:
      90: FILE    *cin, *cout;
      91: FILE    *dataconn();
      92:
      93: char *
      94: hookup(host, port)
      95:     char *host;
      96:     int port;
      97: {
      98:     register struct hostent *hp = 0;
      99:     int s,len;
     100:     static char hostnamebuf[80];
     101:
     102:     bzero((char *)&hisctladdr, sizeof (hisctladdr));
     103:     hisctladdr.sin_addr.s_addr = inet_addr(host);
     104:     if (hisctladdr.sin_addr.s_addr != -1) {
     105:         hisctladdr.sin_family = AF_INET;
     106:         (void) strncpy(hostnamebuf, host, sizeof(hostnamebuf));
     107:     } else {
     108:         hp = gethostbyname(host);
     109:         if (hp == NULL) {
     110:             fprintf(stderr, "ftp: %s: ", host);
     111:             herror((char *)NULL);
     112:             code = -1;
     113:             return((char *) 0);
     114:         }
     115:         hisctladdr.sin_family = hp->h_addrtype;
     116:         bcopy(hp->h_addr_list[0],
     117:             (caddr_t)&hisctladdr.sin_addr, hp->h_length);
     118:         (void) strncpy(hostnamebuf, hp->h_name, sizeof(hostnamebuf));
     119:     }
     120:     hostname = hostnamebuf;
     121:     s = socket(hisctladdr.sin_family, SOCK_STREAM, 0);
     122:     if (s < 0) {
     123:         perror("ftp: socket");
     124:         code = -1;
     125:         return (0);
     126:     }
     127:     hisctladdr.sin_port = port;
     128:     while (connect(s, &hisctladdr, sizeof (hisctladdr)) < 0) {
     129:         if (hp && hp->h_addr_list[1]) {
     130:             int oerrno = errno;
     131:
     132:             fprintf(stderr, "ftp: connect to address %s: ",
     133:                 inet_ntoa(hisctladdr.sin_addr));
     134:             errno = oerrno;
     135:             perror((char *) 0);
     136:             hp->h_addr_list++;
     137:             bcopy(hp->h_addr_list[0],
     138:                  (caddr_t)&hisctladdr.sin_addr, hp->h_length);
     139:             fprintf(stdout, "Trying %s...\n",
     140:                 inet_ntoa(hisctladdr.sin_addr));
     141:             (void) close(s);
     142:             s = socket(hisctladdr.sin_family, SOCK_STREAM, 0);
     143:             if (s < 0) {
     144:                 perror("ftp: socket");
     145:                 code = -1;
     146:                 return (0);
     147:             }
     148:             continue;
     149:         }
     150:         perror("ftp: connect");
     151:         code = -1;
     152:         goto bad;
     153:     }
     154:     len = sizeof (myctladdr);
     155:     if (getsockname(s, (char *)&myctladdr, &len) < 0) {
     156:         perror("ftp: getsockname");
     157:         code = -1;
     158:         goto bad;
     159:     }
     160:     cin = fdopen(s, "r");
     161:     cout = fdopen(s, "w");
     162:     if (cin == NULL || cout == NULL) {
     163:         fprintf(stderr, "ftp: fdopen failed.\n");
     164:         if (cin)
     165:             (void) fclose(cin);
     166:         if (cout)
     167:             (void) fclose(cout);
     168:         code = -1;
     169:         goto bad;
     170:     }
     171:     if (verbose)
     172:         printf("Connected to %s.\n", hostname);
     173:     if (getreply(0) > 2) {  /* read startup message from server */
     174:         if (cin)
     175:             (void) fclose(cin);
     176:         if (cout)
     177:             (void) fclose(cout);
     178:         code = -1;
     179:         goto bad;
     180:     }
     181: #ifdef SO_OOBINLINE
     182:     {
     183:     int on = 1;
     184:
     185:     if (setsockopt(s, SOL_SOCKET, SO_OOBINLINE, &on, sizeof(on))
     186:         < 0 && debug) {
     187:             perror("ftp: setsockopt");
     188:         }
     189:     }
     190: #endif SO_OOBINLINE
     191:
     192:     return (hostname);
     193: bad:
     194:     (void) close(s);
     195:     return ((char *)0);
     196: }
     197:
     198: login(host)
     199:     char *host;
     200: {
     201:     char tmp[80];
     202:     char *user, *pass, *acct;
     203:     int n, aflag = 0;
     204:
     205:     user = pass = acct = 0;
     206:     if (ruserpass(host, &user, &pass, &acct) < 0) {
     207:         code = -1;
     208:         return(0);
     209:     }
     210:     while (user == NULL) {
     211:         char *myname = getlogin();
     212:
     213:         if (myname == NULL) {
     214:             struct passwd *pp = getpwuid(getuid());
     215:
     216:             if (pp != NULL)
     217:                 myname = pp->pw_name;
     218:         }
     219:         if (myname)
     220:             printf("Name (%s:%s): ", host, myname);
     221:         else
     222:             printf("Name (%s): ", host);
     223:         (void) fgets(tmp, sizeof(tmp) - 1, stdin);
     224:         tmp[strlen(tmp) - 1] = '\0';
     225:         if (*tmp == '\0')
     226:             user = myname;
     227:         else
     228:             user = tmp;
     229:     }
     230:     n = command("USER %s", user);
     231:     if (n == CONTINUE) {
     232:         if (pass == NULL)
     233:             pass = getpass("Password:");
     234:         n = command("PASS %s", pass);
     235:     }
     236:     if (n == CONTINUE) {
     237:         aflag++;
     238:         acct = getpass("Account:");
     239:         n = command("ACCT %s", acct);
     240:     }
     241:     if (n != COMPLETE) {
     242:         fprintf(stderr, "Login failed.\n");
     243:         return (0);
     244:     }
     245:     if (!aflag && acct != NULL)
     246:         (void) command("ACCT %s", acct);
     247:     if (proxy)
     248:         return(1);
     249:     for (n = 0; n < macnum; ++n) {
     250:         if (!strcmp("init", macros[n].mac_name)) {
     251:             (void) strcpy(line, "$init");
     252:             makeargv();
     253:             domacro(margc, margv);
     254:             break;
     255:         }
     256:     }
     257:     return (1);
     258: }
     259:
     260: cmdabort()
     261: {
     262:     extern jmp_buf ptabort;
     263:
     264:     printf("\n");
     265:     (void) fflush(stdout);
     266:     abrtflag++;
     267:     if (ptflag)
     268:         longjmp(ptabort,1);
     269: }
     270:
     271: /*VARARGS1*/
     272: #ifdef pyr
     273: command(fmt, va_alist)
     274:     char *fmt;
     275: va_dcl
     276: #else
     277: command(fmt, args)
     278:     char *fmt;
     279: #endif /* !pyr */
     280: {
     281: #ifdef pyr
     282:     va_list ap;
     283: #endif /* pyr */
     284:     int r, (*oldintr)(), cmdabort();
     285:
     286:     abrtflag = 0;
     287:     if (debug) {
     288:         printf("---> ");
     289: #ifdef pyr
     290:         va_start(ap);
     291:         _doprnt(fmt, ap, stdout);
     292:         va_end(ap);
     293: #else
     294:         _doprnt(fmt, &args, stdout);
     295: #endif /* !pyr */
     296:         printf("\n");
     297:         (void) fflush(stdout);
     298:     }
     299:     if (cout == NULL) {
     300:         perror ("No control connection for command");
     301:         code = -1;
     302:         return (0);
     303:     }
     304:     oldintr = signal(SIGINT,cmdabort);
     305: #ifdef pyr
     306:     va_start(ap);
     307:     _doprnt(fmt, ap, cout);
     308:     va_end(ap);
     309: #else
     310:     _doprnt(fmt, &args, cout);
     311: #endif /* !pyr */
     312:     fprintf(cout, "\r\n");
     313:     (void) fflush(cout);
     314:     cpend = 1;
     315:     r = getreply(!strcmp(fmt, "QUIT"));
     316:     if (abrtflag && oldintr != SIG_IGN)
     317:         (*oldintr)();
     318:     (void) signal(SIGINT, oldintr);
     319:     return(r);
     320: }
     321:
     322: char reply_string[BUFSIZ];      /* last line of previous reply */
     323:
     324: #include <ctype.h>
     325:
     326: getreply(expecteof)
     327:     int expecteof;
     328: {
     329:     register int c, n;
     330:     register int dig;
     331:     register char *cp;
     332:     int originalcode = 0, continuation = 0, (*oldintr)(), cmdabort();
     333:     int pflag = 0;
     334:     char *pt = pasv;
     335:
     336:     oldintr = signal(SIGINT,cmdabort);
     337:     for (;;) {
     338:         dig = n = code = 0;
     339:         cp = reply_string;
     340:         while ((c = getc(cin)) != '\n') {
     341:             if (c == IAC) {     /* handle telnet commands */
     342:                 switch (c = getc(cin)) {
     343:                 case WILL:
     344:                 case WONT:
     345:                     c = getc(cin);
     346:                     fprintf(cout, "%c%c%c",IAC,DONT,c);
     347:                     (void) fflush(cout);
     348:                     break;
     349:                 case DO:
     350:                 case DONT:
     351:                     c = getc(cin);
     352:                     fprintf(cout, "%c%c%c",IAC,WONT,c);
     353:                     (void) fflush(cout);
     354:                     break;
     355:                 default:
     356:                     break;
     357:                 }
     358:                 continue;
     359:             }
     360:             dig++;
     361:             if (c == EOF) {
     362:                 if (expecteof) {
     363:                     (void) signal(SIGINT,oldintr);
     364:                     code = 221;
     365:                     return (0);
     366:                 }
     367:                 lostpeer();
     368:                 if (verbose) {
     369:                     printf("421 Service not available, remote server has closed connection\n");
     370:                     (void) fflush(stdout);
     371:                 }
     372:                 code = 421;
     373:                 return(4);
     374:             }
     375:             if (c != '\r' && (verbose > 0 ||
     376:                 (verbose > -1 && n == '5' && dig > 4))) {
     377:                 if (proxflag &&
     378:                    (dig == 1 || dig == 5 && verbose == 0))
     379:                     printf("%s:",hostname);
     380:                 (void) putchar(c);
     381:             }
     382:             if (dig < 4 && isdigit(c))
     383:                 code = code * 10 + (c - '0');
     384:             if (!pflag && code == 227)
     385:                 pflag = 1;
     386:             if (dig > 4 && pflag == 1 && isdigit(c))
     387:                 pflag = 2;
     388:             if (pflag == 2) {
     389:                 if (c != '\r' && c != ')')
     390:                     *pt++ = c;
     391:                 else {
     392:                     *pt = '\0';
     393:                     pflag = 3;
     394:                 }
     395:             }
     396:             if (dig == 4 && c == '-') {
     397:                 if (continuation)
     398:                     code = 0;
     399:                 continuation++;
     400:             }
     401:             if (n == 0)
     402:                 n = c;
     403:             if (cp < &reply_string[sizeof(reply_string) - 1])
     404:                 *cp++ = c;
     405:         }
     406:         if (verbose > 0 || verbose > -1 && n == '5') {
     407:             (void) putchar(c);
     408:             (void) fflush (stdout);
     409:         }
     410:         if (continuation && code != originalcode) {
     411:             if (originalcode == 0)
     412:                 originalcode = code;
     413:             continue;
     414:         }
     415:         *cp = '\0';
     416:         if (n != '1')
     417:             cpend = 0;
     418:         (void) signal(SIGINT,oldintr);
     419:         if (code == 421 || originalcode == 421)
     420:             lostpeer();
     421:         if (abrtflag && oldintr != cmdabort && oldintr != SIG_IGN)
     422:             (*oldintr)();
     423:         return (n - '0');
     424:     }
     425: }
     426:
     427: empty(mask, sec)
     428:     struct fd_set *mask;
     429:     int sec;
     430: {
     431:     struct timeval t;
     432:
     433:     t.tv_sec = (long) sec;
     434:     t.tv_usec = 0;
     435:     return(select(32, mask, (struct fd_set *) 0, (struct fd_set *) 0, &t));
     436: }
     437:
     438: jmp_buf sendabort;
     439:
     440: abortsend()
     441: {
     442:
     443:     mflag = 0;
     444:     abrtflag = 0;
     445:     printf("\nsend aborted\n");
     446:     (void) fflush(stdout);
     447:     longjmp(sendabort, 1);
     448: }
     449:
     450: #define HASHBYTES 1024
     451:
     452: sendrequest(cmd, local, remote, printnames)
     453:     char *cmd, *local, *remote;
     454:     int printnames;
     455: {
     456:     FILE *fin, *dout = 0, *popen();
     457:     int (*closefunc)(), pclose(), fclose(), (*oldintr)(), (*oldintp)();
     458:     int abortsend();
     459:     char buf[BUFSIZ], *bufp;
     460:     long bytes = 0, hashbytes = HASHBYTES;
     461:     register int c, d;
     462:     struct stat st;
     463:     struct timeval start, stop;
     464:     char *mode;
     465:
     466:     if (verbose && printnames) {
     467:         if (local && *local != '-')
     468:             printf("local: %s ", local);
     469:         if (remote)
     470:             printf("remote: %s\n", remote);
     471:     }
     472:     if (proxy) {
     473:         proxtrans(cmd, local, remote);
     474:         return;
     475:     }
     476:     closefunc = NULL;
     477:     oldintr = NULL;
     478:     oldintp = NULL;
     479:     mode = "w";
     480:     if (setjmp(sendabort)) {
     481:         while (cpend) {
     482:             (void) getreply(0);
     483:         }
     484:         if (data >= 0) {
     485:             (void) close(data);
     486:             data = -1;
     487:         }
     488:         if (oldintr)
     489:             (void) signal(SIGINT,oldintr);
     490:         if (oldintp)
     491:             (void) signal(SIGPIPE,oldintp);
     492:         code = -1;
     493:         return;
     494:     }
     495:     oldintr = signal(SIGINT, abortsend);
     496:     if (strcmp(local, "-") == 0)
     497:         fin = stdin;
     498:     else if (*local == '|') {
     499:         oldintp = signal(SIGPIPE,SIG_IGN);
     500:         fin = popen(local + 1, "r");
     501:         if (fin == NULL) {
     502:             perror(local + 1);
     503:             (void) signal(SIGINT, oldintr);
     504:             (void) signal(SIGPIPE, oldintp);
     505:             code = -1;
     506:             return;
     507:         }
     508:         closefunc = pclose;
     509:     } else {
     510:         fin = fopen(local, "r");
     511:         if (fin == NULL) {
     512:             perror(local);
     513:             (void) signal(SIGINT, oldintr);
     514:             code = -1;
     515:             return;
     516:         }
     517:         closefunc = fclose;
     518:         if (fstat(fileno(fin), &st) < 0 ||
     519:             (st.st_mode&S_IFMT) != S_IFREG) {
     520:             fprintf(stdout, "%s: not a plain file.\n", local);
     521:             (void) signal(SIGINT, oldintr);
     522:             fclose(fin);
     523:             code = -1;
     524:             return;
     525:         }
     526:     }
     527:     if (initconn()) {
     528:         (void) signal(SIGINT, oldintr);
     529:         if (oldintp)
     530:             (void) signal(SIGPIPE, oldintp);
     531:         code = -1;
     532:         if (closefunc != NULL)
     533:             (*closefunc)(fin);
     534:         return;
     535:     }
     536:     if (setjmp(sendabort))
     537:         goto abort;
     538:
     539:     if (restart_point &&
     540:         (strcmp(cmd, "STOR") == 0 || strcmp(cmd, "APPE") == 0)) {
     541:         if (fseek(fin, (long) restart_point, 0) < 0) {
     542:             perror(local);
     543:             restart_point = 0;
     544:             if (closefunc != NULL)
     545:                 (*closefunc)(fin);
     546:             return;
     547:         }
     548:         if (command("REST %ld", (long) restart_point)
     549:             != CONTINUE) {
     550:             restart_point = 0;
     551:             if (closefunc != NULL)
     552:                 (*closefunc)(fin);
     553:             return;
     554:         }
     555:         restart_point = 0;
     556:         mode = "r+w";
     557:     }
     558:     if (remote) {
     559:         if (command("%s %s", cmd, remote) != PRELIM) {
     560:             (void) signal(SIGINT, oldintr);
     561:             if (oldintp)
     562:                 (void) signal(SIGPIPE, oldintp);
     563:             if (closefunc != NULL)
     564:                 (*closefunc)(fin);
     565:             return;
     566:         }
     567:     } else
     568:         if (command("%s", cmd) != PRELIM) {
     569:             (void) signal(SIGINT, oldintr);
     570:             if (oldintp)
     571:                 (void) signal(SIGPIPE, oldintp);
     572:             if (closefunc != NULL)
     573:                 (*closefunc)(fin);
     574:             return;
     575:         }
     576:     dout = dataconn(mode);
     577:     if (dout == NULL)
     578:         goto abort;
     579:     (void) gettimeofday(&start, (struct timezone *)0);
     580:     oldintp = signal(SIGPIPE, SIG_IGN);
     581:     switch (type) {
     582:
     583:     case TYPE_I:
     584:     case TYPE_L:
     585:         errno = d = 0;
     586:         while ((c = read(fileno(fin), buf, sizeof (buf))) > 0) {
     587:             bytes += c;
     588:             for (bufp = buf; c > 0; c -= d, bufp += d)
     589:                 if ((d = write(fileno(dout), bufp, c)) <= 0)
     590:                     break;
     591:             if (hash) {
     592:                 while (bytes >= hashbytes) {
     593:                     (void) putchar('#');
     594:                     hashbytes += HASHBYTES;
     595:                 }
     596:                 (void) fflush(stdout);
     597:             }
     598:         }
     599:         if (hash && bytes > 0) {
     600:             if (bytes < HASHBYTES)
     601:                 (void) putchar('#');
     602:             (void) putchar('\n');
     603:             (void) fflush(stdout);
     604:         }
     605:         if (c < 0)
     606:             perror(local);
     607:         if (d <= 0) {
     608:             if (d == 0)
     609:                 fprintf(stderr, "netout: write returned 0?\n");
     610:             else if (errno != EPIPE)
     611:                 perror("netout");
     612:             bytes = -1;
     613:         }
     614:         break;
     615:
     616:     case TYPE_A:
     617:         while ((c = getc(fin)) != EOF) {
     618:             if (c == '\n') {
     619:                 while (hash && (bytes >= hashbytes)) {
     620:                     (void) putchar('#');
     621:                     (void) fflush(stdout);
     622:                     hashbytes += HASHBYTES;
     623:                 }
     624:                 if (ferror(dout))
     625:                     break;
     626:                 (void) putc('\r', dout);
     627:                 bytes++;
     628:             }
     629:             (void) putc(c, dout);
     630:             bytes++;
     631:     /*		if (c == '\r') {			  	*/
     632:     /*		(void)	putc('\0', dout);  /* this violates rfc */
     633:     /*			bytes++;				*/
     634:     /*		}                          			*/
     635:         }
     636:         if (hash) {
     637:             if (bytes < hashbytes)
     638:                 (void) putchar('#');
     639:             (void) putchar('\n');
     640:             (void) fflush(stdout);
     641:         }
     642:         if (ferror(fin))
     643:             perror(local);
     644:         if (ferror(dout)) {
     645:             if (errno != EPIPE)
     646:                 perror("netout");
     647:             bytes = -1;
     648:         }
     649:         break;
     650:     }
     651:     (void) gettimeofday(&stop, (struct timezone *)0);
     652:     if (closefunc != NULL)
     653:         (*closefunc)(fin);
     654:     (void) fclose(dout);
     655:     (void) getreply(0);
     656:     (void) signal(SIGINT, oldintr);
     657:     if (oldintp)
     658:         (void) signal(SIGPIPE, oldintp);
     659:     if (bytes > 0)
     660:         ptransfer("sent", bytes, &start, &stop);
     661:     return;
     662: abort:
     663:     (void) gettimeofday(&stop, (struct timezone *)0);
     664:     (void) signal(SIGINT, oldintr);
     665:     if (oldintp)
     666:         (void) signal(SIGPIPE, oldintp);
     667:     if (!cpend) {
     668:         code = -1;
     669:         return;
     670:     }
     671:     if (data >= 0) {
     672:         (void) close(data);
     673:         data = -1;
     674:     }
     675:     if (dout)
     676:         (void) fclose(dout);
     677:     (void) getreply(0);
     678:     code = -1;
     679:     if (closefunc != NULL && fin != NULL)
     680:         (*closefunc)(fin);
     681:     if (bytes > 0)
     682:         ptransfer("sent", bytes, &start, &stop);
     683: }
     684:
     685: jmp_buf recvabort;
     686:
     687: abortrecv()
     688: {
     689:
     690:     mflag = 0;
     691:     abrtflag = 0;
     692:     printf("\n");
     693:     (void) fflush(stdout);
     694:     longjmp(recvabort, 1);
     695: }
     696:
     697: recvrequest(cmd, local, remote, mode, printnames)
     698:     char *cmd, *local, *remote, *mode;
     699: {
     700:     FILE *fout, *din = 0, *popen();
     701:     int (*closefunc)(), pclose(), fclose(), (*oldintr)(), (*oldintp)();
     702:     int abortrecv(), oldverbose, oldtype = 0, is_retr, tcrflag, nfnd;
     703:     char *bufp, *gunique(), msg;
     704:     static char *buf;
     705:     static long bufsize;
     706:     long bytes = 0, hashbytes = HASHBYTES;
     707:     struct fd_set mask;
     708:     register int c, d;
     709:     struct timeval start, stop;
     710:     struct stat st;
     711:     extern char *malloc();
     712:
     713:     is_retr = strcmp(cmd, "RETR") == 0;
     714:     if (is_retr && verbose && printnames) {
     715:         if (local && *local != '-')
     716:             printf("local: %s ", local);
     717:         if (remote)
     718:             printf("remote: %s\n", remote);
     719:     }
     720:     if (proxy && is_retr) {
     721:         proxtrans(cmd, local, remote);
     722:         return;
     723:     }
     724:     closefunc = NULL;
     725:     oldintr = NULL;
     726:     oldintp = NULL;
     727:     tcrflag = !crflag && is_retr;
     728:     if (setjmp(recvabort)) {
     729:         while (cpend) {
     730:             (void) getreply(0);
     731:         }
     732:         if (data >= 0) {
     733:             (void) close(data);
     734:             data = -1;
     735:         }
     736:         if (oldintr)
     737:             (void) signal(SIGINT, oldintr);
     738:         code = -1;
     739:         return;
     740:     }
     741:     oldintr = signal(SIGINT, abortrecv);
     742:     if (strcmp(local, "-") && *local != '|') {
     743:         if (access(local, 2) < 0) {
     744:             char *dir = rindex(local, '/');
     745:
     746:             if (errno != ENOENT && errno != EACCES) {
     747:                 perror(local);
     748:                 (void) signal(SIGINT, oldintr);
     749:                 code = -1;
     750:                 return;
     751:             }
     752:             if (dir != NULL)
     753:                 *dir = 0;
     754:             d = access(dir ? local : ".", 2);
     755:             if (dir != NULL)
     756:                 *dir = '/';
     757:             if (d < 0) {
     758:                 perror(local);
     759:                 (void) signal(SIGINT, oldintr);
     760:                 code = -1;
     761:                 return;
     762:             }
     763:             if (!runique && errno == EACCES &&
     764:                 chmod(local, 0600) < 0) {
     765:                 perror(local);
     766:                 (void) signal(SIGINT, oldintr);
     767:                 code = -1;
     768:                 return;
     769:             }
     770:             if (runique && errno == EACCES &&
     771:                (local = gunique(local)) == NULL) {
     772:                 (void) signal(SIGINT, oldintr);
     773:                 code = -1;
     774:                 return;
     775:             }
     776:         }
     777:         else if (runique && (local = gunique(local)) == NULL) {
     778:             (void) signal(SIGINT, oldintr);
     779:             code = -1;
     780:             return;
     781:         }
     782:     }
     783:     if (initconn()) {
     784:         (void) signal(SIGINT, oldintr);
     785:         code = -1;
     786:         return;
     787:     }
     788:     if (setjmp(recvabort))
     789:         goto abort;
     790:     if (!is_retr) {
     791:         if (type != TYPE_A && (allbinary == 0 || type != TYPE_I)) {
     792:             oldtype = type;
     793:             oldverbose = verbose;
     794:             if (!debug)
     795:                 verbose = 0;
     796:             setascii();
     797:             verbose = oldverbose;
     798:         }
     799:     } else if (restart_point) {
     800:         if (command("REST %ld", (long) restart_point) != CONTINUE)
     801:             return;
     802:     }
     803:     if (remote) {
     804:         if (command("%s %s", cmd, remote) != PRELIM) {
     805:             (void) signal(SIGINT, oldintr);
     806:             if (oldtype) {
     807:                 if (!debug)
     808:                     verbose = 0;
     809:                 switch (oldtype) {
     810:                     case TYPE_I:
     811:                         setbinary();
     812:                         break;
     813:                     case TYPE_E:
     814:                         setebcdic();
     815:                         break;
     816:                     case TYPE_L:
     817:                         settenex();
     818:                         break;
     819:                 }
     820:                 verbose = oldverbose;
     821:             }
     822:             return;
     823:         }
     824:     } else {
     825:         if (command("%s", cmd) != PRELIM) {
     826:             (void) signal(SIGINT, oldintr);
     827:             if (oldtype) {
     828:                 if (!debug)
     829:                     verbose = 0;
     830:                 switch (oldtype) {
     831:                     case TYPE_I:
     832:                         setbinary();
     833:                         break;
     834:                     case TYPE_E:
     835:                         setebcdic();
     836:                         break;
     837:                     case TYPE_L:
     838:                         settenex();
     839:                         break;
     840:                 }
     841:                 verbose = oldverbose;
     842:             }
     843:             return;
     844:         }
     845:     }
     846:     din = dataconn("r");
     847:     if (din == NULL)
     848:         goto abort;
     849:     if (strcmp(local, "-") == 0)
     850:         fout = stdout;
     851:     else if (*local == '|') {
     852:         oldintp = signal(SIGPIPE, SIG_IGN);
     853:         fout = popen(local + 1, "w");
     854:         if (fout == NULL) {
     855:             perror(local+1);
     856:             goto abort;
     857:         }
     858:         closefunc = pclose;
     859:     } else {
     860:         fout = fopen(local, mode);
     861:         if (fout == NULL) {
     862:             perror(local);
     863:             goto abort;
     864:         }
     865:         closefunc = fclose;
     866:     }
     867:     if (fstat(fileno(fout), &st) < 0 || st.st_blksize == 0)
     868:         st.st_blksize = BUFSIZ;
     869:     if (st.st_blksize > bufsize) {
     870:         if (buf)
     871:             (void) free(buf);
     872:         buf = malloc((int)st.st_blksize);
     873:         if (buf == NULL) {
     874:             perror("malloc");
     875:             bufsize = 0;
     876:             goto abort;
     877:         }
     878:         bufsize = st.st_blksize;
     879:     }
     880:     (void) gettimeofday(&start, (struct timezone *)0);
     881:     switch (type) {
     882:
     883:     case TYPE_I:
     884:     case TYPE_L:
     885:         if (restart_point &&
     886:             lseek(fileno(fout), (long) restart_point, L_SET) < 0) {
     887:             perror(local);
     888:             if (closefunc != NULL)
     889:                 (*closefunc)(fout);
     890:             return;
     891:         }
     892:         errno = d = 0;
     893:         while ((c = read(fileno(din), buf, (int)bufsize)) > 0) {
     894:             if ((d = write(fileno(fout), buf, c)) != c)
     895:                 break;
     896:             bytes += c;
     897:             if (hash) {
     898:                 while (bytes >= hashbytes) {
     899:                     (void) putchar('#');
     900:                     hashbytes += HASHBYTES;
     901:                 }
     902:                 (void) fflush(stdout);
     903:             }
     904:         }
     905:         if (hash && bytes > 0) {
     906:             if (bytes < HASHBYTES)
     907:                 (void) putchar('#');
     908:             (void) putchar('\n');
     909:             (void) fflush(stdout);
     910:         }
     911:         if (c < 0) {
     912:             if (errno != EPIPE)
     913:                 perror("netin");
     914:             bytes = -1;
     915:         }
     916:         if (d < c) {
     917:             if (d < 0)
     918:                 perror(local);
     919:             else
     920:                 fprintf(stderr, "%s: short write\n", local);
     921:         }
     922:         break;
     923:
     924:     case TYPE_A:
     925:         if (restart_point) {
     926:             register int i, n, c;
     927:
     928:             if (fseek(fout, 0L, L_SET) < 0)
     929:                 goto done;
     930:             n = restart_point;
     931:             i = 0;
     932:             while (i++ < n) {
     933:                 if ((c=getc(fout)) == EOF)
     934:                     goto done;
     935:                 if (c == '\n')
     936:                     i++;
     937:             }
     938:             if (fseek(fout, 0L, L_INCR) < 0) {
     939: done:
     940:                 perror(local);
     941:                 if (closefunc != NULL)
     942:                     (*closefunc)(fout);
     943:                 return;
     944:             }
     945:         }
     946:         while ((c = getc(din)) != EOF) {
     947:             while (c == '\r') {
     948:                 while (hash && (bytes >= hashbytes)) {
     949:                     (void) putchar('#');
     950:                     (void) fflush(stdout);
     951:                     hashbytes += HASHBYTES;
     952:                 }
     953:                 bytes++;
     954:                 if ((c = getc(din)) != '\n' || tcrflag) {
     955:                     if (ferror(fout))
     956:                         goto break2;
     957:                     (void) putc('\r', fout);
     958:                     if (c == '\0') {
     959:                         bytes++;
     960:                         goto contin2;
     961:                     }
     962:                     if (c == EOF)
     963:                         goto contin2;
     964:                 }
     965:             }
     966:             (void) putc(c, fout);
     967:             bytes++;
     968:     contin2:    ;
     969:         }
     970: break2:
     971:         if (hash) {
     972:             if (bytes < hashbytes)
     973:                 (void) putchar('#');
     974:             (void) putchar('\n');
     975:             (void) fflush(stdout);
     976:         }
     977:         if (ferror(din)) {
     978:             if (errno != EPIPE)
     979:                 perror("netin");
     980:             bytes = -1;
     981:         }
     982:         if (ferror(fout))
     983:             perror(local);
     984:         break;
     985:     }
     986:     if (closefunc != NULL)
     987:         (*closefunc)(fout);
     988:     (void) signal(SIGINT, oldintr);
     989:     if (oldintp)
     990:         (void) signal(SIGPIPE, oldintp);
     991:     (void) gettimeofday(&stop, (struct timezone *)0);
     992:     (void) fclose(din);
     993:     (void) getreply(0);
     994:     if (bytes > 0 && is_retr)
     995:         ptransfer("received", bytes, &start, &stop);
     996:     if (oldtype) {
     997:         if (!debug)
     998:             verbose = 0;
     999:         switch (oldtype) {
    1000:             case TYPE_I:
    1001:                 setbinary();
    1002:                 break;
    1003:             case TYPE_E:
    1004:                 setebcdic();
    1005:                 break;
    1006:             case TYPE_L:
    1007:                 settenex();
    1008:                 break;
    1009:         }
    1010:         verbose = oldverbose;
    1011:     }
    1012:     return;
    1013: abort:
    1014:
    1015: /* abort using RFC959 recommended IP,SYNC sequence  */
    1016:
    1017:     (void) gettimeofday(&stop, (struct timezone *)0);
    1018:     if (oldintp)
    1019:         (void) signal(SIGPIPE, oldintr);
    1020:     (void) signal(SIGINT,SIG_IGN);
    1021:     if (oldtype) {
    1022:         if (!debug)
    1023:             verbose = 0;
    1024:         switch (oldtype) {
    1025:             case TYPE_I:
    1026:                 setbinary();
    1027:                 break;
    1028:             case TYPE_E:
    1029:                 setebcdic();
    1030:                 break;
    1031:             case TYPE_L:
    1032:                 settenex();
    1033:                 break;
    1034:         }
    1035:         verbose = oldverbose;
    1036:     }
    1037:     if (!cpend) {
    1038:         code = -1;
    1039:         (void) signal(SIGINT,oldintr);
    1040:         return;
    1041:     }
    1042:
    1043:     fprintf(cout,"%c%c",IAC,IP);
    1044:     (void) fflush(cout);
    1045:     msg = IAC;
    1046: /* send IAC in urgent mode instead of DM because UNIX places oob mark */
    1047: /* after urgent byte rather than before as now is protocol            */
    1048:     if (send(fileno(cout),&msg,1,MSG_OOB) != 1) {
    1049:         perror("abort");
    1050:     }
    1051:     fprintf(cout,"%cABOR\r\n",DM);
    1052:     (void) fflush(cout);
    1053:     FD_ZERO(&mask);
    1054:     FD_SET(fileno(cin), &mask);
    1055:     if (din) {
    1056:         FD_SET(fileno(din), &mask);
    1057:     }
    1058:     if ((nfnd = empty(&mask,10)) <= 0) {
    1059:         if (nfnd < 0) {
    1060:             perror("abort");
    1061:         }
    1062:         code = -1;
    1063:         lostpeer();
    1064:     }
    1065:     if (din && FD_ISSET(fileno(din), &mask)) {
    1066:         while ((c = read(fileno(din), buf, (int)bufsize)) > 0)
    1067:             ;
    1068:     }
    1069:     if ((c = getreply(0)) == ERROR && code == 552) { /* needed for nic style abort */
    1070:         if (data >= 0) {
    1071:             (void) close(data);
    1072:             data = -1;
    1073:         }
    1074:         (void) getreply(0);
    1075:     }
    1076:     (void) getreply(0);
    1077:     code = -1;
    1078:     if (data >= 0) {
    1079:         (void) close(data);
    1080:         data = -1;
    1081:     }
    1082:     if (closefunc != NULL && fout != NULL)
    1083:         (*closefunc)(fout);
    1084:     if (din)
    1085:         (void) fclose(din);
    1086:     if (bytes > 0)
    1087:         ptransfer("received", bytes, &start, &stop);
    1088:     (void) signal(SIGINT,oldintr);
    1089: }
    1090:
    1091: /*
    1092:  * Need to start a listen on the data channel
    1093:  * before we send the command, otherwise the
    1094:  * server's connect may fail.
    1095:  */
    1096: int sendport = -1;
    1097:
    1098: initconn()
    1099: {
    1100:     register char *p, *a;
    1101:     int result, len, tmpno = 0;
    1102:     int on = 1;
    1103:
    1104: noport:
    1105:     data_addr = myctladdr;
    1106:     if (sendport)
    1107:         data_addr.sin_port = 0; /* let system pick one */
    1108:     if (data != -1)
    1109:         (void) close (data);
    1110:     data = socket(AF_INET, SOCK_STREAM, 0);
    1111:     if (data < 0) {
    1112:         perror("ftp: socket");
    1113:         if (tmpno)
    1114:             sendport = 1;
    1115:         return (1);
    1116:     }
    1117:     if (!sendport)
    1118:         if (setsockopt(data, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof (on)) < 0) {
    1119:             perror("ftp: setsockopt (reuse address)");
    1120:             goto bad;
    1121:         }
    1122:     if (bind(data, (struct sockaddr *)&data_addr, sizeof (data_addr)) < 0) {
    1123:         perror("ftp: bind");
    1124:         goto bad;
    1125:     }
    1126:     if (options & SO_DEBUG &&
    1127:         setsockopt(data, SOL_SOCKET, SO_DEBUG, (char *)&on, sizeof (on)) < 0)
    1128:         perror("ftp: setsockopt (ignored)");
    1129:     len = sizeof (data_addr);
    1130:     if (getsockname(data, (char *)&data_addr, &len) < 0) {
    1131:         perror("ftp: getsockname");
    1132:         goto bad;
    1133:     }
    1134:     if (listen(data, 1) < 0)
    1135:         perror("ftp: listen");
    1136:     if (sendport) {
    1137:         a = (char *)&data_addr.sin_addr;
    1138:         p = (char *)&data_addr.sin_port;
    1139: #define UC(b)   (((int)b)&0xff)
    1140:         result =
    1141:             command("PORT %d,%d,%d,%d,%d,%d",
    1142:               UC(a[0]), UC(a[1]), UC(a[2]), UC(a[3]),
    1143:               UC(p[0]), UC(p[1]));
    1144:         if (result == ERROR && sendport == -1) {
    1145:             sendport = 0;
    1146:             tmpno = 1;
    1147:             goto noport;
    1148:         }
    1149:         return (result != COMPLETE);
    1150:     }
    1151:     if (tmpno)
    1152:         sendport = 1;
    1153:     return (0);
    1154: bad:
    1155:     (void) close(data), data = -1;
    1156:     if (tmpno)
    1157:         sendport = 1;
    1158:     return (1);
    1159: }
    1160:
    1161: FILE *
    1162: dataconn(mode)
    1163:     char *mode;
    1164: {
    1165:     struct sockaddr_in from;
    1166:     int s, fromlen = sizeof (from);
    1167:
    1168:     s = accept(data, (struct sockaddr *) &from, &fromlen);
    1169:     if (s < 0) {
    1170:         perror("ftp: accept");
    1171:         (void) close(data), data = -1;
    1172:         return (NULL);
    1173:     }
    1174:     (void) close(data);
    1175:     data = s;
    1176:     return (fdopen(data, mode));
    1177: }
    1178:
    1179: ptransfer(direction, bytes, t0, t1)
    1180:     char *direction;
    1181:     long bytes;
    1182:     struct timeval *t0, *t1;
    1183: {
    1184:     struct timeval td;
    1185:     float s, bs;
    1186:
    1187:     if (verbose) {
    1188:         tvsub(&td, t1, t0);
    1189:         s = td.tv_sec + (td.tv_usec / 1000000.);
    1190: #define nz(x)   ((x) == 0 ? 1 : (x))
    1191:         bs = bytes / nz(s);
    1192:         printf("%ld bytes %s in %.2g seconds (%.2g Kbytes/s)\n",
    1193:             bytes, direction, s, bs / 1024.);
    1194:     }
    1195: }
    1196:
    1197: /*tvadd(tsum, t0)
    1198: 	struct timeval *tsum, *t0;
    1199: {
    1200:
    1201: 	tsum->tv_sec += t0->tv_sec;
    1202: 	tsum->tv_usec += t0->tv_usec;
    1203: 	if (tsum->tv_usec > 1000000)
    1204: 		tsum->tv_sec++, tsum->tv_usec -= 1000000;
    1205: } */
    1206:
    1207: tvsub(tdiff, t1, t0)
    1208:     struct timeval *tdiff, *t1, *t0;
    1209: {
    1210:
    1211:     tdiff->tv_sec = t1->tv_sec - t0->tv_sec;
    1212:     tdiff->tv_usec = t1->tv_usec - t0->tv_usec;
    1213:     if (tdiff->tv_usec < 0)
    1214:         tdiff->tv_sec--, tdiff->tv_usec += 1000000;
    1215: }
    1216:
    1217: psabort()
    1218: {
    1219:     extern int abrtflag;
    1220:
    1221:     abrtflag++;
    1222: }
    1223:
    1224: pswitch(flag)
    1225:     int flag;
    1226: {
    1227:     extern int proxy, abrtflag;
    1228:     int (*oldintr)();
    1229:     static struct comvars {
    1230:         int connect;
    1231:         char name[MAXHOSTNAMELEN];
    1232:         struct sockaddr_in mctl;
    1233:         struct sockaddr_in hctl;
    1234:         FILE *in;
    1235:         FILE *out;
    1236:         int tpe;
    1237:         int cpnd;
    1238:         int sunqe;
    1239:         int runqe;
    1240:         int mcse;
    1241:         int ntflg;
    1242:         char nti[17];
    1243:         char nto[17];
    1244:         int mapflg;
    1245:         char mi[MAXPATHLEN];
    1246:         char mo[MAXPATHLEN];
    1247:         } proxstruct, tmpstruct;
    1248:     struct comvars *ip, *op;
    1249:
    1250:     abrtflag = 0;
    1251:     oldintr = signal(SIGINT, psabort);
    1252:     if (flag) {
    1253:         if (proxy)
    1254:             return;
    1255:         ip = &tmpstruct;
    1256:         op = &proxstruct;
    1257:         proxy++;
    1258:     }
    1259:     else {
    1260:         if (!proxy)
    1261:             return;
    1262:         ip = &proxstruct;
    1263:         op = &tmpstruct;
    1264:         proxy = 0;
    1265:     }
    1266:     ip->connect = connected;
    1267:     connected = op->connect;
    1268:     if (hostname) {
    1269:         (void) strncpy(ip->name, hostname, sizeof(ip->name) - 1);
    1270:         ip->name[strlen(ip->name)] = '\0';
    1271:     } else
    1272:         ip->name[0] = 0;
    1273:     hostname = op->name;
    1274:     ip->hctl = hisctladdr;
    1275:     hisctladdr = op->hctl;
    1276:     ip->mctl = myctladdr;
    1277:     myctladdr = op->mctl;
    1278:     ip->in = cin;
    1279:     cin = op->in;
    1280:     ip->out = cout;
    1281:     cout = op->out;
    1282:     ip->tpe = type;
    1283:     type = op->tpe;
    1284:     if (!type)
    1285:         type = 1;
    1286:     ip->cpnd = cpend;
    1287:     cpend = op->cpnd;
    1288:     ip->sunqe = sunique;
    1289:     sunique = op->sunqe;
    1290:     ip->runqe = runique;
    1291:     runique = op->runqe;
    1292:     ip->mcse = mcase;
    1293:     mcase = op->mcse;
    1294:     ip->ntflg = ntflag;
    1295:     ntflag = op->ntflg;
    1296:     (void) strncpy(ip->nti, ntin, 16);
    1297:     (ip->nti)[strlen(ip->nti)] = '\0';
    1298:     (void) strcpy(ntin, op->nti);
    1299:     (void) strncpy(ip->nto, ntout, 16);
    1300:     (ip->nto)[strlen(ip->nto)] = '\0';
    1301:     (void) strcpy(ntout, op->nto);
    1302:     ip->mapflg = mapflag;
    1303:     mapflag = op->mapflg;
    1304:     (void) strncpy(ip->mi, mapin, MAXPATHLEN - 1);
    1305:     (ip->mi)[strlen(ip->mi)] = '\0';
    1306:     (void) strcpy(mapin, op->mi);
    1307:     (void) strncpy(ip->mo, mapout, MAXPATHLEN - 1);
    1308:     (ip->mo)[strlen(ip->mo)] = '\0';
    1309:     (void) strcpy(mapout, op->mo);
    1310:     (void) signal(SIGINT, oldintr);
    1311:     if (abrtflag) {
    1312:         abrtflag = 0;
    1313:         (*oldintr)();
    1314:     }
    1315: }
    1316:
    1317: jmp_buf ptabort;
    1318: int ptabflg;
    1319:
    1320: abortpt()
    1321: {
    1322:     printf("\n");
    1323:     (void) fflush(stdout);
    1324:     ptabflg++;
    1325:     mflag = 0;
    1326:     abrtflag = 0;
    1327:     longjmp(ptabort, 1);
    1328: }
    1329:
    1330: proxtrans(cmd, local, remote)
    1331:     char *cmd, *local, *remote;
    1332: {
    1333:     int (*oldintr)(), abortpt(), tmptype, oldtype = 0, secndflag = 0, nfnd;
    1334:     extern jmp_buf ptabort;
    1335:     char *cmd2;
    1336:     struct fd_set mask;
    1337:
    1338:     if (strcmp(cmd, "RETR"))
    1339:         cmd2 = "RETR";
    1340:     else
    1341:         cmd2 = runique ? "STOU" : "STOR";
    1342:     if (command("PASV") != COMPLETE) {
    1343:         printf("proxy server does not support third part transfers.\n");
    1344:         return;
    1345:     }
    1346:     tmptype = type;
    1347:     pswitch(0);
    1348:     if (!connected) {
    1349:         printf("No primary connection\n");
    1350:         pswitch(1);
    1351:         code = -1;
    1352:         return;
    1353:     }
    1354:     if (type != tmptype) {
    1355:         oldtype = type;
    1356:         switch (tmptype) {
    1357:             case TYPE_A:
    1358:                 setascii();
    1359:                 break;
    1360:             case TYPE_I:
    1361:                 setbinary();
    1362:                 break;
    1363:             case TYPE_E:
    1364:                 setebcdic();
    1365:                 break;
    1366:             case TYPE_L:
    1367:                 settenex();
    1368:                 break;
    1369:         }
    1370:     }
    1371:     if (command("PORT %s", pasv) != COMPLETE) {
    1372:         switch (oldtype) {
    1373:             case 0:
    1374:                 break;
    1375:             case TYPE_A:
    1376:                 setascii();
    1377:                 break;
    1378:             case TYPE_I:
    1379:                 setbinary();
    1380:                 break;
    1381:             case TYPE_E:
    1382:                 setebcdic();
    1383:                 break;
    1384:             case TYPE_L:
    1385:                 settenex();
    1386:                 break;
    1387:         }
    1388:         pswitch(1);
    1389:         return;
    1390:     }
    1391:     if (setjmp(ptabort))
    1392:         goto abort;
    1393:     oldintr = signal(SIGINT, abortpt);
    1394:     if (command("%s %s", cmd, remote) != PRELIM) {
    1395:         (void) signal(SIGINT, oldintr);
    1396:         switch (oldtype) {
    1397:             case 0:
    1398:                 break;
    1399:             case TYPE_A:
    1400:                 setascii();
    1401:                 break;
    1402:             case TYPE_I:
    1403:                 setbinary();
    1404:                 break;
    1405:             case TYPE_E:
    1406:                 setebcdic();
    1407:                 break;
    1408:             case TYPE_L:
    1409:                 settenex();
    1410:                 break;
    1411:         }
    1412:         pswitch(1);
    1413:         return;
    1414:     }
    1415:     sleep(2);
    1416:     pswitch(1);
    1417:     secndflag++;
    1418:     if (command("%s %s", cmd2, local) != PRELIM)
    1419:         goto abort;
    1420:     ptflag++;
    1421:     (void) getreply(0);
    1422:     pswitch(0);
    1423:     (void) getreply(0);
    1424:     (void) signal(SIGINT, oldintr);
    1425:     switch (oldtype) {
    1426:         case 0:
    1427:             break;
    1428:         case TYPE_A:
    1429:             setascii();
    1430:             break;
    1431:         case TYPE_I:
    1432:             setbinary();
    1433:             break;
    1434:         case TYPE_E:
    1435:             setebcdic();
    1436:             break;
    1437:         case TYPE_L:
    1438:             settenex();
    1439:             break;
    1440:     }
    1441:     pswitch(1);
    1442:     ptflag = 0;
    1443:     printf("local: %s remote: %s\n", local, remote);
    1444:     return;
    1445: abort:
    1446:     (void) signal(SIGINT, SIG_IGN);
    1447:     ptflag = 0;
    1448:     if (strcmp(cmd, "RETR") && !proxy)
    1449:         pswitch(1);
    1450:     else if (!strcmp(cmd, "RETR") && proxy)
    1451:         pswitch(0);
    1452:     if (!cpend && !secndflag) {  /* only here if cmd = "STOR" (proxy=1) */
    1453:         if (command("%s %s", cmd2, local) != PRELIM) {
    1454:             pswitch(0);
    1455:             switch (oldtype) {
    1456:                 case 0:
    1457:                     break;
    1458:                 case TYPE_A:
    1459:                     setascii();
    1460:                     break;
    1461:                 case TYPE_I:
    1462:                     setbinary();
    1463:                     break;
    1464:                 case TYPE_E:
    1465:                     setebcdic();
    1466:                     break;
    1467:                 case TYPE_L:
    1468:                     settenex();
    1469:                     break;
    1470:             }
    1471:             if (cpend) {
    1472:                 char msg[2];
    1473:
    1474:                 fprintf(cout,"%c%c",IAC,IP);
    1475:                 (void) fflush(cout);
    1476:                 *msg = IAC;
    1477:                 *(msg+1) = DM;
    1478:                 if (send(fileno(cout),msg,2,MSG_OOB) != 2)
    1479:                     perror("abort");
    1480:                 fprintf(cout,"ABOR\r\n");
    1481:                 (void) fflush(cout);
    1482:                 FD_ZERO(&mask);
    1483:                 FD_SET(fileno(cin), &mask);
    1484:                 if ((nfnd = empty(&mask,10)) <= 0) {
    1485:                     if (nfnd < 0) {
    1486:                         perror("abort");
    1487:                     }
    1488:                     if (ptabflg)
    1489:                         code = -1;
    1490:                     lostpeer();
    1491:                 }
    1492:                 (void) getreply(0);
    1493:                 (void) getreply(0);
    1494:             }
    1495:         }
    1496:         pswitch(1);
    1497:         if (ptabflg)
    1498:             code = -1;
    1499:         (void) signal(SIGINT, oldintr);
    1500:         return;
    1501:     }
    1502:     if (cpend) {
    1503:         char msg[2];
    1504:
    1505:         fprintf(cout,"%c%c",IAC,IP);
    1506:         (void) fflush(cout);
    1507:         *msg = IAC;
    1508:         *(msg+1) = DM;
    1509:         if (send(fileno(cout),msg,2,MSG_OOB) != 2)
    1510:             perror("abort");
    1511:         fprintf(cout,"ABOR\r\n");
    1512:         (void) fflush(cout);
    1513:         FD_ZERO(&mask);
    1514:         FD_SET(fileno(cin), &mask);
    1515:         if ((nfnd = empty(&mask,10)) <= 0) {
    1516:             if (nfnd < 0) {
    1517:                 perror("abort");
    1518:             }
    1519:             if (ptabflg)
    1520:                 code = -1;
    1521:             lostpeer();
    1522:         }
    1523:         (void) getreply(0);
    1524:         (void) getreply(0);
    1525:     }
    1526:     pswitch(!proxy);
    1527:     if (!cpend && !secndflag) {  /* only if cmd = "RETR" (proxy=1) */
    1528:         if (command("%s %s", cmd2, local) != PRELIM) {
    1529:             pswitch(0);
    1530:             switch (oldtype) {
    1531:                 case 0:
    1532:                     break;
    1533:                 case TYPE_A:
    1534:                     setascii();
    1535:                     break;
    1536:                 case TYPE_I:
    1537:                     setbinary();
    1538:                     break;
    1539:                 case TYPE_E:
    1540:                     setebcdic();
    1541:                     break;
    1542:                 case TYPE_L:
    1543:                     settenex();
    1544:                     break;
    1545:             }
    1546:             if (cpend) {
    1547:                 char msg[2];
    1548:
    1549:                 fprintf(cout,"%c%c",IAC,IP);
    1550:                 (void) fflush(cout);
    1551:                 *msg = IAC;
    1552:                 *(msg+1) = DM;
    1553:                 if (send(fileno(cout),msg,2,MSG_OOB) != 2)
    1554:                     perror("abort");
    1555:                 fprintf(cout,"ABOR\r\n");
    1556:                 (void) fflush(cout);
    1557:                 FD_ZERO(&mask);
    1558:                 FD_SET(fileno(cin), &mask);
    1559:                 if ((nfnd = empty(&mask,10)) <= 0) {
    1560:                     if (nfnd < 0) {
    1561:                         perror("abort");
    1562:                     }
    1563:                     if (ptabflg)
    1564:                         code = -1;
    1565:                     lostpeer();
    1566:                 }
    1567:                 (void) getreply(0);
    1568:                 (void) getreply(0);
    1569:             }
    1570:             pswitch(1);
    1571:             if (ptabflg)
    1572:                 code = -1;
    1573:             (void) signal(SIGINT, oldintr);
    1574:             return;
    1575:         }
    1576:     }
    1577:     if (cpend) {
    1578:         char msg[2];
    1579:
    1580:         fprintf(cout,"%c%c",IAC,IP);
    1581:         (void) fflush(cout);
    1582:         *msg = IAC;
    1583:         *(msg+1) = DM;
    1584:         if (send(fileno(cout),msg,2,MSG_OOB) != 2)
    1585:             perror("abort");
    1586:         fprintf(cout,"ABOR\r\n");
    1587:         (void) fflush(cout);
    1588:         FD_ZERO(&mask);
    1589:         FD_SET(fileno(cin), &mask);
    1590:         if ((nfnd = empty(&mask,10)) <= 0) {
    1591:             if (nfnd < 0) {
    1592:                 perror("abort");
    1593:             }
    1594:             if (ptabflg)
    1595:                 code = -1;
    1596:             lostpeer();
    1597:         }
    1598:         (void) getreply(0);
    1599:         (void) getreply(0);
    1600:     }
    1601:     pswitch(!proxy);
    1602:     if (cpend) {
    1603:         FD_ZERO(&mask);
    1604:         FD_SET(fileno(cin), &mask);
    1605:         if ((nfnd = empty(&mask,10)) <= 0) {
    1606:             if (nfnd < 0) {
    1607:                 perror("abort");
    1608:             }
    1609:             if (ptabflg)
    1610:                 code = -1;
    1611:             lostpeer();
    1612:         }
    1613:         (void) getreply(0);
    1614:         (void) getreply(0);
    1615:     }
    1616:     if (proxy)
    1617:         pswitch(0);
    1618:     switch (oldtype) {
    1619:         case 0:
    1620:             break;
    1621:         case TYPE_A:
    1622:             setascii();
    1623:             break;
    1624:         case TYPE_I:
    1625:             setbinary();
    1626:             break;
    1627:         case TYPE_E:
    1628:             setebcdic();
    1629:             break;
    1630:         case TYPE_L:
    1631:             settenex();
    1632:             break;
    1633:     }
    1634:     pswitch(1);
    1635:     if (ptabflg)
    1636:         code = -1;
    1637:     (void) signal(SIGINT, oldintr);
    1638: }
    1639:
    1640: reset()
    1641: {
    1642:     struct fd_set mask;
    1643:     int nfnd = 1;
    1644:
    1645:     FD_ZERO(&mask);
    1646:     while (nfnd > 0) {
    1647:         FD_SET(fileno(cin), &mask);
    1648:         if ((nfnd = empty(&mask,0)) < 0) {
    1649:             perror("reset");
    1650:             code = -1;
    1651:             lostpeer();
    1652:         }
    1653:         else if (nfnd) {
    1654:             (void) getreply(0);
    1655:         }
    1656:     }
    1657: }
    1658:
    1659: char *
    1660: gunique(local)
    1661:     char *local;
    1662: {
    1663:     static char new[MAXPATHLEN];
    1664:     char *cp = rindex(local, '/');
    1665:     int d, count=0;
    1666:     char ext = '1';
    1667:
    1668:     if (cp)
    1669:         *cp = '\0';
    1670:     d = access(cp ? local : ".", 2);
    1671:     if (cp)
    1672:         *cp = '/';
    1673:     if (d < 0) {
    1674:         perror(local);
    1675:         return((char *) 0);
    1676:     }
    1677:     (void) strcpy(new, local);
    1678:     cp = new + strlen(new);
    1679:     *cp++ = '.';
    1680:     while (!d) {
    1681:         if (++count == 100) {
    1682:             printf("runique: can't find unique file name.\n");
    1683:             return((char *) 0);
    1684:         }
    1685:         *cp++ = ext;
    1686:         *cp = '\0';
    1687:         if (ext == '9')
    1688:             ext = '0';
    1689:         else
    1690:             ext++;
    1691:         if ((d = access(new, 0)) < 0)
    1692:             break;
    1693:         if (ext != '0')
    1694:             cp--;
    1695:         else if (*(cp - 2) == '.')
    1696:             *(cp - 1) = '1';
    1697:         else {
    1698:             *(cp - 2) = *(cp - 2) + 1;
    1699:             cp--;
    1700:         }
    1701:     }
    1702:     return(new);
    1703: }

#### Defined functions

abortpt defined in line 1320; used 2 times

- in line 1333, 1393

abortrecv defined in line 687; used 2 times

- in line 702, 741

abortsend defined in line 440; used 2 times

- in line 458, 495

cmdabort defined in line 260; used 5 times

- in line 284, 304, 332-336(2), 421

command defined in line 275; used 51 times

- in line 230-239(3), 246, 548, 559, 568, 800-804(2), 825, 1141, 1342, 1371, 1394, 1418, 1453, 1528
- in /usr/src/ucb/ftp/cmds.c line 116, 200-202(2), 584, 980-983(2), 1036, 1072, 1118-1119(2), 1293-1297(2), 1306, 1314, 1331-1333(2), 1358-1361(2), 1385-1388(2), 1419, 1455, 1481, 1490, 1500, 1513, 1543, 1630, 2009-2012(2), 2034, 2125, 2152, 2170

dataconn defined in line 1161; used 3 times

- in line 91, 576, 846

empty defined in line 427; used 7 times

- in line 1058, 1484, 1515, 1559, 1590, 1605, 1648

getreply defined in line 326; used 25 times

- in line 173, 315, 482, 655, 677, 730, 993, 1069-1076(3), 1421-1423(2), 1492-1493(2), 1523-1524(2), 1567-1568(2), 1598-1599(2), 1613-1614(2), 1654
- in /usr/src/ucb/ftp/cmds.c line 1420, 1456

gunique defined in line 1659; used 3 times

- in line 703, 771, 777

hookup defined in line 93; used 2 times

- in /usr/src/ucb/ftp/cmds.c line 66, 99

initconn defined in line 1098; used 2 times

- in line 527, 783

login defined in line 198; used 1 times

- in /usr/src/ucb/ftp/cmds.c line 105

proxtrans defined in line 1330; used 2 times

- in line 473, 721

psabort defined in line 1217; used 1 times

- in line 1251

pswitch defined in line 1224; used 29 times

- in line 1347-1350(2), 1388, 1412-1416(2), 1422, 1441, 1449-1454(3), 1496, 1526-1529(2), 1570, 1601, 1617, 1634
- in /usr/src/ucb/ftp/cmds.c line 756-761(2), 802, 809, 1526, 1640, 1648, 1699-1703(2), 1715
- in /usr/src/ucb/ftp/main.c line 171, 181

ptransfer defined in line 1179; used 4 times

- in line 660, 682, 995, 1087

recvrequest defined in line 697; used 5 times

- in /usr/src/ucb/ftp/cmds.c line 620, 703, 759, 1150, 1199

reset defined in line 1640; used 2 times

- in /usr/src/ucb/ftp/cmdtab.c line 37, 162

sendrequest defined in line 452; used 4 times

- in /usr/src/ucb/ftp/cmds.c line 351, 416, 439, 465

tvsub defined in line 1207; used 1 times

- in line 1188

#### Defined variables

abrtflag defined in line 82; used 13 times

- in line 266, 286, 316, 421, 444, 691, 1219-1221(2), 1227, 1250, 1311-1312(2), 1326

allbinary defined in line 85; used 2 times

- in line 791
- in /usr/src/ucb/ftp/cmds.c line 115

connected defined in line 84; used 3 times

- in line 1266-1267(2), 1348

data defined in line 81; used 32 times

- in line 484-486(3), 671-673(3), 732-734(3), 1070-1072(3), 1078-1080(3), 1108-1111(4), 1118-1134(5), 1155(2), 1168-1176(6)

data_addr defined in line 80; used 8 times

- in line 1105-1107(2), 1122(2), 1129-1130(2), 1137-1138(2)

hisctladdr defined in line 79; used 17 times

- in line 102-105(5), 115-121(3), 127-142(7), 1274-1275(2)

myctladdr defined in line 86; used 5 times

- in line 154-155(2), 1105, 1276-1277(2)

ptabflg defined in line 1318; used 9 times

- in line 1324, 1488, 1497, 1519, 1563, 1571, 1594, 1609, 1635

ptabort defined in line 1317; used 5 times

- in line 262, 268, 1327, 1334, 1391

ptflag defined in line 83; used 4 times

- in line 267, 1420, 1442-1447(2)

recvabort defined in line 685; used 3 times

- in line 694, 728, 788

reply_string defined in line 322; used 12 times

- in line 339, 403(2)
- in /usr/src/ucb/ftp/cmds.c line 118-120(2), 129-133(2), 140, 588, 612, 2154, 2160

restart_point defined in line 88; used 17 times

- in line 539-555(6), 799-800(2), 885-886(2), 925-930(2)
- in /usr/src/ucb/ftp/cmds.c line 495, 576, 622, 2025-2026(2)

sccsid defined in line 19; never used
sendabort defined in line 438; used 3 times

- in line 447, 480, 536

sendport defined in line 1096; used 8 times

- in line 1106, 1114-1117(2), 1136, 1144-1145(2), 1152-1157(2)

#### Defined struct's

comvars defined in line 1229; used 2 times

- in line 1248(2)

#### Defined macros

FD_CLR defined in line 70; never used
FD_ISSET defined in line 71; used 1 times

- in line 1065

FD_SET defined in line 69; used 9 times

- in line 51, 1054-1056(2), 1483, 1514, 1558, 1589, 1604, 1647

FD_SETSIZE defined in line 60; used 1 times

- in line 59

FD_ZERO defined in line 72; used 7 times

- in line 1053, 1482, 1513, 1557, 1588, 1603, 1645

HASHBYTES defined in line 450; used 8 times

- in line 460, 594, 600, 622, 706, 900, 906, 951

MAXHOSTNAMELEN defined in line 46; used 2 times

- in line 45, 1231

NBBY defined in line 52; used 1 times

- in line 64

NFDBITS defined in line 64; used 6 times

- in line 69-71(6)

UC defined in line 1139; used 6 times

- in line 1142-1143(6)

howmany defined in line 66; used 1 times

- in line 65

nz defined in line 1190; used 1 times

- in line 1191

Last modified: 1997-10-03 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 5566 |