[BusyBox] latest rm patch

Matt Kraai kraai at alumni.carnegiemellon.edu
Tue Apr 24 15:20:59 UTC 2001


Howdy,

The attached patch is my latest rm incarnation.  I don't know of
any outstanding issues, so please let me know what I'm missing.

Matt
-------------- next part --------------
Index: Makefile
===================================================================
RCS file: /var/cvs/busybox/Makefile,v
retrieving revision 1.189
diff -u -r1.189 Makefile
--- Makefile	2001/04/23 16:11:57	1.189
+++ Makefile	2001/04/24 15:19:38
@@ -247,7 +247,8 @@
 process_escape_sequence.c read_package_field.c read_text_file_to_buffer.c \
 recursive_action.c safe_read.c safe_strncpy.c seek_ared_file.c syscalls.c \
 syslog_msg_with_name.c time_string.c trim.c untar.c unzip.c vdprintf.c \
-verror_msg.c vperror_msg.c wfopen.c xfuncs.c xgetcwd.c xregcomp.c interface.c
+verror_msg.c vperror_msg.c wfopen.c xfuncs.c xgetcwd.c xregcomp.c interface.c \
+remove_file.c
 
 LIBBB_OBJS=$(patsubst %.c,$(LIBBB)/%.o, $(LIBBB_CSRC))
 LIBBB_CFLAGS = -I$(LIBBB)
Index: mv.c
===================================================================
RCS file: /var/cvs/busybox/mv.c,v
retrieving revision 1.15
diff -u -r1.15 mv.c
--- mv.c	2001/04/24 01:30:02	1.15
+++ mv.c	2001/04/24 15:19:38
@@ -32,20 +32,6 @@
 
 static int flags;
 
-static int remove_file(const char *path, struct stat *statbuf, void *junk)
-{
-	if (unlink(path) < 0)
-		return FALSE;
-	return TRUE;
-}
-
-static int remove_directory(const char *path, struct stat *statbuf, void *junk)
-{
-	if (rmdir(path) < 0)
-		return FALSE;
-	return TRUE;
-}
-
 static int manual_rename(const char *source, const char *dest)
 {
 	struct stat source_stat;
@@ -92,8 +78,7 @@
 			FILEUTILS_PRESERVE_SYMLINKS) < 0)
 		return -1;
 
-	if (!recursive_action(source, TRUE, FALSE, TRUE, remove_file,
-				remove_directory, NULL))
+	if (remove_file(source, FILEUTILS_RECUR | FILEUTILS_FORCE) < 0)
 		return -1;
 
 	return 0;
Index: rm.c
===================================================================
RCS file: /var/cvs/busybox/rm.c,v
retrieving revision 1.33
diff -u -r1.33 rm.c
--- rm.c	2001/04/11 17:20:44	1.33
+++ rm.c	2001/04/24 15:19:38
@@ -3,12 +3,8 @@
  * Mini rm implementation for busybox
  *
  *
- * Copyright (C) 1999,2000,2001 by Lineo, inc.
- * Written by Erik Andersen <andersen at lineo.com>, <andersee at debian.org>
+ * Copyright (C) 2001 Matt Kraai <kraai at alumni.carnegiemellon.edu>
  *
- * INTERACTIVE feature Copyright (C) 2001 by Alcove
- *   written by Christophe Boyanique <Christophe.Boyanique at fr.alcove.com>
- *   for Ipanema Technologies
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -36,103 +32,45 @@
 #include <getopt.h>
 #include "busybox.h"
 
-static int recursiveFlag = FALSE;
-static int forceFlag = FALSE;
-#ifdef BB_FEATURE_RM_INTERACTIVE
-	static int interactiveFlag = FALSE;
-#endif
-static const char *srcName;
-
-
-static int fileAction(const char *fileName, struct stat *statbuf, void* junk)
-{
-#ifdef BB_FEATURE_RM_INTERACTIVE
-	if (interactiveFlag == TRUE) {
-		printf("rm: remove `%s'? ", fileName);
-		if (ask_confirmation() == 0)
-			return (TRUE);
-	}
-#endif
-	if (unlink(fileName) < 0) {
-		perror_msg("%s", fileName);
-		return (FALSE);
-	}
-	return (TRUE);
-}
-
-static int dirAction(const char *fileName, struct stat *statbuf, void* junk)
-{
-	if (recursiveFlag == FALSE) {
-		errno = EISDIR;
-		perror_msg("%s", fileName);
-		return (FALSE);
-	} 
-#ifdef BB_FEATURE_RM_INTERACTIVE
-	if (interactiveFlag == TRUE) {
-		printf("rm: remove directory `%s'? ", fileName);
-		if (ask_confirmation() == 0)
-			return (TRUE);
-	}
-#endif
-	if (rmdir(fileName) < 0) {
-		perror_msg("%s", fileName);
-		return (FALSE);
-	}
-	return (TRUE);
-}
-
 extern int rm_main(int argc, char **argv)
 {
+	int status = 0;
 	int opt;
-	int status = EXIT_SUCCESS;
-	struct stat statbuf;
-	
-	
-	/* do normal option parsing */
-	while ((opt = getopt(argc, argv, "Rrf-"
-#ifdef BB_FEATURE_RM_INTERACTIVE
-"i"
-#endif
-)) > 0) {
+	int flags = 0;
+	int i;
+
+	while ((opt = getopt(argc, argv, "fiRr")) != -1) {
 		switch (opt) {
-			case 'R':
-			case 'r':
-				recursiveFlag = TRUE;
-				break;
-			case 'f':
-				forceFlag = TRUE;
-#ifdef BB_FEATURE_RM_INTERACTIVE
-
-				interactiveFlag = FALSE;
-#endif
-				break;
-#ifdef BB_FEATURE_RM_INTERACTIVE
-			case 'i':
-				interactiveFlag = TRUE;
-				forceFlag = FALSE;
-				break;
-#endif
-			default:
-				show_usage();
+		case 'f':
+			flags &= ~FILEUTILS_INTERACTIVE;
+			flags |= FILEUTILS_FORCE;
+			break;
+		case 'i':
+			flags &= ~FILEUTILS_FORCE;
+			flags |= FILEUTILS_INTERACTIVE;
+			break;
+		case 'R':
+		case 'r':
+			flags |= FILEUTILS_RECUR;
+			break;
 		}
 	}
-	
-	if (argc == optind && forceFlag == FALSE) {
+
+	if (!(flags & FILEUTILS_FORCE) && optind == argc)
 		show_usage();
-	}
+
+	for (i = optind; i < argc; i++) {
+		char *base = get_last_path_component(argv[i]);
 
-	while (optind < argc) {
-		srcName = argv[optind];
-		if (forceFlag == TRUE && lstat(srcName, &statbuf) != 0
-			&& errno == ENOENT) {
-			/* do not reports errors for non-existent files if -f, just skip them */
-		} else {
-			if (recursive_action(srcName, recursiveFlag, FALSE,
-								TRUE, fileAction, dirAction, NULL) == FALSE) {
-				status = EXIT_FAILURE;
-			}
+		if (strcmp(base, ".") == 0 || strcmp(base, "..") == 0) {
+			error_msg("cannot remove `.' or `..'");
+			status = 1;
+			continue;
 		}
-		optind++;
+
+		if (remove_file(argv[i], flags) < 0)
+			status = 1;
 	}
+
 	return status;
 }
Index: libbb/libbb.h
===================================================================
RCS file: /var/cvs/busybox/libbb/libbb.h,v
retrieving revision 1.23
diff -u -r1.23 libbb.h
--- libbb/libbb.h	2001/04/24 01:30:02	1.23
+++ libbb/libbb.h	2001/04/24 15:19:38
@@ -93,6 +93,7 @@
 void add_to_ino_dev_hashtable(const struct stat *statbuf, const char *name);
 void reset_ino_dev_hashtable(void);
 
+int remove_file(const char *path, int flags);
 int copy_file(const char *source, const char *dest, int flags);
 int copy_file_chunk(FILE *src_file, FILE *dst_file, unsigned long long chunksize);
 char *buildName(const char *dirName, const char *fileName);
Index: libbb/remove_file.c
===================================================================
RCS file: remove_file.c
diff -N remove_file.c
--- /dev/null	Mon Nov 13 12:19:20 2000
+++ remove_file.c	Tue Apr 24 09:19:39 2001
@@ -0,0 +1,125 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * Mini remove_file implementation for busybox
+ *
+ *
+ * Copyright (C) 2001 Matt Kraai <kraai at alumni.carnegiemellon.edu>
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <stdio.h>
+#include <time.h>
+#include <utime.h>
+#include <dirent.h>
+#include <errno.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <getopt.h>
+#include "libbb.h"
+
+extern int remove_file(const char *path, int flags)
+{
+	struct stat path_stat;
+	int path_exists = 1;
+
+	if (stat(path, &path_stat) < 0) {
+		if (errno != ENOENT) {
+			perror_msg("unable to stat `%s'", path);
+			return -1;
+		}
+
+		path_exists = 0;
+	}
+
+	if (!path_exists) {
+		if (!(flags & FILEUTILS_FORCE))
+			perror_msg("cannot remove `%s'", path);
+		return -1;
+	}
+
+	if (S_ISDIR(path_stat.st_mode)) {
+		DIR *dp;
+		struct dirent *d;
+		int status = 0;
+
+		if (!(flags & FILEUTILS_RECUR)) {
+			error_msg("%s: is a directory", path);
+			return -1;
+		}
+
+		if ((!(flags & FILEUTILS_FORCE) && access(path, W_OK) < 0 &&
+					isatty(0)) ||
+				(flags & FILEUTILS_INTERACTIVE)) {
+			fprintf(stderr, "%s: descend into directory `%s'? ", applet_name,
+					path);
+			if (!ask_confirmation())
+				return 0;
+		}
+
+		if ((dp = opendir(path)) == NULL) {
+			perror_msg("unable to open `%s'", path);
+			return -1;
+		}
+
+		while ((d = readdir(dp)) != NULL) {
+			char *new_path;
+
+			if (strcmp(d->d_name, ".") == 0 ||
+					strcmp(d->d_name, "..") == 0)
+				continue;
+
+			new_path = concat_path_file(path, d->d_name);
+			if (remove_file(new_path, flags) < 0)
+				status = -1;
+			free(new_path);
+		}
+
+		if (closedir(dp) < 0) {
+			perror_msg("unable to close `%s'", path);
+			return -1;
+		}
+
+		if (flags & FILEUTILS_INTERACTIVE) {
+			fprintf(stderr, "%s: remove directory `%s'? ", applet_name, path);
+			if (!ask_confirmation())
+				return status;
+		}
+
+		if (rmdir(path) < 0) {
+			perror_msg("unable to remove `%s'", path);
+			return -1;
+		}
+
+		return status;
+	} else {
+		if ((!(flags & FILEUTILS_FORCE) && access(path, W_OK) < 0 &&
+					isatty(0)) ||
+				(flags & FILEUTILS_INTERACTIVE)) {
+			fprintf(stderr, "%s: remove `%s'? ", applet_name, path);
+			if (!ask_confirmation())
+				return 0;
+		}
+
+		if (unlink(path) < 0) {
+			perror_msg("unable to remove `%s'", path);
+			return -1;
+		}
+
+		return 0;
+	}
+}


More information about the busybox mailing list