Esempio n. 1
0
char *asn_replace(const char *regex, const char *rep, const char *str, mmatic *mm)
{
	int cv[CVS], cvn, rc, br, offset = 0, len = strlen(str);
	xstr *xs = MMXSTR_CREATE("");
	char *mem = malloc(strlen(rep) + 1), *p, *bs;

	while ((rc = _regex_match(regex, str, len, offset, cv, &cvn)) == 1 && cv[0] >= 0 && cv[1] >= cv[0]) {
		if (cv[0] >= len) break;

		dbg(8, "asn_replace(): matched at %d-%d (rc=%d, offset=%d)\n", cv[0], cv[1], rc, offset);

		/* copy text up to the first match */
		xstr_append_size(xs, str+offset, cv[0]-offset);

		/* replace, handling backreferences */
		strcpy(mem, rep);
		for (bs = p = mem; (bs = strchr(bs, '\\'));) {
			if (!bs[1] || !isdigit(bs[1])) continue;

			/* append everything up to \, position bs on the number */
			*bs++ = '\0';
			xstr_append(xs, p);

			/* position p on the end of the number + 1 */
			for (p = bs; *p && isdigit(*p); p++);

			/* substitute */
			br = atoi(bs);
			if (br++ > 0 && br <= cvn) {
#				define IB (2*br - 2)
#				define IT (2*br - 1)
				dbg(9, "asn_replace(): appending backreference %d between %d and %d\n", br-1, cv[IB], cv[IT]-1);
				xstr_append_size(xs, str + cv[IB], cv[IT] - cv[IB]);
			}
			else {
				dbg(1, "asn_replace(): invalid backreference: %d\n", br-1);
			}

			bs = p;
		}

		/* in no backreferences case, this appends the whole "rep" string */
		xstr_append(xs, p);

		/* start next match after
		 * XXX: pcreapi(3) manual page says "The first element of a pair is set to the offset of the first character in
		 * a substring, and the second is set to the offset of the first character *after* the end of a substring.", but
		 * does not mention that e.g. a pattern of just /$/m will return cv[1] == cv[0]! */
		offset = cv[1] + (cv[1] == cv[0]);
		if (offset >= len) break;
	}

	if (offset <= len);
		xstr_append(xs, str + offset);  /* may be just "" */

	free(mem);
	return xs->s;
}
Esempio n. 2
0
__USE_LIBASN

int main(int argc, char *argv[])
{
	char buf[BUFSIZ];
	mmatic *mm = mmatic_create();
	xstr *xs = xstr_create("", mm);
	json *js = json_create(mm);

	while (fgets(buf, BUFSIZ, stdin))
		xstr_append(xs, buf);

	ut *parsed = json_parse(js, xstr_string(xs));
	if (ut_ok(parsed))
		printf("%s", json_print(js, parsed));
	else
		printf("%s\n", ut_err(parsed));

	return 0;
}
Esempio n. 3
0
File: read.c Progetto: Travlo26/rpcd
bool read822(struct req *req)
{
	char buf[BUFSIZ];
	xstr *input = xstr_create("", req);

	while (fgets(buf, sizeof(buf), stdin)) {
		if (!buf[0] || buf[0] == '\n') break;
		xstr_append(input, buf);
	}

	/* eof? */
	if (xstr_length(input) == 0) exit(0);

	dbg(8, "parsing %s\n", xstr_string(input));

	req->params = ut_new_thash(
		rfc822_parse(xstr_string(input), req),
		req);

	return common(req, true);
}
Esempio n. 4
0
/** 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);
}
Esempio n. 5
0
File: read.c Progetto: Travlo26/rpcd
static bool readjson_len(struct req *req, int len)
{
	char buf[BUFSIZ];
	xstr *xs = xstr_create("", req);
	json *js;

	if (len < 0) {
		while (fgets(buf, sizeof(buf), stdin)) {
			if (!buf[0] || buf[0] == '\n') break;
			xstr_append(xs, buf);
		}
	} else {
		int r;

		while ((r = fread(buf, 1, MIN(len, sizeof(buf)), stdin))) {
			if (r < 0) {
				dbg(5, "fread() returned %d, len=%d\n", r, len);
				break;
			}

			/* always appends \0 */
			xstr_append_size(xs, buf, r);

			len -= r;
			if (len <= 0)
				break;
		}
	}

	/* eof? */
	if (xstr_length(xs) == 0) exit(0);

	js = json_create(req);
	req->params = json_parse(js, xstr_string(xs));

	return common(req, false);
}
Esempio n. 6
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;
		}
Esempio n. 7
0
File: read.c Progetto: Travlo26/rpcd
bool readhttp(struct req *req)
{
	enum http_type ht;
	char first[256], buf[BUFSIZ], *ct, *cl, *ac, *uri, *auth;
	int len;
	xstr *xs = xstr_create("", req);

	/* read query */
	if (!fgets(first, sizeof(first), stdin) || first[0] == '\n')
		exit(0); /* eof */

	if (strncmp(first, "POST ", 5) == 0) {
		ht = POST;
		uri = first + 5;
	} else if (strncmp(first, "OPTIONS ", 8) == 0) {
		ht = OPTIONS;
		uri = first + 8;
	} else if (strncmp(first, "GET ", 4) == 0 && O.http.htdocs) { /* @1 */
		ht = GET;
		uri = first + 4;
	} else {
		dbg(4, "invalid method: %s\n", first);
		return errmsg("Invalid HTTP method");
	}

	/* read headers */
	while (fgets(buf, sizeof(buf), stdin)) {
		if (!buf[0] || buf[0] == '\n' || buf[0] == '\r') break;
		xstr_append(xs, buf);
	}

	req->http.headers = rfc822_parse(xstr_string(xs), req);

	/* fetch authentication information ASAP */
	auth = thash_get(req->http.headers, "Authorization");
	if (auth && strncmp(auth, "Basic ", 6) == 0) {
		xstr *ad = asn_b64_dec(auth+6, req);
		char *pass = strchr(xstr_string(ad), ':');

		if (pass) {
			*pass++ = '\0';
			req->http.user = xstr_string(ad);
			req->http.pass = pass;
		}
	}

	const char *cc = thash_get(req->http.headers, "Connection");
	if (cc && (streq(cc, "close") || streq(cc, "Close")))
		req->last = true;

	if (ht == OPTIONS)
		return errcode(JSON_RPC_HTTP_OPTIONS);

	/* handle static query, note that htdocs!=NULL checked @1 */
	if (ht == GET) {
		req->http.needauth = true;

		char *space = strchr(uri, ' ');
		if (space) *space = '\0';

		char *params = strchr(uri, '?');
		if (params) *params = '\0';

		if (streq(uri, "/")) {
			uri = "/index.html";
		} else if (strstr(uri, "..")) {
			dbg(4, "invalid uri: '%s'\n", uri);
			return errcode(JSON_RPC_HTTP_NOT_FOUND);
		}

		req->http.uripath = mmatic_printf(req, "%s%s", O.http.htdocs, uri);
		if (asn_isfile(req->http.uripath) > 0) {
			dbg(4, "GET '%s'\n", req->http.uripath);
			return errcode(JSON_RPC_HTTP_GET);
		}

		dbg(4, "not found: '%s'\n", uri);
		req->http.uripath = NULL;
		return errcode(JSON_RPC_HTTP_NOT_FOUND);
	}

	/* = POST - ie. normal RPC call = */

	ct = thash_get(req->http.headers, "Content-Type");
	if (!ct) return errmsg("Content-Type needed");
	if (strncmp(ct, "application/json", 16) != 0)
		return errmsg("Unsupported Content-Type");

	ac = thash_get(req->http.headers, "Accept");
	if (!ac) return errmsg("Accept needed");
	if (!strstr(ac, "application/json") && !strstr(ac, "*/*"))
		return errmsg("Unsupported Accept");

	/* read the query */
	cl = thash_get(req->http.headers, "Content-Length");
	if (!cl) return errmsg("Content-Length needed");

	len = atoi(cl);
	if (len < 0)
		return errmsg("Unsupported Content-Length");

	return readjson_len(req, len);
}