Bug Summary

File:src/usr.bin/sendbug/sendbug.c
Warning:line 429, column 4
Potential leak of memory pointed to by 'buf'

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple amd64-unknown-openbsd7.4 -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name sendbug.c -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 -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -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/sendbug/obj -resource-dir /usr/local/llvm16/lib/clang/16 -internal-isystem /usr/local/llvm16/lib/clang/16/include -internal-externc-isystem /usr/include -O2 -fdebug-compilation-dir=/usr/src/usr.bin/sendbug/obj -ferror-limit 19 -fwrapv -D_RET_PROTECTOR -ret-protector -fcf-protection=branch -fno-jump-tables -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/scan/2024-01-11-140451-98009-1 -x c /usr/src/usr.bin/sendbug/sendbug.c
1/* $OpenBSD: sendbug.c,v 1.80 2022/04/10 17:47:54 jca Exp $ */
2
3/*
4 * Written by Ray Lai <ray@cyth.net>.
5 * Public domain.
6 */
7
8#include <sys/types.h>
9#include <sys/stat.h>
10#include <sys/sysctl.h>
11#include <sys/wait.h>
12
13#include <ctype.h>
14#include <err.h>
15#include <errno(*__errno()).h>
16#include <fcntl.h>
17#include <limits.h>
18#include <paths.h>
19#include <pwd.h>
20#include <signal.h>
21#include <stdio.h>
22#include <stdlib.h>
23#include <string.h>
24#include <unistd.h>
25
26#include "atomicio.h"
27
28#define _PATH_DMESG"/var/run/dmesg.boot" "/var/run/dmesg.boot"
29#define DMESG_START"OpenBSD " "OpenBSD "
30#define BEGIN64"begin-base64 " "begin-base64 "
31#define END64"====" "===="
32
33void checkfile(const char *);
34void debase(void);
35void dmesg(FILE *);
36int editit(const char *);
37void hwdump(FILE *);
38void init(void);
39int matchline(const char *, const char *, size_t);
40int prompt(void);
41int send_file(const char *, int);
42int sendmail(const char *);
43void template(FILE *);
44void usbdevs(FILE *);
45
46const char *categories = "system user library documentation kernel "
47 "alpha aarch64 amd64 arm hppa i386 m88k mips64 mips64el powerpc powerpc64 "
48 "riscv64 sh sparc64";
49const char *comment[] = {
50 "<synopsis of the problem (one line)>",
51 "<PR category (one line)>",
52 "<precise description of the problem (multiple lines)>",
53 "<code/input/activities to reproduce the problem (multiple lines)>",
54 "<how to correct or work around the problem, if known (multiple lines)>"
55};
56
57struct passwd *pw;
58char os[BUFSIZ1024], rel[BUFSIZ1024], mach[BUFSIZ1024], details[BUFSIZ1024];
59const char *tmpdir = _PATH_TMP"/tmp/";
60char *tmppath;
61int Dflag, Pflag, wantcleanup;
62
63__dead__attribute__((__noreturn__)) void
64usage(void)
65{
66 extern char *__progname;
67
68 fprintf(stderr(&__sF[2]), "usage: %s [-DEP]\n", __progname);
69 exit(1);
70}
71
72void
73cleanup()
74{
75 if (wantcleanup && tmppath && unlink(tmppath) == -1)
76 warn("unlink");
77}
78
79
80int
81main(int argc, char *argv[])
82{
83 int ch, c, fd, ret = 1;
84 struct stat sb;
85 char *pr_form;
86 time_t mtime;
87 FILE *fp;
88
89 if (pledge("stdio rpath wpath cpath tmppath getpw proc exec", NULL((void *)0)) == -1)
1
Assuming the condition is false
2
Taking false branch
90 err(1, "pledge");
91
92 while ((ch = getopt(argc, argv, "DEP")) != -1)
3
Assuming the condition is false
4
Loop condition is false. Execution continues on line 106
93 switch (ch) {
94 case 'D':
95 Dflag = 1;
96 break;
97 case 'E':
98 debase();
99 exit(0);
100 case 'P':
101 Pflag = 1;
102 break;
103 default:
104 usage();
105 }
106 argc -= optind;
107 argv += optind;
108
109 if (argc > 0)
5
Assuming 'argc' is <= 0
6
Taking false branch
110 usage();
111
112 if (Pflag) {
7
Assuming 'Pflag' is 0
8
Taking false branch
113 init();
114 template(stdout(&__sF[1]));
115 exit(0);
116 }
117
118 if (asprintf(&tmppath, "%s%sp.XXXXXXXXXX", tmpdir,
10
Assuming the condition is false
11
Taking false branch
119 tmpdir[strlen(tmpdir) - 1] == '/' ? "" : "/") == -1)
9
'?' condition is true
120 err(1, "asprintf");
121 if ((fd = mkstemp(tmppath)) == -1)
12
Assuming the condition is false
13
Taking false branch
122 err(1, "mkstemp");
123 wantcleanup = 1;
124 atexit(cleanup);
125 if ((fp = fdopen(fd, "w+")) == NULL((void *)0))
14
Assuming the condition is false
15
Taking false branch
126 err(1, "fdopen");
127
128 init();
129
130 pr_form = getenv("PR_FORM");
16
Assuming the environment variable does not exist
131 if (pr_form
16.1
'pr_form' is null
) {
17
Taking false branch
132 char buf[BUFSIZ1024];
133 size_t len;
134 FILE *frfp;
135
136 frfp = fopen(pr_form, "r");
137 if (frfp == NULL((void *)0)) {
138 warn("can't seem to read your template file "
139 "(`%s'), ignoring PR_FORM", pr_form);
140 template(fp);
141 } else {
142 while (!feof(frfp)(!__isthreaded ? (((frfp)->_flags & 0x0020) != 0) : (feof
)(frfp))
) {
143 len = fread(buf, 1, sizeof buf, frfp);
144 if (len == 0)
145 break;
146 if (fwrite(buf, 1, len, fp) != len)
147 break;
148 }
149 fclose(frfp);
150 }
151 } else
152 template(fp);
153
154 if (fflush(fp) == EOF(-1) || fstat(fd, &sb) == -1 || fclose(fp) == EOF(-1))
18
Assuming the condition is false
19
Assuming the condition is false
20
Assuming the condition is false
21
Taking false branch
155 err(1, "error creating template");
156 mtime = sb.st_mtimest_mtim.tv_sec;
157
158 edit:
159 if (editit(tmppath) == -1)
22
Assuming the condition is false
23
Taking false branch
160 err(1, "error running editor");
161
162 if (stat(tmppath, &sb) == -1)
24
Assuming the condition is false
25
Taking false branch
163 err(1, "stat");
164 if (mtime == sb.st_mtimest_mtim.tv_sec)
26
Assuming 'mtime' is not equal to field 'tv_sec'
27
Taking false branch
165 errx(1, "report unchanged, nothing sent");
166
167 prompt:
168 checkfile(tmppath);
169 c = prompt();
170 switch (c) {
28
Control jumps to 'case 115:' at line 177
171 case 'a':
172 case EOF(-1):
173 wantcleanup = 0;
174 errx(1, "unsent report in %s", tmppath);
175 case 'e':
176 goto edit;
177 case 's':
178 if (sendmail(tmppath) == -1)
29
Calling 'sendmail'
179 goto quit;
180 break;
181 default:
182 goto prompt;
183 }
184
185 ret = 0;
186quit:
187 return (ret);
188}
189
190void
191dmesg(FILE *fp)
192{
193 char buf[BUFSIZ1024];
194 FILE *dfp;
195 off_t offset = -1;
196
197 dfp = fopen(_PATH_DMESG"/var/run/dmesg.boot", "r");
198 if (dfp == NULL((void *)0)) {
199 warn("can't read dmesg");
200 return;
201 }
202
203 /* Find last dmesg. */
204 for (;;) {
205 off_t o;
206
207 o = ftello(dfp);
208 if (fgets(buf, sizeof(buf), dfp) == NULL((void *)0))
209 break;
210 if (!strncmp(DMESG_START"OpenBSD ", buf, sizeof(DMESG_START"OpenBSD ") - 1))
211 offset = o;
212 }
213 if (offset != -1) {
214 size_t len;
215
216 clearerr(dfp)(!__isthreaded ? ((void)((dfp)->_flags &= ~(0x0040|0x0020
))) : (clearerr)(dfp))
;
217 fseeko(dfp, offset, SEEK_SET0);
218 while (offset != -1 && !feof(dfp)(!__isthreaded ? (((dfp)->_flags & 0x0020) != 0) : (feof
)(dfp))
) {
219 len = fread(buf, 1, sizeof buf, dfp);
220 if (len == 0)
221 break;
222 if (fwrite(buf, 1, len, fp) != len)
223 break;
224 }
225 }
226 fclose(dfp);
227}
228
229void
230usbdevs(FILE *ofp)
231{
232 char buf[BUFSIZ1024];
233 FILE *ifp;
234 size_t len;
235
236 if ((ifp = popen("usbdevs -v", "r")) != NULL((void *)0)) {
237 while (!feof(ifp)(!__isthreaded ? (((ifp)->_flags & 0x0020) != 0) : (feof
)(ifp))
) {
238 len = fread(buf, 1, sizeof buf, ifp);
239 if (len == 0)
240 break;
241 if (fwrite(buf, 1, len, ofp) != len)
242 break;
243 }
244 pclose(ifp);
245 }
246}
247
248/*
249 * Execute an editor on the specified pathname, which is interpreted
250 * from the shell. This means flags may be included.
251 *
252 * Returns -1 on error, or the exit value on success.
253 */
254int
255editit(const char *pathname)
256{
257 char *argp[] = {"sh", "-c", NULL((void *)0), NULL((void *)0)}, *ed, *p;
258 sig_t sighup, sigint, sigquit, sigchld;
259 pid_t pid;
260 int saved_errno, st, ret = -1;
261
262 ed = getenv("VISUAL");
263 if (ed == NULL((void *)0) || ed[0] == '\0')
264 ed = getenv("EDITOR");
265 if (ed == NULL((void *)0) || ed[0] == '\0')
266 ed = _PATH_VI"/usr/bin/vi";
267 if (asprintf(&p, "%s %s", ed, pathname) == -1)
268 return (-1);
269 argp[2] = p;
270
271 sighup = signal(SIGHUP1, SIG_IGN(void (*)(int))1);
272 sigint = signal(SIGINT2, SIG_IGN(void (*)(int))1);
273 sigquit = signal(SIGQUIT3, SIG_IGN(void (*)(int))1);
274 sigchld = signal(SIGCHLD20, SIG_DFL(void (*)(int))0);
275 if ((pid = fork()) == -1)
276 goto fail;
277 if (pid == 0) {
278 execv(_PATH_BSHELL"/bin/sh", argp);
279 _exit(127);
280 }
281 while (waitpid(pid, &st, 0) == -1) {
282 if (errno(*__errno()) != EINTR4)
283 goto fail;
284 }
285 if (!WIFEXITED(st)(((st) & 0177) == 0))
286 errno(*__errno()) = EINTR4;
287 else
288 ret = WEXITSTATUS(st)(int)(((unsigned)(st) >> 8) & 0xff);
289
290 fail:
291 saved_errno = errno(*__errno());
292 (void)signal(SIGHUP1, sighup);
293 (void)signal(SIGINT2, sigint);
294 (void)signal(SIGQUIT3, sigquit);
295 (void)signal(SIGCHLD20, sigchld);
296 free(p);
297 errno(*__errno()) = saved_errno;
298 return (ret);
299}
300
301int
302prompt(void)
303{
304 int c, ret;
305
306 fpurge(stdin(&__sF[0]));
307 fprintf(stderr(&__sF[2]), "a)bort, e)dit, or s)end: ");
308 fflush(stderr(&__sF[2]));
309 ret = getchar()(!__isthreaded ? (--((&__sF[0]))->_r < 0 ? __srget(
(&__sF[0])) : (int)(*((&__sF[0]))->_p++)) : (getc)
((&__sF[0])))
;
310 if (ret == EOF(-1) || ret == '\n')
311 return (ret);
312 do {
313 c = getchar()(!__isthreaded ? (--((&__sF[0]))->_r < 0 ? __srget(
(&__sF[0])) : (int)(*((&__sF[0]))->_p++)) : (getc)
((&__sF[0])))
;
314 } while (c != EOF(-1) && c != '\n');
315 return (ret);
316}
317
318int
319sendmail(const char *pathname)
320{
321 int filedes[2];
322 pid_t pid;
323
324 if (pipe(filedes) == -1) {
30
Assuming the condition is false
31
Taking false branch
325 warn("pipe: unsent report in %s", pathname);
326 return (-1);
327 }
328 switch ((pid = fork())) {
32
Control jumps to the 'default' case at line 346
329 case -1:
330 warn("fork error: unsent report in %s",
331 pathname);
332 return (-1);
333 case 0:
334 close(filedes[1]);
335 if (dup2(filedes[0], STDIN_FILENO0) == -1) {
336 warn("dup2 error: unsent report in %s",
337 pathname);
338 return (-1);
339 }
340 close(filedes[0]);
341 execl(_PATH_SENDMAIL"/usr/sbin/sendmail", "sendmail",
342 "-oi", "-t", (char *)NULL((void *)0));
343 warn("sendmail error: unsent report in %s",
344 pathname);
345 return (-1);
346 default:
347 close(filedes[0]);
348 /* Pipe into sendmail. */
349 if (send_file(pathname, filedes[1]) == -1) {
33
Calling 'send_file'
350 warn("send_file error: unsent report in %s",
351 pathname);
352 return (-1);
353 }
354 close(filedes[1]);
355 while (waitpid(pid, NULL((void *)0), 0) == -1) {
356 if (errno(*__errno()) != EINTR4)
357 break;
358 }
359 break;
360 }
361 return (0);
362}
363
364void
365init(void)
366{
367 size_t len;
368 int sysname[2];
369 char *cp;
370
371 if ((pw = getpwuid(getuid())) == NULL((void *)0))
372 err(1, "getpwuid");
373
374 sysname[0] = CTL_KERN1;
375 sysname[1] = KERN_OSTYPE1;
376 len = sizeof(os) - 1;
377 if (sysctl(sysname, 2, &os, &len, NULL((void *)0), 0) == -1)
378 err(1, "sysctl");
379
380 sysname[0] = CTL_KERN1;
381 sysname[1] = KERN_OSRELEASE2;
382 len = sizeof(rel) - 1;
383 if (sysctl(sysname, 2, &rel, &len, NULL((void *)0), 0) == -1)
384 err(1, "sysctl");
385
386 sysname[0] = CTL_KERN1;
387 sysname[1] = KERN_VERSION4;
388 len = sizeof(details) - 1;
389 if (sysctl(sysname, 2, &details, &len, NULL((void *)0), 0) == -1)
390 err(1, "sysctl");
391
392 cp = strchr(details, '\n');
393 if (cp) {
394 cp++;
395 if (*cp)
396 *cp++ = '\t';
397 if (*cp)
398 *cp++ = '\t';
399 if (*cp)
400 *cp++ = '\t';
401 }
402
403 sysname[0] = CTL_HW6;
404 sysname[1] = HW_MACHINE1;
405 len = sizeof(mach) - 1;
406 if (sysctl(sysname, 2, &mach, &len, NULL((void *)0), 0) == -1)
407 err(1, "sysctl");
408}
409
410int
411send_file(const char *file, int dst)
412{
413 size_t len;
414 char *buf, *lbuf;
415 FILE *fp;
416 int rval = -1, saved_errno;
417
418 if ((fp = fopen(file, "r")) == NULL((void *)0))
34
Assuming the condition is false
35
Taking false branch
419 return (-1);
420 lbuf = NULL((void *)0);
421 while ((buf = fgetln(fp, &len))) {
36
Loop condition is true. Entering loop body
44
Execution continues on line 421
45
Loop condition is true. Entering loop body
422 if (buf[len - 1] == '\n') {
37
Assuming the condition is false
38
Taking false branch
46
Assuming the condition is false
47
Taking false branch
423 buf[len - 1] = '\0';
424 --len;
425 } else {
426 /* EOF without EOL, copy and add the NUL */
427 if ((lbuf = malloc(len + 1)) == NULL((void *)0))
39
Memory is allocated
40
Assuming the condition is false
41
Taking false branch
48
Assuming the condition is false
49
Taking false branch
428 goto end;
429 memcpy(lbuf, buf, len);
50
Potential leak of memory pointed to by 'buf'
430 lbuf[len] = '\0';
431 buf = lbuf;
432 }
433
434 /* Skip lines starting with "SENDBUG". */
435 if (strncmp(buf, "SENDBUG", sizeof("SENDBUG") - 1) == 0)
42
Assuming the condition is true
43
Taking true branch
436 continue;
437 while (len) {
438 char *sp = NULL((void *)0), *ep = NULL((void *)0);
439 size_t copylen;
440
441 if ((sp = strchr(buf, '<')) != NULL((void *)0)) {
442 size_t i;
443
444 for (i = 0; i < sizeof(comment) / sizeof(*comment); ++i) {
445 size_t commentlen = strlen(comment[i]);
446
447 if (strncmp(sp, comment[i], commentlen) == 0) {
448 ep = sp + commentlen - 1;
449 break;
450 }
451 }
452 }
453 /* Length of string before comment. */
454 if (ep)
455 copylen = sp - buf;
456 else
457 copylen = len;
458 if (atomicio(vwrite(ssize_t (*)(int, void *, size_t))write, dst, buf, copylen) != copylen)
459 goto end;
460 if (!ep)
461 break;
462 /* Skip comment. */
463 len -= ep - buf + 1;
464 buf = ep + 1;
465 }
466 if (atomicio(vwrite(ssize_t (*)(int, void *, size_t))write, dst, "\n", 1) != 1)
467 goto end;
468 }
469 rval = 0;
470 end:
471 saved_errno = errno(*__errno());
472 free(lbuf);
473 fclose(fp);
474 errno(*__errno()) = saved_errno;
475 return (rval);
476}
477
478/*
479 * Does line start with `s' and end with non-comment and non-whitespace?
480 * Note: Does not treat `line' as a C string.
481 */
482int
483matchline(const char *s, const char *line, size_t linelen)
484{
485 size_t slen;
486 int iscomment;
487
488 slen = strlen(s);
489 /* Is line shorter than string? */
490 if (linelen <= slen)
491 return (0);
492 /* Does line start with string? */
493 if (memcmp(line, s, slen) != 0)
494 return (0);
495 /* Does line contain anything but comments and whitespace? */
496 line += slen;
497 linelen -= slen;
498 iscomment = 0;
499 while (linelen) {
500 if (iscomment) {
501 if (*line == '>')
502 iscomment = 0;
503 } else if (*line == '<')
504 iscomment = 1;
505 else if (!isspace((unsigned char)*line))
506 return (1);
507 ++line;
508 --linelen;
509 }
510 return (0);
511}
512
513/*
514 * Are all required fields filled out?
515 */
516void
517checkfile(const char *pathname)
518{
519 FILE *fp;
520 size_t len;
521 int category = 0, synopsis = 0, subject = 0;
522 char *buf;
523
524 if ((fp = fopen(pathname, "r")) == NULL((void *)0)) {
525 warn("%s", pathname);
526 return;
527 }
528 while ((buf = fgetln(fp, &len))) {
529 if (matchline(">Category:", buf, len))
530 category = 1;
531 else if (matchline(">Synopsis:", buf, len))
532 synopsis = 1;
533 else if (matchline("Subject:", buf, len))
534 subject = 1;
535 }
536 fclose(fp);
537 if (!category || !synopsis || !subject) {
538 fprintf(stderr(&__sF[2]), "Some fields are blank, please fill them in: ");
539 if (!subject)
540 fprintf(stderr(&__sF[2]), "Subject ");
541 if (!synopsis)
542 fprintf(stderr(&__sF[2]), "Synopsis ");
543 if (!category)
544 fprintf(stderr(&__sF[2]), "Category ");
545 fputc('\n', stderr(&__sF[2]));
546 }
547}
548
549void
550template(FILE *fp)
551{
552 fprintf(fp, "SENDBUG: -*- sendbug -*-\n");
553 fprintf(fp, "SENDBUG: Lines starting with `SENDBUG' will"
554 " be removed automatically.\n");
555 fprintf(fp, "SENDBUG:\n");
556 fprintf(fp, "SENDBUG: Choose from the following categories:\n");
557 fprintf(fp, "SENDBUG:\n");
558 fprintf(fp, "SENDBUG: %s\n", categories);
559 fprintf(fp, "SENDBUG:\n");
560 fprintf(fp, "SENDBUG:\n");
561 fprintf(fp, "To: %s\n", "bugs@openbsd.org");
562 fprintf(fp, "Subject: \n");
563 fprintf(fp, "From: %s\n", pw->pw_name);
564 fprintf(fp, "Cc: %s\n", pw->pw_name);
565 fprintf(fp, "Reply-To: %s\n", pw->pw_name);
566 fprintf(fp, "\n");
567 fprintf(fp, ">Synopsis:\t%s\n", comment[0]);
568 fprintf(fp, ">Category:\t%s\n", comment[1]);
569 fprintf(fp, ">Environment:\n");
570 fprintf(fp, "\tSystem : %s %s\n", os, rel);
571 fprintf(fp, "\tDetails : %s\n", details);
572 fprintf(fp, "\tArchitecture: %s.%s\n", os, mach);
573 fprintf(fp, "\tMachine : %s\n", mach);
574 fprintf(fp, ">Description:\n");
575 fprintf(fp, "\t%s\n", comment[2]);
576 fprintf(fp, ">How-To-Repeat:\n");
577 fprintf(fp, "\t%s\n", comment[3]);
578 fprintf(fp, ">Fix:\n");
579 fprintf(fp, "\t%s\n", comment[4]);
580
581 if (!Dflag) {
582 int root;
583
584 fprintf(fp, "\n");
585 root = !geteuid();
586 if (!root)
587 fprintf(fp, "SENDBUG: Run sendbug as root "
588 "if this is an ACPI report!\n");
589 fprintf(fp, "SENDBUG: dmesg%s and usbdevs are attached.\n"
590 "SENDBUG: Feel free to delete or use the -D flag if they "
591 "contain sensitive information.\n",
592 root ? ", pcidump, acpidump" : "");
593 fputs("\ndmesg:\n", fp);
594 dmesg(fp);
595 fputs("\nusbdevs:\n", fp);
596 usbdevs(fp);
597 if (root)
598 hwdump(fp);
599 }
600}
601
602void
603hwdump(FILE *ofp)
604{
605 char buf[BUFSIZ1024];
606 FILE *ifp;
607 char *cmd, *acpidir;
608 size_t len;
609
610 if (asprintf(&acpidir, "%s%sp.XXXXXXXXXX", tmpdir,
611 tmpdir[strlen(tmpdir) - 1] == '/' ? "" : "/") == -1)
612 err(1, "asprintf");
613 if (mkdtemp(acpidir) == NULL((void *)0))
614 err(1, "mkdtemp");
615
616 if (asprintf(&cmd, "echo \"\\npcidump:\"; pcidump -xxv; "
617 "echo \"\\nacpidump:\"; cd %s && cp /var/db/acpi/* .; "
618 "for i in *; do b64encode $i $i; done; rm -rf %s",
619 acpidir, acpidir) == -1)
620 err(1, "asprintf");
621
622 if ((ifp = popen(cmd, "r")) != NULL((void *)0)) {
623 while (!feof(ifp)(!__isthreaded ? (((ifp)->_flags & 0x0020) != 0) : (feof
)(ifp))
) {
624 len = fread(buf, 1, sizeof buf, ifp);
625 if (len == 0)
626 break;
627 if (fwrite(buf, 1, len, ofp) != len)
628 break;
629 }
630 pclose(ifp);
631 }
632 free(cmd);
633 free(acpidir);
634}
635
636void
637debase(void)
638{
639 char buf[BUFSIZ1024];
640 FILE *fp = NULL((void *)0);
641 size_t len;
642
643 while (fgets(buf, sizeof(buf), stdin(&__sF[0])) != NULL((void *)0)) {
644 len = strlen(buf);
645 if (!strncmp(buf, BEGIN64"begin-base64 ", sizeof(BEGIN64"begin-base64 ") - 1)) {
646 if (fp)
647 errx(1, "double begin");
648 fp = popen("b64decode", "w");
649 if (!fp)
650 errx(1, "popen b64decode");
651 }
652 if (fp && fwrite(buf, 1, len, fp) != len)
653 errx(1, "pipe error");
654 if (!strncmp(buf, END64"====", sizeof(END64"====") - 1)) {
655 if (pclose(fp) == -1)
656 errx(1, "pclose b64decode");
657 fp = NULL((void *)0);
658 }
659 }
660}