* ntp_crypto.c string buffer safety.
* Remove use of MAXFILENAME in mode 7 (ntpdc) on-wire structs.
* Change ntpd MAXFILENAME from 128 to 256 to match ntp-keygen.
+* Buffer safety and sign extension fixes (thanks Coverity Scan).
(4.2.7p147) 2011/04/07 Released by Harlan Stenn <stenn@ntp.org>
* [Bug 1875] 'asn2ntp()' rewritten with 'caltontp()'; 'timegm()'
substitute likely to crash with 64bit time_t.
int trace /* trace flags */ )
{
TTY ttyb;
- int fd, flags;
+ int fd;
+ int flags;
+ int rc;
+ int saved_errno;
flags = trace;
fd = tty_open(device, O_RDWR, 0777);
if (fd < 0)
- return (fd);
+ return -1;
- tcgetattr(fd, &ttyb);
+ rc = tcgetattr(fd, &ttyb);
+ if (rc < 0) {
+ saved_errno = errno;
+ close(fd);
+ errno = saved_errno;
+ return -1;
+ }
ttyb.c_iflag = 0; /* input modes */
ttyb.c_oflag = 0; /* output modes */
ttyb.c_cflag = IBAUD|CS8|CLOCAL; /* control modes (no read) */
cfsetispeed(&ttyb, (u_int)speed);
cfsetospeed(&ttyb, (u_int)speed);
tcsetattr(fd, TCSANOW, &ttyb);
+ if (rc < 0) {
+ saved_errno = errno;
+ close(fd);
+ errno = saved_errno;
+ return -1;
+ }
return (fd);
}
retval = *((*bufpp)++);
retval |= *((*bufpp)++) << 8;
retval |= *((*bufpp)++) << 16;
- retval |= *((*bufpp)++) << 24;
+ retval |= (u_long)*((*bufpp)++) << 24;
return retval;
}
{
long retval;
- retval = *((*bufpp)++) << 24;
+ retval = (u_long)*((*bufpp)++) << 24;
retval |= *((*bufpp)++) << 16;
retval |= *((*bufpp)++) << 8;
retval |= *((*bufpp)++);
mantissa_high = 0;
mantissa_low = (val &0x7F) << 16;
- mantissa_low |= get_byte(bufp, offsets, &fieldindex) << 8;
+ mantissa_low |= (u_long)get_byte(bufp, offsets, &fieldindex) << 8;
mantissa_low |= get_byte(bufp, offsets, &fieldindex);
break;
characteristic |= (val & 0xF0) >> 4; /* grab lower characteristic bits */
mantissa_high = (val & 0x0F) << 16;
- mantissa_high |= get_byte(bufp, offsets, &fieldindex) << 8;
+ mantissa_high |= (u_long)get_byte(bufp, offsets, &fieldindex) << 8;
mantissa_high |= get_byte(bufp, offsets, &fieldindex);
- mantissa_low = get_byte(bufp, offsets, &fieldindex) << 24;
- mantissa_low |= get_byte(bufp, offsets, &fieldindex) << 16;
- mantissa_low |= get_byte(bufp, offsets, &fieldindex) << 8;
+ mantissa_low = (u_long)get_byte(bufp, offsets, &fieldindex) << 24;
+ mantissa_low |= (u_long)get_byte(bufp, offsets, &fieldindex) << 16;
+ mantissa_low |= (u_long)get_byte(bufp, offsets, &fieldindex) << 8;
mantissa_low |= get_byte(bufp, offsets, &fieldindex);
break;
static int fg_start (int, struct peer *);
static void fg_shutdown (int, struct peer *);
static void fg_poll (int, struct peer *);
-static void fg_receive (struct recvbuf *);
+static void fg_receive (struct recvbuf *);
/*
* Forum Graphic unit control structure
*/
struct fgunit {
- int pollnum; /* Use peer.poll instead? */
- int status; /* Hug to check status information on GPS */
- int y2kwarn; /* Y2K bug */
+ int pollnum; /* Use peer.poll instead? */
+ int status; /* Hug to check status information on GPS */
+ int y2kwarn; /* Y2K bug */
};
/*
* Transfer vector
*/
struct refclock refclock_fg = {
- fg_start, /* start up driver */
- fg_shutdown, /* shut down driver */
- fg_poll, /* transmit poll message */
- noentry, /* not used */
- noentry, /* initialize driver (not used) */
- noentry, /* not used */
- NOFLAGS /* not used */
+ fg_start, /* start up driver */
+ fg_shutdown, /* shut down driver */
+ fg_poll, /* transmit poll message */
+ noentry, /* not used */
+ noentry, /* initialize driver (not used) */
+ noentry, /* not used */
+ NOFLAGS /* not used */
};
/*
static int
fg_init(
- int fd
- )
+ int fd
+ )
{
if (write(fd, fginit, LENFG) != LENFG)
- return 0;
-
- return (1);
+ return 0;
+ return 1;
}
/*
/*
* Open device file for reading.
*/
- (void)sprintf(device, DEVICE, unit);
+ snprintf(device, sizeof(device), DEVICE, unit);
DPRINTF(1, ("starting FG with device %s\n",device));
pp = peer->procptr;
- /*
- * Time to poll the clock. The FG clock responds to a
- * "<DLE>D<DLE><CR>" by returning a timecode in the format specified
- * above. If nothing is heard from the clock for two polls,
- * declare a timeout and keep going.
- */
+ /*
+ * Time to poll the clock. The FG clock responds to a
+ * "<DLE>D<DLE><CR>" by returning a timecode in the format specified
+ * above. If nothing is heard from the clock for two polls,
+ * declare a timeout and keep going.
+ */
if (write(pp->io.fd, fgdate, LENFG) != LENFG)
- refclock_report(peer, CEVNT_FAULT);
- else
- pp->polls++;
+ refclock_report(peer, CEVNT_FAULT);
+ else
+ pp->polls++;
- if (peer->burst > 0)
- return;
+ if (peer->burst > 0)
+ return;
/*
- if (pp->coderecv == pp->codeproc) {
- refclock_report(peer, CEVNT_TIMEOUT);
- return;
- }
+ if (pp->coderecv == pp->codeproc) {
+ refclock_report(peer, CEVNT_TIMEOUT);
+ return;
+ }
*/
- peer->burst = NSTAGE;
+ peer->burst = NSTAGE;
- record_clock_stats(&peer->srcadr, pp->a_lastcode);
-
+ record_clock_stats(&peer->srcadr, pp->a_lastcode);
return;
*/
static void
fg_receive(
- struct recvbuf *rbufp
- )
+ struct recvbuf *rbufp
+ )
{
- struct refclockproc *pp;
+ struct refclockproc *pp;
struct fgunit *up;
- struct peer *peer;
+ struct peer *peer;
char *bpt;
- /*
- * Initialize pointers and read the timecode and timestamp
+ /*
+ * Initialize pointers and read the timecode and timestamp
* We can't use gtlin function because we need bynary data in buf */
- peer = rbufp->recv_peer;
- pp = peer->procptr;
- up = pp->unitptr;
+ peer = rbufp->recv_peer;
+ pp = peer->procptr;
+ up = pp->unitptr;
/*
- * Below hug to implement receiving of status information
- */
- if(!up->pollnum)
- {
+ * Below hug to implement receiving of status information
+ */
+ if(!up->pollnum) {
up->pollnum++;
return;
}
- if (rbufp->recv_length < (LENFG-2))
- {
+ if (rbufp->recv_length < (LENFG - 2)) {
refclock_report(peer, CEVNT_BADREPLY);
- return; /* The reply is invalid discard it. */
+ return; /* The reply is invalid discard it. */
}
/* Below I trying to find a correct reply in buffer.
*/
bpt = (char *)rbufp->recv_space.X_recv_buffer;
- while(*bpt != '\10')
+ while (*bpt != '\x10')
bpt++;
#define BP2(x) ( bpt[x] & 15 )
#define BP1(x) (( bpt[x] & 240 ) >> 4)
- pp->year = BP1(2)*10 + BP2(2);
+ pp->year = BP1(2) * 10 + BP2(2);
- if(pp->year == 94)
- {
+ if (pp->year == 94) {
refclock_report(peer, CEVNT_BADREPLY);
- if(!fg_init(pp->io.fd))
+ if (!fg_init(pp->io.fd))
refclock_report(peer, CEVNT_FAULT);
- return;
+ return;
/* GPS is just powered up. The date is invalid -
discarding it. Initilize GPS one more time */
/* Sorry - this driver will broken in 2094 ;) */
}
if (pp->year < 99)
- pp->year += 100;
+ pp->year += 100;
- pp->year += 1900;
- pp->day = 100 * BP2(3) + 10 * BP1(4) + BP2(4);
+ pp->year += 1900;
+ pp->day = 100 * BP2(3) + 10 * BP1(4) + BP2(4);
/*
After Jan, 10 2000 Forum Graphic GPS receiver had a very strange
Hope it is a problem of my unit only and not a Y2K problem of FG GPS.
Below small code to avoid such situation.
*/
- if(up->y2kwarn > 10)
- pp->hour = BP1(6)*10 + BP2(6);
+ if (up->y2kwarn > 10)
+ pp->hour = BP1(6)*10 + BP2(6);
else
- pp->hour = BP1(5)*10 + BP2(5);
-
- if((up->y2kwarn > 10) && (pp->hour == 10))
- {
- pp->minute = BP1(7)*10 + BP2(7);
- pp->second = BP1(8)*10 + BP2(8);
- pp->nsec = (BP1(9)*10 + BP2(9)) * 1000000;
- pp->nsec += BP1(10) * 1000;
+ pp->hour = BP1(5)*10 + BP2(5);
+
+ if ((up->y2kwarn > 10) && (pp->hour == 10)) {
+ pp->minute = BP1(7)*10 + BP2(7);
+ pp->second = BP1(8)*10 + BP2(8);
+ pp->nsec = (BP1(9)*10 + BP2(9)) * 1000000;
+ pp->nsec += BP1(10) * 1000;
} else {
- pp->hour = BP1(5)*10 + BP2(5);
- pp->minute = BP1(6)*10 + BP2(6);
- pp->second = BP1(7)*10 + BP2(7);
- pp->nsec = (BP1(8)*10 + BP2(8)) * 1000000;
- pp->nsec += BP1(9) * 1000;
+ pp->hour = BP1(5)*10 + BP2(5);
+ pp->minute = BP1(6)*10 + BP2(6);
+ pp->second = BP1(7)*10 + BP2(7);
+ pp->nsec = (BP1(8)*10 + BP2(8)) * 1000000;
+ pp->nsec += BP1(9) * 1000;
}
-
- if((pp->hour == 10) && (pp->minute == 10))
- {
+
+ if ((pp->hour == 10) && (pp->minute == 10)) {
up->y2kwarn++;
}
- sprintf(pp->a_lastcode, "%d %d %d %d %d", pp->year, pp->day, pp->hour, pp->minute, pp->second);
+ snprintf(pp->a_lastcode, sizeof(pp->a_lastcode),
+ "%d %d %d %d %d", pp->year, pp->day, pp->hour,
+ pp->minute, pp->second);
pp->lencode = strlen(pp->a_lastcode);
- /*get_systime(&pp->lastrec);*/
+ /*get_systime(&pp->lastrec);*/
#ifdef DEBUG
- if (debug)
- printf ("fg: time is %04d/%03d %02d:%02d:%02d UTC\n",
- pp->year, pp->day, pp->hour, pp->minute, pp->second);
+ if (debug)
+ printf("fg: time is %04d/%03d %02d:%02d:%02d UTC\n",
+ pp->year, pp->day, pp->hour, pp->minute, pp->second);
#endif
- pp->disp = (10e-6);
+ pp->disp = (10e-6);
pp->lastrec = rbufp->recv_time; /* Is it better than get_systime()? */
/* pp->leap = LEAP_NOWARNING; */
- /*
- * Process the new sample in the median filter and determine the
- * timecode timestamp.
- */
+ /*
+ * Process the new sample in the median filter and determine the
+ * timecode timestamp.
+ */
- if (!refclock_process(pp))
- refclock_report(peer, CEVNT_BADTIME);
- pp->lastref = pp->lastrec;
+ if (!refclock_process(pp))
+ refclock_report(peer, CEVNT_BADTIME);
+ pp->lastref = pp->lastrec;
refclock_receive(peer);
return;
}
/*
* Open serial port. Use CLK line discipline, if available.
*/
- (void)sprintf(device, DEVICE, unit);
+ snprintf(device, sizeof(device), DEVICE, unit);
fd = refclock_open(device, SPEED232, LDISC_CLK);
if (fd <= 0)
return (0);
else
sp->metric = wwv_metric(sp);
if (pp->sloppyclockflag & CLK_FLAG4) {
- sprintf(tbuf,
+ snprintf(tbuf, sizeof(tbuf),
"wwv8 %04x %3d %s %04x %.0f %.0f/%.1f %ld %ld",
up->status, up->gain, sp->refid,
sp->reach & 0xffff, sp->metric, sp->synmax,
}
if ((pp->sloppyclockflag & CLK_FLAG4) && !(up->status &
MSYNC)) {
- sprintf(tbuf,
+ snprintf(tbuf, sizeof(tbuf),
"wwv1 %04x %3d %4d %5.0f %5.1f %5d %4d %4d %4d",
up->status, up->gain, tepoch, up->epomax,
up->eposnr, tmp2, avgcnt, syncnt,
}
rp->metric = wwv_metric(rp);
if (pp->sloppyclockflag & CLK_FLAG4) {
- sprintf(tbuf,
+ snprintf(tbuf, sizeof(tbuf),
"wwv5 %04x %3d %4d %.0f/%.1f %.0f/%.1f %s %04x %.0f %.0f/%.1f %s %04x %.0f %.0f/%.1f",
up->status, up->gain, up->yepoch,
up->epomax, up->eposnr, up->datsig,
}
if ((pp->sloppyclockflag & CLK_FLAG4) && !(up->status &
INSYNC)) {
- sprintf(tbuf,
+ snprintf(tbuf, sizeof(tbuf),
"wwv4 %2d %04x %3d %4d %5.0f %2d %d %d %d %5.0f %5.1f",
up->rsec - 1, up->status, up->gain, up->yepoch,
up->epomax, vp->radix, vp->digit, mldigit,
cp = &up->mitig[i];
cp->gain = up->gain;
cp->wwv.select = SELV;
- sprintf(cp->wwv.refid, "WV%.0f", floor(qsy[i]));
+ snprintf(cp->wwv.refid, sizeof(cp->wwv.refid), "WV%.0f",
+ floor(qsy[i]));
cp->wwvh.select = SELH;
- sprintf(cp->wwvh.refid, "WH%.0f", floor(qsy[i]));
+ snprintf(cp->wwvh.refid, sizeof(cp->wwvh.refid), "WH%.0f",
+ floor(qsy[i]));
}
up->dchan = (DCHAN + NCHAN - 1) % NCHAN;
wwv_newchan(peer);
* Open serial port.
* Something like LDISC_ACTS that looked for ! would be nice...
*/
- (void)sprintf(device, DEVICE, unit);
+ snprintf(device, sizeof(device), DEVICE, unit);
fd = refclock_open(device, SPEED232, LDISC_RAW);
if (fd <= 0)
return (0);
TRACE(2, ("Got packet, size = %d\n", n));
if ((int)count > (n - CTL_HEADER_LEN)) {
- TRACE(1, ("Received count of %d octets, data in packet is %d\n",
+ TRACE(1, ("Received count of %u octets, data in packet is %d\n",
count, (n - CTL_HEADER_LEN)));
continue;
}
continue;
}
if (offset + count > sizeof(pktdata)) {
- TRACE(1, ("Offset %d, count %d, too big for buffer\n",
+ TRACE(1, ("Offset %u, count %u, too big for buffer\n",
offset, count));
return ERR_TOOMUCH;
}
/*
* invalid character (no consecutive bit sequence)
*/
- dprintf(("parse: cvt_rawdcf: character check for 0x%x@%d FAILED\n", *s, s - buffer));
+ dprintf(("parse: cvt_rawdcf: character check for 0x%x@%d FAILED\n",
+ (u_int)*s, s - buffer));
*s = (unsigned char)~0;
rtc = CVT_FAIL|CVT_BADFMT;
}
*/
static char *
pr_timeval(
- struct timeval *val
- )
+ struct timeval *val
+ )
{
static char buf[20];
if (val->tv_sec == 0)
- sprintf(buf, "%c0.%06ld", (val->tv_usec < 0) ? '-' : '+', (long int)l_abs(val->tv_usec));
+ snprintf(buf, sizeof(buf), "%c0.%06ld",
+ (val->tv_usec < 0) ? '-' : '+',
+ (long int)l_abs(val->tv_usec));
else
- sprintf(buf, "%ld.%06ld", (long int)val->tv_sec, (long int)l_abs(val->tv_usec));
+ snprintf(buf, sizeof(buf), "%ld.%06ld",
+ (long int)val->tv_sec,
+ (long int)l_abs(val->tv_usec));
return buf;
}
/*
* Function prototypes
*/
-char *sprintb (u_int, const char *);
-const char *timex_state (int);
+const char * sprintb (u_int, const char *);
+const char * timex_state (int);
#ifdef SIGSYS
void pll_trap (int);
extern int ntp_optind;
extern char *ntp_optarg;
#ifdef SUBST_ADJTIMEX
- struct timex ntv;
+ struct timex ntv;
#else
struct ntptimeval ntv;
#endif
int cost = 0;
volatile int rawtime = 0;
- memset((char *)&ntx, 0, sizeof(ntx));
+ ZERO(ntx);
progname = argv[0];
- while ((c = ntp_getopt(argc, argv, optargs)) != EOF) switch (c) {
+ while ((c = ntp_getopt(argc, argv, optargs)) != EOF) {
+ switch (c) {
#ifdef MOD_MICRO
- case 'M':
- ntx.modes |= MOD_MICRO;
- break;
+ case 'M':
+ ntx.modes |= MOD_MICRO;
+ break;
#endif
#ifdef MOD_NANO
- case 'N':
- ntx.modes |= MOD_NANO;
- break;
+ case 'N':
+ ntx.modes |= MOD_NANO;
+ break;
#endif
#ifdef NTP_API
# if NTP_API > 3
- case 'T':
- ntx.modes = MOD_TAI;
- ntx.constant = atoi(ntp_optarg);
- break;
+ case 'T':
+ ntx.modes = MOD_TAI;
+ ntx.constant = atoi(ntp_optarg);
+ break;
# endif
#endif
- case 'c':
- cost++;
- break;
- case 'e':
- ntx.modes |= MOD_ESTERROR;
- ntx.esterror = atoi(ntp_optarg);
- break;
- case 'f':
- ntx.modes |= MOD_FREQUENCY;
- ntx.freq = (long)(atof(ntp_optarg) * SCALE_FREQ);
- break;
- case 'm':
- ntx.modes |= MOD_MAXERROR;
- ntx.maxerror = atoi(ntp_optarg);
- break;
- case 'o':
- ntx.modes |= MOD_OFFSET;
- ntx.offset = atoi(ntp_optarg);
- break;
- case 'r':
- rawtime++;
- break;
- case 's':
- ntx.modes |= MOD_STATUS;
- ntx.status = atoi(ntp_optarg);
- if (ntx.status < 0 || ntx.status >= 0x100) errflg++;
- break;
- case 't':
- ntx.modes |= MOD_TIMECONST;
- ntx.constant = atoi(ntp_optarg);
- break;
- default:
- errflg++;
+ case 'c':
+ cost++;
+ break;
+
+ case 'e':
+ ntx.modes |= MOD_ESTERROR;
+ ntx.esterror = atoi(ntp_optarg);
+ break;
+
+ case 'f':
+ ntx.modes |= MOD_FREQUENCY;
+ ntx.freq = (long)(atof(ntp_optarg) * SCALE_FREQ);
+ break;
+
+ case 'm':
+ ntx.modes |= MOD_MAXERROR;
+ ntx.maxerror = atoi(ntp_optarg);
+ break;
+
+ case 'o':
+ ntx.modes |= MOD_OFFSET;
+ ntx.offset = atoi(ntp_optarg);
+ break;
+
+ case 'r':
+ rawtime++;
+ break;
+
+ case 's':
+ ntx.modes |= MOD_STATUS;
+ ntx.status = atoi(ntp_optarg);
+ if (ntx.status < 0 || ntx.status >= 0x100)
+ errflg++;
+ break;
+
+ case 't':
+ ntx.modes |= MOD_TIMECONST;
+ ntx.constant = atoi(ntp_optarg);
+ break;
+
+ default:
+ errflg++;
+ }
}
if (errflg || (ntp_optind != argc)) {
- (void) fprintf(stderr,
- "usage: %s [-%s]\n\n\
+ fprintf(stderr,
+ "usage: %s [-%s]\n\n\
%s%s%s\
-c display the time taken to call ntp_gettime (us)\n\
-e esterror estimate of the error (us)\n\
-r print the unix and NTP time raw\n\
-s status Set the status bits\n\
-t timeconstant log2 of PLL time constant (0 .. %d)\n",
- progname, optargs,
+ progname, optargs,
#ifdef MOD_MICRO
"-M switch to microsecond mode\n",
#else
#else
"",
#endif
- MAXTC);
+ MAXTC);
exit(2);
}
*/
pll_control = 1;
#ifdef SIGSYS
- if (sigsetjmp(env, 1) == 0)
- {
+ if (sigsetjmp(env, 1) == 0) {
#endif
status = syscall(BADCALL, &ntv); /* dummy parameter */
if ((status < 0) && (errno == ENOSYS))
#ifdef SIGSYS
if (sigsetjmp(env, 1) == 0) {
#endif
- for (c = 0; c < sizeof times / sizeof times[0]; c++) {
+ for (c = 0; c < COUNTOF(times); c++) {
status = ntp_gettime(&ntv);
if ((status < 0) && (errno == ENOSYS))
--pll_control;
#endif
if (pll_control >= 0) {
printf("[ us %06d:", times[0]);
- for (c = 1; c < sizeof times / sizeof times[0]; c++)
+ for (c = 1; c < COUNTOF(times); c++)
printf(" %d", times[c] - times[c - 1]);
printf(" ]\n");
}
* Fetch timekeeping data and display.
*/
status = ntp_gettime(&ntv);
- if (status < 0)
+ if (status < 0) {
perror("ntp_gettime() call fails");
- else {
+ } else {
printf("ntp_gettime() returns code %d (%s)\n",
status, timex_state(status));
time_frac = ntv.time.tv_frac_sec;
ts.l_uf += ts_roundbit;
ts.l_uf &= ts_mask;
printf(" time %s, (.%0*d),\n",
- prettydate(&ts), fdigits, (int) time_frac);
+ prettydate(&ts), fdigits, (int)time_frac);
printf(" maximum error %lu us, estimated error %lu us",
(u_long)ntv.maxerror, (u_long)ntv.esterror);
if (rawtime)
- printf(" ntptime=%x.%x unixtime=%x.%0*d %s",
- (unsigned int) ts.l_ui, (unsigned int) ts.l_uf,
- (int) ntv.time.tv_sec, fdigits, (int) time_frac,
- ctime((const time_t *) &ntv.time.tv_sec));
+ printf(" ntptime=%x.%x unixtime=%x.%0*d %s",
+ (u_int)ts.l_ui, (u_int)ts.l_uf,
+ (int)ntv.time.tv_sec, fdigits,
+ (int)time_frac,
+ ctime((time_t *)&ntv.time.tv_sec));
#if NTP_API > 3
printf(", TAI offset %ld\n", (long)ntv.tai);
#else
#endif /* NTP_API */
}
status = ntp_adjtime(&ntx);
- if (status < 0)
+ if (status < 0) {
perror((errno == EPERM) ?
"Must be root to set kernel values\nntp_adjtime() call fails" :
"ntp_adjtime() call fails");
- else {
+ } else {
flash = ntx.status;
printf("ntp_adjtime() returns code %d (%s)\n",
status, timex_state(status));
" time constant %lu, precision %.3f us, tolerance %.0f ppm,\n",
(u_long)ntx.constant, gtemp, ftemp);
if (ntx.shift == 0)
- exit (0);
+ exit(0);
ftemp = (double)ntx.ppsfreq / SCALE_FREQ;
gtemp = (double)ntx.stabil / SCALE_FREQ;
htemp = (double)ntx.jitter;
printf(" intervals %lu, jitter exceeded %lu, stability exceeded %lu, errors %lu.\n",
(u_long)ntx.calcnt, (u_long)ntx.jitcnt,
(u_long)ntx.stbcnt, (u_long)ntx.errcnt);
- return (0);
+ return 0;
}
/*
/*
* Print a value a la the %b format of the kernel's printf
*/
-char *
+const char *
sprintb(
- register u_int v,
- register const char *bits
+ u_int v,
+ const char * bits
)
{
- register char *cp;
- register int i, any = 0;
- register char c;
+ char *cp;
+ char *cplim;
+ int i;
+ int any;
+ char c;
static char buf[132];
- if (bits && *bits == 8)
- (void)sprintf(buf, "0%o", v);
+ if (bits != NULL && *bits == 8)
+ snprintf(buf, sizeof(buf), "0%o", v);
else
- (void)sprintf(buf, "0x%x", v);
+ snprintf(buf, sizeof(buf), "0x%x", v);
cp = buf + strlen(buf);
- if (bits) {
+ cplim = buf + sizeof(buf);
+ if (bits != NULL) {
bits++;
*cp++ = ' ';
*cp++ = '(';
+ any = FALSE;
while ((i = *bits++) != 0) {
- if (v & (1 << (i-1))) {
- if (any)
- *cp++ = ',';
- any = 1;
- for (; (c = *bits) > 32; bits++)
- *cp++ = c;
- } else
- for (; *bits > 32; bits++)
- continue;
+ if (v & (1 << (i - 1))) {
+ if (any) {
+ *cp++ = ',';
+ if (cp >= cplim)
+ goto overrun;
+ }
+ any = TRUE;
+ for (; (c = *bits) > 32; bits++) {
+ *cp++ = c;
+ if (cp >= cplim)
+ goto overrun;
+ }
+ } else {
+ for (; *bits > 32; bits++)
+ continue;
+ }
}
*cp++ = ')';
+ if (cp >= cplim)
+ goto overrun;
}
*cp = '\0';
- return (buf);
+ return buf;
+
+ overrun:
+ return "sprintb buffer too small";
}
-const char *timex_states[] = {
+const char * const timex_states[] = {
"OK", "INS", "DEL", "OOP", "WAIT", "ERROR"
};
const char *
timex_state(
- register int s
+ int s
)
{
static char buf[32];
- if (s >= 0 && s < sizeof(timex_states) / sizeof(timex_states[0]))
- return (timex_states[s]);
- sprintf(buf, "TIME-#%d", s);
- return (buf);
+ if (s >= 0 && s < COUNTOF(timex_states))
+ return timex_states[s];
+ snprintf(buf, sizeof(buf), "TIME-#%d", s);
+ return buf;
}