Esempio n. 1
0
dstr dstr_cat(dstr ds, const char *str) {
	size_t length = str ? strlen(str) : 0;

	return dstr_cat_len(ds, str, length);
}
Esempio n. 2
0
dstr *dstr_split_args(const char *line, int *argc) {
	const char *p = line;
	dstr current = NULL;
	dstr *argv = NULL;

	*argc = 0;
	for (;;) {
		while (*p && isspace(*p))
			++p;
		if (*p) {
			int inq  = 0; /* 1 if in quotes */
			int insq = 0; /* 1 if in single quotes */
			int done = 0;

			if (current == NULL)
				current = dstr_new_len("", 0);
			while (!done) {
				/* FIXME */
				if (inq) {
					if (*p == '\\' && *(p + 1) == 'x' &&
						is_hex_digit(*(p + 2)) && is_hex_digit(*(p + 3))) {
						unsigned char byte = 16 * hex_digit_to_int(*(p + 2)) +
							hex_digit_to_int(*(p + 3));

						p += 3;
						current = dstr_cat_len(current, (char *)&byte, 1);
					} else if (*p == '\\' && *(p + 1)) {
						char c;

						++p;
						switch (*p) {
						case 'a':
							c = '\a';
							break;
						case 'b':
							c = '\b';
							break;
						case 'n':
							c = '\n';
							break;
						case 'r':
							c = '\r';
							break;
						case 't':
							c = '\t';
							break;
						default:
							c = *p;
							break;
						}
						current = dstr_cat_len(current, &c, 1);
					} else if (*p == '"') {
						/* closing quote must be followed by a space or not at all */
						if (*(p + 1) && !isspace(*(p + 1)))
							goto err;
						done = 1;
					/* unterminated quotes */
					} else if (*p == '\0')
						goto err;
					else
						current = dstr_cat_len(current, p, 1);
				} else if (insq) {
					if (*p == '\\' && *(p + 1) == '\'') {
						++p;
						current = dstr_cat_len(current, "'", 1);
					} else if (*p == '\'') {
						/* closing quote must be followed by a space or not at all */
						if (*(p + 1) && !isspace(*(p + 1)))
							goto err;
						done = 1;
					/* unterminated quotes */
					} else if (*p == '\0')
						goto err;
					else
						current = dstr_cat_len(current, p, 1);
				} else
					switch (*p) {
					case ' ':
					case '\0':
					case '\n':
					case '\r':
					case '\t':
						done = 1;
						break;
					case '"':
						inq = 1;
						break;
					case '\'':
						insq = 1;
						break;
					default:
						current = dstr_cat_len(current, p, 1);
						break;
					}
				if (*p)
					++p;
			}
			if (RESIZE(argv, (*argc + 1) * sizeof (char *)) == NULL)
				goto err;
			argv[*argc] = current;
			++*argc;
			current = NULL;
		} else
			return argv;
	}

err:
	{
		int i;

		for (i = 0; i < *argc; ++i)
			dstr_free(argv[i]);
		FREE(argv);
		if (current)
			dstr_free(current);
		return NULL;
	}
}
Esempio n. 3
0
/* FIXME */
static void *q_thread(void *data) {
	struct crss *crss = (struct crss *)data;
	char buf[64];
	dstr rid, res = NULL;
	db_iterator_t *it;
	const char *key, *value;
	size_t klen, vlen;

	snprintf(buf, sizeof buf, "%p,", crss->c);
	rid = dstr_new(buf);
	rid = dstr_cat(rid, crss->rid);
	it = db_iterator_create(db, db_ro);
	db_iterator_seek(it, crss->start, dstr_length(crss->start));
	/* seek failed */
	if (!db_iterator_valid(it)) {
		res = dstr_new(crss->rid);
		res = dstr_cat(res, ",1\r\n\r\n");
		pthread_spin_lock(&crss->c->lock);
		if (net_try_write(crss->c->fd, res, dstr_length(res), 10, NET_NONBLOCK) == -1)
			xcb_log(XCB_LOG_WARNING, "Writing to client '%p': %s", crss->c, strerror(errno));
		pthread_spin_unlock(&crss->c->lock);
		goto end;
	}
	key = db_iterator_key(it, &klen);
	while (memcmp(key, crss->stop, dstr_length(crss->stop)) <= 0) {
		if (crss->cancel)
			break;
		if (!strcmp(crss->match, "") || strstr(key, crss->match)) {
			value = db_iterator_value(it, &vlen);
			res = dstr_new(crss->rid);
			res = dstr_cat(res, ",0,");
			res = dstr_cat_len(res, key, klen);
			res = dstr_cat(res, ",");
			res = dstr_cat_len(res, value, vlen);
			res = dstr_cat(res, "\r\n");
			pthread_spin_lock(&crss->c->lock);
			if (net_try_write(crss->c->fd, res, dstr_length(res), 10, NET_NONBLOCK) == -1) {
				xcb_log(XCB_LOG_WARNING, "Writing to client '%p': %s",
					crss->c, strerror(errno));
				pthread_spin_unlock(&crss->c->lock);
				goto end;
			}
			pthread_spin_unlock(&crss->c->lock);
			dstr_free(res);
		}
		db_iterator_next(it);
		if (!db_iterator_valid(it) || crss->cancel)
			break;
		key = db_iterator_key(it, &klen);
	}
	res = dstr_new(crss->rid);
	res = dstr_cat(res, ",1\r\n\r\n");
	pthread_spin_lock(&crss->c->lock);
	if (net_try_write(crss->c->fd, res, dstr_length(res), 10, NET_NONBLOCK) == -1)
		xcb_log(XCB_LOG_WARNING, "Writing to client '%p': %s", crss->c, strerror(errno));
	pthread_spin_unlock(&crss->c->lock);

end:
	db_iterator_destroy(&it);
	dstr_free(res);
	table_lock(rids);
	table_remove(rids, rid);
	table_unlock(rids);
	dstr_free(rid);
	client_decr(crss->c);
	dstr_free(crss->rid);
	dstr_free(crss->match);
	dstr_free(crss->start);
	dstr_free(crss->stop);
	FREE(crss);
	return NULL;
}