From: Todd C. Miller Subject: Re: ctime(3) can fail (libexec and sbin) To: Florian Obser Cc: tech@openbsd.org Date: Tue, 07 May 2024 13:32:04 -0600 On Mon, 06 May 2024 21:07:16 +0200, Florian Obser wrote: > anyone? I know this is a pain to review... Most of this looks fine, some comments inline. - todd > diff --git libexec/ftpd/ftpd.c libexec/ftpd/ftpd.c > index 810933525da..1e1e579b316 100644 > --- libexec/ftpd/ftpd.c > +++ libexec/ftpd/ftpd.c > @@ -2739,7 +2739,10 @@ logxfer(const char *name, off_t size, time_t start) > int len; > > if ((statfd >= 0) && (getcwd(dir, sizeof(dir)) != NULL)) { > + char *cnow; > + > time(&now); > + cnow = ctime(&now); > > vpw = malloc(strlen(guest ? guestpw : pw->pw_name) * 4 + 1); > if (vpw == NULL) > @@ -2755,7 +2758,8 @@ logxfer(const char *name, off_t size, time_t start) > > len = snprintf(buf, sizeof(buf), > "%.24s %lld %s %lld %s %c %s %c %c %s ftp %d %s %s\n", > - ctime(&now), (long long)(now - start + (now == start)), > + cnow ? cnow : "?\n", You don't want the trailing newline for this one since "%.24s" is being used to strip the newline from the ctime(3) string. > + (long long)(now - start + (now == start)), > vremotehost, (long long)size, vpath, > ((type == TYPE_A) ? 'a' : 'b'), "*" /* none yet */, > 'o', ((guest) ? 'a' : 'r'), > diff --git libexec/mail.local/mail.local.c libexec/mail.local/mail.local.c > index 7d0dfb4abb1..5885da01351 100644 > --- libexec/mail.local/mail.local.c > +++ libexec/mail.local/mail.local.c > @@ -112,7 +112,7 @@ storemail(char *from) > FILE *fp = NULL; > time_t tval; > int fd, eline = 1; > - char *tbuf, *line = NULL; > + char *tbuf, *line = NULL, *cnow; > size_t linesize = 0; > ssize_t linelen; > > @@ -124,7 +124,8 @@ storemail(char *from) > free(tbuf); > > (void)time(&tval); > - (void)fprintf(fp, "From %s %s", from, ctime(&tval)); > + cnow = ctime(&tval); > + (void)fprintf(fp, "From %s %s", from, cnow ? cnow : "?\n"); > > while ((linelen = getline(&line, &linesize, stdin)) != -1) { > if (line[linelen - 1] == '\n') > diff --git libexec/spamd/spamd.c libexec/spamd/spamd.c > index 1be4c4b5527..0158cf469c6 100644 > --- libexec/spamd/spamd.c > +++ libexec/spamd/spamd.c > @@ -730,6 +730,7 @@ initcon(struct con *cp, int fd, struct sockaddr *sa) > NI_NUMERICHOST); > if (error) > strlcpy(cp->addr, "", sizeof(cp->addr)); > + memset(ctimebuf, 0, sizeof(ctimebuf)); > ctime_r(&t, ctimebuf); > ctimebuf[sizeof(ctimebuf) - 2] = '\0'; /* nuke newline */ > snprintf(cp->obuf, cp->osize, "220 %s ESMTP %s; %s\r\n", > diff --git sbin/dump/itime.c sbin/dump/itime.c > index 4498d91b19c..b445aff5ee3 100644 > --- sbin/dump/itime.c > +++ sbin/dump/itime.c > @@ -162,7 +162,7 @@ putdumptime(void) > FILE *df; > struct dumpdates *dtwalk; > int fd, i; > - char *fname; > + char *fname, *ct; > time_t t; > > if(uflag == 0) > @@ -213,12 +213,21 @@ putdumptime(void) > quit("ftruncate (%s): %s\n", dumpdates, strerror(errno)); > (void) fclose(df); > t = (time_t)spcl.c_date; > - msg("level %c dump on %s", level, t == 0 ? "the epoch\n" : ctime(&t)); > + if (t == 0) > + ct = "the epoch\n"; > + else if ((ct = ctime(&t)) == NULL) > + ct = "?\n"; > + msg("level %c dump on %s", level, ct); > } > > static void > dumprecout(FILE *file, struct dumpdates *what) > { > + char *ct; > + > + ct = ctime(&what->dd_ddate); > + if (ct == NULL) > + quit("Cannot convert date\n"); > > if (fprintf(file, DUMPOUTFMT, > what->dd_name, > @@ -243,8 +252,22 @@ getrecord(FILE *df, struct dumpdates *ddatep) > dumpdates, recno); > > #ifdef FDEBUG > - msg("getrecord: %s %c %s", ddatep->dd_name, ddatep->dd_level, > - ddatep->dd_ddate == 0 ? "the epoch\n" : ctime(&ddatep->dd_ddate)); > + { > + char *ct; > + > + if (ddatep->dd_ddate == 0) > + ct = "the epoch\n"; > + else > + ct = ctime(&ddatep->dd_ddate); > + > + if (ct) > + msg("getrecord: %s %c %s", ddatep->dd_name, > + ddatep->dd_level, ct); > + else > + msg("getrecord: %s %c %lld seconds after the epoch\n", > + ddatep->dd_name, ddatep->dd_level, > + ddatep->dd_ddate); > + } > #endif > return(0); > } > diff --git sbin/dump/main.c sbin/dump/main.c > index a5071abedd3..a4c9c5972dc 100644 > --- sbin/dump/main.c > +++ sbin/dump/main.c > @@ -117,7 +117,7 @@ main(int argc, char *argv[]) > ino_t maxino; > time_t t; > int dirlist; > - char *toplevel, *str, *mount_point = NULL, *realpath; > + char *toplevel, *str, *mount_point = NULL, *realpath, *ct; > int just_estimate = 0; > u_int64_t zero_uid = 0; > > @@ -423,11 +423,13 @@ main(int argc, char *argv[]) > getdumptime(); /* /etc/dumpdates snarfed */ > > t = (time_t)spcl.c_date; > + ct = ctime(&t); > msg("Date of this level %c dump: %s", level, > - t == 0 ? "the epoch\n" : ctime(&t)); > + t == 0 ? "the epoch\n" : ct ? ct : "?\n"); > t = (time_t)spcl.c_ddate; > + ct = ctime(&t); > msg("Date of last level %c dump: %s", lastlevel, > - t == 0 ? "the epoch\n" : ctime(&t)); > + t == 0 ? "the epoch\n" : ct ? ct : "?\n"); > msg("Dumping %s ", disk); > if (mount_point != NULL) > msgtail("(%s) ", mount_point); > @@ -589,10 +591,12 @@ main(int argc, char *argv[]) > spcl.c_tapea, spcl.c_volume, > (spcl.c_volume == 1) ? "" : "s"); > t = (time_t)spcl.c_date; > + ct = ctime(&t); > msg("Date of this level %c dump: %s", level, > - t == 0 ? "the epoch\n" : ctime(&t)); > + t == 0 ? "the epoch\n" : ct ? ct : "?\n"); > t = do_stats(); > - msg("Date this dump completed: %s", ctime(&t)); > + ct = ctime(&t); > + msg("Date this dump completed: %s", ct ? ct : "?\n"); > msg("Average transfer rate: %ld KB/s\n", xferrate / tapeno); > putdumptime(); > trewind(); > diff --git sbin/dump/optr.c sbin/dump/optr.c > index 43f11d58457..4080f8b7904 100644 > --- sbin/dump/optr.c > +++ sbin/dump/optr.c > @@ -394,8 +394,11 @@ lastdump(int arg) > if (strncmp(lastname, dtwalk->dd_name, > sizeof(dtwalk->dd_name)) == 0) > continue; > - date = (char *)ctime(&dtwalk->dd_ddate); > - date[16] = '\0'; /* blast away seconds and year */ > + date = ctime(&dtwalk->dd_ddate); > + if (date) > + date[16] = '\0'; /* blast away seconds and year */ > + else > + date = "?"; > lastname = dtwalk->dd_name; > dt = fstabsearch(dtwalk->dd_name); > dumpme = (dt != NULL && > diff --git sbin/dump/tape.c sbin/dump/tape.c > index 835fd223835..018dae905a5 100644 > --- sbin/dump/tape.c > +++ sbin/dump/tape.c > @@ -231,11 +231,13 @@ do_stats(void) > { > time_t tnow, ttaken; > int64_t blocks; > + char *ct; > > (void)time(&tnow); > ttaken = tnow - tstart_volume; > blocks = spcl.c_tapea - tapea_volume; > - msg("Volume %d completed at: %s", tapeno, ctime(&tnow)); > + ct = ctime(&tnow); > + msg("Volume %d completed at: %s", tapeno, ct ? ct : "?\n"); > if (ttaken > 0) { > msg("Volume %d took %lld:%02lld:%02lld\n", tapeno, > (long long)ttaken / 3600, ((long long)ttaken % 3600) / 60, > @@ -565,7 +567,7 @@ startnewtape(int top) > pid_t childpid; > int status; > pid_t waitingpid; > - char *p; > + char *p, *ct; > sig_t interrupt_save; > > interrupt_save = signal(SIGINT, SIG_IGN); > @@ -688,7 +690,8 @@ restore_check_point: > writeheader((ino_t)slp->inode); > if (sblock->fs_magic != FS_UFS2_MAGIC) > spcl.c_flags &=~ DR_NEWHEADER; > - msg("Volume %d started at: %s", tapeno, ctime(&tstart_volume)); > + ct = ctime(&tstart_volume); > + msg("Volume %d started at: %s", tapeno, ct ? ct : "?\n"); > if (tapeno > 1) > msg("Volume %d begins with blocks from inode %llu\n", > tapeno, (unsigned long long)slp->inode); > diff --git sbin/dumpfs/dumpfs.c sbin/dumpfs/dumpfs.c > index 481f5b41e95..ee652614950 100644 > --- sbin/dumpfs/dumpfs.c > +++ sbin/dumpfs/dumpfs.c > @@ -163,13 +163,19 @@ dumpfs(int fd, const char *name) > off_t off; > int i, j; > u_int cg; > + char *ct; > > switch (afs.fs_magic) { > case FS_UFS2_MAGIC: > fssize = afs.fs_size; > fstime = afs.fs_time; > - printf("magic\t%x (FFS2)\ttime\t%s", > - afs.fs_magic, ctime(&fstime)); > + ct = ctime(&fstime); > + if (ct) > + printf("magic\t%x (FFS2)\ttime\t%s", > + afs.fs_magic, ctime(&fstime)); > + else > + printf("magic\t%x (FFS2)\ttime\t%lld\n", > + afs.fs_magic, fstime); > printf("superblock location\t%jd\tid\t[ %x %x ]\n", > (intmax_t)afs.fs_sblockloc, afs.fs_id[0], afs.fs_id[1]); > printf("ncg\t%u\tsize\t%jd\tblocks\t%jd\n", > @@ -178,8 +184,13 @@ dumpfs(int fd, const char *name) > case FS_UFS1_MAGIC: > fssize = afs.fs_ffs1_size; > fstime = afs.fs_ffs1_time; > - printf("magic\t%x (FFS1)\ttime\t%s", > - afs.fs_magic, ctime(&fstime)); > + ct = ctime(&fstime); > + if (ct) > + printf("magic\t%x (FFS1)\ttime\t%s", > + afs.fs_magic, ctime(&fstime)); > + else > + printf("magic\t%x (FFS1)\ttime\t%lld\n", > + afs.fs_magic, fstime); > printf("id\t[ %x %x ]\n", afs.fs_id[0], afs.fs_id[1]); > i = 0; > if (afs.fs_postblformat != FS_42POSTBLFMT) { > @@ -325,6 +336,7 @@ dumpcg(const char *name, int fd, u_int c) > time_t cgtime; > off_t cur; > int i, j; > + char *ct; > > printf("\ncg %u:\n", c); > cur = (off_t)fsbtodb(&afs, cgtod(&afs, c)) * DEV_BSIZE; > @@ -335,18 +347,30 @@ dumpcg(const char *name, int fd, u_int c) > switch (afs.fs_magic) { > case FS_UFS2_MAGIC: > cgtime = acg.cg_ffs2_time; > - printf("magic\t%x\ttell\t%jx\ttime\t%s", > - acg.cg_magic, (intmax_t)cur, ctime(&cgtime)); > + ct = ctime(&cgtime); > + if (ct) > + printf("magic\t%x\ttell\t%jx\ttime\t%s", > + acg.cg_magic, (intmax_t)cur, ct); > + else > + printf("magic\t%x\ttell\t%jx\ttime\t%lld\n", > + acg.cg_magic, (intmax_t)cur, cgtime); > printf("cgx\t%u\tndblk\t%u\tniblk\t%u\tinitiblk %u\n", > acg.cg_cgx, acg.cg_ndblk, acg.cg_ffs2_niblk, > acg.cg_initediblk); > break; > case FS_UFS1_MAGIC: > cgtime = acg.cg_time; > - printf("magic\t%x\ttell\t%jx\ttime\t%s", > - afs.fs_postblformat == FS_42POSTBLFMT ? > - ((struct ocg *)&acg)->cg_magic : acg.cg_magic, > - (intmax_t)cur, ctime(&cgtime)); > + ct = ctime(&cgtime); > + if (ct) > + printf("magic\t%x\ttell\t%jx\ttime\t%s", > + afs.fs_postblformat == FS_42POSTBLFMT ? > + ((struct ocg *)&acg)->cg_magic : acg.cg_magic, > + (intmax_t)cur, ct); > + else > + printf("magic\t%x\ttell\t%jx\ttime\t%lld\n", > + afs.fs_postblformat == FS_42POSTBLFMT ? > + ((struct ocg *)&acg)->cg_magic : acg.cg_magic, > + (intmax_t)cur, cgtime); > printf("cgx\t%u\tncyl\t%d\tniblk\t%d\tndblk\t%u\n", > acg.cg_cgx, acg.cg_ncyl, acg.cg_niblk, acg.cg_ndblk); > break; > diff --git sbin/fsck_ext2fs/inode.c sbin/fsck_ext2fs/inode.c > index a1861b08623..e1bf9a89348 100644 > --- sbin/fsck_ext2fs/inode.c > +++ sbin/fsck_ext2fs/inode.c > @@ -581,7 +581,10 @@ pinode(ino_t ino) > printf("SIZE=%llu ", (long long)inosize(dp)); > t = (time_t) letoh32(dp->e2di_mtime); > p = ctime(&t); > - printf("MTIME=%12.12s %4.4s ", &p[4], &p[20]); > + if (p) > + printf("MTIME=%12.12s %4.4s ", &p[4], &p[20]); > + else > + printf("MTIME=%lld ", t); > } > > void > diff --git sbin/fsck_ext2fs/pass1.c sbin/fsck_ext2fs/pass1.c > index 377852c1c80..e30e67f3c14 100644 > --- sbin/fsck_ext2fs/pass1.c > +++ sbin/fsck_ext2fs/pass1.c > @@ -167,8 +167,12 @@ checkinode(ino_t inumber, struct inodesc *idesc) > if (dp->e2di_dtime != 0) { > time_t t = letoh32(dp->e2di_dtime); > char *p = ctime(&t); > - pwarn("INODE I=%llu HAS DTIME=%12.12s %4.4s", > - (unsigned long long)inumber, &p[4], &p[20]); > + if (p) > + pwarn("INODE I=%llu HAS DTIME=%12.12s %4.4s", > + (unsigned long long)inumber, &p[4], &p[20]); > + else > + pwarn("INODE I=%llu HAS DTIME=%lld", > + (unsigned long long)inumber, t); > if (preen) { > printf(" (CORRECTED)\n"); > } > diff --git sbin/fsck_ffs/inode.c sbin/fsck_ffs/inode.c > index ebda1d4a10d..831d8f30be8 100644 > --- sbin/fsck_ffs/inode.c > +++ sbin/fsck_ffs/inode.c > @@ -544,7 +544,10 @@ pinode(ino_t ino) > printf("SIZE=%llu ", (unsigned long long)DIP(dp, di_size)); > t = DIP(dp, di_mtime); > p = ctime(&t); > - printf("MTIME=%12.12s %4.4s ", &p[4], &p[20]); > + if (p) > + printf("MTIME=%12.12s %4.4s ", &p[4], &p[20]); > + else > + printf("MTIME=%lld ", t); > } > > void > diff --git sbin/fsdb/fsdbutil.c sbin/fsdb/fsdbutil.c > index cb6e842a747..2bc8113cff4 100644 > --- sbin/fsdb/fsdbutil.c > +++ sbin/fsdb/fsdbutil.c > @@ -127,17 +127,25 @@ printstat(const char *cp, ino_t inum, union dinode *dp) > DIP(dp, di_mode), DIP(dp, di_size)); > t = DIP(dp, di_mtime); > p = ctime(&t); > - printf("\n\tMTIME=%15.15s %4.4s [%d nsec]", &p[4], &p[20], > - DIP(dp, di_mtimensec)); > + if (p) > + printf("\n\tMTIME=%15.15s %4.4s [%d nsec]", &p[4], &p[20], > + DIP(dp, di_mtimensec)); > + else > + printf("\n\tMTIME=%lld [%d nsec]", t, DIP(dp, di_mtimensec)); > t = DIP(dp, di_ctime); > p = ctime(&t); > - printf("\n\tCTIME=%15.15s %4.4s [%d nsec]", &p[4], &p[20], > - DIP(dp, di_ctimensec)); > + if (p) > + printf("\n\tCTIME=%15.15s %4.4s [%d nsec]", &p[4], &p[20], > + DIP(dp, di_ctimensec)); > + else > + printf("\n\tCTIME=%lld [%d nsec]", t, DIP(dp, di_ctimensec)); > t = DIP(dp, di_atime); > p = ctime(&t); > - printf("\n\tATIME=%15.15s %4.4s [%d nsec]\n", &p[4], &p[20], > - DIP(dp, di_atimensec)); > - > + if (p) > + printf("\n\tATIME=%15.15s %4.4s [%d nsec]\n", &p[4], &p[20], > + DIP(dp, di_atimensec)); > + else > + printf("\n\tATIME=%lld [%d nsec]\n", t, DIP(dp, di_atimensec)); > if ((name = user_from_uid(DIP(dp, di_uid), 1)) != NULL) > printf("OWNER=%s ", name); > else > diff --git sbin/fsirand/fsirand.c sbin/fsirand/fsirand.c > index 8aef979ae94..7ab7a53664d 100644 > --- sbin/fsirand/fsirand.c > +++ sbin/fsirand/fsirand.c > @@ -226,8 +226,13 @@ fsirand(char *device) > if (printonly && (sblock->fs_id[0] || sblock->fs_id[1])) { > if (sblock->fs_inodefmt >= FS_44INODEFMT && sblock->fs_id[0]) { > time_t t = sblock->fs_id[0]; /* XXX 2038 */ > - (void)printf("%s was randomized on %s", devpath, > - ctime(&t)); > + char *ct = ctime(&t); > + if (ct) > + (void)printf("%s was randomized on %s", devpath > , > + ct); > + else > + (void)printf("%s was randomized on %lld\n", > + devpath, t); > } > (void)printf("fsid: %x %x\n", sblock->fs_id[0], > sblock->fs_id[1]); > diff --git sbin/mount/mount.c sbin/mount/mount.c > index eaff190b572..b830077c432 100644 > --- sbin/mount/mount.c > +++ sbin/mount/mount.c > @@ -503,9 +503,11 @@ prmount(struct statfs *sf) > char buf[26]; > time_t t = sf->f_ctime; > > - ctime_r(&t, buf); > - buf[24] = '\0'; > - printf(", ctime=%s", buf); > + if (ctime_r(&t, buf)) { > + buf[24] = '\0'; > + printf(", ctime=%s", buf); To avoid the newline this could simply be: printf(", ctime=%.24s", buf); > + } else > + printf(", ctime=%lld", t); > } > > /* > diff --git sbin/pfctl/pfctl_table.c sbin/pfctl/pfctl_table.c > index ba21402943d..d649fb8c3b3 100644 > --- sbin/pfctl/pfctl_table.c > +++ sbin/pfctl/pfctl_table.c > @@ -389,14 +389,19 @@ print_table(struct pfr_table *ta, int verbose, int debu > g) > void > print_tstats(struct pfr_tstats *ts, int debug) > { > - time_t time = ts->pfrts_tzero; > - int dir, op; > + time_t time = ts->pfrts_tzero; > + int dir, op; > + char *ct; > > if (!debug && !(ts->pfrts_flags & PFR_TFLAG_ACTIVE)) > return; > + ct = ctime(&time); > print_table(&ts->pfrts_t, 1, debug); > printf("\tAddresses: %d\n", ts->pfrts_cnt); > - printf("\tCleared: %s", ctime(&time)); > + if (ct) > + printf("\tCleared: %s", ct); > + else > + printf("\tCleared: %lld\n", time); > printf("\tReferences: [ Anchors: %-18d Rules: %-18d ]\n", > ts->pfrts_refcnt[PFR_REFCNT_ANCHOR], > ts->pfrts_refcnt[PFR_REFCNT_RULE]); > @@ -487,11 +492,16 @@ print_addrx(struct pfr_addr *ad, struct pfr_addr *rad, > int dns) > void > print_astats(struct pfr_astats *as, int dns) > { > - time_t time = as->pfras_tzero; > - int dir, op; > + time_t time = as->pfras_tzero; > + int dir, op; > + char *ct; > > + ct = ctime(&time); > print_addrx(&as->pfras_a, NULL, dns); > - printf("\tCleared: %s", ctime(&time)); > + if (ct) > + printf("\tCleared: %s", ctime(&time)); > + else > + printf("\tCleared: %lld\n", time); > if (as->pfras_a.pfra_states) > printf("\tActive States: %d\n", as->pfras_a.pfra_states); > if (as->pfras_a.pfra_type == PFRKE_COST) > @@ -603,8 +613,9 @@ pfctl_show_ifaces(const char *filter, int opts) > void > print_iface(struct pfi_kif *p, int opts) > { > - time_t tzero = p->pfik_tzero; > - int i, af, dir, act; > + time_t tzero = p->pfik_tzero; > + int i, af, dir, act; > + char *ct; > > printf("%s", p->pfik_name); > if (opts & PF_OPT_VERBOSE) { > @@ -615,7 +626,12 @@ print_iface(struct pfi_kif *p, int opts) > > if (!(opts & PF_OPT_VERBOSE2)) > return; > - printf("\tCleared: %s", ctime(&tzero)); > + > + ct = ctime(&tzero); > + if (ct) > + printf("\tCleared: %s", ct); > + else > + printf("\tCleared: %lld\n", tzero); > printf("\tReferences: [ States: %-18d Rules: %-18d ]\n", > p->pfik_states, p->pfik_rules); > for (i = 0; i < 8; i++) { > diff --git sbin/restore/tape.c sbin/restore/tape.c > index 4288c79e1a6..6ecc6623904 100644 > --- sbin/restore/tape.c > +++ sbin/restore/tape.c > @@ -387,8 +387,17 @@ gethdr: > } > if (tmpbuf.c_date != dumpdate || tmpbuf.c_ddate != dumptime) { > time_t t = (time_t)tmpbuf.c_date; > - fprintf(stderr, "Wrong dump date\n\tgot: %s", ctime(&t)); > - fprintf(stderr, "\twanted: %s", ctime(&dumpdate)); > + char *ct1, *ct2; > + > + ct1 = ctime(&t); > + ct2 = ctime(&dumpdate); This won't work since ctime() uses static storage. Both ct1 and ct2 will point to the same string. Either use ctime_r() with separate buffers or just do the ctime() + fprintf() bits separately. > + if (ct1 && ct2) { > + fprintf(stderr, "Wrong dump date\n\tgot: %s", ct1); > + fprintf(stderr, "\twanted: %s", ct2); > + } else { > + fprintf(stderr, "Wrong dump date\n\tgot: %lld\n", t); > + fprintf(stderr, "\twanted: %lld\n", dumpdate); > + } > volno = 0; > goto again; > } > @@ -488,12 +497,21 @@ void > printdumpinfo(void) > { > time_t t; > + char *ct; > > t = (time_t)spcl.c_date; > - fprintf(stdout, "Dump date: %s", ctime(&t)); > + ct = ctime(&t); > + if (ct) > + fprintf(stdout, "Dump date: %s", ct); > + else > + fprintf(stdout, "Dump date: %lld\n", t); > t = (time_t)spcl.c_ddate; > - fprintf(stdout, "Dumped from: %s", > - (spcl.c_ddate == 0) ? "the epoch\n" : ctime(&t)); > + ct = ctime(&t); > + if (ct) > + fprintf(stdout, "Dumped from: %s", > + (spcl.c_ddate == 0) ? "the epoch\n" : ct); > + else > + fprintf(stdout, "Dumped from: %lld\n", t); > if (spcl.c_host[0] == '\0') > return; > fprintf(stderr, "Level %d dump of %s on %s:%s\n", > diff --git sbin/route/route.c sbin/route/route.c > index 4228114edc7..16c3a947dcb 100644 > --- sbin/route/route.c > +++ sbin/route/route.c > @@ -1140,6 +1140,7 @@ monitor(int argc, char *argv[]) > int n; > char msg[2048]; > time_t now; > + char *ct; > > verbose = 1; > for (;;) { > @@ -1149,7 +1150,11 @@ monitor(int argc, char *argv[]) > err(1, "read"); > } > now = time(NULL); > - printf("got message of size %d on %s", n, ctime(&now)); > + ct = ctime(&now); > + if (ct) > + printf("got message of size %d on %s", n, ct); > + else > + printf("got message of size %d on %lld\n", n, now); > print_rtmsg((struct rt_msghdr *)msg, n); > } > } > diff --git sbin/savecore/savecore.c sbin/savecore/savecore.c > index afc223e5a08..7307c1d1ace 100644 > --- sbin/savecore/savecore.c > +++ sbin/savecore/savecore.c > @@ -608,6 +608,7 @@ int > get_crashtime(void) > { > time_t dumptime; /* Time the dump was taken. */ > + char *ct; > > (void)KREAD(kd_dump, dump_nl[X_TIME].n_value, &dumptime); > if (dumptime == 0) { > @@ -615,7 +616,12 @@ get_crashtime(void) > syslog(LOG_ERR, "dump time is zero"); > return (0); > } > - (void)printf("savecore: system went down at %s", ctime(&dumptime)); > + ct = ctime(&dumptime); > + if (ct) > + printf("savecore: system went down at %s", ct); > + else > + printf("savecore: system went down %lld seconds after the" > + " epoch\n", dumptime); > #define SECSPERDAY (24 * 60 * 60) > #define LEEWAY (7 * SECSPERDAY) > if (dumptime < now - LEEWAY || dumptime > now + LEEWAY) { > diff --git sbin/scan_ffs/scan_ffs.c sbin/scan_ffs/scan_ffs.c > index d1b673c4dca..62346d33aa8 100644 > --- sbin/scan_ffs/scan_ffs.c > +++ sbin/scan_ffs/scan_ffs.c > @@ -47,6 +47,28 @@ > > static void usage(void); > > +static void > +print_info(int flags, struct fs *sb, long long at, char* lastmount) > +{ > + if (flags & FLAG_LABELS ) { > + printf("X: %lld %lld 4.2BSD %d %d %d # %s\n", > + ((off_t)sb->fs_ffs1_size * sb->fs_fsize / 512), at, > + sb->fs_fsize, sb->fs_bsize, sb->fs_cpg, lastmount); > + } else { > + /* XXX 2038 */ > + time_t t = sb->fs_ffs1_time; > + char *ct = ctime(&t); > + if (ct) > + printf("ffs at %lld size %lld mount %s time %s", at, > + (long long)(off_t) sb->fs_ffs1_size * sb->fs_fsize, > + lastmount, ct); > + else > + printf("ffs at %lld size %lld mount %s time %lld\n", at > , > + (long long)(off_t) sb->fs_ffs1_size * sb->fs_fsize, > + lastmount, t); > + } > +} > + > static int > ufsscan(int fd, daddr_t beg, daddr_t end, int flags) > { > @@ -76,27 +98,9 @@ ufsscan(int fd, daddr_t beg, daddr_t end, int flags) > sb->fs_ffs1_size); > > if (((blk+(n/512)) - lastblk) == (SBSIZE/512)) > { > - if (flags & FLAG_LABELS ) { > - printf("X: %lld %lld 4.2BSD %d > %d %d # %s\n", > - ((off_t)sb->fs_ffs1_size * > - sb->fs_fsize / 512), > - (long long)(blk + (n/512) - > - (2*SBSIZE/512)), > - sb->fs_fsize, sb->fs_bsize, > - sb->fs_cpg, lastmount); > - } else { > - /* XXX 2038 */ > - time_t t = sb->fs_ffs1_time; > - > - printf("ffs at %lld size %lld " > - "mount %s time %s", > - (long long)(blk+(n/512) - > - (2*SBSIZE/512)), > - (long long)(off_t)sb->fs_ff > s1_size * > - sb->fs_fsize, > - lastmount, ctime(&t)); > - } > - > + print_info(flags, sb, > + (long long)(blk + (n/512) - > + (2*SBSIZE/512)), lastmount); > if (flags & FLAG_SMART) { > off_t size = (off_t)sb->fs_ffs1 > _size * > sb->fs_fsize; > diff --git sbin/sysctl/sysctl.c sbin/sysctl/sysctl.c > index 9beb8167536..dc1ef4e3b3d 100644 > --- sbin/sysctl/sysctl.c > +++ sbin/sysctl/sysctl.c > @@ -937,8 +937,14 @@ parse(char *string, int flags) > struct timeval *btp = (struct timeval *)buf; > > if (!nflag) { > + char *ct; > boottime = btp->tv_sec; > - (void)printf("%s%s%s", string, equ, ctime(&boottime)); > + ct = ctime(&boottime); > + if (ct) > + (void)printf("%s%s%s", string, equ, ct); > + else > + (void)printf("%s%s%lld\n", string, equ, > + boottime); > } else > (void)printf("%lld\n", (long long)btp->tv_sec); > return; > @@ -2855,9 +2861,11 @@ print_sensor(struct sensor *s) > time_t t = s->tv.tv_sec; > char ct[26]; > > - ctime_r(&t, ct); > - ct[19] = '\0'; > - printf(", %s.%03ld", ct, s->tv.tv_usec / 1000); > + if (ctime_r(&t, ct)) { > + ct[19] = '\0'; > + printf(", %s.%03ld", ct, s->tv.tv_usec / 1000); > + } else > + printf(", %lld.%03ld", t, s->tv.tv_usec / 1000); > } > } > > diff --git sbin/unwind/libunbound/validator/autotrust.c sbin/unwind/libunboun > d/validator/autotrust.c > index 3eb13b35c22..2c386644d7a 100644 > --- sbin/unwind/libunbound/validator/autotrust.c > +++ sbin/unwind/libunbound/validator/autotrust.c > @@ -1084,7 +1084,11 @@ trustanchor_state2str(autr_state_type s) > /** ctime r for autotrust */ > static char* autr_ctime_r(time_t* t, char* s) > { > - ctime_r(t, s); > + if (ctime_r(t, s) == NULL) { > + s[0] = '?'; > + s[1] = '\n'; > + s[2] = '\0'; > + } > #ifdef USE_WINSOCK > if(strlen(s) > 10 && s[7]==' ' && s[8]=='0') > s[8]=' '; /* fix error in windows ctime */ >