date and time created 83/02/11 15:44:43 by rrh
[unix-history] / usr / src / usr.bin / error / touch.c
index 89ff100..6dbdac4 100644 (file)
@@ -1,4 +1,4 @@
-static char *sccsid = "@(#)touch.c     1.3 (Berkeley) %G%";
+static char *sccsid = "@(#)touch.c     1.5 (Berkeley) %G%";
 #include <stdio.h>
 #include <ctype.h>
 #include <sys/types.h>
 #include <stdio.h>
 #include <ctype.h>
 #include <sys/types.h>
@@ -253,8 +253,12 @@ hackfile(name, files, ix, nerrors)
 
        diverterrors(name, errordest, files, ix, previewed, nerrors);
 
 
        diverterrors(name, errordest, files, ix, previewed, nerrors);
 
-       if (errordest == TOTHEFILE)
-               writetouched();
+       if (errordest == TOTHEFILE){
+               /*
+                *      overwrite the original file
+                */
+               writetouched(1);
+       }
 }
 
 boolean preview(name, nerrors, files, ix)
 }
 
 boolean preview(name, nerrors, files, ix)
@@ -468,8 +472,8 @@ execvarg(n_pissed_on, r_argc, r_argv)
 FILE   *o_touchedfile; /* the old file */
 FILE   *n_touchedfile; /* the new file */
 char   *o_name;
 FILE   *o_touchedfile; /* the old file */
 FILE   *n_touchedfile; /* the new file */
 char   *o_name;
-char   n_name[32];
-char   *canon_name = "ErrorXXXXXX";
+char   n_name[64];
+char   *canon_name = "/tmp/ErrorXXXXXX";
 int    o_lineno;
 int    n_lineno;
 boolean        tempfileopen = FALSE;
 int    o_lineno;
 int    n_lineno;
 boolean        tempfileopen = FALSE;
@@ -528,19 +532,122 @@ text(p, use_all)
        n_lineno++;
 }
 
        n_lineno++;
 }
 
-writetouched()
+/*
+ *     write the touched file to its temporary copy,
+ *     then bring the temporary in over the local file
+ */
+writetouched(overwrite)
+       int     overwrite;
 {
 {
-       int     nread;
-
+       reg     int     nread;
+       reg     FILE    *localfile;
+       reg     FILE    *tmpfile;
+               int     botch;
+               int     oktorm;
+
+       botch = 0;
+       oktorm = 1;
        while((nread = fread(edbuf, 1, sizeof(edbuf), o_touchedfile)) != NULL){
        while((nread = fread(edbuf, 1, sizeof(edbuf), o_touchedfile)) != NULL){
-               fwrite(edbuf, 1, nread, n_touchedfile);
+               if (nread != fwrite(edbuf, 1, nread, n_touchedfile)){
+                       /*
+                        *      Catastrophe in temporary area: file system full?
+                        */
+                       botch = 1;
+                       fprintf(stderr,
+                         "%s: write failure: No errors inserted in \"%s\"\n",
+                         processname, o_name);
+               }
        }
        fclose(n_touchedfile);
        fclose(o_touchedfile);
        }
        fclose(n_touchedfile);
        fclose(o_touchedfile);
-       unlink(o_name);
-       link(n_name, o_name);
+       /*
+        *      Now, copy the temp file back over the original
+        *      file, thus preserving links, etc
+        */
+       if (botch == 0 && overwrite){
+               botch = 0;
+               localfile = NULL;
+               tmpfile = NULL;
+               if ((localfile = fopen(o_name, "w")) == NULL){
+                       fprintf(stderr,
+                               "%s: Can't open file \"%s\" to overwrite.\n",
+                               processname, o_name);
+                       botch++;
+               }
+               if ((tmpfile = fopen(n_name, "r")) == NULL){
+                       fprintf(stderr, "%s: Can't open file \"%s\" to read.\n",
+                               processname, n_name);
+                       botch++;
+               }
+               if (!botch)
+                       oktorm = mustoverwrite(localfile, tmpfile);
+               if (localfile != NULL)
+                       fclose(localfile);
+               if (tmpfile != NULL)
+                       fclose(tmpfile);
+       }
+       if (oktorm == 0){
+               fprintf(stderr, "%s: Catastrophe: A copy of \"%s\: was saved in \"%s\"\n",
+                       processname, o_name, n_name);
+               exit(1);
+       }
+       /*
+        *      Kiss the temp file good bye
+        */
        unlink(n_name);
        tempfileopen = FALSE;
        unlink(n_name);
        tempfileopen = FALSE;
+       return(TRUE);
+}
+/*
+ *     return 1 if the tmpfile can be removed after writing it out
+ */
+int mustoverwrite(preciousfile, tmpfile)
+       FILE    *preciousfile;
+       FILE    *tmpfile;
+{
+       int     nread;
+
+       while((nread = fread(edbuf, 1, sizeof(edbuf), tmpfile)) != NULL){
+               if (mustwrite(edbuf, nread, preciousfile) == 0)
+                       return(0);
+       }
+       return(1);
+}
+/*
+ *     return 0 on catastrophe
+ */
+mustwrite(base, n, preciousfile)
+       char    *base;
+       int     n;
+       FILE    *preciousfile;
+{
+       int     nwrote;
+
+       if (n <= 0)
+               return(1);
+       nwrote = fwrite(base, 1, n, preciousfile);
+       if (nwrote == n)
+               return(1);
+       perror(processname);
+       switch(inquire(terse
+           ? "Botch overwriting: retry? "
+           : "Botch overwriting the source file: retry? ")){
+       case Q_YES:
+       case Q_yes:
+               mustwrite(base + nwrote, n - nwrote, preciousfile);
+               return(1);
+       case Q_NO:
+       case Q_no:
+               switch(inquire("Are you sure? ")){
+               case Q_YES:
+               case Q_yes:
+                       return(0);
+               case Q_NO:
+               case Q_no:
+                       mustwrite(base + nwrote, n - nwrote, preciousfile);
+                       return(1);
+               }
+       }
 }
 
 onintr()
 }
 
 onintr()
@@ -553,8 +660,12 @@ onintr()
                signal(SIGINT, onintr);
                return;
        default:
                signal(SIGINT, onintr);
                return;
        default:
-               if (tempfileopen)
-                       writetouched();
+               if (tempfileopen){
+                       /*
+                        *      Don't overwrite the original file!
+                        */
+                       writetouched(0);
+               }
                exit(1);
        }
        /*NOTREACHED*/
                exit(1);
        }
        /*NOTREACHED*/