Implement rename query.

This commit is contained in:
joerg 2009-09-18 13:05:19 +00:00
parent c349dcd7cd
commit 1d5ec6dab9

View File

@ -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 <joerg@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 @@ extract_dir(struct archive *a, struct archive_entry *e, const char *path)
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 @@ extract_file(struct archive *a, struct archive_entry *e, const char *path)
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 @@ extract_file(struct archive *a, struct archive_entry *e, const char *path)
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 @@ extract_file(struct archive *a, struct archive_entry *e, const char *path)
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 @@ extract_file(struct archive *a, struct archive_entry *e, const char *path)
break;
}
if (write(fd, p, q - p) != q - p)
error("write('%s')", path);
error("write('%s')", *path);
}
}
if (tty)
@ -547,9 +593,9 @@ extract_file(struct archive *a, struct archive_entry *e, const char *path)
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 @@ extract(struct archive *a, struct archive_entry *e)
if (S_ISDIR(filetype))
extract_dir(a, e, realpathname);
else
extract_file(a, e, realpathname);
extract_file(a, e, &realpathname);
free(realpathname);
free(pathname);