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

unix.superglobalmegacorp.com

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