Annotation of 43BSDReno/bin/rm/rm.c, revision 1.1.1.1

1.1       root        1: static char *sccsid = "@(#)rm.c        4.23 (Berkeley) 12/5/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();
                     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, *rindex();
                     77: 
                     78:        cp = rindex(arg, '/');
                     79:        if (cp == NULL)
                     80:                cp = arg;
                     81:        else
                     82:                ++cp;
                     83:        if (isdot(cp)) {
                     84:                fprintf(stderr, "rm: cannot remove `.' or `..'\n");
                     85:                return (0);
                     86:        }
                     87:        if (lstat(arg, &buf)) {
                     88:                if (!fflg) {
                     89:                        fprintf(stderr, "rm: %s nonexistent\n", arg);
                     90:                        errcode++;
                     91:                }
                     92:                return (0);             /* error */
                     93:        }
                     94:        if ((buf.st_mode&S_IFMT) == S_IFDIR) {
                     95:                if (!rflg) {
                     96:                        if (!fflg) {
                     97:                                fprintf(stderr, "rm: %s directory\n", arg);
                     98:                                errcode++;
                     99:                        }
                    100:                        return (0);
                    101:                }
                    102:                if (iflg && level != 0) {
                    103:                        printf("rm: remove directory %s? ", arg);
                    104:                        if (!yes())
                    105:                                return (0);     /* didn't remove everything */
                    106:                }
                    107:                if (access(arg, R_OK|W_OK|X_OK) != 0) {
                    108:                        if (rmdir(arg) == 0)
                    109:                                return (1);     /* salvaged: removed empty dir */
                    110:                        if (!fflg) {
                    111:                                fprintf(stderr, "rm: %s not changed\n", arg);
                    112:                                errcode++;
                    113:                        }
                    114:                        return (0);             /* error */
                    115:                }
                    116:                if ((dirp = opendir(arg)) == NULL) {
                    117:                        if (!fflg) {
                    118:                                fprintf(stderr, "rm: cannot read %s?\n", arg);
                    119:                                errcode++;
                    120:                        }
                    121:                        return (0);
                    122:                }
                    123:                if (level == 0)
                    124:                        append(arg);
                    125:                prevname[0] = '\0';
                    126:                while ((dp = readdir(dirp)) != NULL) {
                    127:                        if (isdot(dp->d_name)) {
                    128:                                strcpy(prevname, dp->d_name);
                    129:                                continue;
                    130:                        }
                    131:                        append(dp->d_name);
                    132:                        closedir(dirp);
                    133:                        ok = rm(path, level + 1);
                    134:                        for (cp = pathp; *--cp != '/' && cp > path; )
                    135:                                ;
                    136:                        pathp = cp;
                    137:                        *cp++ = '\0';
                    138:                        if ((dirp = opendir(arg)) == NULL) {
                    139:                                if (!fflg) {
                    140:                                        fprintf(stderr, "rm: cannot read %s?\n", arg);
                    141:                                        errcode++;
                    142:                                }
                    143:                                break;
                    144:                        }
                    145:                        /* pick up where we left off */
                    146:                        if (prevname[0] != '\0') {
                    147:                                while ((dp = readdir(dirp)) != NULL &&
                    148:                                    strcmp(prevname, dp->d_name) != 0)
                    149:                                        ;
                    150:                        }
                    151:                        /* skip the one we just failed to delete */
                    152:                        if (!ok) {
                    153:                                dp = readdir(dirp);
                    154:                                if (dp != NULL && strcmp(cp, dp->d_name)) {
                    155:                                        fprintf(stderr,
                    156:                        "rm: internal synchronization error: %s, %s, %s\n",
                    157:                                                arg, cp, dp->d_name);
                    158:                                }
                    159:                                strcpy(prevname, dp->d_name);
                    160:                        }
                    161:                }
                    162:                closedir(dirp);
                    163:                if (level == 0) {
                    164:                        pathp = path;
                    165:                        *pathp = '\0';
                    166:                }
                    167:                if (iflg) {
                    168:                        printf("rm: remove %s? ", arg);
                    169:                        if (!yes())
                    170:                                return (0);
                    171:                }
                    172:                if (rmdir(arg) < 0) {
                    173:                        if (!fflg || iflg) {
                    174:                                fprintf(stderr, "rm: %s not removed\n", arg);
                    175:                                errcode++;
                    176:                        }
                    177:                        return (0);
                    178:                }
                    179:                return (1);
                    180:        }
                    181: 
                    182:        if (!fflg) {
                    183:                if ((buf.st_mode&S_IFMT) != S_IFLNK && access(arg, W_OK) < 0) {
                    184:                        printf("rm: override protection %o for %s? ",
                    185:                                buf.st_mode&0777, arg);
                    186:                        if (!yes())
                    187:                                return (0);
                    188:                        goto rm;
                    189:                }
                    190:        }
                    191:        if (iflg) {
                    192:                printf("rm: remove %s? ", arg);
                    193:                if (!yes())
                    194:                        return (0);
                    195:        }
                    196: rm:    if (unlink(arg) < 0) {
                    197:                if (!fflg || iflg) {
                    198:                        fprintf(stderr, "rm: %s: ", arg);
                    199:                        perror((char *)NULL);
                    200:                        errcode++;
                    201:                }
                    202:                return (0);
                    203:        }
                    204:        return (1);
                    205: }
                    206: 
                    207: /*
                    208:  * Get a yes/no answer from the user.
                    209:  */
                    210: yes()
                    211: {
                    212:        int i, b;
                    213: 
                    214:        i = b = getchar();
                    215:        while (b != '\n' && b != EOF)
                    216:                b = getchar();
                    217:        return (i == 'y');
                    218: }
                    219: 
                    220: /*
                    221:  * Append 'name' to 'path'.
                    222:  */
                    223: append(name)
                    224:        char *name;
                    225: {
                    226:        register int n;
                    227:        char *malloc();
                    228: 
                    229:        n = strlen(name);
                    230:        if (path == NULL) {
                    231:                pathsz = MAXNAMLEN + MAXPATHLEN + 2;
                    232:                if ((path = malloc((u_int)pathsz)) == NULL) {
                    233:                        fprintf(stderr, "rm: ran out of memory\n");
                    234:                        exit(1);
                    235:                }
                    236:                pathp = path;
                    237:        } else if (pathp + n + 2 > path + pathsz) {
                    238:                fprintf(stderr, "rm: path name too long: %s\n", path);
                    239:                exit(1);
                    240:        } else if (pathp != path && pathp[-1] != '/')
                    241:                *pathp++ = '/';
                    242:        strcpy(pathp, name);
                    243:        pathp += n;
                    244: }
                    245: 
                    246: usage()
                    247: {
                    248:        fputs("usage: rm [-rif] file ...\n", stderr);
                    249:        exit(1);
                    250: }

unix.superglobalmegacorp.com

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