Annotation of researchv9/ipc/src/bin/nftp.c, revision 1.1.1.1

1.1       root        1: #include <sys/param.h>
                      2: #include <sys/types.h>
                      3: #include <sys/stat.h>
                      4: #include <sys/ioctl.h>
                      5: #include <stdio.h>
                      6: #include <signal.h>
                      7: #include <sys/timeb.h>
                      8: #include <errno.h>
                      9: #include <libc.h>
                     10: #include <sys/utsname.h>
                     11: #include <ipc.h>
                     12: #include "ftp.h"
                     13: #include "ftp_var.h"
                     14: 
                     15: int    data = -1;
                     16: int    connected;
                     17: 
                     18: FILE   *cin, *cout;
                     19: FILE   *dataconn();
                     20: 
                     21: char rhost[256];
                     22: 
                     23: char *
                     24: hookup(host, port)
                     25:        char *host;
                     26:        int port;
                     27: {
                     28:        int s;
                     29: 
                     30:        strcpy(rhost, ipcpath(host, "tcp", "tcp.21"));
                     31:        s = ipcopen(rhost, "light hup");
                     32:        cin = fdopen(s, "r");
                     33:        cout = fdopen(s, "w");
                     34:        if (cin == NULL || cout == NULL) {
                     35:                fprintf(stderr, "ftp: fdopen failed.\n");
                     36:                if (cin)
                     37:                        fclose(cin);
                     38:                if (cout)
                     39:                        fclose(cout);
                     40:                goto bad;
                     41:        }
                     42:        if (verbose)
                     43:                printf("Connected to %s.\n", rhost);
                     44:        (void) getreply(0);             /* read startup message from server */
                     45:        return (rhost);
                     46: bad:
                     47:        close(s);
                     48:        return ((char *)0);
                     49: }
                     50: 
                     51: login(hp)
                     52:        char *hp;
                     53: {
                     54:        char acct[80];
                     55:        char user[80], passwd[80];
                     56:        int n;
                     57:        struct sgttyb sbuf;
                     58:        int oldflags;
                     59: 
                     60:        getresponse("login: ", user, sizeof(user));
                     61:        ioctl(fileno(stdin), TIOCGETP, &sbuf);
                     62:        oldflags = sbuf.sg_flags;
                     63:        sbuf.sg_flags = oldflags & ~ECHO;
                     64:        ioctl(fileno(stdin), TIOCSETP, &sbuf);
                     65:        getresponse("password: ", passwd, sizeof(passwd));
                     66:        sbuf.sg_flags = oldflags;
                     67:        ioctl(fileno(stdin), TIOCSETP, &sbuf);
                     68:        printf("\n"); (void) fflush(stdout);
                     69:        n = command("USER %s", user);
                     70:        if (n == CONTINUE)
                     71:                n = command("PASS %s", passwd);
                     72:        if (n == CONTINUE) {
                     73:                getresponse("ACCOUNT: ", acct, sizeof(acct));
                     74:                n = command("ACCT %s", acct);
                     75:        }
                     76:        if (n != COMPLETE) {
                     77:                fprintf(stderr, "Login failed.\n");
                     78:                return (0);
                     79:        }
                     80:        return (1);
                     81: }
                     82: 
                     83: getresponse(prompt, cp, len)
                     84:        char *prompt;
                     85:        char *cp;
                     86:        int len;
                     87: {
                     88:        int c;
                     89:        char *p = cp;
                     90: 
                     91:        printf(prompt); (void) fflush(stdout);
                     92:        while(c = getchar())
                     93:                if (c != ' ' && c != '\t')
                     94:                        break;
                     95:        while(c != '\n' && c != EOF) {
                     96:                if ((cp + len - 1) > p)
                     97:                        *p++ = c;
                     98:                c = getchar();
                     99:        }
                    100:        *p = '\0';
                    101: }
                    102: 
                    103: 
                    104: 
                    105: /*VARARGS 1*/
                    106: command(fmt, args)
                    107:        char *fmt;
                    108: {
                    109:        if (debug) {
                    110:                printf("---> ");
                    111:                _doprnt(fmt, &args, stdout);
                    112:                printf("\n");
                    113:                (void) fflush(stdout);
                    114:        }
                    115:        if (cout == NULL) {
                    116:                perror ("No control connection for command");
                    117:                return (0);
                    118:        }
                    119:        _doprnt(fmt, &args, cout);
                    120:        fprintf(cout, "\r\n");
                    121:        (void) fflush(cout);
                    122:        return (getreply(!strcmp(fmt, "QUIT")));
                    123: }
                    124: 
                    125: #include <ctype.h>
                    126: 
                    127: getreply(expecteof)
                    128:        int expecteof;
                    129: {
                    130:        register int c, n;
                    131:        register int code, dig;
                    132:        int originalcode = 0, continuation = 0;
                    133: 
                    134:        for (;;) {
                    135:                dig = n = code = 0;
                    136:                while ((c = getc(cin)) != '\n') {
                    137:                        dig++;
                    138:                        if (c == EOF) {
                    139:                                if (expecteof)
                    140:                                        return (0);
                    141:                                lostpeer();
                    142:                                exit(1);
                    143:                        }
                    144:                        if (verbose && c != '\r' ||
                    145:                            (n == '5' && dig > 4))
                    146:                                putchar(c);
                    147:                        if (dig < 4 && isdigit(c))
                    148:                                code = code * 10 + (c - '0');
                    149:                        if (dig == 4 && c == '-')
                    150:                                continuation++;
                    151:                        if (n == 0)
                    152:                                n = c;
                    153:                }
                    154:                if (verbose || n == '5')
                    155:                        putchar(c);
                    156:                if (continuation && code != originalcode) {
                    157:                        if (originalcode == 0)
                    158:                                originalcode = code;
                    159:                        continue;
                    160:                }
                    161:                if (expecteof || empty(cin))
                    162:                        return (n - '0');
                    163:        }
                    164: }
                    165: 
                    166: empty(f)
                    167:        FILE *f;
                    168: {
                    169:        int mask;
                    170: 
                    171:        if (f->_cnt > 0)
                    172:                return (0);
                    173:        mask = (1 << fileno(f));
                    174:        (void) select(20, &mask, 0, 0);
                    175:        return (mask == 0);
                    176: }
                    177: 
                    178: jmp_buf        sendabort;
                    179: 
                    180: abortsend()
                    181: {
                    182: 
                    183:        longjmp(sendabort, 1);
                    184: }
                    185: 
                    186: sendrequest(cmd, local, remote)
                    187:        char *cmd, *local, *remote;
                    188: {
                    189:        FILE *fin, *dout, *popen();
                    190:        int (*closefunc)(), pclose(), fclose(), (*oldintr)();
                    191:        char buf[BUFSIZ];
                    192:        register int bytes = 0, c;
                    193:        struct stat st;
                    194:        struct timeb start, stop;
                    195:        extern int errno;
                    196: 
                    197:        closefunc = NULL;
                    198:        if (setjmp(sendabort))
                    199:                goto bad;
                    200:        oldintr = signal(SIGINT, abortsend);
                    201:        if (strcmp(local, "-") == 0)
                    202:                fin = stdin;
                    203:        else if (*local == '|') {
                    204:                fin = popen(local + 1, "r");
                    205:                if (fin == NULL) {
                    206:                        perror(local + 1);
                    207:                        goto bad;
                    208:                }
                    209:                closefunc = pclose;
                    210:        } else {
                    211:                fin = fopen(local, "r");
                    212:                if (fin == NULL) {
                    213:                        perror(local);
                    214:                        goto bad;
                    215:                }
                    216:                closefunc = fclose;
                    217:                if (fstat(fileno(fin), &st) < 0 ||
                    218:                    (st.st_mode&S_IFMT) != S_IFREG) {
                    219:                        fprintf(stderr, "%s: not a plain file.", local);
                    220:                        goto bad;
                    221:                }
                    222:        }
                    223:        if (initconn())
                    224:                goto bad;
                    225:        if (remote) {
                    226:                if (command("%s %s", cmd, remote) != PRELIM)
                    227:                        goto bad;
                    228:        } else
                    229:                if (command("%s", cmd) != PRELIM)
                    230:                        goto bad;
                    231:        dout = dataconn("w");
                    232:        if (dout == NULL)
                    233:                goto bad;
                    234:        ftime(&start);
                    235:        switch (type) {
                    236: 
                    237:        case TYPE_I:
                    238:        case TYPE_L:
                    239:                errno = 0;
                    240:                while ((c = read(fileno (fin), buf, sizeof (buf))) > 0) {
                    241:                        if (write(fileno (dout), buf, c) < 0)
                    242:                                break;
                    243:                        bytes += c;
                    244:                }
                    245:                if (c < 0)
                    246:                        perror(local);
                    247:                else if (errno)
                    248:                        perror("netout");
                    249:                break;
                    250: 
                    251:        case TYPE_A:
                    252:                while ((c = getc(fin)) != EOF) {
                    253:                        if (c == '\n') {
                    254:                                if (ferror(dout))
                    255:                                        break;
                    256:                                putc('\r', dout);
                    257:                                bytes++;
                    258:                        }
                    259:                        putc(c, dout);
                    260:                        bytes++;
                    261:                        if (c == '\r') {
                    262:                                putc('\0', dout);
                    263:                                bytes++;
                    264:                        }
                    265:                }
                    266:                if (ferror(fin))
                    267:                        perror(local);
                    268:                else if (ferror(dout))
                    269:                        perror("netout");
                    270:                break;
                    271:        }
                    272:        ftime(&stop);
                    273:        if (closefunc != NULL)
                    274:                (*closefunc)(fin);
                    275:        (void) fclose(dout);
                    276:        (void) getreply(0);
                    277: done:
                    278:        signal(SIGINT, oldintr);
                    279:        if (bytes > 0 && verbose)
                    280:                ptransfer("sent", bytes, &start, &stop);
                    281:        return;
                    282: bad:
                    283:        if (data >= 0)
                    284:                (void) close(data), data = -1;
                    285:        if (closefunc != NULL && fin != NULL)
                    286:                (*closefunc)(fin);
                    287:        goto done;
                    288: }
                    289: 
                    290: jmp_buf        recvabort;
                    291: 
                    292: abortrecv()
                    293: {
                    294: 
                    295:        longjmp(recvabort, 1);
                    296: }
                    297: 
                    298: recvrequest(cmd, local, remote)
                    299:        char *cmd, *local, *remote;
                    300: {
                    301:        FILE *fout, *din, *popen();
                    302:        char buf[BUFSIZ];
                    303:        int (*closefunc)(), pclose(), fclose(), (*oldintr)(), c;
                    304:        register int bytes = 0;
                    305:        struct timeb start, stop;
                    306:        extern int errno;
                    307: 
                    308:        closefunc = NULL;
                    309:        if (setjmp(recvabort))
                    310:                goto bad;
                    311:        oldintr = signal(SIGINT, abortrecv);
                    312:        if (strcmp(local, "-") && *local != '|')
                    313:                if (access(local, 2) < 0) {
                    314:                        char *dir = strrchr(local, '/');
                    315: 
                    316:                        if (dir != NULL)
                    317:                                *dir = 0;
                    318:                        if (access(dir ? dir : ".", 2) < 0) {
                    319:                                perror(local);
                    320:                                goto bad;
                    321:                        }
                    322:                        if (dir != NULL)
                    323:                                *dir = '/';
                    324:                }
                    325:        if (initconn())
                    326:                goto bad;
                    327:        if (remote) {
                    328:                if (command("%s %s", cmd, remote) != PRELIM)
                    329:                        goto bad;
                    330:        } else
                    331:                if (command("%s", cmd) != PRELIM)
                    332:                        goto bad;
                    333:        if (strcmp(local, "-") == 0)
                    334:                fout = stdout;
                    335:        else if (*local == '|') {
                    336:                fout = popen(local + 1, "w");
                    337:                closefunc = pclose;
                    338:        } else {
                    339:                fout = fopen(local, "w");
                    340:                closefunc = fclose;
                    341:        }
                    342:        if (fout == NULL) {
                    343:                perror(local + 1);
                    344:                goto bad;
                    345:        }
                    346:        din = dataconn("r");
                    347:        if (din == NULL)
                    348:                goto bad;
                    349:        ftime(&start);
                    350:        switch (type) {
                    351: 
                    352:        case TYPE_I:
                    353:        case TYPE_L:
                    354:                errno = 0;
                    355:                while ((c = read(fileno(din), buf, sizeof (buf))) > 0) {
                    356:                        if (write(fileno(fout), buf, c) < 0)
                    357:                                break;
                    358:                        bytes += c;
                    359:                }
                    360:                if (c < 0)
                    361:                        perror("netin");
                    362:                if (errno)
                    363:                        perror(local);
                    364:                break;
                    365: 
                    366:        case TYPE_A:
                    367:                while ((c = getc(din)) != EOF) {
                    368:                        if (c == '\r') {
                    369:                                bytes++;
                    370:                                if ((c = getc(din)) != '\n') {
                    371:                                        if (ferror (fout))
                    372:                                                break;
                    373:                                        putc ('\r', fout);
                    374:                                }
                    375:                                if (c == '\0') {
                    376:                                        bytes++;
                    377:                                        continue;
                    378:                                }
                    379:                        }
                    380:                        putc (c, fout);
                    381:                        bytes++;
                    382:                }
                    383:                if (ferror (din))
                    384:                        perror ("netin");
                    385:                if (ferror (fout))
                    386:                        perror (local);
                    387:                break;
                    388:        }
                    389:        ftime(&stop);
                    390:        (void) fclose(din);
                    391:        if (closefunc != NULL)
                    392:                (*closefunc)(fout);
                    393:        (void) getreply(0);
                    394: done:
                    395:        signal(SIGINT, oldintr);
                    396:        if (bytes > 0 && verbose)
                    397:                ptransfer("received", bytes, &start, &stop);
                    398:        return;
                    399: bad:
                    400:        if (data >= 0)
                    401:                (void) close(data), data = -1;
                    402:        if (closefunc != NULL && fout != NULL)
                    403:                (*closefunc)(fout);
                    404:        goto done;
                    405: }
                    406: 
                    407: /*
                    408:  * Need to start a listen on the data channel
                    409:  * before we send the command, otherwise the
                    410:  * server's connect may fail.
                    411:  */
                    412: initconn()
                    413: {
                    414:        int result;
                    415:        char *a, *p;
                    416:        char portname[32];
                    417:        in_addr in_address();
                    418:        in_addr hostorderaddr;
                    419:        int hostorderport;
                    420:        struct utsname u;
                    421: 
                    422:        data = tcpcreat(portname, "heavy hup");
                    423:        if (data<0) {
                    424:                fprintf(stderr, "can't create data port\n");
                    425:                goto bad;
                    426:        }
                    427:        hostorderport = htons(fstotcp(portname));
                    428:        uname(&u);
                    429:        hostorderaddr = htonl(in_address(u.sysname));
                    430:        p = (char *)&hostorderport;
                    431:        a = (char *)&hostorderaddr;
                    432: #define        UC(b)   (((int)b)&0xff)
                    433:        result =
                    434:            command("PORT %d,%d,%d,%d,%d,%d",
                    435:              UC(a[0]), UC(a[1]), UC(a[2]), UC(a[3]),
                    436:              UC(p[0]), UC(p[1]));
                    437:        return (result != COMPLETE);
                    438: bad:
                    439:        (void) close(data), data = -1;
                    440:        return (1);
                    441: }
                    442: 
                    443: FILE *
                    444: dataconn(mode)
                    445:        char *mode;
                    446: {
                    447:        int s;
                    448:        ipcinfo *ip;
                    449: 
                    450:        ip = ipclisten(data);
                    451:        if (ip == NULL) {
                    452:                perror("ftp: listen");
                    453:                (void) close(data), data = -1;
                    454:                return (NULL);
                    455:        }
                    456:        s = ipcaccept(ip, -1);
                    457:        if (s < 0) {
                    458:                perror("ftp: accept");
                    459:                (void) close(data), data = -1;
                    460:                return (NULL);
                    461:        }
                    462:        (void) close(data);
                    463:        data = s;
                    464:        return (fdopen(data, mode));
                    465: }
                    466: 
                    467: ptransfer(direction, bytes, t0, t1)
                    468:        char *direction;
                    469:        int bytes;
                    470:        struct timeb *t0, *t1;
                    471: {
                    472:        struct timeb td;
                    473:        double ms, bs;
                    474: 
                    475:        tvsub(&td, t1, t0);
                    476:        ms = (td.time * 1000) + td.millitm;
                    477:        ms += 0.05;
                    478:        bs = bytes * 1000;
                    479:        bs = bs/(ms*1024.0);
                    480:        printf("%d bytes %s in %.3f seconds (%.2f Kbytes/s)\n",
                    481:                bytes, direction, ms/1000.0, bs);
                    482: }
                    483: 
                    484: tvadd(tsum, t0)
                    485:        struct timeb *tsum, *t0;
                    486: {
                    487: 
                    488:        tsum->time += t0->time;
                    489:        tsum->millitm += t0->millitm;
                    490:        if (tsum->time > 1000)
                    491:                tsum->time++, tsum->millitm -= 1000;
                    492: }
                    493: 
                    494: tvsub(tdiff, t1, t0)
                    495:        struct timeb *tdiff, *t1, *t0;
                    496: {
                    497: 
                    498:        tdiff->time = t1->time - t0->time;
                    499:        tdiff->millitm = t1->millitm - t0->millitm;
                    500:        if (tdiff->millitm < 0)
                    501:                tdiff->time--, tdiff->millitm += 1000;
                    502: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.