ccdb51b96d
And many other things, too many to list here. For example, it now properly logs uds instead of erroring out. Separating concerns in many places definitely improves the readability.
102 lines
1.7 KiB
C
102 lines
1.7 KiB
C
/* See LICENSE file for copyright and license details. */
|
|
#include <errno.h>
|
|
#include <limits.h>
|
|
#include <stdarg.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <time.h>
|
|
|
|
#include "util.h"
|
|
|
|
char *argv0;
|
|
|
|
static void
|
|
verr(const char *fmt, va_list ap)
|
|
{
|
|
if (argv0 && strncmp(fmt, "usage", strlen("usage"))) {
|
|
fprintf(stderr, "%s: ", argv0);
|
|
}
|
|
|
|
vfprintf(stderr, fmt, ap);
|
|
|
|
if (fmt[0] && fmt[strlen(fmt) - 1] == ':') {
|
|
fputc(' ', stderr);
|
|
perror(NULL);
|
|
} else {
|
|
fputc('\n', stderr);
|
|
}
|
|
}
|
|
|
|
void
|
|
warn(const char *fmt, ...)
|
|
{
|
|
va_list ap;
|
|
|
|
va_start(ap, fmt);
|
|
verr(fmt, ap);
|
|
va_end(ap);
|
|
}
|
|
|
|
void
|
|
die(const char *fmt, ...)
|
|
{
|
|
va_list ap;
|
|
|
|
va_start(ap, fmt);
|
|
verr(fmt, ap);
|
|
va_end(ap);
|
|
|
|
exit(1);
|
|
}
|
|
|
|
#define INVALID 1
|
|
#define TOOSMALL 2
|
|
#define TOOLARGE 3
|
|
|
|
long long
|
|
strtonum(const char *numstr, long long minval, long long maxval,
|
|
const char **errstrp)
|
|
{
|
|
long long ll = 0;
|
|
int error = 0;
|
|
char *ep;
|
|
struct errval {
|
|
const char *errstr;
|
|
int err;
|
|
} ev[4] = {
|
|
{ NULL, 0 },
|
|
{ "invalid", EINVAL },
|
|
{ "too small", ERANGE },
|
|
{ "too large", ERANGE },
|
|
};
|
|
|
|
ev[0].err = errno;
|
|
errno = 0;
|
|
if (minval > maxval) {
|
|
error = INVALID;
|
|
} else {
|
|
ll = strtoll(numstr, &ep, 10);
|
|
if (numstr == ep || *ep != '\0')
|
|
error = INVALID;
|
|
else if ((ll == LLONG_MIN && errno == ERANGE) || ll < minval)
|
|
error = TOOSMALL;
|
|
else if ((ll == LLONG_MAX && errno == ERANGE) || ll > maxval)
|
|
error = TOOLARGE;
|
|
}
|
|
if (errstrp != NULL)
|
|
*errstrp = ev[error].errstr;
|
|
errno = ev[error].err;
|
|
if (error)
|
|
ll = 0;
|
|
|
|
return ll;
|
|
}
|
|
|
|
char *
|
|
timestamp(time_t t, char buf[TIMESTAMP_LEN])
|
|
{
|
|
strftime(buf, TIMESTAMP_LEN, "%a, %d %b %Y %T GMT", gmtime(&t));
|
|
|
|
return buf;
|
|
}
|