int main(int argc, char **argv) { int o; struct VSM_data *vd; vd = VSM_New(); VSL_Setup(vd); while ((o = getopt(argc, argv, VSL_ARGS "Vw:")) != -1) { switch (o) { case 'V': VCS_Message("varnishhist"); exit(0); case 'w': delay = atoi(optarg); break; default: if (VSL_Arg(vd, o, optarg) > 0) break; usage(); } } if (VSL_Open(vd, 1)) exit(1); log_ten = log(10.0); do_curses(vd); exit(0); }
static void * varnishlog_thread(void *priv) { struct varnish *v; struct VSM_data *vsl; CAST_OBJ_NOTNULL(v, priv, VARNISH_MAGIC); vsl = VSM_New(); VSL_Setup(vsl); (void)VSL_Arg(vsl, 'n', v->workdir); VSL_NonBlocking(vsl, 1); while (v->pid && VSL_Open(vsl, 0) != 0) { assert(usleep(VSL_SLEEP_USEC) == 0 || errno == EINTR); } while (v->pid) { if (VSL_Dispatch(vsl, h_addlog, v) < 0) { assert(usleep(v->vsl_sleep) == 0 || errno == EINTR); v->vsl_sleep += v->vsl_sleep; if (v->vsl_sleep > VSL_SLEEP_USEC) v->vsl_sleep = VSL_SLEEP_USEC; } } VSM_Delete(vsl); return (NULL); }
static void vstat_init_ctx(struct agent_core_t *core, struct vstat_thread_ctx_t *t_ctx) { t_ctx->vd = VSM_New(); t_ctx->vsb = VSB_new_auto(); t_ctx->curl = ipc_register(core,"curl"); t_ctx->logger = ipc_register(core,"logger"); if (core->config->n_arg) VSC_Arg(t_ctx->vd, 'n', core->config->n_arg); }
/* * Parse the -n argument and populate -T if necessary. * * Run on every connect, must do some cleanup. * * XXX: It writes to stdout in addition to the logger because the logger * may not be operational yet. Not sure if this makes sense... At any rate, * the required bit is to write to the logger. */ static int n_arg_sock(struct agent_core_t *core) { struct VSM_data *vsd; struct vadmin_config_t *vadmin; char *p; GET_PRIV(core, vadmin); vsd = VSM_New(); assert(VSL_Arg(vsd, 'n', core->config->n_arg)); if (VSM_Open(vsd, 1)) { logger(vadmin->logger,"Couldn't open VSM"); fprintf(stderr, "Couldn't open VSM\n"); VSM_Delete(vsd); vsd = NULL; } if (core->config->T_arg_orig) { if (core->config->T_arg) free(core->config->T_arg); core->config->T_arg = strdup(core->config->T_arg_orig); } else { if (vsd == NULL) { logger(vadmin->logger,"No -T arg and no shmlog readable."); return -1; } p = VSM_Find_Chunk(vsd, "Arg", "-T", "", NULL); if (p == NULL) { fprintf(stderr, "No -T arg in shared memory\n"); logger(vadmin->logger, "No -T arg in shared memory."); return (-1); } core->config->T_arg = strdup(p); } if (core->config->S_arg == NULL && !vsd) { logger(vadmin->logger, "No shmlog and no -S arg. Unknown if authentication will work."); } if (vsd && core->config->S_arg == NULL) { p = VSM_Find_Chunk(vsd, "Arg", "-S", "", NULL); if (p != NULL) core->config->S_arg = strdup(p); } p = strchr(core->config->T_arg, '\n'); if (p) { assert(p); *p = '\0'; } if (vsd) VSM_Delete(vsd); logger(vadmin->logger, "-T argument computed to: %s", core->config->T_arg ? core->config->T_arg : "(null)"); return (1); }
int main(int argc, char **argv) { struct VSM_data *vd; int o, once = 0; float period = 60; /* seconds */ vd = VSM_New(); while ((o = getopt(argc, argv, VSL_ARGS "1fVp:")) != -1) { switch (o) { case '1': AN(VSL_Arg(vd, 'd', NULL)); once = 1; break; case 'f': f_flag = 1; break; case 'p': errno = 0; period = strtol(optarg, NULL, 0); if (errno != 0) { fprintf(stderr, "Syntax error, %s is not a number", optarg); exit(1); } break; case 'V': VCS_Message("varnishtop"); exit(0); case 'm': fprintf(stderr, "-m is not supported\n"); exit(1); default: if (VSL_Arg(vd, o, optarg) > 0) break; usage(); } } if (VSM_Open(vd)) { fprintf(stderr, "%s\n", VSM_Error(vd)); exit (1); } if (once) { do_once(vd); } else { do_curses(vd, period); } exit(0); }
static int n_arg_sock(const char *n_arg) { char *T_arg = NULL, *T_start = NULL; char *S_arg = NULL; struct VSM_data *vsm; char *p; int sock; struct VSM_fantom vt; vsm = VSM_New(); AN(vsm); if (VSM_n_Arg(vsm, n_arg) < 0) { fprintf(stderr, "%s\n", VSM_Error(vsm)); VSM_Delete(vsm); return (-1); } if (VSM_Open(vsm)) { fprintf(stderr, "%s\n", VSM_Error(vsm)); VSM_Delete(vsm); return (-1); } if (!VSM_Get(vsm, &vt, "Arg", "-T", "")) { fprintf(stderr, "No -T arg in shared memory\n"); VSM_Delete(vsm); return (-1); } AN(vt.b); T_start = T_arg = strdup(vt.b); if (VSM_Get(vsm, &vt, "Arg", "-S", "")) { AN(vt.b); S_arg = strdup(vt.b); } VSM_Delete(vsm); sock = -1; while (*T_arg) { p = strchr(T_arg, '\n'); AN(p); *p = '\0'; sock = cli_sock(T_arg, S_arg); if (sock >= 0) break; T_arg = p + 1; } free(T_start); free(S_arg); return (sock); }
int main(int argc, char *argv[]) { int c; struct VSM_data *vd; const char *address = NULL; vd = VSM_New(); debug = 0; VSL_Arg(vd, 'c', NULL); while ((c = getopt(argc, argv, "a:Dr:n:")) != -1) { switch (c) { case 'a': address = optarg; break; case 'D': ++debug; break; default: if (VSL_Arg(vd, c, optarg) > 0) break; usage(); } } if (address == NULL) { usage(); } if (VSM_Open(vd)) { fprintf(stderr, "%s\n", VSM_Error(vd)); exit(1); } addr_info = init_connection(address); signal(SIGPIPE, SIG_IGN); pthread_attr_init(&thread_attr); /* * XXX: seting the stack size manually reduces the memory usage * XXX: (allowing more threads) and increases speed (?) */ pthread_attr_setstacksize(&thread_attr, 32768); while (VSL_Dispatch(vd, gen_traffic, NULL) == 0) /* nothing */ ; thread_close(-1); exit(0); }
static void * varnishlog_thread(void *priv) { struct varnish *v; struct VSM_data *vsl; CAST_OBJ_NOTNULL(v, priv, VARNISH_MAGIC); vsl = VSM_New(); (void)VSL_Arg(vsl, 'n', v->workdir); while (v->pid) { if (VSL_Dispatch(vsl, h_addlog, v) <= 0) usleep(100000); } VSM_Delete(vsl); return (NULL); }
static int n_arg_sock(const char *n_arg) { char *T_arg = NULL, *T_start = NULL; char *S_arg = NULL; struct VSM_data *vsd; char *p; int sock; vsd = VSM_New(); assert(VSL_Arg(vsd, 'n', n_arg)); if (VSM_Open(vsd, 1)) { fprintf(stderr, "Could not open shared memory\n"); return (-1); } if (T_arg == NULL) { p = VSM_Find_Chunk(vsd, "Arg", "-T", "", NULL); if (p == NULL) { fprintf(stderr, "No -T arg in shared memory\n"); return (-1); } T_start = T_arg = strdup(p); } if (S_arg == NULL) { p = VSM_Find_Chunk(vsd, "Arg", "-S", "", NULL); if (p != NULL) S_arg = strdup(p); } sock = -1; while (*T_arg) { p = strchr(T_arg, '\n'); AN(p); *p = '\0'; sock = cli_sock(T_arg, S_arg); if (sock >= 0) break; T_arg = p + 1; } free(T_start); free(S_arg); return (sock); }
static void varnish_launch(struct varnish *v) { struct vsb *vsb, *vsb1; int i, nfd, nap; struct vss_addr **ap; char abuf[128], pbuf[128]; struct pollfd fd[2]; enum VCLI_status_e u; char *r; v->vd = VSM_New(); VSC_Setup(v->vd); /* Create listener socket */ nap = VSS_resolve("127.0.0.1", "0", &ap); AN(nap); v->cli_fd = VSS_listen(ap[0], 1); VTCP_myname(v->cli_fd, abuf, sizeof abuf, pbuf, sizeof pbuf); AZ(VSB_finish(v->args)); vtc_log(v->vl, 2, "Launch"); vsb = VSB_new_auto(); AN(vsb); VSB_printf(vsb, "cd ${pwd} &&"); VSB_printf(vsb, " ${varnishd} -d -d -n %s", v->workdir); VSB_printf(vsb, " -l 10m,1m,-"); VSB_printf(vsb, " -p auto_restart=off"); VSB_printf(vsb, " -p syslog_cli_traffic=off"); VSB_printf(vsb, " -a '%s'", "127.0.0.1:0"); VSB_printf(vsb, " -S %s/_S", v->workdir); VSB_printf(vsb, " -M '%s %s'", abuf, pbuf); VSB_printf(vsb, " -P %s/varnishd.pid", v->workdir); VSB_printf(vsb, " %s", VSB_data(v->storage)); VSB_printf(vsb, " %s", VSB_data(v->args)); AZ(VSB_finish(vsb)); vtc_log(v->vl, 3, "CMD: %s", VSB_data(vsb)); vsb1 = macro_expand(v->vl, VSB_data(vsb)); AN(vsb1); VSB_delete(vsb); vsb = vsb1; vtc_log(v->vl, 3, "CMD: %s", VSB_data(vsb)); AZ(pipe(&v->fds[0])); AZ(pipe(&v->fds[2])); v->pid = fork(); assert(v->pid >= 0); if (v->pid == 0) { assert(dup2(v->fds[0], 0) == 0); assert(dup2(v->fds[3], 1) == 1); assert(dup2(1, 2) == 2); AZ(close(v->fds[0])); AZ(close(v->fds[1])); AZ(close(v->fds[2])); AZ(close(v->fds[3])); for (i = 3; i <getdtablesize(); i++) (void)close(i); AZ(execl("/bin/sh", "/bin/sh", "-c", VSB_data(vsb), (char*)0)); exit(1); } else { vtc_log(v->vl, 3, "PID: %ld", (long)v->pid); } AZ(close(v->fds[0])); AZ(close(v->fds[3])); v->fds[0] = v->fds[2]; v->fds[2] = v->fds[3] = -1; VSB_delete(vsb); AZ(pthread_create(&v->tp, NULL, varnish_thread, v)); AZ(pthread_create(&v->tp_vsl, NULL, varnishlog_thread, v)); /* Wait for the varnish to call home */ memset(fd, 0, sizeof fd); fd[0].fd = v->cli_fd; fd[0].events = POLLIN; fd[1].fd = v->fds[0]; fd[1].events = 0; /* Only care about POLLHUP, which is output-only */ i = poll(fd, 2, 10000); vtc_log(v->vl, 4, "CLIPOLL %d 0x%x 0x%x", i, fd[0].revents, fd[1].revents); if (i == 0) { vtc_log(v->vl, 0, "FAIL timeout waiting for CLI connection"); return; } if (fd[1].revents & POLLHUP) { vtc_log(v->vl, 0, "FAIL debug pipe closed"); return; } if (!(fd[0].revents & POLLIN)) { vtc_log(v->vl, 0, "FAIL CLI connection wait failure"); return; } nfd = accept(v->cli_fd, NULL, NULL); if (nfd < 0) { vtc_log(v->vl, 0, "FAIL no CLI connection accepted"); return; } AZ(close(v->cli_fd)); v->cli_fd = nfd; vtc_log(v->vl, 3, "CLI connection fd = %d", v->cli_fd); assert(v->cli_fd >= 0); /* Receive the banner or auth response */ u = varnish_ask_cli(v, NULL, &r); if (vtc_error) return; if (u != CLIS_AUTH) vtc_log(v->vl, 0, "CLI auth demand expected: %u %s", u, r); bprintf(abuf, "%s/_S", v->workdir); nfd = open(abuf, O_RDONLY); assert(nfd >= 0); assert(sizeof abuf >= CLI_AUTH_RESPONSE_LEN + 7); strcpy(abuf, "auth "); VCLI_AuthResponse(nfd, r, abuf + 5); AZ(close(nfd)); free(r); strcat(abuf, "\n"); u = varnish_ask_cli(v, abuf, &r); if (vtc_error) return; if (u != CLIS_OK) vtc_log(v->vl, 0, "CLI auth command failed: %u %s", u, r); free(r); (void)VSL_Arg(v->vd, 'n', v->workdir); AZ(VSC_Open(v->vd, 1)); }
int main(int argc, char * const *argv) { int c; struct VSM_data *vd; int delay = 1, once = 0, xml = 0, json = 0, do_repeat = 0; vd = VSM_New(); while ((c = getopt(argc, argv, VSC_ARGS "1f:lVw:xjt:")) != -1) { switch (c) { case '1': once = 1; break; case 'l': list_fields(vd); exit(0); case 'V': VCS_Message("varnishstat"); exit(0); case 'w': do_repeat = 1; delay = atoi(optarg); break; case 'x': xml = 1; break; case 'j': json = 1; break; default: if (VSC_Arg(vd, c, optarg) > 0) break; usage(); } } if (VSM_Open(vd)) { fprintf(stderr, "%s\n", VSM_Error(vd)); exit(1); } if (!(xml || json || once)) { do_curses(vd, delay); exit(0); } while (1) { if (xml) do_xml(vd); else if (json) do_json(vd); else if (once) do_once(vd, VSC_Main(vd, NULL)); else { assert(0); } if (!do_repeat) break; // end of output block marker. printf("\n"); sleep(delay); } exit(0); }
static int varnish_read (user_data_t *ud) /* {{{ */ { struct VSM_data *vd; const c_varnish_stats_t *stats; user_config_t *conf; if ((ud == NULL) || (ud->data == NULL)) return (EINVAL); conf = ud->data; vd = VSM_New(); #if HAVE_VARNISH_V3 VSC_Setup(vd); #endif if (conf->instance != NULL) { int status; status = VSM_n_Arg (vd, conf->instance); if (status < 0) { VSM_Delete (vd); ERROR ("varnish plugin: VSM_n_Arg (\"%s\") failed " "with status %i.", conf->instance, status); return (-1); } } #if HAVE_VARNISH_V3 if (VSC_Open (vd, /* diag = */ 1)) #else /* if HAVE_VARNISH_V4 */ if (VSM_Open (vd)) #endif { VSM_Delete (vd); ERROR ("varnish plugin: Unable to open connection."); return (-1); } #if HAVE_VARNISH_V3 stats = VSC_Main(vd); #else /* if HAVE_VARNISH_V4 */ stats = VSC_Main(vd, NULL); #endif if (!stats) { VSM_Delete (vd); ERROR ("varnish plugin: Unable to get statistics."); return (-1); } varnish_monitor (conf, stats); VSM_Delete (vd); return (0); } /* }}} */
static unsigned int vlog_reply(struct http_request *request, void *data) { struct vlog_req_priv vrp = { .limit = 10 }; int disp_status; char *p; char *tag = NULL; char *tag_re = NULL; struct VSL_data *vsl = NULL; struct VSLQ *vslq = NULL; struct VSL_cursor *c = NULL; enum VSL_grouping_e grouping = VSL_g_request; struct agent_core_t *core = data; p = next_slash(request->url + 1); if (p) { char *lim = strdup(p); assert(lim); char *tmp2 = strchr(lim, '/'); if (tmp2 && *tmp2) *tmp2 = '\0'; int j = sscanf(lim, "%u", &vrp.limit); if(j != 1) { free(lim); http_reply(request->connection, 500, "Not a number"); return 0; } free(lim); p = next_slash(p); } if (p) { tag = strdup(p); char *tmp2 = strchr(tag,'/'); if (tmp2 && *tmp2) *tmp2 = '\0'; p = next_slash(p); } if (p) { tag_re = strdup(p); char *tmp2 = strchr(tag_re, '/'); if (tmp2 && *tmp2) *tmp2 = '\0'; p = next_slash(p); } vrp.answer = VSB_new_auto(); assert(vrp.answer != NULL); vrp.vsm = VSM_New(); assert(vrp.vsm); if (!VSM_n_Arg(vrp.vsm, core->config->n_arg)) { VSB_printf(vrp.answer, "Error in creating shmlog: %s", VSM_Error(vrp.vsm)); VSB_finish(vrp.answer); http_reply(request->connection, 500, VSB_data(vrp.answer)); goto cleanup; } if (VSM_Open(vrp.vsm) != 0) { VSB_printf(vrp.answer, "Error in opening shmlog: %s", VSM_Error(vrp.vsm)); VSB_finish(vrp.answer); http_reply(request->connection, 500, VSB_data(vrp.answer)); goto cleanup; } vsl = VSL_New(); assert(vsl); if (tag) { grouping = VSL_g_raw; if (VSL_Arg(vsl, 'i', tag) < 0) { VSB_printf(vrp.answer, "Unable to specify tag '%s': %s", tag, VSL_Error(vsl)); VSB_finish(vrp.answer); http_reply(request->connection, 500, VSB_data(vrp.answer)); goto cleanup; } if (tag_re) { VSL_Arg(vsl,'I', tag_re); } } c = VSL_CursorVSM(vsl, vrp.vsm, VSL_COPT_BATCH | VSL_COPT_TAILSTOP); if (c == NULL) { VSB_printf(vrp.answer, "Can't open log (%s)", VSL_Error(vsl)); VSB_finish(vrp.answer); http_reply(request->connection, 500, VSB_data(vrp.answer)); goto cleanup; } vslq = VSLQ_New(vsl, &c, grouping, NULL); if (vslq == NULL) { VSB_clear(vrp.answer); VSB_printf(vrp.answer, "Error in creating query: %s", VSL_Error(vsl)); http_reply(request->connection, 500, VSB_data(vrp.answer)); goto cleanup; } VSB_printf(vrp.answer, "{ \"log\": ["); do { disp_status = VSLQ_Dispatch(vslq, vlog_cb_func, &vrp); } while (disp_status == 1 && vrp.entries < vrp.limit); VSB_printf(vrp.answer, "\n] }\n"); assert(VSB_finish(vrp.answer) == 0); if (VSB_len(vrp.answer) > 1) { struct http_response *resp = http_mkresp(request->connection, 200, NULL); resp->data = VSB_data(vrp.answer); resp->ndata = VSB_len(vrp.answer); http_add_header(resp,"Content-Type","application/json"); send_response(resp); http_free_resp(resp); } else { http_reply(request->connection, 500, "FAIL"); } cleanup: free(tag); free(tag_re); VSB_delete(vrp.answer); if (vslq) VSLQ_Delete(&vslq); if (vsl) VSL_Delete(vsl); if (vrp.vsm) VSM_Delete(vrp.vsm); vrp.answer = NULL; return 0; } void vlog_init(struct agent_core_t *core) { struct agent_plugin_t *plug; struct vlog_priv_t *priv; ALLOC_OBJ(priv); plug = plugin_find(core,"vlog"); plug->data = priv; http_register_url(core, "/log", M_GET, vlog_reply, core); }
static unsigned int vlog_reply(struct httpd_request *request, void *data) { struct vlog_priv_t *vlog; int ret; char *limit = NULL; char *p; char *tag = NULL; char *itag = NULL; struct agent_core_t *core = data; GET_PRIV(data,vlog); p = next_slash(request->url + 1); assert(vlog->tag==NULL); assert(vlog->answer == NULL); if (p) { limit = strdup(p); assert(limit); char *tmp2 = index(limit,'/'); if (tmp2 && *tmp2) *tmp2 = '\0'; if(!(atoi(limit) > 0)) { free(limit); send_response_fail(request->connection,"Not a number"); return 0; } p = next_slash(p); } if (p) { tag = strdup(p); char *tmp2 = index(tag,'/'); if (tmp2 && *tmp2) *tmp2 = '\0'; p = next_slash(p); } if (p) { itag = strdup(p); char *tmp2 = index(itag,'/'); if (tmp2 && *tmp2) *tmp2 = '\0'; p = next_slash(p); } vlog->answer = VSB_new_auto(); assert(vlog->answer != NULL); vlog->vd = VSM_New(); assert(VSL_Arg(vlog->vd, 'n', core->config->n_arg)); VSL_Setup(vlog->vd); VSL_Arg(vlog->vd, 'd', ""); if (tag) { VSL_Arg(vlog->vd, 'i', tag); if (itag) VSL_Arg(vlog->vd,'I',itag); } else { VSL_Arg(vlog->vd, 'k', limit ? limit : "10"); } if (limit) free(limit); VSB_printf(vlog->answer, "{ \"log\": ["); ret = VSL_Open(vlog->vd, 1); assert(!ret); if (tag == NULL) { do_order(vlog); } else { do_unorder(vlog); } if (tag) free(tag); if (itag) free(itag); VSB_printf(vlog->answer, "\n] }\n"); assert(VSB_finish(vlog->answer) == 0); if (VSB_len(vlog->answer) > 1) { send_response(request->connection, 200, VSB_data(vlog->answer), VSB_len(vlog->answer)); } else { send_response_fail(request->connection, "FAIL"); } VSB_clear(vlog->answer); VSM_Close(vlog->vd); vlog->answer = NULL; vlog->entries = 0; return 0; }
void VUT_Setup(void) { struct VSL_cursor *c; double t_start; int i; AN(VUT.vsl); AZ(VUT.vsm); AZ(VUT.vslq); /* Check input arguments */ if ((VUT.n_arg == NULL ? 0 : 1) + (VUT.N_arg == NULL ? 0 : 1) + (VUT.r_arg == NULL ? 0 : 1) > 1) VUT_Error(1, "Only one of -n, -N and -r options may be used"); /* Create and validate the query expression */ VUT.vslq = VSLQ_New(VUT.vsl, NULL, VUT.g_arg, VUT.q_arg); if (VUT.vslq == NULL) VUT_Error(1, "Query expression error:\n%s", VSL_Error(VUT.vsl)); /* Setup input */ if (VUT.r_arg) { REPLACE(VUT.name, VUT.r_arg); c = VSL_CursorFile(VUT.vsl, VUT.r_arg, 0); if (c == NULL) VUT_Error(1, "Can't open log file (%s)", VSL_Error(VUT.vsl)); } else { VUT.vsm = VSM_New(); AN(VUT.vsm); if (VUT.n_arg && VSM_n_Arg(VUT.vsm, VUT.n_arg) <= 0) VUT_Error(1, "%s", VSM_Error(VUT.vsm)); if (VUT.N_arg && VSM_N_Arg(VUT.vsm, VUT.N_arg) <= 0) VUT_Error(1, "%s", VSM_Error(VUT.vsm)); REPLACE(VUT.name, VSM_Name(VUT.vsm)); t_start = NAN; c = NULL; while (1) { i = VSM_Open(VUT.vsm); if (!i) c = VSL_CursorVSM(VUT.vsl, VUT.vsm, (VUT.d_opt ? VSL_COPT_TAILSTOP : VSL_COPT_TAIL) | VSL_COPT_BATCH); if (c) break; if (isnan(t_start) && VUT.t_arg > 0.) { VUT_Error(0, "Can't open log -" " retrying for %.0f seconds", VUT.t_arg); t_start = VTIM_real(); } VSM_Close(VUT.vsm); if (VUT.t_arg <= 0.) break; if (VTIM_real() - t_start > VUT.t_arg) break; VSM_ResetError(VUT.vsm); VSL_ResetError(VUT.vsl); VTIM_sleep(0.5); } if (VUT.t_arg >= 0. && (i || !c)) { if (i) VUT_Error(1, "Can't open VSM file (%s)", VSM_Error(VUT.vsm)); else VUT_Error(1, "Can't open log (%s)", VSL_Error(VUT.vsl)); } else if (!isnan(t_start)) VUT_Error(0, "Log opened"); } if (c) VSLQ_SetCursor(VUT.vslq, &c); AZ(c); /* Signal handlers */ (void)signal(SIGHUP, vut_sighup); (void)signal(SIGINT, vut_sigint); (void)signal(SIGTERM, vut_sigint); (void)signal(SIGUSR1, vut_sigusr1); /* Open PID file */ if (VUT.P_arg) { AZ(VUT.pfh); VUT.pfh = VPF_Open(VUT.P_arg, 0644, NULL); if (VUT.pfh == NULL) VUT_Error(1, "%s: %s", VUT.P_arg, strerror(errno)); } /* Daemon mode */ if (VUT.D_opt && varnish_daemon(0, 0) == -1) VUT_Error(1, "Daemon mode: %s", strerror(errno)); /* Write PID and setup exit handler */ if (VUT.pfh != NULL) { VPF_Write(VUT.pfh); AZ(atexit(vut_vpf_remove)); } }
int main(int argc, char * const *argv) { struct VSM_data *vd; double t_arg = 5.0, t_start = NAN; int once = 0, xml = 0, json = 0, f_list = 0, curses = 0; signed char opt; int i; VUT_Init(progname, argc, argv, &vopt_spec); vd = VSM_New(); AN(vd); while ((opt = getopt(argc, argv, vopt_spec.vopt_optstring)) != -1) { switch (opt) { case '1': once = 1; break; case 'h': /* Usage help */ usage(0); case 'l': f_list = 1; break; case 't': if (!strcasecmp(optarg, "off")) t_arg = -1.; else { t_arg = VNUM(optarg); if (isnan(t_arg)) VUT_Error(1, "-t: Syntax error"); if (t_arg < 0.) VUT_Error(1, "-t: Range error"); } break; case 'V': VCS_Message("varnishstat"); exit(0); case 'x': xml = 1; break; case 'j': json = 1; break; default: i = VSC_Arg(vd, opt, optarg); if (i < 0) VUT_Error(1, "%s", VSM_Error(vd)); if (!i) usage(1); } } if (optind != argc) usage(1); if (!(xml || json || once || f_list)) curses = 1; while (1) { i = VSM_Open(vd); if (!i) break; if (isnan(t_start) && t_arg > 0.) { fprintf(stderr, "Can't open log -" " retrying for %.0f seconds\n", t_arg); t_start = VTIM_real(); } if (t_arg <= 0.) break; if (VTIM_real() - t_start > t_arg) break; VSM_ResetError(vd); VTIM_sleep(0.5); } if (curses) { if (i && t_arg >= 0.) VUT_Error(1, "%s", VSM_Error(vd)); do_curses(vd, 1.0); exit(0); } if (i) VUT_Error(1, "%s", VSM_Error(vd)); if (xml) do_xml(vd); else if (json) do_json(vd); else if (once) do_once(vd); else if (f_list) list_fields(vd); else assert(0); exit(0); }