From b475309cae5b70447017624e2c1942747a89e1a6 Mon Sep 17 00:00:00 2001 From: Simon Morgan Date: Tue, 5 Aug 2008 02:02:28 +0100 Subject: [PATCH] This shouldn't be here. --- rm.c | 425 ------------------------------------------------------------------- 1 file changed, 425 deletions(-) delete mode 100644 rm.c diff --git a/rm.c b/rm.c deleted file mode 100644 index 37aaba9..0000000 --- a/rm.c +++ /dev/null @@ -1,425 +0,0 @@ -/* $OpenBSD: rm.c,v 1.21 2007/06/06 00:08:57 ray Exp $ */ -/* $NetBSD: rm.c,v 1.19 1995/09/07 06:48:50 jtc Exp $ */ - -/*- - * Copyright (c) 1990, 1993, 1994 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifndef lint -static char copyright[] = -"@(#) Copyright (c) 1990, 1993, 1994\n\ - The Regents of the University of California. All rights reserved.\n"; -#endif /* not lint */ - -#ifndef lint -#if 0 -static char sccsid[] = "@(#)rm.c 8.8 (Berkeley) 4/27/95"; -#else -static char rcsid[] = "$OpenBSD: rm.c,v 1.21 2007/06/06 00:08:57 ray Exp $"; -#endif -#endif /* not lint */ - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -extern char *__progname; - -int dflag, eval, fflag, iflag, Pflag, stdin_ok; - -int check(char *, char *, struct stat *); -void checkdot(char **); -void rm_file(char **); -int rm_overwrite(char *, struct stat *); -int pass(int, int, off_t, char *, size_t); -void rm_tree(char **); -void usage(void); - -/* - * rm -- - * This rm is different from historic rm's, but is expected to match - * POSIX 1003.2 behavior. The most visible difference is that -f - * has two specific effects now, ignore non-existent files and force - * file removal. - */ -int -main(int argc, char *argv[]) -{ - int ch, rflag; - - setlocale(LC_ALL, ""); - - Pflag = rflag = 0; - while ((ch = getopt(argc, argv, "dfiPRr")) != -1) - switch(ch) { - case 'd': - dflag = 1; - break; - case 'f': - fflag = 1; - iflag = 0; - break; - case 'i': - fflag = 0; - iflag = 1; - break; - case 'P': - Pflag = 1; - break; - case 'R': - case 'r': /* Compatibility. */ - rflag = 1; - break; - default: - usage(); - } - argc -= optind; - argv += optind; - - if (argc < 1 && fflag == 0) - usage(); - - checkdot(argv); - - if (*argv) { - stdin_ok = isatty(STDIN_FILENO); - - if (rflag) - rm_tree(argv); - else - rm_file(argv); - } - - exit (eval); -} - -void -rm_tree(char **argv) -{ - FTS *fts; - FTSENT *p; - int needstat; - int flags; - - /* - * Remove a file hierarchy. If forcing removal (-f), or interactive - * (-i) or can't ask anyway (stdin_ok), don't stat the file. - */ - needstat = !fflag && !iflag && stdin_ok; - - /* - * If the -i option is specified, the user can skip on the pre-order - * visit. The fts_number field flags skipped directories. - */ -#define SKIPPED 1 - - flags = FTS_PHYSICAL; - if (!needstat) - flags |= FTS_NOSTAT; - if (!(fts = fts_open(argv, flags, NULL))) - err(1, NULL); - while ((p = fts_read(fts)) != NULL) { - switch (p->fts_info) { - case FTS_DNR: - if (!fflag || p->fts_errno != ENOENT) { - warnx("%s: %s", - p->fts_path, strerror(p->fts_errno)); - eval = 1; - } - continue; - case FTS_ERR: - errx(1, "%s: %s", p->fts_path, strerror(p->fts_errno)); - case FTS_NS: - /* - * FTS_NS: assume that if can't stat the file, it - * can't be unlinked. - */ - if (!needstat) - break; - if (!fflag || p->fts_errno != ENOENT) { - warnx("%s: %s", - p->fts_path, strerror(p->fts_errno)); - eval = 1; - } - continue; - case FTS_D: - /* Pre-order: give user chance to skip. */ - if (!fflag && !check(p->fts_path, p->fts_accpath, - p->fts_statp)) { - (void)fts_set(fts, p, FTS_SKIP); - p->fts_number = SKIPPED; - } - continue; - case FTS_DP: - /* Post-order: see if user skipped. */ - if (p->fts_number == SKIPPED) - continue; - break; - default: - if (!fflag && - !check(p->fts_path, p->fts_accpath, p->fts_statp)) - continue; - } - - /* - * If we can't read or search the directory, may still be - * able to remove it. Don't print out the un{read,search}able - * message unless the remove fails. - */ - switch (p->fts_info) { - case FTS_DP: - case FTS_DNR: - if (!rmdir(p->fts_accpath) || - (fflag && errno == ENOENT)) - continue; - break; - - default: - if (Pflag) - rm_overwrite(p->fts_accpath, NULL); - if (!unlink(p->fts_accpath) || - (fflag && errno == ENOENT)) - continue; - } - warn("%s", p->fts_path); - eval = 1; - } - if (errno) - err(1, "fts_read"); - fts_close(fts); -} - -void -rm_file(char **argv) -{ - struct stat sb; - int rval; - char *f; - - /* - * Remove a file. POSIX 1003.2 states that, by default, attempting - * to remove a directory is an error, so must always stat the file. - */ - while ((f = *argv++) != NULL) { - /* Assume if can't stat the file, can't unlink it. */ - if (lstat(f, &sb)) { - if (!fflag || errno != ENOENT) { - warn("%s", f); - eval = 1; - } - continue; - } - - if (S_ISDIR(sb.st_mode) && !dflag) { - warnx("%s: is a directory", f); - eval = 1; - continue; - } - if (!fflag && !check(f, f, &sb)) - continue; - else if (S_ISDIR(sb.st_mode)) - rval = rmdir(f); - else { - if (Pflag) - rm_overwrite(f, &sb); - rval = unlink(f); - } - if (rval && (!fflag || errno != ENOENT)) { - warn("%s", f); - eval = 1; - } - } -} - -/* - * rm_overwrite -- - * Overwrite the file 3 times with varying bit patterns. - * - * XXX - * This is a cheap way to *really* delete files. Note that only regular - * files are deleted, directories (and therefore names) will remain. - * Also, this assumes a fixed-block file system (like FFS, or a V7 or a - * System V file system). In a logging file system, you'll have to have - * kernel support. - * Returns 1 for success. - */ -int -rm_overwrite(char *file, struct stat *sbp) -{ - struct stat sb; - struct statfs fsb; - size_t bsize; - int fd; - char *buf = NULL; - - fd = -1; - if (sbp == NULL) { - if (lstat(file, &sb)) - goto err; - sbp = &sb; - } - if (!S_ISREG(sbp->st_mode)) - return (1); - if (sbp->st_nlink > 1) { - warnx("%s (inode %u): not overwritten due to multiple links", - file, sbp->st_ino); - return (0); - } - if ((fd = open(file, O_WRONLY, 0)) == -1) - goto err; - if (fstatfs(fd, &fsb) == -1) - goto err; - bsize = MAX(fsb.f_iosize, 1024U); - if ((buf = malloc(bsize)) == NULL) - err(1, "%s: malloc", file); - - if (!pass(0xff, fd, sbp->st_size, buf, bsize) || fsync(fd) || - lseek(fd, (off_t)0, SEEK_SET)) - goto err; - if (!pass(0x00, fd, sbp->st_size, buf, bsize) || fsync(fd) || - lseek(fd, (off_t)0, SEEK_SET)) - goto err; - if (!pass(0xff, fd, sbp->st_size, buf, bsize) || fsync(fd)) - goto err; - close(fd); - free(buf); - return (1); - -err: - warn("%s", file); - close(fd); - eval = 1; - free(buf); - return (0); -} - -int -pass(int val, int fd, off_t len, char *buf, size_t bsize) -{ - size_t wlen; - - memset(buf, val, bsize); - for (; len > 0; len -= wlen) { - wlen = len < bsize ? len : bsize; - if (write(fd, buf, wlen) != wlen) - return (0); - } - return (1); -} - -int -check(char *path, char *name, struct stat *sp) -{ - int ch, first; - char modep[15]; - - /* Check -i first. */ - if (iflag) - (void)fprintf(stderr, "remove %s? ", path); - else { - /* - * If it's not a symbolic link and it's unwritable and we're - * talking to a terminal, ask. Symbolic links are excluded - * because their permissions are meaningless. Check stdin_ok - * first because we may not have stat'ed the file. - */ - if (!stdin_ok || S_ISLNK(sp->st_mode) || !access(name, W_OK)) - return (1); - strmode(sp->st_mode, modep); - (void)fprintf(stderr, "override %s%s%s/%s for %s? ", - modep + 1, modep[9] == ' ' ? "" : " ", - user_from_uid(sp->st_uid, 0), - group_from_gid(sp->st_gid, 0), path); - } - (void)fflush(stderr); - - first = ch = getchar(); - while (ch != '\n' && ch != EOF) - ch = getchar(); - return (first == 'y' || first == 'Y'); -} - -/* - * POSIX.2 requires that if "." or ".." are specified as the basename - * portion of an operand, a diagnostic message be written to standard - * error and nothing more be done with such operands. - * - * Since POSIX.2 defines basename as the final portion of a path after - * trailing slashes have been removed, we'll remove them here. - */ -#define ISDOT(a) ((a)[0] == '.' && (!(a)[1] || ((a)[1] == '.' && !(a)[2]))) -void -checkdot(char **argv) -{ - char *p, **save, **t; - int complained; - - complained = 0; - for (t = argv; *t;) { - /* strip trailing slashes */ - p = strrchr (*t, '\0'); - while (--p > *t && *p == '/') - *p = '\0'; - - /* extract basename */ - if ((p = strrchr(*t, '/')) != NULL) - ++p; - else - p = *t; - - if (ISDOT(p)) { - if (!complained++) - warnx("\".\" and \"..\" may not be removed"); - eval = 1; - for (save = t; (t[0] = t[1]) != NULL; ++t) - continue; - t = save; - } else - ++t; - } -} - -void -usage(void) -{ - (void)fprintf(stderr, "usage: %s [-dfiPRr] file ...\n", __progname); - exit(1); -} -- 2.11.4.GIT