Annotation of 43BSD/bin/rm.c, revision 1.1

1.1     ! root        1: static char *sccsid = "@(#)rm.c        4.18 (Berkeley) 1/6/86";
        !             2: 
        !             3: /*
        !             4:  * rm - for ReMoving files, directories & trees.
        !             5:  */
        !             6: 
        !             7: #include <stdio.h>
        !             8: #include <sys/param.h>
        !             9: #include <sys/stat.h>
        !            10: #include <sys/dir.h>
        !            11: #include <sys/file.h>
        !            12: 
        !            13: int    fflg;           /* -f force - supress error messages */
        !            14: int    iflg;           /* -i interrogate user on each file */
        !            15: int    rflg;           /* -r recurse */
        !            16: 
        !            17: int    errcode;        /* true if errors occured */
        !            18: 
        !            19: char   *strcpy(), *malloc(), *realloc();
        !            20: 
        !            21: main(argc, argv)
        !            22:        char *argv[];
        !            23: {
        !            24:        register char *arg;
        !            25: 
        !            26:        fflg = !isatty(0);
        !            27:        iflg = 0;
        !            28:        rflg = 0;
        !            29:        while (argc > 1 && argv[1][0] == '-') {
        !            30:                arg = *++argv;
        !            31:                argc--;
        !            32: 
        !            33:                /*
        !            34:                 *  all files following a null option are considered file names
        !            35:                 */
        !            36:                if (arg[1] == '\0')
        !            37:                        break;
        !            38: 
        !            39:                while (*++arg != '\0')
        !            40:                        switch(*arg) {
        !            41:                        case 'f':
        !            42:                                fflg++;
        !            43:                                break;
        !            44: 
        !            45:                        case 'i':
        !            46:                                iflg++;
        !            47:                                break;
        !            48: 
        !            49:                        case 'R':
        !            50:                        case 'r':
        !            51:                                rflg++;
        !            52:                                break;
        !            53: 
        !            54:                        default:
        !            55:                                fprintf(stderr, "usage: rm [-rif] file ...\n");
        !            56:                                exit(1);
        !            57:                        }
        !            58:        }
        !            59: 
        !            60:        if (argc < 2 && !fflg) {
        !            61:                fprintf(stderr, "usage: rm [-rif] file ...\n");
        !            62:                exit(1);
        !            63:        }
        !            64: 
        !            65:        while (--argc > 0)
        !            66:                (void) rm(*++argv, 0);
        !            67: 
        !            68:        exit(errcode != 0);
        !            69: }
        !            70: 
        !            71: char   *path;          /* pointer to malloc'ed buffer for path */
        !            72: char   *pathp;         /* current pointer to end of path */
        !            73: int    pathsz;         /* size of path */
        !            74: 
        !            75: /*
        !            76:  * Return TRUE if sucessful. Recursive with -r (rflg)
        !            77:  */
        !            78: rm(arg, level)
        !            79:        char arg[];
        !            80: {
        !            81:        int ok;                         /* true if recursive rm succeeded */
        !            82:        struct stat buf;                /* for finding out what a file is */
        !            83:        struct direct *dp;              /* for reading a directory */
        !            84:        DIR *dirp;                      /* for reading a directory */
        !            85:        char prevname[MAXNAMLEN + 1];   /* previous name for -r */
        !            86:        char *cp;
        !            87: 
        !            88:        if (dotname(arg)) {
        !            89:                fprintf(stderr, "rm: cannot remove `.' or `..'\n");
        !            90:                return (0);
        !            91:        }
        !            92:        if (lstat(arg, &buf)) {
        !            93:                if (!fflg) {
        !            94:                        fprintf(stderr, "rm: %s nonexistent\n", arg);
        !            95:                        errcode++;
        !            96:                }
        !            97:                return (0);             /* error */
        !            98:        }
        !            99:        if ((buf.st_mode&S_IFMT) == S_IFDIR) {
        !           100:                if (!rflg) {
        !           101:                        if (!fflg) {
        !           102:                                fprintf(stderr, "rm: %s directory\n", arg);
        !           103:                                errcode++;
        !           104:                        }
        !           105:                        return (0);
        !           106:                }
        !           107:                if (iflg && level != 0) {
        !           108:                        printf("rm: remove directory %s? ", arg);
        !           109:                        if (!yes())
        !           110:                                return (0);     /* didn't remove everything */
        !           111:                }
        !           112:                if (access(arg, R_OK|W_OK|X_OK) != 0) {
        !           113:                        if (rmdir(arg) == 0)
        !           114:                                return (1);     /* salvaged: removed empty dir */
        !           115:                        if (!fflg) {
        !           116:                                fprintf(stderr, "rm: %s not changed\n", arg);
        !           117:                                errcode++;
        !           118:                        }
        !           119:                        return (0);             /* error */
        !           120:                }
        !           121:                if ((dirp = opendir(arg)) == NULL) {
        !           122:                        if (!fflg) {
        !           123:                                fprintf(stderr, "rm: cannot read %s?\n", arg);
        !           124:                                errcode++;
        !           125:                        }
        !           126:                        return (0);
        !           127:                }
        !           128:                if (level == 0)
        !           129:                        append(arg);
        !           130:                prevname[0] = '\0';
        !           131:                while ((dp = readdir(dirp)) != NULL) {
        !           132:                        if (dotname(dp->d_name)) {
        !           133:                                strcpy(prevname, dp->d_name);
        !           134:                                continue;
        !           135:                        }
        !           136:                        append(dp->d_name);
        !           137:                        closedir(dirp);
        !           138:                        ok = rm(path, level + 1);
        !           139:                        for (cp = pathp; *--cp != '/' && cp > path; )
        !           140:                                ;
        !           141:                        pathp = cp;
        !           142:                        *cp++ = '\0';
        !           143:                        if ((dirp = opendir(arg)) == NULL) {
        !           144:                                if (!fflg) {
        !           145:                                        fprintf(stderr, "rm: cannot read %s?\n", arg);
        !           146:                                        errcode++;
        !           147:                                }
        !           148:                                break;
        !           149:                        }
        !           150:                        /* pick up where we left off */
        !           151:                        if (prevname[0] != '\0') {
        !           152:                                while ((dp = readdir(dirp)) != NULL &&
        !           153:                                    strcmp(prevname, dp->d_name) != 0)
        !           154:                                        ;
        !           155:                        }
        !           156:                        /* skip the one we just failed to delete */
        !           157:                        if (!ok) {
        !           158:                                dp = readdir(dirp);
        !           159:                                if (dp != NULL && strcmp(cp, dp->d_name)) {
        !           160:                                        fprintf(stderr,
        !           161:                        "rm: internal synchronization error: %s, %s, %s\n",
        !           162:                                                arg, cp, dp->d_name);
        !           163:                                }
        !           164:                                strcpy(prevname, dp->d_name);
        !           165:                        }
        !           166:                }
        !           167:                closedir(dirp);
        !           168:                if (level == 0) {
        !           169:                        pathp = path;
        !           170:                        *pathp = '\0';
        !           171:                }
        !           172:                if (iflg) {
        !           173:                        printf("rm: remove %s? ", arg);
        !           174:                        if (!yes())
        !           175:                                return (0);
        !           176:                }
        !           177:                if (rmdir(arg) < 0) {
        !           178:                        if (!fflg || iflg) {
        !           179:                                fprintf(stderr, "rm: %s not removed\n", arg);
        !           180:                                errcode++;
        !           181:                        }
        !           182:                        return (0);
        !           183:                }
        !           184:                return (1);
        !           185:        }
        !           186: 
        !           187:        if (iflg) {
        !           188:                printf("rm: remove %s? ", arg);
        !           189:                if (!yes())
        !           190:                        return (0);
        !           191:        } else if (!fflg) {
        !           192:                if ((buf.st_mode&S_IFMT) != S_IFLNK && access(arg, W_OK) < 0) {
        !           193:                        printf("rm: override protection %o for %s? ",
        !           194:                                buf.st_mode&0777, arg);
        !           195:                        if (!yes())
        !           196:                                return (0);
        !           197:                }
        !           198:        }
        !           199:        if (unlink(arg) < 0) {
        !           200:                if (!fflg || iflg) {
        !           201:                        fprintf(stderr, "rm: %s not removed\n", arg);
        !           202:                        errcode++;
        !           203:                }
        !           204:                return (0);
        !           205:        }
        !           206:        return (1);
        !           207: }
        !           208: 
        !           209: /*
        !           210:  * boolean: is it "." or ".." ?
        !           211:  */
        !           212: dotname(s)
        !           213:        char *s;
        !           214: {
        !           215:        if (s[0] == '.')
        !           216:                if (s[1] == '.')
        !           217:                        if (s[2] == '\0')
        !           218:                                return (1);
        !           219:                        else
        !           220:                                return (0);
        !           221:                else if (s[1] == '\0')
        !           222:                        return (1);
        !           223:        return (0);
        !           224: }
        !           225: 
        !           226: /*
        !           227:  * Get a yes/no answer from the user.
        !           228:  */
        !           229: yes()
        !           230: {
        !           231:        int i, b;
        !           232: 
        !           233:        i = b = getchar();
        !           234:        while (b != '\n' && b != EOF)
        !           235:                b = getchar();
        !           236:        return (i == 'y');
        !           237: }
        !           238: 
        !           239: /*
        !           240:  * Append 'name' to 'path'.
        !           241:  */
        !           242: append(name)
        !           243:        char *name;
        !           244: {
        !           245:        register int n;
        !           246: 
        !           247:        n = strlen(name);
        !           248:        if (path == NULL) {
        !           249:                pathsz = MAXNAMLEN + MAXPATHLEN + 2;
        !           250:                if ((path = malloc(pathsz)) == NULL) {
        !           251:                        fprintf(stderr, "rm: ran out of memory\n");
        !           252:                        exit(1);
        !           253:                }
        !           254:                pathp = path;
        !           255:        } else if (pathp + n + 2 > path + pathsz) {
        !           256:                fprintf(stderr, "rm: path name too long: %s\n", path);
        !           257:                exit(1);
        !           258:        } else if (pathp != path && pathp[-1] != '/')
        !           259:                *pathp++ = '/';
        !           260:        strcpy(pathp, name);
        !           261:        pathp += n;
        !           262: }

unix.superglobalmegacorp.com

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