inp.c (416ba5c74546f32a993436a99516d35008e9f384) inp.c (1e3e581593b6484569a2e6570329db4e2306f6cf)
1/*-
2 * Copyright 1986, Larry Wall
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following condition is met:
6 * 1. Redistributions of source code must retain the above copyright notice,
7 * this condition and the following disclaimer.
8 *

--- 17 unchanged lines hidden (view full) ---

26 * $OpenBSD: inp.c,v 1.36 2012/04/10 14:46:34 ajacoutot Exp $
27 * $FreeBSD$
28 */
29
30#include <sys/types.h>
31#include <sys/file.h>
32#include <sys/stat.h>
33#include <sys/mman.h>
1/*-
2 * Copyright 1986, Larry Wall
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following condition is met:
6 * 1. Redistributions of source code must retain the above copyright notice,
7 * this condition and the following disclaimer.
8 *

--- 17 unchanged lines hidden (view full) ---

26 * $OpenBSD: inp.c,v 1.36 2012/04/10 14:46:34 ajacoutot Exp $
27 * $FreeBSD$
28 */
29
30#include <sys/types.h>
31#include <sys/file.h>
32#include <sys/stat.h>
33#include <sys/mman.h>
34#include <sys/wait.h>
34
35#include <ctype.h>
35
36#include <ctype.h>
37#include <errno.h>
36#include <libgen.h>
37#include <stddef.h>
38#include <stdint.h>
39#include <stdio.h>
40#include <stdlib.h>
41#include <string.h>
42#include <unistd.h>
43

--- 84 unchanged lines hidden (view full) ---

128 return true;
129}
130
131/* Try keeping everything in memory. */
132
133static bool
134plan_a(const char *filename)
135{
38#include <libgen.h>
39#include <stddef.h>
40#include <stdint.h>
41#include <stdio.h>
42#include <stdlib.h>
43#include <string.h>
44#include <unistd.h>
45

--- 84 unchanged lines hidden (view full) ---

130 return true;
131}
132
133/* Try keeping everything in memory. */
134
135static bool
136plan_a(const char *filename)
137{
136 int ifd, statfailed;
138 int ifd, statfailed, devnull, pstat;
137 char *p, *s, lbuf[INITLINELEN];
138 struct stat filestat;
139 ptrdiff_t sz;
140 size_t i;
141 size_t iline, lines_allocated;
139 char *p, *s, lbuf[INITLINELEN];
140 struct stat filestat;
141 ptrdiff_t sz;
142 size_t i;
143 size_t iline, lines_allocated;
144 pid_t pid;
145 char *argp[4] = {NULL};
142
143#ifdef DEBUGGING
144 if (debug & 8)
145 return false;
146#endif
147
148 if (filename == NULL || *filename == '\0')
149 return false;

--- 11 unchanged lines hidden (view full) ---

161 if (check_only)
162 return true;
163 makedirs(filename, true);
164 close(creat(filename, 0666));
165 statfailed = stat(filename, &filestat);
166 }
167 if (statfailed && check_only)
168 fatal("%s not found, -C mode, can't probe further\n", filename);
146
147#ifdef DEBUGGING
148 if (debug & 8)
149 return false;
150#endif
151
152 if (filename == NULL || *filename == '\0')
153 return false;

--- 11 unchanged lines hidden (view full) ---

165 if (check_only)
166 return true;
167 makedirs(filename, true);
168 close(creat(filename, 0666));
169 statfailed = stat(filename, &filestat);
170 }
171 if (statfailed && check_only)
172 fatal("%s not found, -C mode, can't probe further\n", filename);
169 /* For nonexistent or read-only files, look for RCS or SCCS versions. */
173 /* For nonexistent or read-only files, look for RCS versions. */
174
170 if (statfailed ||
171 /* No one can write to it. */
172 (filestat.st_mode & 0222) == 0 ||
173 /* I can't write to it. */
174 ((filestat.st_mode & 0022) == 0 && filestat.st_uid != getuid())) {
175 if (statfailed ||
176 /* No one can write to it. */
177 (filestat.st_mode & 0222) == 0 ||
178 /* I can't write to it. */
179 ((filestat.st_mode & 0022) == 0 && filestat.st_uid != getuid())) {
175 const char *cs = NULL, *filebase, *filedir;
180 char *filebase, *filedir;
176 struct stat cstat;
177 char *tmp_filename1, *tmp_filename2;
178
179 tmp_filename1 = strdup(filename);
180 tmp_filename2 = strdup(filename);
181 if (tmp_filename1 == NULL || tmp_filename2 == NULL)
182 fatal("strdupping filename");
181 struct stat cstat;
182 char *tmp_filename1, *tmp_filename2;
183
184 tmp_filename1 = strdup(filename);
185 tmp_filename2 = strdup(filename);
186 if (tmp_filename1 == NULL || tmp_filename2 == NULL)
187 fatal("strdupping filename");
188
183 filebase = basename(tmp_filename1);
184 filedir = dirname(tmp_filename2);
185
189 filebase = basename(tmp_filename1);
190 filedir = dirname(tmp_filename2);
191
186 /* Leave room in lbuf for the diff command. */
187 s = lbuf + 20;
188
189#define try(f, a1, a2, a3) \
192#define try(f, a1, a2, a3) \
190 (snprintf(s, buf_size - 20, f, a1, a2, a3), stat(s, &cstat) == 0)
193 (snprintf(lbuf, sizeof(lbuf), f, a1, a2, a3), stat(lbuf, &cstat) == 0)
191
194
192 if (try("%s/RCS/%s%s", filedir, filebase, RCSSUFFIX) ||
193 try("%s/RCS/%s%s", filedir, filebase, "") ||
194 try("%s/%s%s", filedir, filebase, RCSSUFFIX)) {
195 snprintf(buf, buf_size, CHECKOUT, filename);
196 snprintf(lbuf, sizeof lbuf, RCSDIFF, filename);
197 cs = "RCS";
198 } else if (try("%s/SCCS/%s%s", filedir, SCCSPREFIX, filebase) ||
199 try("%s/%s%s", filedir, SCCSPREFIX, filebase)) {
200 snprintf(buf, buf_size, GET, s);
201 snprintf(lbuf, sizeof lbuf, SCCSDIFF, s, filename);
202 cs = "SCCS";
203 } else if (statfailed)
204 fatal("can't find %s\n", filename);
205
206 free(tmp_filename1);
207 free(tmp_filename2);
208
209 /*
210 * else we can't write to it but it's not under a version
211 * control system, so just proceed.
212 */
195 /*
196 * else we can't write to it but it's not under a version
197 * control system, so just proceed.
198 */
213 if (cs) {
199 if (try("%s/RCS/%s%s", filedir, filebase, RCSSUFFIX) ||
200 try("%s/RCS/%s%s", filedir, filebase, "") ||
201 try("%s/%s%s", filedir, filebase, RCSSUFFIX)) {
214 if (!statfailed) {
215 if ((filestat.st_mode & 0222) != 0)
216 /* The owner can write to it. */
217 fatal("file %s seems to be locked "
202 if (!statfailed) {
203 if ((filestat.st_mode & 0222) != 0)
204 /* The owner can write to it. */
205 fatal("file %s seems to be locked "
218 "by somebody else under %s\n",
219 filename, cs);
206 "by somebody else under RCS\n",
207 filename);
220 /*
221 * It might be checked out unlocked. See if
222 * it's safe to check out the default version
223 * locked.
224 */
225 if (verbose)
226 say("Comparing file %s to default "
208 /*
209 * It might be checked out unlocked. See if
210 * it's safe to check out the default version
211 * locked.
212 */
213 if (verbose)
214 say("Comparing file %s to default "
227 "%s version...\n",
228 filename, cs);
229 if (system(lbuf))
215 "RCS version...\n", filename);
216
217 switch (pid = fork()) {
218 case -1:
219 fatal("can't fork: %s\n",
220 strerror(errno));
221 case 0:
222 devnull = open("/dev/null", O_RDONLY);
223 if (devnull == -1) {
224 fatal("can't open /dev/null: %s",
225 strerror(errno));
226 }
227 (void)dup2(devnull, STDOUT_FILENO);
228 argp[0] = strdup(RCSDIFF);
229 argp[1] = strdup(filename);
230 execv(RCSDIFF, argp);
231 exit(127);
232 }
233 pid = waitpid(pid, &pstat, 0);
234 if (pid == -1 || WEXITSTATUS(pstat) != 0) {
230 fatal("can't check out file %s: "
235 fatal("can't check out file %s: "
231 "differs from default %s version\n",
232 filename, cs);
236 "differs from default RCS version\n",
237 filename);
238 }
233 }
239 }
240
234 if (verbose)
241 if (verbose)
235 say("Checking out file %s from %s...\n",
236 filename, cs);
237 if (system(buf) || stat(filename, &filestat))
238 fatal("can't check out file %s from %s\n",
239 filename, cs);
242 say("Checking out file %s from RCS...\n",
243 filename);
244
245 switch (pid = fork()) {
246 case -1:
247 fatal("can't fork: %s\n", strerror(errno));
248 case 0:
249 argp[0] = strdup(CHECKOUT);
250 argp[1] = strdup("-l");
251 argp[2] = strdup(filename);
252 execv(CHECKOUT, argp);
253 exit(127);
254 }
255 pid = waitpid(pid, &pstat, 0);
256 if (pid == -1 || WEXITSTATUS(pstat) != 0 ||
257 stat(filename, &filestat)) {
258 fatal("can't check out file %s from RCS\n",
259 filename);
260 }
261 } else if (statfailed) {
262 fatal("can't find %s\n", filename);
240 }
263 }
264 free(tmp_filename1);
265 free(tmp_filename2);
241 }
266 }
267
242 filemode = filestat.st_mode;
243 if (!S_ISREG(filemode))
244 fatal("%s is not a normal file--can't patch\n", filename);
245 if ((uint64_t)filestat.st_size > SIZE_MAX) {
246 say("block too large to mmap\n");
247 return false;
248 }
249 i_size = (size_t)filestat.st_size;

--- 253 unchanged lines hidden ---
268 filemode = filestat.st_mode;
269 if (!S_ISREG(filemode))
270 fatal("%s is not a normal file--can't patch\n", filename);
271 if ((uint64_t)filestat.st_size > SIZE_MAX) {
272 say("block too large to mmap\n");
273 return false;
274 }
275 i_size = (size_t)filestat.st_size;

--- 253 unchanged lines hidden ---