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

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

unix.superglobalmegacorp.com

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