<commit_before>/* file: reads RDF from Turtle files in a directory and serves them using
 * the Quilt serializers.
 *
 * Author: <NAME> <<EMAIL>>
 *
 * Copyright (c) 2014-2015 BBC
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

#ifdef HAVE_CONFIG_H
# include "config.h"
#endif

#include "p_file.h"

static int file_process(QUILTREQ *request);

static char *basepath;

# ifndef HAVE_STRLCPY
#  undef strlcpy
#  define strlcpy(dest, src, buflen)			\
	if(buflen > 1)								\
	{											\
		strncpy(dest, src, buflen - 1);			\
		(dest)[buflen - 1] = 0;					\
	}											\
	else if(buflen)								\
	{											\
		(dest)[0] = 0;							\
	}
#endif /*!HAVE_STRLCPY*/

# ifndef HAVE_STRLCAT
#  undef strlcat
#  define strlcat(dest, src, buflen)			\
	if(buflen > 1)								\
	{											\
		strncat(dest, src, buflen - 1);			\
		(dest)[buflen - 1] = 0;					\
	}											\
	else if(buflen)								\
	{											\
		(dest)[0] = 0;							\
	}
#endif /*!HAVE_STRLCAT*/

int
quilt_plugin_init(void)
{
	if(quilt_plugin_register_engine(QUILT_PLUGIN_NAME, file_process))
	{
		quilt_logf(LOG_CRIT, QUILT_PLUGIN_NAME ": failed to register engine\n");
		return -1;
	}
	basepath = quilt_config_geta("file:root", DATAROOTDIR "/" PACKAGE_TARNAME "/sample");
	return 0;
}

static int
file_process(QUILTREQ *request)
{
	librdf_world *world;
	librdf_parser *parser;
	librdf_uri *base;
	const char *s;
	char *pathname;
	size_t buflen, len;
	FILE *f;
	QUILTCANON *canonical;

	canonical = request->canonical;
	world = quilt_librdf_world();
	if(request->home)
	{
		s = "index";
	}
	else
	{
		s = request->path;
		quilt_canon_add_path(canonical, request->path);
	}
	/* QUILT-36: this will be unnecessary once the fragment is inferred */
	quilt_canon_set_fragment(canonical, "id");
	while(*s == '/')
	{
		s++;
	}
	len = strlen(basepath);
	/* basepath + '/' + s + '.ttl' */
	buflen = strlen(basepath) + 1 + strlen(s) + 4 + 1;
	pathname = (char *) malloc(buflen);
	if(!pathname)
	{
		quilt_logf(LOG_CRIT, QUILT_PLUGIN_NAME ": failed to allocate %u bytes\n", (unsigned) len);
		return 500;
	}
	strlcpy(pathname, basepath, buflen);
	pathname[len] = '/';
	pathname[len + 1] = 0;
	strlcat(&(pathname[len + 1]), s, buflen);
	strlcat(pathname, ".ttl", buflen);
	f = fopen(pathname, "rb");
	if(!f)
	{
		quilt_logf(LOG_ERR, QUILT_PLUGIN_NAME ": failed to open %s: %s\n", pathname, strerror(errno));
		free(pathname);
		return 404;
	}
	parser = librdf_new_parser(world, "turtle", NULL, NULL);
	if(!parser)
	{
		quilt_logf(LOG_CRIT, QUILT_PLUGIN_NAME ": failed to create Turtle parser\n");
		fclose(f);
		free(pathname);
		return 404;
	}
	base = librdf_new_uri(world, (const unsigned char *) request->base);
	if(!base)
	{
		quilt_logf(LOG_CRIT, QUILT_PLUGIN_NAME ": failed to create new RDF URI from <%s>\n", request->base);
		fclose(f);
		free(pathname);
		librdf_free_parser(parser);
		return 500;
	}
	quilt_logf(LOG_DEBUG, QUILT_PLUGIN_NAME ": parsing %s\n", pathname);<commit_msg>When using strlcat(), ensure the pointer passed is actually the start of the buffer.<commit_after>/* file: reads RDF from Turtle files in a directory and serves them using
 * the Quilt serializers.
 *
 * Author: <NAME> <<EMAIL>>
 *
 * Copyright (c) 2014-2015 BBC
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

#ifdef HAVE_CONFIG_H
# include "config.h"
#endif

#include "p_file.h"

static int file_process(QUILTREQ *request);

static char *basepath;

# ifndef HAVE_STRLCPY
#  undef strlcpy
#  define strlcpy(dest, src, buflen)			\
	if(buflen > 1)								\
	{											\
		strncpy(dest, src, buflen - 1);			\
		(dest)[buflen - 1] = 0;					\
	}											\
	else if(buflen)								\
	{											\
		(dest)[0] = 0;							\
	}
#endif /*!HAVE_STRLCPY*/

# ifndef HAVE_STRLCAT
#  undef strlcat
#  define strlcat(dest, src, buflen)			\
	if(buflen > 1)								\
	{											\
		strncat(dest, src, buflen - 1);			\
		(dest)[buflen - 1] = 0;					\
	}											\
	else if(buflen)								\
	{											\
		(dest)[0] = 0;							\
	}
#endif /*!HAVE_STRLCAT*/

int
quilt_plugin_init(void)
{
	if(quilt_plugin_register_engine(QUILT_PLUGIN_NAME, file_process))
	{
		quilt_logf(LOG_CRIT, QUILT_PLUGIN_NAME ": failed to register engine\n");
		return -1;
	}
	basepath = quilt_config_geta("file:root", DATAROOTDIR "/" PACKAGE_TARNAME "/sample");
	return 0;
}

static int
file_process(QUILTREQ *request)
{
	librdf_world *world;
	librdf_parser *parser;
	librdf_uri *base;
	const char *s;
	char *pathname;
	size_t buflen, len;
	FILE *f;
	QUILTCANON *canonical;

	canonical = request->canonical;
	world = quilt_librdf_world();
	if(request->home)
	{
		s = "index";
	}
	else
	{
		s = request->path;
		quilt_canon_add_path(canonical, request->path);
	}
	/* QUILT-36: this will be unnecessary once the fragment is inferred */
	quilt_canon_set_fragment(canonical, "id");
	while(*s == '/')
	{
		s++;
	}
	len = strlen(basepath);
	/* basepath + '/' + s + '.ttl' */
	buflen = strlen(basepath) + 1 + strlen(s) + 4 + 1;
	pathname = (char *) malloc(buflen);
	if(!pathname)
	{
		quilt_logf(LOG_CRIT, QUILT_PLUGIN_NAME ": failed to allocate %u bytes\n", (unsigned) len);
		return 500;
	}
	strlcpy(pathname, basepath, buflen);
	pathname[len] = '/';
	pathname[len + 1] = 0;
	strlcat(pathname, s, buflen);
	strlcat(pathname, ".ttl", buflen);
	f = fopen(pathname, "rb");
	if(!f)
	{
		quilt_logf(LOG_ERR, QUILT_PLUGIN_NAME ": failed to open %s: %s\n", pathname, strerror(errno));
		free(pathname);
		return 404;
	}
	parser = librdf_new_parser(world, "turtle", NULL, NULL);
	if(!parser)
	{
		quilt_logf(LOG_CRIT, QUILT_PLUGIN_NAME ": failed to create Turtle parser\n");
		fclose(f);
		free(pathname);
		return 404;
	}
	base = librdf_new_uri(world, (const unsigned char *) request->base);
	if(!base)
	{
		quilt_logf(LOG_CRIT, QUILT_PLUGIN_NAME ": failed to create new RDF URI from <%s>\n", request->base);
		fclose(f);
		free(pathname);
		librdf_free_parser(parser);
		return 500;
	}
	quilt_logf(LOG_DEBUG, QUILT_PLUGIN_NAME ": parsing %s\n", pathname);
{'fraction_non_alphanumeric': 0.13778348309798888, 'fraction_numerical': 0.012979603480245329, 'mean_word_length': 3.39073262366938, 'pattern_counts': {'":': 12, '<': 11, '<?xml version=': 0, '>': 27, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4842389', 'n_tokens_mistral': 3133, 'n_tokens_neox': 2779, 'n_words': 671}