Exemple #1
0
int SLNSubmissionCreate(SLNSessionRef const session, strarg_t const knownURI, SLNSubmissionRef *const out) {
	assert(out);
	if(!SLNSessionHasPermission(session, SLN_WRONLY)) return UV_EACCES;

	SLNSubmissionRef sub = calloc(1, sizeof(struct SLNSubmission));
	if(!sub) return UV_ENOMEM;
	int rc = 0;

	sub->session = session;
	if(knownURI) {
		sub->knownURI = strdup(knownURI);
		if(!sub->knownURI) rc = UV_ENOMEM;
		if(rc < 0) goto cleanup;
	}
	sub->type = NULL;

	sub->tmppath = SLNRepoCopyTempPath(SLNSessionGetRepo(session));
	if(!sub->tmppath) rc = UV_ENOMEM;
	if(rc < 0) goto cleanup;
	rc = async_fs_open_mkdirp(sub->tmppath, O_CREAT | O_EXCL | O_RDWR, 0400);
	if(rc < 0) goto cleanup;
	sub->tmpfile = rc;

	sub->hasher = SLNHasherCreate(sub->type);
	if(!sub->hasher) rc = UV_ENOMEM;
	if(rc < 0) goto cleanup;

	sub->metaFileID = 0;

	*out = sub; sub = NULL;

cleanup:
	SLNSubmissionFree(&sub);
	return rc;
}
int BlogGeneric(BlogRef const blog,
                SLNSessionRef const session,
                strarg_t const htmlpath,
                strarg_t const URI,
                SLNFileInfo const *const src)
{
	str_t *tmp = NULL;
	uv_file html = -1;
	int rc = 0;

	tmp = SLNRepoCopyTempPath(blog->repo);
	if(!tmp) rc = UV_ENOMEM;
	if(rc < 0) goto cleanup;

	rc = async_fs_open_mkdirp(tmp, O_CREAT | O_EXCL | O_WRONLY, 0400);
	if(rc < 0) goto cleanup;
	html = rc;

	preview_state const state = {
		.blog = blog,
		.session = session,
		.fileURI = URI,
	};
	rc = TemplateWriteFile(blog->preview, &preview_cbs, &state, html);
	if(rc < 0) goto cleanup;

	rc = async_fs_fdatasync(html);
	if(rc < 0) goto cleanup;

	rc = async_fs_link_mkdirp(tmp, htmlpath);
	if(rc < 0) goto cleanup;

cleanup:
	async_fs_unlink(tmp); FREE(&tmp);
	if(html >= 0) { async_fs_close(html); html = -1; }
	assert(html < 0);
	return rc;
}
static int convert(BlogRef const blog,
                   SLNSessionRef const session,
                   char const *const htmlpath,
                   SLNSubmissionRef *const outmeta,
                   strarg_t const URI,
                   SLNFileInfo const *const src,
                   BlogTypeCheck const types,
                   BlogConverter const converter)
{
	int rc = types(src->type);
	if(rc < 0) return UV_EINVAL;

	str_t *tmp = NULL;
	uv_file html = -1;
	uv_file file = -1;
	char const *buf = NULL;
	SLNSubmissionRef meta = NULL;
	yajl_gen json = NULL;

	tmp = SLNRepoCopyTempPath(blog->repo);
	if(!tmp) rc = UV_ENOMEM;
	if(rc < 0) goto cleanup;

	rc = async_fs_open_mkdirp(tmp, O_CREAT | O_EXCL | O_WRONLY, 0400);
	if(rc < 0) goto cleanup;
	html = rc;

	rc = async_fs_open(src->path, O_RDONLY, 0000);
	if(rc < 0) goto cleanup;
	file = rc;

	// We use size+1 to get nul-termination. Kind of a hack.
	buf = mmap(NULL, src->size+1, PROT_READ, MAP_SHARED, file, 0);
	if(MAP_FAILED == buf) rc = -errno;
	if(rc < 0) goto cleanup;
	if('\0' != buf[src->size]) rc = UV_EIO; // Slightly paranoid.
	if(rc < 0) goto cleanup;

	async_fs_close(file); file = -1;

	if(outmeta) {
		rc = SLNSubmissionCreate(session, NULL, URI, &meta);
		if(rc < 0) goto cleanup;
		rc = SLNSubmissionSetType(meta, SLN_META_TYPE);
		if(rc < 0) goto cleanup;
	}

	SLNSubmissionWrite(meta, (byte_t const *)URI, strlen(URI));
	SLNSubmissionWrite(meta, (byte_t const *)STR_LEN("\n\n"));

	json = yajl_gen_alloc(NULL);
	if(!json) rc = UV_ENOMEM;
	if(rc < 0) goto cleanup;
	yajl_gen_config(json, yajl_gen_print_callback, (void (*)())SLNSubmissionWrite, meta);
	yajl_gen_config(json, yajl_gen_beautify, (int)true);

	async_pool_enter(NULL);
	yajl_gen_map_open(json);
	rc = converter(html, json, buf, src->size, src->type);
	yajl_gen_map_close(json);
	async_pool_leave(NULL);
	if(rc < 0) goto cleanup;

	rc = async_fs_fdatasync(html);
	if(rc < 0) goto cleanup;

	rc = async_fs_link_mkdirp(tmp, htmlpath);
	if(rc < 0) goto cleanup;

	rc = SLNSubmissionEnd(meta);
	if(rc < 0) goto cleanup;

	if(outmeta) {
		*outmeta = meta; meta = NULL;
	}

cleanup:
	async_fs_unlink(tmp); FREE(&tmp);
	if(html >= 0) { async_fs_close(html); html = -1; }
	if(file >= 0) { async_fs_close(file); file = -1; }
	if(buf) { munmap((void *)buf, src->size+1); buf = NULL; }
	if(json) { yajl_gen_free(json); json = NULL; }
	SLNSubmissionFree(&meta);
	assert(html < 0);
	assert(file < 0);
	return rc;
}