<commit_before>/*
 * The Qubes OS Project, http://www.qubes-os.org
 *
 * Copyright (C) 2010  <NAME>  <<EMAIL>>
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 *
 */

#include <sys/select.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/stat.h>
#include "qrexec.h"
#include "buffer.h"
#include "glue.h"

enum client_flags {
	CLIENT_INVALID = 0,
	CLIENT_CMDLINE = 1,
	CLIENT_DATA = 2,
	CLIENT_DONT_READ = 4,
	CLIENT_OUTQ_FULL = 8
};

struct _client {
	int state;
	struct buffer buffer;
};

struct _client clients[MAX_FDS];

int max_client_fd = -1;
int server_fd;

void handle_usr1(int x)
{
        exit(0);
}

void init(int xid)
{
	char dbg_log[256];
	int logfd;

	if (xid <= 0) {
		fprintf(stderr, "domain id=0?\n");
		exit(1);
	}
	signal(SIGUSR1, handle_usr1);
	switch (fork()) {
	case -1:
		perror("fork");
		exit(1);
	case 0:
		break;
	default:
	        pause();
		exit(0);
	}
	close(0);
	snprintf(dbg_log, sizeof(dbg_log),
		 "/var/log/qubes/qrexec.%d.log", xid);
	umask(0007);
	logfd = open(dbg_log, O_WRONLY | O_CREAT | O_TRUNC, 0640);
	dup2(logfd, 1);
	dup2(logfd, 2);

	chdir("/var/run/qubes");
	if (setsid() < 0) {
		perror("setsid()");
		exit(1);
	}

	umask(0);
	server_fd = get_server_socket(xid);
	umask(0077);
	peer_client_init(xid, REXEC_PORT);
	setuid(getuid());
	signal(SIGPIPE, SIG_IGN);
	signal(SIGUSR1, SIG_DFL);
}

void handle_new_client()
{
	int fd = do_accept(server_fd);
	if (fd >= MAX_FDS) {
		fprintf(stderr, "too many clients ?\n");
		exit(1);
	}
	clients[fd].state = CLIENT_CMDLINE;
	buffer_init(&clients[fd].buffer);
	if (fd > max_client_fd)
		max_client_fd = fd;
}

void flush_client(int fd)
{
	int i;
	struct server_header s_hdr;
	close(fd);
	clients[fd].state = CLIENT_INVALID;
	buffer_free(&clients[fd].buffer);
	if (max_client_fd == fd) {
		for (i = fd; clients[i].state == CLIENT_INVALID && i >= 0;
		     i--);
		max_client_fd = i;
	}<commit_msg>qrexec_daemon child should notify the parent.<commit_after>/*
 * The Qubes OS Project, http://www.qubes-os.org
 *
 * Copyright (C) 2010  <NAME>  <<EMAIL>>
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 *
 */

#include <sys/select.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/stat.h>
#include "qrexec.h"
#include "buffer.h"
#include "glue.h"

enum client_flags {
	CLIENT_INVALID = 0,
	CLIENT_CMDLINE = 1,
	CLIENT_DATA = 2,
	CLIENT_DONT_READ = 4,
	CLIENT_OUTQ_FULL = 8
};

struct _client {
	int state;
	struct buffer buffer;
};

struct _client clients[MAX_FDS];

int max_client_fd = -1;
int server_fd;

void handle_usr1(int x)
{
        exit(0);
}

void init(int xid)
{
	char dbg_log[256];
	int logfd;

	if (xid <= 0) {
		fprintf(stderr, "domain id=0?\n");
		exit(1);
	}
	signal(SIGUSR1, handle_usr1);
	switch (fork()) {
	case -1:
		perror("fork");
		exit(1);
	case 0:
		break;
	default:
	        pause();
		exit(0);
	}
	close(0);
	snprintf(dbg_log, sizeof(dbg_log),
		 "/var/log/qubes/qrexec.%d.log", xid);
	umask(0007);
	logfd = open(dbg_log, O_WRONLY | O_CREAT | O_TRUNC, 0640);
	dup2(logfd, 1);
	dup2(logfd, 2);

	chdir("/var/run/qubes");
	if (setsid() < 0) {
		perror("setsid()");
		exit(1);
	}

	umask(0);
	server_fd = get_server_socket(xid);
	umask(0077);
	peer_client_init(xid, REXEC_PORT);
	setuid(getuid());
	signal(SIGPIPE, SIG_IGN);
	signal(SIGUSR1, SIG_DFL);
	kill(getppid(), SIGUSR1);
}

void handle_new_client()
{
	int fd = do_accept(server_fd);
	if (fd >= MAX_FDS) {
		fprintf(stderr, "too many clients ?\n");
		exit(1);
	}
	clients[fd].state = CLIENT_CMDLINE;
	buffer_init(&clients[fd].buffer);
	if (fd > max_client_fd)
		max_client_fd = fd;
}

void flush_client(int fd)
{
	int i;
	struct server_header s_hdr;
	close(fd);
	clients[fd].state = CLIENT_INVALID;
	buffer_free(&clients[fd].buffer);
	if (max_client_fd == fd) {
		for (i = fd; clients[i].state == CLIENT_INVALID && i >= 0;
		     i--);
		max_client_fd = i;
	}
{'fraction_non_alphanumeric': 0.14066304551414122, 'fraction_numerical': 0.022288818130736094, 'mean_word_length': 4.0, 'pattern_counts': {'":': 0, '<': 29, '<?xml version=': 0, '>': 31, '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': '5153943', 'n_tokens_mistral': 2185, 'n_tokens_neox': 2066, 'n_words': 577}