int EFSConfigurationCreate(uv_file const fd, EFSConfigurationRef *const out) {
	assert(out);
	if(fd < 0) return UV_EINVAL;

	EFSConfigurationRef conf = calloc(1, sizeof(struct EFSConfiguration));
	if(!conf) return UV_ENOMEM;
	int rc = 0;

	uv_buf_t buf[1];
	buf->base = malloc(BUF_LEN);
	if(!buf->base) { rc = UV_ENOMEM; goto cleanup; }
	buf->len = BUF_LEN;

	ssize_t len;
	int64_t pos = 0;
	for(;;) {
		len = async_fs_read(fd, buf, 1, pos);
		if(len < 0) { rc = len; goto cleanup; }
		
	}



	*out = conf;

cleanup:

	if(rc < 0) EFSConfigurationFree(&conf);
	return rc;
}
示例#2
0
ssize_t async_fs_readall_simple(uv_file const file, uv_buf_t const *const buf) {
	async_pool_enter(NULL);
	size_t pos = 0;
	ssize_t rc;
	for(;;) {
		uv_buf_t b2 = uv_buf_init(buf->base+pos, buf->len-pos);
		rc = async_fs_read(file, &b2, 1, -1);
		if(rc < 0) break;
		if(0 == rc) { rc = pos; break; }
		pos += rc;
		if(pos >= buf->len) { rc = pos; break; }
	}
	async_pool_leave(NULL);
	return rc;
}
示例#3
0
int SLNSubmissionParseMetaFile(SLNSubmissionRef const sub, uint64_t const fileID, DB_txn *const txn, uint64_t *const out) {
	assert(out);
	if(!sub) return DB_EINVAL;
	if(!fileID) return DB_EINVAL;
	if(!txn) return DB_EINVAL;

	strarg_t const type = SLNSubmissionGetType(sub);
	if(!type) return 0;
	if(0 != strcasecmp(SLN_META_TYPE, type) &&
	   0 != strcasecmp("text/x-sln-meta+json; charset=utf-8", type) &&
	   0 != strcasecmp("text/efs-meta+json; charset=utf-8", type)) return 0;
	// TODO: Get rid of these obsolete types.

	uv_file const fd = SLNSubmissionGetFile(sub);
	if(fd < 0) return DB_EINVAL;

	int rc = 0;
	uv_buf_t buf[1] = {};
	DB_txn *subtxn = NULL;
	parser_t ctx[1] = {};
	yajl_handle parser = NULL;

	buf->base = malloc(BUF_LEN);
	if(!buf->base) { rc = DB_ENOMEM; goto cleanup; }

	buf->len = URI_MAX;
	int64_t pos = 0;
	ssize_t len = async_fs_read(fd, buf, 1, pos);
	if(len < 0) {
		fprintf(stderr, "Submission meta-file read error (%s)\n", sln_strerror(len));
		rc = DB_EIO;
		goto cleanup;
	}

	size_t i;
	for(i = 0; i < len; i++) {
		char const c = buf->base[i];
		if('\r' == c || '\n' == c) break;
	}
	if(i >= len) {
		fprintf(stderr, "Submission meta-file parse error (invalid target URI)\n");
		rc = DB_EIO;
		goto cleanup;
	}
	assert(i < len);
	str_t targetURI[URI_MAX];
	memcpy(targetURI, buf->base, i);
	targetURI[i] = '\0';
	pos += i;

	// TODO: Support sub-transactions in LevelDB backend.
	// TODO: db_txn_begin should support NULL env.
//	rc = db_txn_begin(NULL, txn, DB_RDWR, &subtxn);
//	if(rc < 0) goto cleanup;
	subtxn = txn;

	uint64_t const metaFileID = add_metafile(subtxn, fileID, targetURI);
	if(!metaFileID) goto cleanup;
	// Duplicate meta-file, not an error.
	// TODO: Unless the previous version wasn't actually a meta-file.

	ctx->txn = subtxn;
	ctx->metaFileID = metaFileID;
	ctx->targetURI = targetURI;
	ctx->depth = -1;
	parser = yajl_alloc(&callbacks, NULL, ctx);
	if(!parser) rc = DB_ENOMEM;
	if(rc < 0) goto cleanup;
	yajl_config(parser, yajl_allow_partial_values, (int)true);

	yajl_status status = yajl_status_ok;
	for(;;) {
		buf->len = MIN(BUF_LEN, PARSE_MAX-pos);
		if(!buf->len) break;
		len = async_fs_read(fd, buf, 1, pos);
		if(len < 0) {
			fprintf(stderr, "Submission meta-file read error (%s)\n", sln_strerror(len));
			rc = DB_EIO;
			goto cleanup;
		}
		if(0 == len) break;
		status = yajl_parse(parser, (byte_t const *)buf->base, len);
		if(yajl_status_ok != status) break;
		pos += len;
	}
	status = yajl_complete_parse(parser);
	if(yajl_status_ok != status) {
		unsigned char *msg = yajl_get_error(parser, true, (byte_t const *)buf->base, len);
		fprintf(stderr, "%s", msg);
		yajl_free_error(parser, msg); msg = NULL;
		rc = DB_EIO;
		goto cleanup;
	}

	assert(-1 == ctx->depth);

//	rc = db_txn_commit(subtxn); subtxn = NULL;
	if(rc < 0) goto cleanup;

	*out = metaFileID;

cleanup:
//	db_txn_abort(subtxn); subtxn = NULL;
	FREE(&buf->base);
	if(parser) yajl_free(parser); parser = NULL;
	assert_zeroed(ctx->fields, DEPTH_MAX);
	return rc;
}