changeset 214:98820d1eaa79

Upgrade patch to understand creating and deleting files.
author Rob Landley <rob@landley.net>
date Thu, 20 Dec 2007 06:30:19 -0600
parents db91356e3c43
children 34e36dffd47a
files lib/lib.c lib/lib.h toys/patch.c toys/toylist.h
diffstat 4 files changed, 54 insertions(+), 17 deletions(-) [+]
line wrap: on
line diff
--- a/lib/lib.c	Thu Dec 20 06:29:59 2007 -0600
+++ b/lib/lib.c	Thu Dec 20 06:30:19 2007 -0600
@@ -178,6 +178,12 @@
 	if (access(path, flags)) perror_exit("Can't access '%s'\n", path);
 }
 
+// Die unless we can delete a file.  (File must exist to be deleted.)
+void xunlink(char *path)
+{
+	if (unlink(path)) perror_exit("unlink '%s'", path);
+}
+
 // Die unless we can open/create a file, returning file descriptor.
 int xcreate(char *path, int flags, int mode)
 {
--- a/lib/lib.h	Thu Dec 20 06:29:59 2007 -0600
+++ b/lib/lib.h	Thu Dec 20 06:30:19 2007 -0600
@@ -60,6 +60,7 @@
 void xflush(void);
 void xexec(char **argv);
 void xaccess(char *path, int flags);
+void xunlink(char *path);
 int xcreate(char *path, int flags, int mode);
 int xopen(char *path, int flags);
 void xclose(int fd);
--- a/toys/patch.c	Thu Dec 20 06:29:59 2007 -0600
+++ b/toys/patch.c	Thu Dec 20 06:30:19 2007 -0600
@@ -135,7 +135,7 @@
 		buf->prev->next = NULL;
 		llist_free(buf, do_line);
 	}
-	delete_tempfile(TT.filein, TT.fileout, &TT.tempfile);
+	delete_tempfile(TT.filein, TT.fileout, &TT.tempname);
 	TT.filein = -1;
 }
 
@@ -174,19 +174,38 @@
 		apply_hunk();
 			
 		// Open a new file?
-		if (!strncmp("+++ ", patchline, 4)) {
-			int i;
-			char *s, *start;
-
-			// Finish old file.
-			if (TT.tempfile)
-				replace_tempfile(TT.filein, TT.fileout, &TT.tempfile);
+		if (!strncmp("--- ", patchline, 4)) {
+			char *s;
+			free(TT.oldname);
 
 			// Trim date from end of filename (if any).  We don't care.
 			for (s = patchline+4; *s && *s!='\t'; s++)
 				if (*s=='\\' && s[1]) s++;
-			*s = i = 0;
-			for (s = start = patchline+4; *s;) {
+
+			TT.oldname = xstrdup(patchline+4);
+		} else if (!strncmp("+++ ", patchline, 4)) {
+			int i = 0, del = 0;
+			char *s, *start;
+
+			// Finish old file.
+			if (TT.tempname)
+				replace_tempfile(TT.filein, TT.fileout, &TT.tempname);
+
+			// Trim date from end of filename (if any).  We don't care.
+			for (s = patchline+4; *s && *s!='\t'; s++)
+				if (*s=='\\' && s[1]) s++;
+			*s = 0;
+
+
+			// If new file is null (before -p trim), we're deleting oldname
+			start = patchline+4;
+			if (!strcmp(start, "/dev/null")) {
+				start = TT.oldname;
+				del++;
+			} else start = patchline+4;
+				
+			// handle -p path truncation.
+			for (s = start; *s;) {
 				if ((toys.optflags & FLAG_PATHLEN) && TT.prefix == i) break;
 				if (*(s++)=='/') {
 					start = s;
@@ -194,11 +213,18 @@
 				}
 			}
 
+			if (del) xunlink(TT.oldname);
 			// If we've got a file to open, do so.
-			if (!(toys.optflags & FLAG_PATHLEN) || i <= TT.prefix) {
-				printf("patching %s\n", start);
-				TT.filein = xopen(start, O_RDWR);
-				TT.fileout = copy_tempfile(TT.filein, start, &TT.tempfile);
+			else if (!(toys.optflags & FLAG_PATHLEN) || i <= TT.prefix) {
+				// If the old file was null, we're creating a new one.
+				if (!strcmp(TT.oldname, "/dev/null")) {
+					printf("creating %s\n", start);
+					TT.filein = xcreate(start, O_CREAT|O_RDWR, 0666);
+				} else {
+					printf("patching %s\n", start);
+					TT.filein = xopen(start, O_RDWR);
+				}
+				TT.fileout = copy_tempfile(TT.filein, start, &TT.tempname);
 				TT.state = 1;
 				TT.context = 0;
 				TT.linenum = 0;
@@ -210,6 +236,7 @@
 			TT.state = 2;
 			sscanf(patchline+3, "%ld,%ld %ld,%ld", &TT.oldline,
 				&TT.oldlen, &TT.newline, &TT.newlen);
+			// Don't free it.
 			continue;
 		}
 
@@ -219,6 +246,9 @@
 
 	// Flush pending hunk and flush data
 	apply_hunk();
-	if (TT.tempfile) replace_tempfile(TT.filein, TT.fileout, &TT.tempfile);
-	close(TT.filepatch);
+	if (TT.tempname) replace_tempfile(TT.filein, TT.fileout, &TT.tempname);
+	if (CFG_TOYBOX_FREE) {
+		close(TT.filepatch);
+		free(TT.oldname);
+	}
 }
--- a/toys/toylist.h	Thu Dec 20 06:29:59 2007 -0600
+++ b/toys/toylist.h	Thu Dec 20 06:30:19 2007 -0600
@@ -74,7 +74,7 @@
 	struct double_list *plines, *flines;
 	long oldline, oldlen, newline, newlen, linenum;
 	int context, state, filein, fileout, filepatch;
-	char *tempfile;
+	char *tempname, *oldname;
 };
 
 struct sleep_data {