#include "shmlog.h"
#include "varnishapi.h"
-/*
- * It would be simpler to use sparse array initialization and put it
- * directly in tagnames, but -pedantic gets in the way
- */
-
-static struct tagnames {
- enum shmlogtag tag;
- const char *name;
-} stagnames[] = {
-#define SLTM(foo) { SLT_##foo, #foo },
+static const char *tagnames[] = {
+#define SLTM(foo) [SLT_##foo] = #foo,
#include "shmlog_tags.h"
#undef SLTM
- { SLT_ENDMARKER, NULL}
};
-static const char *tagnames[256];
-
static char *
vis_it(unsigned char *p)
{
{
int i, c;
unsigned u, v;
- unsigned char *p, *q;
+ unsigned char *p;
int o_flag = 0;
char *w_opt = NULL;
FILE *wfile = NULL;
- char *r_opt = NULL;
- FILE *rfile = NULL;
int h_opt = 0;
- unsigned char rbuf[255+4];
- struct shmloghead *loghead;
+ struct VSL_data *vd;
- loghead = VSL_OpenLog();
+ vd = VSL_New();
- for (i = 0; stagnames[i].tag != SLT_ENDMARKER; i++)
- tagnames[stagnames[i].tag] = stagnames[i].name;
-
- while ((c = getopt(argc, argv, "hor:w:")) != -1) {
+ while ((c = getopt(argc, argv, VSL_ARGS "how:")) != -1) {
+ if (VSL_Arg(vd, c, optarg))
+ continue;
switch (c) {
case 'h':
h_opt = 1;
case 'o':
o_flag = 1;
break;
- case 'r':
- r_opt = optarg;
- break;
case 'w':
w_opt = optarg;
break;
}
}
- if (r_opt != NULL && w_opt != NULL)
- Usage();
+ if (VSL_OpenLog(vd))
+ exit (1);
+
if (o_flag && w_opt != NULL)
Usage();
- if (r_opt != NULL) {
- if (!strcmp(r_opt, "-"))
- rfile = stdin;
- else
- rfile = fopen(r_opt, "r");
- if (rfile == NULL)
- perror(r_opt);
- }
if (w_opt != NULL) {
wfile = fopen(w_opt, "w");
if (wfile == NULL)
u = 0;
v = 0;
- q = NULL;
- if (r_opt == NULL) {
- while (VSL_NextLog(loghead, &q) != NULL)
- ;
- }
while (1) {
- if (r_opt == NULL) {
- p = VSL_NextLog(loghead, &q);
- if (p == NULL) {
- if (w_opt == NULL) {
- if (o_flag && ++v == 100)
- clean_order();
- fflush(stdout);
- } else if (++v == 100) {
- fflush(wfile);
- printf("\nFlushed\n");
- }
- usleep(50000);
- continue;
+ p = VSL_NextLog(vd);
+ if (p == NULL) {
+ if (w_opt == NULL) {
+ if (o_flag && ++v == 100)
+ clean_order();
+ fflush(stdout);
+ } else if (++v == 100) {
+ fflush(wfile);
+ printf("\nFlushed\n");
}
- } else {
- i = fread(rbuf, 4, 1, rfile);
- if (i != 1)
- break;
- if (rbuf[1] > 0)
- i = fread(rbuf + 4, rbuf[1], 1, rfile);
- if (i != 1)
- break;
- p = rbuf;
+ usleep(50000);
+ continue;
}
v = 0;
if (wfile != NULL) {
#include "shmlog.h"
#include "varnishapi.h"
+struct VSL_data {
+ struct shmloghead *head;
+ unsigned char *logstart;
+ unsigned char *logend;
+ unsigned char *ptr;
+ char *r_arg;
+ FILE *fi;
+ unsigned char rbuf[4 + 255 + 1];
+};
+
#ifndef MAP_HASSEMAPHORE
#define MAP_HASSEMAPHORE 0 /* XXX Linux */
#endif
-static unsigned char *logstart, *logend;
+static int vsl_fd;
+static struct shmloghead *vsl_lh;
+
+/*--------------------------------------------------------------------*/
-struct shmloghead *
-VSL_OpenLog(void)
+static int
+vsl_shmem_map(void)
{
- int fd;
int i;
- struct shmloghead slh, *lh;
+ struct shmloghead slh;
- fd = open(SHMLOG_FILENAME, O_RDONLY);
- if (fd < 0) {
+ if (vsl_lh != NULL)
+ return (0);
+
+ vsl_fd = open(SHMLOG_FILENAME, O_RDONLY);
+ if (vsl_fd < 0) {
fprintf(stderr, "Cannot open %s: %s\n",
SHMLOG_FILENAME, strerror(errno));
- exit (1);
+ return (1);
}
- i = read(fd, &slh, sizeof slh);
+ i = read(vsl_fd, &slh, sizeof slh);
if (i != sizeof slh) {
fprintf(stderr, "Cannot read %s: %s\n",
SHMLOG_FILENAME, strerror(errno));
- exit (1);
+ return (1);
}
if (slh.magic != SHMLOGHEAD_MAGIC) {
fprintf(stderr, "Wrong magic number in file %s\n",
SHMLOG_FILENAME);
- exit (1);
+ return (1);
}
- lh = mmap(NULL, slh.size + sizeof slh,
- PROT_READ, MAP_HASSEMAPHORE, fd, 0);
- if (lh == MAP_FAILED) {
+ vsl_lh = mmap(NULL, slh.size + sizeof slh,
+ PROT_READ, MAP_HASSEMAPHORE, vsl_fd, 0);
+ if (vsl_lh == MAP_FAILED) {
fprintf(stderr, "Cannot mmap %s: %s\n",
SHMLOG_FILENAME, strerror(errno));
- exit (1);
+ return (1);
}
+ return (0);
+}
- logstart = (unsigned char *)lh + lh->start;
- logend = logstart + lh->size;
+/*--------------------------------------------------------------------*/
- return (lh);
+struct VSL_data *
+VSL_New(void)
+{
+ struct VSL_data *vd;
+
+ vd = calloc(sizeof *vd, 1);
+ return (vd);
+}
+
+int
+VSL_OpenLog(struct VSL_data *vd)
+{
+
+ if (vd->r_arg != NULL) {
+ if (!strcmp(vd->r_arg, "-"))
+ vd->fi = stdin;
+ else
+ vd->fi = fopen(vd->r_arg, "r");
+ if (vd->fi != NULL)
+ return (0);
+ perror(vd->r_arg);
+ return (1);
+ }
+ if (vsl_shmem_map())
+ return (1);
+
+ vd->logstart = (unsigned char *)vsl_lh + vsl_lh->start;
+ vd->logend = vd->logstart + vsl_lh->size;
+ vd->head = vsl_lh;
+ return (0);
}
unsigned char *
-VSL_NextLog(struct shmloghead *lh __unused, unsigned char **pp)
+VSL_NextLog(struct VSL_data *vd)
{
unsigned char *p;
+ int i;
- p = *pp;
+ if (vd->fi != NULL) {
+ i = fread(vd->rbuf, 4, 1, vd->fi);
+ if (i != 1)
+ return (NULL);
+ if (vd->rbuf[1] > 0) {
+ i = fread(vd->rbuf + 4, vd->rbuf[1], 1, vd->fi);
+ if (i != 1)
+ return (NULL);
+ }
+ return (vd->rbuf);
+ }
+
+ p = vd->ptr;
if (p == NULL)
- p = logstart;
+ p = vd->logstart;
while (1) {
if (*p == SLT_WRAPMARKER) {
- p = logstart;
+ p = vd->logstart;
continue;
}
if (*p == SLT_ENDMARKER) {
- *pp = p;
+ vd->ptr = p;
return (NULL);
}
- *pp = p + p[1] + 4;
+ vd->ptr = p + p[1] + 4;
return (p);
}
}
+
+int
+VSL_Arg(struct VSL_data *vd, int arg, const char *opt)
+{
+ switch (arg) {
+ case 'r':
+ vd->r_arg = strdup(opt);
+ return (1);
+ default:
+ return (0);
+ }
+}
+
+struct varnish_stats *
+VSL_OpenStats(void)
+{
+
+ if (vsl_shmem_map())
+ return (NULL);
+ return (&vsl_lh->stats);
+}
+