Thu Aug 17 08:53:01 2017 UTC ()
- since we use log_it for cron_pclose() use log_it for cron_popen() too
  so we can see the reason it failed.
- add log_itx() that takes a format and use it.
- simplify with asprintf()


(christos)
diff -r1.8 -r1.9 src/external/bsd/cron/dist/do_command.c
diff -r1.4 -r1.5 src/external/bsd/cron/dist/funcs.h
diff -r1.4 -r1.5 src/external/bsd/cron/dist/misc.c

cvs diff -r1.8 -r1.9 src/external/bsd/cron/dist/do_command.c (expand / switch to unified diff)

--- src/external/bsd/cron/dist/do_command.c 2017/06/09 17:36:30 1.8
+++ src/external/bsd/cron/dist/do_command.c 2017/08/17 08:53:00 1.9
@@ -1,41 +1,41 @@ @@ -1,41 +1,41 @@
1/* $NetBSD: do_command.c,v 1.8 2017/06/09 17:36:30 christos Exp $ */ 1/* $NetBSD: do_command.c,v 1.9 2017/08/17 08:53:00 christos Exp $ */
2 2
3/* Copyright 1988,1990,1993,1994 by Paul Vixie 3/* Copyright 1988,1990,1993,1994 by Paul Vixie
4 * All rights reserved 4 * All rights reserved
5 */ 5 */
6 6
7/* 7/*
8 * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") 8 * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
9 * Copyright (c) 1997,2000 by Internet Software Consortium, Inc. 9 * Copyright (c) 1997,2000 by Internet Software Consortium, Inc.
10 * 10 *
11 * Permission to use, copy, modify, and distribute this software for any 11 * Permission to use, copy, modify, and distribute this software for any
12 * purpose with or without fee is hereby granted, provided that the above 12 * purpose with or without fee is hereby granted, provided that the above
13 * copyright notice and this permission notice appear in all copies. 13 * copyright notice and this permission notice appear in all copies.
14 * 14 *
15 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES 15 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
16 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 16 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
17 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR 17 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
18 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 18 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 19 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
20 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 20 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
21 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 21 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22 */ 22 */
23#include <sys/cdefs.h> 23#include <sys/cdefs.h>
24#if !defined(lint) && !defined(LINT) 24#if !defined(lint) && !defined(LINT)
25#if 0 25#if 0
26static char rcsid[] = "Id: do_command.c,v 1.9 2004/01/23 18:56:42 vixie Exp"; 26static char rcsid[] = "Id: do_command.c,v 1.9 2004/01/23 18:56:42 vixie Exp";
27#else 27#else
28__RCSID("$NetBSD: do_command.c,v 1.8 2017/06/09 17:36:30 christos Exp $"); 28__RCSID("$NetBSD: do_command.c,v 1.9 2017/08/17 08:53:00 christos Exp $");
29#endif 29#endif
30#endif 30#endif
31 31
32#include "cron.h" 32#include "cron.h"
33#include <unistd.h> 33#include <unistd.h>
34 34
35static int child_process(entry *); 35static int child_process(entry *);
36static int safe_p(const char *, const char *); 36static int safe_p(const char *, const char *);
37 37
38void 38void
39do_command(entry *e, user *u) { 39do_command(entry *e, user *u) {
40 int retval; 40 int retval;
41 41
@@ -474,34 +474,36 @@ child_process(entry *e) { @@ -474,34 +474,36 @@ child_process(entry *e) {
474 /* if we are supposed to be mailing, MAILTO will 474 /* if we are supposed to be mailing, MAILTO will
475 * be non-NULL. only in this case should we set 475 * be non-NULL. only in this case should we set
476 * up the mail command and subjects and stuff... 476 * up the mail command and subjects and stuff...
477 */ 477 */
478 478
479 if (mailto && safe_p(usernm, mailto)) { 479 if (mailto && safe_p(usernm, mailto)) {
480 char **env; 480 char **env;
481 char mailcmd[MAX_COMMAND]; 481 char mailcmd[MAX_COMMAND];
482 char hostname[MAXHOSTNAMELEN + 1]; 482 char hostname[MAXHOSTNAMELEN + 1];
483 483
484 (void)gethostname(hostname, MAXHOSTNAMELEN); 484 (void)gethostname(hostname, MAXHOSTNAMELEN);
485 if (strlens(MAILFMT, MAILARG, NULL) + 1 485 if (strlens(MAILFMT, MAILARG, NULL) + 1
486 >= sizeof mailcmd) { 486 >= sizeof mailcmd) {
487 warnx("mailcmd too long"); 487 log_it(usernm, getpid(), "MAIL",
 488 "mailcmd too long");
488 retval = ERROR_EXIT; 489 retval = ERROR_EXIT;
489 goto child_process_end; 490 goto child_process_end;
490 } 491 }
491 (void)snprintf(mailcmd, sizeof(mailcmd),  492 (void)snprintf(mailcmd, sizeof(mailcmd),
492 MAILFMT, MAILARG); 493 MAILFMT, MAILARG);
493 if (!(mail = cron_popen(mailcmd, "w", e->pwd))) { 494 if (!(mail = cron_popen(mailcmd, "w", e->pwd))) {
494 warn("cannot run `%s'", mailcmd); 495 log_itx(usernm, getpid(), "MAIL",
 496 "cannot run `%s'", mailcmd);
495 retval = ERROR_EXIT; 497 retval = ERROR_EXIT;
496 goto child_process_end; 498 goto child_process_end;
497 } 499 }
498 (void)fprintf(mail, 500 (void)fprintf(mail,
499 "From: root (Cron Daemon)\n"); 501 "From: root (Cron Daemon)\n");
500 (void)fprintf(mail, "To: %s\n", mailto); 502 (void)fprintf(mail, "To: %s\n", mailto);
501 (void)fprintf(mail, 503 (void)fprintf(mail,
502 "Subject: Cron <%s@%s> %s\n", 504 "Subject: Cron <%s@%s> %s\n",
503 usernm, hostname, e->cmd); 505 usernm, hostname, e->cmd);
504 (void)fprintf(mail, 506 (void)fprintf(mail,
505 "Auto-Submitted: auto-generated\n"); 507 "Auto-Submitted: auto-generated\n");
506#ifdef MAIL_DATE 508#ifdef MAIL_DATE
507 (void)fprintf(mail, "Date: %s\n", 509 (void)fprintf(mail, "Date: %s\n",
@@ -539,33 +541,30 @@ child_process(entry *e) { @@ -539,33 +541,30 @@ child_process(entry *e) {
539 * the termination of the grandchild 541 * the termination of the grandchild
540 * in addition to the mail process, since 542 * in addition to the mail process, since
541 * it (the grandchild) is likely to exit 543 * it (the grandchild) is likely to exit
542 * after closing its stdout. 544 * after closing its stdout.
543 */ 545 */
544 status = cron_pclose(mail); 546 status = cron_pclose(mail);
545 } 547 }
546 548
547 /* if there was output and we could not mail it, 549 /* if there was output and we could not mail it,
548 * log the facts so the poor user can figure out 550 * log the facts so the poor user can figure out
549 * what's going on. 551 * what's going on.
550 */ 552 */
551 if (mailto && status) { 553 if (mailto && status) {
552 char buf[MAX_TEMPSTR]; 554 log_itx(usernm, getpid(), "MAIL",
553 555 "mailed %d byte%s of output but got status"
554 (void)snprintf(buf, sizeof(buf), 556 " %#04x", bytes, bytes == 1 ? "" : "s",
555 "mailed %d byte%s of output but got status 0x%04x\n", 557 status);
556 bytes, (bytes==1)?"":"s", 
557 status); 
558 log_it(usernm, getpid(), "MAIL", buf); 
559 } 558 }
560 559
561 } /*if data from grandchild*/ 560 } /*if data from grandchild*/
562 561
563 Debug(DPROC, ("[%ld] got EOF from grandchild\n", 562 Debug(DPROC, ("[%ld] got EOF from grandchild\n",
564 (long)getpid())); 563 (long)getpid()));
565 564
566 (void)fclose(in); /* also closes stdout_pipe[READ_PIPE] */ 565 (void)fclose(in); /* also closes stdout_pipe[READ_PIPE] */
567 } 566 }
568 567
569 /* wait for children to die. 568 /* wait for children to die.
570 */ 569 */
571 sigchld_handler(0); 570 sigchld_handler(0);

cvs diff -r1.4 -r1.5 src/external/bsd/cron/dist/funcs.h (expand / switch to unified diff)

--- src/external/bsd/cron/dist/funcs.h 2017/06/09 17:36:30 1.4
+++ src/external/bsd/cron/dist/funcs.h 2017/08/17 08:53:00 1.5
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: funcs.h,v 1.4 2017/06/09 17:36:30 christos Exp $ */ 1/* $NetBSD: funcs.h,v 1.5 2017/08/17 08:53:00 christos Exp $ */
2 2
3/* 3/*
4 * Id: funcs.h,v 1.9 2004/01/23 18:56:42 vixie Exp 4 * Id: funcs.h,v 1.9 2004/01/23 18:56:42 vixie Exp
5 */ 5 */
6 6
7/* 7/*
8 * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") 8 * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
9 * Copyright (c) 1997,2000 by Internet Software Consortium, Inc. 9 * Copyright (c) 1997,2000 by Internet Software Consortium, Inc.
10 * 10 *
11 * Permission to use, copy, modify, and distribute this software for any 11 * Permission to use, copy, modify, and distribute this software for any
12 * purpose with or without fee is hereby granted, provided that the above 12 * purpose with or without fee is hereby granted, provided that the above
13 * copyright notice and this permission notice appear in all copies. 13 * copyright notice and this permission notice appear in all copies.
14 * 14 *
@@ -34,26 +34,31 @@ void set_cron_uid(void), @@ -34,26 +34,31 @@ void set_cron_uid(void),
34 job_add(entry *, user *, time_t), 34 job_add(entry *, user *, time_t),
35 do_command(entry *, user *), 35 do_command(entry *, user *),
36 link_user(cron_db *, user *), 36 link_user(cron_db *, user *),
37 unlink_user(cron_db *, user *), 37 unlink_user(cron_db *, user *),
38 free_user(user *), 38 free_user(user *),
39 env_free(char **), 39 env_free(char **),
40 unget_char(int, FILE *), 40 unget_char(int, FILE *),
41 free_entry(entry *), 41 free_entry(entry *),
42 acquire_daemonlock(int), 42 acquire_daemonlock(int),
43 skip_comments(FILE *), 43 skip_comments(FILE *),
44 log_it(const char *, int, const char *, const char *), 44 log_it(const char *, int, const char *, const char *),
45 log_close(void); 45 log_close(void);
46 46
 47
 48void
 49 log_itx(const char *, int, const char *, const char *, ...)
 50 __printflike(4, 5);
 51
47int job_runqueue(void), 52int job_runqueue(void),
48 set_debug_flags(const char *), 53 set_debug_flags(const char *),
49 get_char(FILE *), 54 get_char(FILE *),
50 get_string(char *, int, FILE *, const char *), 55 get_string(char *, int, FILE *, const char *),
51 load_env(char *, FILE *), 56 load_env(char *, FILE *),
52 cron_pclose(FILE *), 57 cron_pclose(FILE *),
53 glue_strings(char *, size_t, const char *, const char *, char), 58 glue_strings(char *, size_t, const char *, const char *, char),
54 strcmp_until(const char *, const char *, char), 59 strcmp_until(const char *, const char *, char),
55 strdtb(char *); 60 strdtb(char *);
56 61
57size_t strlens(const char *, ...); 62size_t strlens(const char *, ...);
58 63
59char *env_get(const char *, char **), 64char *env_get(const char *, char **),

cvs diff -r1.4 -r1.5 src/external/bsd/cron/dist/misc.c (expand / switch to unified diff)

--- src/external/bsd/cron/dist/misc.c 2017/06/09 17:36:30 1.4
+++ src/external/bsd/cron/dist/misc.c 2017/08/17 08:53:00 1.5
@@ -1,41 +1,41 @@ @@ -1,41 +1,41 @@
1/* $NetBSD: misc.c,v 1.4 2017/06/09 17:36:30 christos Exp $ */ 1/* $NetBSD: misc.c,v 1.5 2017/08/17 08:53:00 christos Exp $ */
2 2
3/* Copyright 1988,1990,1993,1994 by Paul Vixie 3/* Copyright 1988,1990,1993,1994 by Paul Vixie
4 * All rights reserved 4 * All rights reserved
5 */ 5 */
6 6
7/* 7/*
8 * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") 8 * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
9 * Copyright (c) 1997,2000 by Internet Software Consortium, Inc. 9 * Copyright (c) 1997,2000 by Internet Software Consortium, Inc.
10 * 10 *
11 * Permission to use, copy, modify, and distribute this software for any 11 * Permission to use, copy, modify, and distribute this software for any
12 * purpose with or without fee is hereby granted, provided that the above 12 * purpose with or without fee is hereby granted, provided that the above
13 * copyright notice and this permission notice appear in all copies. 13 * copyright notice and this permission notice appear in all copies.
14 * 14 *
15 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES 15 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
16 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 16 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
17 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR 17 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
18 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 18 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 19 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
20 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 20 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
21 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 21 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22 */ 22 */
23#include <sys/cdefs.h> 23#include <sys/cdefs.h>
24#if !defined(lint) && !defined(LINT) 24#if !defined(lint) && !defined(LINT)
25#if 0 25#if 0
26static char rcsid[] = "Id: misc.c,v 1.16 2004/01/23 18:56:43 vixie Exp"; 26static char rcsid[] = "Id: misc.c,v 1.16 2004/01/23 18:56:43 vixie Exp";
27#else 27#else
28__RCSID("$NetBSD: misc.c,v 1.4 2017/06/09 17:36:30 christos Exp $"); 28__RCSID("$NetBSD: misc.c,v 1.5 2017/08/17 08:53:00 christos Exp $");
29#endif 29#endif
30#endif 30#endif
31 31
32/* vix 26jan87 [RCS has the rest of the log] 32/* vix 26jan87 [RCS has the rest of the log]
33 * vix 30dec86 [written] 33 * vix 30dec86 [written]
34 */ 34 */
35 35
36#include "cron.h" 36#include "cron.h"
37#include <limits.h> 37#include <limits.h>
38#include <vis.h> 38#include <vis.h>
39 39
40#if defined(SYSLOG) && defined(LOG_FILE) 40#if defined(SYSLOG) && defined(LOG_FILE)
41# undef LOG_FILE 41# undef LOG_FILE
@@ -302,61 +302,58 @@ acquire_daemonlock(int closeflag) { @@ -302,61 +302,58 @@ acquire_daemonlock(int closeflag) {
302 if (closeflag) { 302 if (closeflag) {
303 /* close stashed fd for child so we don't leak it. */ 303 /* close stashed fd for child so we don't leak it. */
304 if (fd != -1) { 304 if (fd != -1) {
305 (void)close(fd); 305 (void)close(fd);
306 fd = -1; 306 fd = -1;
307 } 307 }
308 return; 308 return;
309 } 309 }
310 310
311 if (fd == -1) { 311 if (fd == -1) {
312 pidfile = _PATH_CRON_PID; 312 pidfile = _PATH_CRON_PID;
313 /* Initial mode is 0600 to prevent flock() race/DoS. */ 313 /* Initial mode is 0600 to prevent flock() race/DoS. */
314 if ((fd = open(pidfile, O_RDWR|O_CREAT, 0600)) == -1) { 314 if ((fd = open(pidfile, O_RDWR|O_CREAT, 0600)) == -1) {
315 (void)snprintf(buf, sizeof(buf), 315 log_itx("CRON", getpid(), "DEATH",
316 "can't open or create %s: %s", 316 "can't open or create %s: %s",
317 pidfile, strerror(errno)); 317 pidfile, strerror(errno));
318 log_it("CRON", getpid(), "DEATH", buf); 318 exit(ERROR_EXIT);
319 errx(ERROR_EXIT, "%s", buf); 
320 } 319 }
321 /* fd must be > STDERR since we dup fd 0-2 to /dev/null */ 320 /* fd must be > STDERR since we dup fd 0-2 to /dev/null */
322 if (fd <= STDERR) { 321 if (fd <= STDERR) {
323 if (dup2(fd, STDERR + 1) < 0) { 322 if (dup2(fd, STDERR + 1) < 0) {
324 snprintf(buf, sizeof buf, 323 log_itx("CRON", getpid(), "DEATH",
325 "can't dup pid fd: %s", strerror(errno)); 324 "can't dup pid fd: %s", strerror(errno));
326 log_it("CRON", getpid(), "DEATH", buf); 
327 exit(ERROR_EXIT); 325 exit(ERROR_EXIT);
328 } 326 }
329 close(fd); 327 close(fd);
330 fd = STDERR + 1; 328 fd = STDERR + 1;
331 } 329 }
332 330
333 if (flock(fd, LOCK_EX|LOCK_NB) < OK) { 331 if (flock(fd, LOCK_EX|LOCK_NB) < OK) {
334 int save_errno = errno; 332 int save_errno = errno;
335 333
336 memset(buf, 0, sizeof(buf)); 334 memset(buf, 0, sizeof(buf));
337 if ((num = read(fd, buf, sizeof(buf) - 1)) > 0 && 335 if ((num = read(fd, buf, sizeof(buf) - 1)) > 0 &&
338 (otherpid = strtol(buf, &ep, 10)) > 0 && 336 (otherpid = strtol(buf, &ep, 10)) > 0 &&
339 ep != buf && *ep == '\n' && otherpid != LONG_MAX) { 337 ep != buf && *ep == '\n' && otherpid != LONG_MAX) {
340 (void)snprintf(buf, sizeof(buf), 338 log_itx("CRON", getpid(), "DEATH",
341 "can't lock %s, otherpid may be %ld: %s", 339 "can't lock %s, otherpid may be %ld: %s",
342 pidfile, otherpid, strerror(save_errno)); 340 pidfile, otherpid, strerror(save_errno));
343 } else { 341 } else {
344 (void)snprintf(buf, sizeof(buf), 342 log_itx("CRON", getpid(), "DEATH",
345 "can't lock %s, otherpid unknown: %s", 343 "can't lock %s, otherpid unknown: %s",
346 pidfile, strerror(save_errno)); 344 pidfile, strerror(save_errno));
347 } 345 }
348 log_it("CRON", getpid(), "DEATH", buf); 346 exit(ERROR_EXIT);
349 errx(ERROR_EXIT, "%s", buf); 
350 } 347 }
351 (void) fchmod(fd, 0644); 348 (void) fchmod(fd, 0644);
352 (void) fcntl(fd, F_SETFD, 1); 349 (void) fcntl(fd, F_SETFD, 1);
353 } 350 }
354 351
355 (void)snprintf(buf, sizeof(buf), "%ld\n", (long)getpid()); 352 (void)snprintf(buf, sizeof(buf), "%ld\n", (long)getpid());
356 (void) lseek(fd, (off_t)0, SEEK_SET); 353 (void) lseek(fd, (off_t)0, SEEK_SET);
357 num = write(fd, buf, strlen(buf)); 354 num = write(fd, buf, strlen(buf));
358 (void) ftruncate(fd, num); 355 (void) ftruncate(fd, num);
359 356
360 /* abandon fd even though the file is open. we need to keep 357 /* abandon fd even though the file is open. we need to keep
361 * it open and locked, but we don't need the handles elsewhere. 358 * it open and locked, but we don't need the handles elsewhere.
362 */ 359 */
@@ -434,70 +431,74 @@ skip_comments(FILE *file) { @@ -434,70 +431,74 @@ skip_comments(FILE *file) {
434 431
435 while (ch != '\n' && ch != EOF) 432 while (ch != '\n' && ch != EOF)
436 ch = get_char(file); 433 ch = get_char(file);
437 434
438 /* ch is now the newline of a line which we're going to 435 /* ch is now the newline of a line which we're going to
439 * ignore. 436 * ignore.
440 */ 437 */
441 } 438 }
442 if (ch != EOF) 439 if (ch != EOF)
443 unget_char(ch, file); 440 unget_char(ch, file);
444} 441}
445 442
446void 443void
 444log_itx(const char *username, PID_T xpid, const char *event, const char *fmt,
 445 ...)
 446{
 447 char *detail;
 448 va_list ap;
 449 va_start(ap, fmt);
 450 if (vasprintf(&detail, fmt, ap) == -1) {
 451 va_end(ap);
 452 return;
 453 }
 454 log_it(username, xpid, event, detail);
 455 free(detail);
 456}
 457
 458void
447log_it(const char *username, PID_T xpid, const char *event, const char *detail) { 459log_it(const char *username, PID_T xpid, const char *event, const char *detail) {
448#if defined(LOG_FILE) || DEBUGGING 460#if defined(LOG_FILE) || DEBUGGING
449 PID_T pid = xpid; 461 PID_T pid = xpid;
450#endif 462#endif
451#if defined(LOG_FILE) 463#if defined(LOG_FILE)
452 char *msg; 464 char *msg;
453 size_t msglen; 465 int msglen;
454 TIME_T now = time((TIME_T) 0); 466 TIME_T now = time((TIME_T) 0);
455 struct tm *t = localtime(&now); 467 struct tm *t = localtime(&now);
456#endif /*LOG_FILE*/ 
457 
458#if defined(LOG_FILE) 
459 /* we assume that MAX_TEMPSTR will hold the date, time, &punctuation. 
460 */ 
461 msglen = strlen(username) + strlen(event) + strlen(detail) + 
462 MAX_TEMPSTR); 
463 msg = malloc(msglen); 
464 if (msg == NULL) 
465 return; 
466 468
467 if (LogFD < OK) { 469 if (LogFD < OK) {
468 LogFD = open(LOG_FILE, O_WRONLY|O_APPEND|O_CREAT, 0600); 470 LogFD = open(LOG_FILE, O_WRONLY|O_APPEND|O_CREAT, 0600);
469 if (LogFD < OK) { 471 if (LogFD < OK) {
470 warn("can't open log file `%s'", LOG_FILE); 472 warn("can't open log file `%s'", LOG_FILE);
471 } else { 473 } else {
472 (void) fcntl(LogFD, F_SETFD, FD_CLOEXEC); 474 (void) fcntl(LogFD, F_SETFD, FD_CLOEXEC);
473 } 475 }
474 } 476 }
475 477
476 /* we have to sprintf() it because fprintf() doesn't always write 478 /* we have to sprintf() it because fprintf() doesn't always write
477 * everything out in one chunk and this has to be atomically appended 479 * everything out in one chunk and this has to be atomically appended
478 * to the log file. 480 * to the log file.
479 */ 481 */
480 (void)snprintf(msg, msglen, 482 msglen = asprintf(&msg,
481 "%s (%02d/%02d-%02d:%02d:%02d-%d) %s (%s)\n", 483 "%s (%02d/%02d-%02d:%02d:%02d-%d) %s (%s)\n", username,
482 username, 484 t->tm_mon + 1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec, pid,
483 t->tm_mon+1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec, pid, 485 event, detail);
484 event, detail); 486 if (msglen == -1)
 487 return;
485 488
486 /* we have to run strlen() because sprintf() returns (char*) on old BSD 489 if (LogFD < OK || write(LogFD, msg, (size_t)msglen) < OK) {
487 */ 
488 if (LogFD < OK || write(LogFD, msg, strlen(msg)) < OK) { 
489 warn("can't write to log file"); 490 warn("can't write to log file");
490 write(STDERR, msg, strlen(msg)); 491 write(STDERR, msg, (size_t)msglen);
491 } 492 }
492 493
493 free(msg); 494 free(msg);
494#endif /*LOG_FILE*/ 495#endif /*LOG_FILE*/
495 496
496#if defined(SYSLOG) 497#if defined(SYSLOG)
497 if (!syslog_open) { 498 if (!syslog_open) {
498# ifdef LOG_DAEMON 499# ifdef LOG_DAEMON
499 openlog(getprogname(), LOG_PID, FACILITY); 500 openlog(getprogname(), LOG_PID, FACILITY);
500# else 501# else
501 openlog(getprogname(), LOG_PID); 502 openlog(getprogname(), LOG_PID);
502# endif 503# endif
503 syslog_open = TRUE; /* assume openlog success */ 504 syslog_open = TRUE; /* assume openlog success */