This rather large diff takes a swing at atoi() in the tree; converting many of them to strtonum().
strtonum() is not a perfect API. But atoi() is far worse, as is strtol() -- if endptr is unchecked (quite common). The same extends to the rest of that family of functions. Please reserve any criticism of strtonum() for elsewhere -- by realizing most of these changes are adding missing range checks, coping with junk on the ends of the strings, and making hard decisions about how errors should be passed onwards. Adding such error checks and range checks is infeasable using the strtol function; the difficulty encountered during a previous audit acted as the genesis for strtonum()... Many of the cases being handled are for problems like " b" " 0junk" "" being treated same, ignoring the wrong text at the end. Sometimes the leading whitespace is a problem, other times it is not. The gravest problem is range checking. Often this is entirely missing, or negative input will do the wrong thing. Sometimes an internal variable can be forced into 0 by passing in junk. I think the best approach is to get the truly good changes in first, then deal with the more suspicious or incorrect changes; so please be kind with your replies and keep them simple. Index: bin/csh/proc.c =================================================================== RCS file: /cvs/src/bin/csh/proc.c,v retrieving revision 1.26 diff -u -p -u -r1.26 proc.c --- bin/csh/proc.c 8 Feb 2015 06:09:50 -0000 1.26 +++ bin/csh/proc.c 13 Apr 2015 14:58:41 -0000 @@ -34,6 +34,7 @@ #include <sys/wait.h> #include <errno.h> #include <unistd.h> +#include <limits.h> #include <stdlib.h> #include <string.h> #include <stdarg.h> @@ -931,6 +932,7 @@ void dokill(Char **v, struct command *t) { int signum = SIGTERM; + const char *errstr; char *name; v++; @@ -940,8 +942,8 @@ dokill(Char **v, struct command *t) if (!Isdigit(v[1][0])) stderror(ERR_NAME | ERR_BADSIG); - signum = atoi(short2str(v[1])); - if (signum < 0 || signum >= NSIG) + signum = strtonum(short2str(v[1]), 0, NSIG-1, &errstr); + if (errstr) stderror(ERR_NAME | ERR_BADSIG); else if (signum == 0) (void) fputc('0', cshout); /* 0's symbolic name is '0' */ @@ -958,8 +960,8 @@ dokill(Char **v, struct command *t) return; } if (Isdigit(v[0][1])) { - signum = atoi(short2str(v[0] + 1)); - if (signum < 0 || signum >= NSIG) + signum = strtonum(short2str(v[0] + 1), 0, NSIG-1, &errstr); + if (errstr) stderror(ERR_NAME | ERR_BADSIG); } else { @@ -1147,12 +1149,18 @@ pfind(Char *cp) return (pprevious); } if (Isdigit(cp[1])) { - int idx = atoi(short2str(cp + 1)); + const char *errstr; + int idx = strtonum(short2str(cp + 1), 1, INT_MAX, &errstr); + if (errstr) { + stderror(ERR_NAME | ERR_NOSUCHJOB); + return (0); + } for (pp = proclist.p_next; pp; pp = pp->p_next) if (pp->p_index == idx && pp->p_pid == pp->p_jobid) return (pp); stderror(ERR_NAME | ERR_NOSUCHJOB); + return (0); } np = NULL; for (pp = proclist.p_next; pp; pp = pp->p_next) Index: bin/date/date.c =================================================================== RCS file: /cvs/src/bin/date/date.c,v retrieving revision 1.46 diff -u -p -u -r1.46 date.c --- bin/date/date.c 17 Mar 2015 19:31:30 -0000 1.46 +++ bin/date/date.c 7 Apr 2015 17:11:20 -0000 @@ -59,6 +59,7 @@ int main(int argc, char *argv[]) { struct timezone tz; + const char *errstr; struct tm *tp; int ch, rflag; char *format, buf[1024], *outzone = NULL; @@ -87,12 +88,10 @@ main(int argc, char *argv[]) err(1, "cannot unsetenv TZ"); break; case 't': /* minutes west of GMT */ - /* error check; don't allow "PST" */ - if (isdigit((unsigned char)*optarg)) { - tz.tz_minuteswest = atoi(optarg); - break; - } - /* FALLTHROUGH */ + tz.tz_minuteswest = strtonum(optarg, 0, 24*60-1, &errstr); + if (errstr) + errx(1, "-t %s: %s", optarg, errstr); + break; case 'z': outzone = optarg; break; Index: bin/ksh/exec.c =================================================================== RCS file: /cvs/src/bin/ksh/exec.c,v retrieving revision 1.50 diff -u -p -u -r1.50 exec.c --- bin/ksh/exec.c 10 Jun 2013 21:09:27 -0000 1.50 +++ bin/ksh/exec.c 13 Apr 2015 13:55:58 -0000 @@ -1234,6 +1234,7 @@ do_selectargs(char **ap, bool print_menu static const char *const read_args[] = { "read", "-r", "REPLY", (char *) 0 }; + const char *errstr; char *s; int i, argct; @@ -1252,8 +1253,10 @@ do_selectargs(char **ap, bool print_menu return (char *) 0; s = str_val(global("REPLY")); if (*s) { - i = atoi(s); - return (i >= 1 && i <= argct) ? ap[i - 1] : null; + i = strtonum(s, 1, argct-1, &errstr); + if (errstr) + return null; + return ap[i - 1]; } print_menu = 1; } Index: bin/ksh/jobs.c =================================================================== RCS file: /cvs/src/bin/ksh/jobs.c,v retrieving revision 1.40 diff -u -p -u -r1.40 jobs.c --- bin/ksh/jobs.c 4 Sep 2013 15:49:18 -0000 1.40 +++ bin/ksh/jobs.c 13 Apr 2015 04:20:47 -0000 @@ -1428,11 +1428,17 @@ static Job * j_lookup(const char *cp, int *ecodep) { Job *j, *last_match; + const char *errstr; Proc *p; int len, job = 0; if (digit(*cp)) { - job = atoi(cp); + job = strtonum(cp, 1, INT_MAX, &errstr); + if (errstr) { + if (ecodep) + *ecodep = JL_NOSUCH; + return (Job *) 0; + } /* Look for last_proc->pid (what $! returns) first... */ for (j = job_list; j != (Job *) 0; j = j->next) if (j->last_proc && j->last_proc->pid == job) @@ -1467,7 +1473,9 @@ j_lookup(const char *cp, int *ecodep) case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': - job = atoi(cp); + job = strtonum(cp, 1, INT_MAX, &errstr); + if (errstr) + break; for (j = job_list; j != (Job *) 0; j = j->next) if (j->job == job) return j; Index: bin/ksh/var.c =================================================================== RCS file: /cvs/src/bin/ksh/var.c,v retrieving revision 1.40 diff -u -p -u -r1.40 var.c --- bin/ksh/var.c 12 Dec 2014 05:00:55 -0000 1.40 +++ bin/ksh/var.c 6 Apr 2015 09:52:48 -0000 @@ -1007,8 +1007,19 @@ setspec(struct tbl *vp) set_editmode(str_val(vp)); break; case V_COLUMNS: - if ((x_cols = intval(vp)) <= MIN_COLS) - x_cols = MIN_COLS; + { + long l; + + if (getint(vp, &l, false) == -1) { + //warningf(false, "%s: bad COLUMNS", str_val(vp)); + x_cols = MIN_COLS; + break; + } + if (l <= MIN_COLS || l > INT_MAX) + x_cols = MIN_COLS; + else + x_cols = l; + } break; #endif /* EDIT */ case V_MAIL: Index: bin/ls/ls.c =================================================================== RCS file: /cvs/src/bin/ls/ls.c,v retrieving revision 1.39 diff -u -p -u -r1.39 ls.c --- bin/ls/ls.c 31 Mar 2014 20:54:37 -0000 1.39 +++ bin/ls/ls.c 5 Apr 2015 14:08:11 -0000 @@ -47,6 +47,7 @@ #include <stdlib.h> #include <string.h> #include <unistd.h> +#include <limits.h> #include <util.h> #include "ls.h" @@ -99,22 +100,27 @@ ls_main(int argc, char *argv[]) static char dot[] = ".", *dotav[] = { dot, NULL }; struct winsize win; int ch, fts_options, notused; - int kflag = 0; + int kflag = 0, width = 0; char *p; /* Terminal defaults to -Cq, non-terminal defaults to -1. */ if (isatty(STDOUT_FILENO)) { if ((p = getenv("COLUMNS")) != NULL) - termwidth = atoi(p); - else if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &win) == 0 && + width = strtonum(p, 0, INT_MAX, NULL); + if (width == 0 && + ioctl(STDOUT_FILENO, TIOCGWINSZ, &win) == 0 && win.ws_col > 0) - termwidth = win.ws_col; + width = win.ws_col; + if (width) + termwidth = width; f_column = f_nonprint = 1; } else { f_singlecol = 1; /* retrieve environment variable, in case of explicit -C */ if ((p = getenv("COLUMNS")) != NULL) - termwidth = atoi(p); + width = strtonum(p, 0, INT_MAX, NULL); + if (width) + termwidth = width; } /* Root is -A automatically. */ Index: bin/pax/options.c =================================================================== RCS file: /cvs/src/bin/pax/options.c,v retrieving revision 1.89 diff -u -p -u -r1.89 options.c --- bin/pax/options.c 15 Mar 2015 21:53:09 -0000 1.89 +++ bin/pax/options.c 4 Apr 2015 15:57:23 -0000 @@ -223,6 +223,7 @@ pax_options(int argc, char **argv) unsigned i; unsigned int flg = 0; unsigned int bflg = 0; + const char *errstr; char *pt; /* @@ -462,9 +463,12 @@ pax_options(int argc, char **argv) flg |= CEF; if (strcmp(NONE, optarg) == 0) maxflt = -1; - else if ((maxflt = atoi(optarg)) < 0) { - paxwarn(1, "Error count value must be positive"); - pax_usage(); + else { + maxflt = strtonum(optarg, 0, INT_MAX, &errstr); + if (errstr) { + paxwarn(1, "Error count value: %s", errstr); + pax_usage(); + } } break; case 'G': @@ -1079,6 +1083,7 @@ mkpath(path) static void cpio_options(int argc, char **argv) { + const char *errstr; int c; unsigned i; char *str; @@ -1214,7 +1219,12 @@ cpio_options(int argc, char **argv) /* * set block size in bytes */ - wrblksz = atoi(optarg); + wrblksz = strtonum(optarg, 0, INT_MAX, &errstr); + if (errstr) { + paxwarn(1, "Invalid block size %s: %s", + optarg, errstr); + pax_usage(); + } break; case 'E': /* Index: bin/systrace/filter.c =================================================================== RCS file: /cvs/src/bin/systrace/filter.c,v retrieving revision 1.35 diff -u -p -u -r1.35 filter.c --- bin/systrace/filter.c 16 Jan 2015 00:19:12 -0000 1.35 +++ bin/systrace/filter.c 13 Apr 2015 15:07:31 -0000 @@ -615,7 +615,8 @@ filter_ask(int fd, struct intercept_tlq filter_templates(emulation); continue; } else if (!strncasecmp(line, "template ", 9)) { - int count = atoi(line + 9); + const char *errstr; + int count = strtonum(line + 9, 0, INT_MAX, &errstr); if (count == 0 || filter_template(fd, policy, count) == -1) { Index: bin/systrace/lex.l =================================================================== RCS file: /cvs/src/bin/systrace/lex.l,v retrieving revision 1.19 diff -u -p -u -r1.19 lex.l --- bin/systrace/lex.l 16 Jan 2015 00:19:12 -0000 1.19 +++ bin/systrace/lex.l 4 Apr 2015 16:03:07 -0000 @@ -103,7 +103,14 @@ as { return AS; } "<" { return LESSER; } ">" { return GREATER; } [\_\$A-Za-z][\.\(\)\/A-Za-z_\-0-9]*\$? { yylval.string = strdup(yytext); return STRING; } -[0-9]+ { yylval.number = atoi(yytext); return NUMBER; } +[0-9]+ { + const char *errstr; + yylval.number = strtonum(yytext, 0, INT_MAX, &errstr); + if (errstr) { + yyerror("number %s: %s", yytext, errstr); + } + return NUMBER; + } \" { BEGIN(quote); *quotestr = '\0'; quoteescape = 0; Index: bin/systrace/systrace.c =================================================================== RCS file: /cvs/src/bin/systrace/systrace.c,v retrieving revision 1.62 diff -u -p -u -r1.62 systrace.c --- bin/systrace/systrace.c 16 Jan 2015 00:19:12 -0000 1.62 +++ bin/systrace/systrace.c 7 Apr 2015 17:14:08 -0000 @@ -647,6 +647,7 @@ main(int argc, char **argv) char **args; char *filename = NULL; char *policypath = NULL; + const char *errstr; struct timeval tv; pid_t pidattach = 0; int usex11 = 1; @@ -707,7 +708,8 @@ main(int argc, char **argv) case 'p': if (setcredentials) usage(); - if ((pidattach = atoi(optarg)) == 0) { + pidattach = strtonum(optarg, 1, INT_MAX, &errstr); + if (errstr) { warnx("bad pid: %s", optarg); usage(); } Index: lib/libc/rpc/getrpcent.c =================================================================== RCS file: /cvs/src/lib/libc/rpc/getrpcent.c,v retrieving revision 1.16 diff -u -p -u -r1.16 getrpcent.c --- lib/libc/rpc/getrpcent.c 15 Sep 2014 06:15:48 -0000 1.16 +++ lib/libc/rpc/getrpcent.c 4 Apr 2015 15:07:55 -0000 @@ -35,6 +35,7 @@ #include <stdlib.h> #include <sys/types.h> #include <string.h> +#include <limits.h> #include <rpc/rpc.h> /* @@ -147,6 +148,7 @@ getrpcent(void) static struct rpcent * interpret(char *val, int len) { + const char *errstr; struct rpcdata *d = _rpcdata(); char *p; char *cp, **q; @@ -170,7 +172,9 @@ interpret(char *val, int len) d->rpc.r_name = d->line; while (*cp == ' ' || *cp == '\t') cp++; - d->rpc.r_number = atoi(cp); + d->rpc.r_number = strtonum(cp, 0, INT_MAX, &errstr); + if (errstr) + return (0); q = d->rpc.r_aliases = d->rpc_aliases; cp = strpbrk(cp, " \t"); if (cp != NULL) Index: lib/libskey/skeylogin.c =================================================================== RCS file: /cvs/src/lib/libskey/skeylogin.c,v retrieving revision 1.56 diff -u -p -u -r1.56 skeylogin.c --- lib/libskey/skeylogin.c 16 Jan 2015 16:48:52 -0000 1.56 +++ lib/libskey/skeylogin.c 4 Apr 2015 15:07:55 -0000 @@ -95,6 +95,7 @@ skeygetent(int fd, struct skey *mp, cons { char *cp, filename[PATH_MAX], *last; struct stat statbuf; + const char *errstr; size_t nread; FILE *keyfile; @@ -154,7 +155,9 @@ skeygetent(int fd, struct skey *mp, cons goto bad_keyfile; if ((cp = strtok_r(NULL, " \t\n\r", &last)) == NULL) goto bad_keyfile; - mp->n = atoi(cp); /* XXX - use strtol() */ + mp->n = strtonum(cp, 0, UINT_MAX, &errstr); + if (errstr) + goto bad_keyfile; if ((mp->seed = strtok_r(NULL, " \t\n\r", &last)) == NULL) goto bad_keyfile; if ((mp->val = strtok_r(NULL, " \t\n\r", &last)) == NULL) Index: libexec/comsat/comsat.c =================================================================== RCS file: /cvs/src/libexec/comsat/comsat.c,v retrieving revision 1.38 diff -u -p -u -r1.38 comsat.c --- libexec/comsat/comsat.c 16 Jan 2015 06:39:49 -0000 1.38 +++ libexec/comsat/comsat.c 4 Apr 2015 15:07:55 -0000 @@ -200,13 +200,16 @@ mailfor(char *name) { struct utmp *utp = &utmp[nutmp]; char utname[UT_NAMESIZE+1]; + const char *errstr; char *cp; off_t offset; if (!(cp = strchr(name, '@'))) return; *cp = '\0'; - offset = atoi(cp + 1); + offset = strtonum(cp + 1, 0, INT_MAX, &errstr); + if (errstr) + return; while (--utp >= utmp) { memcpy(utname, utp->ut_name, UT_NAMESIZE); utname[UT_NAMESIZE] = '\0'; Index: libexec/rpc.rstatd/rstatd.c =================================================================== RCS file: /cvs/src/libexec/rpc.rstatd/rstatd.c,v retrieving revision 1.26 diff -u -p -u -r1.26 rstatd.c --- libexec/rpc.rstatd/rstatd.c 13 Mar 2015 03:24:27 -0000 1.26 +++ libexec/rpc.rstatd/rstatd.c 14 Apr 2015 23:59:41 -0000 @@ -34,6 +34,7 @@ #include <stdlib.h> #include <string.h> #include <unistd.h> +#include <limits.h> #include <signal.h> #include <pwd.h> #include <syslog.h> @@ -65,6 +66,7 @@ main(int argc, char *argv[]) socklen_t fromlen; struct passwd *pw; struct sockaddr_storage from; + const char *errstr; SVCXPRT *transp; openlog("rpc.rstatd", LOG_NDELAY|LOG_CONS|LOG_PID, LOG_DAEMON); @@ -88,8 +90,8 @@ main(int argc, char *argv[]) } if (argc == 2) - closedown = atoi(argv[1]); - if (closedown <= 0) + closedown = strtonum(argv[1], 1, INT_MAX, &errstr); + if (errstr) closedown = 20; /* Index: libexec/spamd/spamd.c =================================================================== RCS file: /cvs/src/libexec/spamd/spamd.c,v retrieving revision 1.126 diff -u -p -u -r1.126 spamd.c --- libexec/spamd/spamd.c 12 Mar 2015 20:07:20 -0000 1.126 +++ libexec/spamd/spamd.c 4 Apr 2015 15:07:55 -0000 @@ -1246,22 +1246,23 @@ main(int argc, char *argv[]) bind_address = optarg; break; case 'B': - i = atoi(optarg); - maxblack = i; + maxblack = strtonum(optarg, 0, INT_MAX, &errstr); + if (errstr) + errx(1, "-B %s: %s", optarg, errstr); break; case 'c': - i = atoi(optarg); - if (i > maxfiles) { + maxcon = strtonum(optarg, 1, maxfiles, &errstr); + if (errstr) { fprintf(stderr, "%d > system max of %d connections\n", - i, maxfiles); + maxcon, maxfiles); usage(); } - maxcon = i; break; case 'p': - i = atoi(optarg); - port = i; + port = strtonum(optarg, 1, USHRT_MAX, &errstr); + if (errstr) + errx(1, "-p %s: %s", optarg, errstr); break; case 'd': debug = 1; @@ -1290,16 +1291,14 @@ main(int argc, char *argv[]) errx(1, "-h arg too long"); break; case 's': - i = strtonum(optarg, 0, 10, &errstr); + stutter = strtonum(optarg, 0, 10, &errstr); if (errstr) usage(); - stutter = i; break; case 'S': - i = strtonum(optarg, 0, 90, &errstr); + grey_stutter = strtonum(optarg, 0, 90, &errstr); if (errstr) usage(); - grey_stutter = i; break; case 'M': low_prio_mx_ip = optarg; @@ -1311,9 +1310,9 @@ main(int argc, char *argv[]) verbose = 1; break; case 'w': - window = atoi(optarg); - if (window <= 0) - usage(); + window = strtonum(optarg, 1, INT_MAX, &errstr); + if (errstr) + errx(1, "-w %s: %s", optarg, errstr); break; case 'Y': if (sync_addhost(optarg, sync_port) != 0) Index: sbin/fsck/fsck.c =================================================================== RCS file: /cvs/src/sbin/fsck/fsck.c,v retrieving revision 1.34 diff -u -p -u -r1.34 fsck.c --- sbin/fsck/fsck.c 20 Mar 2015 01:53:05 -0000 1.34 +++ sbin/fsck/fsck.c 4 Apr 2015 15:07:55 -0000 @@ -88,6 +88,7 @@ static int hasopt(const char *, const ch int main(int argc, char *argv[]) { + const char *errstr; struct fstab *fs; int i, rval = 0; char *vfstype = NULL; @@ -139,7 +140,10 @@ main(int argc, char *argv[]) break; case 'l': - maxrun = atoi(optarg); + maxrun = strtonum(optarg, 0, INT_MAX, &errstr); + if (errstr) + errx(1, "-l %s: %s", optarg, errstr); + break; case 'T': Index: sbin/growfs/growfs.c =================================================================== RCS file: /cvs/src/sbin/growfs/growfs.c,v retrieving revision 1.38 diff -u -p -u -r1.38 growfs.c --- sbin/growfs/growfs.c 20 Jan 2015 18:22:21 -0000 1.38 +++ sbin/growfs/growfs.c 4 Apr 2015 15:48:42 -0000 @@ -1865,7 +1865,7 @@ charsperline(void) columns = ws.ws_col; } if (columns == 0 && (cp = getenv("COLUMNS"))) { - columns = atoi(cp); + columns = strtonum(cp, 1, INT_MAX, NULL); } if (columns == 0) { columns = 80; /* last resort */ Index: sbin/mount_msdos/mount_msdos.c =================================================================== RCS file: /cvs/src/sbin/mount_msdos/mount_msdos.c,v retrieving revision 1.29 diff -u -p -u -r1.29 mount_msdos.c --- sbin/mount_msdos/mount_msdos.c 16 Jan 2015 06:39:59 -0000 1.29 +++ sbin/mount_msdos/mount_msdos.c 9 Apr 2015 21:38:41 -0000 @@ -158,19 +158,16 @@ gid_t a_gid(char *s) { struct group *gr; + const char *errstr; char *gname; gid_t gid; if ((gr = getgrnam(s)) != NULL) - gid = gr->gr_gid; - else { - for (gname = s; isdigit((unsigned char)*s); ++s) - ; - if (!*s) - gid = atoi(gname); - else - errx(1, "unknown group id: %s", gname); - } + return gr->gr_gid; + + gid = (gid_t)strtonum(s, 0, GID_MAX, &errstr); + if (errstr) + errx(1, "group is %s: %s", errstr, s); return (gid); } @@ -178,19 +175,15 @@ uid_t a_uid(char *s) { struct passwd *pw; + const char *errstr; char *uname; uid_t uid; if ((pw = getpwnam(s)) != NULL) - uid = pw->pw_uid; - else { - for (uname = s; isdigit((unsigned char)*s); ++s) - ; - if (!*s) - uid = atoi(uname); - else - errx(1, "unknown user id: %s", uname); - } + + uid = (gid_t)strtonum(s, 0, UID_MAX, &errstr); + if (errstr) + errx(1, "user is %s: %s", errstr, s); return (uid); } Index: sbin/newfs/mkfs.c =================================================================== RCS file: /cvs/src/sbin/newfs/mkfs.c,v retrieving revision 1.90 diff -u -p -u -r1.90 mkfs.c --- sbin/newfs/mkfs.c 6 Feb 2015 22:29:00 -0000 1.90 +++ sbin/newfs/mkfs.c 4 Apr 2015 15:07:55 -0000 @@ -1149,7 +1149,7 @@ charsperline(void) if (ioctl(0, TIOCGWINSZ, &ws) != -1) columns = ws.ws_col; if (columns == 0 && (cp = getenv("COLUMNS"))) - columns = atoi(cp); + columns = strtonum(cp, 1, INT_MAX, NULL); if (columns == 0) columns = 80; /* last resort */ return columns; Index: sbin/newfs_msdos/newfs_msdos.c =================================================================== RCS file: /cvs/src/sbin/newfs_msdos/newfs_msdos.c,v retrieving revision 1.25 diff -u -p -u -r1.25 newfs_msdos.c --- sbin/newfs_msdos/newfs_msdos.c 16 Jan 2015 06:40:00 -0000 1.25 +++ sbin/newfs_msdos/newfs_msdos.c 4 Apr 2015 15:07:55 -0000 @@ -249,6 +249,7 @@ main(int argc, char *argv[]) ssize_t n; time_t now; u_int fat, bss, rds, cls, dir, lsn, x, x1, x2; + const char *errstr; int ch, fd, fd1; while ((ch = getopt(argc, argv, opts)) != -1) @@ -260,11 +261,11 @@ main(int argc, char *argv[]) opt_B = optarg; break; case 'F': - if (strcmp(optarg, "12") && - strcmp(optarg, "16") && - strcmp(optarg, "32")) + opt_F = strtonum(optarg, 1, INT_MAX, &errstr); + if (errstr) + errx(1, "-l %s: %s", optarg, errstr); + if (!(opt_F == 12 || opt_F == 16 || opt_F == 32)) errx(1, "%s: bad FAT type", optarg); - opt_F = atoi(optarg); break; case 'I': opt_I = argto4(optarg, 0, "volume ID"); Index: sbin/quotacheck/quotacheck.c =================================================================== RCS file: /cvs/src/sbin/quotacheck/quotacheck.c,v retrieving revision 1.37 diff -u -p -u -r1.37 quotacheck.c --- sbin/quotacheck/quotacheck.c 7 Feb 2015 02:09:14 -0000 1.37 +++ sbin/quotacheck/quotacheck.c 4 Apr 2015 15:07:55 -0000 @@ -136,6 +136,7 @@ main(int argc, char *argv[]) struct quotaname *auxdata; int i, argnum, maxrun, errs, ch; u_int64_t done = 0; /* XXX supports maximum 64 filesystems */ + const char *errstr; char *name; errs = maxrun = 0; @@ -151,7 +152,9 @@ main(int argc, char *argv[]) gflag = 1; break; case 'l': - maxrun = atoi(optarg); + maxrun = strtonum(optarg, 0, INT_MAX, &errstr); + if (errstr) + errx(1, "-l %s: %s", optarg, errstr); break; case 'u': uflag = 1; Index: sbin/savecore/savecore.c =================================================================== RCS file: /cvs/src/sbin/savecore/savecore.c,v retrieving revision 1.51 diff -u -p -u -r1.51 savecore.c --- sbin/savecore/savecore.c 15 Mar 2015 00:41:27 -0000 1.51 +++ sbin/savecore/savecore.c 4 Apr 2015 15:52:21 -0000 @@ -34,7 +34,6 @@ #include <sys/stat.h> #include <sys/mount.h> #include <sys/syslog.h> -#include <sys/types.h> #include <sys/time.h> #include <sys/resource.h> @@ -390,8 +389,13 @@ save_core(void) if (ferror(fp)) err1: syslog(LOG_WARNING, "%s: %s", path, strerror(errno)); bounds = 0; - } else - bounds = atoi(buf); + } else { + const char *errstr; + + bounds = strtonum(buf, 0, INT_MAX, &errstr); + if (errstr) + syslog(LOG_WARNING, "bounds was corrupt: %s", errstr); + } if (fp != NULL) (void)fclose(fp); if ((fp = fopen(path, "w")) == NULL) @@ -607,8 +611,13 @@ check_space(void) else { if (fgets(buf, sizeof(buf), fp) == NULL) minfree = 0; - else - minfree = atoi(buf); + else { + const char *errstr; + + minfree = strtonum(buf, 0, LLONG_MAX, &errstr); + syslog(LOG_WARNING, + "minfree was corrupt: %s", errstr); + } (void)fclose(fp); } Index: sbin/shutdown/shutdown.c =================================================================== RCS file: /cvs/src/sbin/shutdown/shutdown.c,v retrieving revision 1.41 diff -u -p -u -r1.41 shutdown.c --- sbin/shutdown/shutdown.c 15 Mar 2015 00:41:27 -0000 1.41 +++ sbin/shutdown/shutdown.c 4 Apr 2015 15:07:55 -0000 @@ -437,9 +437,12 @@ getoffset(char *timearg) (void)time(&now); if (*timearg == '+') { /* +minutes */ - if (!isdigit((unsigned char)*++timearg)) + const char *errstr; + + offset = strtonum(++timearg, 0, INT_MAX, &errstr); + if (errstr); badtime(); - offset = atoi(timearg) * 60; + offset *= 60; shuttime = now + offset; return; } Index: sbin/swapctl/swapctl.c =================================================================== RCS file: /cvs/src/sbin/swapctl/swapctl.c,v retrieving revision 1.19 diff -u -p -u -r1.19 swapctl.c --- sbin/swapctl/swapctl.c 16 Jan 2015 06:40:01 -0000 1.19 +++ sbin/swapctl/swapctl.c 4 Apr 2015 15:07:55 -0000 @@ -58,6 +58,7 @@ #include <errno.h> #include <stdio.h> #include <stdlib.h> +#include <limits.h> #include <string.h> #include <fstab.h> #include <util.h> @@ -116,6 +117,7 @@ extern char *__progname; /* from crt0.o int main(int argc, char *argv[]) { + const char *errstr; int c; if (strcmp(__progname, "swapon") == 0) @@ -149,8 +151,9 @@ main(int argc, char *argv[]) case 'p': pflag = 1; - /* XXX strtol() */ - pri = atoi(optarg); + pri = strtonum(optarg, 0, INT_MAX, &errstr); + if (errstr) + errx(1, "-p %s: %s", errstr, optarg); break; case 's': Index: sbin/sysctl/sysctl.c =================================================================== RCS file: /cvs/src/sbin/sysctl/sysctl.c,v retrieving revision 1.210 diff -u -p -u -r1.210 sysctl.c --- sbin/sysctl/sysctl.c 13 Feb 2015 00:02:21 -0000 1.210 +++ sbin/sysctl/sysctl.c 4 Apr 2015 15:07:55 -0000 @@ -102,6 +102,7 @@ #include <stdlib.h> #include <string.h> #include <ctype.h> +#include <limits.h> #include <unistd.h> #include <machine/cpu.h> @@ -1297,6 +1298,8 @@ sysctl_bios(char *string, char **bufpp, return (-1); mib[2] = indx; if (indx == BIOS_DISKINFO) { + const char *errstr; + if (*bufpp == NULL) { char name[BUFSIZ]; @@ -1312,7 +1315,11 @@ sysctl_bios(char *string, char **bufpp, warnx("%s: incomplete specification", string); return (-1); } - mib[3] = atoi(name); + mib[3] = strtonum(name, 0, INT_MAX, &errstr); + if (errstr) { + warnx("%s: %s", string, errstr); + return (-1); + } *typep = CTLTYPE_STRUCT; return (4); } else { @@ -1802,6 +1809,7 @@ sysctl_malloc(char *string, char **bufpp { int indx, stor, i; char *name, bufp[SYSCTL_BUFSIZ], *buf, *ptr; + const char *errstr; struct list lp; size_t size; @@ -1839,7 +1847,9 @@ sysctl_malloc(char *string, char **bufpp free(lp.list); return (-1); } - mib[3] = atoi(name); + mib[3] = strtonum(name, 0, INT_MAX, &errstr); + if (errstr) + return -1; return (4); } else if (mib[2] == KERN_MALLOC_BUCKETS) { *typep = CTLTYPE_STRING; @@ -2398,7 +2408,13 @@ sysctl_sensors(char *string, char **bufp numt = -1; for (i = 0; typename[i] != '\0'; i++) if (isdigit((unsigned char)typename[i])) { - numt = atoi(&typename[i]); + const char *errstr; + + numt = strtonum(&typename[i], 0, INT_MAX, &errstr); + if (errstr) { + warnx("%s: %s", string, errstr); + return (-1); + } typename[i] = '\0'; break; } @@ -2702,7 +2718,14 @@ sysctl_emul(char *string, char *newval, mib[2] = emul_names[i].index; len = sizeof(int); if (newval) { - enabled = atoi(newval); + const char *errstr; + + enabled = strtonum(newval, 0, INT_MAX, &errstr); + if (errstr) { + warn("%s", string); + print = 0; + continue; + } if (sysctl(mib, 4, &old, &len, &enabled, len) == -1) { warn("%s", string); print = 0; Index: sbin/wsconsctl/map_scan.l =================================================================== RCS file: /cvs/src/sbin/wsconsctl/map_scan.l,v retrieving revision 1.4 diff -u -p -u -r1.4 map_scan.l --- sbin/wsconsctl/map_scan.l 14 Jul 2012 08:28:47 -0000 1.4 +++ sbin/wsconsctl/map_scan.l 4 Apr 2015 15:40:27 -0000 @@ -34,6 +34,7 @@ #include <dev/wscons/wsksymdef.h> #include <dev/wscons/wsksymvar.h> +#include <limits.h> #include <err.h> #include "wsconsctl.h" #include "y.tab.h" @@ -81,7 +82,11 @@ keysym { } [0-9]+ { - yylval.ival = atoi(yytext); + const char *errstr; + + yylval.ival = strtonum(yytext, 0, INT_MAX, &errstr); + if (errstr) + errx(1, "%s: %s", yytext, errstr); return(T_NUMBER); } Index: usr.bin/calendar/calendar.c =================================================================== RCS file: /cvs/src/usr.bin/calendar/calendar.c,v retrieving revision 1.30 diff -u -p -u -r1.30 calendar.c --- usr.bin/calendar/calendar.c 15 Mar 2015 00:41:28 -0000 1.30 +++ usr.bin/calendar/calendar.c 5 Apr 2015 21:38:13 -0000 @@ -41,6 +41,7 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <limits.h> #include <time.h> #include <unistd.h> @@ -68,6 +69,7 @@ int main(int argc, char *argv[]) { int ch; + const char *errstr; char *caldir; (void)setlocale(LC_ALL, ""); @@ -95,12 +97,16 @@ main(int argc, char *argv[]) break; case 'A': /* days after current date */ - f_dayAfter = atoi(optarg); + f_dayAfter = strtonum(optarg, 0, INT_MAX, &errstr); + if (errstr) + errx(1, "-A %s: %s", optarg, errstr); f_SetdayAfter = 1; break; case 'B': /* days before current date */ - f_dayBefore = atoi(optarg); + f_dayBefore = strtonum(optarg, 0, INT_MAX, &errstr); + if (errstr) + errx(1, "-A %s: %s", optarg, errstr); break; default: Index: usr.bin/calendar/io.c =================================================================== RCS file: /cvs/src/usr.bin/calendar/io.c,v retrieving revision 1.38 diff -u -p -u -r1.38 io.c --- usr.bin/calendar/io.c 15 Mar 2015 00:41:28 -0000 1.38 +++ usr.bin/calendar/io.c 5 Apr 2015 21:40:18 -0000 @@ -281,12 +281,16 @@ getfield(char *p, char **endp, int *flag } } if (i > NUMEV) { - switch(*start) { + const char *errstr; + + switch (*start) { case '-': case '+': - var = atoi(start); - if (var > 365 || var < -365) + var = strtonum(start + 1, 0, 365, &errstr); + if (errstr) return (0); /* Someone is just being silly */ + if (*start == '-') + var = -var; val += (NUMEV + 1) * var; /* We add one to the matching event and multiply by * (NUMEV + 1) so as not to return 0 if there's a match. Index: usr.bin/find/function.c =================================================================== RCS file: /cvs/src/usr.bin/find/function.c,v retrieving revision 1.43 diff -u -p -u -r1.43 function.c --- usr.bin/find/function.c 15 Mar 2015 00:41:28 -0000 1.43 +++ usr.bin/find/function.c 8 Apr 2015 15:43:58 -0000 @@ -883,8 +883,10 @@ c_group(char *gname, char ***ignored, in g = getgrnam(gname); if (g == NULL) { - gid = atoi(gname); - if (gid == 0 && gname[0] != '0') + const char *errstr; + + gid = strtonum(gname, 0, GID_MAX, &errstr); + if (errstr) errx(1, "-group: %s: no such group", gname); } else gid = g->gr_gid; @@ -1014,9 +1016,12 @@ PLAN * c_mindepth(char *arg, char ***ignored, int unused) { PLAN *new; + const char *errstr = NULL; new = palloc(N_MINDEPTH, f_mindepth); - new->min_data = atoi(arg); + new->min_data = strtonum(arg, 0, INT_MAX, &errstr); + if (errstr) + errx(1, "%s: mindepth value %s", arg, errstr); return (new); } @@ -1488,8 +1493,10 @@ c_user(char *username, char ***ignored, p = getpwnam(username); if (p == NULL) { - uid = atoi(username); - if (uid == 0 && username[0] != '0') + const char *errstr; + + uid = strtonum(username, 0, UID_MAX, &errstr); + if (errstr) errx(1, "-user: %s: no such user", username); } else uid = p->pw_uid; Index: usr.bin/ipcrm/ipcrm.c =================================================================== RCS file: /cvs/src/usr.bin/ipcrm/ipcrm.c,v retrieving revision 1.10 diff -u -p -u -r1.10 ipcrm.c --- usr.bin/ipcrm/ipcrm.c 19 Dec 2005 19:13:50 -0000 1.10 +++ usr.bin/ipcrm/ipcrm.c 4 Apr 2015 15:07:55 -0000 @@ -39,6 +39,7 @@ #include <sys/shm.h> #include <stdio.h> #include <unistd.h> +#include <limits.h> #include <stdlib.h> #include <ctype.h> #include <err.h> @@ -112,6 +113,7 @@ int main(int argc, char *argv[]) { int c, result, errflg, target_id; + const char *errstr; key_t target_key; errflg = 0; @@ -122,7 +124,9 @@ main(int argc, char *argv[]) case 'q': case 'm': case 's': - target_id = atoi(optarg); + target_id = strtonum(optarg, 0, LONG_MAX, &errstr); + if (errstr) + errx(1, "-%c %s: %s\n", c, optarg, &errstr); if (c == 'q') result = msgrm(0, target_id); else if (c == 'm') Index: usr.bin/kdump/kdump.c =================================================================== RCS file: /cvs/src/usr.bin/kdump/kdump.c,v retrieving revision 1.98 diff -u -p -u -r1.98 kdump.c --- usr.bin/kdump/kdump.c 26 Jan 2015 04:38:23 -0000 1.98 +++ usr.bin/kdump/kdump.c 4 Apr 2015 15:12:30 -0000 @@ -169,6 +169,7 @@ main(int argc, char *argv[]) int ch, silent; size_t ktrlen, size; int trpoints = ALL_POINTS; + const char *errstr; void *m; def_emul = current = &emulations[0]; /* native */ @@ -192,13 +193,17 @@ main(int argc, char *argv[]) tail = 1; break; case 'm': - maxdata = atoi(optarg); + maxdata = strtonum(optarg, 0, INT_MAX, &errstr); + if (errstr) + errx(1, "-m %s: %s", optarg, errstr); break; case 'n': fancy = 0; break; case 'p': - pid_opt = atoi(optarg); + pid_opt = strtonum(optarg, 1, INT_MAX, &errstr); + if (errstr) + errx(1, "-p %s: %s", optarg, errstr); break; case 'R': timestamp = 2; /* relative timestamp */ Index: usr.bin/ktrace/ktrace.c =================================================================== RCS file: /cvs/src/usr.bin/ktrace/ktrace.c,v retrieving revision 1.31 diff -u -p -u -r1.31 ktrace.c --- usr.bin/ktrace/ktrace.c 16 Jan 2015 06:40:09 -0000 1.31 +++ usr.bin/ktrace/ktrace.c 4 Apr 2015 15:07:55 -0000 @@ -211,7 +211,9 @@ main(int argc, char *argv[]) static int rpid(const char *p) { + const char *errstr; static int first; + int pid; if (first++) { warnx("only one -g or -p flag is permitted."); @@ -221,7 +223,12 @@ rpid(const char *p) warnx("illegal process id."); usage(); } - return(atoi(p)); + pid = strtonum(p, 1, INT_MAX, &errstr); + if (errstr) { + warnx("illegal process id: %s", errstr); + usage(); + } + return pid; } static void Index: usr.bin/logger/logger.c =================================================================== RCS file: /cvs/src/usr.bin/logger/logger.c,v retrieving revision 1.13 diff -u -p -u -r1.13 logger.c --- usr.bin/logger/logger.c 27 Nov 2013 13:32:02 -0000 1.13 +++ usr.bin/logger/logger.c 4 Apr 2015 15:07:55 -0000 @@ -32,6 +32,7 @@ #include <errno.h> #include <unistd.h> +#include <limits.h> #include <stdlib.h> #include <stdio.h> #include <ctype.h> @@ -155,10 +156,15 @@ pencode(char *s) int decode(char *name, CODE *codetab) { + int n; CODE *c; - if (isdigit((unsigned char)*name)) - return (atoi(name)); + if (isdigit((unsigned char)*name)) { + const char *errstr; + int n = strtonum(name, 0, INT_MAX, &errstr); + if (!errstr) + return (n); + } for (c = codetab; c->c_name; c++) if (!strcasecmp(name, c->c_name)) Index: usr.bin/make/generate.c =================================================================== RCS file: /cvs/src/usr.bin/make/generate.c,v retrieving revision 1.16 diff -u -p -u -r1.16 generate.c --- usr.bin/make/generate.c 18 May 2014 08:08:50 -0000 1.16 +++ usr.bin/make/generate.c 13 Apr 2015 18:50:23 -0000 @@ -29,6 +29,7 @@ #include <stdint.h> #include <stdio.h> #include <stdlib.h> +#include <limits.h> #include <ohash.h> #include "stats.h" @@ -137,6 +138,7 @@ main(int argc, char *argv[]) uint32_t v; uint32_t h; uint32_t slots; + const char *errstr; const char *e; char **occupied; char **t; @@ -146,11 +148,13 @@ main(int argc, char *argv[]) if (argc != 3) exit(1); - tn = atoi(argv[1]); - if (!tn) + tn = strtonum(argv[1], 1, INT_MAX, &errstr); + if (errstr) exit(1); t = table[tn-1]; - slots = atoi(argv[2]); + slots = strtonum(argv[2], 0, INT_MAX, &errstr); + if (errstr) + exit(1); if (slots) { occupied = calloc(slots, sizeof(char *)); if (!occupied) Index: usr.bin/sed/process.c =================================================================== RCS file: /cvs/src/usr.bin/sed/process.c,v retrieving revision 1.22 diff -u -p -u -r1.22 process.c --- usr.bin/sed/process.c 13 Apr 2015 05:11:23 -0000 1.22 +++ usr.bin/sed/process.c 13 Apr 2015 05:11:36 -0000 @@ -457,12 +457,14 @@ lputs(char *s) static int termwidth = -1; if (termwidth == -1) { + termwidth = 0; if ((p = getenv("COLUMNS"))) - termwidth = atoi(p); - else if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &win) == 0 && + termwidth = strtonum(p, 0, INT_MAX, NULL); + if (termwidth == 0 && + ioctl(STDOUT_FILENO, TIOCGWINSZ, &win) == 0 && win.ws_col > 0) termwidth = win.ws_col; - else + if (termwidth == 0) termwidth = 60; } Index: usr.bin/skey/skey.c =================================================================== RCS file: /cvs/src/usr.bin/skey/skey.c,v retrieving revision 1.27 diff -u -p -u -r1.27 skey.c --- usr.bin/skey/skey.c 20 Mar 2014 20:39:13 -0000 1.27 +++ usr.bin/skey/skey.c 13 Apr 2015 17:31:59 -0000 @@ -27,6 +27,7 @@ #include <string.h> #include <err.h> #include <unistd.h> +#include <limits.h> #include <skey.h> void usage(char *); @@ -37,6 +38,7 @@ main(int argc, char *argv[]) int n, i, cnt = 1, pass = 0, hexmode = 0; char passwd[SKEY_MAX_PW_LEN+1], key[SKEY_BINKEY_SIZE]; char buf[33], *seed, *slash; + const char *errstr; /* If we were called as otp-METHOD, set algorithm based on that */ if ((slash = strrchr(argv[0], '/'))) @@ -56,7 +58,9 @@ main(int argc, char *argv[]) case 'n': if (++i == argc) usage(argv[0]); - cnt = atoi(argv[i]); + cnt = strtonum(argv[i], 0, INT_MAX, &errstr); + if (errstr) + usage(argv[0]); break; case 'p': if (++i == argc) @@ -96,19 +100,15 @@ main(int argc, char *argv[]) *slash++ = '\0'; seed = slash; - if ((n = atoi(argv[i])) < 0) { - warnx("%d not positive", n); - usage(argv[0]); - } else if (n > SKEY_MAX_SEQ) { - warnx("%d is larger than max (%d)", n, SKEY_MAX_SEQ); + n = strtonum(argv[i], 1, SKEY_MAX_SEQ, &errstr); + if (errstr) { + warnx("%s: %s", argv[i], errstr); usage(argv[0]); } } else { - if ((n = atoi(argv[i])) < 0) { - warnx("%d not positive", n); - usage(argv[0]); - } else if (n > SKEY_MAX_SEQ) { - warnx("%d is larger than max (%d)", n, SKEY_MAX_SEQ); + n = strtonum(argv[i], 1, SKEY_MAX_SEQ, &errstr); + if (errstr) { + warnx("%s: %s", argv[i], errstr); usage(argv[0]); } seed = argv[++i]; Index: usr.bin/skeyinit/skeyinit.c =================================================================== RCS file: /cvs/src/usr.bin/skeyinit/skeyinit.c,v retrieving revision 1.56 diff -u -p -u -r1.56 skeyinit.c --- usr.bin/skeyinit/skeyinit.c 16 Jan 2015 06:40:11 -0000 1.56 +++ usr.bin/skeyinit/skeyinit.c 4 Apr 2015 15:07:55 -0000 @@ -52,6 +52,7 @@ main(int argc, char **argv) char seed[SKEY_MAX_SEED_LEN + 1]; char buf[256], key[SKEY_BINKEY_SIZE], filename[PATH_MAX], *ht; char lastc, me[UT_NAMESIZE + 1], *p, *auth_type; + const char *errstr; u_int32_t noise; struct skey skey; struct passwd *pp; @@ -108,7 +109,8 @@ main(int argc, char **argv) case 'n': if (argv[++i] == NULL || argv[i][0] == '\0') usage(); - if ((n = atoi(argv[i])) < 1 || n >= SKEY_MAX_SEQ) + n = strtonum(argv[i], 1, SKEY_MAX_SEQ - 1, &errstr); + if (errstr) errx(1, "count must be > 0 and < %d", SKEY_MAX_SEQ); break; @@ -324,6 +326,7 @@ secure_mode(int *count, char *key, char char *buf, size_t bufsiz) { char *p, newseed[SKEY_MAX_SEED_LEN + 2]; + const char *errstr; int i, n; (void)puts("You need the 6 words generated from the \"skey\" command."); @@ -335,11 +338,11 @@ secure_mode(int *count, char *key, char SKEY_MAX_SEQ); (void)fgets(buf, bufsiz, stdin); clearerr(stdin); - n = atoi(buf); - if (n > 0 && n < SKEY_MAX_SEQ) + n = strtonum(buf, 1, SKEY_MAX_SEQ-1, &errstr); + if (errstr) break; /* Valid range */ - (void)fprintf(stderr, "ERROR: Count must be between 1 and %d\n", - SKEY_MAX_SEQ); + fprintf(stderr, "ERROR: Count must be between 1 and %d\n", + SKEY_MAX_SEQ); } for (i = 0; ; i++) { @@ -492,6 +495,7 @@ convert_db(void) FILE *newfile; char buf[256], *logname, *hashtype, *seed, *val, *cp; char filename[PATH_MAX]; + const char *errstr; int fd, n; if ((keyfile = fopen(_PATH_SKEYKEYS, "r")) == NULL) @@ -516,7 +520,9 @@ convert_db(void) hashtype = cp; if ((cp = strtok(NULL, " \t")) == NULL) continue; - n = atoi(cp); + n = strtonum(cp, 0, INT_MAX, &errstr); + if (errstr) + continue; if ((seed = strtok(NULL, " \t")) == NULL) continue; if ((val = strtok(NULL, " \t")) == NULL) Index: usr.bin/systat/main.c =================================================================== RCS file: /cvs/src/usr.bin/systat/main.c,v retrieving revision 1.62 diff -u -p -u -r1.62 main.c --- usr.bin/systat/main.c 12 Mar 2015 01:03:00 -0000 1.62 +++ usr.bin/systat/main.c 4 Apr 2015 15:07:55 -0000 @@ -296,13 +296,12 @@ cmd_delay(const char *buf) void cmd_count(const char *buf) { + const char *errstr; int ms; - ms = atoi(buf); - if (ms <= 0 || ms > lines - HEADER_LINES) + maxprint = strtonum(buf, 1, lines - HEADER_LINES, &errstr); + if (errstr) maxprint = lines - HEADER_LINES; - else - maxprint = ms; } @@ -380,6 +379,7 @@ int main(int argc, char *argv[]) { char errbuf[_POSIX2_LINE_MAX]; + const char *errstr; extern char *optarg; extern int optind; double delay = 5; @@ -418,9 +418,9 @@ main(int argc, char *argv[]) interactive = 0; break; case 'd': - countmax = atoi(optarg); - if (countmax < 0) - countmax = 0; + countmax = strtonum(optarg, 1, INT_MAX, &errstr); + if (errstr) + errx(1, "-d %s: %s", optarg, errstr); break; case 'i': interactive = 1; @@ -438,11 +438,9 @@ main(int argc, char *argv[]) delay = 5; break; case 'w': - rawwidth = atoi(optarg); - if (rawwidth < 1) - rawwidth = DEFAULT_WIDTH; - if (rawwidth >= MAX_LINE_BUF) - rawwidth = MAX_LINE_BUF - 1; + rawwidth = strtonum(optarg, 1, MAX_LINE_BUF-1, &errstr); + if (errstr) + errx(1, "-w %s: %s", optarg, errstr); break; default: usage(); Index: usr.bin/tip/tip.c =================================================================== RCS file: /cvs/src/usr.bin/tip/tip.c,v retrieving revision 1.55 diff -u -p -u -r1.55 tip.c --- usr.bin/tip/tip.c 7 Feb 2015 10:07:15 -0000 1.55 +++ usr.bin/tip/tip.c 13 Apr 2015 17:28:32 -0000 @@ -50,6 +50,8 @@ int main(int argc, char *argv[]) { char *sys = NULL; + const char *errstr; + int baud; int i, pair[2]; vinit(); @@ -81,7 +83,12 @@ main(int argc, char *argv[]) case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': - vsetnum(BAUDRATE, atoi(&argv[1][1])); + baud = strtonum(&argv[1][1], 0, INT_MAX, &errstr); + if (errstr) { + fprintf(stderr, "incorrect speed: %s\n", errstr); + exit(1); + } + vsetnum(BAUDRATE, baud); break; default: Index: usr.bin/unifdef/unifdef.c =================================================================== RCS file: /cvs/src/usr.bin/unifdef/unifdef.c,v retrieving revision 1.18 diff -u -p -u -r1.18 unifdef.c --- usr.bin/unifdef/unifdef.c 17 Feb 2015 05:16:09 -0000 1.18 +++ usr.bin/unifdef/unifdef.c 4 Apr 2015 15:07:55 -0000 @@ -252,6 +252,7 @@ static const char *xstrdup(const ch int main(int argc, char *argv[]) { + const char *errstr; int opt; while ((opt = getopt(argc, argv, "i:D:U:f:I:M:o:x:bBcdehKklmnsStV")) != -1) @@ -332,7 +333,9 @@ main(int argc, char *argv[]) version(); break; case 'x': - exitmode = atoi(optarg); + exitmode = strtonum(optarg, 0, 2, &errstr); + if (errstr) + errx(1, "-x %s: %s", optarg, errstr); if(exitmode < 0 || exitmode > 2) usage(); break; Index: usr.bin/vis/vis.c =================================================================== RCS file: /cvs/src/usr.bin/vis/vis.c,v retrieving revision 1.16 diff -u -p -u -r1.16 vis.c --- usr.bin/vis/vis.c 8 Feb 2015 23:40:34 -0000 1.16 +++ usr.bin/vis/vis.c 4 Apr 2015 15:07:55 -0000 @@ -34,6 +34,7 @@ #include <string.h> #include <stdlib.h> #include <unistd.h> +#include <limits.h> #include <err.h> #include <vis.h> @@ -50,6 +51,7 @@ __dead void usage(void); int main(int argc, char *argv[]) { + const char *errstr; FILE *fp; int ch; @@ -80,10 +82,11 @@ main(int argc, char *argv[]) eflags |= VIS_NOSLASH; break; case 'F': - if ((foldwidth = atoi(optarg))<5) { + foldwidth = strtonum(optarg, 1, INT_MAX, &errstr); + if (errstr) + errx(1, "%s: %s", optarg, errstr); + if (foldwidth < 5) errx(1, "can't fold lines to less than 5 cols"); - /* NOTREACHED */ - } /*FALLTHROUGH*/ case 'f': fold = 1; /* fold output lines to 80 cols */ Index: usr.bin/vmstat/vmstat.c =================================================================== RCS file: /cvs/src/usr.bin/vmstat/vmstat.c,v retrieving revision 1.137 diff -u -p -u -r1.137 vmstat.c --- usr.bin/vmstat/vmstat.c 30 Jan 2015 19:00:56 -0000 1.137 +++ usr.bin/vmstat/vmstat.c 5 Apr 2015 14:43:25 -0000 @@ -766,7 +766,13 @@ domem(void) siz = sizeof(struct kmembuckets); i = 0; while ((ap = strsep(&bufp, ",")) != NULL) { - mib[3] = atoi(ap); + const char *errstr; + + mib[3] = strtonum(ap, 0, INT_MAX, &errstr); + if (errstr) { + warn("kernel lied about %d being a number", mib[3]); + return; + } if (sysctl(mib, 4, &buckets[MINBUCKET + i], &siz, NULL, 0) < 0) { Index: usr.bin/xargs/xargs.c =================================================================== RCS file: /cvs/src/usr.bin/xargs/xargs.c,v retrieving revision 1.28 diff -u -p -u -r1.28 xargs.c --- usr.bin/xargs/xargs.c 16 Jan 2015 06:40:14 -0000 1.28 +++ usr.bin/xargs/xargs.c 4 Apr 2015 15:07:55 -0000 @@ -50,6 +50,7 @@ #include <stdlib.h> #include <string.h> #include <unistd.h> +#include <limits.h> #include "pathnames.h" @@ -78,6 +79,7 @@ main(int argc, char *argv[]) int ch, Jflag, nargs, nflag, nline; size_t linelen; char *endptr; + const char *errstr; inpline = replstr = NULL; ep = environ; @@ -125,19 +127,23 @@ main(int argc, char *argv[]) replstr = optarg; break; case 'L': - Lflag = atoi(optarg); + Lflag = strtonum(optarg, 0, INT_MAX, &errstr); + if (errstr) + errx(1, "-L %s: %s", optarg, errstr); break; case 'n': nflag = 1; - if ((nargs = atoi(optarg)) <= 0) - errx(1, "illegal argument count"); + nargs = strtonum(optarg, 1, INT_MAX, &errstr); + if (errstr) + errx(1, "-n %s: %s", optarg, errstr); break; case 'o': oflag = 1; break; case 'P': - if ((maxprocs = atoi(optarg)) <= 0) - errx(1, "max. processes must be >0"); + maxprocs = strtonum(optarg, 1, INT_MAX, &errstr); + if (errstr) + errx(1, "-P %s: %s", optarg, errstr); break; case 'p': pflag = 1; @@ -151,7 +157,9 @@ main(int argc, char *argv[]) errx(1, "replacements must be a number"); break; case 's': - nline = atoi(optarg); + nline = strtonum(optarg, 0, INT_MAX, &errstr); + if (errstr) + errx(1, "-n %s: %s", optarg, errstr); break; case 't': tflag = 1; Index: usr.sbin/fdformat/fdformat.c =================================================================== RCS file: /cvs/src/usr.sbin/fdformat/fdformat.c,v retrieving revision 1.19 diff -u -p -u -r1.19 fdformat.c --- usr.sbin/fdformat/fdformat.c 8 Oct 2014 04:55:03 -0000 1.19 +++ usr.sbin/fdformat/fdformat.c 4 Apr 2015 15:07:55 -0000 @@ -45,6 +45,7 @@ #include <unistd.h> #include <fcntl.h> #include <string.h> +#include <limits.h> #include <ctype.h> #include <err.h> #include <util.h> @@ -181,33 +182,46 @@ main(int argc, char *argv[]) int rate = -1, gaplen = -1, secsize = -1, steps = -1; int fill = 0xf6, quiet = 0, verify = 1, verify_only = 0; int fd, c, track, error, tracks_per_dot, bytes_per_track, errs; + const char *errstr; char *devname; struct fd_type fdt; while((c = getopt(argc, argv, "c:s:h:r:g:S:F:t:i:qvn")) != -1) switch (c) { case 'c': /* # of cyls */ - cyls = atoi(optarg); + cyls = strtonum(optarg, 1, INT_MAX, &errstr); + if (errstr) + errx(1, "-c %s: %s", optarg, errstr); break; case 's': /* # of secs per track */ - secs = atoi(optarg); + secs = strtonum(optarg, 1, INT_MAX, &errstr); + if (errstr) + errx(1, "-s %s: %s", optarg, errstr); break; case 'h': /* # of heads */ - heads = atoi(optarg); + heads = strtonum(optarg, 1, INT_MAX, &errstr); + if (errstr) + errx(1, "-h %s: %s", optarg, errstr); break; case 'r': /* transfer rate, kilobyte/sec */ - rate = atoi(optarg); + rate = strtonum(optarg, 1, INT_MAX, &errstr); + if (errstr) + errx(1, "-r %s: %s", optarg, errstr); break; case 'g': /* length of GAP3 to format with */ - gaplen = atoi(optarg); + gaplen = strtonum(optarg, 1, INT_MAX, &errstr); + if (errstr) + errx(1, "-g %s: %s", optarg, errstr); break; case 'S': /* sector size shift factor (1 << S)*128 */ - secsize = atoi(optarg); + secsize = strtonum(optarg, 1, INT_MAX, &errstr); + if (errstr) + errx(1, "-S %s: %s", optarg, errstr); break; case 'F': /* fill byte, C-like notation allowed */ @@ -215,11 +229,15 @@ main(int argc, char *argv[]) break; case 't': /* steps per track */ - steps = atoi(optarg); + steps = strtonum(optarg, 1, INT_MAX, &errstr); + if (errstr) + errx(1, "-t %s: %s", optarg, errstr); break; case 'i': /* interleave factor */ - intleave = atoi(optarg); + intleave = strtonum(optarg, 1, INT_MAX, &errstr); + if (errstr) + errx(1, "-i %s: %s", optarg, errstr); break; case 'q': Index: usr.sbin/ndp/ndp.c =================================================================== RCS file: /cvs/src/usr.sbin/ndp/ndp.c,v retrieving revision 1.59 diff -u -p -u -r1.59 ndp.c --- usr.sbin/ndp/ndp.c 16 Jan 2015 06:40:18 -0000 1.59 +++ usr.sbin/ndp/ndp.c 4 Apr 2015 15:07:55 -0000 @@ -102,6 +102,7 @@ #include <stdlib.h> #include <string.h> #include <unistd.h> +#include <limits.h> #include <err.h> #include "gmt2local.h" @@ -202,8 +203,8 @@ main(int argc, char *argv[]) /*NOTREACHED*/ } mode = 'a'; - repeat = atoi(optarg); - if (repeat < 0) { + repeat = strtonum(optarg, 1, INT_MAX, &errstr); + if (errstr) { usage(); /*NOTREACHED*/ } Index: usr.sbin/pwd_mkdb/pwd_mkdb.c =================================================================== RCS file: /cvs/src/usr.sbin/pwd_mkdb/pwd_mkdb.c,v retrieving revision 1.46 diff -u -p -u -r1.46 pwd_mkdb.c --- usr.sbin/pwd_mkdb/pwd_mkdb.c 16 Jan 2015 06:40:19 -0000 1.46 +++ usr.sbin/pwd_mkdb/pwd_mkdb.c 15 Apr 2015 02:25:48 -0000 @@ -402,7 +402,7 @@ cp(char *from, char *to, mode_t mode) void mv(char *from, char *to) { - char buf[PATH_MAX * 2]; + char buf[PATH_MAX-1 + 4 + PATH_MAX-1 + 1]; if (rename(from, to)) { int sverrno = errno; Index: usr.sbin/rbootd/bpf.c =================================================================== RCS file: /cvs/src/usr.sbin/rbootd/bpf.c,v retrieving revision 1.21 diff -u -p -u -r1.21 bpf.c --- usr.sbin/rbootd/bpf.c 16 Jan 2015 06:40:19 -0000 1.21 +++ usr.sbin/rbootd/bpf.c 13 Apr 2015 15:09:50 -0000 @@ -58,6 +58,7 @@ #include <string.h> #include <syslog.h> #include <unistd.h> +#include <limits.h> #include <ifaddrs.h> #include "defs.h" #include "pathnames.h" @@ -261,6 +262,7 @@ BpfGetIntfName(char **errmsg) { int minunit = 999, n; char *cp; + const char *errstr; static char device[IFNAMSIZ]; static char errbuf[128] = "No Error!"; struct ifaddrs *ifap, *ifa, *mp = NULL; @@ -288,8 +290,8 @@ BpfGetIntfName(char **errmsg) for (cp = ifa->ifa_name; !isdigit((unsigned char)*cp); ++cp) ; - n = atoi(cp); - if (n < minunit) { + n = strtonum(cp, 0, INT_MAX, &errstr); + if (errstr == NULL && n < minunit) { minunit = n; mp = ifa; } Index: usr.sbin/rip6query/rip6query.c =================================================================== RCS file: /cvs/src/usr.sbin/rip6query/rip6query.c,v retrieving revision 1.14 diff -u -p -u -r1.14 rip6query.c --- usr.sbin/rip6query/rip6query.c 19 Mar 2014 14:02:24 -0000 1.14 +++ usr.sbin/rip6query/rip6query.c 4 Apr 2015 15:07:55 -0000 @@ -38,6 +38,7 @@ #include <ctype.h> #include <signal.h> #include <errno.h> +#include <limits.h> #include <err.h> #include <sys/types.h> @@ -76,6 +77,7 @@ main(int argc, char *argv[]) int c; int ifidx = -1; int error; + const char *errstr; char pbuf[NI_MAXSERV]; struct addrinfo hints, *res; @@ -89,7 +91,9 @@ main(int argc, char *argv[]) } break; case 'w': - query_wait = atoi(optarg); + query_wait = strtonum(optarg, 1, INT_MAX, &errstr); + if (errstr) + errx(1, "-w %s: %s", optarg, errstr); break; default: usage(); Index: usr.sbin/rpc.lockd/lockd.c =================================================================== RCS file: /cvs/src/usr.sbin/rpc.lockd/lockd.c,v retrieving revision 1.13 diff -u -p -u -r1.13 lockd.c --- usr.sbin/rpc.lockd/lockd.c 16 Jan 2015 06:40:20 -0000 1.13 +++ usr.sbin/rpc.lockd/lockd.c 9 Apr 2015 13:06:18 -0000 @@ -46,6 +46,7 @@ #include <err.h> #include <errno.h> #include <signal.h> +#include <limits.h> #include <string.h> #include <unistd.h> #include <netdb.h> @@ -68,6 +69,7 @@ int main(int argc, char *argv[]) { SVCXPRT *transp; + const char *errstr; int ch; struct sigaction sigchild, sigalarm; int grace_period = 30; @@ -75,15 +77,15 @@ main(int argc, char *argv[]) while ((ch = getopt(argc, argv, "d:g:")) != (-1)) { switch (ch) { case 'd': - debug_level = atoi(optarg); - if (!debug_level) { + debug_level = strtonum(optarg, 1, 20, &errstr); + if (errstr) { usage(); /* NOTREACHED */ } break; case 'g': - grace_period = atoi(optarg); - if (!grace_period) { + grace_period = strtonum(optarg, 1, INT_MAX, &errstr); + if (errstr) { usage(); /* NOTREACHED */ } Index: usr.sbin/sa/main.c =================================================================== RCS file: /cvs/src/usr.sbin/sa/main.c,v retrieving revision 1.12 diff -u -p -u -r1.12 main.c --- usr.sbin/sa/main.c 24 Nov 2013 01:06:19 -0000 1.12 +++ usr.sbin/sa/main.c 4 Apr 2015 15:07:55 -0000 @@ -72,6 +72,7 @@ main(int argc, char **argv) { int ch; int error = 0; + const char *errstr; extern char *__progname; while ((ch = getopt(argc, argv, "abcdDfijkKlmnqrstuv:")) != -1) @@ -156,7 +157,10 @@ main(int argc, char **argv) case 'v': /* cull junk */ vflag = 1; - cutoff = atoi(optarg); + /* XXX cutoff could be converted to quad_t? */ + cutoff = strtonum(optarg, 1, INT_MAX, &errstr); + if (errstr) + errx(1, "-v $s: %s", optarg, errstr); break; case '?': default: Index: usr.sbin/tcpdump/tcpdump.c =================================================================== RCS file: /cvs/src/usr.sbin/tcpdump/tcpdump.c,v retrieving revision 1.69 diff -u -p -u -r1.69 tcpdump.c --- usr.sbin/tcpdump/tcpdump.c 15 Apr 2015 02:32:28 -0000 1.69 +++ usr.sbin/tcpdump/tcpdump.c 15 Apr 2015 02:34:53 -0000 @@ -42,6 +42,7 @@ #include <stdlib.h> #include <string.h> #include <unistd.h> +#include <limits.h> #include <ctype.h> #include <err.h> #include <errno.h> @@ -209,6 +210,7 @@ main(int argc, char **argv) struct bpf_program *fcode; u_char *pcap_userdata; u_int dirfilt = 0, dlt = (u_int) -1; + const char *errstr; if ((cp = strrchr(argv[0], '/')) != NULL) program_name = cp + 1; @@ -235,9 +237,10 @@ main(int argc, char **argv) break; case 'c': - cnt = atoi(optarg); - if (cnt <= 0) - error("invalid packet count %s", optarg); + cnt = strtonum(optarg, 1, INT_MAX, &errstr); + if (errstr) + error("invalid packet count %s: %s", + optarg, errstr); break; case 'D': @@ -307,9 +310,9 @@ main(int argc, char **argv) break; case 's': - snaplen = atoi(optarg); - if (snaplen <= 0) - error("invalid snaplen %s", optarg); + snaplen = strtonum(optarg, 1, INT_MAX, &errstr); + if (errstr) + error("invalid snaplen %s: %s", optarg, errstr); break; case 'S':