diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2013-10-13 12:13:46 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2013-10-13 12:13:46 +0300 |
commit | 510fc646f13b843d046323e3477edb6c1bc2258d (patch) | |
tree | 3de9ea346897300e00ef169fcc84ab508b3d70a3 | |
parent | fcc1c011757f71bb3ec1c883a19c1945fd83cf11 (diff) | |
download | vmod-binlog-510fc646f13b843d046323e3477edb6c1bc2258d.tar.gz vmod-binlog-510fc646f13b843d046323e3477edb6c1bc2258d.tar.bz2 |
Improve error reporting.
* src/pack.c: Use packerror to report errors.
* src/pack.h (packerror): New proto.
* src/binlog.c (packerror): New function.
* src/binlogcat.c (packerror,error,verror): New functions.
-rw-r--r-- | src/binlog.c | 11 | ||||
-rw-r--r-- | src/binlogcat.c | 56 | ||||
-rw-r--r-- | src/pack.c | 148 | ||||
-rw-r--r-- | src/pack.h | 2 |
4 files changed, 119 insertions, 98 deletions
diff --git a/src/binlog.c b/src/binlog.c index 325f337..7e88817 100644 --- a/src/binlog.c +++ b/src/binlog.c @@ -21,12 +21,13 @@ #include <fcntl.h> #include <unistd.h> #include <errno.h> #include <syslog.h> #include <stddef.h> #include <stdlib.h> +#include <stdarg.h> #include <ctype.h> #include <time.h> #include "vrt.h" #include "vcc_if.h" #include "bin/varnishd/cache.h" #include "vmod-binlog.h" @@ -88,13 +89,23 @@ binlog_debug(const char *fmt, ...) va_start(ap, fmt); vsyslog(LOG_DAEMON|LOG_DEBUG, fmt, ap); va_end(ap); } #define debug(c,l,s) do { if ((c)->debug>=(l)) binlog_debug s; } while(0) + +void +packerror(const char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + vsyslog(LOG_DAEMON|LOG_NOTICE, fmt, ap); + va_end(ap); +} + int module_init(struct vmod_priv *priv, const struct VCL_conf *vclconf) { struct binlog_config *conf = calloc(1, sizeof(*conf)); AN(conf); priv->priv = conf; diff --git a/src/binlogcat.c b/src/binlogcat.c index dd36337..8cdfaaa 100644 --- a/src/binlogcat.c +++ b/src/binlogcat.c @@ -17,12 +17,13 @@ #include <config.h> #include <unistd.h> #include <stddef.h> #include <stdio.h> #include <stdlib.h> +#include <stdarg.h> #include <errno.h> #include <time.h> #include <string.h> #include "vmod-binlog.h" #include "pack.h" @@ -30,12 +31,40 @@ char *progname; char *timefmt = "%c"; int number_option; int verbose_option; int timediff_option; void +verror(const char *fmt, va_list ap) +{ + fprintf(stderr, "%s: ", progname); + vfprintf(stderr, fmt, ap); + fputc('\n', stderr); +} + +void +error(const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + verror(fmt, ap); + va_end(ap); +} + +void +packerror(const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + verror(fmt, ap); + va_end(ap); +} + +void catlog(const char *fname) { FILE *fp; struct binlog_file_header header; struct binlog_record *rec; char timebuf[128]; @@ -49,74 +78,69 @@ catlog(const char *fname) if (strcmp(fname, "-") == 0) fp = stdin; else { fp = fopen(fname, "r"); if (!fp) { - fprintf(stderr, "%s: cannot open %s: %s\n", - progname, fname, strerror(errno)); + error("cannot open %s: %s", strerror(errno)); exit(1); } } if (fread(&header, sizeof(header), 1, fp) != 1) { - fprintf(stderr, "%s: error reading header of %s: %s\n", - progname, fname, strerror(errno)); + error("error reading header of %s: %s", + fname, strerror(errno)); exit(1); } if (memcmp(header.magic, BINLOG_MAGIC_STR, BINLOG_MAGIC_LEN)) { - fprintf(stderr, "%s: %s is not a binlog file\n", - progname, fname); + error("%s is not a binlog file", fname); exit(1); } if (header.version != BINLOG_VERSION) { - fprintf(stderr, "%s: %s: unknown version\n", - progname, fname); + error("%s: unknown version", progname, fname); exit(1); } size = header.hdrsize - sizeof(header); dataspec = malloc(size); if (!dataspec) { - fprintf(stderr, "%s: not enough memory", progname); + error("not enough memory"); abort(); } if (fread(dataspec, size, 1, fp) != 1) { - fprintf(stderr, "%s: error reading header of %s: %s\n", - progname, fname, strerror(errno)); + error("error reading header of %s: %s", + fname, strerror(errno)); exit(1); } if (verbose_option) printf("# %s; format=%s; recsize=%lu; recnum=%lu\n", fname, dataspec, header.recsize, header.recnum); inst = packcomp(dataspec, &p); if (*p) { - fprintf(stderr, "%s: %s: bad dataspec near %s", - progname, dataspec, p); + error("%s: bad dataspec near %s", dataspec, p); exit(1); } free(dataspec); rec = malloc(header.recsize); if (!rec) { - fprintf(stderr, "%s: not enough memory", progname); + error("not enough memory"); abort(); } env = packenv_create(header.recsize - offsetof(struct binlog_record,data)); env->fp = stdout; for (i = 0; i < header.recnum; i++) { if (fread(rec, header.recsize, 1, fp) != 1) { - fprintf(stderr, "%s: %s: unexpected eof\n", - progname, fname); + error("%s: unexpected eof", fname); break; } if (timediff_option) { if (i == 0) start_ts = rec->ts; @@ -115,18 +115,22 @@ static int getunum(char *s, uintmax_t maxval, uintmax_t *retval) { uintmax_t x = 0; for (; *s && isspace(*s); s++); for (; *s; s++) { - if (!isdigit(*s)) + if (!isdigit(*s)) { + errno = EINVAL; return -1; + } x = x*10 + *s - '0'; } - if (x > maxval) + if (x > maxval) { + errno = ERANGE; return -1; + } *retval = x; return 0; } static int getsnum(char *s, intmax_t minval, intmax_t maxval, intmax_t *retval) @@ -137,24 +141,29 @@ getsnum(char *s, intmax_t minval, intmax_t maxval, intmax_t *retval) for (; *s && isspace(*s); s++); if (*s == '-') { neg = 1; ++s; } for (; *s; s++) { - if (!isdigit(*s)) + if (!isdigit(*s)) { + errno = EINVAL; return -1; + } x = x*10 + *s - '0'; } if (neg) { - if (x > -minval) + if (x > -minval) { + errno = ERANGE; return -1; + } *retval = -x; - } else if (x > maxval) + } else if (x > maxval) { + errno = ERANGE; return -1; - else + } else *retval = x; return 0; } #define GETSARG(env, type, minv, maxv) do { \ if ((env)->buf_base) { \ @@ -162,28 +171,34 @@ getsnum(char *s, intmax_t minval, intmax_t maxval, intmax_t *retval) if (arg) { \ intmax_t x; \ if (getsnum(arg, minv, maxv, &x) == 0) { \ type v = (type) x; \ memcpy(env->buf_base + env->buf_pos, \ &v, sizeof(v)); \ - } \ - } \ + } else \ + packerror("error converting %s to %s: %s", \ + arg, #type, strerror(errno)); \ + } else \ + packerror("out of arguments"); \ } \ } while(0) #define GETUARG(env, type, maxv) do { \ if ((env)->buf_base) { \ char *arg = packenv_get(env); \ if (arg) { \ uintmax_t x; \ if (getunum(arg, maxv, &x) == 0) { \ type v = (type) x; \ memcpy(env->buf_base + env->buf_pos, \ &v, sizeof(v)); \ - } \ - } \ + } else \ + packerror("error converting %s to %s: %s", \ + arg, #type, strerror(errno)); \ + } else \ + packerror("out of arguments"); \ } \ } while(0) static void Z_packer(struct packenv *env, int rep) @@ -194,13 +209,14 @@ Z_packer(struct packenv *env, int rep) memset(env->buf_base + env->buf_pos, 0, rep); if (arg) { size_t len = strlen(arg); if (len > rep - 1) len = rep - 1; memcpy(env->buf_base + env->buf_pos, arg, len); - } + } else + packerror("out of arguments"); } env->buf_pos += rep; } static void Z_unpacker(struct packenv *env, int rep) @@ -213,12 +229,14 @@ static void c_packer(struct packenv *env, int rep) { if (env->buf_base) { char *arg = packenv_get(env); if (arg) env->buf_base[env->buf_pos] = *arg; + else + packerror("out of arguments"); } env->buf_pos++; } static void c_unpacker(struct packenv *env, int rep) @@ -347,14 +365,18 @@ n_packer(struct packenv *env, int rep) if (arg) { uintmax_t x; if (getunum(arg, UINT16_MAX, &x) == 0) { uint16_t v = htons((uint16_t) x); memcpy(env->buf_base + env->buf_pos, &v, sizeof(v)); - } - } + } else + packerror("error converting %s to %s: %s", + arg, "uint16_t (network order)", + strerror(errno)); + } else + packerror("out of arguments"); } env->buf_pos += sizeof(uint16_t); } static void n_unpacker(struct packenv *env, int rep) @@ -373,14 +395,18 @@ N_packer(struct packenv *env, int rep) if (arg) { uintmax_t x; if (getunum(arg, UINT32_MAX, &x) == 0) { uint32_t v = htonl((uint32_t) x); memcpy(env->buf_base + env->buf_pos, &v, sizeof(v)); - } - } + } else + packerror("error converting %s to %s: %s", + arg, "uint32_t (network order)", + strerror(errno)); + } else + packerror("out of arguments"); } env->buf_pos += sizeof(uint32_t); } static void N_unpacker(struct packenv *env, int rep) @@ -399,14 +425,18 @@ v_packer(struct packenv *env, int rep) if (arg) { uintmax_t x; if (getunum(arg, UINT16_MAX, &x) == 0) { uint16_t v = ntohs((uint16_t) x); memcpy(env->buf_base + env->buf_pos, &v, sizeof(v)); - } - } + } else + packerror("error converting %s to %s: %s", + arg, "uint16_t (host order)", + strerror(errno)); + } else + packerror("out of arguments"); } env->buf_pos += sizeof(uint16_t); } static void v_unpacker(struct packenv *env, int rep) @@ -425,14 +455,18 @@ V_packer(struct packenv *env, int rep) if (arg) { uintmax_t x; if (getunum(arg, UINT32_MAX, &x) == 0) { uint32_t v = ntohl((uint32_t) x); memcpy(env->buf_base + env->buf_pos, &v, sizeof(v)); - } - } + } else + packerror("error converting %s to %s: %s", + arg, "uint32_t (host order)", + strerror(errno)); + } else + packerror("out of arguments"); } env->buf_pos += sizeof(uint32_t); } static void V_unpacker(struct packenv *env, int rep) @@ -451,13 +485,19 @@ f_packer(struct packenv *env, int rep) if (arg) { float v; char *p; errno = 0; v = strtof(arg, &p); - if (*p == 0 && errno == 0) + if (*p) + packerror("error converting %s to %s (near %s)", + arg, "float", p); + else if (errno) + packerror("error converting %s to %s: %s", + arg, "float", strerror(errno)); + else memcpy(env->buf_base + env->buf_pos, &v, sizeof(v)); } } env->buf_pos += sizeof(float); } @@ -479,13 +519,19 @@ d_packer(struct packenv *env, int rep) if (arg) { double v; char *p; errno = 0; v = strtod(arg, &p); - if (*p == 0 && errno == 0) + if (*p) + packerror("error converting %s to %s (near %s)", + arg, "double", p); + else if (errno) + packerror("error converting %s to %s: %s", + arg, "double", strerror(errno)); + else memcpy(env->buf_base + env->buf_pos, &v, sizeof(v)); } } env->buf_pos += sizeof(double); } @@ -757,66 +803,6 @@ packenv_free(struct packenv *env) void packenv_init(struct packenv *env) { memset(env->buf_base, 0, env->buf_size); env->buf_pos = 0; } - -#ifdef STANDALONE -#include <unistd.h> - -int -main(int argc, char **argv) -{ - void (*fn)(struct packinst *pi, struct packenv *env) = packin; - struct packinst *pi; - struct packenv *env; - char *end; - int c; - - while ((c = getopt(argc, argv, "d")) != EOF) { - switch (c) { - case 'd': - fn = packout; - break; - default: - exit(1); - } - } - - argc -= optind; - argv += optind; - - if (argc == 0) - abort(); - - pi = packcomp(argv[0], &end); - if (!pi) { - fprintf(stderr, "out of memory\n"); - abort(); - } - if (*end) { - fprintf(stderr, "compile error near %s\n", end); - exit(1); - } - env = packenv_create(packsize(pi)); - if (!env) { - fprintf(stderr, "out of memory\n"); - abort(); - } - - env->fp = stdout; - env->argv = argv + 1; - env->argc = argc - 1; - - if (fn == packout) - fread(env->buf_base, env->buf_size, 1, stdin); - - fn(pi, env); - if (fn == packin) { - fwrite(env->buf_base, env->buf_size, 1, stdout); - } - - packenv_free(env); - packfree(pi); -} -#endif @@ -37,12 +37,12 @@ struct packinst *packinnext(struct packinst *pi, struct packenv *env); size_t packsize(struct packinst *pi); struct packenv *packenv_create(size_t size); void packenv_init(struct packenv *env); void packenv_free(struct packenv *env); - +void packerror(const char *, ...); |