static int answer_articleselect(struct evbuffer *buf, const boardheader_t *bptr, const char *rest_key, select_part_func sfunc, void *ctx) { char path[PATH_MAX]; const char *ck, *filename; int cklen, offset, maxlen = 0; struct stat st; if (!parse_articlepart_key(rest_key, &ck, &cklen, &offset, &maxlen, &filename)) return -1; if (!is_valid_article_filename(filename)) return -1; setbfile(path, bptr->brdname, filename); if (answer_file(buf, path, &st, ck, cklen, offset, maxlen) < 0) return -1; int sel_offset, sel_size; int len = evbuffer_get_length(buf); if (sfunc(evbuffer_pullup(buf, len), len, &sel_offset, &sel_size, ctx) != 0 || evbuffer_slice(buf, sel_offset, sel_size) != 0) return -1; struct evbuffer *meta = evbuffer_new(); evbuffer_add_printf(meta, "%d-%d,%lu,%d,%d\n", (int) st.st_dev, (int) st.st_ino, st.st_size, sel_offset, sel_size); evbuffer_prepend_buffer(buf, meta); evbuffer_free(meta); return 0; }
int select_article(struct evbuffer *buf, select_result_t *result, const select_spec_t *spec) { select_part_func sfunc; switch (spec->type) { case SELECT_TYPE_HEAD: sfunc = select_article_head; break; case SELECT_TYPE_TAIL: sfunc = select_article_tail; break; case SELECT_TYPE_PART: sfunc = select_article_part; break; default: return SELECT_EARG; } struct stat st; int ret; if ((ret = answer_file(buf, spec->filename, &st, spec->cachekey, spec->cachekey_len, spec->offset, spec->maxlen)) < 0) return ret; int sel_offset, sel_size; int len = evbuffer_get_length(buf); const char *data = (const char *) evbuffer_pullup(buf, -1); if (sfunc(data, len, &sel_offset, &sel_size, NULL) != 0 || evbuffer_slice(buf, sel_offset, sel_size) != 0) return SELECT_EUNKNOWN; if (result != NULL) { snprintf(result->cachekey, sizeof(result->cachekey), "%d-%d", (int)st.st_dev, (int)st.st_ino); result->size = st.st_size; result->sel_offset = sel_offset; result->sel_size = sel_size; } return SELECT_OK; }
static void answer_appropriate(struct vmod_fsdirector_file_system *fs) { unsigned available; char *url; char *url_start; char *url_end; size_t url_len; size_t root_len; char *path; struct stat stat_buf; if (strncmp("GET ", fs->htc.ws->s, 4)) { prepare_answer(&fs->htc, 405); prepare_body(&fs->htc); return; } url_start = &fs->htc.ws->s[4]; url_end = strchr(url_start, ' '); url_len = (url_end - url_start) + strlen(fs->root) + 1; url = WS_Alloc(fs->htc.ws, url_len); snprintf(url, url_len, "%s%s", fs->root, url_start); path = url; if (lstat(path, &stat_buf) < 0) { handle_file_error(&fs->htc, errno); return; } answer_file(fs, &stat_buf, path); }