summaryrefslogtreecommitdiff
path: root/usr.bin/patch
diff options
context:
space:
mode:
authorkristerw <kristerw@NetBSD.org>2002-03-11 23:29:02 +0000
committerkristerw <kristerw@NetBSD.org>2002-03-11 23:29:02 +0000
commit2b96113ff9ad1eb5559f95affe3fdd8cb216d057 (patch)
treea58ad4f35520443095a41afc92745b75c673403f /usr.bin/patch
parentbc84308f58c28a4f50e6b2c39b1cca24351a8119 (diff)
KNF
Diffstat (limited to 'usr.bin/patch')
-rw-r--r--usr.bin/patch/inp.c573
-rw-r--r--usr.bin/patch/util.c671
2 files changed, 649 insertions, 595 deletions
diff --git a/usr.bin/patch/inp.c b/usr.bin/patch/inp.c
index 0697eb5503e..a9fd1e37d93 100644
--- a/usr.bin/patch/inp.c
+++ b/usr.bin/patch/inp.c
@@ -1,7 +1,7 @@
-/* $NetBSD: inp.c,v 1.8 2002/03/11 18:47:51 kristerw Exp $ */
+/* $NetBSD: inp.c,v 1.9 2002/03/11 23:29:02 kristerw Exp $ */
#include <sys/cdefs.h>
#ifndef lint
-__RCSID("$NetBSD: inp.c,v 1.8 2002/03/11 18:47:51 kristerw Exp $");
+__RCSID("$NetBSD: inp.c,v 1.9 2002/03/11 23:29:02 kristerw Exp $");
#endif /* not lint */
#include "EXTERN.h"
@@ -16,332 +16,359 @@ __RCSID("$NetBSD: inp.c,v 1.8 2002/03/11 18:47:51 kristerw Exp $");
#include <unistd.h>
#include <fcntl.h>
-/* Input-file-with-indexable-lines abstract type */
+/* Input-file-with-indexable-lines abstract type. */
-static long i_size; /* size of the input file */
-static char *i_womp; /* plan a buffer for entire file */
-static char **i_ptr; /* pointers to lines in i_womp */
+static long i_size; /* Size of the input file */
+static char *i_womp; /* Plan a buffer for entire file */
+static char **i_ptr; /* Pointers to lines in i_womp */
-static int tifd = -1; /* plan b virtual string array */
-static char *tibuf[2]; /* plan b buffers */
+static int tifd = -1; /* Plan b virtual string array */
+static char *tibuf[2]; /* Plan b buffers */
static LINENUM tiline[2] = {-1, -1}; /* 1st line in each buffer */
-static LINENUM lines_per_buf; /* how many lines per buffer */
-static int tireclen; /* length of records in tmp file */
-
-/* New patch--prepare to edit another file. */
+static LINENUM lines_per_buf; /* How many lines per buffer */
+static int tireclen; /* Length of records in tmp file */
+/*
+ * New patch--prepare to edit another file.
+ */
void
re_input(void)
{
- if (using_plan_a) {
- i_size = 0;
-
- if (i_ptr != NULL)
- free(i_ptr);
- if (i_womp != NULL)
- free(i_womp);
- i_womp = NULL;
- i_ptr = NULL;
- }
- else {
- using_plan_a = TRUE; /* maybe the next one is smaller */
- Close(tifd);
- tifd = -1;
- free(tibuf[0]);
- free(tibuf[1]);
- tibuf[0] = tibuf[1] = NULL;
- tiline[0] = tiline[1] = -1;
- tireclen = 0;
- }
+ if (using_plan_a) {
+ i_size = 0;
+
+ if (i_ptr != NULL)
+ free(i_ptr);
+ if (i_womp != NULL)
+ free(i_womp);
+ i_womp = NULL;
+ i_ptr = NULL;
+ } else {
+ using_plan_a = TRUE; /* maybe the next one is smaller */
+ Close(tifd);
+ tifd = -1;
+ free(tibuf[0]);
+ free(tibuf[1]);
+ tibuf[0] = tibuf[1] = NULL;
+ tiline[0] = tiline[1] = -1;
+ tireclen = 0;
+ }
}
-/* Constuct the line index, somehow or other. */
-
+/*
+ * Constuct the line index, somehow or other.
+ */
void
scan_input(char *filename)
{
- if (!plan_a(filename))
- plan_b(filename);
- if (verbose) {
- say("Patching file %s using Plan %s...\n", filename,
- (using_plan_a ? "A" : "B") );
- }
+ if (!plan_a(filename))
+ plan_b(filename);
+ if (verbose) {
+ say("Patching file %s using Plan %s...\n", filename,
+ (using_plan_a ? "A" : "B") );
+ }
}
-/* Try keeping everything in memory. */
-
+/*
+ * Try keeping everything in memory.
+ */
bool
plan_a(char *filename)
{
- int ifd, statfailed;
- char *s;
- LINENUM iline;
- char lbuf[MAXLINELEN];
+ int ifd, statfailed;
+ char *s;
+ LINENUM iline;
+ char lbuf[MAXLINELEN];
- statfailed = stat(filename, &filestat);
- if (statfailed && ok_to_create_file) {
- if (verbose)
- say("(Creating file %s...)\n",filename);
- makedirs(filename, TRUE);
- close(creat(filename, 0666));
statfailed = stat(filename, &filestat);
- }
- /* For nonexistent or read-only files, look for RCS or SCCS versions. */
- if (statfailed
- /* No one can write to it. */
- || (filestat.st_mode & 0222) == 0
- /* I can't write to it. */
- || ((filestat.st_mode & 0022) == 0 && filestat.st_uid != myuid)) {
- struct stat cstat;
- char *cs = NULL;
- char *filebase;
- int pathlen;
-
- filebase = basename(filename);
- pathlen = filebase - filename;
-
- /* Put any leading path into `s'.
- Leave room in lbuf for the diff command. */
- s = lbuf + 20;
- strncpy(s, filename, pathlen);
+ if (statfailed && ok_to_create_file) {
+ if (verbose)
+ say("(Creating file %s...)\n",filename);
+ makedirs(filename, TRUE);
+ close(creat(filename, 0666));
+ statfailed = stat(filename, &filestat);
+ }
+ /*
+ * For nonexistent or read-only files, look for RCS or SCCS
+ * versions.
+ */
+ if (statfailed ||
+ /* No one can write to it. */
+ (filestat.st_mode & 0222) == 0 ||
+ /* I can't write to it. */
+ ((filestat.st_mode & 0022) == 0 && filestat.st_uid != myuid)) {
+ struct stat cstat;
+ char *cs = NULL;
+ char *filebase;
+ int pathlen;
+
+ filebase = basename(filename);
+ pathlen = filebase - filename;
+
+ /*
+ * Put any leading path into `s'.
+ * Leave room in lbuf for the diff command.
+ */
+ s = lbuf + 20;
+ strncpy(s, filename, pathlen);
#define try(f, a1, a2) (Sprintf(s + pathlen, f, a1, a2), stat(s, &cstat) == 0)
#define try1(f, a1) (Sprintf(s + pathlen, f, a1), stat(s, &cstat) == 0)
- if ( try("RCS/%s%s", filebase, RCSSUFFIX)
- || try1("RCS/%s" , filebase)
- || try( "%s%s", filebase, RCSSUFFIX)) {
- Sprintf(buf, CHECKOUT, filename);
- Sprintf(lbuf, RCSDIFF, filename);
- cs = "RCS";
- } else if ( try("SCCS/%s%s", SCCSPREFIX, filebase)
- || try( "%s%s", SCCSPREFIX, filebase)) {
- Sprintf(buf, GET, s);
- Sprintf(lbuf, SCCSDIFF, s, filename);
- cs = "SCCS";
- } else if (statfailed)
- fatal("can't find %s\n", filename);
- /* else we can't write to it but it's not under a version
- control system, so just proceed. */
- if (cs) {
- if (!statfailed) {
- if ((filestat.st_mode & 0222) != 0)
- /* The owner can write to it. */
- fatal("file %s seems to be locked by somebody else under %s\n",
- filename, cs);
- /* It might be checked out unlocked. See if it's safe to
- check out the default version locked. */
- if (verbose)
- say("Comparing file %s to default %s version...\n",
- filename, cs);
- if (system(lbuf))
- fatal("can't check out file %s: differs from default %s version\n",
- filename, cs);
- }
- if (verbose)
- say("Checking out file %s from %s...\n", filename, cs);
- if (system(buf) || stat(filename, &filestat))
- fatal("can't check out file %s from %s\n", filename, cs);
+ if (try("RCS/%s%s", filebase, RCSSUFFIX) ||
+ try1("RCS/%s" , filebase) ||
+ try("%s%s", filebase, RCSSUFFIX)) {
+ Sprintf(buf, CHECKOUT, filename);
+ Sprintf(lbuf, RCSDIFF, filename);
+ cs = "RCS";
+ } else if (try("SCCS/%s%s", SCCSPREFIX, filebase) ||
+ try("%s%s", SCCSPREFIX, filebase)) {
+ Sprintf(buf, GET, s);
+ Sprintf(lbuf, SCCSDIFF, s, filename);
+ cs = "SCCS";
+ } else if (statfailed)
+ fatal("can't find %s\n", filename);
+ /*
+ * else we can't write to it but it's not under a version
+ * control system, so just proceed.
+ */
+ if (cs) {
+ if (!statfailed) {
+ if ((filestat.st_mode & 0222) != 0)
+ /* The owner can write to it. */
+ fatal(
+"file %s seems to be locked by somebody else under %s\n",
+ filename, cs);
+ /*
+ * It might be checked out unlocked. See if
+ * it's safe to check out the default version
+ * locked.
+ */
+ if (verbose)
+ say(
+"Comparing file %s to default %s version...\n",
+ filename, cs);
+ if (system(lbuf))
+ fatal(
+"can't check out file %s: differs from default %s version\n",
+ filename, cs);
+ }
+ if (verbose)
+ say("Checking out file %s from %s...\n",
+ filename, cs);
+ if (system(buf) || stat(filename, &filestat))
+ fatal("can't check out file %s from %s\n",
+ filename, cs);
+ }
+ }
+ if (old_file_is_dev_null &&
+ ok_to_create_file &&
+ (filestat.st_size != 0)) {
+ fatal(
+"patch creates new file but existing file %s not empty\n",
+ filename);
}
- }
- if (old_file_is_dev_null && ok_to_create_file && (filestat.st_size != 0)) {
- fatal("patch creates new file but existing file %s not empty\n",
- filename);
- }
-
- filemode = filestat.st_mode;
- if (!S_ISREG(filemode))
- fatal("%s is not a normal file--can't patch\n", filename);
- i_size = filestat.st_size;
- if (out_of_mem) {
- set_hunkmax(); /* make sure dynamic arrays are allocated */
- out_of_mem = FALSE;
- return FALSE; /* force plan b because plan a bombed */
- }
- i_womp = malloc(i_size+2);
- if (i_womp == NULL)
- return FALSE;
- if ((ifd = open(filename, 0)) < 0)
- pfatal("can't open file %s", filename);
- if (read(ifd, i_womp, i_size) != i_size) {
- Close(ifd); /* probably means i_size > 15 or 16 bits worth */
- free(i_womp); /* at this point it doesn't matter if i_womp was */
- return FALSE; /* undersized. */
+ filemode = filestat.st_mode;
+ if (!S_ISREG(filemode))
+ fatal("%s is not a normal file--can't patch\n", filename);
+ i_size = filestat.st_size;
+ if (out_of_mem) {
+ set_hunkmax(); /* make sure dynamic arrays are allocated */
+ out_of_mem = FALSE;
+ return FALSE; /* force plan b because plan a bombed */
}
- Close(ifd);
- if (i_size && i_womp[i_size-1] != '\n')
- i_womp[i_size++] = '\n';
- i_womp[i_size] = '\0';
-
- /* count the lines in the buffer so we know how many pointers we need */
- iline = 0;
- for (s=i_womp; *s; s++) {
- if (*s == '\n')
- iline++;
- }
- i_ptr = malloc((iline + 2) * sizeof(char *));
- if (i_ptr == NULL) { /* shucks, it was a near thing */
- free(i_womp);
- return FALSE;
- }
+ i_womp = malloc(i_size + 2);
+ if (i_womp == NULL)
+ return FALSE;
+ if ((ifd = open(filename, 0)) < 0)
+ pfatal("can't open file %s", filename);
+ if (read(ifd, i_womp, i_size) != i_size) {
+ /*
+ * This probably means i_size > 15 or 16 bits worth at this
+ * point it doesn't matter if i_womp was undersized.
+ */
+ Close(ifd);
+ free(i_womp);
+ return FALSE;
+ }
+ Close(ifd);
+ if (i_size && i_womp[i_size - 1] != '\n')
+ i_womp[i_size++] = '\n';
+ i_womp[i_size] = '\0';
+
+ /*
+ * Count the lines in the buffer so we know how many pointers we
+ * need.
+ */
+ iline = 0;
+ for (s = i_womp; *s; s++) {
+ if (*s == '\n')
+ iline++;
+ }
+ i_ptr = malloc((iline + 2) * sizeof(char *));
+ if (i_ptr == NULL) { /* shucks, it was a near thing */
+ free(i_womp);
+ return FALSE;
+ }
- /* now scan the buffer and build pointer array */
-
- iline = 1;
- i_ptr[iline] = i_womp;
- for (s=i_womp; *s; s++) {
- if (*s == '\n')
- i_ptr[++iline] = s+1; /* these are NOT null terminated */
- }
- input_lines = iline - 1;
-
- /* now check for revision, if any */
-
- if (revision != NULL) {
- if (!rev_in_string(i_womp)) {
- if (force) {
- if (verbose)
- say(
+ /* Now scan the buffer and build pointer array. */
+ iline = 1;
+ i_ptr[iline] = i_womp;
+ for (s = i_womp; *s; s++) {
+ if (*s == '\n') {
+ /* These are NOT null terminated. */
+ i_ptr[++iline] = s + 1;
+ }
+ }
+ input_lines = iline - 1;
+
+ /* Now check for revision, if any. */
+ if (revision != NULL) {
+ if (!rev_in_string(i_womp)) {
+ if (force) {
+ if (verbose)
+ say(
"Warning: this file doesn't appear to be the %s version--patching anyway.\n",
revision);
- }
- else if (batch) {
- fatal(
+ } else if (batch) {
+ fatal(
"this file doesn't appear to be the %s version--aborting.\n", revision);
- }
- else {
- ask(
+ } else {
+ ask(
"This file doesn't appear to be the %s version--patch anyway? [n] ",
revision);
- if (*buf != 'y')
- fatal("aborted\n");
- }
+ if (*buf != 'y')
+ fatal("aborted\n");
+ }
+ } else if (verbose)
+ say("Good. This file appears to be the %s version.\n",
+ revision);
}
- else if (verbose)
- say("Good. This file appears to be the %s version.\n",
- revision);
- }
- return TRUE; /* plan a will work */
-}
-/* Keep (virtually) nothing in memory. */
+ return TRUE; /* Plan a will work. */
+}
+/*
+ * Keep (virtually) nothing in memory.
+ */
void
plan_b(char *filename)
{
- FILE *ifp;
- int i = 0;
- int maxlen = 1;
- bool found_revision = (revision == NULL);
-
- using_plan_a = FALSE;
- if ((ifp = fopen(filename, "r")) == NULL)
- pfatal("can't open file %s", filename);
- if ((tifd = creat(TMPINNAME, 0666)) < 0)
- pfatal("can't open file %s", TMPINNAME);
- while (fgets(buf, sizeof buf, ifp) != NULL) {
- if (revision != NULL && !found_revision && rev_in_string(buf))
- found_revision = TRUE;
- if ((i = strlen(buf)) > maxlen)
- maxlen = i; /* find longest line */
- }
- if (revision != NULL) {
- if (!found_revision) {
- if (force) {
- if (verbose)
- say(
+ FILE *ifp;
+ int i = 0;
+ int maxlen = 1;
+ bool found_revision = (revision == NULL);
+
+ using_plan_a = FALSE;
+ if ((ifp = fopen(filename, "r")) == NULL)
+ pfatal("can't open file %s", filename);
+ if ((tifd = creat(TMPINNAME, 0666)) < 0)
+ pfatal("can't open file %s", TMPINNAME);
+ while (fgets(buf, sizeof buf, ifp) != NULL) {
+ if (revision != NULL && !found_revision && rev_in_string(buf))
+ found_revision = TRUE;
+ if ((i = strlen(buf)) > maxlen)
+ maxlen = i; /* Find longest line. */
+ }
+ if (revision != NULL) {
+ if (!found_revision) {
+ if (force) {
+ if (verbose)
+ say(
"Warning: this file doesn't appear to be the %s version--patching anyway.\n",
- revision);
- }
- else if (batch) {
- fatal(
+ revision);
+ } else if (batch) {
+ fatal(
"this file doesn't appear to be the %s version--aborting.\n", revision);
- }
- else {
- ask(
+ } else {
+ ask(
"This file doesn't appear to be the %s version--patch anyway? [n] ",
- revision);
- if (*buf != 'y')
- fatal("aborted\n");
- }
+ revision);
+ if (*buf != 'y')
+ fatal("aborted\n");
+ }
+ } else if (verbose)
+ say("Good. This file appears to be the %s version.\n",
+ revision);
}
- else if (verbose)
- say("Good. This file appears to be the %s version.\n",
- revision);
- }
- Fseek(ifp, 0L, 0); /* rewind file */
- lines_per_buf = BUFFERSIZE / maxlen;
- tireclen = maxlen;
- tibuf[0] = malloc(BUFFERSIZE + 1);
- tibuf[1] = malloc(BUFFERSIZE + 1);
- if (tibuf[1] == NULL)
- fatal("out of memory\n");
- for (i=1; ; i++) {
- if (! (i % lines_per_buf)) /* new block */
- if (write(tifd, tibuf[0], BUFFERSIZE) < BUFFERSIZE)
- pfatal("can't write temp file");
- if (fgets(tibuf[0] + maxlen * (i%lines_per_buf), maxlen + 1, ifp)
- == NULL) {
- input_lines = i - 1;
- if (i % lines_per_buf)
- if (write(tifd, tibuf[0], BUFFERSIZE) < BUFFERSIZE)
- pfatal("can't write temp file");
- break;
+ Fseek(ifp, 0L, 0); /* Rewind file. */
+ lines_per_buf = BUFFERSIZE / maxlen;
+ tireclen = maxlen;
+ tibuf[0] = malloc(BUFFERSIZE + 1);
+ tibuf[1] = malloc(BUFFERSIZE + 1);
+ if (tibuf[1] == NULL)
+ fatal("out of memory\n");
+ for (i = 1; ; i++) {
+ if (! (i % lines_per_buf)) /* New block. */
+ if (write(tifd, tibuf[0], BUFFERSIZE) < BUFFERSIZE)
+ pfatal("can't write temp file");
+ if (fgets(tibuf[0] + maxlen * (i % lines_per_buf),
+ maxlen + 1, ifp) == NULL) {
+ input_lines = i - 1;
+ if (i % lines_per_buf)
+ if (write(tifd, tibuf[0], BUFFERSIZE)
+ < BUFFERSIZE)
+ pfatal("can't write temp file");
+ break;
+ }
+ }
+ Fclose(ifp);
+ Close(tifd);
+ if ((tifd = open(TMPINNAME, 0)) < 0) {
+ pfatal("can't reopen file %s", TMPINNAME);
}
- }
- Fclose(ifp);
- Close(tifd);
- if ((tifd = open(TMPINNAME, 0)) < 0) {
- pfatal("can't reopen file %s", TMPINNAME);
- }
}
-/* Fetch a line from the input file, \n terminated, not necessarily \0. */
-
+/*
+ * Fetch a line from the input file, \n terminated, not necessarily \0.
+ */
char *
ifetch(LINENUM line, int whichbuf)
{
- if (line < 1 || line > input_lines)
- return "";
- if (using_plan_a)
- return i_ptr[line];
- else {
- LINENUM offline = line % lines_per_buf;
- LINENUM baseline = line - offline;
-
- if (tiline[0] == baseline)
- whichbuf = 0;
- else if (tiline[1] == baseline)
- whichbuf = 1;
+ if (line < 1 || line > input_lines)
+ return "";
+ if (using_plan_a)
+ return i_ptr[line];
else {
- tiline[whichbuf] = baseline;
- Lseek(tifd, baseline / lines_per_buf * BUFFERSIZE, 0);
- if (read(tifd, tibuf[whichbuf], BUFFERSIZE) < 0)
- pfatal("error reading tmp file %s", TMPINNAME);
+ LINENUM offline = line % lines_per_buf;
+ LINENUM baseline = line - offline;
+
+ if (tiline[0] == baseline)
+ whichbuf = 0;
+ else if (tiline[1] == baseline)
+ whichbuf = 1;
+ else {
+ tiline[whichbuf] = baseline;
+ Lseek(tifd, baseline / lines_per_buf * BUFFERSIZE, 0);
+ if (read(tifd, tibuf[whichbuf], BUFFERSIZE) < 0)
+ pfatal("error reading tmp file %s", TMPINNAME);
+ }
+ return tibuf[whichbuf] + (tireclen * offline);
}
- return tibuf[whichbuf] + (tireclen*offline);
- }
}
-/* True if the string argument contains the revision number we want. */
-
+/*
+ * True if the string argument contains the revision number we want.
+ */
bool
rev_in_string(char *string)
{
- char *s;
- int patlen;
-
- if (revision == NULL)
- return TRUE;
- patlen = strlen(revision);
- if (strnEQ(string,revision,patlen) && isspace((unsigned char)string[patlen]))
- return TRUE;
- for (s = string; *s; s++) {
- if (isspace((unsigned char)*s) && strnEQ(s+1, revision, patlen) &&
- isspace((unsigned char)s[patlen+1] )) {
- return TRUE;
+ char *s;
+ int patlen;
+
+ if (revision == NULL)
+ return TRUE;
+ patlen = strlen(revision);
+ if (strnEQ(string,revision,patlen) &&
+ isspace((unsigned char)string[patlen]))
+ return TRUE;
+ for (s = string; *s; s++) {
+ if (isspace((unsigned char)*s) &&
+ strnEQ(s + 1, revision, patlen) &&
+ isspace((unsigned char)s[patlen + 1] )) {
+ return TRUE;
+ }
}
- }
return FALSE;
}
diff --git a/usr.bin/patch/util.c b/usr.bin/patch/util.c
index 8bc688fde27..dd6b317fc8c 100644
--- a/usr.bin/patch/util.c
+++ b/usr.bin/patch/util.c
@@ -1,7 +1,7 @@
-/* $NetBSD: util.c,v 1.10 2002/03/11 18:47:51 kristerw Exp $ */
+/* $NetBSD: util.c,v 1.11 2002/03/11 23:29:02 kristerw Exp $ */
#include <sys/cdefs.h>
#ifndef lint
-__RCSID("$NetBSD: util.c,v 1.10 2002/03/11 18:47:51 kristerw Exp $");
+__RCSID("$NetBSD: util.c,v 1.11 2002/03/11 23:29:02 kristerw Exp $");
#endif /* not lint */
#include "EXTERN.h"
@@ -15,402 +15,429 @@ __RCSID("$NetBSD: util.c,v 1.10 2002/03/11 18:47:51 kristerw Exp $");
#include <unistd.h>
#include <fcntl.h>
-/* Rename a file, copying it if necessary. */
-
+/*
+ * Rename a file, copying it if necessary.
+ */
int
move_file(char *from, char *to)
{
- char bakname[512];
- char *s;
- int i;
- int fromfd;
+ char bakname[512];
+ char *s;
+ int i;
+ int fromfd;
- /* to stdout? */
+ /* to stdout? */
- if (strEQ(to, "-")) {
+ if (strEQ(to, "-")) {
#ifdef DEBUGGING
- if (debug & 4)
- say("Moving %s to stdout.\n", from);
+ if (debug & 4)
+ say("Moving %s to stdout.\n", from);
#endif
- fromfd = open(from, 0);
- if (fromfd < 0)
- pfatal("internal error, can't reopen %s", from);
- while ((i=read(fromfd, buf, sizeof buf)) > 0)
- if (write(1, buf, i) != 1)
- pfatal("write failed");
- Close(fromfd);
- return 0;
- }
+ fromfd = open(from, 0);
+ if (fromfd < 0)
+ pfatal("internal error, can't reopen %s", from);
+ while ((i = read(fromfd, buf, sizeof buf)) > 0)
+ if (write(1, buf, i) != 1)
+ pfatal("write failed");
+ Close(fromfd);
+ return 0;
+ }
- if (origprae) {
- Strcpy(bakname, origprae);
- Strcat(bakname, to);
- } else {
+ if (origprae) {
+ Strcpy(bakname, origprae);
+ Strcat(bakname, to);
+ } else {
#ifndef NODIR
- char *backupname = find_backup_file_name(to);
- if (backupname == (char *) 0)
- fatal("out of memory\n");
- Strcpy(bakname, backupname);
- free(backupname);
+ char *backupname = find_backup_file_name(to);
+ if (backupname == NULL)
+ fatal("out of memory\n");
+ Strcpy(bakname, backupname);
+ free(backupname);
#else /* NODIR */
- Strcpy(bakname, to);
- Strcat(bakname, simple_backup_suffix);
+ Strcpy(bakname, to);
+ Strcat(bakname, simple_backup_suffix);
#endif /* NODIR */
- }
+ }
- if (stat(to, &filestat) == 0) { /* output file exists */
- dev_t to_device = filestat.st_dev;
- ino_t to_inode = filestat.st_ino;
- char *simplename = bakname;
+ if (stat(to, &filestat) == 0) { /* output file exists */
+ dev_t to_device = filestat.st_dev;
+ ino_t to_inode = filestat.st_ino;
+ char *simplename = bakname;
- for (s=bakname; *s; s++) {
- if (*s == '/')
- simplename = s+1;
- }
- /* Find a backup name that is not the same file.
- Change the first lowercase char into uppercase;
- if that isn't sufficient, chop off the first char and try again. */
- while (stat(bakname, &filestat) == 0 &&
- to_device == filestat.st_dev && to_inode == filestat.st_ino) {
- /* Skip initial non-lowercase chars. */
- for (s=simplename; *s && !islower((unsigned char)*s); s++) ;
- if (*s)
- *s = toupper(*s);
- else
- Strcpy(simplename, simplename+1);
- }
- while (unlink(bakname) >= 0) ; /* while() is for benefit of Eunice */
+ for (s = bakname; *s; s++) {
+ if (*s == '/')
+ simplename = s + 1;
+ }
+ /*
+ * Find a backup name that is not the same file.
+ * Change the first lowercase char into uppercase;
+ * if that isn't sufficient, chop off the first char
+ * and try again.
+ */
+ while (stat(bakname, &filestat) == 0 &&
+ to_device == filestat.st_dev &&
+ to_inode == filestat.st_ino) {
+ /* Skip initial non-lowercase chars. */
+ for (s = simplename;
+ *s && !islower((unsigned char)*s);
+ s++)
+ ;
+ if (*s)
+ *s = toupper(*s);
+ else
+ Strcpy(simplename, simplename + 1);
+ }
+ while (unlink(bakname) >= 0)
+ ; /* while() is for benefit of Eunice */
#ifdef DEBUGGING
- if (debug & 4)
- say("Moving %s to %s.\n", to, bakname);
+ if (debug & 4)
+ say("Moving %s to %s.\n", to, bakname);
#endif
- if (link(to, bakname) < 0) {
- /* Maybe `to' is a symlink into a different file system.
- Copying replaces the symlink with a file; using rename
- would be better. */
- int tofd;
- int bakfd;
-
- bakfd = creat(bakname, 0666);
- if (bakfd < 0) {
- say("Can't backup %s, output is in %s: %s\n", to, from,
- strerror(errno));
- return -1;
- }
- tofd = open(to, 0);
- if (tofd < 0)
- pfatal("internal error, can't open %s", to);
- while ((i=read(tofd, buf, sizeof buf)) > 0)
- if (write(bakfd, buf, i) != i)
- pfatal("write failed");
- Close(tofd);
- Close(bakfd);
+ if (link(to, bakname) < 0) {
+ /*
+ * Maybe `to' is a symlink into a different file
+ * system. Copying replaces the symlink with a file;
+ * using rename would be better.
+ */
+ int tofd;
+ int bakfd;
+
+ bakfd = creat(bakname, 0666);
+ if (bakfd < 0) {
+ say("Can't backup %s, output is in %s: %s\n",
+ to, from, strerror(errno));
+ return -1;
+ }
+ tofd = open(to, 0);
+ if (tofd < 0)
+ pfatal("internal error, can't open %s", to);
+ while ((i = read(tofd, buf, sizeof buf)) > 0)
+ if (write(bakfd, buf, i) != i)
+ pfatal("write failed");
+ Close(tofd);
+ Close(bakfd);
+ }
+ while (unlink(to) >= 0) ;
}
- while (unlink(to) >= 0) ;
- }
#ifdef DEBUGGING
- if (debug & 4)
- say("Moving %s to %s.\n", from, to);
+ if (debug & 4)
+ say("Moving %s to %s.\n", from, to);
#endif
- if (link(from, to) < 0) { /* different file system? */
- int tofd;
-
- tofd = creat(to, 0666);
- if (tofd < 0) {
- say("Can't create %s, output is in %s: %s\n",
- to, from, strerror(errno));
- return -1;
+ if (link(from, to) < 0) { /* different file system? */
+ int tofd;
+
+ tofd = creat(to, 0666);
+ if (tofd < 0) {
+ say("Can't create %s, output is in %s: %s\n",
+ to, from, strerror(errno));
+ return -1;
+ }
+ fromfd = open(from, 0);
+ if (fromfd < 0)
+ pfatal("internal error, can't reopen %s", from);
+ while ((i = read(fromfd, buf, sizeof buf)) > 0)
+ if (write(tofd, buf, i) != i)
+ pfatal("write failed");
+ Close(fromfd);
+ Close(tofd);
}
- fromfd = open(from, 0);
- if (fromfd < 0)
- pfatal("internal error, can't reopen %s", from);
- while ((i=read(fromfd, buf, sizeof buf)) > 0)
- if (write(tofd, buf, i) != i)
- pfatal("write failed");
- Close(fromfd);
- Close(tofd);
- }
- Unlink(from);
- return 0;
+ Unlink(from);
+ return 0;
}
-/* Copy a file. */
-
+/*
+ * Copy a file.
+ */
void
copy_file(char *from, char *to)
{
- int tofd;
- int fromfd;
- int i;
-
- tofd = creat(to, 0666);
- if (tofd < 0)
- pfatal("can't create %s", to);
- fromfd = open(from, 0);
- if (fromfd < 0)
- pfatal("internal error, can't reopen %s", from);
- while ((i=read(fromfd, buf, sizeof buf)) > 0)
- if (write(tofd, buf, i) != i)
- pfatal("write to %s failed", to);
- Close(fromfd);
- Close(tofd);
-}
+ int tofd;
+ int fromfd;
+ int i;
-/* Allocate a unique area for a string. */
+ tofd = creat(to, 0666);
+ if (tofd < 0)
+ pfatal("can't create %s", to);
+ fromfd = open(from, 0);
+ if (fromfd < 0)
+ pfatal("internal error, can't reopen %s", from);
+ while ((i = read(fromfd, buf, sizeof buf)) > 0)
+ if (write(tofd, buf, i) != i)
+ pfatal("write to %s failed", to);
+ Close(fromfd);
+ Close(tofd);
+}
+/*
+ * Allocate a unique area for a string.
+ */
char *
savestr(char *s)
{
- char *rv;
- char *t;
-
- if (!s)
- s = "Oops";
- t = s;
- while (*t++);
- rv = malloc(t - s);
- if (rv == NULL) {
- if (using_plan_a)
- out_of_mem = TRUE;
- else
- fatal("out of memory\n");
- }
- else {
- t = rv;
- while ((*t++ = *s++) != '\0');
- }
- return rv;
+ char *rv;
+ char *t;
+
+ if (!s)
+ s = "Oops";
+ t = s;
+ while (*t++)
+ ;
+ rv = malloc(t - s);
+ if (rv == NULL) {
+ if (using_plan_a)
+ out_of_mem = TRUE;
+ else
+ fatal("out of memory\n");
+ } else {
+ t = rv;
+ while ((*t++ = *s++) != '\0');
+ }
+ return rv;
}
-/* Vanilla terminal output (buffered). */
-
+/*
+ * Vanilla terminal output (buffered).
+ */
void
say(const char *pat, ...)
{
- va_list ap;
- va_start(ap, pat);
+ va_list ap;
+ va_start(ap, pat);
- vfprintf(stderr, pat, ap);
- va_end(ap);
- Fflush(stderr);
+ vfprintf(stderr, pat, ap);
+ va_end(ap);
+ Fflush(stderr);
}
-/* Terminal output, pun intended. */
-
+/*
+ * Terminal output, pun intended.
+ */
void /* very void */
fatal(const char *pat, ...)
{
- va_list ap;
- va_start(ap, pat);
+ va_list ap;
+ va_start(ap, pat);
- fprintf(stderr, "patch: **** ");
- vfprintf(stderr, pat, ap);
- va_end(ap);
- my_exit(1);
+ fprintf(stderr, "patch: **** ");
+ vfprintf(stderr, pat, ap);
+ va_end(ap);
+ my_exit(1);
}
-/* Say something from patch, something from the system, then silence . . . */
-
+/*
+ * Say something from patch, something from the system, then silence...
+ */
void /* very void */
pfatal(const char *pat, ...)
{
- va_list ap;
- int errnum = errno;
- va_start(ap, pat);
+ va_list ap;
+ int errnum = errno;
+ va_start(ap, pat);
- fprintf(stderr, "patch: **** ");
- vfprintf(stderr, pat, ap);
- fprintf(stderr, ": %s\n", strerror(errnum));
- va_end(ap);
- my_exit(1);
+ fprintf(stderr, "patch: **** ");
+ vfprintf(stderr, pat, ap);
+ fprintf(stderr, ": %s\n", strerror(errnum));
+ va_end(ap);
+ my_exit(1);
}
-/* Get a response from the user, somehow or other. */
+/*
+ * Get a response from the user, somehow or other.
+ */
void
ask(const char *pat, ...)
{
- int ttyfd;
- int r;
- bool tty2 = isatty(2);
- va_list ap;
- va_start(ap, pat);
-
- (void) vsprintf(buf, pat, ap);
- va_end(ap);
- Fflush(stderr);
- write(2, buf, strlen(buf));
- if (tty2) { /* might be redirected to a file */
- r = read(2, buf, sizeof buf);
- }
- else if (isatty(1)) { /* this may be new file output */
- Fflush(stdout);
- write(1, buf, strlen(buf));
- r = read(1, buf, sizeof buf);
- }
- else if ((ttyfd = open("/dev/tty", 2)) >= 0 && isatty(ttyfd)) {
+ int ttyfd;
+ int r;
+ bool tty2 = isatty(2);
+ va_list ap;
+ va_start(ap, pat);
+
+ (void)vsprintf(buf, pat, ap);
+ va_end(ap);
+ Fflush(stderr);
+ write(2, buf, strlen(buf));
+ if (tty2) { /* might be redirected to a file */
+ r = read(2, buf, sizeof buf);
+ } else if (isatty(1)) { /* this may be new file output */
+ Fflush(stdout);
+ write(1, buf, strlen(buf));
+ r = read(1, buf, sizeof buf);
+ } else if ((ttyfd = open("/dev/tty", 2)) >= 0 && isatty(ttyfd)) {
/* might be deleted or unwriteable */
- write(ttyfd, buf, strlen(buf));
- r = read(ttyfd, buf, sizeof buf);
- Close(ttyfd);
- }
- else if (isatty(0)) { /* this is probably patch input */
- Fflush(stdin);
- write(0, buf, strlen(buf));
- r = read(0, buf, sizeof buf);
- }
- else { /* no terminal at all--default it */
- buf[0] = '\n';
- r = 1;
- }
- if (r <= 0)
- buf[0] = 0;
- else
- buf[r] = '\0';
- if (!tty2)
- say("%s",buf);
+ write(ttyfd, buf, strlen(buf));
+ r = read(ttyfd, buf, sizeof buf);
+ Close(ttyfd);
+ } else if (isatty(0)) { /* this is probably patch input */
+ Fflush(stdin);
+ write(0, buf, strlen(buf));
+ r = read(0, buf, sizeof buf);
+ } else { /* no terminal at all--default it */
+ buf[0] = '\n';
+ r = 1;
+ }
+ if (r <= 0)
+ buf[0] = 0;
+ else
+ buf[r] = '\0';
+ if (!tty2)
+ say("%s", buf);
}
-/* How to handle certain events when not in a critical region. */
-
+/*
+ * How to handle certain events when not in a critical region.
+ */
void
set_signals(int reset)
{
- static void (*hupval)(int),(*intval)(int);
-
- if (!reset) {
- hupval = signal(SIGHUP, SIG_IGN);
- if (hupval != SIG_IGN)
- hupval = my_exit;
- intval = signal(SIGINT, SIG_IGN);
- if (intval != SIG_IGN)
- intval = my_exit;
- }
- Signal(SIGHUP, hupval);
- Signal(SIGINT, intval);
+ static void (*hupval)(int);
+ static void (*intval)(int);
+
+ if (!reset) {
+ hupval = signal(SIGHUP, SIG_IGN);
+ if (hupval != SIG_IGN)
+ hupval = my_exit;
+ intval = signal(SIGINT, SIG_IGN);
+ if (intval != SIG_IGN)
+ intval = my_exit;
+ }
+ Signal(SIGHUP, hupval);
+ Signal(SIGINT, intval);
}
-/* How to handle certain events when in a critical region. */
-
+/*
+ * How to handle certain events when in a critical region.
+ */
void
ignore_signals()
{
- Signal(SIGHUP, SIG_IGN);
- Signal(SIGINT, SIG_IGN);
+ Signal(SIGHUP, SIG_IGN);
+ Signal(SIGINT, SIG_IGN);
}
-/* Make sure we'll have the directories to create a file.
- If `striplast' is TRUE, ignore the last element of `filename'. */
-
+/*
+ * Make sure we'll have the directories to create a file.
+ * If `striplast' is TRUE, ignore the last element of `filename'.
+ */
void
makedirs(char *filename, bool striplast)
{
- char tmpbuf[256];
- char *s = tmpbuf;
- char *dirv[20]; /* Point to the NULs between elements. */
- int i;
- int dirvp = 0; /* Number of finished entries in dirv. */
-
- /* Copy `filename' into `tmpbuf' with a NUL instead of a slash
- between the directories. */
- while (*filename) {
- if (*filename == '/') {
- filename++;
- dirv[dirvp++] = s;
- *s++ = '\0';
- }
- else {
- *s++ = *filename++;
+ char tmpbuf[256];
+ char *s = tmpbuf;
+ char *dirv[20]; /* Point to the NULs between elements. */
+ int i;
+ int dirvp = 0; /* Number of finished entries in dirv. */
+
+ /*
+ * Copy `filename' into `tmpbuf' with a NUL instead of a slash
+ * between the directories.
+ */
+ while (*filename) {
+ if (*filename == '/') {
+ filename++;
+ dirv[dirvp++] = s;
+ *s++ = '\0';
+ } else {
+ *s++ = *filename++;
+ }
}
- }
- *s = '\0';
- dirv[dirvp] = s;
- if (striplast)
- dirvp--;
- if (dirvp < 0)
- return;
-
- strcpy(buf, "mkdir");
- s = buf;
- for (i=0; i<=dirvp; i++) {
- struct stat sbuf;
-
- if (stat(tmpbuf, &sbuf) && errno == ENOENT) {
- while (*s) s++;
- *s++ = ' ';
- strcpy(s, tmpbuf);
+ *s = '\0';
+ dirv[dirvp] = s;
+ if (striplast)
+ dirvp--;
+ if (dirvp < 0)
+ return;
+
+ strcpy(buf, "mkdir");
+ s = buf;
+ for (i = 0; i <= dirvp; i++) {
+ struct stat sbuf;
+
+ if (stat(tmpbuf, &sbuf) && errno == ENOENT) {
+ while (*s)
+ s++;
+ *s++ = ' ';
+ strcpy(s, tmpbuf);
+ }
+ *dirv[i] = '/';
}
- *dirv[i] = '/';
- }
- if (s != buf)
- system(buf);
+ if (s != buf)
+ system(buf);
}
-/* Make filenames more reasonable. */
-
+/*
+ * Make filenames more reasonable.
+ */
char *
fetchname(char *at, int strip_leading, int assume_exists)
{
- char *fullname;
- char *name;
- char *t;
- char tmpbuf[200];
- int sleading = strip_leading;
-
- if (!at)
- return NULL;
- while (isspace((unsigned char)*at))
- at++;
+ char *fullname;
+ char *name;
+ char *t;
+ char tmpbuf[200];
+ int sleading = strip_leading;
+
+ if (!at)
+ return NULL;
+ while (isspace((unsigned char)*at))
+ at++;
#ifdef DEBUGGING
- if (debug & 128)
- say("fetchname %s %d %d\n",at,strip_leading,assume_exists);
+ if (debug & 128)
+ say("fetchname %s %d %d\n", at, strip_leading, assume_exists);
#endif
- filename_is_dev_null = FALSE;
- if (strnEQ(at, "/dev/null", 9)) { /* so files can be created by diffing */
- filename_is_dev_null = TRUE;
- return NULL; /* against /dev/null. */
- }
- name = fullname = t = savestr(at);
-
- /* Strip off up to `sleading' leading slashes and null terminate. */
- for (; *t && !isspace((unsigned char)*t); t++)
- if (*t == '/')
- if (--sleading >= 0)
- name = t+1;
- *t = '\0';
-
- /* If no -p option was given (957 is the default value!),
- we were given a relative pathname,
- and the leading directories that we just stripped off all exist,
- put them back on. */
- if (strip_leading == 957 && name != fullname && *fullname != '/') {
- name[-1] = '\0';
- if (stat(fullname, &filestat) == 0 && S_ISDIR (filestat.st_mode)) {
- name[-1] = '/';
- name=fullname;
+ filename_is_dev_null = FALSE;
+ if (strnEQ(at, "/dev/null", 9)) {
+ /* So files can be created by diffing against /dev/null. */
+ filename_is_dev_null = TRUE;
+ return NULL;
+ }
+ name = fullname = t = savestr(at);
+
+ /* Strip off up to `sleading' leading slashes and null terminate. */
+ for (; *t && !isspace((unsigned char)*t); t++)
+ if (*t == '/')
+ if (--sleading >= 0)
+ name = t + 1;
+ *t = '\0';
+
+ /*
+ * If no -p option was given (957 is the default value!),
+ * we were given a relative pathname,
+ * and the leading directories that we just stripped off all exist,
+ * put them back on.
+ */
+ if (strip_leading == 957 && name != fullname && *fullname != '/') {
+ name[-1] = '\0';
+ if (stat(fullname, &filestat) == 0 &&
+ S_ISDIR(filestat.st_mode)) {
+ name[-1] = '/';
+ name = fullname;
+ }
}
- }
-
- name = savestr(name);
- free(fullname);
-
- if (stat(name, &filestat) && !assume_exists) {
- char *filebase = basename(name);
- int pathlen = filebase - name;
-
- /* Put any leading path into `tmpbuf'. */
- strncpy(tmpbuf, name, pathlen);
-
-#define try(f, a1, a2) (Sprintf(tmpbuf + pathlen, f, a1, a2), stat(tmpbuf, &filestat) == 0)
-#define try1(f, a1) (Sprintf(tmpbuf + pathlen, f, a1), stat(tmpbuf, &filestat) == 0)
- if ( try("RCS/%s%s", filebase, RCSSUFFIX)
- || try1("RCS/%s" , filebase)
- || try( "%s%s", filebase, RCSSUFFIX)
- || try("SCCS/%s%s", SCCSPREFIX, filebase)
- || try( "%s%s", SCCSPREFIX, filebase))
- return name;
- free(name);
- name = NULL;
- }
-
- return name;
+
+ name = savestr(name);
+ free(fullname);
+
+ if (stat(name, &filestat) && !assume_exists) {
+ char *filebase = basename(name);
+ int pathlen = filebase - name;
+
+ /* Put any leading path into `tmpbuf'. */
+ strncpy(tmpbuf, name, pathlen);
+
+#define try(f, a1, a2) \
+ (Sprintf(tmpbuf + pathlen, f, a1, a2), stat(tmpbuf, &filestat) == 0)
+#define try1(f, a1) \
+ (Sprintf(tmpbuf + pathlen, f, a1), stat(tmpbuf, &filestat) == 0)
+ if (try("RCS/%s%s", filebase, RCSSUFFIX) ||
+ try1("RCS/%s" , filebase) ||
+ try( "%s%s", filebase, RCSSUFFIX) ||
+ try("SCCS/%s%s", SCCSPREFIX, filebase) ||
+ try( "%s%s", SCCSPREFIX, filebase))
+ return name;
+ free(name);
+ name = NULL;
+ }
+
+ return name;
}