void prelog_add(char *ua, char *login, time_t tstamp, char *message, char *link, md5_byte_t md5[16], int viewed) { prelog_msg *pl, *p, *pp; ALLOC_OBJ(pl, prelog_msg); pl->ua = strdup(ua); pl->login = strdup(login); pl->msg = strdup(message); pl->link = link ? strdup(link) : NULL; pl->tstamp = tstamp; pl->viewed = viewed; memcpy(pl->md5, md5, 16); pp = NULL; p = prelog; while (p && p->tstamp < tstamp) { pp = p; p = p->next; } if (pp) { pl->next = pp->next; pp->next = pl; } else { pl->next = prelog; prelog = pl; } }
struct vslq_query * vslq_newquery(struct VSL_data *vsl, enum VSL_grouping_e grouping, const char *querystring) { struct vslq_query *query; const char *error; int pos; vre_t *regex; (void)grouping; AN(querystring); regex = VRE_compile(querystring, 0, &error, &pos); if (regex == NULL) { vsl_diag(vsl, "failed to compile regex at pos %d: %s", pos, error); return (NULL); } ALLOC_OBJ(query, VSLQ_QUERY_MAGIC); if (query != NULL) query->regex = regex; return (query); }
void VBP_Insert(struct backend *b, const struct vrt_backend_probe *vp, struct tcp_pool *tp) { struct vbp_target *vt; CHECK_OBJ_NOTNULL(b, BACKEND_MAGIC); CHECK_OBJ_NOTNULL(vp, VRT_BACKEND_PROBE_MAGIC); AZ(b->probe); ALLOC_OBJ(vt, VBP_TARGET_MAGIC); XXXAN(vt); vt->tcp_pool = tp; vt->backend = b; b->probe = vt; vbp_set_defaults(vt, vp); vbp_build_req(vt, vp, b); vbp_reset(vt); vbp_update_backend(vt); }
static void vxp_expr_num(struct vxp *vxp, struct vex_rhs **prhs) { char *endptr; AN(prhs); AZ(*prhs); if (vxp->t->tok != VAL) { VSB_printf(vxp->sb, "Expected number got '%.*s' ", PF(vxp->t)); vxp_ErrWhere(vxp, vxp->t, -1); return; } AN(vxp->t->dec); ALLOC_OBJ(*prhs, VEX_RHS_MAGIC); AN(*prhs); if (strchr(vxp->t->dec, '.')) { (*prhs)->type = VEX_FLOAT; (*prhs)->val_float = VNUM(vxp->t->dec); if (isnan((*prhs)->val_float)) { VSB_printf(vxp->sb, "Floating point parse error "); vxp_ErrWhere(vxp, vxp->t, -1); return; } } else { (*prhs)->type = VEX_INT; (*prhs)->val_int = strtoll(vxp->t->dec, &endptr, 0); while (isspace(*endptr)) endptr++; if (*endptr != '\0') { VSB_printf(vxp->sb, "Integer parse error "); vxp_ErrWhere(vxp, vxp->t, -1); return; } } vxp_NextToken(vxp); }
static struct vsmw_cluster * vsmw_newcluster(struct vsmw *vsmw, size_t len, const char *pfx) { struct vsmw_cluster *vc; int fd; size_t ps; ALLOC_OBJ(vc, VSMW_CLUSTER_MAGIC); AN(vc); vsmw_mkent(vsmw, pfx); REPLACE(vc->fn, VSB_data(vsmw->vsb)); VTAILQ_INSERT_TAIL(&vsmw->clusters, vc, list); ps = getpagesize(); len = RUP2(len, ps); vc->len = len; fd = openat(vsmw->vdirfd, vc->fn, O_RDWR | O_CREAT | O_EXCL, vsmw->mode); assert(fd >= 0); AZ(VFIL_allocate(fd, (off_t)len, 1)); vc->ptr = (void *)mmap(NULL, len, PROT_READ|PROT_WRITE, MAP_HASSEMAPHORE | MAP_NOSYNC | MAP_SHARED, fd, 0); AZ(close(fd)); assert(vc->ptr != MAP_FAILED); (void)mlock(vc->ptr, len); return (vc); }
VCL_BACKEND VRT_AddDirector(VRT_CTX, const struct vdi_methods *m, void *priv, const char *fmt, ...) { struct vsb *vsb; struct vcl *vcl; struct vcldir *vdir; struct director *d; va_list ap; int i; CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); CHECK_OBJ_NOTNULL(m, VDI_METHODS_MAGIC); AN(fmt); vcl = ctx->vcl; CHECK_OBJ_NOTNULL(vcl, VCL_MAGIC); AZ(errno=pthread_rwlock_rdlock(&vcl->temp_rwl)); if (vcl->temp == VCL_TEMP_COOLING) { AZ(errno=pthread_rwlock_unlock(&vcl->temp_rwl)); return (NULL); } ALLOC_OBJ(d, DIRECTOR_MAGIC); AN(d); ALLOC_OBJ(vdir, VCLDIR_MAGIC); AN(vdir); vdir->dir = d; d->vdir = vdir; vdir->methods = m; d->priv = priv; vsb = VSB_new_auto(); AN(vsb); VSB_printf(vsb, "%s.", VCL_Name(vcl)); i = VSB_len(vsb); va_start(ap, fmt); VSB_vprintf(vsb, fmt, ap); va_end(ap); AZ(VSB_finish(vsb)); REPLACE((vdir->cli_name), VSB_data(vsb)); VSB_destroy(&vsb); d->vcl_name = vdir->cli_name + i; vdir->vcl = vcl; d->sick = 0; vdir->admin_health = VDI_AH_PROBE; vdir->health_changed = VTIM_real(); Lck_Lock(&vcl_mtx); VTAILQ_INSERT_TAIL(&vcl->director_list, vdir, list); Lck_Unlock(&vcl_mtx); if (VCL_WARM(vcl)) /* Only when adding backend to already warm VCL */ VDI_Event(d, VCL_EVENT_WARM); else if (vcl->temp != VCL_TEMP_INIT) WRONG("Dynamic Backends can only be added to warm VCLs"); AZ(errno=pthread_rwlock_unlock(&vcl->temp_rwl)); return (d); }
static int answer_to_connection(void *cls, struct MHD_Connection *connection, const char *url, const char *method, const char *version, const char *upload_data, size_t * upload_data_size, void **con_cls) { struct agent_core_t *core = (struct agent_core_t *)cls; struct http_priv_t *http; struct http_request request; struct connection_info_struct *con_info; (void)version; GET_PRIV(core, http); if (*con_cls == NULL) { ALLOC_OBJ(con_info); *con_cls = con_info; return (MHD_YES); } con_info = *con_cls; assert(core->config->userpass); log_request(connection, http, method, url); if (!strcmp(method, "OPTIONS")) { /* We need this for preflight requests (CORS). */ return (http_reply(connection, 200, NULL)); } else if (!strcmp(method, "GET") || !strcmp(method, "HEAD") || !strcmp(method, "DELETE")) { if (check_auth(connection, core, con_info)) return (MHD_YES); if (!strcmp(method, "DELETE")) request.method = M_DELETE; else request.method = M_GET; request.connection = connection; request.url = url; request.ndata = 0; if (find_listener(&request, http)) return (MHD_YES); } else if (!strcmp(method, "POST") || !strcmp(method, "PUT")) { if (*upload_data_size != 0) { if (*upload_data_size + con_info->progress >= RCV_BUFFER) { warnlog(http->logger, "Client input exceeded buffer size " "of %u bytes. Dropping client.", RCV_BUFFER); return (MHD_NO); } memcpy(con_info->answerstring + con_info->progress, upload_data, *upload_data_size); con_info->progress += *upload_data_size; *upload_data_size = 0; return (MHD_YES); } else if ((char *)con_info->answerstring != NULL) { if (check_auth(connection, core, con_info)) return (MHD_YES); if (!strcmp(method, "POST")) request.method = M_POST; else request.method = M_PUT; request.connection = connection; request.url = url; request.ndata = con_info->progress; request.data = con_info->answerstring; /* * FIXME */ ((char *)request.data)[con_info->progress] = '\0'; if (find_listener(&request, http)) return (MHD_YES); } } if (request.method == M_GET && !strcmp(url, "/")) { if (http->help_page == NULL) http->help_page = make_help(http); assert(http->help_page); return (http_reply(connection, 200, http->help_page)); } return (http_reply(connection, 500, "Failed")); }
int VRT_Vmod_Init(void **hdl, void *ptr, int len, const char *nm, const char *path, const char *file_id, VRT_CTX) { struct vmod *v; const struct vmod_data *d; char buf[256]; void *dlhdl; ASSERT_CLI(); CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); AN(ctx->cli); dlhdl = dlopen(path, RTLD_NOW | RTLD_LOCAL); if (dlhdl == NULL) { VCLI_Out(ctx->cli, "Loading VMOD %s from %s:\n", nm, path); VCLI_Out(ctx->cli, "dlopen() failed: %s\n", dlerror()); VCLI_Out(ctx->cli, "Check child process permissions.\n"); return (1); } VTAILQ_FOREACH(v, &vmods, list) if (v->hdl == dlhdl) break; if (v == NULL) { ALLOC_OBJ(v, VMOD_MAGIC); AN(v); v->hdl = dlhdl; bprintf(buf, "Vmod_%s_Data", nm); d = dlsym(v->hdl, buf); if (d == NULL || d->file_id == NULL || strcmp(d->file_id, file_id)) { VCLI_Out(ctx->cli, "Loading VMOD %s from %s:\n", nm, path); VCLI_Out(ctx->cli, "This is no longer the same file seen by" " the VCL-compiler.\n"); (void)dlclose(v->hdl); FREE_OBJ(v); return (1); } if (d->vrt_major != VRT_MAJOR_VERSION || d->vrt_minor > VRT_MINOR_VERSION || d->name == NULL || strcmp(d->name, nm) || d->func == NULL || d->func_len <= 0 || d->proto == NULL || d->spec == NULL || d->abi == NULL) { VCLI_Out(ctx->cli, "Loading VMOD %s from %s:\n", nm, path); VCLI_Out(ctx->cli, "VMOD data is mangled.\n"); (void)dlclose(v->hdl); FREE_OBJ(v); return (1); } v->funclen = d->func_len; v->funcs = d->func; REPLACE(v->nm, nm); REPLACE(v->path, path); VSC_C_main->vmods++; VTAILQ_INSERT_TAIL(&vmods, v, list); } assert(len == v->funclen); memcpy(ptr, v->funcs, v->funclen); v->ref++; *hdl = v; return (0); }
ME_UndoItem *ME_AddUndoItem(ME_TextEditor *editor, ME_DIType type, const ME_DisplayItem *pdi) { if (editor->nUndoMode == umIgnore) return NULL; else if (editor->nUndoLimit == 0) return NULL; else { ME_DisplayItem *pItem = (ME_DisplayItem *)ALLOC_OBJ(ME_UndoItem); ((ME_UndoItem *)pItem)->nCR = ((ME_UndoItem *)pItem)->nLF = -1; switch(type) { case diUndoPotentialEndTransaction: /* only should be added for manually typed chars, not undos or redos */ assert(editor->nUndoMode == umAddToUndo); /* intentional fall-through to next case */ case diUndoEndTransaction: break; case diUndoSetParagraphFormat: assert(pdi); pItem->member.para = pdi->member.para; pItem->member.para.pFmt = ALLOC_OBJ(PARAFORMAT2); *pItem->member.para.pFmt = *pdi->member.para.pFmt; break; case diUndoInsertRun: assert(pdi); pItem->member.run = pdi->member.run; pItem->member.run.strText = ME_StrDup(pItem->member.run.strText); ME_AddRefStyle(pItem->member.run.style); if (pdi->member.run.ole_obj) { pItem->member.run.ole_obj = ALLOC_OBJ(*pItem->member.run.ole_obj); ME_CopyReObject(pItem->member.run.ole_obj, pdi->member.run.ole_obj); } else pItem->member.run.ole_obj = NULL; break; case diUndoSetCharFormat: break; case diUndoDeleteRun: case diUndoJoinParagraphs: break; case diUndoSplitParagraph: { ME_DisplayItem *prev_para = pdi->member.para.prev_para; assert(pdi->member.para.pFmt->cbSize == sizeof(PARAFORMAT2)); pItem->member.para.pFmt = ALLOC_OBJ(PARAFORMAT2); pItem->member.para.pFmt->cbSize = sizeof(PARAFORMAT2); pItem->member.para.pFmt->dwMask = 0; *pItem->member.para.pFmt = *pdi->member.para.pFmt; pItem->member.para.border = pdi->member.para.border; pItem->member.para.nFlags = prev_para->member.para.nFlags & ~MEPF_CELL; pItem->member.para.pCell = NULL; break; } default: assert(0 == "AddUndoItem, unsupported item type"); return NULL; } pItem->type = type; pItem->prev = NULL; if (editor->nUndoMode == umAddToUndo || editor->nUndoMode == umAddBackToUndo) { if (editor->pUndoStack && editor->pUndoStack->type == diUndoPotentialEndTransaction) { editor->pUndoStack->type = diUndoEndTransaction; } if (editor->nUndoMode == umAddToUndo) TRACE("Pushing id=%s to undo stack, deleting redo stack\n", ME_GetDITypeName(type)); else TRACE("Pushing id=%s to undo stack\n", ME_GetDITypeName(type)); pItem->next = editor->pUndoStack; if (type == diUndoEndTransaction || type == diUndoPotentialEndTransaction) editor->nUndoStackSize++; if (editor->pUndoStack) editor->pUndoStack->prev = pItem; else editor->pUndoStackBottom = pItem; editor->pUndoStack = pItem; if (editor->nUndoStackSize > editor->nUndoLimit) { /* remove oldest undo from stack */ ME_DisplayItem *p = editor->pUndoStackBottom; while (p->type !=diUndoEndTransaction) p = p->prev; /*find new stack bottom */ editor->pUndoStackBottom = p->prev; editor->pUndoStackBottom->next = NULL; do { ME_DisplayItem *pp = p->next; ME_DestroyDisplayItem(p); p = pp; } while (p); editor->nUndoStackSize--; } /* any new operation (not redo) clears the redo stack */ if (editor->nUndoMode == umAddToUndo) { ME_DisplayItem *p = editor->pRedoStack; while(p) { ME_DisplayItem *pp = p->next; ME_DestroyDisplayItem(p); p = pp; } editor->pRedoStack = NULL; } } else if (editor->nUndoMode == umAddToRedo) { TRACE("Pushing id=%s to redo stack\n", ME_GetDITypeName(type)); pItem->next = editor->pRedoStack; if (editor->pRedoStack) editor->pRedoStack->prev = pItem; editor->pRedoStack = pItem; } else assert(0); return (ME_UndoItem *)pItem; } }
void smp_mgt_init(struct stevedore *parent, int ac, char * const *av) { struct smp_sc *sc; struct smp_sign sgn; void *target; int i; ASSERT_MGT(); AZ(av[ac]); /* Necessary alignment. See also smp_object::__filler__ */ assert(sizeof(struct smp_object) % 8 == 0); #define SIZOF(foo) fprintf(stderr, \ "sizeof(%s) = %zu = 0x%zx\n", #foo, sizeof(foo), sizeof(foo)); SIZOF(struct smp_ident); SIZOF(struct smp_sign); SIZOF(struct smp_segptr); SIZOF(struct smp_object); #undef SIZOF /* See comments in storage_persistent.h */ assert(sizeof(struct smp_ident) == SMP_IDENT_SIZE); /* Allocate softc */ ALLOC_OBJ(sc, SMP_SC_MAGIC); XXXAN(sc); sc->parent = parent; sc->fd = -1; VTAILQ_INIT(&sc->segments); /* Argument processing */ if (ac != 2) ARGV_ERR("(-spersistent) wrong number of arguments\n"); i = STV_GetFile(av[0], &sc->fd, &sc->filename, "-spersistent"); if (i == 2) ARGV_ERR("(-spersistent) need filename (not directory)\n"); sc->align = sizeof(void*) * 2; sc->granularity = getpagesize(); sc->mediasize = STV_FileSize(sc->fd, av[1], &sc->granularity, "-spersistent"); AZ(ftruncate(sc->fd, sc->mediasize)); /* Try to determine correct mmap address */ i = read(sc->fd, &sgn, sizeof sgn); assert(i == sizeof sgn); if (!strcmp(sgn.ident, "SILO")) target = (void*)(uintptr_t)sgn.mapped; else target = NULL; sc->base = (void*)mmap(target, sc->mediasize, PROT_READ|PROT_WRITE, MAP_NOCORE | MAP_NOSYNC | MAP_SHARED, sc->fd, 0); if (sc->base == MAP_FAILED) ARGV_ERR("(-spersistent) failed to mmap (%s)\n", strerror(errno)); smp_def_sign(sc, &sc->idn, 0, "SILO"); sc->ident = SIGN_DATA(&sc->idn); i = smp_valid_silo(sc); if (i) { printf("Warning SILO (%s) not reloaded (reason=%d)\n", sc->filename, i); smp_newsilo(sc); } AZ(smp_valid_silo(sc)); smp_metrics(sc); parent->priv = sc; /* XXX: only for sendfile I guess... */ mgt_child_inherit(sc->fd, "storage_persistent"); }
int VRT_Vmod_Init(void **hdl, void *ptr, int len, const char *nm, const char *path, struct cli *cli) { struct vmod *v; void *x, *y, *z, *w; char buf[256]; void *dlhdl; ASSERT_CLI(); dlhdl = dlopen(path, RTLD_NOW | RTLD_LOCAL); if (dlhdl == NULL) { VCLI_Out(cli, "Loading VMOD %s from %s:\n", nm, path); VCLI_Out(cli, "dlopen() failed: %s\n", dlerror()); VCLI_Out(cli, "Check child process permissions.\n"); return (1); } VTAILQ_FOREACH(v, &vmods, list) if (v->hdl == dlhdl) break; if (v == NULL) { ALLOC_OBJ(v, VMOD_MAGIC); AN(v); v->hdl = dlhdl; bprintf(buf, "Vmod_%s_Name", nm); x = dlsym(v->hdl, buf); bprintf(buf, "Vmod_%s_Len", nm); y = dlsym(v->hdl, buf); bprintf(buf, "Vmod_%s_Func", nm); z = dlsym(v->hdl, buf); bprintf(buf, "Vmod_%s_ABI", nm); w = dlsym(v->hdl, buf); if (x == NULL || y == NULL || z == NULL || w == NULL) { VCLI_Out(cli, "Loading VMOD %s from %s:\n", nm, path); VCLI_Out(cli, "VMOD symbols not found\n"); VCLI_Out(cli, "Check relative pathnames.\n"); (void)dlclose(v->hdl); FREE_OBJ(v); return (1); } AN(x); AN(y); AN(z); AN(w); if (strcmp(x, nm)) { VCLI_Out(cli, "Loading VMOD %s from %s:\n", nm, path); VCLI_Out(cli, "File contain wrong VMOD (\"%s\")\n", (char *) x); VCLI_Out(cli, "Check relative pathnames ?.\n"); (void)dlclose(v->hdl); FREE_OBJ(v); return (1); } if (strcmp(w, VMOD_ABI_Version)) { VCLI_Out(cli, "Loading VMOD %s from %s:\n", nm, path); VCLI_Out(cli, "VMOD ABI (%s)", (char*)w); VCLI_Out(cli, " incompatible with varnish ABI (%s)\n", VMOD_ABI_Version); (void)dlclose(v->hdl); FREE_OBJ(v); return (1); } // XXX: Check w for ABI version compatibility v->funclen = *(const int *)y; v->funcs = z; REPLACE(v->nm, nm); REPLACE(v->path, path); VSC_C_main->vmods++; VTAILQ_INSERT_TAIL(&vmods, v, list); } assert(len == v->funclen); memcpy(ptr, v->funcs, v->funclen); v->ref++; *hdl = v; return (0); }
/* join tp with tp->member.para.next_para, keeping tp's style; this * is consistent with the original */ ME_DisplayItem *ME_JoinParagraphs(ME_TextEditor *editor, ME_DisplayItem *tp, BOOL keepFirstParaFormat) { ME_DisplayItem *pNext, *pFirstRunInNext, *pRun, *pTmp; int i, shift; ME_UndoItem *undo = NULL; int end_len; CHARFORMAT2W fmt; ME_Cursor startCur, endCur; assert(tp->type == diParagraph); assert(tp->member.para.next_para); assert(tp->member.para.next_para->type == diParagraph); pNext = tp->member.para.next_para; /* Need to locate end-of-paragraph run here, in order to know end_len */ pRun = ME_FindItemBack(pNext, diRunOrParagraph); assert(pRun); assert(pRun->type == diRun); assert(pRun->member.run.nFlags & MERF_ENDPARA); end_len = pRun->member.run.strText->nLen; /* null char format operation to store the original char format for the ENDPARA run */ ME_InitCharFormat2W(&fmt); endCur.pPara = pNext; endCur.pRun = ME_FindItemFwd(pNext, diRun); endCur.nOffset = 0; startCur = endCur; ME_PrevRun(&startCur.pPara, &startCur.pRun); ME_SetCharFormat(editor, &startCur, &endCur, &fmt); undo = ME_AddUndoItem(editor, diUndoSplitParagraph, pNext); if (undo) { undo->nStart = pNext->member.para.nCharOfs - end_len; undo->eol_str = pRun->member.run.strText; pRun->member.run.strText = NULL; /* Avoid freeing the string */ } if (!keepFirstParaFormat) { ME_AddUndoItem(editor, diUndoSetParagraphFormat, tp); *tp->member.para.pFmt = *pNext->member.para.pFmt; tp->member.para.border = pNext->member.para.border; } if (!editor->bEmulateVersion10) { /* v4.1 */ /* Table cell/row properties are always moved over from the removed para. */ tp->member.para.nFlags = pNext->member.para.nFlags; tp->member.para.pCell = pNext->member.para.pCell; /* Remove cell boundary if it is between the end paragraph run and the next * paragraph display item. */ pTmp = pRun->next; while (pTmp != pNext) { if (pTmp->type == diCell) { ME_Cell *pCell = &pTmp->member.cell; if (undo) { assert(!(undo->di.member.para.nFlags & MEPF_ROWEND)); if (!(undo->di.member.para.nFlags & MEPF_ROWSTART)) undo->di.member.para.nFlags |= MEPF_CELL; undo->di.member.para.pCell = ALLOC_OBJ(ME_DisplayItem); *undo->di.member.para.pCell = *pTmp; undo->di.member.para.pCell->next = NULL; undo->di.member.para.pCell->prev = NULL; undo->di.member.para.pCell->member.cell.next_cell = NULL; undo->di.member.para.pCell->member.cell.prev_cell = NULL; } ME_Remove(pTmp); if (pCell->prev_cell) pCell->prev_cell->member.cell.next_cell = pCell->next_cell; if (pCell->next_cell) pCell->next_cell->member.cell.prev_cell = pCell->prev_cell; ME_DestroyDisplayItem(pTmp); break; } pTmp = pTmp->next; } } shift = pNext->member.para.nCharOfs - tp->member.para.nCharOfs - end_len; pFirstRunInNext = ME_FindItemFwd(pNext, diRunOrParagraph); assert(pFirstRunInNext->type == diRun); /* Update selection cursors so they don't point to the removed end * paragraph run, and point to the correct paragraph. */ for (i=0; i < editor->nCursors; i++) { if (editor->pCursors[i].pRun == pRun) { editor->pCursors[i].pRun = pFirstRunInNext; editor->pCursors[i].nOffset = 0; } else if (editor->pCursors[i].pPara == pNext) { editor->pCursors[i].pPara = tp; } } pTmp = pNext; do { pTmp = ME_FindItemFwd(pTmp, diRunOrParagraphOrEnd); if (pTmp->type != diRun) break; TRACE("shifting \"%s\" by %d (previous %d)\n", debugstr_w(pTmp->member.run.strText->szData), shift, pTmp->member.run.nCharOfs); pTmp->member.run.nCharOfs += shift; } while(1); ME_Remove(pRun); ME_DestroyDisplayItem(pRun); if (editor->pLastSelStartPara == pNext) editor->pLastSelStartPara = tp; if (editor->pLastSelEndPara == pNext) editor->pLastSelEndPara = tp; tp->member.para.next_para = pNext->member.para.next_para; pNext->member.para.next_para->member.para.prev_para = tp; ME_Remove(pNext); ME_DestroyDisplayItem(pNext); ME_PropagateCharOffset(tp->member.para.next_para, -end_len); ME_CheckCharOffsets(editor); editor->nParagraphs--; tp->member.para.nFlags |= MEPF_REWRAP; return tp; }
const char * BAN_Commit(struct ban_proto *bp) { struct ban *b, *bi; ssize_t ln; double t0; CHECK_OBJ_NOTNULL(bp, BAN_PROTO_MAGIC); AN(bp->vsb); if (ban_shutdown) return (ban_error(bp, "Shutting down")); AZ(VSB_finish(bp->vsb)); ln = VSB_len(bp->vsb); assert(ln >= 0); ALLOC_OBJ(b, BAN_MAGIC); if (b == NULL) return (ban_error(bp, ban_build_err_no_mem)); VTAILQ_INIT(&b->objcore); b->spec = malloc(ln + BANS_HEAD_LEN); if (b->spec == NULL) { free(b); return (ban_error(bp, ban_build_err_no_mem)); } b->flags = bp->flags; memset(b->spec, 0, BANS_HEAD_LEN); t0 = VTIM_real(); memcpy(b->spec + BANS_TIMESTAMP, &t0, sizeof t0); b->spec[BANS_FLAGS] = b->flags & 0xff; memcpy(b->spec + BANS_HEAD_LEN, VSB_data(bp->vsb), ln); ln += BANS_HEAD_LEN; vbe32enc(b->spec + BANS_LENGTH, ln); Lck_Lock(&ban_mtx); if (ban_shutdown) { /* We could have raced a shutdown */ Lck_Unlock(&ban_mtx); BAN_Free(b); return (ban_error(bp, "Shutting down")); } bi = VTAILQ_FIRST(&ban_head); VTAILQ_INSERT_HEAD(&ban_head, b, list); ban_start = b; VSC_C_main->bans++; VSC_C_main->bans_added++; VSC_C_main->bans_persisted_bytes += ln; if (b->flags & BANS_FLAG_OBJ) VSC_C_main->bans_obj++; if (b->flags & BANS_FLAG_REQ) VSC_C_main->bans_req++; if (bi != NULL) ban_info_new(b->spec, ln); /* Notify stevedores */ if (cache_param->ban_dups) { /* Hunt down duplicates, and mark them as completed */ for (bi = VTAILQ_NEXT(b, list); bi != NULL; bi = VTAILQ_NEXT(bi, list)) { if (!(bi->flags & BANS_FLAG_COMPLETED) && ban_equal(b->spec, bi->spec)) { ban_mark_completed(bi); VSC_C_main->bans_dups++; } } } if (!(b->flags & BANS_FLAG_REQ)) ban_kick_lurker(); Lck_Unlock(&ban_mtx); BAN_Abandon(bp); return (NULL); }
vmod_event(VRT_CTX, struct vmod_priv *priv, enum vcl_event_e ev) { struct vmod_disco *vd; CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); switch(ev) { case VCL_EVENT_LOAD: AZ(pthread_mutex_lock(&global_mtx)); if (global_load_count == 0) { ALLOC_OBJ(vd, VMOD_DISCO_MAGIC); AN(vd); priv->len = sizeof(*vd); priv->free = free_func; VTAILQ_INIT(&vd->dirs); update_rwlock_new(&vd->mtx); AN(vd->mtx); default_mod = vd; } else { vd = priv->priv; CHECK_OBJ_ORNULL(vd, VMOD_DISCO_MAGIC); if (!vd) { struct vmod_disco *dvd = default_mod ? default_mod : warmed_mod; if (dvd) { update_rwlock_wrlock(dvd->mtx); } ALLOC_OBJ(vd, VMOD_DISCO_MAGIC); AN(vd); priv->len = sizeof(*vd); priv->free = free_func; VTAILQ_INIT(&vd->dirs); update_rwlock_new(&vd->mtx); AN(vd->mtx); default_mod = vd; if (dvd) { update_rwlock_unlock(dvd->mtx, NULL); } } } CHECK_OBJ_NOTNULL(vd, VMOD_DISCO_MAGIC); priv->priv = vd; global_load_count++; AZ(pthread_mutex_unlock(&global_mtx)); break; case VCL_EVENT_DISCARD: AZ(pthread_mutex_lock(&global_mtx)); AN(global_load_count); global_load_count--; AZ(pthread_mutex_unlock(&global_mtx)); break; case VCL_EVENT_WARM: AZ(pthread_mutex_lock(&global_mtx)); vd = priv->priv; CHECK_OBJ_NOTNULL(vd, VMOD_DISCO_MAGIC); AZ(vd->wrk); update_rwlock_wrlock(vd->mtx); if (default_mod == NULL && warmed_mod != NULL) default_mod = warmed_mod; warmed_mod = vd; vmod_disco_bgthread_start(&vd->wrk, vd, 10); update_rwlock_unlock(vd->mtx, NULL); AZ(pthread_mutex_unlock(&global_mtx)); break; case VCL_EVENT_COLD: AZ(pthread_mutex_lock(&global_mtx)); CAST_OBJ_NOTNULL(vd, priv->priv, VMOD_DISCO_MAGIC); CHECK_OBJ_NOTNULL(vd->wrk, VMOD_DISCO_BGTHREAD_MAGIC); vmod_disco_bgthread_delete(&vd->wrk); AZ(vd->wrk); if (vd == default_mod && warmed_mod != NULL) default_mod = warmed_mod; AZ(pthread_mutex_unlock(&global_mtx)); break; case VCL_EVENT_USE: AZ(pthread_mutex_lock(&global_mtx)); CAST_OBJ_NOTNULL(vd, priv->priv, VMOD_DISCO_MAGIC); if (vd != default_mod) default_mod = vd; AZ(pthread_mutex_unlock(&global_mtx)); default: break; } return 0; }
static void vxp_expr_lhs(struct vxp *vxp, struct vex_lhs **plhs) { char *p; int i; AN(plhs); AZ(*plhs); ALLOC_OBJ(*plhs, VEX_LHS_MAGIC); AN(*plhs); (*plhs)->tags = vbit_init(SLT__MAX); (*plhs)->level = -1; if (vxp->t->tok == '{') { /* Transaction level limits */ vxp_NextToken(vxp); if (vxp->t->tok != VAL) { VSB_printf(vxp->sb, "Expected integer got '%.*s' ", PF(vxp->t)); vxp_ErrWhere(vxp, vxp->t, -1); return; } (*plhs)->level = (int)strtol(vxp->t->dec, &p, 0); if ((*plhs)->level < 0) { VSB_printf(vxp->sb, "Expected positive integer "); vxp_ErrWhere(vxp, vxp->t, -1); return; } if (*p == '-') { (*plhs)->level_pm = -1; p++; } else if (*p == '+') { (*plhs)->level_pm = 1; p++; } if (*p) { VSB_printf(vxp->sb, "Syntax error in level limit "); vxp_ErrWhere(vxp, vxp->t, -1); return; } vxp_NextToken(vxp); ExpectErr(vxp, '}'); vxp_NextToken(vxp); } while (1) { /* The tags this expression applies to */ if (vxp->t->tok != VAL) { VSB_printf(vxp->sb, "Expected VSL tag name got '%.*s' ", PF(vxp->t)); vxp_ErrWhere(vxp, vxp->t, -1); return; } i = VSL_Glob2Tags(vxp->t->dec, -1, vsl_vbm_bitset, (*plhs)->tags); if (i == -1) { VSB_printf(vxp->sb, "Tag name matches zero tags "); vxp_ErrWhere(vxp, vxp->t, -1); return; } if (i == -2) { VSB_printf(vxp->sb, "Tag name is ambiguous "); vxp_ErrWhere(vxp, vxp->t, -1); return; } if (i == -3) { VSB_printf(vxp->sb, "Syntax error in tag name "); vxp_ErrWhere(vxp, vxp->t, -1); return; } assert(i > 0); vxp_NextToken(vxp); if (vxp->t->tok != ',') break; vxp_NextToken(vxp); } if (vxp->t->tok == ':') { /* Record prefix */ vxp_NextToken(vxp); if (vxp->t->tok != VAL) { VSB_printf(vxp->sb, "Expected string got '%.*s' ", PF(vxp->t)); vxp_ErrWhere(vxp, vxp->t, -1); return; } AN(vxp->t->dec); (*plhs)->prefix = strdup(vxp->t->dec); AN((*plhs)->prefix); (*plhs)->prefixlen = strlen((*plhs)->prefix); vxp_NextToken(vxp); } if (vxp->t->tok == '[') { /* LHS field [] */ vxp_NextToken(vxp); if (vxp->t->tok != VAL) { VSB_printf(vxp->sb, "Expected integer got '%.*s' ", PF(vxp->t)); vxp_ErrWhere(vxp, vxp->t, -1); return; } (*plhs)->field = (int)strtol(vxp->t->dec, &p, 0); if (*p || (*plhs)->field <= 0) { VSB_printf(vxp->sb, "Expected positive integer "); vxp_ErrWhere(vxp, vxp->t, -1); return; } vxp_NextToken(vxp); ExpectErr(vxp, ']'); vxp_NextToken(vxp); } }
int VRT_Vmod_Init(void **hdl, void *ptr, int len, const char *nm, const char *path, struct cli *cli) { struct vmod *v; void *x, *y, *z, *w; ASSERT_CLI(); VTAILQ_FOREACH(v, &vmods, list) if (!strcmp(v->nm, nm)) // Also path, len ? break; if (v == NULL) { ALLOC_OBJ(v, VMOD_MAGIC); AN(v); v->hdl = dlopen(path, RTLD_NOW | RTLD_LOCAL); if (v->hdl == NULL) { VCLI_Out(cli, "Loading VMOD %s from %s:\n", nm, path); VCLI_Out(cli, "dlopen() failed: %s\n", dlerror()); VCLI_Out(cli, "Check child process permissions.\n"); FREE_OBJ(v); return (1); } x = dlsym(v->hdl, "Vmod_Name"); y = dlsym(v->hdl, "Vmod_Len"); z = dlsym(v->hdl, "Vmod_Func"); w = dlsym(v->hdl, "Vmod_Id"); if (x == NULL || y == NULL || z == NULL || w == NULL) { VCLI_Out(cli, "Loading VMOD %s from %s:\n", nm, path); VCLI_Out(cli, "VMOD symbols not found\n"); VCLI_Out(cli, "Check relative pathnames.\n"); (void)dlclose(v->hdl); FREE_OBJ(v); return (1); } AN(x); AN(y); AN(z); AN(w); if (strcmp(x, nm)) { VCLI_Out(cli, "Loading VMOD %s from %s:\n", nm, path); VCLI_Out(cli, "File contain wrong VMOD (\"%s\")\n", x); VCLI_Out(cli, "Check relative pathnames ?.\n"); (void)dlclose(v->hdl); FREE_OBJ(v); return (1); } v->funclen = *(const int *)y; v->funcs = z; REPLACE(v->nm, nm); REPLACE(v->path, path); VSC_C_main->vmods++; VTAILQ_INSERT_TAIL(&vmods, v, list); v->idptr = w; } assert(len == v->funclen); memcpy(ptr, v->funcs, v->funclen); v->ref++; *hdl = v; return (0); }
static struct storage * sma_alloc(struct stevedore *st, size_t size) { struct sma_sc *sma_sc; struct sma *sma = NULL; void *p; CAST_OBJ_NOTNULL(sma_sc, st->priv, SMA_SC_MAGIC); Lck_Lock(&sma_sc->sma_mtx); sma_sc->stats->c_req++; if (sma_sc->sma_alloc + size > sma_sc->sma_max) { sma_sc->stats->c_fail += size; size = 0; } else { sma_sc->sma_alloc += size; sma_sc->stats->c_bytes += size; sma_sc->stats->g_alloc++; sma_sc->stats->g_bytes += size; if (sma_sc->sma_max != SIZE_MAX) sma_sc->stats->g_space -= size; } Lck_Unlock(&sma_sc->sma_mtx); if (size == 0) return (NULL); /* * Do not collaps the sma allocation with sma->s.ptr: it is not * a good idea. Not only would it make ->trim impossible, * performance-wise it would be a catastropy with chunksized * allocations growing another full page, just to accomodate the sma. */ p = malloc(size); if (p != NULL) { ALLOC_OBJ(sma, SMA_MAGIC); if (sma != NULL) sma->s.ptr = p; else free(p); } if (sma == NULL) { Lck_Lock(&sma_sc->sma_mtx); /* * XXX: Not nice to have counters go backwards, but we do * XXX: Not want to pick up the lock twice just for stats. */ sma_sc->stats->c_fail++; sma_sc->stats->c_bytes -= size; sma_sc->stats->g_alloc--; sma_sc->stats->g_bytes -= size; if (sma_sc->sma_max != SIZE_MAX) sma_sc->stats->g_space += size; Lck_Unlock(&sma_sc->sma_mtx); return (NULL); } sma->sc = sma_sc; sma->sz = size; sma->s.priv = sma; sma->s.len = 0; sma->s.space = size; #ifdef SENDFILE_WORKS sma->s.fd = -1; #endif sma->s.stevedore = st; sma->s.magic = STORAGE_MAGIC; return (&sma->s); }
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); }
VDP_ESI(struct req *req, enum vdp_action act, void **priv, const void *ptr, ssize_t len) { uint8_t *q, *r; ssize_t l = 0; uint32_t icrc = 0; uint8_t tailbuf[8 + 5]; const uint8_t *pp; struct ecx *ecx, *pecx; int retval = 0; if (act == VDP_INIT) { AZ(*priv); ALLOC_OBJ(ecx, ECX_MAGIC); AN(ecx); ecx->preq = req; *priv = ecx; return (0); } CAST_OBJ_NOTNULL(ecx, *priv, ECX_MAGIC); if (act == VDP_FINI) { FREE_OBJ(ecx); *priv = NULL; return (0); } pp = ptr; while (1) { switch (ecx->state) { case 0: ecx->p = ObjGetattr(req->wrk, req->objcore, OA_ESIDATA, &l); AN(ecx->p); assert(l > 0); ecx->e = ecx->p + l; if (*ecx->p == VEC_GZ) { ecx->isgzip = 1; ecx->p++; } if (req->esi_level == 0) { /* * Only the top level document gets to * decide this. */ if (ecx->isgzip) { assert(sizeof gzip_hdr == 10); /* Send out the gzip header */ retval = VDP_bytes(req, VDP_NULL, gzip_hdr, 10); ecx->l_crc = 0; ecx->crc = crc32(0L, Z_NULL, 0); } } ecx->state = 1; break; case 1: if (ecx->p >= ecx->e) { ecx->state = 2; break; } switch (*ecx->p) { case VEC_V1: case VEC_V2: case VEC_V8: ecx->l = ved_decode_len(req, &ecx->p); if (ecx->l < 0) return (-1); if (ecx->isgzip) { assert(*ecx->p == VEC_C1 || *ecx->p == VEC_C2 || *ecx->p == VEC_C8); l = ved_decode_len(req, &ecx->p); if (l < 0) return (-1); icrc = vbe32dec(ecx->p); ecx->p += 4; if (ecx->isgzip) { ecx->crc = crc32_combine( ecx->crc, icrc, l); ecx->l_crc += l; } } ecx->state = 3; break; case VEC_S1: case VEC_S2: case VEC_S8: ecx->l = ved_decode_len(req, &ecx->p); if (ecx->l < 0) return (-1); Debug("SKIP1(%d)\n", (int)ecx->l); ecx->state = 4; break; case VEC_INCL: ecx->p++; q = (void*)strchr((const char*)ecx->p, '\0'); AN(q); q++; r = (void*)strchr((const char*)q, '\0'); AN(r); if (VDP_bytes(req, VDP_FLUSH, NULL, 0)) { ecx->p = ecx->e; break; } Debug("INCL [%s][%s] BEGIN\n", q, ecx->p); ved_include(req, (const char*)q, (const char*)ecx->p, ecx); Debug("INCL [%s][%s] END\n", q, ecx->p); ecx->p = r + 1; break; default: VSLb(req->vsl, SLT_Error, "ESI corruption line %d 0x%02x [%s]\n", __LINE__, *ecx->p, ecx->p); WRONG("ESI-codes: Illegal code"); } break; case 2: if (ecx->isgzip && req->esi_level == 0) { /* * We are bytealigned here, so simply emit * a gzip literal block with finish bit set. */ tailbuf[0] = 0x01; tailbuf[1] = 0x00; tailbuf[2] = 0x00; tailbuf[3] = 0xff; tailbuf[4] = 0xff; /* Emit CRC32 */ vle32enc(tailbuf + 5, ecx->crc); /* MOD(2^32) length */ vle32enc(tailbuf + 9, ecx->l_crc); (void)VDP_bytes(req, VDP_NULL, tailbuf, 13); } if (req->transport->deliver == VED_Deliver) { CAST_OBJ_NOTNULL(pecx, req->transport_priv, ECX_MAGIC); pecx->crc = crc32_combine(pecx->crc, ecx->crc, ecx->l_crc); pecx->l_crc += ecx->l_crc; } retval = VDP_bytes(req, VDP_FLUSH, NULL, 0); ecx->state = 99; return (retval); case 3: case 4: /* * There is no guarantee that the 'l' bytes are all * in the same storage segment, so loop over storage * until we have processed them all. */ if (ecx->l <= len) { if (ecx->state == 3) retval = VDP_bytes(req, act, pp, ecx->l); len -= ecx->l; pp += ecx->l; ecx->state = 1; break; } if (ecx->state == 3 && len > 0) retval = VDP_bytes(req, act, pp, len); ecx->l -= len; return (retval); case 99: /* * VEP does not account for the PAD+CRC+LEN * so we can see up to approx 15 bytes here. */ return (retval); default: WRONG("FOO"); break; } if (retval) return (retval); } }
ME_UndoItem *ME_AddUndoItem(ME_TextEditor *editor, ME_DIType type, ME_DisplayItem *pdi) { if (editor->nUndoMode == umIgnore) return NULL; else if (editor->nUndoLimit == 0) return NULL; else { ME_DisplayItem *pItem = (ME_DisplayItem *)ALLOC_OBJ(ME_UndoItem); switch(type) { case diUndoEndTransaction: break; case diUndoSetParagraphFormat: assert(pdi); CopyMemory(&pItem->member.para, &pdi->member.para, sizeof(ME_Paragraph)); pItem->member.para.pFmt = ALLOC_OBJ(PARAFORMAT2); CopyMemory(pItem->member.para.pFmt, pdi->member.para.pFmt, sizeof(PARAFORMAT2)); break; case diUndoInsertRun: assert(pdi); CopyMemory(&pItem->member.run, &pdi->member.run, sizeof(ME_Run)); pItem->member.run.strText = ME_StrDup(pItem->member.run.strText); ME_AddRefStyle(pItem->member.run.style); break; case diUndoSetCharFormat: case diUndoSetDefaultCharFormat: break; case diUndoDeleteRun: case diUndoJoinParagraphs: break; case diUndoSplitParagraph: pItem->member.para.pFmt = ALLOC_OBJ(PARAFORMAT2); pItem->member.para.pFmt->cbSize = sizeof(PARAFORMAT2); pItem->member.para.pFmt->dwMask = 0; break; default: assert(0 == "AddUndoItem, unsupported item type"); return NULL; } pItem->type = type; pItem->prev = NULL; if (editor->nUndoMode == umAddToUndo || editor->nUndoMode == umAddBackToUndo) { if (editor->nUndoMode == umAddToUndo) TRACE("Pushing id=%s to undo stack, deleting redo stack\n", ME_GetDITypeName(type)); else TRACE("Pushing id=%s to undo stack\n", ME_GetDITypeName(type)); pItem->next = editor->pUndoStack; if (type == diUndoEndTransaction) editor->nUndoStackSize++; if (editor->pUndoStack) editor->pUndoStack->prev = pItem; else editor->pUndoStackBottom = pItem; editor->pUndoStack = pItem; if (editor->nUndoStackSize > editor->nUndoLimit) { /* remove oldest undo from stack */ ME_DisplayItem *p = editor->pUndoStackBottom; while (p->type !=diUndoEndTransaction) p = p->prev; /*find new stack bottom */ editor->pUndoStackBottom = p->prev; editor->pUndoStackBottom->next = NULL; do { ME_DisplayItem *pp = p->next; ME_DestroyDisplayItem(p); p = pp; } while (p); editor->nUndoStackSize--; } /* any new operation (not redo) clears the redo stack */ if (editor->nUndoMode == umAddToUndo) { ME_DisplayItem *p = editor->pRedoStack; while(p) { ME_DisplayItem *pp = p->next; ME_DestroyDisplayItem(p); p = pp; } editor->pRedoStack = NULL; } } else if (editor->nUndoMode == umAddToRedo) { TRACE("Pushing id=%s to redo stack\n", ME_GetDITypeName(type)); pItem->next = editor->pRedoStack; if (editor->pRedoStack) editor->pRedoStack->prev = pItem; editor->pRedoStack = pItem; } else assert(0); return (ME_UndoItem *)pItem; } }