void VJ_Init(const char *j_arg) { char **av; int i; if (j_arg != NULL) { av = VAV_Parse(j_arg, NULL, ARGV_COMMA); AN(av); if (av[0] != NULL) ARGV_ERR("-j argument: %s\n", av[0]); if (av[1] == NULL) ARGV_ERR("-j argument is emtpy\n"); vjt = pick(vj_choice, av[1], "jail"); CHECK_OBJ_NOTNULL(vjt, JAIL_TECH_MAGIC); (void)vjt->init(av + 2); VAV_Free(av); } else { /* * Go through list of jail technologies until one * succeeds, falling back to "none". */ for (i = 0; vj_choice[i].name != NULL; i++) { vjt = vj_choice[i].ptr; CHECK_OBJ_NOTNULL(vjt, JAIL_TECH_MAGIC); if (!vjt->init(NULL)) break; } } VSB_printf(vident, ",-j%s", vjt->name); }
void VRT_ban_string(struct sess *sp, const char *str) { char *a1, *a2, *a3; char **av; struct ban *b; int good; int i; (void)sp; av = VAV_Parse(str, NULL, ARGV_NOESC); if (av[0] != NULL) { /* XXX: report error how ? */ VAV_Free(av); return; } b = BAN_New(); good = 0; for (i = 1; ;) { a1 = av[i++]; if (a1 == NULL) break; good = 0; a2 = av[i++]; if (a2 == NULL) break; a3 = av[i++]; if (a3 == NULL) break; if (BAN_AddTest(NULL, b, a1, a2, a3)) break; good = 1; if (av[i] == NULL) break; good = 0; if (strcmp(av[i++], "&&")) break; } if (!good) /* XXX: report error how ? */ BAN_Free(b); else BAN_Insert(b); VAV_Free(av); }
int tweak_poolparam(struct vsb *vsb, const struct parspec *par, const char *arg) { volatile struct poolparam *pp, px; char **av; int retval = 0; pp = par->priv; if (arg == NULL) { VSB_printf(vsb, "%u,%u,%g", pp->min_pool, pp->max_pool, pp->max_age); } else { av = VAV_Parse(arg, NULL, ARGV_COMMA); do { if (av[0] != NULL) { VSB_printf(vsb, "Parse error: %s", av[0]); retval = -1; break; } if (av[1] == NULL || av[2] == NULL || av[3] == NULL) { VSB_printf(vsb, "Three fields required:" " min_pool, max_pool and max_age\n"); retval = -1; break; } px = *pp; retval = tweak_generic_uint(vsb, &px.min_pool, av[1], par->min, par->max); if (retval) break; retval = tweak_generic_uint(vsb, &px.max_pool, av[2], par->min, par->max); if (retval) break; retval = tweak_generic_double(vsb, &px.max_age, av[3], "0", "1e6", "%.0f"); if (retval) break; if (px.min_pool > px.max_pool) { VSB_printf(vsb, "min_pool cannot be larger" " than max_pool\n"); retval = -1; break; } *pp = px; } while(0); VAV_Free(av); } return (retval); }
void VRT_ban_string(VRT_CTX, const char *str) { char *a1, *a2, *a3; char **av; struct ban *b; int i; CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); AN(ctx->vsl); AN(str); b = BAN_New(); if (b == NULL) { VSLb(ctx->vsl, SLT_VCL_Error, "ban(): Out of Memory"); return; } av = VAV_Parse(str, NULL, ARGV_NOESC); AN(av); if (av[0] != NULL) { VSLb(ctx->vsl, SLT_VCL_Error, "ban(): %s", av[0]); VAV_Free(av); BAN_Free(b); return; } for (i = 0; ;) { a1 = av[++i]; if (a1 == NULL) { VSLb(ctx->vsl, SLT_VCL_Error, "ban(): No ban conditions found."); break; } a2 = av[++i]; if (a2 == NULL) { VSLb(ctx->vsl, SLT_VCL_Error, "ban(): Expected comparison operator."); break; } a3 = av[++i]; if (a3 == NULL) { VSLb(ctx->vsl, SLT_VCL_Error, "ban(): Expected second operand."); break; } if (BAN_AddTest(b, a1, a2, a3) || av[++i] == NULL) { a1 = BAN_Insert(b); if (a1 != NULL) { VSLb(ctx->vsl, SLT_VCL_Error, "ban(): %s", a1); BAN_Free_Errormsg(a1); } break; } if (strcmp(av[i], "&&")) { VSLb(ctx->vsl, SLT_VCL_Error, "ban(): Expected && between conditions," " found \"%s\"", av[i]); break; } } VAV_Free(av); }
void VRT_ban_string(VRT_CTX, const char *str) { char *a1, *a2, *a3; char **av; struct ban_proto *bp; const char *err; int i; CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); AN(ctx->vsl); AN(str); bp = BAN_Build(); if (bp == NULL) { VSLb(ctx->vsl, SLT_VCL_Error, "ban(): Out of Memory"); return; } av = VAV_Parse(str, NULL, ARGV_NOESC); AN(av); if (av[0] != NULL) { VSLb(ctx->vsl, SLT_VCL_Error, "ban(): %s", av[0]); VAV_Free(av); BAN_Abandon(bp); return; } for (i = 0; ;) { a1 = av[++i]; if (a1 == NULL) { VSLb(ctx->vsl, SLT_VCL_Error, "ban(): No ban conditions found."); break; } a2 = av[++i]; if (a2 == NULL) { VSLb(ctx->vsl, SLT_VCL_Error, "ban(): Expected comparison operator."); break; } a3 = av[++i]; if (a3 == NULL) { VSLb(ctx->vsl, SLT_VCL_Error, "ban(): Expected second operand."); break; } err = BAN_AddTest(bp, a1, a2, a3); if (err) { VSLb(ctx->vsl, SLT_VCL_Error, "ban(): %s", err); break; } if (av[++i] == NULL) { err = BAN_Commit(bp); if (err == NULL) bp = NULL; else VSLb(ctx->vsl, SLT_VCL_Error, "ban(): %s", err); break; } if (strcmp(av[i], "&&")) { VSLb(ctx->vsl, SLT_VCL_Error, "ban(): Expected && between conditions," " found \"%s\"", av[i]); break; } } if (bp != NULL) BAN_Abandon(bp); VAV_Free(av); }
char * mgt_VccCompile(struct cli *cli, struct vclprog *vcl, const char *vclname, const char *vclsrc, const char *vclsrcfile, int C_flag) { struct vcc_priv vp; struct vsb *sb; unsigned status; char buf[1024]; FILE *fcs; char **av; int ac; AN(cli); sb = VSB_new_auto(); XXXAN(sb); INIT_OBJ(&vp, VCC_PRIV_MAGIC); vp.vclsrc = vclsrc; vp.vclsrcfile = vclsrcfile; /* * The subdirectory must have a unique name to 100% certain evade * the refcounting semantics of dlopen(3). * * Bad implementations of dlopen(3) think the shlib you are opening * is the same, if the filename is the same as one already opened. * * Sensible implementations do a stat(2) and requires st_ino and * st_dev to also match. * * A correct implementation would run on filesystems which tickle * st_gen, and also insist that be the identical, before declaring * a match. * * Since no correct implementations are known to exist, we are subject * to really interesting races if you do something like: * * (running on 'boot' vcl) * vcl.load foo /foo.vcl * vcl.use foo * few/slow requests * vcl.use boot * vcl.discard foo * vcl.load foo /foo.vcl // dlopen(3) says "same-same" * vcl.use foo * * Because discard of the first 'foo' lingers on non-zero reference * count, and when it finally runs, it trashes the second 'foo' because * dlopen(3) decided they were really the same thing. * * The Best way to reproduce this is to have regexps in the VCL. */ VSB_printf(sb, "vcl_%s.%.9f", vclname, VTIM_real()); AZ(VSB_finish(sb)); vp.dir = strdup(VSB_data(sb)); AN(vp.dir); if (VJ_make_subdir(vp.dir, "VCL", cli->sb)) { free(vp.dir); VSB_destroy(&sb); VCLI_Out(cli, "VCL compilation failed"); VCLI_SetResult(cli, CLIS_PARAM); return (NULL); } VSB_clear(sb); VSB_printf(sb, "%s/%s", vp.dir, VGC_SRC); AZ(VSB_finish(sb)); vp.csrcfile = strdup(VSB_data(sb)); AN(vp.csrcfile); VSB_clear(sb); VSB_printf(sb, "%s/%s", vp.dir, VGC_LIB); AZ(VSB_finish(sb)); vp.libfile = strdup(VSB_data(sb)); AN(vp.csrcfile); VSB_clear(sb); status = mgt_vcc_compile(&vp, sb, C_flag); AZ(VSB_finish(sb)); if (VSB_len(sb) > 0) VCLI_Out(cli, "%s", VSB_data(sb)); VSB_destroy(&sb); if (status || C_flag) { (void)unlink(vp.csrcfile); free(vp.csrcfile); (void)unlink(vp.libfile); free(vp.libfile); (void)rmdir(vp.dir); free(vp.dir); if (status) { VCLI_Out(cli, "VCL compilation failed"); VCLI_SetResult(cli, CLIS_PARAM); } return (NULL); } fcs = fopen(vp.csrcfile, "r"); AN(fcs); while (1) { AN(fgets(buf, sizeof buf, fcs)); if (memcmp(buf, VCC_INFO_PREFIX, strlen(VCC_INFO_PREFIX))) break; av = VAV_Parse(buf, &ac, 0); AN(av); AZ(av[0]); AZ(strcmp(av[1], "/*")); AZ(strcmp(av[ac-1], "*/")); if (!strcmp(av[3], "VCL")) mgt_vcl_depends(vcl, av[4]); else if (!strcmp(av[3], "VMOD")) mgt_vcl_vmod(vcl, av[4], av[5]); else WRONG("Wrong VCCINFO"); VAV_Free(av); } AZ(fclose(fcs)); (void)unlink(vp.csrcfile); free(vp.csrcfile); free(vp.dir); VCLI_Out(cli, "VCL compiled.\n"); return (vp.libfile); }