Annotation of coherent/a/usr/bob/uusrc/src/uumkdir.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * uumkdir.c
        !             3:  *
        !             4:  * Makes directories for uucico to write in.
        !             5:  *
        !             6:  */
        !             7: 
        !             8: #include <sys/stat.h>
        !             9: #include <sys/dir.h>
        !            10: #include <sys/ino.h>
        !            11: #include <pwd.h>
        !            12: #include <signal.h>
        !            13: #include <errno.h>
        !            14: #include "dcp.h"
        !            15: 
        !            16: #ifndef NULL
        !            17: #define        NULL    ((char*) 0)
        !            18: #endif
        !            19: 
        !            20: #ifndef TRUE
        !            21: #define TRUE   (0 == 0)
        !            22: #endif
        !            23: 
        !            24: #define MAXDIR 32
        !            25: #define        equal(s1, s2)      (strcmp(s1, s2) == 0)
        !            26: 
        !            27: /*
        !            28:  * Masks by types of permissions.
        !            29:  */
        !            30: #define        AEXEC   (S_IEXEC|(S_IEXEC>>3)|(S_IEXEC>>6))
        !            31: #define        AREAD   (S_IREAD|(S_IREAD>>3)|(S_IREAD>>6))
        !            32: #define        AWRITE  (S_IWRITE|(S_IWRITE>>3)|(S_IWRITE>>6))
        !            33: #define        ASUID   (S_ISUID|S_ISGID)
        !            34: #define        ATEXT   S_ISVTX
        !            35: 
        !            36: /*
        !            37:  * Masks by types of users.
        !            38:  */
        !            39: #define        AOWN    (S_ISUID|S_ISVTX|S_IREAD|S_IWRITE|S_IEXEC)
        !            40: #define        AGRP    (S_ISGID|S_ISVTX|(S_IREAD>>3)|(S_IWRITE>>3)|(S_IEXEC>>3))
        !            41: #define        AOTH    (S_ISVTX|(S_IREAD>>6)|(S_IWRITE>>6)|(S_IEXEC>>6))
        !            42: #define        AALL    (AOWN|AGRP|AOTH)
        !            43: 
        !            44: typedef
        !            45: struct inpdir_s {
        !            46:        char    * dir;          /* dir string entered */
        !            47:        char    * start;        /* start of new dir in string */
        !            48:        char    * end;          /* end of dir string */
        !            49:        char    * p;            /* end of current parent string */
        !            50:        char    * c;            /* end of current child string */
        !            51: } inpdir_t;
        !            52: 
        !            53: char usage[] = "Usage: uumkdir [ -m mode ] [ -p ] dir ...\n";
        !            54: char badsm[] = "uumkdir: badly formed symbolic mode\n";
        !            55: char badom[] = "uumkdir: badly formed octal mode\n";
        !            56: 
        !            57: long   int     new;            /* bit-wise child dir condition */
        !            58: short  uid;                    /* user ID */
        !            59: int            interrupted;    /* interrupt flag */
        !            60: int            endflag;        /* end od dir string flag */
        !            61: int            pflag;          /* p option flag */
        !            62: int            mflag;          /* m option flag */
        !            63: int            mode = 0755;    /* initial mode setup for m option */
        !            64: 
        !            65: extern char    *malloc();
        !            66: extern char    *strcpy();
        !            67: extern char    *strncpy();
        !            68: extern char    *strcat();
        !            69: 
        !            70: /*
        !            71:  *     Interrupts are handled to prevent the formation of mangled directories.
        !            72:  */
        !            73: 
        !            74: main(argc, argv)
        !            75: int    argc;
        !            76: register char  ** argv;
        !            77: 
        !            78: {
        !            79:        register int    status = 0;     /* condition of mkdir:
        !            80:                                                0 - success, 1 - error */
        !            81:        inpdir_t        dirs;           /* structure with dir string info */
        !            82:        char          * end;            /* pointer to end of dir string */
        !            83: 
        !            84:        extern  void    fatal();
        !            85:        extern  int     catch();
        !            86:        extern  int     readmode();
        !            87:        extern  int     mkpath();
        !            88:        extern  int     error();
        !            89: 
        !            90:        if ( (setuid(0) < 0) || (setgid(0) < 0) )
        !            91:                fatal("uumkdir must be executed setuid root\n");
        !            92: 
        !            93:        catch(SIGINT);
        !            94:        catch(SIGHUP);
        !            95:        signal(SIGQUIT, SIG_IGN);
        !            96: 
        !            97:        while((--argc > 0) && ((*++argv)[0] == '-')) {
        !            98:                switch((*argv)[1]) {
        !            99:                case 'p':
        !           100:                        if (pflag)
        !           101:                                fatal(usage);
        !           102:                        pflag = TRUE;
        !           103:                        break;
        !           104:                case 'm':
        !           105:                        if (mflag || (--argc <= 0))
        !           106:                                fatal(usage);
        !           107:                        uid   = getuid();
        !           108:                        mflag = TRUE;
        !           109:                        mode  = readmode(*++argv, mode);
        !           110:                        break;
        !           111:                case 'v':
        !           112:                case 'V':
        !           113:                        fatal("uumkdir: Version %s", VERSION);
        !           114:                default:
        !           115:                        fatal(usage);
        !           116:                }
        !           117:        }
        !           118:        if (argc <= 0)
        !           119:                fatal(usage);
        !           120:        else {
        !           121:                for(; *argv ; ++argv) {
        !           122:                        if (dirs.dir)
        !           123:                                free(dirs.dir);
        !           124:                        for(end = *argv ; *end != '\0' ; ++end)
        !           125:                                ;
        !           126:                        do {
        !           127:                                if (end == *argv) {
        !           128:                                        error("bad argument (empty string)", 0);
        !           129:                                        exit(1);
        !           130:                                }
        !           131:                        } while(*--end == '/');
        !           132:                        *++end = '\0';
        !           133:                        if ((dirs.dir = malloc(end - *argv + 1)) == NULL) {
        !           134:                                error("out of memory ", 0);
        !           135:                                exit(1);
        !           136:                        }
        !           137:                        strcpy(dirs.dir, *argv);
        !           138:                        dirs.end = dirs.dir + (end - *argv);
        !           139:                        if (mkpath(&dirs) < 0)
        !           140:                                status = 1;  /* error */
        !           141:                        if (interrupted)
        !           142:                                exit(1);
        !           143:                }
        !           144:        }
        !           145:        exit(status);
        !           146: }
        !           147: 
        !           148: /**
        !           149:  * int
        !           150:  * mkpath(pdir)
        !           151:  * inpdir_t    * pdir;
        !           152:  *
        !           153:  *     Input:  pdir    - pointer to structure.
        !           154:  *
        !           155:  *     Action: Create new directory and all necessary directories
        !           156:  *             to new directory.
        !           157:  *
        !           158:  *     Return: 0 if all directory creations are successful, else -1.
        !           159:  *
        !           160:  *     Note:   All directories created before an error is
        !           161:  *             encountered are not removed from user's file.
        !           162:  */
        !           163: 
        !           164: int
        !           165: mkpath(pdir)
        !           166: inpdir_t       * pdir;
        !           167: {
        !           168:        register char   * childnam;     /* dir name of child */
        !           169:        register char   * child;        /* path name of child */
        !           170:        register char   * parent;       /* path name of parent */
        !           171:        register int    n;
        !           172:        int               err;          /* error response from dir creation */
        !           173:        int               numdir;       /* number of directories minus first
        !           174:                                           parent specified in full path name */
        !           175:        extern char *   getparent();
        !           176:        extern char *   getchild();
        !           177:        extern char *   getpath();
        !           178:        extern int      mkdir();
        !           179:        extern int      setmod();
        !           180:        extern int      error();
        !           181: 
        !           182:        numdir  = 0;
        !           183:        new     = 0L;
        !           184:        endflag = !TRUE;
        !           185: 
        !           186:        if ((child = malloc(pdir->end - pdir->dir + 1)) == NULL)
        !           187:                return(error("out of memory ", 0));
        !           188:        parent = getparent(pdir);
        !           189:        n = pdir->start - pdir->dir;
        !           190:        strncpy(child, pdir->dir, n);
        !           191:        child[n] = '\0';
        !           192:        do {
        !           193:                ++numdir;
        !           194:                if ((int)(childnam = getchild(pdir)) < 0) {
        !           195:                        error("can't get dir name ", pdir->dir, 0);
        !           196:                        break;
        !           197:                }
        !           198:                child = getpath(pdir, child);
        !           199:                if (pdir->c == pdir->end) {
        !           200:                        /* Last child declared cannot be "." or "..". */
        !           201:                        if (equal(childnam, ".") || equal(childnam, "..")) {
        !           202:                                error(pdir->dir," not allowed", 0);
        !           203:                                break;
        !           204:                        }
        !           205:                        /* Signal end of dir string. */
        !           206:                        endflag = TRUE;
        !           207:                        if (mkdir(parent, child) == -1)
        !           208:                                break;
        !           209:                        /* Signal new dir. */
        !           210:                        new = (new << 1) | 1L;
        !           211:                        numdir += MAXDIR;
        !           212:                } else {
        !           213:                        new = (new << 1) | 0L;
        !           214:                        if (!equal(childnam, ".") && !equal(childnam, "..")) {
        !           215:                                if ((err = mkdir(parent, child)) == -1)
        !           216:                                        break;
        !           217:                                else if (err == 0)
        !           218:                                        new |= 1L;
        !           219:                        }
        !           220:                }
        !           221:                /* Get next parent. */
        !           222:                parent = getpath(pdir, parent);
        !           223:                pdir->p = pdir->c;
        !           224:        } while(numdir <= MAXDIR);
        !           225:        /*  Set user-selected mode if available. */
        !           226:        if (mflag) {
        !           227:                if (setmod(parent, numdir, pdir->start, (pdir->p - 1)) < 0)
        !           228:                        return(-1);
        !           229:        }
        !           230:        if (numdir > MAXDIR)
        !           231:                return(0);
        !           232:        else
        !           233:                return(-1);
        !           234: }
        !           235: 
        !           236: /**
        !           237:  * int
        !           238:  * setmod(ch, ndir, start, p)
        !           239:  * char        * ch;
        !           240:  * char        * start;
        !           241:  * char        * p;
        !           242:  * int   ndir;
        !           243:  *
        !           244:  *     Input:  ch      - string holding all new dir names.
        !           245:  *             start   - start of new dir.
        !           246:  *             p       - end of new dir.
        !           247:  *             ndir    - number of directories tested.
        !           248:  *
        !           249:  *     Action: Set mode of all new directories created.
        !           250:  *
        !           251:  *     Return: 0 if all mode setups are successful, else -1.
        !           252:  *
        !           253:  *     Note:   None.
        !           254:  */
        !           255: 
        !           256: int
        !           257: setmod(ch, ndir, start, p)
        !           258: char   * ch;
        !           259: char   * start;
        !           260: char   * p;
        !           261: int      ndir;
        !           262: {
        !           263:        char    * c;    /* pointer to end of dir string */
        !           264:        /* Get pointer to end of string. */
        !           265:        for(c = ch ; *c != '\0' ; ++c)
        !           266:                ;
        !           267:        if (ndir > MAXDIR)
        !           268:                ndir -= (MAXDIR - 1);
        !           269:        /* Reset to mode desired. */
        !           270:        while(--ndir > 0) {
        !           271:                /* Change dir mode if new directory. */
        !           272:                if ((new & 01L) == 1L)
        !           273:                        if (chmod(ch, mode) < 0) {
        !           274:                                write(2, ch, (c - ch));
        !           275:                                write(2, ": ", 2);
        !           276:                                write(2, sys_errlist[ errno ],
        !           277:                                        strlen(sys_errlist[ errno ]));
        !           278:                                write(2, "\n", 1);
        !           279:                                return(-1);
        !           280:                        }
        !           281:                new = new >> 1;
        !           282:                /* Remove current dir name from string.  */
        !           283:                for(++p ; (--p >= start) && (*p != '/') ; *--c = '\0')
        !           284:                        ;
        !           285:                /* Remove trailing slashes. */
        !           286:                for(++p ; (--p >= start) && (*p == '/') ; *--c = '\0')
        !           287:                        ;
        !           288:        }
        !           289:        return(0);
        !           290: }
        !           291: 
        !           292: /**
        !           293:  * char *
        !           294:  * getparent(pdir)
        !           295:  * inpdir_t    * pdir;
        !           296:  *
        !           297:  *     Input:  pdir    - pointer to structure.
        !           298:  *
        !           299:  *     Action: Get parent to directory currently working on.
        !           300:  *
        !           301:  *     Return: Pointer to parent string.
        !           302:  *
        !           303:  *     Note:   None.
        !           304:  */
        !           305: 
        !           306: char *
        !           307: getparent(pdir)
        !           308: inpdir_t       * pdir;
        !           309: {
        !           310:        int     found;          /* 0: parent found, -1: parent not found */
        !           311:        int     size;           /* size of dir string in structure */
        !           312:        char  * par;            /* pointer to parent string */
        !           313:        char  * tail;           /* pointer to end of parent string */
        !           314:        extern int      error();
        !           315: 
        !           316:        size = pdir->end - pdir->dir;
        !           317:        if ((par = malloc(size + 3)) == NULL) {
        !           318:                error("out of memory ", 0);
        !           319:                exit(1);
        !           320:        }
        !           321:        /* Copy structure string to parent and set tail to end of
        !           322:         * parent string.
        !           323:         */
        !           324:        strcpy(par, pdir->dir);
        !           325:        tail = par + size;
        !           326:        /* Search for parent string. */
        !           327:        do {
        !           328:                /* Remove last dir name in string. */
        !           329:                for(; (--tail >= par) && (*tail != '/') ; *tail = '\0')
        !           330:                        ;
        !           331:                /* Remove trailing slashes. */
        !           332:                for(++tail ; (--tail > par) && (*tail == '/') ; *tail = '\0')
        !           333:                        ;
        !           334:                /** Substitute "." for null path. */
        !           335:                if (++tail == par) {
        !           336:                        *tail = '.';
        !           337:                        *(tail + 1) = '/';
        !           338:                }
        !           339:                if ((found = access(par, 03)) == -1)
        !           340:                        switch(errno) {
        !           341:                        case ENOENT:
        !           342:                                break;
        !           343:                        case EACCES:
        !           344:                                error("no permission to mkdir in ", par, 0);
        !           345:                                exit(1);
        !           346:                        default:
        !           347:                                error("can't make ", pdir->dir, 0);
        !           348:                                exit(1);
        !           349:                        }
        !           350:        } while((found == -1) && pflag);
        !           351:        /* Set start of first child and pointer to end of first parent. */
        !           352:        pdir->start = pdir->p = pdir->dir + (tail - par);
        !           353:        return(par);
        !           354: }
        !           355: 
        !           356: /**
        !           357:  * char *
        !           358:  * getchild(pdir)
        !           359:  * inpdir_t    * pdir;
        !           360:  *
        !           361:  *     Input:  pdir    - pointer to structure.
        !           362:  *
        !           363:  *     Action: Get current child dir name.
        !           364:  *
        !           365:  *     Return: Pointer to child dir name.
        !           366:  *
        !           367:  *     Note:   If dir name found exceeds DIRSIZ in length, it will be
        !           368:  *             truncated to DIRSIZ.
        !           369:  */
        !           370: 
        !           371: char *
        !           372: getchild(pdir)
        !           373: inpdir_t       * pdir;
        !           374: {
        !           375:        static char     nam[ DIRSIZ + 1 ];      /* dir name of child */
        !           376:        char          * c;                      /* pointer to end of child name */
        !           377:        int             i, j;                   /* working counters */
        !           378:        /* Increment to start of next dir name. */
        !           379:        for(i = 0, c = pdir->p ; (c < pdir->end) && (*c == '/') ; ++i, ++c)
        !           380:                ;
        !           381:        /* Increment to end of dir name. */
        !           382:        for(j = 0 ; (c < pdir->end) && (*c != '/') ; ++j, ++c)
        !           383:                ;
        !           384:        pdir->c = c;
        !           385:        /* Copy up to DIRSIZ length of child dir name to static memory. */
        !           386:        if (j > DIRSIZ)
        !           387:                j = DIRSIZ;
        !           388:        strncpy(nam, pdir->p + i, j);
        !           389:        nam[j] = '\0';
        !           390:        return(nam);
        !           391: }
        !           392: 
        !           393: /**
        !           394:  * char *
        !           395:  * getpath(pdir, dir)
        !           396:  * inpdir_t    * pdir;
        !           397:  * char                * dir;
        !           398:  *
        !           399:  *     Input:  pdir    - pointer to structure.
        !           400:  *             dir     - current path name.
        !           401:  *     Action: Get current path name of child.
        !           402:  *     Return: Pointer to current path name.
        !           403:  *     Note:   None.
        !           404:  */
        !           405: 
        !           406: char *
        !           407: getpath(pdir, dir)
        !           408: inpdir_t       * pdir;
        !           409: char           * dir;
        !           410: {
        !           411:        strncat(dir, pdir->p, (pdir->c - pdir->p));
        !           412:        return(strcat(dir, "\0"));
        !           413: }
        !           414: 
        !           415: /**
        !           416:  * int
        !           417:  * mkdir(parent, child)
        !           418:  * char        * parent;
        !           419:  * char        * child;
        !           420:  *
        !           421:  *     Input:  parent  - pointer to dir path name to parent.
        !           422:  *             child   - pointer to dir path name to child.
        !           423:  *     Action: Make a directory. If the parent exists and is writeable,
        !           424:  *             the directory and its "." and ".." links are created.
        !           425:  *     Return: 0 if successful, 1 if dir existed already and dir is
        !           426:  *             not the last dir in string. Else -1.
        !           427:  *     Note:   None.
        !           428:  */
        !           429: 
        !           430: int
        !           431: mkdir(parent, child)
        !           432: char   * parent;
        !           433: char   * child;
        !           434: {
        !           435:        extern  char   * concat();
        !           436:        extern  int     linkerr();
        !           437:        extern  int     error();
        !           438:        struct  passwd  *pw;
        !           439: 
        !           440:        /* Test if parent file is accessible by user. */
        !           441:        if (access(parent, 03))
        !           442:                switch(errno) {
        !           443:                case ENOENT:
        !           444:                        error("parent dir ", parent, " doesn't exist", 0);
        !           445:                        return(-1);
        !           446:                case EACCES:
        !           447:                        error("no permission to mkdir in ", parent, 0);
        !           448:                        return(-1);
        !           449:                default:
        !           450:                        return(error("can't make ", child, 0));
        !           451:                }
        !           452:        /* Creat new directory. */
        !           453:        if (mknod(child, IFDIR | 0777, 0)) {
        !           454:                switch(errno) {
        !           455:                case EEXIST:
        !           456:                        if (endflag)
        !           457:                                return(error(child, " already exists", 0));
        !           458:                        else
        !           459:                                return(1);
        !           460:                case EPERM:
        !           461:                        return(error("not the super-user", 0));
        !           462:                default:
        !           463:                        return(error("can't make ", child, 0));
        !           464:                }
        !           465:        }
        !           466:        if (link(child, concat(child, "/.")))
        !           467:                return(linkerr(child, "."));
        !           468:        if (link(parent, concat(child, "/..")))
        !           469:                return(linkerr(child, ".."));
        !           470:        /* Set ownership of directory to user.   */
        !           471:        if ((pw = getpwnam("uucp")) == NULL)
        !           472:                return -1;
        !           473:        if (chown(child, pw->pw_uid, pw->pw_gid) < 0)
        !           474:                return -1;
        !           475:        return(0);
        !           476: }
        !           477: 
        !           478: /**
        !           479:  * char *
        !           480:  * concat(s1, s2)
        !           481:  * char        * s1, * s2;
        !           482:  *     Input:  s1, s2  - strings to be concatenated.
        !           483:  *     Action: Join string s2 to string s1 to form a new string.
        !           484:  *     Return: Pointer to start of concatenation of `s1' and `s2'.
        !           485:  *     Note:   None.
        !           486:  */
        !           487: 
        !           488: char *
        !           489: concat(s1, s2)
        !           490: char   * s1;
        !           491: char   * s2;
        !           492: {
        !           493:        static char     * str;
        !           494:        if (str)
        !           495:                free(str);
        !           496:        /* Allocate memory space for concatenated string. */
        !           497:        if ((str = malloc(strlen(s1) + strlen(s2) + 1)) == NULL) {
        !           498:                error("out of memory", 0);
        !           499:                exit(1);
        !           500:        }
        !           501:        strcpy(str, s1);
        !           502:        return(strcat(str, s2));
        !           503: }
        !           504: 
        !           505: /**
        !           506:  * int
        !           507:  * linkerr(dir, name)
        !           508:  * char        * dir;
        !           509:  * char        * name;
        !           510:  *
        !           511:  *     input:  dir     - directory where linking failed.
        !           512:  *             name    - type of link failed, "." or "..".
        !           513:  *     Action: Recover from link failure. In the event that "." or ".."
        !           514:  *             cannot be created, remove all traces of the directory.
        !           515:  *     return: -1.
        !           516:  *     Note:   none.
        !           517:  */
        !           518: 
        !           519: int
        !           520: linkerr(dir, name)
        !           521: char   * dir;
        !           522: char   * name;
        !           523: {
        !           524:        extern char     * concat();
        !           525:        extern int        error();
        !           526: 
        !           527:        unlink(concat(dir, "/."));
        !           528:        unlink(concat(dir, "/.."));
        !           529:        unlink(dir);
        !           530:        return(error("link to '", name, "' failed", 0));
        !           531: }
        !           532: 
        !           533: /**
        !           534:  * int
        !           535:  * onintr()
        !           536:  *
        !           537:  *     Input:  None.
        !           538:  *     Action: Reset SIGINT and SIGHUP and set interrupt counter.
        !           539:  *     Return: Pointer to previous action on success, else -1.
        !           540:  *     Note:   None.
        !           541:  */
        !           542: 
        !           543: int
        !           544: onintr()
        !           545: {
        !           546:        signal(SIGINT, SIG_IGN);
        !           547:        signal(SIGHUP, SIG_IGN);
        !           548:        ++interrupted;
        !           549: }
        !           550: 
        !           551: /**
        !           552:  * int
        !           553:  * catch(sig)
        !           554:  * 
        !           555:  *     Input:  sig     - signal caught.
        !           556:  *     Action: Reset signals.
        !           557:  *     Return: Pointer to previous action on success, else -1.
        !           558:  *     Note:   None.
        !           559:  */
        !           560: 
        !           561: int
        !           562: catch(sig)
        !           563: {
        !           564:        extern int      onintr();
        !           565:        if (signal(sig, SIG_IGN) == SIG_DFL)
        !           566:                signal(sig, onintr);
        !           567: }
        !           568: 
        !           569: /**
        !           570:  * int
        !           571:  * error(arg1)
        !           572:  * char        * arg1;
        !           573:  *
        !           574:  *     Input:  arg1    - error message string.
        !           575:  *     Action: Display error message.
        !           576:  *     Return: -1.
        !           577:  *     Note:   None.
        !           578:  */
        !           579: 
        !           580: int
        !           581: error(arg1)
        !           582: char   * arg1;
        !           583: {
        !           584:        register char ** p;
        !           585:        write(2, "mkdir: ", 7);
        !           586:        for(p = &arg1 ; *p != 0 ; ++p)
        !           587:                write(2, *p, strlen(*p));
        !           588:        write(2, "\n", 1);
        !           589:        return(-1);
        !           590: }
        !           591: 
        !           592: /**
        !           593:  * int
        !           594:  * readmode(s, mode)
        !           595:  * char        * s;
        !           596:  * int   mode;
        !           597:  *     
        !           598:  *     Input:  s       - string containing setting changes.
        !           599:  *             mode    - current setting of permission.
        !           600:  *     Action: Read in the symbolic mode and set the variables `who', `op',
        !           601:  *             and `mode'. Knows about the old octal modes as well.
        !           602:  *     Return: New mode.
        !           603:  *     Note:   None.
        !           604:  */
        !           605: 
        !           606: int
        !           607: readmode(s, mode)
        !           608: register char * s;
        !           609: int    mode;
        !           610: {
        !           611:        register int    c;
        !           612:        register int    op;
        !           613:        register int    m1, m2;
        !           614:        extern void     fatal();
        !           615:        extern void     checkmode();
        !           616:        extern int      getumask();
        !           617:        extern int      mrepl();
        !           618: 
        !           619:        if ((*s >= '0') && (*s <= '7')) {
        !           620:                mode = 0;
        !           621:                while(*s != '\0') {
        !           622:                        if ((*s < '0') || (*s > '7'))
        !           623:                                fatal(badom);
        !           624:                        mode = (mode << 3) | (*s++)-'0';
        !           625:                }
        !           626:                checkmode(mode);
        !           627:                return(mode);
        !           628:        }
        !           629: newsym:
        !           630:        for(m1 = 0 ;;) {
        !           631:                switch(*s++) {
        !           632:                case 'u': m1 |= AOWN; continue;
        !           633:                case 'g': m1 |= AGRP; continue;
        !           634:                case 'o': m1 |= AOTH; continue;
        !           635:                case 'a': m1 |= AALL; continue;
        !           636:                default : s--; break;
        !           637:                }
        !           638:                break;
        !           639:        }
        !           640:        if (m1 == 0)
        !           641:                m1 = AALL & ~getumask();
        !           642: newop:
        !           643:        if (((c = *s++) == '=') || (c == '+') || (c == '-'))
        !           644:                op = c;
        !           645:        else
        !           646:                fatal(badsm);
        !           647:        for(m2 = 0 ;;) {
        !           648:                switch(*s++) {
        !           649:                case 'r': m2 |= AREAD;  continue;
        !           650:                case 'w': m2 |= AWRITE; continue;
        !           651:                case 'x': m2 |= AEXEC;  continue;
        !           652:                case 's': m2 |= ASUID;  continue;
        !           653:                case 't': m2 |= ATEXT;  continue;
        !           654:                case 'u': m2 |= mrepl(mode & AOWN);          continue;
        !           655:                case 'g': m2 |= mrepl((mode & AGRP) << 3); continue;
        !           656:                case 'o': m2 |= mrepl((mode & AOTH) << 6); continue;
        !           657:                default : s--; break;
        !           658:                }
        !           659:                break;
        !           660:        }
        !           661:        switch(op) {
        !           662:                case '-': mode &= ~(m1 & m2); break;
        !           663:                case '+': mode |= m1 & m2;    break;
        !           664:                case '=': mode  = (mode & ~m1) | (m1 & m2); break;
        !           665:        }
        !           666:        if (*s == '\0') {
        !           667:                checkmode(mode);
        !           668:                return(mode);
        !           669:        }
        !           670:        if ((*s == '+') || (*s == '-') || (*s == '='))
        !           671:                goto newop;
        !           672:        if (*s++ == ',')
        !           673:                goto newsym;
        !           674:        fatal(badsm);
        !           675: }
        !           676: 
        !           677: /**
        !           678:  * int
        !           679:  * getumask()
        !           680:  *
        !           681:  *     Input:  None.
        !           682:  *
        !           683:  *     Action: Get the value of the umask setting.
        !           684:  *
        !           685:  *     Return:         ????
        !           686:  *
        !           687:  *     Note:   None.
        !           688:  */
        !           689: 
        !           690: int
        !           691: getumask()
        !           692: 
        !           693: {
        !           694:        register int omask;
        !           695: 
        !           696:        omask = umask(0);
        !           697:        umask(omask);
        !           698:        return(omask);
        !           699: }
        !           700: 
        !           701: /**
        !           702:  * void
        !           703:  * checkmode(mode)
        !           704:  * int mode;
        !           705:  *
        !           706:  *     Input:  mode    - current setup of permission.
        !           707:  *     Action: Check the mode to see if any problem bits are on.
        !           708:  *             For now, this is S_ISVTX for non-super-users.
        !           709:  *     Return: None.
        !           710:  *     Note:   None.
        !           711:  */
        !           712: 
        !           713: void
        !           714: checkmode(mode)
        !           715: register int mode;
        !           716: {
        !           717:        static char stickwarn[] = 
        !           718:                "mkdir: Warning: non-super user may not set sticky bit\n";
        !           719:        if ((uid != 0) && (mode & S_ISVTX)) {
        !           720:                write(2, stickwarn, 54);
        !           721:                exit(1);
        !           722:        }
        !           723: }
        !           724: 
        !           725: /**
        !           726:  * int
        !           727:  * mrepl(m)
        !           728:  * int m;
        !           729:  *     Input:  m       - mode setting to be replicated.
        !           730:  *     Action: Replicate the 3-bits of the mode from the owner
        !           731:  *             position to all positions.
        !           732:  *     Return: Replicated mode setup.
        !           733:  *     Note:   None.
        !           734:  */
        !           735: 
        !           736: int
        !           737: mrepl(m)
        !           738: register int m;
        !           739: {
        !           740:        register int m1;
        !           741: 
        !           742:        m1 = m & AOWN;
        !           743:        m  = m1 | (m1 >> 3) | (m1 >> 6);
        !           744:        if (m1 & S_ISUID)
        !           745:                m |= S_ISGID;
        !           746:        return(m);
        !           747: }

unix.superglobalmegacorp.com

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