Annotation of coherent/d/bin/mkdir.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * mkdir.c
                      3:  * 5/10/90
                      4:  * Usage: mkdir [ -rp ] dir ...
                      5:  * Make directories.
                      6:  *
                      7:  * Changes by michael 5/10/93
                      8:  *      implemented -p option
                      9:  *
                     10:  * Changes by steve 5/10/90:
                     11:  *     in getchild(), bumped strncpy count by 1 to return NUL-terminated result
                     12:  *     in getparent(), hacked bogus "ending slash" code so that e.g.
                     13:  *             getparent("/foo") returns "/" rather than ""
                     14:  *
                     15:  * Changes by steve 4/12/90:
                     16:  *     corrected fatal() call
                     17:  *     added success return status to mkdir()
                     18:  *     improved return status of getchild()
                     19:  *     implemented -r option
                     20:  */
                     21: 
                     22: #include       <sys/dir.h>
                     23: #include       <sys/ino.h>
                     24: #include       <signal.h>
                     25: #include       <stdio.h>
                     26: #include       <errno.h>
                     27: 
                     28: 
                     29: #define        equal(s1, s2)   (strcmp(s1, s2) == 0)
                     30: 
                     31: int    interrupted;
                     32: int    rflag;
                     33: 
                     34: char   *getparent(),
                     35:        *getchild(),
                     36:        *concat(),
                     37:        *malloc(),
                     38:        *strcat(),
                     39:        *strcpy(),
                     40:        *strncpy();
                     41: 
                     42: /*
                     43:  * main
                     44:  * Interrupts are handled to prevent the formation of mangled directories.
                     45:  */
                     46: main(argc, argv)
                     47: register char  **argv;
                     48: {
                     49:        register int status = 0;
                     50: 
                     51:        catch(SIGINT);
                     52:        catch(SIGHUP);
                     53:        signal(SIGQUIT, SIG_IGN);
                     54: 
                     55:        if (argc > 1 && argv[1][0] == '-' &&
                     56:                        (argv[1][1] == 'r' || argv[1][1] == 'p')) {
                     57:                ++rflag;
                     58:                --argc;
                     59:                ++argv;
                     60:        }
                     61:        if (*++argv == NULL) {
                     62:                fprintf(stderr, "Usage: mkdir [-rp] dir ...\n");
                     63:                exit(1);
                     64:        } else
                     65:                while (*argv) {
                     66:                        if (mkdir(*argv++) < 0)
                     67:                                status = 1;             /* error */
                     68:                        if (interrupted)
                     69:                                exit(1);
                     70:                }
                     71:        exit(status);
                     72: }
                     73: 
                     74: /*
                     75:  * Make a directory.
                     76:  * If the parent exists and is writeable, the directory and its "." and
                     77:  * ".." links are created.
                     78:  */
                     79: int
                     80: mkdir(dir)
                     81: register char  *dir;
                     82: {
                     83:        register char   *parent,
                     84:                        *child;
                     85: 
                     86:        if ((child = getchild(dir)) == NULL) {
                     87:                error("cannot get child name %s", dir);
                     88:                return -1;
                     89:        } else if (equal(child, ".") || equal(child, "..")) {
                     90:                error("%s not allowed", dir);
                     91:                return -1;
                     92:        }
                     93:        if ((parent = getparent(dir)) == NULL)
                     94:                return -1;
                     95:        if (access(parent, 03)) {
                     96:                if (rflag && errno == ENOENT) {
                     97:                        /* Make parent recursively. */
                     98:                        if (mkdir(parent) != 0) {
                     99:                                free(parent);
                    100:                                return -1;
                    101:                        }
                    102:                } else {
                    103:                        switch (errno) {
                    104:                        case ENOENT:
                    105:                                error("parent directory %s does not exist", parent);
                    106:                                break;
                    107:                        case EACCES:
                    108:                                error("no permission to mkdir in %s", parent);
                    109:                                break;
                    110:                        default:
                    111:                                noway(dir);
                    112:                                break;
                    113:                        }
                    114:                        free(parent);
                    115:                        return -1;
                    116:                }
                    117:        }
                    118:        if (mknod(dir, IFDIR|0777, 0)) {
                    119:                switch (errno) {
                    120:                case EEXIST:
                    121:                        error("%s already exists", dir);
                    122:                        break;
                    123:                case EPERM:
                    124:                        error("not the super-user");
                    125:                        break;
                    126:                default:
                    127:                        noway(dir);
                    128:                        break;
                    129:                }
                    130:                free(parent);
                    131:                return -1;
                    132:        } else if (link(dir, concat(dir, "/."))) {
                    133:                linkerr(dir, ".");
                    134:                free(parent);
                    135:                return -1;
                    136:        } else if (link(parent, concat(dir, "/.."))) {
                    137:                linkerr(dir, "..");
                    138:                free(parent);
                    139:                return -1;
                    140:        }
                    141:        free(parent);
                    142:        return (chown(dir, getuid(), getgid()) < 0) ? -1 : 0;
                    143: }
                    144: 
                    145: 
                    146: /*
                    147:  * Return name of parent in an allocated buffer.
                    148:  */
                    149: char   *
                    150: getparent(dir)
                    151: char   *dir;
                    152: {
                    153:        register        i;
                    154:        register char   *p;
                    155:        char            *par;
                    156:        int             tmp;
                    157: 
                    158:        i = strlen(dir);
                    159:        par = malloc(i+1);
                    160:        if (par == NULL) {
                    161:                nomemory();
                    162:                return NULL;
                    163:        }
                    164:        strcpy(par, dir);
                    165: 
                    166:        for (p=par+i; p>par; )
                    167:                if (*--p != '/')
                    168:                        break;
                    169:        for (++p; *--p!='/'; )
                    170:                if (p == par) {
                    171:                        *p = '.';
                    172:                        break;
                    173:                }
                    174:        *++p = 0;
                    175:        tmp = strlen(par) - 1;
                    176:        if (tmp > 0 && par[tmp] == '/')
                    177:                par[tmp] = 0;                   /* kill any ending slash */
                    178:        return par;
                    179: }
                    180: 
                    181: /*
                    182:  * Return rightmost component of pathname
                    183:  * in a statically allocated buffer.
                    184:  */
                    185: char   *
                    186: getchild(dir)
                    187: register char  *dir;
                    188: {
                    189:        register char   *p,
                    190:                        *q;
                    191:        int             i;
                    192:        static char     ch[DIRSIZ+1];
                    193: 
                    194:        p = &dir[strlen(dir)];
                    195:        do {
                    196:                if (p == dir)
                    197:                        fatal("illegal directory name");
                    198:        } while (*--p == '/');
                    199:        q = p;
                    200:        while (q > dir)
                    201:                if (*--q == '/') {
                    202:                        ++q;
                    203:                        break;
                    204:                }
                    205:        i = p+1 - q;
                    206:        if (i > DIRSIZ)
                    207:                i = DIRSIZ;
                    208:        return strncpy(ch, q, i+1);
                    209: }
                    210: 
                    211: 
                    212: /*
                    213:  * Return concatenation of 's1' and 's2' in a malloc'ed buffer.
                    214:  * Free the previous buffer.
                    215:  */
                    216: char   *
                    217: concat(s1, s2)
                    218: char   *s1,
                    219:        *s2;
                    220: {
                    221:        static char     *str;
                    222: 
                    223:        if (str)
                    224:                free(str);
                    225:        str = malloc(strlen(s1)+strlen(s2)+1);
                    226:        if (str == NULL) {
                    227:                nomemory();
                    228:                return -1;
                    229:        }
                    230:        strcpy(str, s1);
                    231:        return strcat(str, s2);
                    232: }
                    233: 
                    234: 
                    235: /*
                    236:  * Recover from link failure.
                    237:  * In the event that "." or ".." cannot be created, remove all traces
                    238:  * of the directory.
                    239:  */
                    240: linkerr(dir, name)
                    241: char   *dir,
                    242:        *name;
                    243: {
                    244:        unlink(concat(dir, "/."));
                    245:        unlink(concat(dir, "/.."));
                    246:        unlink(dir);
                    247:        error("link to %s failed", name);
                    248:        return -1;
                    249: }
                    250: 
                    251: 
                    252: nomemory()
                    253: {
                    254:        error("out of memory");
                    255:        return -1;
                    256: }
                    257: 
                    258: 
                    259: noway(dir)
                    260: char   *dir;
                    261: {
                    262:        error("cannot make %s", dir);
                    263:        return -1;
                    264: }
                    265: 
                    266: 
                    267: onintr()
                    268: {
                    269:        signal(SIGINT, SIG_IGN);
                    270:        signal(SIGHUP, SIG_IGN);
                    271:        ++interrupted;
                    272: }
                    273: 
                    274: 
                    275: catch(sig)
                    276: {
                    277:        if (signal(sig, SIG_IGN) == SIG_DFL)
                    278:                signal(sig, onintr);
                    279: }
                    280: 
                    281: error(arg1)
                    282: char   *arg1;
                    283: {
                    284:        fprintf(stderr, "mkdir: %r\n", &arg1);
                    285: }
                    286: 
                    287: fatal(arg1)
                    288: char   *arg1;
                    289: {
                    290:        error(arg1);
                    291:        exit(1);
                    292: }
                    293: 
                    294: /* end of mkdir.c */

unix.superglobalmegacorp.com

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