GCC Code Coverage Report | |||||||||||||||||||||
|
|||||||||||||||||||||
Line | Branch | Exec | Source |
1 |
/* $OpenBSD: checkout.c,v 1.171 2017/06/01 08:08:24 joris Exp $ */ |
||
2 |
/* |
||
3 |
* Copyright (c) 2006 Joris Vink <joris@openbsd.org> |
||
4 |
* |
||
5 |
* Permission to use, copy, modify, and distribute this software for any |
||
6 |
* purpose with or without fee is hereby granted, provided that the above |
||
7 |
* copyright notice and this permission notice appear in all copies. |
||
8 |
* |
||
9 |
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
||
10 |
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
||
11 |
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |
||
12 |
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
||
13 |
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
||
14 |
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
||
15 |
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
||
16 |
*/ |
||
17 |
|||
18 |
#include <sys/types.h> |
||
19 |
#include <sys/dirent.h> |
||
20 |
#include <sys/stat.h> |
||
21 |
#include <sys/time.h> |
||
22 |
|||
23 |
#include <errno.h> |
||
24 |
#include <fcntl.h> |
||
25 |
#include <libgen.h> |
||
26 |
#include <stdlib.h> |
||
27 |
#include <string.h> |
||
28 |
#include <time.h> |
||
29 |
#include <unistd.h> |
||
30 |
|||
31 |
#include "cvs.h" |
||
32 |
#include "diff.h" |
||
33 |
#include "remote.h" |
||
34 |
|||
35 |
static void checkout_check_repository(int, char **); |
||
36 |
static int checkout_classify(const char *, const char *); |
||
37 |
static void checkout_repository(const char *, const char *); |
||
38 |
|||
39 |
extern int print_stdout; |
||
40 |
extern int prune_dirs; |
||
41 |
extern int build_dirs; |
||
42 |
|||
43 |
static int flags = CR_REPO | CR_RECURSE_DIRS; |
||
44 |
static int Aflag = 0; |
||
45 |
static char *dflag = NULL; |
||
46 |
static char *koptstr = NULL; |
||
47 |
static char *dateflag = NULL; |
||
48 |
|||
49 |
static int nflag = 0; |
||
50 |
|||
51 |
char *checkout_target_dir = NULL; |
||
52 |
|||
53 |
time_t cvs_specified_date = -1; |
||
54 |
time_t cvs_directory_date = -1; |
||
55 |
int disable_fast_checkout = 0; |
||
56 |
|||
57 |
struct cvs_cmd cvs_cmd_checkout = { |
||
58 |
CVS_OP_CHECKOUT, CVS_USE_WDIR, "checkout", |
||
59 |
{ "co", "get" }, |
||
60 |
"Checkout a working copy of a repository", |
||
61 |
"[-AcflNnPpRs] [-D date | -r tag] [-d dir] [-j rev] [-k mode] " |
||
62 |
"[-t id] module ...", |
||
63 |
"AcD:d:fj:k:lNnPpRr:st:", |
||
64 |
NULL, |
||
65 |
cvs_checkout |
||
66 |
}; |
||
67 |
|||
68 |
struct cvs_cmd cvs_cmd_export = { |
||
69 |
CVS_OP_EXPORT, CVS_USE_WDIR, "export", |
||
70 |
{ "exp", "ex" }, |
||
71 |
"Export sources from CVS, similar to checkout", |
||
72 |
"[-flNnR] [-d dir] [-k mode] -D date | -r rev module ...", |
||
73 |
"D:d:k:flNnRr:", |
||
74 |
NULL, |
||
75 |
cvs_export |
||
76 |
}; |
||
77 |
|||
78 |
int |
||
79 |
cvs_checkout(int argc, char **argv) |
||
80 |
{ |
||
81 |
int ch; |
||
82 |
|||
83 |
✓✓ | 46 |
while ((ch = getopt(argc, argv, cvs_cmd_checkout.cmd_opts)) != -1) { |
84 |
✓✗✗✗ ✓✗✓✗ ✗✗✓✗ ✓✗ |
20 |
switch (ch) { |
85 |
case 'A': |
||
86 |
Aflag = 1; |
||
87 |
if (koptstr == NULL) |
||
88 |
reset_option = 1; |
||
89 |
if (cvs_specified_tag == NULL) |
||
90 |
reset_tag = 1; |
||
91 |
break; |
||
92 |
case 'c': |
||
93 |
cvs_modules_list(); |
||
94 |
exit(0); |
||
95 |
case 'D': |
||
96 |
dateflag = optarg; |
||
97 |
if ((cvs_specified_date = date_parse(dateflag)) == -1) |
||
98 |
fatal("invalid date: %s", dateflag); |
||
99 |
reset_tag = 0; |
||
100 |
break; |
||
101 |
case 'd': |
||
102 |
✗✓ | 1 |
if (dflag != NULL) |
103 |
fatal("-d specified two or more times"); |
||
104 |
1 |
dflag = optarg; |
|
105 |
1 |
checkout_target_dir = dflag; |
|
106 |
|||
107 |
✓✗ | 1 |
if (cvs_server_active == 1) |
108 |
disable_fast_checkout = 1; |
||
109 |
break; |
||
110 |
case 'j': |
||
111 |
if (cvs_join_rev1 == NULL) |
||
112 |
cvs_join_rev1 = optarg; |
||
113 |
else if (cvs_join_rev2 == NULL) |
||
114 |
cvs_join_rev2 = optarg; |
||
115 |
else |
||
116 |
fatal("too many -j options"); |
||
117 |
break; |
||
118 |
case 'k': |
||
119 |
2 |
reset_option = 0; |
|
120 |
2 |
koptstr = optarg; |
|
121 |
2 |
kflag = rcs_kflag_get(koptstr); |
|
122 |
✓✗✓✗ ✗✗ |
4 |
if (RCS_KWEXP_INVAL(kflag)) { |
123 |
cvs_log(LP_ERR, |
||
124 |
"invalid RCS keyword expansion mode"); |
||
125 |
fatal("%s", cvs_cmd_checkout.cmd_synopsis); |
||
126 |
} |
||
127 |
break; |
||
128 |
case 'l': |
||
129 |
flags &= ~CR_RECURSE_DIRS; |
||
130 |
break; |
||
131 |
case 'N': |
||
132 |
break; |
||
133 |
case 'n': |
||
134 |
nflag = 1; |
||
135 |
break; |
||
136 |
case 'P': |
||
137 |
prune_dirs = 1; |
||
138 |
break; |
||
139 |
case 'p': |
||
140 |
1 |
cmdp->cmd_flags &= ~CVS_USE_WDIR; |
|
141 |
1 |
print_stdout = 1; |
|
142 |
1 |
cvs_noexec = 1; |
|
143 |
1 |
nflag = 1; |
|
144 |
1 |
break; |
|
145 |
case 'R': |
||
146 |
flags |= CR_RECURSE_DIRS; |
||
147 |
break; |
||
148 |
case 'r': |
||
149 |
6 |
reset_tag = 0; |
|
150 |
6 |
cvs_specified_tag = optarg; |
|
151 |
6 |
break; |
|
152 |
default: |
||
153 |
fatal("%s", cvs_cmd_checkout.cmd_synopsis); |
||
154 |
} |
||
155 |
} |
||
156 |
|||
157 |
12 |
argc -= optind; |
|
158 |
12 |
argv += optind; |
|
159 |
|||
160 |
✗✓ | 12 |
if (argc == 0) |
161 |
fatal("%s", cvs_cmd_checkout.cmd_synopsis); |
||
162 |
|||
163 |
✗✓ | 12 |
if (cvs_server_active == 1 && disable_fast_checkout != 1) { |
164 |
cmdp->cmd_flags &= ~CVS_USE_WDIR; |
||
165 |
cvs_noexec = 1; |
||
166 |
} |
||
167 |
|||
168 |
12 |
checkout_check_repository(argc, argv); |
|
169 |
|||
170 |
✗✓ | 12 |
if (cvs_server_active == 1 && disable_fast_checkout != 1) |
171 |
cvs_noexec = 0; |
||
172 |
|||
173 |
12 |
return (0); |
|
174 |
} |
||
175 |
|||
176 |
int |
||
177 |
cvs_export(int argc, char **argv) |
||
178 |
{ |
||
179 |
int ch; |
||
180 |
|||
181 |
2 |
prune_dirs = 1; |
|
182 |
|||
183 |
✓✓ | 3 |
while ((ch = getopt(argc, argv, cvs_cmd_export.cmd_opts)) != -1) { |
184 |
✓✗✗✗ ✗✓✗ |
2 |
switch (ch) { |
185 |
case 'd': |
||
186 |
if (dflag != NULL) |
||
187 |
fatal("-d specified two or more times"); |
||
188 |
dflag = optarg; |
||
189 |
checkout_target_dir = dflag; |
||
190 |
|||
191 |
if (cvs_server_active == 1) |
||
192 |
disable_fast_checkout = 1; |
||
193 |
break; |
||
194 |
case 'k': |
||
195 |
koptstr = optarg; |
||
196 |
kflag = rcs_kflag_get(koptstr); |
||
197 |
if (RCS_KWEXP_INVAL(kflag)) { |
||
198 |
cvs_log(LP_ERR, |
||
199 |
"invalid RCS keyword expansion mode"); |
||
200 |
fatal("%s", cvs_cmd_export.cmd_synopsis); |
||
201 |
} |
||
202 |
break; |
||
203 |
case 'l': |
||
204 |
flags &= ~CR_RECURSE_DIRS; |
||
205 |
break; |
||
206 |
case 'N': |
||
207 |
break; |
||
208 |
case 'R': |
||
209 |
flags |= CR_RECURSE_DIRS; |
||
210 |
break; |
||
211 |
case 'r': |
||
212 |
1 |
cvs_specified_tag = optarg; |
|
213 |
1 |
break; |
|
214 |
default: |
||
215 |
fatal("%s", cvs_cmd_export.cmd_synopsis); |
||
216 |
} |
||
217 |
} |
||
218 |
|||
219 |
1 |
argc -= optind; |
|
220 |
1 |
argv += optind; |
|
221 |
|||
222 |
✗✓ | 1 |
if (cvs_specified_tag == NULL) |
223 |
fatal("must specify a tag or date"); |
||
224 |
|||
225 |
✗✓ | 1 |
if (argc == 0) |
226 |
fatal("%s", cvs_cmd_export.cmd_synopsis); |
||
227 |
|||
228 |
1 |
checkout_check_repository(argc, argv); |
|
229 |
|||
230 |
1 |
return (0); |
|
231 |
} |
||
232 |
|||
233 |
static void |
||
234 |
checkout_check_repository(int argc, char **argv) |
||
235 |
{ |
||
236 |
int i; |
||
237 |
char *wdir, *d; |
||
238 |
26 |
struct cvs_recursion cr; |
|
239 |
struct module_checkout *mc; |
||
240 |
struct cvs_ignpat *ip; |
||
241 |
struct cvs_filelist *fl, *nxt; |
||
242 |
13 |
char repo[PATH_MAX], fpath[PATH_MAX], *f[1]; |
|
243 |
|||
244 |
13 |
build_dirs = print_stdout ? 0 : 1; |
|
245 |
|||
246 |
✗✓ | 13 |
if (cvsroot_is_remote()) { |
247 |
cvs_client_connect_to_server(); |
||
248 |
|||
249 |
if (cvs_specified_tag != NULL) |
||
250 |
cvs_client_send_request("Argument -r%s", |
||
251 |
cvs_specified_tag); |
||
252 |
if (Aflag) |
||
253 |
cvs_client_send_request("Argument -A"); |
||
254 |
|||
255 |
if (dateflag != NULL) |
||
256 |
cvs_client_send_request("Argument -D%s", dateflag); |
||
257 |
|||
258 |
if (kflag) |
||
259 |
cvs_client_send_request("Argument -k%s", koptstr); |
||
260 |
|||
261 |
if (dflag != NULL) |
||
262 |
cvs_client_send_request("Argument -d%s", dflag); |
||
263 |
|||
264 |
if (!(flags & CR_RECURSE_DIRS)) |
||
265 |
cvs_client_send_request("Argument -l"); |
||
266 |
|||
267 |
if (cvs_cmdop == CVS_OP_CHECKOUT && prune_dirs == 1) |
||
268 |
cvs_client_send_request("Argument -P"); |
||
269 |
|||
270 |
if (print_stdout == 1) |
||
271 |
cvs_client_send_request("Argument -p"); |
||
272 |
|||
273 |
if (nflag == 1) |
||
274 |
cvs_client_send_request("Argument -n"); |
||
275 |
|||
276 |
cr.enterdir = NULL; |
||
277 |
cr.leavedir = NULL; |
||
278 |
if (print_stdout) |
||
279 |
cr.fileproc = NULL; |
||
280 |
else |
||
281 |
cr.fileproc = cvs_client_sendfile; |
||
282 |
|||
283 |
flags &= ~CR_REPO; |
||
284 |
cr.flags = flags; |
||
285 |
|||
286 |
if (cvs_cmdop != CVS_OP_EXPORT) |
||
287 |
cvs_file_run(argc, argv, &cr); |
||
288 |
|||
289 |
cvs_client_send_files(argv, argc); |
||
290 |
cvs_client_senddir("."); |
||
291 |
|||
292 |
cvs_client_send_request("%s", |
||
293 |
(cvs_cmdop == CVS_OP_CHECKOUT) ? "co" : "export"); |
||
294 |
|||
295 |
cvs_client_get_responses(); |
||
296 |
|||
297 |
return; |
||
298 |
} |
||
299 |
|||
300 |
✓✓ | 52 |
for (i = 0; i < argc; i++) { |
301 |
13 |
mc = cvs_module_lookup(argv[i]); |
|
302 |
13 |
current_module = mc; |
|
303 |
|||
304 |
✗✓ | 26 |
RB_FOREACH(fl, cvs_flisthead, &(mc->mc_ignores)) |
305 |
cvs_file_ignore(fl->file_path, &checkout_ign_pats); |
||
306 |
|||
307 |
✓✓ | 52 |
RB_FOREACH(fl, cvs_flisthead, &(mc->mc_modules)) { |
308 |
13 |
module_repo_root = NULL; |
|
309 |
|||
310 |
26 |
(void)xsnprintf(repo, sizeof(repo), "%s/%s", |
|
311 |
13 |
current_cvsroot->cr_dir, fl->file_path); |
|
312 |
|||
313 |
✓✓ | 13 |
if (!(mc->mc_flags & MODULE_ALIAS) || dflag != NULL) |
314 |
1 |
module_repo_root = xstrdup(fl->file_path); |
|
315 |
|||
316 |
✗✓ | 13 |
if (mc->mc_flags & MODULE_NORECURSE) |
317 |
flags &= ~CR_RECURSE_DIRS; |
||
318 |
|||
319 |
✓✓ | 13 |
if (dflag != NULL) |
320 |
1 |
wdir = dflag; |
|
321 |
✓✗ | 12 |
else if (mc->mc_flags & MODULE_ALIAS) |
322 |
12 |
wdir = fl->file_path; |
|
323 |
else |
||
324 |
wdir = mc->mc_name; |
||
325 |
|||
326 |
✓✓✓ | 26 |
switch (checkout_classify(repo, fl->file_path)) { |
327 |
case CVS_FILE: |
||
328 |
1 |
cr.fileproc = cvs_update_local; |
|
329 |
1 |
cr.flags = flags; |
|
330 |
|||
331 |
✗✓ | 1 |
if (!(mc->mc_flags & MODULE_ALIAS)) { |
332 |
module_repo_root = |
||
333 |
xstrdup(dirname(fl->file_path)); |
||
334 |
d = wdir; |
||
335 |
(void)xsnprintf(fpath, sizeof(fpath), |
||
336 |
"%s/%s", d, |
||
337 |
basename(fl->file_path)); |
||
338 |
} else { |
||
339 |
1 |
d = dirname(wdir); |
|
340 |
1 |
strlcpy(fpath, fl->file_path, |
|
341 |
sizeof(fpath)); |
||
342 |
} |
||
343 |
|||
344 |
✗✓ | 1 |
if (build_dirs == 1) |
345 |
cvs_mkpath(d, cvs_specified_tag); |
||
346 |
|||
347 |
1 |
f[0] = fpath; |
|
348 |
1 |
cvs_file_run(1, f, &cr); |
|
349 |
1 |
break; |
|
350 |
case CVS_DIR: |
||
351 |
✓✗ | 12 |
if (build_dirs == 1) |
352 |
12 |
cvs_mkpath(wdir, cvs_specified_tag); |
|
353 |
12 |
checkout_repository(repo, wdir); |
|
354 |
12 |
break; |
|
355 |
default: |
||
356 |
break; |
||
357 |
} |
||
358 |
|||
359 |
✓✓✗✓ ✗✗ |
25 |
if (nflag != 1 && mc->mc_prog != NULL && |
360 |
mc->mc_flags & MODULE_RUN_ON_CHECKOUT) |
||
361 |
cvs_exec(mc->mc_prog, NULL, 0); |
||
362 |
|||
363 |
13 |
free(module_repo_root); |
|
364 |
} |
||
365 |
|||
366 |
✓✗ | 13 |
if (mc->mc_canfree == 1) { |
367 |
✓✓ | 52 |
for (fl = RB_MIN(cvs_flisthead, &(mc->mc_modules)); |
368 |
26 |
fl != NULL; fl = nxt) { |
|
369 |
13 |
nxt = RB_NEXT(cvs_flisthead, |
|
370 |
&(mc->mc_modules), fl); |
||
371 |
13 |
RB_REMOVE(cvs_flisthead, |
|
372 |
&(mc->mc_modules), fl); |
||
373 |
13 |
free(fl->file_path); |
|
374 |
13 |
free(fl); |
|
375 |
} |
||
376 |
} |
||
377 |
|||
378 |
✗✓ | 13 |
while ((ip = TAILQ_FIRST(&checkout_ign_pats)) != NULL) { |
379 |
TAILQ_REMOVE(&checkout_ign_pats, ip, ip_list); |
||
380 |
free(ip); |
||
381 |
} |
||
382 |
|||
383 |
13 |
free(mc); |
|
384 |
} |
||
385 |
26 |
} |
|
386 |
|||
387 |
static int |
||
388 |
checkout_classify(const char *repo, const char *arg) |
||
389 |
{ |
||
390 |
26 |
char *d, *f, fpath[PATH_MAX]; |
|
391 |
13 |
struct stat sb; |
|
392 |
|||
393 |
✓✓ | 13 |
if (stat(repo, &sb) == 0) { |
394 |
✓✗ | 12 |
if (S_ISDIR(sb.st_mode)) |
395 |
12 |
return CVS_DIR; |
|
396 |
} |
||
397 |
|||
398 |
1 |
d = dirname(repo); |
|
399 |
1 |
f = basename(repo); |
|
400 |
|||
401 |
1 |
(void)xsnprintf(fpath, sizeof(fpath), "%s/%s%s", d, f, RCS_FILE_EXT); |
|
402 |
✓✗ | 1 |
if (stat(fpath, &sb) == 0) { |
403 |
✗✓ | 1 |
if (!S_ISREG(sb.st_mode)) { |
404 |
cvs_log(LP_ERR, "ignoring %s: not a regular file", arg); |
||
405 |
return 0; |
||
406 |
} |
||
407 |
1 |
return CVS_FILE; |
|
408 |
} |
||
409 |
|||
410 |
(void)xsnprintf(fpath, sizeof(fpath), "%s/%s/%s%s", |
||
411 |
d, CVS_PATH_ATTIC, f, RCS_FILE_EXT); |
||
412 |
if (stat(fpath, &sb) == 0) { |
||
413 |
if (!S_ISREG(sb.st_mode)) { |
||
414 |
cvs_log(LP_ERR, "ignoring %s: not a regular file", arg); |
||
415 |
return 0; |
||
416 |
} |
||
417 |
return CVS_FILE; |
||
418 |
} |
||
419 |
|||
420 |
cvs_log(LP_ERR, "cannot find module `%s' - ignored", arg); |
||
421 |
return 0; |
||
422 |
13 |
} |
|
423 |
|||
424 |
static void |
||
425 |
checkout_repository(const char *repobase, const char *wdbase) |
||
426 |
{ |
||
427 |
24 |
struct cvs_flisthead fl, dl; |
|
428 |
12 |
struct cvs_recursion cr; |
|
429 |
|||
430 |
12 |
RB_INIT(&fl); |
|
431 |
12 |
RB_INIT(&dl); |
|
432 |
|||
433 |
12 |
cvs_history_add((cvs_cmdop == CVS_OP_CHECKOUT) ? |
|
434 |
CVS_HISTORY_CHECKOUT : CVS_HISTORY_EXPORT, NULL, wdbase); |
||
435 |
|||
436 |
✗✓ | 12 |
if (print_stdout) { |
437 |
cr.enterdir = NULL; |
||
438 |
cr.leavedir = NULL; |
||
439 |
} else { |
||
440 |
12 |
cr.enterdir = cvs_update_enterdir; |
|
441 |
✗✓ | 12 |
if (cvs_server_active == 1) { |
442 |
if (disable_fast_checkout != 1) |
||
443 |
cr.leavedir = NULL; |
||
444 |
else |
||
445 |
cr.leavedir = cvs_update_leavedir; |
||
446 |
} else { |
||
447 |
12 |
cr.leavedir = prune_dirs ? cvs_update_leavedir : NULL; |
|
448 |
} |
||
449 |
} |
||
450 |
12 |
cr.fileproc = cvs_update_local; |
|
451 |
12 |
cr.flags = flags; |
|
452 |
|||
453 |
12 |
cvs_repository_lock(repobase, 0); |
|
454 |
12 |
cvs_repository_getdir(repobase, wdbase, &fl, &dl, |
|
455 |
12 |
flags & CR_RECURSE_DIRS ? REPOSITORY_DODIRS : 0); |
|
456 |
|||
457 |
12 |
cvs_file_walklist(&fl, &cr); |
|
458 |
12 |
cvs_file_freelist(&fl); |
|
459 |
|||
460 |
12 |
cvs_repository_unlock(repobase); |
|
461 |
|||
462 |
12 |
cvs_file_walklist(&dl, &cr); |
|
463 |
12 |
cvs_file_freelist(&dl); |
|
464 |
12 |
} |
|
465 |
|||
466 |
void |
||
467 |
cvs_checkout_file(struct cvs_file *cf, RCSNUM *rnum, char *tag, int co_flags) |
||
468 |
{ |
||
469 |
BUF *bp; |
||
470 |
mode_t mode; |
||
471 |
int cf_kflag, exists; |
||
472 |
80 |
time_t rcstime; |
|
473 |
CVSENTRIES *ent; |
||
474 |
40 |
struct timeval tv[2]; |
|
475 |
40 |
struct tm datetm; |
|
476 |
char *entry, *tosend; |
||
477 |
40 |
char kbuf[8], sticky[CVS_REV_BUFSZ], rev[CVS_REV_BUFSZ]; |
|
478 |
40 |
char timebuf[CVS_TIME_BUFSZ], tbuf[CVS_TIME_BUFSZ]; |
|
479 |
static char lastwd[PATH_MAX]; |
||
480 |
|||
481 |
exists = 0; |
||
482 |
tosend = NULL; |
||
483 |
|||
484 |
✓✗ | 40 |
if (!(co_flags & CO_REMOVE)) |
485 |
40 |
rcsnum_tostr(rnum, rev, sizeof(rev)); |
|
486 |
else |
||
487 |
rev[0] = '\0'; |
||
488 |
|||
489 |
40 |
cvs_log(LP_TRACE, "cvs_checkout_file(%s, %s, %d) -> %s", |
|
490 |
40 |
cf->file_path, rev, co_flags, |
|
491 |
40 |
(cvs_server_active) ? "to client" : "to disk"); |
|
492 |
|||
493 |
✓✓ | 40 |
if (co_flags & CO_DUMP) { |
494 |
1 |
rcs_rev_write_fd(cf->file_rcs, rnum, STDOUT_FILENO, 0); |
|
495 |
1 |
return; |
|
496 |
} |
||
497 |
|||
498 |
✓✗ | 39 |
if (cvs_server_active == 0) { |
499 |
39 |
(void)unlink(cf->file_path); |
|
500 |
|||
501 |
✓✗ | 39 |
if (!(co_flags & CO_MERGE)) { |
502 |
✓✓ | 39 |
if (cf->file_flags & FILE_ON_DISK) { |
503 |
exists = 1; |
||
504 |
17 |
(void)close(cf->fd); |
|
505 |
17 |
} |
|
506 |
|||
507 |
39 |
cf->fd = open(cf->file_path, |
|
508 |
O_CREAT | O_RDWR | O_TRUNC); |
||
509 |
✗✓ | 39 |
if (cf->fd == -1) |
510 |
fatal("cvs_checkout_file: open: %s", |
||
511 |
strerror(errno)); |
||
512 |
|||
513 |
39 |
rcs_rev_write_fd(cf->file_rcs, rnum, cf->fd, 0); |
|
514 |
39 |
cf->file_flags |= FILE_ON_DISK; |
|
515 |
39 |
} else { |
|
516 |
cvs_merge_file(cf, (cvs_join_rev1 == NULL)); |
||
517 |
} |
||
518 |
|||
519 |
39 |
mode = cf->file_rcs->rf_mode; |
|
520 |
39 |
mode |= S_IWUSR; |
|
521 |
|||
522 |
✗✓ | 39 |
if (fchmod(cf->fd, mode) == -1) |
523 |
fatal("cvs_checkout_file: fchmod: %s", strerror(errno)); |
||
524 |
|||
525 |
✓✓✓✗ ✓✗ |
83 |
if ((exists == 0) && (cf->file_ent == NULL) && |
526 |
!(co_flags & CO_MERGE)) |
||
527 |
22 |
rcstime = rcs_rev_getdate(cf->file_rcs, rnum); |
|
528 |
else |
||
529 |
17 |
time(&rcstime); |
|
530 |
|||
531 |
39 |
tv[0].tv_sec = rcstime; |
|
532 |
39 |
tv[0].tv_usec = 0; |
|
533 |
39 |
tv[1] = tv[0]; |
|
534 |
✗✓ | 39 |
if (futimes(cf->fd, tv) == -1) |
535 |
fatal("cvs_checkout_file: futimes: %s", |
||
536 |
strerror(errno)); |
||
537 |
} else { |
||
538 |
time(&rcstime); |
||
539 |
} |
||
540 |
|||
541 |
39 |
gmtime_r(&rcstime, &datetm); |
|
542 |
39 |
asctime_r(&datetm, tbuf); |
|
543 |
39 |
tbuf[strcspn(tbuf, "\n")] = '\0'; |
|
544 |
|||
545 |
✗✓ | 39 |
if (co_flags & CO_MERGE) { |
546 |
(void)xsnprintf(timebuf, sizeof(timebuf), "Result of merge+%s", |
||
547 |
tbuf); |
||
548 |
} else { |
||
549 |
39 |
strlcpy(timebuf, tbuf, sizeof(timebuf)); |
|
550 |
} |
||
551 |
|||
552 |
✓✓ | 39 |
if (reset_tag) { |
553 |
6 |
sticky[0] = '\0'; |
|
554 |
✓✓ | 39 |
} else if (co_flags & CO_SETSTICKY) |
555 |
✓✗ | 17 |
if (tag != NULL) |
556 |
17 |
(void)xsnprintf(sticky, sizeof(sticky), "T%s", tag); |
|
557 |
else if (cvs_specified_date != -1) { |
||
558 |
gmtime_r(&cvs_specified_date, &datetm); |
||
559 |
(void)strftime(sticky, sizeof(sticky), |
||
560 |
"D"CVS_DATE_FMT, &datetm); |
||
561 |
} else if (cvs_directory_date != -1) { |
||
562 |
gmtime_r(&cvs_directory_date, &datetm); |
||
563 |
(void)strftime(sticky, sizeof(sticky), |
||
564 |
"D"CVS_DATE_FMT, &datetm); |
||
565 |
} else |
||
566 |
(void)xsnprintf(sticky, sizeof(sticky), "T%s", rev); |
||
567 |
✓✓✓✓ |
21 |
else if (cf->file_ent != NULL && cf->file_ent->ce_tag != NULL) |
568 |
1 |
(void)xsnprintf(sticky, sizeof(sticky), "T%s", |
|
569 |
cf->file_ent->ce_tag); |
||
570 |
else |
||
571 |
15 |
sticky[0] = '\0'; |
|
572 |
|||
573 |
39 |
kbuf[0] = '\0'; |
|
574 |
✓✗✓✓ |
78 |
if (cf->file_rcs != NULL && cf->file_rcs->rf_expand != NULL) { |
575 |
10 |
cf_kflag = rcs_kflag_get(cf->file_rcs->rf_expand); |
|
576 |
✓✗ | 10 |
if (kflag || cf_kflag != RCS_KWEXP_DEFAULT) |
577 |
20 |
(void)xsnprintf(kbuf, sizeof(kbuf), |
|
578 |
10 |
"-k%s", cf->file_rcs->rf_expand); |
|
579 |
✓✓✓✓ |
52 |
} else if (!reset_option && cf->file_ent != NULL) { |
580 |
✗✓ | 5 |
if (cf->file_ent->ce_opts != NULL) |
581 |
strlcpy(kbuf, cf->file_ent->ce_opts, sizeof(kbuf)); |
||
582 |
} |
||
583 |
|||
584 |
39 |
entry = xmalloc(CVS_ENT_MAXLINELEN); |
|
585 |
39 |
cvs_ent_line_str(cf->file_name, rev, timebuf, kbuf, sticky, 0, 0, |
|
586 |
entry, CVS_ENT_MAXLINELEN); |
||
587 |
|||
588 |
✓✗ | 39 |
if (cvs_server_active == 0) { |
589 |
✓✓ | 39 |
if (!(co_flags & CO_REMOVE) && cvs_cmdop != CVS_OP_EXPORT) { |
590 |
36 |
ent = cvs_ent_open(cf->file_wd); |
|
591 |
36 |
cvs_ent_add(ent, entry); |
|
592 |
36 |
cf->file_ent = cvs_ent_parse(entry); |
|
593 |
36 |
} |
|
594 |
} else { |
||
595 |
if (co_flags & CO_MERGE) { |
||
596 |
(void)unlink(cf->file_path); |
||
597 |
cvs_merge_file(cf, (cvs_join_rev1 == NULL)); |
||
598 |
tosend = cf->file_path; |
||
599 |
} |
||
600 |
|||
601 |
/* |
||
602 |
* If this file has a tag, push out the Directory with the |
||
603 |
* tag to the client. Except when this file was explicitly |
||
604 |
* specified on the command line. |
||
605 |
*/ |
||
606 |
if (tag != NULL && strcmp(cf->file_wd, lastwd) && |
||
607 |
!(cf->file_flags & FILE_USER_SUPPLIED)) { |
||
608 |
strlcpy(lastwd, cf->file_wd, PATH_MAX); |
||
609 |
cvs_server_set_sticky(cf->file_wd, sticky); |
||
610 |
} |
||
611 |
|||
612 |
if (co_flags & CO_COMMIT) |
||
613 |
cvs_server_update_entry("Updated", cf); |
||
614 |
else if (co_flags & CO_MERGE) |
||
615 |
cvs_server_update_entry("Merged", cf); |
||
616 |
else if (co_flags & CO_REMOVE) |
||
617 |
cvs_server_update_entry("Removed", cf); |
||
618 |
else |
||
619 |
cvs_server_update_entry("Updated", cf); |
||
620 |
|||
621 |
if (!(co_flags & CO_REMOVE)) { |
||
622 |
cvs_remote_output(entry); |
||
623 |
|||
624 |
if (!(co_flags & CO_MERGE)) { |
||
625 |
mode = cf->file_rcs->rf_mode; |
||
626 |
mode |= S_IWUSR; |
||
627 |
bp = rcs_rev_getbuf(cf->file_rcs, rnum, 0); |
||
628 |
cvs_remote_send_file_buf(cf->file_path, |
||
629 |
bp, mode); |
||
630 |
} else { |
||
631 |
cvs_remote_send_file(tosend, cf->fd); |
||
632 |
} |
||
633 |
} |
||
634 |
} |
||
635 |
|||
636 |
39 |
free(entry); |
|
637 |
79 |
} |
Generated by: GCOVR (Version 3.3) |