add manual page, cleanup
[unix-history] / usr / src / usr.bin / error / touch.c
index 89ff100..1d183d8 100644 (file)
@@ -1,4 +1,24 @@
-static char *sccsid = "@(#)touch.c     1.3 (Berkeley) %G%";
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that the above copyright notice and this paragraph are
+ * duplicated in all such forms and that any documentation,
+ * advertising materials, and other materials related to such
+ * distribution and use acknowledge that the software was developed
+ * by the University of California, Berkeley.  The name of the
+ * University may not be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)touch.c    5.4 (Berkeley) %G%";
+#endif /* not lint */
+
 #include <stdio.h>
 #include <ctype.h>
 #include <sys/types.h>
 #include <stdio.h>
 #include <ctype.h>
 #include <sys/types.h>
@@ -241,9 +261,13 @@ hackfile(name, files, ix, nerrors)
        boolean previewed;
        int     errordest;      /* where errors go*/
 
        boolean previewed;
        int     errordest;      /* where errors go*/
 
-       previewed = preview(name, nerrors, files, ix);
-
-       errordest = settotouch(name);
+       if (!oktotouch(name)) {
+               previewed = FALSE;
+               errordest = TOSTDOUT;
+       } else {
+               previewed = preview(name, nerrors, files, ix);
+               errordest = settotouch(name);
+       }
 
        if (errordest != TOSTDOUT)
                touchedfiles[ix] = TRUE;
 
        if (errordest != TOSTDOUT)
                touchedfiles[ix] = TRUE;
@@ -253,8 +277,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)
@@ -266,18 +294,16 @@ boolean preview(name, nerrors, files, ix)
        int     back;
        reg     Eptr    *erpp;
 
        int     back;
        reg     Eptr    *erpp;
 
-       if (!oktotouch(name))
-               return(false);
        if (nerrors <= 0)
        if (nerrors <= 0)
-               return(false);
-       back = false;
+               return(FALSE);
+       back = FALSE;
        if(query){
                switch(inquire(terse
                    ? "Preview? "
                    : "Do you want to preview the errors first? ")){
                case Q_YES:
                case Q_yes:
        if(query){
                switch(inquire(terse
                    ? "Preview? "
                    : "Do you want to preview the errors first? ")){
                case Q_YES:
                case Q_yes:
-                       back = true;
+                       back = TRUE;
                        EITERATE(erpp, files, ix){
                                errorprint(stdout, *erpp, TRUE);
                        }
                        EITERATE(erpp, files, ix){
                                errorprint(stdout, *erpp, TRUE);
                        }
@@ -468,8 +494,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 +554,124 @@ 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);
+               }
+       default:
+               return(0);
+       }
 }
 
 onintr()
 }
 
 onintr()
@@ -553,8 +684,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*/
@@ -579,6 +714,9 @@ int inquire(fmt, a1, a2)
        /*VARARGS1*/
 {
        char    buffer[128];
        /*VARARGS1*/
 {
        char    buffer[128];
+
+       if (queryfile == NULL)
+               return(0);
        for(;;){
                do{
                        fflush(stdout);
        for(;;){
                do{
                        fflush(stdout);