Annotation of coherent/a/usr/bob/uusrc/src/uumkdir.c, revision 1.1.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.