Annotation of 43BSDTahoe/bin/rm.c, revision 1.1.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.