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

1.1       root        1: 
                      2: /*
                      3:  * rmdir -- remove directories
                      4:  */
                      5: #include       <sys/stat.h>
                      6: #include       <sys/dir.h>
                      7: #include       <signal.h>
                      8: #include       <stdio.h>
                      9: #include       <errno.h>
                     10: 
                     11: 
                     12: #define        equal( s1, s2)  (strcmp( s1, s2) == 0)
                     13: 
                     14: int            fflag,                  /* force flag */
                     15:                interrupted;
                     16: struct stat    dot;
                     17: 
                     18: char   *getparent(),
                     19:        *getchild(),
                     20:        *strncpy(),
                     21:        *strcat(),
                     22:        *strcpy(),
                     23:        *concat();
                     24: 
                     25: /*
                     26:  * main
                     27:  * Interrupts are handled to prevent the formation of mangled directories.
                     28:  */
                     29: main( argc, argv)
                     30: register char  **argv;
                     31: {
                     32:        register int status = 0;
                     33: 
                     34:        if (*++argv!= NULL && equal( *argv, "-f")) {
                     35:                if (getuid())
                     36:                        fatal("only superuser can force");
                     37:                ++fflag;
                     38:                ++argv;
                     39:        }
                     40:        if (stat( ".", &dot))
                     41:                fatal("can't find .");
                     42:        catch(SIGINT);
                     43:        catch(SIGHUP);
                     44:        signal(SIGQUIT, SIG_IGN);
                     45: 
                     46:        if (*argv == NULL) {
                     47:                fprintf(stderr, "Usage: rmdir [ -f ] dir ...\n");
                     48:                exit(1);
                     49:        }
                     50:        else
                     51:                while (*argv) {
                     52:                        if (rmdir(*argv++) < 0)
                     53:                                status = 1;  /* error */
                     54:                        if (interrupted)
                     55:                                exit(1);
                     56:                }
                     57:        exit(status);
                     58: }
                     59: 
                     60: 
                     61: /*
                     62:  * remove a directory
                     63:  * The directory and its "." and ".." entries are unlinked if everything
                     64:  * looks kosher.  The force option causes most checking to be suppressed
                     65:  * and unlinks only what is specifically named.  `rmdir' takes a dim view
                     66:  * to non-hierarchical directories.
                     67:  */
                     68: rmdir(dir)
                     69: register char  *dir;
                     70: {
                     71:        register char   *child;
                     72:        register FILE   *f;
                     73:        struct stat     s;
                     74:        struct direct   d;
                     75: 
                     76: 
                     77:        if ((int) (child = getchild( dir)) < 0) {
                     78:                error("can't get child dir name %s", dir);
                     79:                return(-1);
                     80:        }
                     81:        if (access( dir, 0) || stat( dir, &s)) {
                     82:                error("can't find %s", dir);
                     83:                return(-1);
                     84:        }
                     85:        if ((s.st_mode&S_IFMT) != S_IFDIR) {
                     86:                error("%s not a directory", dir);
                     87:                return(-1);
                     88:        }
                     89:        if (access( getparent( dir), 3)) {
                     90:                error("no permission to remove %s", dir);
                     91:                return(-1);
                     92:        }
                     93:        if (fflag == 0) {
                     94:                if (equal( child, ".") || equal( child, "..")) {
                     95:                        error("%s not allowed", dir);
                     96:                        return(-1);
                     97:                }
                     98:                if (s.st_ino==dot.st_ino && s.st_dev==dot.st_dev) {
                     99:                        error("but %s is your working directory", dir);
                    100:                        return(-1);
                    101:                }
                    102:                f = fopen( dir, "r");
                    103:                if (f==NULL || access( dir, 4)) {
                    104:                        error("can't read %s", dir);
                    105:                        return(-1);     
                    106:                }
                    107:                while (fread( &d, sizeof d, 1, f) == 1) {
                    108:                        if (d.d_ino == 0)
                    109:                                continue;
                    110:                        if (equal( d.d_name, ".") || equal( d.d_name, ".."))
                    111:                                continue;
                    112:                        error("%s not empty", dir);
                    113:                        return(-1);
                    114:                }
                    115:                fclose(f);
                    116: 
                    117:                if (s.st_nlink <= 2) {
                    118:                        unlink( concat( dir, "/."));
                    119:                        unlink( concat( dir, "/.."));
                    120:                }
                    121:        }
                    122: 
                    123:        if (unlink( dir)) {
                    124:                error("unlink %s failed", dir);
                    125:                return(-1);
                    126:        }
                    127:        return(0);
                    128: }
                    129: 
                    130: 
                    131: /*
                    132:  * return name of parent
                    133:  */
                    134: char   *
                    135: getparent( dir)
                    136: char   *dir;
                    137: {
                    138:        register        i;
                    139:        register char   *p;
                    140:        static char     *par;
                    141:        int             tmp;
                    142: 
                    143:        if (par)
                    144:                free( par);
                    145:        i = strlen( dir);
                    146:        par = malloc( i+1);
                    147:        if (par == NULL)
                    148:                nomemory( );
                    149:        strcpy( par, dir);
                    150: 
                    151:        for (p=par+i; p>par; )
                    152:                if (*--p != '/')
                    153:                        break;
                    154:        for (++p; *--p!='/'; )
                    155:                if (p == par) {
                    156:                        *p = '.';
                    157:                        break;
                    158:                }
                    159:        *++p = '\0';
                    160:        if (par[tmp = strlen(par)-1] == '/')
                    161:           par[tmp] = 0;  /* kill any ending slash */
                    162:        return (par);
                    163: }
                    164: 
                    165: 
                    166: /*
                    167:  * return rightmost component of pathname
                    168:  */
                    169: char   *
                    170: getchild( dir)
                    171: register char  *dir;
                    172: {
                    173:        register char   *p,
                    174:                        *q;
                    175:        int             i;
                    176:        static char     ch[DIRSIZ+1];
                    177: 
                    178:        p = &dir[strlen( dir)];
                    179:        do {
                    180:                if (p == dir) {
                    181:                        error("not permitted");
                    182:                        return(-1);
                    183:                }
                    184:        } while (*--p == '/');
                    185:        q = p;
                    186:        while (q > dir)
                    187:                if (*--q == '/') {
                    188:                        ++q;
                    189:                        break;
                    190:                }
                    191:        i = p+1 - q;
                    192:        if (i > DIRSIZ)
                    193:                i = DIRSIZ;
                    194:        return (strncpy( ch, q, i));
                    195: }
                    196: 
                    197: 
                    198: /*
                    199:  * return concatenation of `s1' and `s2'
                    200:  */
                    201: char   *
                    202: concat( s1, s2)
                    203: char   *s1,
                    204:        *s2;
                    205: {
                    206:        static char     *str;
                    207: 
                    208:        if (str)
                    209:                free( str);
                    210:        str = malloc( strlen( s1)+strlen( s2)+1);
                    211:        if (str == NULL)
                    212:                nomemory( );
                    213:        strcpy( str, s1);
                    214:        return (strcat( str, s2));
                    215: }
                    216: 
                    217: 
                    218: nomemory( )
                    219: {
                    220:        fatal("out of memory");
                    221: }
                    222: 
                    223: 
                    224: onintr( )
                    225: {
                    226: 
                    227:        signal( SIGINT, SIG_IGN);
                    228:        signal( SIGHUP, SIG_IGN);
                    229:        ++interrupted;
                    230: }
                    231: 
                    232: 
                    233: catch( sig)
                    234: {
                    235: 
                    236:        if( signal( sig, SIG_IGN) == SIG_DFL)
                    237:                signal( sig, onintr);
                    238: }
                    239: 
                    240: 
                    241: error(arg1)
                    242: char   *arg1;
                    243: {
                    244:        fprintf( stderr, "rmdir: %r\n", &arg1);
                    245: }
                    246: 
                    247: fatal(arg1)
                    248: char   *arg1;
                    249: {
                    250:        error(arg1);
                    251:        exit(1);
                    252: }

unix.superglobalmegacorp.com

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