I've added a comment and replaced memcpy with strlcpy as suggested. > Nitpick, but I'd probably slightly prefer parse_priority.
Me too, but it gets called by printline/printsys so I copied that. If anyone has stronger feelings about it I'll change it to whatever. > Looking at the old code again, it seems like the '>' was effectively > optional, and a stray '<' could zero pri. Was this a bug or a feature? The old code was pretty loose about what it accepted, and I think the new behaviour makes more sense. man syslogd has a paragraph about it: The message sent to syslogd should consist of a single line. The message can contain a priority code, which should be a preceding decimal number in angle braces, for example, ``<5>''. This priority code should map into the priorities defined in the include file <sys/syslog.h>. Mike Index: syslogd.c =================================================================== RCS file: /cvs/src/usr.sbin/syslogd/syslogd.c,v retrieving revision 1.177 diff -u -p -r1.177 syslogd.c --- syslogd.c 20 Jul 2015 19:49:33 -0000 1.177 +++ syslogd.c 12 Feb 2016 22:35:52 -0000 @@ -1325,6 +1325,34 @@ usage(void) } /* + * Parse a priority code of the form "<123>" into pri, and return the + * length of the priority code including the surrounding angle brackets. + */ +size_t +parsepriority(const char *msg, int *pri) +{ + size_t nlen; + char buf[11]; + const char *errstr; + int maybepri; + + if (*msg++ == '<') { + nlen = strspn(msg, "1234567890"); + if (nlen > 0 && nlen < sizeof(buf) && msg[nlen] == '>') { + strlcpy(buf, msg, nlen + 1); + maybepri = strtonum(buf, 0, INT_MAX, &errstr); + if (errstr == NULL) { + *pri = maybepri; + return nlen + 2; + } + } + } + + return 0; +} + +/* * Take a raw input line, decode the message, and print the message * on the appropriate log files. */ @@ -1337,13 +1365,7 @@ printline(char *hname, char *msg) /* test for special codes */ pri = DEFUPRI; p = msg; - if (*p == '<') { - pri = 0; - while (isdigit((unsigned char)*++p)) - pri = 10 * pri + (*p - '0'); - if (*p == '>') - ++p; - } + p += parsepriority(p, &pri); if (pri &~ (LOG_FACMASK|LOG_PRIMASK)) pri = DEFUPRI; @@ -1374,19 +1396,16 @@ printsys(char *msg) { int c, pri, flags; char *lp, *p, *q, line[MAXLINE + 1]; + size_t prilen; (void)snprintf(line, sizeof line, "%s: ", _PATH_UNIX); lp = line + strlen(line); for (p = msg; *p != '\0'; ) { flags = SYNC_FILE | ADDDATE; /* fsync file after write */ pri = DEFSPRI; - if (*p == '<') { - pri = 0; - while (isdigit((unsigned char)*++p)) - pri = 10 * pri + (*p - '0'); - if (*p == '>') - ++p; - } else { + prilen = parsepriority(p, &pri); + p += prilen; + if (prilen == 0) { /* kernel printf's come out on console */ flags |= IGN_CONS; }