<commit_before>/*
 * Copyright (c) 2012 Varnish Software AS
 * All rights reserved.
 *
 * Author: <NAME> <<EMAIL>>
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

#define _GNU_SOURCE
#include "common.h"
#include "plugins.h"
#include "ipc.h"
#include "httpd.h"

#include <assert.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
#include <string.h>
#include <time.h>
#include <errno.h>

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#define VCL_PATH "tmp/"
#define VCL_ACTIVE_PATH "tmp/active_vcl"


struct vcl_priv_t {
	int logger;
	int vadmin;
	const char *help;
};

struct vcl_list {
	char name[1024];
	char available[11];
	char ref[11];
};

static void mk_help(struct vcl_priv_t *vcl) {
	vcl->help = "The following logic can be used:\n"
		"GET /vcl/ - Fetch a list of VCLs (e.g: vcl.list)\n"
		"GET /vcl/vclname - Fetch the vcl named vclname (vcl.show)\n"
		"POST /vcl/ - Upload a new VCL, named dynamically. (vcl.inline).\n"
		"PUT /vcl/vclname - Upload a new VCL with the specified name.\n"
		"DELETE /vcl/vclname - Discard a named VCL (vcl.discard)\n"
		"PUT /vcldeploy/vclname - Deploy the vcl (e.g: vcl.use)\n";
}

static int vcl_persist(const char *id, const char *vcl) {
	int fd, ret;
	char *path;
	struct stat sbuf;
	fd = asprintf(&path, VCL_PATH "%s.vcl", id);
	assert(fd>0);
	fd = open(path, O_CREAT | O_WRONLY | O_TRUNC, S_IRWXU);
	if (fd < 0) {
		ret = -1;
		goto out;
	}
	ret = stat(path, &sbuf);
	if (ret < 0) {
		ret = -1;
		goto out;
	}
	if (!(S_ISREG(sbuf.st_mode))) {
		ret = -1;
		goto out;
	}
	ret = write(fd, (const void *)vcl, strlen(vcl));
	assert(ret>0);
	ret = 0;
	out:
	close(fd);
	free(path);
	return ret;
}

static int vcl_persist_active(const char *id)
{
	int ret;
	char buf[1024];
	struct stat sbuf;
	/*
	 * FIXME: need to move things into place to avoid disaster if we
	 * crash during update, leaving no active vcl in place.
	 */
	sprintf(buf, VCL_PATH "%s.vcl", id);
	ret = stat(buf, &sbuf);
	if (ret < 0)
		return -1;
	if (!(S_ISREG(sbuf.st_mode)))
		return -1;
	unlink(VCL_ACTIVE_PATH);
	sprintf(buf, "%s.vcl", id);
	ret = symlink(buf, VCL_ACTIVE_PATH);
	if (ret!=0)
		return -1;
	return 0;
}

static int vcl_store(struct httpd_request *request,
		      struct vcl_priv_t *vcl,
		      struct ipc_ret_t *vret,
		      const char *id)
{
	int ret;
	ipc_run(vcl->vadmin, vret, "vcl.inline %s << __EOF_%s__\n%s\n__EOF_%s__",
		id,id,(char *)request->data,id);
	if (vret->status == 200) {
		logger(vcl->logger, "VCL stored OK");
		ret = vcl_persist(id, request->data);
		if (ret) {
			logger(vcl->logger, "vcl.inline OK, but persisting to disk failed. Errno: %d", errno);
			free(vret->answer);
			vret->answer = strdup("VCL stored in varnish OK, but persisting to disk failed.");
			return 500;
		}
		return 201;<commit_msg>Use hardlinks for active_vcl instead of symlink<commit_after>/*
 * Copyright (c) 2012 Varnish Software AS
 * All rights reserved.
 *
 * Author: <NAME> <<EMAIL>>
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

#define _GNU_SOURCE
#include "common.h"
#include "plugins.h"
#include "ipc.h"
#include "httpd.h"

#include <assert.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
#include <string.h>
#include <time.h>
#include <errno.h>

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#define VCL_PATH "tmp/"
#define VCL_ACTIVE_PATH "tmp/active_vcl"


struct vcl_priv_t {
	int logger;
	int vadmin;
	const char *help;
};

struct vcl_list {
	char name[1024];
	char available[11];
	char ref[11];
};

static void mk_help(struct vcl_priv_t *vcl) {
	vcl->help = "The following logic can be used:\n"
		"GET /vcl/ - Fetch a list of VCLs (e.g: vcl.list)\n"
		"GET /vcl/vclname - Fetch the vcl named vclname (vcl.show)\n"
		"POST /vcl/ - Upload a new VCL, named dynamically. (vcl.inline).\n"
		"PUT /vcl/vclname - Upload a new VCL with the specified name.\n"
		"DELETE /vcl/vclname - Discard a named VCL (vcl.discard)\n"
		"PUT /vcldeploy/vclname - Deploy the vcl (e.g: vcl.use)\n";
}

static int vcl_persist(const char *id, const char *vcl) {
	int fd, ret;
	char *path;
	struct stat sbuf;
	fd = asprintf(&path, VCL_PATH "%s.vcl", id);
	assert(fd>0);
	fd = open(path, O_CREAT | O_WRONLY | O_TRUNC, S_IRWXU);
	if (fd < 0) {
		ret = -1;
		goto out;
	}
	ret = stat(path, &sbuf);
	if (ret < 0) {
		ret = -1;
		goto out;
	}
	if (!(S_ISREG(sbuf.st_mode))) {
		ret = -1;
		goto out;
	}
	ret = write(fd, (const void *)vcl, strlen(vcl));
	assert(ret>0);
	ret = 0;
	out:
	close(fd);
	free(path);
	return ret;
}

static int vcl_persist_active(const char *id)
{
	int ret;
	char buf[1024];
	struct stat sbuf;
	/*
	 * FIXME: need to move things into place to avoid disaster if we
	 * crash during update, leaving no active vcl in place.
	 */
	sprintf(buf, VCL_PATH "%s.vcl", id);
	ret = stat(buf, &sbuf);
	if (ret < 0)
		return -1;
	if (!(S_ISREG(sbuf.st_mode)))
		return -1;
	unlink(VCL_ACTIVE_PATH);
	ret = link(buf, VCL_ACTIVE_PATH);
	if (ret!=0)
		return -1;
	return 0;
}

static int vcl_store(struct httpd_request *request,
		      struct vcl_priv_t *vcl,
		      struct ipc_ret_t *vret,
		      const char *id)
{
	int ret;
	ipc_run(vcl->vadmin, vret, "vcl.inline %s << __EOF_%s__\n%s\n__EOF_%s__",
		id,id,(char *)request->data,id);
	if (vret->status == 200) {
		logger(vcl->logger, "VCL stored OK");
		ret = vcl_persist(id, request->data);
		if (ret) {
			logger(vcl->logger, "vcl.inline OK, but persisting to disk failed. Errno: %d", errno);
			free(vret->answer);
			vret->answer = strdup("VCL stored in varnish OK, but persisting to disk failed.");
			return 500;
		}
		return 201;
{'fraction_non_alphanumeric': 0.124320987654321, 'fraction_numerical': 0.010123456790123457, 'mean_word_length': 3.8048635824436534, 'pattern_counts': {'":': 0, '<': 41, '<?xml version=': 0, '>': 53, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, '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': '1257195', 'n_tokens_mistral': 3141, 'n_tokens_neox': 2908, 'n_words': 1004}