Bug Summary

File:src/usr.bin/cvs/edit.c
Warning:line 468, column 15
1st function call argument is an uninitialized value

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple amd64-unknown-openbsd7.0 -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name edit.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 1 -pic-is-pie -mframe-pointer=all -relaxed-aliasing -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -target-feature +retpoline-indirect-calls -target-feature +retpoline-indirect-branches -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/usr/src/usr.bin/cvs/obj -resource-dir /usr/local/lib/clang/13.0.0 -I /usr/src/usr.bin/cvs -internal-isystem /usr/local/lib/clang/13.0.0/include -internal-externc-isystem /usr/include -O2 -fdebug-compilation-dir=/usr/src/usr.bin/cvs/obj -ferror-limit 19 -fwrapv -D_RET_PROTECTOR -ret-protector -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-valloc -fno-builtin-free -fno-builtin-strdup -fno-builtin-strndup -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /home/ben/Projects/vmm/scan-build/2022-01-12-194120-40624-1 -x c /usr/src/usr.bin/cvs/edit.c
1/* $OpenBSD: edit.c,v 1.53 2017/06/01 08:08:24 joris Exp $ */
2/*
3 * Copyright (c) 2006, 2007 Xavier Santolaria <xsa@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/stat.h>
19
20#include <errno(*__errno()).h>
21#include <stdlib.h>
22#include <string.h>
23#include <time.h>
24#include <unistd.h>
25
26#include "cvs.h"
27#include "remote.h"
28
29#define E_COMMIT0x01 0x01
30#define E_EDIT0x02 0x02
31#define E_UNEDIT0x04 0x04
32#define E_ALL(0x02|0x01|0x04) (E_EDIT0x02|E_COMMIT0x01|E_UNEDIT0x04)
33
34#define BASE_ADD0x01 0x01
35#define BASE_GET0x02 0x02
36#define BASE_REMOVE0x04 0x04
37
38static void cvs_edit_local(struct cvs_file *);
39static void cvs_editors_local(struct cvs_file *);
40static void cvs_unedit_local(struct cvs_file *);
41
42static RCSNUM *cvs_base_handle(struct cvs_file *, int);
43
44static int edit_aflags = 0;
45
46struct cvs_cmd cvs_cmd_edit = {
47 CVS_OP_EDIT7, CVS_USE_WDIR0x01, "edit",
48 { { 0 }, { 0 } },
49 "Get ready to edit a watched file",
50 "[-lR] [-a action] [file ...]",
51 "a:lR",
52 NULL((void *)0),
53 cvs_edit
54};
55
56struct cvs_cmd cvs_cmd_editors = {
57 CVS_OP_EDITORS8, CVS_USE_WDIR0x01, "editors",
58 { { 0 }, { 0 } },
59 "See who is editing a watched file",
60 "[-lR] [file ...]",
61 "lR",
62 NULL((void *)0),
63 cvs_editors
64};
65
66struct cvs_cmd cvs_cmd_unedit = {
67 CVS_OP_UNEDIT23, CVS_USE_WDIR0x01, "unedit",
68 { { 0 }, { 0 } },
69 "Undo an edit command",
70 "[-lR] [file ...]",
71 "lR",
72 NULL((void *)0),
73 cvs_unedit
74};
75
76int
77cvs_edit(int argc, char **argv)
78{
79 int ch;
80 int flags;
81 struct cvs_recursion cr;
82
83 flags = CR_RECURSE_DIRS0x01;
84
85 while ((ch = getopt(argc, argv, cvs_cmd_edit.cmd_opts)) != -1) {
86 switch (ch) {
87 case 'a':
88 if (strcmp(optarg, "edit") == 0)
89 edit_aflags |= E_EDIT0x02;
90 else if (strcmp(optarg, "unedit") == 0)
91 edit_aflags |= E_UNEDIT0x04;
92 else if (strcmp(optarg, "commit") == 0)
93 edit_aflags |= E_COMMIT0x01;
94 else if (strcmp(optarg, "all") == 0)
95 edit_aflags |= E_ALL(0x02|0x01|0x04);
96 else if (strcmp(optarg, "none") == 0)
97 edit_aflags &= ~E_ALL(0x02|0x01|0x04);
98 else
99 fatal("%s", cvs_cmd_edit.cmd_synopsis);
100 break;
101 case 'l':
102 flags &= ~CR_RECURSE_DIRS0x01;
103 break;
104 case 'R':
105 flags |= CR_RECURSE_DIRS0x01;
106 break;
107 default:
108 fatal("%s", cvs_cmd_edit.cmd_synopsis);
109 }
110 }
111
112 argc -= optind;
113 argv += optind;
114
115 if (argc == 0)
116 fatal("%s", cvs_cmd_edit.cmd_synopsis);
117
118 if (edit_aflags == 0)
119 edit_aflags |= E_ALL(0x02|0x01|0x04);
120
121 cr.enterdir = NULL((void *)0);
122 cr.leavedir = NULL((void *)0);
123
124 if (cvsroot_is_remote()) {
125 cvs_client_connect_to_server();
126 cr.fileproc = cvs_client_sendfile;
127
128 if (!(flags & CR_RECURSE_DIRS0x01))
129 cvs_client_send_request("Argument -l");
130 } else {
131 cr.fileproc = cvs_edit_local;
132 }
133
134 cr.flags = flags;
135
136 cvs_file_run(argc, argv, &cr);
137
138 if (cvsroot_is_remote()) {
139 cvs_client_send_files(argv, argc);
140 cvs_client_senddir(".");
141 cvs_client_send_request("edit");
142 cvs_client_get_responses();
143 }
144
145 return (0);
146}
147
148int
149cvs_editors(int argc, char **argv)
150{
151 int ch;
152 int flags;
153 struct cvs_recursion cr;
154
155 flags = CR_RECURSE_DIRS0x01;
156
157 while ((ch = getopt(argc, argv, cvs_cmd_editors.cmd_opts)) != -1) {
158 switch (ch) {
159 case 'l':
160 flags &= ~CR_RECURSE_DIRS0x01;
161 break;
162 case 'R':
163 flags |= CR_RECURSE_DIRS0x01;
164 break;
165 default:
166 fatal("%s", cvs_cmd_editors.cmd_synopsis);
167 }
168 }
169
170 argc -= optind;
171 argv += optind;
172
173 if (argc == 0)
174 fatal("%s", cvs_cmd_editors.cmd_synopsis);
175
176 cr.enterdir = NULL((void *)0);
177 cr.leavedir = NULL((void *)0);
178
179 if (cvsroot_is_remote()) {
180 cvs_client_connect_to_server();
181 cr.fileproc = cvs_client_sendfile;
182
183 if (!(flags & CR_RECURSE_DIRS0x01))
184 cvs_client_send_request("Argument -l");
185 } else {
186 cr.fileproc = cvs_editors_local;
187 }
188
189 cr.flags = flags;
190
191 cvs_file_run(argc, argv, &cr);
192
193 if (cvsroot_is_remote()) {
194 cvs_client_send_files(argv, argc);
195 cvs_client_senddir(".");
196 cvs_client_send_request("editors");
197 cvs_client_get_responses();
198 }
199
200 return (0);
201}
202
203int
204cvs_unedit(int argc, char **argv)
205{
206 int ch;
207 int flags;
208 struct cvs_recursion cr;
209
210 flags = CR_RECURSE_DIRS0x01;
211
212 while ((ch = getopt(argc, argv, cvs_cmd_unedit.cmd_opts)) != -1) {
213 switch (ch) {
214 case 'l':
215 flags &= ~CR_RECURSE_DIRS0x01;
216 break;
217 case 'R':
218 flags |= CR_RECURSE_DIRS0x01;
219 break;
220 default:
221 fatal("%s", cvs_cmd_unedit.cmd_synopsis);
222 }
223 }
224
225 argc -= optind;
226 argv += optind;
227
228 if (argc == 0)
229 fatal("%s", cvs_cmd_unedit.cmd_synopsis);
230
231 cr.enterdir = NULL((void *)0);
232 cr.leavedir = NULL((void *)0);
233
234 if (cvsroot_is_remote()) {
235 cvs_client_connect_to_server();
236 cr.fileproc = cvs_client_sendfile;
237
238 if (!(flags & CR_RECURSE_DIRS0x01))
239 cvs_client_send_request("Argument -l");
240 } else {
241 cr.fileproc = cvs_unedit_local;
242 }
243
244 cr.flags = flags;
245
246 cvs_file_run(argc, argv, &cr);
247
248 if (cvsroot_is_remote()) {
249 cvs_client_send_files(argv, argc);
250 cvs_client_senddir(".");
251 cvs_client_send_request("unedit");
252 cvs_client_get_responses();
253 }
254
255 return (0);
256}
257
258static void
259cvs_edit_local(struct cvs_file *cf)
260{
261 FILE *fp;
262 struct tm t;
263 time_t now;
264 char timebuf[CVS_TIME_BUFSZ64], thishost[HOST_NAME_MAX255+1];
265 char bfpath[PATH_MAX1024], wdir[PATH_MAX1024];
266
267 if (cvs_noexec == 1)
268 return;
269
270 cvs_log(LP_TRACE4, "cvs_edit_local(%s)", cf->file_path);
271
272 cvs_file_classify(cf, cvs_directory_tag);
273
274 if ((fp = fopen(CVS_PATH_NOTIFY"CVS" "/Notify", "a")) == NULL((void *)0))
275 fatal("cvs_edit_local: fopen: `%s': %s",
276 CVS_PATH_NOTIFY"CVS" "/Notify", strerror(errno(*__errno())));
277
278 (void)time(&now);
279 gmtime_r(&now, &t);
280 asctime_r(&t, timebuf);
281 timebuf[strcspn(timebuf, "\n")] = '\0';
282
283 if (gethostname(thishost, sizeof(thishost)) == -1)
284 fatal("gethostname failed");
285
286 if (getcwd(wdir, sizeof(wdir)) == NULL((void *)0))
287 fatal("getcwd failed");
288
289 (void)fprintf(fp, "E%s\t%s GMT\t%s\t%s\t",
290 cf->file_name, timebuf, thishost, wdir);
291
292 if (edit_aflags & E_EDIT0x02)
293 (void)fprintf(fp, "E");
294 if (edit_aflags & E_UNEDIT0x04)
295 (void)fprintf(fp, "U");
296 if (edit_aflags & E_COMMIT0x01)
297 (void)fprintf(fp, "C");
298
299 (void)fprintf(fp, "\n");
300
301 (void)fclose(fp);
302
303 if (fchmod(cf->fd, 0644) == -1)
304 fatal("cvs_edit_local: fchmod %s", strerror(errno(*__errno())));
305
306 (void)xsnprintf(bfpath, PATH_MAX1024, "%s/%s",
307 CVS_PATH_BASEDIR"CVS" "/Base", cf->file_name);
308
309 if (mkdir(CVS_PATH_BASEDIR"CVS" "/Base", 0755) == -1 && errno(*__errno()) != EEXIST17)
310 fatal("cvs_edit_local: `%s': %s", CVS_PATH_BASEDIR"CVS" "/Base",
311 strerror(errno(*__errno())));
312
313 if (cvs_file_copy(cf->file_path, bfpath) == -1)
314 fatal("cvs_edit_local: cvs_file_copy failed");
315
316 (void)cvs_base_handle(cf, BASE_ADD0x01);
317}
318
319static void
320cvs_editors_local(struct cvs_file *cf)
321{
322}
323
324static void
325cvs_unedit_local(struct cvs_file *cf)
326{
327 FILE *fp;
328 struct stat st;
329 struct tm t;
330 time_t now;
331 char bfpath[PATH_MAX1024], timebuf[64], thishost[HOST_NAME_MAX255+1];
332 char wdir[PATH_MAX1024], sticky[CVS_ENT_MAXLINELEN1024];
333 RCSNUM *ba_rev;
334
335 cvs_log(LP_TRACE4, "cvs_unedit_local(%s)", cf->file_path);
336
337 if (cvs_noexec == 1)
1
Assuming 'cvs_noexec' is not equal to 1
2
Taking false branch
338 return;
339
340 cvs_file_classify(cf, cvs_directory_tag);
341
342 (void)xsnprintf(bfpath, PATH_MAX1024, "%s/%s",
343 CVS_PATH_BASEDIR"CVS" "/Base", cf->file_name);
344
345 if (stat(bfpath, &st) == -1)
3
Assuming the condition is false
4
Taking false branch
346 return;
347
348 if (cvs_file_cmp(cf->file_path, bfpath) != 0) {
5
Assuming the condition is false
6
Taking false branch
349 cvs_printf("%s has been modified; revert changes? ",
350 cf->file_name);
351
352 if (cvs_yesno() == -1)
353 return;
354 }
355
356 cvs_rename(bfpath, cf->file_path);
357
358 if ((fp = fopen(CVS_PATH_NOTIFY"CVS" "/Notify", "a")) == NULL((void *)0))
7
Assuming the condition is false
8
Taking false branch
359 fatal("cvs_unedit_local: fopen: `%s': %s",
360 CVS_PATH_NOTIFY"CVS" "/Notify", strerror(errno(*__errno())));
361
362 (void)time(&now);
363 gmtime_r(&now, &t);
364 asctime_r(&t, timebuf);
365 timebuf[strcspn(timebuf, "\n")] = '\0';
366
367 if (gethostname(thishost, sizeof(thishost)) == -1)
9
Assuming the condition is false
10
Taking false branch
368 fatal("gethostname failed");
369
370 if (getcwd(wdir, sizeof(wdir)) == NULL((void *)0))
11
Assuming the condition is false
12
Taking false branch
371 fatal("getcwd failed");
372
373 (void)fprintf(fp, "U%s\t%s GMT\t%s\t%s\t\n",
374 cf->file_name, timebuf, thishost, wdir);
375
376 (void)fclose(fp);
377
378 if ((ba_rev = cvs_base_handle(cf, BASE_GET0x02)) == NULL((void *)0)) {
13
Calling 'cvs_base_handle'
379 cvs_log(LP_ERR1, "%s not mentioned in %s",
380 cf->file_name, CVS_PATH_BASEREV"CVS" "/Baserev");
381 return;
382 }
383
384 if (cf->file_ent != NULL((void *)0)) {
385 CVSENTRIES *entlist;
386 struct cvs_ent *ent;
387 char *entry, rbuf[CVS_REV_BUFSZ32];
388
389 entlist = cvs_ent_open(cf->file_wd);
390
391 if ((ent = cvs_ent_get(entlist, cf->file_name)) == NULL((void *)0))
392 fatal("cvs_unedit_local: cvs_ent_get failed");
393
394 (void)rcsnum_tostr(ba_rev, rbuf, sizeof(rbuf));
395
396 memset(timebuf, 0, sizeof(timebuf));
397 ctime_r(&cf->file_ent->ce_mtime, timebuf);
398 timebuf[strcspn(timebuf, "\n")] = '\0';
399
400 sticky[0] = '\0';
401 if (cf->file_ent->ce_tag != NULL((void *)0))
402 (void)xsnprintf(sticky, sizeof(sticky), "T%s",
403 cf->file_ent->ce_tag);
404
405 (void)xasprintf(&entry, "/%s/%s/%s/%s/%s",
406 cf->file_name, rbuf, timebuf, cf->file_ent->ce_opts ?
407 cf->file_ent->ce_opts : "", sticky);
408
409 cvs_ent_add(entlist, entry);
410
411 cvs_ent_free(ent);
412
413 free(entry);
414 }
415
416 free(ba_rev);
417
418 (void)cvs_base_handle(cf, BASE_REMOVE0x04);
419
420 if (fchmod(cf->fd, 0644) == -1)
421 fatal("cvs_unedit_local: fchmod %s", strerror(errno(*__errno())));
422}
423
424static RCSNUM *
425cvs_base_handle(struct cvs_file *cf, int flags)
426{
427 FILE *fp, *tfp;
428 RCSNUM *ba_rev;
429 int i;
430 char *dp, *sp;
431 char buf[PATH_MAX1024], *fields[2], rbuf[CVS_REV_BUFSZ32];
432
433 cvs_log(LP_TRACE4, "cvs_base_handle(%s)", cf->file_path);
434
435 tfp = NULL((void *)0);
436 ba_rev = NULL((void *)0);
437
438 if (((fp = fopen(CVS_PATH_BASEREV"CVS" "/Baserev", "r")) == NULL((void *)0)) && errno(*__errno()) != ENOENT2) {
14
Assuming the condition is false
439 cvs_log(LP_ERRNO2, "%s", CVS_PATH_BASEREV"CVS" "/Baserev");
440 goto out;
441 }
442
443 if (flags & (BASE_ADD0x01|BASE_REMOVE0x04)) {
15
Taking false branch
444 if ((tfp = fopen(CVS_PATH_BASEREVTMP"CVS" "/Baserev.tmp", "w")) == NULL((void *)0)) {
445 cvs_log(LP_ERRNO2, "%s", CVS_PATH_BASEREVTMP"CVS" "/Baserev.tmp");
446 goto out;
447 }
448 }
449
450 if (fp
15.1
'fp' is not equal to NULL
!= NULL((void *)0)) {
16
Taking true branch
451 while (fgets(buf, sizeof(buf), fp)) {
17
Loop condition is true. Entering loop body
452 buf[strcspn(buf, "\n")] = '\0';
453
454 if (buf[0] != 'B')
18
Assuming the condition is false
19
Taking false branch
455 continue;
456
457 sp = buf + 1;
458 i = 0;
459 do {
22
Loop condition is false. Exiting loop
460 if ((dp = strchr(sp, '/')) != NULL((void *)0))
20
Assuming the condition is false
21
Taking false branch
461 *(dp++) = '\0';
462 fields[i++] = sp;
463 sp = dp;
464 } while (dp
21.1
'dp' is equal to NULL
!= NULL((void *)0) && i < 2);
465
466 if (cvs_file_cmpname(fields[0], cf->file_path) == 0) {
23
Assuming the condition is true
24
Taking true branch
467 if (flags & BASE_GET0x02) {
25
Taking true branch
468 ba_rev = rcsnum_parse(fields[1]);
26
1st function call argument is an uninitialized value
469 if (ba_rev == NULL((void *)0))
470 fatal("cvs_base_handle: "
471 "rcsnum_parse");
472 goto got_rev;
473 }
474 } else {
475 if (flags & (BASE_ADD0x01|BASE_REMOVE0x04))
476 (void)fprintf(tfp, "%s\n", buf);
477 }
478 }
479 }
480
481got_rev:
482 if (flags & (BASE_ADD0x01)) {
483 (void)rcsnum_tostr(cf->file_ent->ce_rev, rbuf, sizeof(rbuf));
484 (void)fprintf(tfp, "B%s/%s/\n", cf->file_path, rbuf);
485 }
486
487out:
488 if (fp != NULL((void *)0))
489 (void)fclose(fp);
490
491 if (tfp != NULL((void *)0)) {
492 (void)fclose(tfp);
493 (void)cvs_rename(CVS_PATH_BASEREVTMP"CVS" "/Baserev.tmp", CVS_PATH_BASEREV"CVS" "/Baserev");
494 }
495
496 return (ba_rev);
497}