static char *get_query(struct req *req) { const char *orig_query; int i; bool inspace = false; xstr *query; query = xstr_create("", req); orig_query = uth_char(req->params, "query"); i = sizeof SQLER_TAG; if (i > xstr_length(uth_xstr(req->params, "query"))) goto end; /* skip whitechars */ for (; orig_query[i]; i++) if (isalpha(orig_query[i])) break; /* replace all whitechars, newlines, etc with single space */ for (; orig_query[i]; i++) { switch (orig_query[i]) { case ' ': if (inspace) continue; xstr_append_char(query, orig_query[i]); inspace = true; break; case '\t': case '\r': case '\n': break; default: xstr_append_char(query, orig_query[i]); inspace = false; } } end: return xstr_string(query); }
/** Parse config file * @retval 0 success * @retval 1 syntax error * @retval 2 logic error * @retval 3 other error */ static int parse_config(struct mg *mg) { FILE *fp; xstr *xs; char buf[4096], *str; json *js; ut *cfg; /* read file contents, ignoring empty lines and comments */ fp = fopen(mg->options.conf_file, "r"); if (!fp) { dbg(0, "%s: fopen() failed: %s\n", mg->options.conf_file, strerror(errno)); return 3; } xs = xstr_create("{", mg->mmtmp); while (fgets(buf, sizeof buf, fp)) { str = pjf_trim(buf); if (!str || !str[0] || str[0] == '#') continue; xstr_append(xs, str); } xstr_append_char(xs, '}'); fclose(fp); /* parse config file as loose JSON */ js = json_create(mg->mmtmp); json_setopt(js, JSON_LOOSE, 1); cfg = json_parse(js, xstr_string(xs)); if (!ut_ok(cfg)) { dbg(0, "parsing config file failed: %s\n", ut_err(cfg)); return 1; } /* parse config */ return (parse_config_ut(mg, cfg) ? 2 : 0); }
/* this probably needs a wise rewrite */ static char *fill_query(struct req *req, char *orig_query, tlist *data) { int i, qs; enum fq_state { NORMAL, INQ } state = NORMAL; xstr *query; MYSQL *conn; ut *arg, *el, *el2; tlist *list, *list2; bool atleastone, atleastone2; #define iskeyw(a) (sizeof(a) == i - qs && strncmp((a), orig_query + qs + 1, sizeof(a) - 1) == 0) /* XXX: uses list and el */ #define appendlist(utlist) do { \ atleastone = false; \ xstr_append(query, "("); \ list = ut_tlist(utlist); \ TLIST_ITER_LOOP(list, el) { \ if (atleastone) \ xstr_append_char(query, ','); \ xstr_append(query, \ pb("\"%s\"", escape(conn, ut_xstr(el)))); \ atleastone = true; \ } \ xstr_append(query, ")"); \ } while(0); conn = uthp_ptr(req->prv, "sqler", "conn"); query = xstr_create("", req); tlist_reset(data); for (i = 0; orig_query[i]; i++) { switch (state) { case NORMAL: if (orig_query[i] == '?') { qs = i; state = INQ; } else { xstr_append_char(query, orig_query[i]); } break; case INQ: if (orig_query[i] == '?') { if (iskeyw("login")) { xstr_append(query, pb("\"%s\"", uthp_char(req->prv, "sqler", "login"))); } else if (iskeyw("role")) { xstr_append(query, pb("\"%s\"", uthp_char(req->prv, "sqler", "role"))); } else { /* probably needs an arg */ arg = tlist_iter(data); if (arg) { if (iskeyw("int")) { xstr_append(query, pb("%d", ut_int(arg))); } else if (iskeyw("str")) { xstr_append(query, pb("\"%s\"", escape(conn, ut_xstr(arg)))); } else if (iskeyw("dbl")) { xstr_append(query, pb("%g", ut_double(arg))); } else if (iskeyw("login")) { xstr_append(query, pb("\"%s\"", uthp_char(req->prv, "sqler", "login"))); } else if (iskeyw("role")) { xstr_append(query, pb("\"%s\"", uthp_char(req->prv, "sqler", "role"))); } else if (iskeyw("array")) { appendlist(arg); } else if (iskeyw("arrays")) { atleastone2 = false; list2 = ut_tlist(arg); TLIST_ITER_LOOP(list2, el2) { if (atleastone2) xstr_append_char(query, ','); appendlist(el2); atleastone2 = true; } } /* XXX: arg eaten by unrecognizible substitution */ } } state = NORMAL; } else if (orig_query[i] < 'a' || orig_query[i] > 'z') { rollback: while (qs <= i) xstr_append_char(query, orig_query[qs++]); state = NORMAL; } break; }