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 --- |