4d21cec081
Don't attempt to edit non regular files. Patches supplied by John Refling in PR pkg/10536.
165 lines
6.2 KiB
Text
165 lines
6.2 KiB
Text
$NetBSD: patch-am,v 1.2 2000/07/10 18:26:55 tron Exp $
|
|
|
|
--- file.c.orig Sun Jul 3 10:48:57 1988
|
|
+++ file.c Wed May 31 16:36:36 2000
|
|
@@ -2,6 +2,10 @@
|
|
* File commands.
|
|
*/
|
|
#include "def.h"
|
|
+#include <stdio.h> // refling
|
|
+#include <sys/types.h>
|
|
+#include <sys/stat.h>
|
|
+
|
|
|
|
BUFFER *findbuffer();
|
|
VOID makename();
|
|
@@ -447,14 +451,147 @@
|
|
writeout(bp, fn) register BUFFER *bp; char *fn; {
|
|
register int s;
|
|
|
|
+// ------------------> refling, for mirroring the original once
|
|
+// ------------------> if .original subdir exists in the same dir as
|
|
+// ------------------> the file to save, and there is an EMPTY file
|
|
+// ------------------> name with the same name as we wish to save
|
|
+
|
|
+// main(int argc, char **argv) {
|
|
+ char *last_slash, *file_name_no_dir, dir_name[1000], cmd[1000], *end_of_dirname;
|
|
+// in[1000];
|
|
+ struct stat stat_struct;
|
|
+ const char nil[] = "nil";
|
|
+ int originaled, journaled, diffoed;
|
|
+
|
|
+ // fn is the incoming string to use, never altered. This is for the
|
|
+ // command line transfer. Not needed in final program.
|
|
+// if (1 == argc) strcpy(fn, "");
|
|
+// else strcpy(fn, argv[1]);
|
|
+
|
|
+ // extract the dirname part of the argument:
|
|
+
|
|
+ // handle case where string is null, just in case
|
|
+ if (0 == strlen(fn)) {
|
|
+ strcpy(dir_name, ".");
|
|
+ file_name_no_dir = (char *)nil; // default: filename in cwd
|
|
+ }
|
|
+
|
|
+ // this case is when there is no slash, so is filename
|
|
+ else if (NULL == (last_slash = (char *)strrchr(fn, '/'))) {
|
|
+ strcpy(dir_name, ".");
|
|
+ file_name_no_dir = fn;
|
|
+ }
|
|
+
|
|
+ // this case is /filename
|
|
+ else if (last_slash == fn) {
|
|
+ strcpy(dir_name, "/");
|
|
+ file_name_no_dir = last_slash + 1;
|
|
+ }
|
|
+
|
|
+ // this case is normal case
|
|
+ else {
|
|
+ *last_slash = 0;
|
|
+ strcpy(dir_name, fn);
|
|
+ *last_slash = '/';
|
|
+ file_name_no_dir = last_slash + 1;
|
|
+ }
|
|
+
|
|
+ // at this point, we have dirname in dir_name. Store its end, so we
|
|
+ // can recover just the dirname later, after concatinating other stuff,
|
|
+ // and a pointer to the stuff following the dirname
|
|
+ end_of_dirname = dir_name + strlen(dir_name);
|
|
+
|
|
+ // get rid of unwanted filenames for this particular application
|
|
+ if (0 == strlen(file_name_no_dir)) file_name_no_dir = (char *)nil;
|
|
+ if (!strcmp(file_name_no_dir, ".")) file_name_no_dir = (char *)nil;
|
|
+ // printf("dir=%s file=%s\n", dir_name, file_name_no_dir);
|
|
+
|
|
+
|
|
+// ///////////////////////////////////////////////////////////////////////////
|
|
+// // start .original: concat the .original directory and filename to dir_name
|
|
+// if (dir_name[strlen(dir_name) - 1] != '/') strcat(dir_name, "/");
|
|
+// strcat(dir_name, ".original/");
|
|
+//
|
|
+ originaled = 0;
|
|
+// // test if .original flag dir exists and the .original/filename does not exist
|
|
+// if (0 == stat(dir_name, &stat_struct) && S_ISDIR(stat_struct.st_mode) &&
|
|
+// 0 != stat(dir_name, &stat_struct)) { // .original/filename does not exist
|
|
+// // test if the initially edited file exists
|
|
+// if (0 == stat(fn, &stat_struct) && S_ISREG(stat_struct.st_mode)) {
|
|
+// strcat(dir_name, file_name_no_dir);
|
|
+// sprintf(cmd, "/bin/cp %s %s", fn, dir_name);
|
|
+// if (0 != system(cmd)) printf(".original/fn backup failed: '%s'\n", cmd);
|
|
+// else originaled = 1;
|
|
+// }
|
|
+// else if ( 0 != stat(fn, &stat_struct)) {
|
|
+// sprintf(cmd, "/usr/bin/touch %s", fn);
|
|
+// if (0 != system(cmd)) printf(".original/fn touch failed: '%s'\n", cmd);
|
|
+// else originaled = 1;
|
|
+// printf(".original/fn touch: '%s'\n", cmd);
|
|
+// }
|
|
+// }
|
|
+//
|
|
+// // restore dir_name to be used in next phase
|
|
+// *end_of_dirname = 0;
|
|
+
|
|
+ ///////////////////////////////////////////////////////////////////////////
|
|
+ // start MG_DOT_ORIG test
|
|
+ diffoed = 0;
|
|
+ if (dir_name[strlen(dir_name) - 1] != '/') strcat(dir_name, "/");
|
|
+ strcat(dir_name, file_name_no_dir);
|
|
+ strcat(dir_name, ".orig");
|
|
+ // if MG_DOT_ORIG set and there is no .orig for the edited file
|
|
+ if (NULL != getenv("MG_DOT_ORIG") && 0 != stat(dir_name, &stat_struct)) {
|
|
+ // if edited file already exists and is a file, copy it to .orig
|
|
+ if (0 == stat(fn, &stat_struct) && S_ISREG(stat_struct.st_mode)) {
|
|
+ sprintf(cmd, "/bin/cp %s %s", fn, dir_name);
|
|
+ if (0 != system(cmd)) printf(".orig backup failed: '%s'\n", cmd);
|
|
+ else diffoed = 1;
|
|
+ }
|
|
+ // if edited file does not exist yet, touch the .orig since it was empty
|
|
+ else if (0 != stat(fn, &stat_struct)) {
|
|
+ sprintf(cmd, "/usr/bin/touch %s", dir_name);
|
|
+ if (0 != system(cmd)) printf(".orig touch failed: '%s'\n", cmd);
|
|
+ else diffoed = 1;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ // restore dir_name to be used in next phase
|
|
+ *end_of_dirname = 0;
|
|
+
|
|
+ ///////////////////////////////////////////////////////////////////////////
|
|
+ // start journal: concat the .journal directory and filename to dir_name
|
|
+ if (dir_name[strlen(dir_name) - 1] != '/') strcat(dir_name, "/");
|
|
+ strcat(dir_name, ".journal/");
|
|
+
|
|
+ journaled = 0;
|
|
+ // test if .journal flag directory exists
|
|
+ if (0 == stat(dir_name, &stat_struct) && S_ISDIR(stat_struct.st_mode)) {
|
|
+ // test if the initially edited file exists
|
|
+ if (0 == stat(fn, &stat_struct) && S_ISREG(stat_struct.st_mode)) {
|
|
+ sprintf(cmd, "/bin/cp %s %s%s-@%ld", fn, dir_name, file_name_no_dir, time(NULL));
|
|
+ if (0 != system(cmd)) printf("journal failed: '%s'\n", cmd);
|
|
+ else journaled = 1;
|
|
+ }
|
|
+ else if (0 != stat(fn, &stat_struct)) {
|
|
+ sprintf(cmd, "/usr/bin/touch %s%s-@%ld", dir_name, file_name_no_dir, time(NULL));
|
|
+ if (0 != system(cmd)) printf(".journal/fn touch failed: '%s'\n", cmd);
|
|
+ else journaled = 1;
|
|
+ }
|
|
+ }
|
|
if ((s=ffwopen(fn)) != FIOSUC) /* Open writes message. */
|
|
return (FALSE);
|
|
s = ffputbuf(bp);
|
|
if (s == FIOSUC) { /* No write error. */
|
|
s = ffclose();
|
|
- if (s==FIOSUC)
|
|
- ewprintf("Wrote %s", fn);
|
|
+ if (s==FIOSUC && !diffoed && !journaled) ewprintf("Wrote %s", fn);
|
|
+ if (s==FIOSUC && !diffoed && journaled) ewprintf("Wrote(j) %s", fn);
|
|
+ if (s==FIOSUC && diffoed && !journaled) ewprintf("Wrote(o) %s", fn);
|
|
+ if (s==FIOSUC && diffoed && journaled) ewprintf("Wrote(o+j) %s", fn);
|
|
} else /* Ignore close error */
|
|
+
|
|
+// ------------------> refling, for originaling and journaling, end
|
|
+
|
|
(VOID) ffclose(); /* if a write error. */
|
|
return s == FIOSUC;
|
|
}
|