Annotation of 43BSDReno/contrib/isode-beta/others/idist/idistd2.c, revision 1.1

1.1     ! root        1: /* idistd2.c -- the non remote operations parts of the protocol */
        !             2: 
        !             3: /*
        !             4:  * $Header: /f/osi/others/idist/RCS/idistd2.c,v 7.0 89/11/23 21:58:33 mrose Rel $
        !             5:  *
        !             6:  * Parts of the idist server which are not mixed up with remote
        !             7:  * operations but depend on the defined types.
        !             8:  *
        !             9:  * Julian Onions <[email protected]>
        !            10:  * Nottingham University Computer Science.
        !            11:  *
        !            12:  *
        !            13:  * $Log:       idistd2.c,v $
        !            14:  * Revision 7.0  89/11/23  21:58:33  mrose
        !            15:  * Release 6.0
        !            16:  * 
        !            17:  */
        !            18: 
        !            19: #ifndef lint
        !            20: static char *rcsid = "$Header: /f/osi/others/idist/RCS/idistd2.c,v 7.0 89/11/23 21:58:33 mrose Rel $";
        !            21: #endif
        !            22: 
        !            23: #include "defs.h"
        !            24: #include "Idist-types.h"
        !            25: 
        !            26: char   *tp, *stp[128];
        !            27: 
        !            28: extern int catname;
        !            29: extern char    target[];
        !            30: extern FILE    *cfile;
        !            31: extern struct type_Idist_FileSpec *cfiletype;
        !            32: extern int oumask;
        !            33: extern char    utmpfile[];
        !            34: extern char    *tmpname;
        !            35: extern struct type_Idist_IA5List *ia5list;
        !            36: 
        !            37: static char    *cannon ();
        !            38: static struct type_Idist_IA5List *str2ia5list ();
        !            39: static int compare ();
        !            40: extern struct type_Idist_FileSpec *makefs ();
        !            41: extern struct type_Idist_QueryResult *query ();
        !            42: extern struct type_Idist_FileList *do_listcdir ();
        !            43: 
        !            44: doexec (cmd)
        !            45: char   *cmd;
        !            46: {
        !            47:        int fd[2], status, pid, i;
        !            48:        char    buf[BUFSIZ];
        !            49: 
        !            50:        if (pipe(fd) < 0)
        !            51:                return NOTOK;
        !            52: 
        !            53:        if ((pid = vfork ()) == 0) {
        !            54:                /*
        !            55:                 * Return everything the shell commands print.
        !            56:                 */
        !            57:                (void) close(0);
        !            58:                (void) close(1);
        !            59:                (void) close(2);
        !            60:                (void) open("/dev/null", 0);
        !            61:                (void) dup(fd[1]);
        !            62:                (void) dup(fd[1]);
        !            63:                (void) close(fd[0]);
        !            64:                (void) close(fd[1]);
        !            65:                execl("/bin/sh", "sh", "-c", cmd, 0);
        !            66:                _exit(127);
        !            67:        }
        !            68:        if (pid == -1)
        !            69:                return NOTOK;
        !            70: 
        !            71:        (void) close(fd[1]);
        !            72: 
        !            73:        while ((i = read(fd[0], buf, sizeof(buf))) > 0) {
        !            74:                addtoia5 (buf, i);
        !            75:        }
        !            76: 
        !            77:        while ((i = wait(&status)) != pid && i != -1)
        !            78:                ;
        !            79:        if (i == -1)
        !            80:                status = -1;
        !            81:        (void) close(fd[0]);
        !            82: 
        !            83:        return OK;
        !            84: }
        !            85: 
        !            86: do_symlink (fs)
        !            87: struct type_Idist_FileSpec *fs;
        !            88: {
        !            89:        char    *new, old[BUFSIZ], *linkname;
        !            90:        int     i;
        !            91: 
        !            92:        new = qb2str (fs -> filename);
        !            93:        linkname = cannon (new);
        !            94:        free (new);
        !            95: 
        !            96:        new = qb2str (fs -> linkname);
        !            97:        (void) strcpy (old, new);
        !            98:        free (new);
        !            99: 
        !           100:        
        !           101:        if (symlink (old, linkname) < 0) {
        !           102:                if (errno != ENOENT || chkparent (linkname) < 0 ||
        !           103:                    symlink (old, linkname) < 0) {
        !           104:                        nadvise (linkname, "Can't symlink %s to", old);
        !           105:                        return NOTOK;
        !           106:                }
        !           107:        }
        !           108: 
        !           109:        if (bit_on (fs -> fileopts, bit_Idist_Options_compare)) {
        !           110:                char    tbuf[BUFSIZ];
        !           111: 
        !           112:                if ((i = readlink (target, tbuf, BUFSIZ)) >= 0 &&
        !           113:                    i == fs -> filesize &&
        !           114:                    strncmp (old, tbuf, fs -> filesize) == 0) {
        !           115:                        (void) unlink (linkname);
        !           116:                        return OK;
        !           117:                }
        !           118:                if (bit_on (fs -> fileopts, bit_Idist_Options_verify)) {
        !           119:                        (void) unlink (linkname);
        !           120:                        note ("need to update: %s", target);
        !           121:                        return OK;
        !           122:                }
        !           123:        }
        !           124: 
        !           125:        if (rename (linkname, target) < 0) {
        !           126:                nadvise (target, "can't rename %s to", linkname);
        !           127:                (void) unlink (linkname);
        !           128:                return NOTOK;
        !           129:        }
        !           130:        if (bit_on (fs -> fileopts, bit_Idist_Options_compare))
        !           131:                note ("updated %s\n", target);
        !           132:        return OK;
        !           133: }
        !           134: 
        !           135: static char    *cannon (name)
        !           136: char   *name;
        !           137: {
        !           138:        static char     nname[BUFSIZ];
        !           139:        char    *cp;
        !           140:        extern  char    *tmpname;
        !           141: 
        !           142:        if (catname)
        !           143:                (void) sprintf (tp, "/%s", name);
        !           144:        if((cp = rindex (target, '/')) == NULL)
        !           145:                (void) strcpy (nname, tmpname);
        !           146:        else if (cp == target)
        !           147:                (void) sprintf (nname, "/%s", tmpname);
        !           148:        else {
        !           149:                *cp = '\0';
        !           150:                (void) sprintf (nname, "%s/%s", target, tmpname);
        !           151:                *cp = '/';
        !           152:        }
        !           153:        return nname;
        !           154: }
        !           155: 
        !           156: /*
        !           157:  * Check to see if parent directory exists and create one if not.
        !           158:  */
        !           159: chkparent(name)
        !           160:        char *name;
        !           161: {
        !           162:        register char *cp;
        !           163:        struct stat stb;
        !           164: 
        !           165:        cp = rindex(name, '/');
        !           166:        if (cp == NULL || cp == name)
        !           167:                return(0);
        !           168:        *cp = '\0';
        !           169:        if (lstat(name, &stb) < 0) {
        !           170:                if (errno == ENOENT && chkparent(name) >= 0 &&
        !           171:                    mkdir(name, 0777 & ~oumask) >= 0) {
        !           172:                        *cp = '/';
        !           173:                        return(0);
        !           174:                }
        !           175:        } else if (ISDIR(stb.st_mode)) {
        !           176:                *cp = '/';
        !           177:                return(0);
        !           178:        }
        !           179:        *cp = '/';
        !           180:        return(-1);
        !           181: }
        !           182: 
        !           183: do_rfile (fs)
        !           184: struct type_Idist_FileSpec *fs;
        !           185: {
        !           186:        char    *name, *p;
        !           187: 
        !           188:        p = qb2str (fs -> filename);
        !           189:        name = cannon (p);
        !           190:        free (p);
        !           191: 
        !           192:        if ((cfile = fopen (name, "w")) == NULL) {
        !           193:                if (errno != ENOENT || chkparent (name) < 0 ||
        !           194:                    (cfile = fopen (name, "w")) == NULL) {
        !           195:                        nadvise (name, "Can't create file");
        !           196:                        return NOTOK;
        !           197:                }
        !           198:        }
        !           199:        (void) fchmod (fileno (cfile), fs -> filemode);
        !           200: 
        !           201:        return OK;
        !           202: }
        !           203: 
        !           204: do_hardlink (fs)
        !           205: struct type_Idist_FileSpec *fs;
        !           206: {
        !           207:        char    *new;
        !           208:        char    *cp;
        !           209:        char    old[BUFSIZ];
        !           210:        struct stat stb;
        !           211:        int     exists = 0;
        !           212: 
        !           213:        new = qb2str (fs -> filename);
        !           214:        cp = qb2str (fs -> linkname);
        !           215:        if (exptilde (old, cp) == NULL) {
        !           216:                free (cp);
        !           217:                free (new);
        !           218:                return NOTOK;
        !           219:        }
        !           220:        free (cp);
        !           221: 
        !           222:        if (catname)
        !           223:                (void) sprintf (tp, "/%s", new);
        !           224:        free (new);
        !           225: 
        !           226:        if (lstat(target, &stb) == 0) {
        !           227:                int mode = stb.st_mode & S_IFMT;
        !           228:                if (mode != S_IFREG && mode != S_IFLNK) {
        !           229:                        nadvise (NULLCP, "%s: not a regular file",
        !           230:                                 host, target);
        !           231:                        return NOTOK;
        !           232:                }
        !           233:                exists = 1;
        !           234:        }
        !           235:        if (chkparent(target) < 0 ) {
        !           236:                nadvise("chkparent", "%s (no parent)", target);
        !           237:                return NOTOK;
        !           238:        }
        !           239:        if (exists && (unlink(target) < 0)) {
        !           240:                nadvise ("unlink", "%s", target);
        !           241:                return NOTOK;
        !           242:        }
        !           243:        if (link(old, target) < 0) {
        !           244:                nadvise (old,  "can't link %s to", target);
        !           245:                return NOTOK;
        !           246:        }
        !           247:        return OK;
        !           248: }
        !           249: 
        !           250: do_direct (fs)
        !           251: struct type_Idist_FileSpec *fs;
        !           252: {
        !           253:        char    *cp, *name;
        !           254:        struct stat stb;
        !           255: 
        !           256:        cp = name = qb2str (fs -> filename);
        !           257: 
        !           258:        if (catname >= sizeof(stp)) {
        !           259:                nadvise (NULLCP, "Too many directory levels");
        !           260:                free (name);
        !           261:                return NOTOK;
        !           262:        }
        !           263: 
        !           264:        stp[catname] = tp;
        !           265:        if (catname++) {
        !           266:                *tp ++ = '/';
        !           267:                while (*tp++ = *cp ++)
        !           268:                        ;
        !           269:                tp --;
        !           270:        }
        !           271:        
        !           272:        if (bit_on (fs -> fileopts, bit_Idist_Options_verify)) {
        !           273:                free (name);
        !           274:                return OK;
        !           275:        }
        !           276: 
        !           277:        if (lstat (target, &stb) == 0) {
        !           278:                if ((stb.st_mode & S_IFMT) == S_IFDIR) {
        !           279:                        if ((stb.st_mode & 07777) == fs -> filemode) {
        !           280:                                free (name);
        !           281:                                return OK;
        !           282:                        }
        !           283:                        note ("%s remote node %o != local mode %o",
        !           284:                              target, stb.st_mode & 07777, fs -> filemode);
        !           285:                        free (name);
        !           286:                        return OK;
        !           287:                }
        !           288:                errno = ENOTDIR;
        !           289:        }
        !           290:        else if (errno == ENOENT && (mkdir (target, fs -> filemode) == 0 ||
        !           291:                                     chkparent (target) == 0 &&
        !           292:                                     mkdir (target, fs -> filemode) == 0)) {
        !           293:                char *owner = qb2str (fs -> fileowner);
        !           294:                char *group = qb2str (fs -> filegroup);
        !           295: 
        !           296:                if (chog (target, owner, group, fs -> filemode) == 0) {
        !           297:                        free (owner);
        !           298:                        free (group);
        !           299:                        free (name);
        !           300:                        return OK;
        !           301:                }
        !           302:                free (owner);
        !           303:                free (group);
        !           304:        }
        !           305:        free (name);
        !           306:        nadvise (target, "Can't install directory");
        !           307:        tp = stp[--catname];
        !           308:        *tp = '\0';
        !           309:        return NOTOK;
        !           310: }
        !           311: 
        !           312: /*
        !           313:  * Remove a file or directory (recursively) and send back an acknowledge
        !           314:  * or an error message.
        !           315:  */
        !           316: remove(str)
        !           317: char   *str;
        !           318: {
        !           319:        DIR *d;
        !           320:        struct direct *dp;
        !           321:        struct stat stb;
        !           322:        char    buf[BUFSIZ];
        !           323:        int     result = OK;
        !           324: 
        !           325:        if (lstat (str, &stb) < 0) {
        !           326:                nadvise (str, "Can't stat file");
        !           327:                return NOTOK;
        !           328:        }
        !           329:        
        !           330:        switch (stb.st_mode & S_IFMT) {
        !           331:        case S_IFREG:
        !           332:        case S_IFLNK:
        !           333:                if (unlink(str) < 0) {
        !           334:                        nadvise (str, "Can't unlink");
        !           335:                        return NOTOK;
        !           336:                }
        !           337:                note ("removed: %s", str);
        !           338:                return OK;
        !           339: 
        !           340:        case S_IFDIR:
        !           341:                break;
        !           342: 
        !           343:        default:
        !           344:                nadvise (NULLCP, "%s: not a plain file", target);
        !           345:                return NOTOK;
        !           346:        }
        !           347: 
        !           348:        if ((d = opendir(str)) == NULL) {
        !           349:                nadvise (str, "Can't open directory");
        !           350:                return NOTOK;
        !           351:        }
        !           352: 
        !           353:        while (dp = readdir(d)) {
        !           354:                if (strcmp(dp->d_name, ".") == 0 ||
        !           355:                    strcmp(dp->d_name, "..") == 0)
        !           356:                        continue;
        !           357:                (void) sprintf (buf, "%s/%s", str, dp -> d_name);
        !           358:                result = remove(buf) == OK ? result : NOTOK;
        !           359:        }
        !           360:        closedir(d);
        !           361:        if (rmdir(str) < 0) {
        !           362:                nadvise (str, "Can't remove directory", str);
        !           363:                return NOTOK;
        !           364:        }
        !           365:        note ("removed: %s", str);
        !           366:        return result;
        !           367: }
        !           368: 
        !           369: 
        !           370: addtoia5 (str, len)
        !           371: char   *str;
        !           372: int    len;
        !           373: {
        !           374:        struct type_Idist_IA5List **ia5p;
        !           375: 
        !           376:        for (ia5p = &ia5list; *ia5p; ia5p = &(*ia5p) -> next)
        !           377:                continue;
        !           378: 
        !           379:        *ia5p = str2ia5list (str, len);
        !           380: }
        !           381: 
        !           382: struct type_Idist_QueryResult *query (str)
        !           383: char   *str;
        !           384: {
        !           385:        struct type_Idist_QueryResult *qr;
        !           386:        struct stat stb;
        !           387: 
        !           388:        qr = (struct type_Idist_QueryResult *) malloc (sizeof *qr);
        !           389:        if (qr == NULL)
        !           390:                adios ("memory", "out of");
        !           391:        
        !           392:        if (catname)
        !           393:                (void) sprintf (tp, "/%s", str);
        !           394: 
        !           395:        if (lstat (target, &stb) < 0) {
        !           396:                if (errno == ENOENT) {
        !           397:                        qr -> offset = type_Idist_QueryResult_doesntExist;
        !           398:                }
        !           399:                else {
        !           400:                        nadvise ("failed", "lstat");
        !           401:                        free (( char *) qr);
        !           402:                        qr = NULL;
        !           403:                }
        !           404:                *tp = '\0';
        !           405:                return qr;
        !           406:        }
        !           407:        qr -> offset = type_Idist_QueryResult_doesExist;
        !           408:        switch (stb.st_mode & S_IFMT) {
        !           409:            case S_IFREG:
        !           410:            case S_IFDIR:
        !           411:            case S_IFLNK:
        !           412:                qr -> un.doesExist = makefs (stb.st_mode & S_IFMT, 0,
        !           413:                                             stb.st_mode & 07777, stb.st_size,
        !           414:                                             stb.st_mtime, "", "", str, "");
        !           415:                break;
        !           416: 
        !           417:            default:
        !           418:                nadvise (NULLCP, "%s: not a file or directory", str);
        !           419:                free ((char *)qr);
        !           420:                qr = NULL;
        !           421:        }
        !           422:        *tp = '\0';
        !           423:        return qr;
        !           424: }
        !           425: 
        !           426: static struct type_Idist_IA5List *str2ia5list (s, len)
        !           427: char   *s;
        !           428: int    len;
        !           429: {
        !           430:        register struct type_Idist_IA5List *ia5;
        !           431: 
        !           432:        if ((ia5 = (struct type_Idist_IA5List  *) calloc (1, sizeof *ia5))
        !           433:            == NULL)
        !           434:                return NULL;
        !           435: 
        !           436:        if ((ia5 -> IA5String = str2qb (s, len, 1)) == NULL) {
        !           437:                free ((char *) ia5);
        !           438:                return NULL;
        !           439:        }
        !           440: 
        !           441:        return ia5;
        !           442: }
        !           443: 
        !           444: struct type_Idist_FileList *do_listcdir ()
        !           445: {
        !           446:        DIR     *d;
        !           447:        register struct direct *dp;
        !           448:        struct type_Idist_FileList *base, **flp;
        !           449:        char    buf[BUFSIZ];
        !           450:        struct stat stb;
        !           451: 
        !           452:        base = NULL;
        !           453:        flp = &base;
        !           454:        
        !           455:        if ((d = opendir (target)) == NULL) {
        !           456:                nadvise (target, "Can't open directory");
        !           457:                return NULL;
        !           458:        }
        !           459: 
        !           460:        while (dp = readdir (d)) {
        !           461:                if (strcmp (dp -> d_name, ".") == 0 ||
        !           462:                    strcmp (dp -> d_name, "..") == 0)
        !           463:                        continue;
        !           464:                (void) sprintf (buf, "%s/%s", target, dp -> d_name);
        !           465:                if (lstat (buf, &stb) < 0) {
        !           466:                        nadvise (buf, "Can't stat");
        !           467:                        continue;
        !           468:                }
        !           469:                switch (stb.st_mode & S_IFMT) {
        !           470:                    case S_IFDIR:
        !           471:                    case S_IFLNK:
        !           472:                    case S_IFREG:
        !           473:                        break;
        !           474:                    default:    /* skip sockets, fifos et al... */
        !           475:                        continue;
        !           476:                }
        !           477:                if ((*flp = (struct type_Idist_FileList *)
        !           478:                     malloc (sizeof **flp)) == NULL)
        !           479:                        adios ("memory", "out of");
        !           480: 
        !           481:                (*flp) -> FileSpec = makefs (stb.st_mode & S_IFMT, 0,
        !           482:                                             stb.st_mode & 07777, stb.st_size,
        !           483:                                             stb.st_mtime, "", "",
        !           484:                                             dp->d_name, "");
        !           485:                (*flp) -> next = NULL;
        !           486:                flp = &(*flp) -> next;
        !           487:        }
        !           488:        closedir (d);
        !           489:        return base;
        !           490: }
        !           491: 
        !           492: fixup ()
        !           493: {
        !           494:        struct timeval tvp[2];
        !           495:        char    *new, *p;
        !           496:        char    *owner, *group;
        !           497:        long    convtime ();
        !           498: 
        !           499:        p = qb2str (cfiletype -> filename);
        !           500:        new = cannon (p);
        !           501:        free (p);
        !           502:        
        !           503:        if (bit_on (cfiletype -> fileopts, bit_Idist_Options_compare)) {
        !           504:                if (compare (target, new) == OK) {
        !           505:                        (void) unlink (new);
        !           506:                        return OK;
        !           507:                }
        !           508:                if (bit_on (cfiletype -> fileopts, bit_Idist_Options_verify)) {
        !           509:                        (void) unlink (new);
        !           510:                        note ("need to update: %s", target);
        !           511:                        return OK;
        !           512:                }
        !           513:        }
        !           514: 
        !           515:        tvp[1].tv_sec =
        !           516:                tvp[0].tv_sec =
        !           517:                        convtime (cfiletype -> filemtime);
        !           518:        tvp[0].tv_usec = tvp[1].tv_usec = 0;
        !           519:        if (utimes (new, tvp) < 0)
        !           520:                nadvise (new, "utimes failed on");
        !           521: 
        !           522:        owner = qb2str (cfiletype -> fileowner);
        !           523:        group = qb2str (cfiletype -> filegroup);
        !           524: 
        !           525:        if (chog (new, owner, group, cfiletype -> filemode) < 0) {
        !           526:                free (owner);
        !           527:                free (group);
        !           528:                (void) unlink (new);
        !           529:                return NOTOK;
        !           530:        }
        !           531:        free (owner);
        !           532:        free (group);
        !           533:        
        !           534:        if (rename (new, target) < 0) {
        !           535:                nadvise (target, "Can't rename %s to", new);
        !           536:                return NOTOK;
        !           537:        }
        !           538:        if (bit_on (cfiletype -> fileopts, bit_Idist_Options_compare))
        !           539:                note ("updated %s", target);
        !           540:        free_Idist_FileSpec (cfiletype);
        !           541:        cfiletype = NULL;
        !           542:        return OK;
        !           543: }
        !           544: 
        !           545: static int     compare (f1, f2)
        !           546: char   *f1, *f2;
        !           547: {
        !           548:        FILE    *fp1, *fp2;
        !           549:        char    buf1[BUFSIZ], buf2[BUFSIZ];     /* these two had
        !           550:                                                   better be identical */
        !           551:        int     n1, n2;
        !           552: 
        !           553:        if ((fp1 = fopen (f1, "r")) == NULL) {
        !           554:                nadvise (f1, "Can't reopen file");
        !           555:                return NOTOK;
        !           556:        }
        !           557:        if ((fp2 = fopen (f2, "r")) == NULL) {
        !           558:                nadvise (f2, "Can't reopend file");
        !           559:                (void) fclose (fp1);
        !           560:                return NOTOK;
        !           561:        }
        !           562:        for (;;) {
        !           563:                n1 = fread (buf1, sizeof buf1[0], sizeof buf1, fp1);
        !           564:                n2 = fread (buf2, sizeof buf2[0], sizeof buf2, fp2);
        !           565:                if (n1 != n2 || n1 == 0)
        !           566:                        break;
        !           567:                if (bcmp (buf1, buf2, n1) != 0)
        !           568:                        break;
        !           569:        }
        !           570: 
        !           571:        (void) fclose (fp1);
        !           572:        (void) fclose (fp2);
        !           573:        return n1 == 0 ? OK : NOTOK;
        !           574: }
        !           575: 
        !           576: 
        !           577: /*
        !           578:  * Change owner, group and mode of file.
        !           579:  */
        !           580: chog(file, owner, group, mode)
        !           581:        char *file, *owner, *group;
        !           582:        int mode;
        !           583: {
        !           584:        register int i;
        !           585:        int uid, gid;
        !           586:        extern char user[];
        !           587:        extern int userid;
        !           588: 
        !           589:        uid = userid;
        !           590:        if (userid == 0) {
        !           591:                if (*owner == ':') {
        !           592:                        uid = atoi(owner + 1);
        !           593:                } else if (pw == NULL || strcmp(owner, pw->pw_name) != 0) {
        !           594:                        if ((pw = getpwnam(owner)) == NULL) {
        !           595:                                if (mode & 04000) {
        !           596:                                        note("%s: unknown login name, clearing setuid",
        !           597:                                                host, owner);
        !           598:                                        mode &= ~04000;
        !           599:                                        uid = 0;
        !           600:                                }
        !           601:                        } else
        !           602:                                uid = pw->pw_uid;
        !           603:                } else
        !           604:                        uid = pw->pw_uid;
        !           605:                if (*group == ':') {
        !           606:                        gid = atoi(group + 1);
        !           607:                        goto ok;
        !           608:                }
        !           609:        } else if ((mode & 04000) && strcmp(user, owner) != 0)
        !           610:                mode &= ~04000;
        !           611:        gid = -1;
        !           612:        if (gr == NULL || strcmp(group, gr->gr_name) != 0) {
        !           613:                if ((*group == ':' && (getgrgid(gid = atoi(group + 1)) == NULL))
        !           614:                   || ((gr = getgrnam(group)) == NULL)) {
        !           615:                        if (mode & 02000) {
        !           616:                                note("%s: unknown group", group);
        !           617:                                mode &= ~02000;
        !           618:                        }
        !           619:                } else
        !           620:                        gid = gr->gr_gid;
        !           621:        } else
        !           622:                gid = gr->gr_gid;
        !           623:        if (userid && gid >= 0) {
        !           624:                if (gr) for (i = 0; gr->gr_mem[i] != NULL; i++)
        !           625:                        if (!(strcmp(user, gr->gr_mem[i])))
        !           626:                                goto ok;
        !           627:                mode &= ~02000;
        !           628:                gid = -1;
        !           629:        }
        !           630: ok:
        !           631:        if (userid == 0 && chown(file, uid, gid) < 0 )
        !           632:                nadvise (file, "chown failed on");
        !           633:        if ((mode & 06000) && chmod(file, mode) < 0) {
        !           634:                nadvise (file, "chmod to 0%o failed on", mode);
        !           635:        }
        !           636:        return(0);
        !           637: }
        !           638: 
        !           639: cleanup ()
        !           640: {
        !           641:        char    *p, *temp;
        !           642: 
        !           643:        if (cfiletype) {
        !           644:                p = qb2str (cfiletype -> filename);
        !           645:                temp = cannon (p);
        !           646:                (void) unlink (temp);
        !           647:        }
        !           648: }

unix.superglobalmegacorp.com

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