Annotation of coherent/d/bin/rmdir.c, revision 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.