Annotation of researchv9/ipc/src/servers/ftpd.c, revision 1.1

1.1     ! root        1: #ifndef lint
        !             2: static char sccsid[] = "@(#)ftpd.c     4.28 (Berkeley) 9/22/83";
        !             3: #endif
        !             4: 
        !             5: #define        CHOOSE_PORT
        !             6: #define DEBUG
        !             7: /*
        !             8:  * FTP server.
        !             9:  */
        !            10: #include <sys/param.h>
        !            11: #include <sys/stat.h>
        !            12: #include <sys/ioctl.h>
        !            13: #include <sys/file.h>
        !            14: #include <wait.h>
        !            15: 
        !            16: #include <sys/inet/in.h>
        !            17: #include <sys/inet/tcp_user.h>
        !            18: 
        !            19: #include "ftp.h"
        !            20: 
        !            21: #include <stdio.h>
        !            22: #include <signal.h>
        !            23: #include <pwd.h>
        !            24: #include <setjmp.h>
        !            25: #include <errno.h>
        !            26: 
        !            27: /*
        !            28:  * File containing login names
        !            29:  * NOT to be used on this machine.
        !            30:  * Commonly used to disallow uucp.
        !            31:  */
        !            32: #define        FTPUSERS        "/etc/ftpusers"
        !            33: 
        !            34: extern int errno;
        !            35: extern char *sys_errlist[];
        !            36: extern char *crypt();
        !            37: extern char version[];
        !            38: extern char *home;             /* pointer to home directory for glob */
        !            39: extern FILE *popen(), *fopen();
        !            40: extern int pclose(), fclose();
        !            41: 
        !            42: struct socket {
        !            43:        unsigned short sport;
        !            44:        long saddr;
        !            45: } his_addr, data_dest, data_source, ctrl_addr;
        !            46: #define        SO_KEEPALIVE    0x2
        !            47: 
        !            48: int    data;
        !            49: jmp_buf        errcatch;
        !            50: int    logged_in;
        !            51: struct passwd *pw;
        !            52: int    debug;
        !            53: int    timeout;
        !            54: int    logging;
        !            55: int    guest;
        !            56: int    type;
        !            57: int    form;
        !            58: int    stru;                   /* avoid C keyword */
        !            59: int    mode;
        !            60: int    usedefault = 1;         /* for data transfers */
        !            61: char   hostname[32];
        !            62: char   remotehost[32];
        !            63: int    pasv;
        !            64: 
        !            65: /*
        !            66:  * Timeout intervals for retrying connections
        !            67:  * to hosts that don't accept PORT cmds.  This
        !            68:  * is a kludge, but given the problems with TCP...
        !            69:  */
        !            70: #define        SWAITMAX        90      /* wait at most 90 seconds */
        !            71: #define        SWAITINT        5       /* interval between retries */
        !            72: 
        !            73: int    swaitmax = SWAITMAX;
        !            74: int    swaitint = SWAITINT;
        !            75: 
        !            76: int    lostconn();
        !            77: int    reapchild();
        !            78: FILE   *getdatasock();
        !            79: FILE   *dataconn();
        !            80: 
        !            81: main(argc, argv)
        !            82:        int argc;
        !            83:        char *argv[];
        !            84: {
        !            85:        int ctrl, s, options = 0;
        !            86:        char *cp;
        !            87:        int dev;
        !            88:        int status;
        !            89:        struct in_service *servp;
        !            90: 
        !            91:        servp = in_service("ftp", "tcp", 0);
        !            92:        if (servp == 0) {
        !            93:                fprintf(stderr, "ftpd: ftp/tcp: unknown service\n");
        !            94:                exit(1);
        !            95:        }
        !            96:        ctrl_addr.sport = servp->port;
        !            97:        data_source.sport = servp->port - 1;
        !            98: 
        !            99:        debug = 0;
        !           100:        argc--, argv++;
        !           101:        while (argc > 0 && *argv[0] == '-') {
        !           102:                for (cp = &argv[0][1]; *cp; cp++) switch (*cp) {
        !           103: 
        !           104:                case 'v':
        !           105:                        debug = 1;
        !           106:                        break;
        !           107: 
        !           108:                case 'd':
        !           109:                        debug = 1;
        !           110:                        break;
        !           111: 
        !           112:                case 'l':
        !           113:                        logging = 1;
        !           114:                        break;
        !           115: 
        !           116:                case 't':
        !           117:                        timeout = atoi(++cp);
        !           118:                        goto nextopt;
        !           119:                        break;
        !           120: 
        !           121:                default:
        !           122:                        fprintf(stderr, "Unknown flag -%c ignored.\n", *cp);
        !           123:                        break;
        !           124:                }
        !           125: nextopt:
        !           126:                argc--, argv++;
        !           127:        }
        !           128: 
        !           129: #ifndef DEBUG
        !           130:        if (fork())
        !           131:                exit(0);
        !           132:        for (s = 0; s < 10; s++)
        !           133:                if (!logging || (s != 2))
        !           134:                        (void) close(s);
        !           135:        (void) open("/", 0);
        !           136:        (void) dup2(0, 1);
        !           137:        if (!logging)
        !           138:                (void) dup2(0, 2);
        !           139:        { int tt = open("/dev/tty", 2);
        !           140:          if (tt > 0) {
        !           141: /*             ioctl(tt, TIOCNOTTY, 0);        */
        !           142:                close(tt);
        !           143:          }
        !           144:        }
        !           145: #endif
        !           146:        signal(SIGPIPE, SIG_IGN); /* used to be lostconn */
        !           147:        signal(SIGHUP, SIG_IGN);
        !           148: 
        !           149:        fprintf(stderr,"ftpd started: options (debug,logging,timeout) are (%d,%d,%d)\n", debug, logging, timeout);
        !           150:        do {
        !           151:                struct tcpuser tu;
        !           152: 
        !           153:                s = tcp_sock();
        !           154:                if (s < 0) {
        !           155:                        perror("ftpd: socket");;
        !           156:                        sleep(5);
        !           157:                        continue;
        !           158:                }
        !           159:                tu.lport = servp->port;
        !           160:                tu.laddr = 0;
        !           161:                tu.fport = 0;
        !           162:                tu.faddr = 0;
        !           163:                tu.param = SO_KEEPALIVE;
        !           164:                if (tcp_listen(s, &tu) < 0) {
        !           165:                        close(s);
        !           166:                        s = -1;
        !           167:                        sleep(30);
        !           168:                        continue;
        !           169:                }
        !           170:        } while (s < 0);
        !           171: 
        !           172:        for (;;) {
        !           173:                int ctrl;
        !           174:                struct tcpuser tu;
        !           175: 
        !           176:                tu.lport = 0;
        !           177:                tu.laddr = 0;
        !           178:                tu.fport = 0;
        !           179:                tu.faddr = 0;
        !           180:                tu.param = 0;
        !           181:                ctrl = tcp_accept(s, &tu);
        !           182:                his_addr.saddr = tu.faddr;
        !           183:                his_addr.sport = tu.fport;
        !           184:                ctrl_addr.saddr = tu.laddr;
        !           185:                ctrl_addr.sport = tu.lport;
        !           186:                dev = tu.param;
        !           187:                fprintf(stderr, "accept req from %s, port %d\n", inet_ntoa(his_addr.saddr), his_addr.sport);
        !           188:                if (ctrl < 0) {
        !           189:                        if (errno == EINTR)
        !           190:                                continue;
        !           191:                        perror("ftpd: accept");
        !           192:                        sleep(1);
        !           193:                        continue;
        !           194:                }
        !           195:                while (wait3(&status, WNOHANG, 0) > 0)
        !           196:                        ;
        !           197:                signal(SIGCHLD, reapchild);
        !           198:                switch(fork()) {
        !           199:                case -1:
        !           200:                        printf("Out of processes\n");
        !           201:                        break;
        !           202:                case 0:
        !           203:                        signal (SIGCHLD, SIG_IGN);
        !           204:                        dolog(&his_addr);
        !           205:                        close(s);
        !           206:                        dup2(ctrl, 0), close(ctrl), dup2(0, 1);
        !           207:                        /*
        !           208:                         * Set up default state
        !           209:                         */
        !           210:                        logged_in = 0;
        !           211:                        data = -1;
        !           212:                        type = TYPE_A;
        !           213:                        form = FORM_N;
        !           214:                        stru = STRU_F;
        !           215:                        mode = MODE_S;
        !           216: /* try to do this equivalently
        !           217:                        (void) getsockname(0, &ctrl_addr, sizeof (ctrl_addr));
        !           218:                        gethostname(hostname, sizeof (hostname));
        !           219: */
        !           220:                        reply(220, "%s FTP server (%s) ready.",
        !           221:                                hostname, version);
        !           222:                        for (;;) {
        !           223:                                setjmp(errcatch);
        !           224:                                yyparse();
        !           225:                                fprintf(stderr, "out of yyparse\n");
        !           226:                        }
        !           227:                }
        !           228:                close(ctrl);
        !           229:        }
        !           230: }
        !           231: 
        !           232: reapchild()
        !           233: {
        !           234:        union wait status;
        !           235: 
        !           236:        while (wait3(&status, WNOHANG, 0) > 0)
        !           237:                ;
        !           238: }
        !           239: 
        !           240: lostconn()
        !           241: {
        !           242: 
        !           243:        if (debug)
        !           244:                fprintf(stderr, "Lost connection.\n");
        !           245:        dologout(-1);
        !           246: }
        !           247: 
        !           248: pass(passwd)
        !           249:        char *passwd;
        !           250: {
        !           251:        char *xpasswd, *savestr();
        !           252:        static struct passwd save;
        !           253: 
        !           254:        if (logged_in || pw == NULL) {
        !           255:                reply(503, "Login with USER first.");
        !           256:                return;
        !           257:        }
        !           258:        if (!guest) {           /* "ftp" is only account allowed no password */
        !           259:                xpasswd = crypt(passwd, pw->pw_passwd);
        !           260:                if (*pw->pw_passwd == '\0' || strcmp(xpasswd, pw->pw_passwd)) {
        !           261:                        reply(530, "Login incorrect.");
        !           262:                        pw = NULL;
        !           263:                        return;
        !           264:                }
        !           265:        }
        !           266: /*
        !           267:        setgid(pw->pw_gid);
        !           268:        initgroups(pw->pw_name, pw->pw_gid);
        !           269: */
        !           270:        if (chdir(pw->pw_dir)) {
        !           271:                reply(550, "User %s: can't change directory to $s.",
        !           272:                        pw->pw_name, pw->pw_dir);
        !           273:                goto bad;
        !           274:        }
        !           275:        if (guest && chroot(pw->pw_dir) < 0) {
        !           276:                reply(550, "Can't set guest privileges.");
        !           277:                goto bad;
        !           278:        }
        !           279:        if (!guest)
        !           280:                reply(230, "User %s logged in.", pw->pw_name);
        !           281:        else
        !           282:                reply(230, "Guest login ok, access restrictions apply.");
        !           283:        logged_in = 1;
        !           284:        dologin(pw);
        !           285: /*     setuid(pw->pw_uid); */
        !           286:        /*
        !           287:         * Save everything so globbing doesn't
        !           288:         * clobber the fields.
        !           289:         */
        !           290:        save = *pw;
        !           291:        save.pw_name = savestr(pw->pw_name);
        !           292:        save.pw_passwd = savestr(pw->pw_passwd);
        !           293:        save.pw_comment = savestr(pw->pw_comment);
        !           294:        save.pw_gecos = savestr(pw->pw_gecos, &save.pw_gecos);
        !           295:        save.pw_dir = savestr(pw->pw_dir);
        !           296:        save.pw_shell = savestr(pw->pw_shell);
        !           297:        pw = &save;
        !           298:        home = pw->pw_dir;              /* home dir for globbing */
        !           299:        return;
        !           300: bad:
        !           301: /*     setuid(0); */
        !           302:        pw = NULL;
        !           303: }
        !           304: 
        !           305: char *
        !           306: savestr(s)
        !           307:        char *s;
        !           308: {
        !           309:        char *malloc();
        !           310:        char *new = malloc(strlen(s) + 1);
        !           311:        
        !           312:        if (new != NULL)
        !           313:                strcpy(new, s);
        !           314:        return (new);
        !           315: }
        !           316: 
        !           317: 
        !           318: openfile(name)
        !           319: char *name;
        !           320: {
        !           321:        reply(550, "%s: can't open", name);
        !           322: }
        !           323: 
        !           324: retrieve(cmd, name)
        !           325:        char *cmd, *name;
        !           326: {
        !           327:        FILE *fin, *dout;
        !           328:        struct stat st;
        !           329:        int (*closefunc)();
        !           330: 
        !           331:        if (cmd == 0) {
        !           332: #ifdef notdef
        !           333:                /* no remote command execution -- it's a security hole */
        !           334:                if (*name == '|')
        !           335:                        fin = popen(name + 1, "r"), closefunc = pclose;
        !           336:                else
        !           337: #endif
        !           338:                if (-1 == access2(name, 4, pw->pw_uid, pw->pw_gid)) {
        !           339:                        fprintf(stderr, "can't access %s\n", name);
        !           340:                        fin = NULL;
        !           341:                } else
        !           342:                        fin = fopen(name, "r"), closefunc = fclose;
        !           343:        } else {
        !           344:                char line[BUFSIZ];
        !           345: 
        !           346:                sprintf(line, cmd, name), name = line;
        !           347:                fprintf(stderr,"cmd is %s\n", line);
        !           348:                fin = popen(line, "r"), closefunc = pclose;
        !           349:        }
        !           350:        if (fin == NULL) {
        !           351:                fprintf(stderr, "bad popen()\n");
        !           352:                if (errno != 0)
        !           353:                        reply(550, "%s: %s.", name, sys_errlist[errno]);
        !           354:                return;
        !           355:        }
        !           356: 
        !           357:        st.st_size = 0;
        !           358:        if (cmd == 0 &&
        !           359:            (stat(name, &st) < 0 || (st.st_mode&S_IFMT) != S_IFREG)) {
        !           360:                reply(550, "%s: not a plain file.", name);
        !           361:                goto done;
        !           362:        }
        !           363:        dout = dataconn(name, st.st_size, "w");
        !           364:        if (dout == NULL)
        !           365:                goto done;
        !           366:        if (send_data(fin, dout) || ferror(dout))
        !           367:                reply(550, "%s: %s.", name, sys_errlist[errno]);
        !           368: 
        !           369:        else {
        !           370:                fclose(dout);
        !           371:                delay(timeout);
        !           372:                reply(226, "Transfer complete.");
        !           373:        }
        !           374:        data = -1;
        !           375: done:
        !           376:        (*closefunc)(fin);
        !           377: }
        !           378: 
        !           379: store(name, mode)
        !           380:        char *name, *mode;
        !           381: {
        !           382:        FILE *fout, *din;
        !           383:        int (*closefunc)(), dochown = 0;
        !           384: 
        !           385: #ifdef notdef
        !           386:        /* no remote command execution -- it's a security hole */
        !           387: 
        !           388:        if (name[0] == '|')
        !           389:                fout = popen(&name[1], "w"), closefunc = pclose;
        !           390:        else
        !           391: #endif
        !           392:        {
        !           393:                struct stat st;
        !           394: 
        !           395:                if (stat(name, &st) < 0)
        !           396:                        dochown++;
        !           397:                if (-1 == access2(name, 2, pw->pw_uid, pw->pw_gid))
        !           398:                        fout = NULL;
        !           399:                else
        !           400:                        fout = fopen(name, mode), closefunc = fclose;
        !           401:        }
        !           402:        if (fout == NULL) {
        !           403:                reply(550, "%s: %s.", name, sys_errlist[errno]);
        !           404:                return;
        !           405:        }
        !           406:        din = dataconn(name, (off_t)-1, "r");
        !           407:        if (din == NULL)
        !           408:                goto done;
        !           409:        if (receive_data(din, fout) || ferror(fout))
        !           410:                reply(550, "%s: %s.", name, sys_errlist[errno]);
        !           411:        else {
        !           412:                fflush(fout);
        !           413:                delay(timeout);
        !           414:                reply(226, "Transfer complete.");
        !           415:        }
        !           416:        fclose(din);
        !           417:        data = -1;
        !           418: done:
        !           419:        if (dochown)
        !           420:                (void) chown(name, pw->pw_uid, -1);
        !           421:        (*closefunc)(fout);
        !           422: }
        !           423: FILE *
        !           424: getdatasock(mode)
        !           425:        char *mode;
        !           426: {
        !           427:        int s;
        !           428: 
        !           429:        if (data >= 0)
        !           430:                return (fdopen(data, mode));
        !           431:        data_source.saddr = ctrl_addr.saddr;
        !           432:        s = tcp_sock();
        !           433:        if (s < 0) {
        !           434:                perror("ftpd: socket");
        !           435:                return(NULL);
        !           436:        }
        !           437:        return (fdopen(s, mode));
        !           438: }
        !           439: 
        !           440: FILE *
        !           441: dataconn(name, size, mode)
        !           442:        char *name;
        !           443:        off_t size;
        !           444:        char *mode;
        !           445: {
        !           446:        char sizebuf[32];
        !           447:        FILE *file;
        !           448:        int retry = 0;
        !           449:        struct tcpuser tu;
        !           450: 
        !           451:        if (size >= 0)
        !           452:                sprintf (sizebuf, " (%ld bytes)", size);
        !           453:        else
        !           454:                (void) strcpy(sizebuf, "");
        !           455:        if (data >= 0) {
        !           456:                reply(125, "Using existing data connection for %s%s.",
        !           457:                    name, sizebuf);
        !           458:                usedefault = 1;
        !           459:                return (fdopen(data, mode));
        !           460:        }
        !           461:        if (usedefault)
        !           462:                data_dest = his_addr;
        !           463:        usedefault = 1;
        !           464:        file  = getdatasock(mode);
        !           465:        if (file == NULL) {
        !           466:                reply(425, "Can't create data socket (%s,%d): %s.",
        !           467:                        inet_ntoa(data_source.saddr),
        !           468:                        ntohs(data_source.sport),
        !           469:                sys_errlist[errno]);
        !           470:                return (NULL);
        !           471:        }
        !           472:        reply(150, "Opening data connection for %s (%s,%d)%s.",
        !           473:            name,
        !           474:                inet_ntoa(data_dest.saddr),
        !           475:                data_dest.sport, sizebuf);
        !           476: 
        !           477:        data = fileno(file);
        !           478:        tu.lport = pasv?0:data_source.sport;
        !           479:        tu.laddr = 0;
        !           480:        tu.fport = data_dest.sport;
        !           481:        tu.faddr = data_dest.saddr;
        !           482:        tu.param = 0;
        !           483:        while (tcp_connect(data, &tu) < 0) {            
        !           484:                if (retry < swaitmax) {
        !           485:                        sleep(swaitint);
        !           486:                        retry += swaitint;
        !           487:                        continue;
        !           488:                }
        !           489:                reply(425, "Can't build data connection: %s.",
        !           490:                    sys_errlist[errno]);
        !           491:                (void)fclose(file);
        !           492:                data = -1;
        !           493:                return (NULL);
        !           494:        }
        !           495:        return (file);
        !           496: }
        !           497: 
        !           498: /*
        !           499:  * Tranfer the contents of "instr" to
        !           500:  * "outstr" peer using the appropriate
        !           501:  * encapulation of the date subject
        !           502:  * to Mode, Structure, and Type.
        !           503:  *
        !           504:  * NB: Form isn't handled.
        !           505:  */
        !           506: send_data(instr, outstr)
        !           507:        FILE *instr, *outstr;
        !           508: {
        !           509:        register int c;
        !           510:        int netfd, filefd, cnt = 0;
        !           511:        char buf[BUFSIZ];
        !           512: 
        !           513:        switch (type) {
        !           514: 
        !           515:        case TYPE_A:
        !           516:                while ((c = getc(instr)) != EOF) {
        !           517:                        if (c == '\n') {
        !           518:                                if (ferror (outstr))
        !           519:                                        return (1);
        !           520:                                putc('\r', outstr);
        !           521:                        }
        !           522:                        putc(c, outstr);
        !           523:                        if (c == '\r')
        !           524:                                putc ('\0', outstr);
        !           525: /*                     cnt++;
        !           526:                        if (!(cnt%1000)) { fprintf(stderr, "%d ", cnt); fflush(stderr); } */
        !           527:                }
        !           528:                if (ferror (instr) || ferror (outstr)) {
        !           529:                        fprintf(stderr,"error: inst %d, outstr %d\n", ferror(instr), ferror(outstr));
        !           530:                        return (1);
        !           531:                }
        !           532:                return (0);
        !           533:                
        !           534:        case TYPE_I:
        !           535:        case TYPE_L:
        !           536:                netfd = fileno(outstr);
        !           537:                filefd = fileno(instr);
        !           538: 
        !           539:                while ((cnt = read(filefd, buf, sizeof (buf))) > 0)
        !           540:                        if (write(netfd, buf, cnt) < 0) {
        !           541:                                fprintf(stderr, "write error, cnt=%d\n", cnt);
        !           542:                                return (1);
        !           543:                }
        !           544:                return (cnt < 0);
        !           545:        }
        !           546:        reply(504,"Unimplemented TYPE %d in send_data", type);
        !           547:        return (1);
        !           548: }
        !           549: 
        !           550: /*
        !           551:  * Transfer data from peer to
        !           552:  * "outstr" using the appropriate
        !           553:  * encapulation of the data subject
        !           554:  * to Mode, Structure, and Type.
        !           555:  *
        !           556:  * N.B.: Form isn't handled.
        !           557:  */
        !           558: receive_data(instr, outstr)
        !           559:        FILE *instr, *outstr;
        !           560: {
        !           561:        register int c;
        !           562:        int cnt;
        !           563:        char buf[BUFSIZ];
        !           564: 
        !           565: 
        !           566:        switch (type) {
        !           567: 
        !           568:        case TYPE_I:
        !           569:        case TYPE_L:
        !           570:                while ((cnt = read(fileno(instr), buf, sizeof buf)) > 0)
        !           571:                        if (write(fileno(outstr), buf, cnt) < 0)
        !           572:                                return (1);
        !           573:                return (cnt < 0);
        !           574: 
        !           575:        case TYPE_E:
        !           576:                reply(504, "TYPE E not implemented.");
        !           577:                return (1);
        !           578: 
        !           579:        case TYPE_A:
        !           580:                while ((c = getc(instr)) != EOF) {
        !           581:                        if (c == '\r') {
        !           582:                                if (ferror (outstr))
        !           583:                                        return (1);
        !           584:                                if ((c = getc(instr)) != '\n')
        !           585:                                        putc ('\r', outstr);
        !           586:                                if (c == '\0')
        !           587:                                        continue;
        !           588:                        }
        !           589:                        putc (c, outstr);
        !           590:                }
        !           591:                if (ferror (instr) || ferror (outstr))
        !           592:                        return (1);
        !           593:                return (0);
        !           594:        }
        !           595:        fatal("Unknown type in receive_data.");
        !           596:        /*NOTREACHED*/
        !           597: }
        !           598: 
        !           599: fatal(s)
        !           600:        char *s;
        !           601: {
        !           602:        reply(451, "Error in server: %s\n", s);
        !           603:        reply(221, "Closing connection due to server error.");
        !           604:        dologout(0);
        !           605: }
        !           606: 
        !           607: reply(n, s, args)
        !           608:        int n;
        !           609:        char *s;
        !           610: {
        !           611: 
        !           612:        printf("%d ", n);
        !           613:        _doprnt(s, &args, stdout);
        !           614:        printf("\r\n");
        !           615:        fflush(stdout);
        !           616:        if (debug) {
        !           617:                fprintf(stderr, "<--- %d ", n);
        !           618:                _doprnt(s, &args, stderr);
        !           619:                fprintf(stderr, "\n");
        !           620:                fflush(stderr);
        !           621:        }
        !           622: }
        !           623: 
        !           624: lreply(n, s, args)
        !           625:        int n;
        !           626:        char *s;
        !           627: {
        !           628:        printf("%d-", n);
        !           629:        _doprnt(s, &args, stdout);
        !           630:        printf("\r\n");
        !           631:        fflush(stdout);
        !           632:        if (debug) {
        !           633:                fprintf(stderr, "<--- %d-", n);
        !           634:                _doprnt(s, &args, stderr);
        !           635:                fprintf(stderr, "\n");
        !           636:        }
        !           637: }
        !           638: 
        !           639: replystr(s)
        !           640:        char *s;
        !           641: {
        !           642:        printf("%s\r\n", s);
        !           643:        fflush(stdout);
        !           644:        if (debug)
        !           645:                fprintf(stderr, "<--- %s\n", s);
        !           646: }
        !           647: 
        !           648: ack(s)
        !           649:        char *s;
        !           650: {
        !           651:        reply(200, "%s command okay.", s);
        !           652: }
        !           653: 
        !           654: nack(s)
        !           655:        char *s;
        !           656: {
        !           657:        reply(502, "%s command not implemented.", s);
        !           658: }
        !           659: 
        !           660: yyerror()
        !           661: {
        !           662:        reply(500, "Command not understood.");
        !           663: }
        !           664: 
        !           665: delete(name)
        !           666:        char *name;
        !           667: {
        !           668:        struct stat st;
        !           669: 
        !           670:        if (stat(name, &st) < 0) {
        !           671:                reply(550, "%s: %s.", name, sys_errlist[errno]);
        !           672:                return;
        !           673:        }
        !           674:        if ((st.st_mode&S_IFMT) == S_IFDIR) {
        !           675:                if (rmdir(name) < 0) {
        !           676:                        reply(550, "%s: %s.", name, sys_errlist[errno]);
        !           677:                        return;
        !           678:                }
        !           679:                goto done;
        !           680:        }
        !           681:        if (unlink(name) < 0) {
        !           682:                reply(550, "%s: %s.", name, sys_errlist[errno]);
        !           683:                return;
        !           684:        }
        !           685: done:
        !           686:        ack("DELE");
        !           687: }
        !           688: 
        !           689: cwd(path)
        !           690:        char *path;
        !           691: {
        !           692: 
        !           693:        if (chdir(path) < 0) {
        !           694:                reply(550, "%s: %s.", path, sys_errlist[errno]);
        !           695:                return;
        !           696:        }
        !           697:        ack("CWD");
        !           698: }
        !           699: 
        !           700: makedir(name)
        !           701:        char *name;
        !           702: {
        !           703:        struct stat st;
        !           704:        int dochown = stat(name, &st) < 0;
        !           705: 
        !           706:        if (mkdir(name, 0777) < 0) {
        !           707:                reply(550, "%s: %s.", name, sys_errlist[errno]);
        !           708:                return;
        !           709:        }
        !           710:        if (dochown)
        !           711:                (void) chown(name, pw->pw_uid, -1);
        !           712:        ack("MKDIR");
        !           713: }
        !           714: 
        !           715: removedir(name)
        !           716:        char *name;
        !           717: {
        !           718: 
        !           719:        if (rmdir(name) < 0) {
        !           720:                reply(550, "%s: %s.", name, sys_errlist[errno]);
        !           721:                return;
        !           722:        }
        !           723:        ack("RMDIR");
        !           724: }
        !           725: 
        !           726: #define        MAXPATHLEN      256
        !           727: pwd()
        !           728: {
        !           729:        char path[MAXPATHLEN + 1];
        !           730: 
        !           731:        if (getwd(path) == NULL) {
        !           732:                reply(451, "%s.", path);
        !           733:                return;
        !           734:        }
        !           735:        reply(251, "\"%s\" is current directory.", path);
        !           736: }
        !           737: 
        !           738: char *
        !           739: renamefrom(name)
        !           740:        char *name;
        !           741: {
        !           742:        struct stat st;
        !           743: 
        !           744:        if (stat(name, &st) < 0) {
        !           745:                reply(550, "%s: %s.", name, sys_errlist[errno]);
        !           746:                return ((char *)0);
        !           747:        }
        !           748:        reply(350, "File exists, ready for destination name");
        !           749:        return (name);
        !           750: }
        !           751: 
        !           752: renamecmd(from, to)
        !           753:        char *from, *to;
        !           754: {
        !           755: 
        !           756:        if (rename(from, to) < 0) {
        !           757:                reply(550, "rename: %s.", sys_errlist[errno]);
        !           758:                return;
        !           759:        }
        !           760:        ack("RNTO");
        !           761: }
        !           762: 
        !           763: dolog(addr)
        !           764:        register struct socket *addr;
        !           765: {
        !           766:        char *h_name = (char *)in_host(addr->saddr);
        !           767:        time_t  t;
        !           768: 
        !           769:        strncpy(remotehost, h_name, sizeof (remotehost));
        !           770:        if (!logging)
        !           771:                return;
        !           772:        t = time(0);
        !           773:        fprintf(stderr,"FTPD: connection from %s at %s", remotehost, ctime(&t));
        !           774:        fflush(stderr);
        !           775: }
        !           776: 
        !           777: #include <utmp.h>
        !           778: 
        !           779: #define        SCPYN(a, b)     strncpy(a, b, sizeof (a))
        !           780: struct utmp utmp;
        !           781: 
        !           782: /*
        !           783:  * Record login in wtmp file.
        !           784:  */
        !           785: 
        !           786: #define        O_WRONLY        1
        !           787: #define O_APPEND       1
        !           788: dologin(pw)
        !           789:        struct passwd *pw;
        !           790: {
        !           791:        int wtmp;
        !           792:        char line[32];
        !           793: 
        !           794:        pasv = 0;
        !           795:        wtmp = open("/usr/adm/wtmp", O_WRONLY|O_APPEND);
        !           796:        if (wtmp >= 0) {
        !           797:                /* hack, but must be unique and no tty line */
        !           798:                sprintf(line, "ftp%d", getpid());
        !           799:                SCPYN(utmp.ut_line, line);
        !           800:                SCPYN(utmp.ut_name, pw->pw_name);
        !           801:                utmp.ut_time = time(0);
        !           802:                (void) write(wtmp, (char *)&utmp, sizeof (utmp));
        !           803:                (void) close(wtmp);
        !           804:        }
        !           805: }
        !           806: 
        !           807: /*
        !           808:  * Record logout in wtmp file
        !           809:  * and exit with supplied status.
        !           810:  */
        !           811: dologout(status)
        !           812:        int status;
        !           813: {
        !           814:        int wtmp;
        !           815: 
        !           816:        if (!logged_in)
        !           817:                _exit(status);
        !           818:        wtmp = open("/usr/adm/wtmp", O_WRONLY|O_APPEND);
        !           819:        if (wtmp >= 0) {
        !           820:                SCPYN(utmp.ut_name, "");
        !           821:                utmp.ut_time = time(0);
        !           822:                (void) write(wtmp, (char *)&utmp, sizeof (utmp));
        !           823:                (void) close(wtmp);
        !           824:        }
        !           825:        /* beware of flushing buffers after a SIGPIPE */
        !           826:        _exit(status);
        !           827: }
        !           828: 
        !           829: static char *
        !           830: nextarg(cpp)
        !           831:        char *cpp;
        !           832: {
        !           833:        register char *cp = cpp;
        !           834: 
        !           835:        if (cp == 0)
        !           836:                return (cp);
        !           837:        while (*cp && *cp != ' ' && *cp != '\t')
        !           838:                cp++;
        !           839:        if (*cp == ' ' || *cp == '\t') {
        !           840:                *cp++ = '\0';
        !           841:                while (*cp == ' ' || *cp == '\t')
        !           842:                        cp++;
        !           843:        }
        !           844:        if (cp == cpp)
        !           845:                return ((char *)0);
        !           846:        return (cp);
        !           847: }
        !           848: 
        !           849: /*
        !           850:  * Check user requesting login priviledges.
        !           851:  * Disallow anyone mentioned in the file FTPUSERS
        !           852:  * to allow people such as uucp to be avoided.
        !           853:  */
        !           854: checkuser(name)
        !           855:        register char *name;
        !           856: {
        !           857:        char line[BUFSIZ], *strchr();
        !           858:        FILE *fd;
        !           859:        int found = 0;
        !           860: 
        !           861:        fd = fopen(FTPUSERS, "r");
        !           862:        if (fd == NULL)
        !           863:                return (1);
        !           864:        while (fgets(line, sizeof (line), fd) != NULL) {
        !           865:                register char *cp = strchr(line, '\n');
        !           866: 
        !           867:                if (cp)
        !           868:                        *cp = '\0';
        !           869:                if (strcmp(line, name) == 0) {
        !           870:                        found++;
        !           871:                        break;
        !           872:                }
        !           873:        }
        !           874:        fclose(fd);
        !           875:        return (!found);
        !           876: }
        !           877: rename(from, to)
        !           878: {
        !           879:        if (-1 == link(from, to))
        !           880:                return(-1);
        !           881:        return(unlink(from));
        !           882: }
        !           883: inet_ntoa(addr)
        !           884: long addr;
        !           885: {
        !           886:        static char b[32];
        !           887:        unsigned char *xp = (unsigned char *)&addr;
        !           888: 
        !           889:        sprintf(b, "%d.%d.%d.%d", xp[3], xp[2], xp[1], xp[0]);
        !           890:        return(b);
        !           891: }
        !           892: delay()
        !           893: {
        !           894: }

unix.superglobalmegacorp.com

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