Annotation of 43BSD/bin/rcp.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (c) 1983 Regents of the University of California.
        !             3:  * All rights reserved.  The Berkeley software License Agreement
        !             4:  * specifies the terms and conditions for redistribution.
        !             5:  */
        !             6: 
        !             7: #ifndef lint
        !             8: char copyright[] =
        !             9: "@(#) Copyright (c) 1983 Regents of the University of California.\n\
        !            10:  All rights reserved.\n";
        !            11: #endif not lint
        !            12: 
        !            13: #ifndef lint
        !            14: static char sccsid[] = "@(#)rcp.c      5.4 (Berkeley) 9/12/85";
        !            15: #endif not lint
        !            16: 
        !            17: /*
        !            18:  * rcp
        !            19:  */
        !            20: #include <sys/param.h>
        !            21: #include <sys/stat.h>
        !            22: #include <sys/time.h>
        !            23: #include <sys/ioctl.h>
        !            24: 
        !            25: #include <netinet/in.h>
        !            26: 
        !            27: #include <stdio.h>
        !            28: #include <signal.h>
        !            29: #include <pwd.h>
        !            30: #include <ctype.h>
        !            31: #include <netdb.h>
        !            32: #include <errno.h>
        !            33: 
        !            34: int    rem;
        !            35: char   *colon(), *index(), *rindex(), *malloc(), *strcpy(), *sprintf();
        !            36: int    errs;
        !            37: int    lostconn();
        !            38: int    errno;
        !            39: char   *sys_errlist[];
        !            40: int    iamremote, targetshouldbedirectory;
        !            41: int    iamrecursive;
        !            42: int    pflag;
        !            43: struct passwd *pwd;
        !            44: struct passwd *getpwuid();
        !            45: int    userid;
        !            46: int    port;
        !            47: 
        !            48: struct buffer {
        !            49:        int     cnt;
        !            50:        char    *buf;
        !            51: } *allocbuf();
        !            52: 
        !            53: /*VARARGS*/
        !            54: int    error();
        !            55: 
        !            56: #define        ga()            (void) write(rem, "", 1)
        !            57: 
        !            58: main(argc, argv)
        !            59:        int argc;
        !            60:        char **argv;
        !            61: {
        !            62:        char *targ, *host, *src;
        !            63:        char *suser, *tuser, *thost;
        !            64:        int i;
        !            65:        char buf[BUFSIZ], cmd[16];
        !            66:        struct servent *sp;
        !            67: 
        !            68:        sp = getservbyname("shell", "tcp");
        !            69:        if (sp == NULL) {
        !            70:                fprintf(stderr, "rcp: shell/tcp: unknown service\n");
        !            71:                exit(1);
        !            72:        }
        !            73:        port = sp->s_port;
        !            74:        pwd = getpwuid(userid = getuid());
        !            75:        if (pwd == 0) {
        !            76:                fprintf(stderr, "who are you?\n");
        !            77:                exit(1);
        !            78:        }
        !            79: 
        !            80:        for (argc--, argv++; argc > 0 && **argv == '-'; argc--, argv++) {
        !            81:                (*argv)++;
        !            82:                while (**argv) switch (*(*argv)++) {
        !            83: 
        !            84:                    case 'r':
        !            85:                        iamrecursive++;
        !            86:                        break;
        !            87: 
        !            88:                    case 'p':           /* preserve mtimes and atimes */
        !            89:                        pflag++;
        !            90:                        break;
        !            91: 
        !            92:                    /* The rest of these are not for users. */
        !            93:                    case 'd':
        !            94:                        targetshouldbedirectory = 1;
        !            95:                        break;
        !            96: 
        !            97:                    case 'f':           /* "from" */
        !            98:                        iamremote = 1;
        !            99:                        (void) response();
        !           100:                        (void) setuid(userid);
        !           101:                        source(--argc, ++argv);
        !           102:                        exit(errs);
        !           103: 
        !           104:                    case 't':           /* "to" */
        !           105:                        iamremote = 1;
        !           106:                        (void) setuid(userid);
        !           107:                        sink(--argc, ++argv);
        !           108:                        exit(errs);
        !           109: 
        !           110:                    default:
        !           111:                        fprintf(stderr,
        !           112:                "Usage: rcp [-p] f1 f2; or: rcp [-rp] f1 ... fn d2\n");
        !           113:                        exit(1);
        !           114:                }
        !           115:        }
        !           116:        rem = -1;
        !           117:        if (argc > 2)
        !           118:                targetshouldbedirectory = 1;
        !           119:        (void) sprintf(cmd, "rcp%s%s%s",
        !           120:            iamrecursive ? " -r" : "", pflag ? " -p" : "", 
        !           121:            targetshouldbedirectory ? " -d" : "");
        !           122:        (void) signal(SIGPIPE, lostconn);
        !           123:        targ = colon(argv[argc - 1]);
        !           124:        if (targ) {                             /* ... to remote */
        !           125:                *targ++ = 0;
        !           126:                if (*targ == 0)
        !           127:                        targ = ".";
        !           128:                thost = index(argv[argc - 1], '@');
        !           129:                if (thost) {
        !           130:                        *thost++ = 0;
        !           131:                        tuser = argv[argc - 1];
        !           132:                        if (*tuser == '\0')
        !           133:                                tuser = NULL;
        !           134:                        else if (!okname(tuser))
        !           135:                                exit(1);
        !           136:                } else {
        !           137:                        thost = argv[argc - 1];
        !           138:                        tuser = NULL;
        !           139:                }
        !           140:                for (i = 0; i < argc - 1; i++) {
        !           141:                        src = colon(argv[i]);
        !           142:                        if (src) {              /* remote to remote */
        !           143:                                *src++ = 0;
        !           144:                                if (*src == 0)
        !           145:                                        src = ".";
        !           146:                                host = index(argv[i], '@');
        !           147:                                if (host) {
        !           148:                                        *host++ = 0;
        !           149:                                        suser = argv[i];
        !           150:                                        if (*suser == '\0')
        !           151:                                                suser = pwd->pw_name;
        !           152:                                        else if (!okname(suser))
        !           153:                                                continue;
        !           154:                (void) sprintf(buf, "rsh %s -l %s -n %s %s '%s%s%s:%s'",
        !           155:                                            host, suser, cmd, src, tuser,
        !           156:                                            tuser ? "@" : "",
        !           157:                                            thost, targ);
        !           158:                                } else
        !           159:                (void) sprintf(buf, "rsh %s -n %s %s '%s%s%s:%s'",
        !           160:                                            argv[i], cmd, src, tuser,
        !           161:                                            tuser ? "@" : "",
        !           162:                                            thost, targ);
        !           163:                                (void) susystem(buf);
        !           164:                        } else {                /* local to remote */
        !           165:                                if (rem == -1) {
        !           166:                                        (void) sprintf(buf, "%s -t %s",
        !           167:                                            cmd, targ);
        !           168:                                        host = thost;
        !           169:                                        rem = rcmd(&host, port, pwd->pw_name,
        !           170:                                            tuser ? tuser : pwd->pw_name,
        !           171:                                            buf, 0);
        !           172:                                        if (rem < 0)
        !           173:                                                exit(1);
        !           174:                                        if (response() < 0)
        !           175:                                                exit(1);
        !           176:                                        (void) setuid(userid);
        !           177:                                }
        !           178:                                source(1, argv+i);
        !           179:                        }
        !           180:                }
        !           181:        } else {                                /* ... to local */
        !           182:                if (targetshouldbedirectory)
        !           183:                        verifydir(argv[argc - 1]);
        !           184:                for (i = 0; i < argc - 1; i++) {
        !           185:                        src = colon(argv[i]);
        !           186:                        if (src == 0) {         /* local to local */
        !           187:                                (void) sprintf(buf, "/bin/cp%s%s %s %s",
        !           188:                                    iamrecursive ? " -r" : "",
        !           189:                                    pflag ? " -p" : "",
        !           190:                                    argv[i], argv[argc - 1]);
        !           191:                                (void) susystem(buf);
        !           192:                        } else {                /* remote to local */
        !           193:                                *src++ = 0;
        !           194:                                if (*src == 0)
        !           195:                                        src = ".";
        !           196:                                host = index(argv[i], '@');
        !           197:                                if (host) {
        !           198:                                        *host++ = 0;
        !           199:                                        suser = argv[i];
        !           200:                                        if (*suser == '\0')
        !           201:                                                suser = pwd->pw_name;
        !           202:                                        else if (!okname(suser))
        !           203:                                                continue;
        !           204:                                } else {
        !           205:                                        host = argv[i];
        !           206:                                        suser = pwd->pw_name;
        !           207:                                }
        !           208:                                (void) sprintf(buf, "%s -f %s", cmd, src);
        !           209:                                rem = rcmd(&host, port, pwd->pw_name, suser,
        !           210:                                    buf, 0);
        !           211:                                if (rem < 0)
        !           212:                                        continue;
        !           213:                                (void) setreuid(0, userid);
        !           214:                                sink(1, argv+argc-1);
        !           215:                                (void) setreuid(userid, 0);
        !           216:                                (void) close(rem);
        !           217:                                rem = -1;
        !           218:                        }
        !           219:                }
        !           220:        }
        !           221:        exit(errs);
        !           222: }
        !           223: 
        !           224: verifydir(cp)
        !           225:        char *cp;
        !           226: {
        !           227:        struct stat stb;
        !           228: 
        !           229:        if (stat(cp, &stb) >= 0) {
        !           230:                if ((stb.st_mode & S_IFMT) == S_IFDIR)
        !           231:                        return;
        !           232:                errno = ENOTDIR;
        !           233:        }
        !           234:        error("rcp: %s: %s.\n", cp, sys_errlist[errno]);
        !           235:        exit(1);
        !           236: }
        !           237: 
        !           238: char *
        !           239: colon(cp)
        !           240:        char *cp;
        !           241: {
        !           242: 
        !           243:        while (*cp) {
        !           244:                if (*cp == ':')
        !           245:                        return (cp);
        !           246:                if (*cp == '/')
        !           247:                        return (0);
        !           248:                cp++;
        !           249:        }
        !           250:        return (0);
        !           251: }
        !           252: 
        !           253: okname(cp0)
        !           254:        char *cp0;
        !           255: {
        !           256:        register char *cp = cp0;
        !           257:        register int c;
        !           258: 
        !           259:        do {
        !           260:                c = *cp;
        !           261:                if (c & 0200)
        !           262:                        goto bad;
        !           263:                if (!isalpha(c) && !isdigit(c) && c != '_' && c != '-')
        !           264:                        goto bad;
        !           265:                cp++;
        !           266:        } while (*cp);
        !           267:        return (1);
        !           268: bad:
        !           269:        fprintf(stderr, "rcp: invalid user name %s\n", cp0);
        !           270:        return (0);
        !           271: }
        !           272: 
        !           273: susystem(s)
        !           274:        char *s;
        !           275: {
        !           276:        int status, pid, w;
        !           277:        register int (*istat)(), (*qstat)();
        !           278: 
        !           279:        if ((pid = vfork()) == 0) {
        !           280:                (void) setuid(userid);
        !           281:                execl("/bin/sh", "sh", "-c", s, (char *)0);
        !           282:                _exit(127);
        !           283:        }
        !           284:        istat = signal(SIGINT, SIG_IGN);
        !           285:        qstat = signal(SIGQUIT, SIG_IGN);
        !           286:        while ((w = wait(&status)) != pid && w != -1)
        !           287:                ;
        !           288:        if (w == -1)
        !           289:                status = -1;
        !           290:        (void) signal(SIGINT, istat);
        !           291:        (void) signal(SIGQUIT, qstat);
        !           292:        return (status);
        !           293: }
        !           294: 
        !           295: source(argc, argv)
        !           296:        int argc;
        !           297:        char **argv;
        !           298: {
        !           299:        char *last, *name;
        !           300:        struct stat stb;
        !           301:        static struct buffer buffer;
        !           302:        struct buffer *bp;
        !           303:        int x, sizerr, f, amt;
        !           304:        off_t i;
        !           305:        char buf[BUFSIZ];
        !           306: 
        !           307:        for (x = 0; x < argc; x++) {
        !           308:                name = argv[x];
        !           309:                if ((f = open(name, 0)) < 0) {
        !           310:                        error("rcp: %s: %s\n", name, sys_errlist[errno]);
        !           311:                        continue;
        !           312:                }
        !           313:                if (fstat(f, &stb) < 0)
        !           314:                        goto notreg;
        !           315:                switch (stb.st_mode&S_IFMT) {
        !           316: 
        !           317:                case S_IFREG:
        !           318:                        break;
        !           319: 
        !           320:                case S_IFDIR:
        !           321:                        if (iamrecursive) {
        !           322:                                (void) close(f);
        !           323:                                rsource(name, &stb);
        !           324:                                continue;
        !           325:                        }
        !           326:                        /* fall into ... */
        !           327:                default:
        !           328: notreg:
        !           329:                        (void) close(f);
        !           330:                        error("rcp: %s: not a plain file\n", name);
        !           331:                        continue;
        !           332:                }
        !           333:                last = rindex(name, '/');
        !           334:                if (last == 0)
        !           335:                        last = name;
        !           336:                else
        !           337:                        last++;
        !           338:                if (pflag) {
        !           339:                        /*
        !           340:                         * Make it compatible with possible future
        !           341:                         * versions expecting microseconds.
        !           342:                         */
        !           343:                        (void) sprintf(buf, "T%ld 0 %ld 0\n",
        !           344:                            stb.st_mtime, stb.st_atime);
        !           345:                        (void) write(rem, buf, strlen(buf));
        !           346:                        if (response() < 0) {
        !           347:                                (void) close(f);
        !           348:                                continue;
        !           349:                        }
        !           350:                }
        !           351:                (void) sprintf(buf, "C%04o %ld %s\n",
        !           352:                    stb.st_mode&07777, stb.st_size, last);
        !           353:                (void) write(rem, buf, strlen(buf));
        !           354:                if (response() < 0) {
        !           355:                        (void) close(f);
        !           356:                        continue;
        !           357:                }
        !           358:                if ((bp = allocbuf(&buffer, f, BUFSIZ)) < 0) {
        !           359:                        (void) close(f);
        !           360:                        continue;
        !           361:                }
        !           362:                sizerr = 0;
        !           363:                for (i = 0; i < stb.st_size; i += bp->cnt) {
        !           364:                        amt = bp->cnt;
        !           365:                        if (i + amt > stb.st_size)
        !           366:                                amt = stb.st_size - i;
        !           367:                        if (sizerr == 0 && read(f, bp->buf, amt) != amt)
        !           368:                                sizerr = 1;
        !           369:                        (void) write(rem, bp->buf, amt);
        !           370:                }
        !           371:                (void) close(f);
        !           372:                if (sizerr == 0)
        !           373:                        ga();
        !           374:                else
        !           375:                        error("rcp: %s: file changed size\n", name);
        !           376:                (void) response();
        !           377:        }
        !           378: }
        !           379: 
        !           380: #include <sys/dir.h>
        !           381: 
        !           382: rsource(name, statp)
        !           383:        char *name;
        !           384:        struct stat *statp;
        !           385: {
        !           386:        DIR *d = opendir(name);
        !           387:        char *last;
        !           388:        struct direct *dp;
        !           389:        char buf[BUFSIZ];
        !           390:        char *bufv[1];
        !           391: 
        !           392:        if (d == 0) {
        !           393:                error("rcp: %s: %s\n", name, sys_errlist[errno]);
        !           394:                return;
        !           395:        }
        !           396:        last = rindex(name, '/');
        !           397:        if (last == 0)
        !           398:                last = name;
        !           399:        else
        !           400:                last++;
        !           401:        if (pflag) {
        !           402:                (void) sprintf(buf, "T%ld 0 %ld 0\n",
        !           403:                    statp->st_mtime, statp->st_atime);
        !           404:                (void) write(rem, buf, strlen(buf));
        !           405:                if (response() < 0) {
        !           406:                        closedir(d);
        !           407:                        return;
        !           408:                }
        !           409:        }
        !           410:        (void) sprintf(buf, "D%04o %d %s\n", statp->st_mode&07777, 0, last);
        !           411:        (void) write(rem, buf, strlen(buf));
        !           412:        if (response() < 0) {
        !           413:                closedir(d);
        !           414:                return;
        !           415:        }
        !           416:        while (dp = readdir(d)) {
        !           417:                if (dp->d_ino == 0)
        !           418:                        continue;
        !           419:                if (!strcmp(dp->d_name, ".") || !strcmp(dp->d_name, ".."))
        !           420:                        continue;
        !           421:                if (strlen(name) + 1 + strlen(dp->d_name) >= BUFSIZ - 1) {
        !           422:                        error("%s/%s: Name too long.\n", name, dp->d_name);
        !           423:                        continue;
        !           424:                }
        !           425:                (void) sprintf(buf, "%s/%s", name, dp->d_name);
        !           426:                bufv[0] = buf;
        !           427:                source(1, bufv);
        !           428:        }
        !           429:        closedir(d);
        !           430:        (void) write(rem, "E\n", 2);
        !           431:        (void) response();
        !           432: }
        !           433: 
        !           434: response()
        !           435: {
        !           436:        char resp, c, rbuf[BUFSIZ], *cp = rbuf;
        !           437: 
        !           438:        if (read(rem, &resp, 1) != 1)
        !           439:                lostconn();
        !           440:        switch (resp) {
        !           441: 
        !           442:        case 0:                         /* ok */
        !           443:                return (0);
        !           444: 
        !           445:        default:
        !           446:                *cp++ = resp;
        !           447:                /* fall into... */
        !           448:        case 1:                         /* error, followed by err msg */
        !           449:        case 2:                         /* fatal error, "" */
        !           450:                do {
        !           451:                        if (read(rem, &c, 1) != 1)
        !           452:                                lostconn();
        !           453:                        *cp++ = c;
        !           454:                } while (cp < &rbuf[BUFSIZ] && c != '\n');
        !           455:                if (iamremote == 0)
        !           456:                        (void) write(2, rbuf, cp - rbuf);
        !           457:                errs++;
        !           458:                if (resp == 1)
        !           459:                        return (-1);
        !           460:                exit(1);
        !           461:        }
        !           462:        /*NOTREACHED*/
        !           463: }
        !           464: 
        !           465: lostconn()
        !           466: {
        !           467: 
        !           468:        if (iamremote == 0)
        !           469:                fprintf(stderr, "rcp: lost connection\n");
        !           470:        exit(1);
        !           471: }
        !           472: 
        !           473: sink(argc, argv)
        !           474:        int argc;
        !           475:        char **argv;
        !           476: {
        !           477:        off_t i, j;
        !           478:        char *targ, *whopp, *cp;
        !           479:        int of, mode, wrerr, exists, first, count, amt, size;
        !           480:        struct buffer *bp;
        !           481:        static struct buffer buffer;
        !           482:        struct stat stb;
        !           483:        int targisdir = 0;
        !           484:        int mask = umask(0);
        !           485:        char *myargv[1];
        !           486:        char cmdbuf[BUFSIZ], nambuf[BUFSIZ];
        !           487:        int setimes = 0;
        !           488:        struct timeval tv[2];
        !           489: #define atime  tv[0]
        !           490: #define mtime  tv[1]
        !           491: #define        SCREWUP(str)    { whopp = str; goto screwup; }
        !           492: 
        !           493:        if (!pflag)
        !           494:                (void) umask(mask);
        !           495:        if (argc != 1) {
        !           496:                error("rcp: ambiguous target\n");
        !           497:                exit(1);
        !           498:        }
        !           499:        targ = *argv;
        !           500:        if (targetshouldbedirectory)
        !           501:                verifydir(targ);
        !           502:        ga();
        !           503:        if (stat(targ, &stb) == 0 && (stb.st_mode & S_IFMT) == S_IFDIR)
        !           504:                targisdir = 1;
        !           505:        for (first = 1; ; first = 0) {
        !           506:                cp = cmdbuf;
        !           507:                if (read(rem, cp, 1) <= 0)
        !           508:                        return;
        !           509:                if (*cp++ == '\n')
        !           510:                        SCREWUP("unexpected '\\n'");
        !           511:                do {
        !           512:                        if (read(rem, cp, 1) != 1)
        !           513:                                SCREWUP("lost connection");
        !           514:                } while (*cp++ != '\n');
        !           515:                *cp = 0;
        !           516:                if (cmdbuf[0] == '\01' || cmdbuf[0] == '\02') {
        !           517:                        if (iamremote == 0)
        !           518:                                (void) write(2, cmdbuf+1, strlen(cmdbuf+1));
        !           519:                        if (cmdbuf[0] == '\02')
        !           520:                                exit(1);
        !           521:                        errs++;
        !           522:                        continue;
        !           523:                }
        !           524:                *--cp = 0;
        !           525:                cp = cmdbuf;
        !           526:                if (*cp == 'E') {
        !           527:                        ga();
        !           528:                        return;
        !           529:                }
        !           530: 
        !           531: #define getnum(t) (t) = 0; while (isdigit(*cp)) (t) = (t) * 10 + (*cp++ - '0');
        !           532:                if (*cp == 'T') {
        !           533:                        setimes++;
        !           534:                        cp++;
        !           535:                        getnum(mtime.tv_sec);
        !           536:                        if (*cp++ != ' ')
        !           537:                                SCREWUP("mtime.sec not delimited");
        !           538:                        getnum(mtime.tv_usec);
        !           539:                        if (*cp++ != ' ')
        !           540:                                SCREWUP("mtime.usec not delimited");
        !           541:                        getnum(atime.tv_sec);
        !           542:                        if (*cp++ != ' ')
        !           543:                                SCREWUP("atime.sec not delimited");
        !           544:                        getnum(atime.tv_usec);
        !           545:                        if (*cp++ != '\0')
        !           546:                                SCREWUP("atime.usec not delimited");
        !           547:                        ga();
        !           548:                        continue;
        !           549:                }
        !           550:                if (*cp != 'C' && *cp != 'D') {
        !           551:                        /*
        !           552:                         * Check for the case "rcp remote:foo\* local:bar".
        !           553:                         * In this case, the line "No match." can be returned
        !           554:                         * by the shell before the rcp command on the remote is
        !           555:                         * executed so the ^Aerror_message convention isn't
        !           556:                         * followed.
        !           557:                         */
        !           558:                        if (first) {
        !           559:                                error("%s\n", cp);
        !           560:                                exit(1);
        !           561:                        }
        !           562:                        SCREWUP("expected control record");
        !           563:                }
        !           564:                cp++;
        !           565:                mode = 0;
        !           566:                for (; cp < cmdbuf+5; cp++) {
        !           567:                        if (*cp < '0' || *cp > '7')
        !           568:                                SCREWUP("bad mode");
        !           569:                        mode = (mode << 3) | (*cp - '0');
        !           570:                }
        !           571:                if (*cp++ != ' ')
        !           572:                        SCREWUP("mode not delimited");
        !           573:                size = 0;
        !           574:                while (isdigit(*cp))
        !           575:                        size = size * 10 + (*cp++ - '0');
        !           576:                if (*cp++ != ' ')
        !           577:                        SCREWUP("size not delimited");
        !           578:                if (targisdir)
        !           579:                        (void) sprintf(nambuf, "%s%s%s", targ,
        !           580:                            *targ ? "/" : "", cp);
        !           581:                else
        !           582:                        (void) strcpy(nambuf, targ);
        !           583:                exists = stat(nambuf, &stb) == 0;
        !           584:                if (cmdbuf[0] == 'D') {
        !           585:                        if (exists) {
        !           586:                                if ((stb.st_mode&S_IFMT) != S_IFDIR) {
        !           587:                                        errno = ENOTDIR;
        !           588:                                        goto bad;
        !           589:                                }
        !           590:                                if (pflag)
        !           591:                                        (void) chmod(nambuf, mode);
        !           592:                        } else if (mkdir(nambuf, mode) < 0)
        !           593:                                goto bad;
        !           594:                        myargv[0] = nambuf;
        !           595:                        sink(1, myargv);
        !           596:                        if (setimes) {
        !           597:                                setimes = 0;
        !           598:                                if (utimes(nambuf, tv) < 0)
        !           599:                                        error("rcp: can't set times on %s: %s\n",
        !           600:                                            nambuf, sys_errlist[errno]);
        !           601:                        }
        !           602:                        continue;
        !           603:                }
        !           604:                if ((of = creat(nambuf, mode)) < 0) {
        !           605:        bad:
        !           606:                        error("rcp: %s: %s\n", nambuf, sys_errlist[errno]);
        !           607:                        continue;
        !           608:                }
        !           609:                if (exists && pflag)
        !           610:                        (void) fchmod(of, mode);
        !           611:                ga();
        !           612:                if ((bp = allocbuf(&buffer, of, BUFSIZ)) < 0) {
        !           613:                        (void) close(of);
        !           614:                        continue;
        !           615:                }
        !           616:                cp = bp->buf;
        !           617:                count = 0;
        !           618:                wrerr = 0;
        !           619:                for (i = 0; i < size; i += BUFSIZ) {
        !           620:                        amt = BUFSIZ;
        !           621:                        if (i + amt > size)
        !           622:                                amt = size - i;
        !           623:                        count += amt;
        !           624:                        do {
        !           625:                                j = read(rem, cp, amt);
        !           626:                                if (j <= 0) {
        !           627:                                        if (j == 0)
        !           628:                                            error("rcp: dropped connection");
        !           629:                                        else
        !           630:                                            error("rcp: %s\n",
        !           631:                                                sys_errlist[errno]);
        !           632:                                        exit(1);
        !           633:                                }
        !           634:                                amt -= j;
        !           635:                                cp += j;
        !           636:                        } while (amt > 0);
        !           637:                        if (count == bp->cnt) {
        !           638:                                if (wrerr == 0 &&
        !           639:                                    write(of, bp->buf, count) != count)
        !           640:                                        wrerr++;
        !           641:                                count = 0;
        !           642:                                cp = bp->buf;
        !           643:                        }
        !           644:                }
        !           645:                if (count != 0 && wrerr == 0 &&
        !           646:                    write(of, bp->buf, count) != count)
        !           647:                        wrerr++;
        !           648:                (void) close(of);
        !           649:                (void) response();
        !           650:                if (setimes) {
        !           651:                        setimes = 0;
        !           652:                        if (utimes(nambuf, tv) < 0)
        !           653:                                error("rcp: can't set times on %s: %s\n",
        !           654:                                    nambuf, sys_errlist[errno]);
        !           655:                }                                  
        !           656:                if (wrerr)
        !           657:                        error("rcp: %s: %s\n", nambuf, sys_errlist[errno]);
        !           658:                else
        !           659:                        ga();
        !           660:        }
        !           661: screwup:
        !           662:        error("rcp: protocol screwup: %s\n", whopp);
        !           663:        exit(1);
        !           664: }
        !           665: 
        !           666: struct buffer *
        !           667: allocbuf(bp, fd, blksize)
        !           668:        struct buffer *bp;
        !           669:        int fd, blksize;
        !           670: {
        !           671:        struct stat stb;
        !           672:        int size;
        !           673: 
        !           674:        if (fstat(fd, &stb) < 0) {
        !           675:                error("rcp: fstat: %s\n", sys_errlist[errno]);
        !           676:                return ((struct buffer *)-1);
        !           677:        }
        !           678:        size = roundup(stb.st_blksize, blksize);
        !           679:        if (size == 0)
        !           680:                size = blksize;
        !           681:        if (bp->cnt < size) {
        !           682:                if (bp->buf != 0)
        !           683:                        free(bp->buf);
        !           684:                bp->buf = (char *)malloc((unsigned) size);
        !           685:                if (bp->buf == 0) {
        !           686:                        error("rcp: malloc: out of memory\n");
        !           687:                        return ((struct buffer *)-1);
        !           688:                }
        !           689:        }
        !           690:        bp->cnt = size;
        !           691:        return (bp);
        !           692: }
        !           693: 
        !           694: /*VARARGS1*/
        !           695: error(fmt, a1, a2, a3, a4, a5)
        !           696:        char *fmt;
        !           697:        int a1, a2, a3, a4, a5;
        !           698: {
        !           699:        char buf[BUFSIZ], *cp = buf;
        !           700: 
        !           701:        errs++;
        !           702:        *cp++ = 1;
        !           703:        (void) sprintf(cp, fmt, a1, a2, a3, a4, a5);
        !           704:        (void) write(rem, buf, strlen(buf));
        !           705:        if (iamremote == 0)
        !           706:                (void) write(2, buf+1, strlen(buf+1));
        !           707: }

unix.superglobalmegacorp.com

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