Module Name:    src
Committed By:   joerg
Date:           Fri Sep 18 13:05:19 UTC 2009

Modified Files:
        src/usr.bin/unzip: unzip.c

Log Message:
Implement rename query.


To generate a diff of this commit:
cvs rdiff -u -r1.7 -r1.8 src/usr.bin/unzip/unzip.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/usr.bin/unzip/unzip.c
diff -u src/usr.bin/unzip/unzip.c:1.7 src/usr.bin/unzip/unzip.c:1.8
--- src/usr.bin/unzip/unzip.c:1.7	Sun Sep  6 20:19:59 2009
+++ src/usr.bin/unzip/unzip.c	Fri Sep 18 13:05:19 2009
@@ -1,4 +1,4 @@
-/* $NetBSD: unzip.c,v 1.7 2009/09/06 20:19:59 wiz Exp $ */
+/* $NetBSD: unzip.c,v 1.8 2009/09/18 13:05:19 joerg Exp $ */
 
 /*-
  * Copyright (c) 2009 Joerg Sonnenberger <jo...@netbsd.org>
@@ -37,7 +37,7 @@
  */
 
 #include <sys/cdefs.h>
-__RCSID("$NetBSD: unzip.c,v 1.7 2009/09/06 20:19:59 wiz Exp $");
+__RCSID("$NetBSD: unzip.c,v 1.8 2009/09/18 13:05:19 joerg Exp $");
 
 #include <sys/queue.h>
 #include <sys/stat.h>
@@ -416,17 +416,59 @@
 static unsigned char buffer[8192];
 static char spinner[] = { '|', '/', '-', '\\' };
 
+static int
+handle_existing_file(char **path)
+{
+	size_t alen;
+	ssize_t len;
+	char buf[4];
+
+	for (;;) {
+		fprintf(stderr,
+		    "replace %s? [y]es, [n]o, [A]ll, [N]one, [r]ename: ",
+		    *path);
+		fgets(buf, 4, stdin);
+		switch (*buf) {
+		case 'A':
+			o_opt = 1;
+			/* FALL THROUGH */
+		case 'y':
+		case 'Y':
+			(void)unlink(*path);
+			return 1;
+		case 'N':
+			n_opt = 1;			
+			/* FALL THROUGH */
+		case 'n':
+			return -1;
+		case 'r':
+		case 'R':
+			printf("New name: ");
+			fflush(stdout);
+			free(*path);
+			*path = NULL;
+			alen = 0;
+			len = getline(path, &alen, stdin);
+			if ((*path)[len - 1] != '\n')
+				(*path)[len - 1] = '\0';
+			return 0;
+		default:
+			break;
+		}
+	}
+}
+
 /*
  * Extract a regular file.
  */
 static void
-extract_file(struct archive *a, struct archive_entry *e, const char *path)
+extract_file(struct archive *a, struct archive_entry *e, char **path)
 {
 	int mode;
 	time_t mtime;
 	struct stat sb;
 	struct timeval tv[2];
-	int cr, fd, text, warn;
+	int cr, fd, text, warn, check;
 	ssize_t len;
 	unsigned char *p, *q, *end;
 
@@ -436,32 +478,36 @@
 	mtime = archive_entry_mtime(e);
 
 	/* look for existing file of same name */
-	if (lstat(path, &sb) == 0) {
+recheck:
+	if (lstat(*path, &sb) == 0) {
 		if (u_opt || f_opt) {
 			/* check if up-to-date */
 			if (S_ISREG(sb.st_mode) && sb.st_mtime >= mtime)
 				return;
-			(void)unlink(path);
+			(void)unlink(*path);
 		} else if (o_opt) {
 			/* overwrite */
-			(void)unlink(path);
+			(void)unlink(*path);
 		} else if (n_opt) {
 			/* do not overwrite */
 			return;
 		} else {
-			/* XXX ask user */
-			errorx("not implemented");
+			check = handle_existing_file(path);
+			if (check == 0)
+				goto recheck;
+			if (check == -1)
+				return; /* do not overwrite */
 		}
 	} else {
 		if (f_opt)
 			return;
 	}
 
-	if ((fd = open(path, O_RDWR|O_CREAT|O_TRUNC, mode)) < 0)
-		error("open('%s')", path);
+	if ((fd = open(*path, O_RDWR|O_CREAT|O_TRUNC, mode)) < 0)
+		error("open('%s')", *path);
 
 	/* loop over file contents and write to disk */
-	info(" extracting: %s", path);
+	info(" extracting: %s", *path);
 	text = a_opt;
 	warn = 0;
 	cr = 0;
@@ -478,7 +524,7 @@
 		if (a_opt && cr) {
 			if (len == 0 || buffer[0] != '\n')
 				if (write(fd, "\r", 1) != 1)
-					error("write('%s')", path);
+					error("write('%s')", *path);
 			cr = 0;
 		}
 
@@ -519,7 +565,7 @@
 				if (!warn && !isascii(*q)) {
 					warningx("%s may be corrupted due"
 					    " to weak text file detection"
-					    " heuristic", path);
+					    " heuristic", *path);
 					warn = 1;
 				}
 				if (q[0] != '\r')
@@ -532,7 +578,7 @@
 					break;
 			}
 			if (write(fd, p, q - p) != q - p)
-				error("write('%s')", path);
+				error("write('%s')", *path);
 		}
 	}
 	if (tty)
@@ -547,9 +593,9 @@
 	tv[1].tv_sec = mtime;
 	tv[1].tv_usec = 0;
 	if (futimes(fd, tv) != 0)
-		error("utimes('%s')", path);
+		error("utimes('%s')", *path);
 	if (close(fd) != 0)
-		error("close('%s')", path);
+		error("close('%s')", *path);
 }
 
 /*
@@ -625,7 +671,7 @@
 	if (S_ISDIR(filetype))
 		extract_dir(a, e, realpathname);
 	else
-		extract_file(a, e, realpathname);
+		extract_file(a, e, &realpathname);
 
 	free(realpathname);
 	free(pathname);

Reply via email to