-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>
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;
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)
int back;
reg Eptr *erpp;
- if (!oktotouch(name))
- return(false);
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:
- back = true;
+ back = TRUE;
EITERATE(erpp, files, ix){
errorprint(stdout, *erpp, TRUE);
}
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;
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){
- 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);
- 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;
+ 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()
signal(SIGINT, onintr);
return;
default:
- if (tempfileopen)
- writetouched();
+ if (tempfileopen){
+ /*
+ * Don't overwrite the original file!
+ */
+ writetouched(0);
+ }
exit(1);
}
/*NOTREACHED*/
/*VARARGS1*/
{
char buffer[128];
+
+ if (queryfile == NULL)
+ return(0);
for(;;){
do{
fflush(stdout);