Annotation of 43BSDReno/contrib/isode-beta/others/idist/install.c, revision 1.1.1.1

1.1       root        1: /* install.c - installation of files on remote host */
                      2: 
                      3: /*
                      4:  * $Header: /f/osi/others/idist/RCS/install.c,v 7.0 89/11/23 21:58:34 mrose Rel $
                      5:  *
                      6:  * Installation of files on remote host - the routines here drive the
                      7:  * protocol for installation, comparision and deletion etc. The
                      8:  * protocol is basically similar to the original rdist, except it is
                      9:  * fully client/server in this model with the daemon only responding
                     10:  * to requests. In the old version, the two sides occasionally swapped
                     11:  * around for some operations. Parts of this file were originally in
                     12:  * the file server.c.
                     13:  *
                     14:  * Julian Onions <[email protected]>
                     15:  * Nottingham University Computer Science
                     16:  * 
                     17:  *
                     18:  * $Log:       install.c,v $
                     19:  * Revision 7.0  89/11/23  21:58:34  mrose
                     20:  * Release 6.0
                     21:  * 
                     22:  */
                     23: 
                     24: /*
                     25:  * Copyright (c) 1983 Regents of the University of California.
                     26:  * All rights reserved.  The Berkeley software License Agreement
                     27:  * specifies the terms and conditions for redistribution.
                     28:  */
                     29: 
                     30: #ifndef lint
                     31: static char sccsid[] = "@(#)server.c   5.3 (Berkeley) 6/7/86";
                     32: static char rcsid[] = "$Header: /f/osi/others/idist/RCS/install.c,v 7.0 89/11/23 21:58:34 mrose Rel $";
                     33: #endif
                     34: 
                     35: #include "defs.h"
                     36: #include <sys/file.h>
                     37: 
                     38: struct linkbuf *ihead;         /* list of files with more than one link */
                     39: char   target[BUFSIZ];         /* target/source directory name */
                     40: char   basename[BUFSIZ];       /* base of directory operations */
                     41: char   *tp;                    /* pointer to end of target name */
                     42: char   *Tdest;                 /* pointer to last T dest*/
                     43: int    catname;                /* cat name to target name */
                     44: char   *stp[128];              /* stack of saved tp's for directories */
                     45: int    oumask;                 /* old umask for creating files */
                     46: char   tranbuf[1024*8];        /* 8K at a time... */
                     47: 
                     48: extern FILE *lfp;              /* log file for mailing changes */
                     49: 
                     50: int    cleanup();
                     51: struct linkbuf *savelink();
                     52: extern char *getstring ();
                     53: 
                     54: /*
                     55:  * Update the file(s) if they are different.
                     56:  * destdir = 1 if destination should be a directory
                     57:  * (i.e., more than one source is being copied to the same destination).
                     58:  */
                     59: install(src, dest, destdir, opts)
                     60:        char *src, *dest;
                     61:        int destdir, opts;
                     62: {
                     63:        char *rname;
                     64:        char destcopy[BUFSIZ];
                     65: 
                     66:        if (dest == NULL) {
                     67:                opts &= ~WHOLE; /* WHOLE mode only useful if renaming */
                     68:                dest = src;
                     69:        }
                     70: 
                     71:        if (nflag || debug) {
                     72:                printf("%s%s%s%s%s%s %s %s\n",
                     73:                       opts & VERIFY ? "verify":"install",
                     74:                       opts & WHOLE ? " -w" : "",
                     75:                       opts & YOUNGER ? " -y" : "",
                     76:                       opts & COMPARE ? " -b" : "",
                     77:                       opts & REMOVE ? " -R" : "",
                     78:                       opts & QUERYM ? " -Q" : "", src, dest);
                     79:                if (nflag)
                     80:                        return;
                     81:        }
                     82: 
                     83:        rname = exptilde(target, src);
                     84:        if (rname == NULL)
                     85:                return;
                     86:        tp = target;
                     87:        (void) strcpy (basename, target);
                     88:        while (*tp)
                     89:                tp++;
                     90:        /*
                     91:         * If we are renaming a directory and we want to preserve
                     92:         * the directory heirarchy (-w), we must strip off the leading
                     93:         * directory name and preserve the rest.
                     94:         */
                     95:        if (opts & WHOLE) {
                     96:                rname = target;
                     97:                while (*rname == '/')
                     98:                        rname++;
                     99:                destdir = 1;
                    100:        } else {
                    101:                rname = rindex(target, '/');
                    102:                if (rname == NULL)
                    103:                        rname = target;
                    104:                else
                    105:                        rname++;
                    106:        }
                    107:        if (debug)
                    108:                printf("target = %s, rname = %s\n", target, rname);
                    109:        /*
                    110:         * Pass the destination file/directory name to remote.
                    111:         */
                    112:        if (initdir (destdir, dest) < 0)
                    113:                return;
                    114: 
                    115:        (void) strcpy(destcopy, dest);
                    116:        Tdest = destcopy;
                    117: 
                    118:        sendf(rname, opts);
                    119:        Tdest = 0;
                    120: }
                    121: 
                    122: #define protoname() (pw ? pw->pw_name : user)
                    123: #define protogroup() (gr ? gr->gr_name : group)
                    124: /*
                    125:  * Transfer the file or directory in target[].
                    126:  * rname is the name of the file on the remote host.
                    127:  */
                    128: sendf(rname, opts)
                    129:        char *rname;
                    130:        int opts;
                    131: {
                    132:        register struct subcmd *sc;
                    133:        struct stat stb;
                    134:        int sizerr, f, u, len;
                    135:        off_t i;
                    136:        DIR *d;
                    137:        struct direct *dp;
                    138:        char *otp, *cp;
                    139:        extern struct subcmd *subcmds;
                    140:        char    buf[BUFSIZ];
                    141:        static char uname[15], group[15];
                    142: 
                    143:        if (debug)
                    144:                printf("sendf(%s, %x)\n", rname, opts);
                    145: 
                    146:        if (except(target))
                    147:                return;
                    148:        if ((opts & FOLLOW ? stat(target, &stb) : lstat(target, &stb)) < 0) {
                    149:                advise (target, "Can't stat");
                    150:                return;
                    151:        }
                    152:        if ((u = update(rname, opts, &stb)) == 0) {
                    153:                if ((stb.st_mode & S_IFMT) == S_IFREG && stb.st_nlink > 1)
                    154:                        (void) savelink(&stb, opts);
                    155:                return;
                    156:        }
                    157: 
                    158:        if (pw == NULL || pw->pw_uid != stb.st_uid)
                    159:                if ((pw = getpwuid(stb.st_uid)) == NULL) {
                    160:                        log(lfp, "%s: no password entry for uid \n", target);
                    161:                        pw = NULL;
                    162:                        (void) sprintf(uname, ":%d", stb.st_uid);
                    163:                }
                    164:        if (gr == NULL || gr->gr_gid != stb.st_gid)
                    165:                if ((gr = getgrgid(stb.st_gid)) == NULL) {
                    166:                        log(lfp, "%s: no name for group %d\n", target);
                    167:                        gr = NULL;
                    168:                        (void) sprintf(group, ":%d", stb.st_gid);
                    169:                }
                    170:        if (u == 1) {
                    171: #ifdef UW
                    172:                if (opts & NOINSTALL) {
                    173:                        log(lfp, "does not exist, did not install: %s\n", target);
                    174:                        goto dospecial;
                    175:                }
                    176: #endif UW
                    177:                if (opts & VERIFY) {
                    178:                        log(lfp, "need to install: %s\n", target);
                    179:                        goto dospecial;
                    180:                }
                    181:                log(lfp, "installing: %s\n", target);
                    182:                opts &= ~(COMPARE|REMOVE);
                    183:        }
                    184: 
                    185:        switch (stb.st_mode & S_IFMT) {
                    186:        case S_IFDIR:
                    187:                if ((d = opendir(target)) == NULL) {
                    188:                        advise (target, "Can't open directory");
                    189:                        return;
                    190:                }
                    191:                if (transfer (stb.st_mode & S_IFMT, opts,
                    192:                              stb.st_mode & 07777, (off_t)0, (time_t)0,
                    193:                              protoname (), protogroup (),
                    194:                              rname, "") < 0) {
                    195:                        closedir (d);
                    196:                        return;
                    197:                }
                    198: 
                    199:                if (opts & REMOVE)
                    200:                        (void) rmchk(opts);
                    201: 
                    202:                otp = tp;
                    203:                len = tp - target;
                    204:                while (dp = readdir(d)) {
                    205:                        if (!strcmp(dp->d_name, ".") ||
                    206:                            !strcmp(dp->d_name, ".."))
                    207:                                continue;
                    208:                        if (len + 1 + strlen(dp->d_name) >= BUFSIZ - 1) {
                    209:                                advise (NULLCP, "%s/%s name too long",
                    210:                                        target, dp->d_name);
                    211:                                continue;
                    212:                        }
                    213:                        tp = otp;
                    214:                        *tp++ = '/';
                    215:                        cp = dp->d_name;
                    216:                        while (*tp++ = *cp++)
                    217:                                ;
                    218:                        tp--;
                    219:                        sendf(dp->d_name, opts);
                    220:                }
                    221:                closedir(d);
                    222:                (void) terminate (S_IFDIR, OK);
                    223:                tp = otp;
                    224:                *tp = '\0';
                    225:                return;
                    226: 
                    227:        case S_IFLNK:
                    228:                if (u != 1)
                    229:                        opts |= COMPARE;
                    230:                if (stb.st_nlink > 1) {
                    231:                        struct linkbuf *lp;
                    232: 
                    233:                        if ((lp = savelink(&stb, opts)) != NULL) {
                    234:                                if (*lp -> target == 0)
                    235:                                        (void) strcpy (buf, lp -> pathname);
                    236:                                else    (void) sprintf (buf, "%s/%s",
                    237:                                                        lp -> target,
                    238:                                                        lp -> pathname);
                    239:                                (void) transfer ((unsigned short)0, opts,
                    240:                                                 (unsigned short)0, (off_t)0,
                    241:                                                 (time_t)0, "", "",
                    242:                                                 rname, buf);
                    243:                                return;
                    244:                        }
                    245:                }
                    246:                sizerr = (readlink(target, buf, BUFSIZ) != stb.st_size);
                    247:                if (debug)
                    248:                        printf("readlink = %.*s\n", stb.st_size, buf);
                    249:                if (transfer (stb.st_mode & S_IFMT, opts, stb.st_mode & 07777,
                    250:                              stb.st_size, stb.st_mtime,
                    251:                              protoname (), protogroup (), rname,
                    252:                              buf) < 0)
                    253:                        return;
                    254:                goto done;
                    255: 
                    256:        case S_IFREG:
                    257:                break;
                    258: 
                    259:        default:
                    260:                advise (NULLCP, "%s: not a file or directory", target);
                    261:                return;
                    262:        }
                    263: 
                    264:        if (u == 2) {
                    265:                if (opts & VERIFY) {
                    266:                        log(lfp, "need to update: %s\n", target);
                    267:                        goto dospecial;
                    268:                }
                    269:                log(lfp, "updating: %s\n", target);
                    270:        }
                    271: 
                    272:        if (stb.st_nlink > 1) {
                    273:                struct linkbuf *lp;
                    274: 
                    275:                if ((lp = savelink(&stb, opts)) != NULL) {
                    276:                        if (*lp -> target == 0)
                    277:                                (void) strcpy (buf, lp -> pathname);
                    278:                        else    (void) sprintf (buf, "%s/%s",
                    279:                                                lp -> target,
                    280:                                                lp -> pathname);
                    281:                        (void) transfer ((unsigned short)0, opts,
                    282:                                         (unsigned short)0, (off_t)0,
                    283:                                         (time_t)0, "", "",
                    284:                                         rname, buf);
                    285:                        return;
                    286:                }
                    287:        }
                    288: 
                    289:        if ((f = open(target, O_RDONLY, 0)) < 0) {
                    290:                advise (target, "Can't open file");
                    291:                return;
                    292:        }
                    293:        if ( transfer ((unsigned short)S_IFREG, opts, stb.st_mode & 07777,
                    294:                       stb.st_size,
                    295:                       stb.st_mtime, protoname (), protogroup (),
                    296:                       rname, "") < 0) {
                    297:                (void) close (f);
                    298:                return;
                    299:        }
                    300:        sizerr = 0;
                    301:        for (i = 0; i < stb.st_size; i += sizeof tranbuf) {
                    302:                int amt = sizeof tranbuf;
                    303:                if (i + amt > stb.st_size)
                    304:                        amt = stb.st_size - i;
                    305:                if (sizerr == 0 && read(f, tranbuf, amt) != amt)
                    306:                        sizerr = 1;
                    307:                if (tran_data (tranbuf, amt) == NOTOK)
                    308:                        break;
                    309:        }
                    310:        (void) close(f);
                    311:        if (sizerr) {
                    312:                advise (NULLCP, "%s: file changed size", target);
                    313:                if (terminate (S_IFREG, NOTOK) < 0)
                    314:                        return;
                    315:        } else {
                    316:                if (terminate (S_IFREG, OK) < 0)
                    317:                        return;
                    318:        }
                    319: done:
                    320:        if (opts & COMPARE)
                    321:                return;
                    322: dospecial:
                    323:        for (sc = subcmds; sc != NULL; sc = sc->sc_next) {
                    324:                if (sc->sc_type != SPECIAL)
                    325:                        continue;
                    326: #ifdef UW
                    327:                if (opts & NOINSTALL)  /* don't do specials associated with
                    328:                                          non-installation notices */
                    329:                        continue;
                    330: #endif UW
                    331:                if (sc->sc_args != NULL && !inlist(sc->sc_args, target))
                    332:                        continue;
                    333:                log(lfp, "special \"%s\"\n", sc->sc_name);
                    334:                if (opts & VERIFY)
                    335:                        continue;
                    336:                (void) sprintf(buf, "FILE=%s;export FILE;%s",
                    337:                               target, sc->sc_name);
                    338:                (void) runspecial (buf);
                    339:                
                    340:        }
                    341: }
                    342: 
                    343: struct linkbuf *
                    344: savelink(sp, opts)
                    345: struct stat *sp;
                    346: int    opts;
                    347: {
                    348:        struct linkbuf *lp;
                    349:        extern  char *makestr ();
                    350: 
                    351:        for (lp = ihead; lp != NULL; lp = lp->nextp)
                    352:                if (lp->inum == sp->st_ino && lp->devnum == sp->st_dev) {
                    353:                        lp->count--;
                    354:                        return(lp);
                    355:                }
                    356:        lp = (struct linkbuf *) malloc(sizeof(*lp));
                    357:        if (lp == NULL)
                    358:                log(lfp, "out of memory, link information lost\n");
                    359:        else {
                    360:                lp->nextp = ihead;
                    361:                ihead = lp;
                    362:                lp->inum = sp->st_ino;
                    363:                lp->devnum = sp->st_dev;
                    364:                lp->count = sp->st_nlink - 1;
                    365:                if (opts & WHOLE)
                    366:                        lp->pathname = makestr (target);
                    367:                else {
                    368:                        if (strncmp (target, basename, strlen(basename)) == 0)
                    369:                                lp -> pathname = makestr (target +
                    370:                                                          strlen(basename) + 1);
                    371:                        else
                    372:                                lp -> pathname = makestr (target);
                    373:                }
                    374:                                
                    375:                if (Tdest)
                    376:                        lp->target = makestr (Tdest);
                    377:                else
                    378:                        *lp->target = 0;
                    379:        }
                    380:        return(NULL);
                    381: }
                    382: 
                    383: update(rname, opts, sp)
                    384:        char *rname;
                    385:        int opts;
                    386:        struct stat *sp;
                    387: {
                    388:        off_t size;
                    389:        time_t mtime;
                    390:        unsigned short mode;
                    391:        int     retval;
                    392: 
                    393:        if (debug) 
                    394:                printf("update(%s, %x, %x)\n", rname, opts, sp);
                    395: 
                    396:        /*
                    397:         * Check to see if the file exists on the remote machine.
                    398:         */
                    399:        switch (retval = rquery (rname, &mtime, &size, &mode)) {
                    400:            case DONE:  /* file doesn't exist so install it */
                    401:                if ((opts & QUERYM) && !query ("Install",
                    402:                                               (sp ->st_mode & S_IFMT),
                    403:                                               NULLCP))
                    404:                        return 0;
                    405:                return(1);
                    406: 
                    407:            case NOTOK: /* something went wrong! */
                    408:                nerrs++;
                    409:                return(0);
                    410: 
                    411:            case OK:
                    412:                break;
                    413: 
                    414:            default:
                    415:                advise (NULLCP, "update: unexpected response %d", retval);
                    416:                return(0);
                    417:        }
                    418: 
                    419:        if (mode == S_IFDIR)
                    420:                return (2);
                    421: 
                    422:        if (opts & COMPARE) {
                    423:                if ((opts & QUERYM) && !query ("Compare and update", mode, NULLCP))
                    424:                        return 0;
                    425:                return(3);
                    426:        }
                    427: 
                    428:        /*
                    429:         * File needs to be updated?
                    430:         */
                    431:        if (opts & YOUNGER) {
                    432:                if (sp->st_mtime == mtime)
                    433:                        return(0);
                    434:                if (sp->st_mtime < mtime) {
                    435:                        log(lfp, "Warning: %s: remote copy is newer\n", target);
                    436:                        return(0);
                    437:                }
                    438:        } else if (sp->st_mtime == mtime && sp->st_size == size)
                    439:                return(0);
                    440:        if ((opts & QUERYM) && !query ("Update",
                    441:                                       sp -> st_mode & S_IFMT, NULLCP))
                    442:                return 0;
                    443:        return(2);
                    444: }
                    445: 
                    446: 
                    447: 
                    448: /*VARARGS2*/
                    449: log(fp, fmt, a1, a2, a3)
                    450:        FILE *fp;
                    451:        char *fmt;
                    452:        int a1, a2, a3;
                    453: {
                    454:        /* Print changes locally if not quiet mode */
                    455:        if (!qflag)
                    456:                printf(fmt, a1, a2, a3);
                    457: 
                    458:        /* Save changes (for mailing) if really updating files */
                    459:        if (!(options & VERIFY) && fp != NULL)
                    460:                fprintf(fp, fmt, a1, a2, a3);
                    461: }
                    462: 
                    463: /*
                    464:  * Remove temporary files and do any cleanup operations before exiting.
                    465:  */
                    466: cleanup()
                    467: {
                    468:        (void) unlink(utmpfile);
                    469:        exit(1);
                    470: }
                    471: 
                    472: query (mess, mode, name)
                    473: int    mode;
                    474: char   *mess, *name;
                    475: {
                    476:        char    buf[BUFSIZ];
                    477:        char    *cp;
                    478: 
                    479:        switch (mode) {
                    480:            case S_IFDIR:
                    481:                cp = "directory";
                    482:                break;
                    483:            case 0:
                    484:            case S_IFREG:
                    485:                cp = "file";
                    486:                break;
                    487:            case S_IFLNK:
                    488:                cp = "symbolic link";
                    489:                break;
                    490:            default:
                    491:                cp = "unknown file type";
                    492:                break;
                    493:        }
                    494: 
                    495:        (void) sprintf (buf, "%s %s %s? ", mess, cp,
                    496:                        name == NULLCP ? target : name);
                    497:        for (;;) {
                    498:                cp = getstring (buf);
                    499:                if (cp == NULLCP)
                    500:                        continue;
                    501:                if (*cp == 'y' || *cp == 'Y' || *cp == 'n' || *cp == 'N')
                    502:                        break;
                    503:        }
                    504:        
                    505:        if (*cp == 'y' || *cp == 'Y')
                    506:                return 1;
                    507:        return 0;
                    508: }

unix.superglobalmegacorp.com

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