Репозиторий Sisyphus
Последнее обновление: 1 октября 2023 | Пакетов: 18631 | Посещений: 37538566
en ru br
Репозитории ALT
S:0.5.15lorg2-alt86
5.1: 0.5.15lorg2-alt33.M50P.1
4.1: 0.5.15lorg2-alt20.M41.1
4.0: 0.5.15lorg2-alt18.M40.1
+updates:0.5.15lorg2-alt18
3.0: 0.5.15cnc6-alt16
www.altlinux.org/Changes

Группа :: Система/Настройка/Пакеты
Пакет: apt

 Главная   Изменения   Спек   Патчи   Sources   Загрузить   Gear   Bugs and FR  Repocop 

Патч: apt-0.5.15cnc6-alt-apt-pipe.patch
Скачать


--- apt-0.5.15cnc6/cmdline/apt-pipe.c..pipe	2005-06-27 22:09:57 +0400
+++ apt-0.5.15cnc6/cmdline/apt-pipe.c	2005-06-27 22:29:45 +0400
@@ -0,0 +1,387 @@
+/* ----------------------------------------------------------------------------
+   $Id: apt-pipe.c,v 1.3 2005/03/20 20:56:03 me Exp $
+ */
+
+#ifndef APT_PIPE_PATH
+#define APT_PIPE_PATH "/var/lib/apt/pipe"
+#endif
+
+#include <argz.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+
+#include <setproctitle.h>
+
+/* ----------------------------------------------------------------------------
+*/
+
+extern int aptpipe_init(void);
+extern int aptpipe_main(int, const char **);
+extern int aptpipe_fini(void);
+
+/* ----------------------------------------------------------------------------
+ */
+
+static volatile sig_atomic_t signalled = 0;
+
+/* ----------------------------------------------------------------------------
+  server
+*/
+static void sighandler(int sig)
+{
+	++signalled;
+}
+
+static void set_sighandler(int flags)
+{
+ 	struct sigaction sa;
+
+	sa.sa_handler = sighandler;
+	sigemptyset(&sa.sa_mask);
+	sigaddset(&sa.sa_mask, SIGINT);
+	sigaddset(&sa.sa_mask, SIGTERM);
+	sigaddset(&sa.sa_mask, SIGHUP);
+	sa.sa_flags = flags;
+
+	(void) sigaction(SIGINT, &sa, NULL);
+	(void) sigaction(SIGTERM, &sa, NULL);
+	(void) sigaction(SIGHUP, &sa, NULL);
+}
+
+static int do_listen()
+{
+	int servsock;
+	struct sockaddr_un sockaddr;
+	
+	if ((servsock = socket(AF_LOCAL, SOCK_STREAM, 0)) < 0)
+		return -1;
+
+	unlink(APT_PIPE_PATH);
+	memset(&sockaddr, 0, sizeof(sockaddr));
+	sockaddr.sun_family = AF_LOCAL;
+	strncpy(sockaddr.sun_path, APT_PIPE_PATH, sizeof(sockaddr.sun_path));
+	if (bind(servsock, (struct sockaddr *)&sockaddr, sizeof(sockaddr)) < 0)
+		return -1;
+
+	return ((listen(servsock, 1)) < 0 ? -1 : servsock);
+}
+
+static ssize_t recv_query(int sock, void *buf, size_t bufsize, int *fd)
+{
+	struct msghdr msg;
+	struct iovec iov[1];
+	ssize_t	received = 0;
+	
+	union {
+		struct cmsghdr cm;
+		char control[CMSG_SPACE(sizeof(int))];
+	} control_un;
+	struct cmsghdr	*cmsg;
+
+	msg.msg_name = NULL;
+	msg.msg_namelen = 0;
+
+	iov[0].iov_base = buf;
+	iov[0].iov_len = bufsize;
+	msg.msg_iov = iov;
+	msg.msg_iovlen = 1;
+
+	msg.msg_control = control_un.control;
+	msg.msg_controllen = sizeof(control_un.control);
+
+	if ((received = recvmsg(sock, &msg, MSG_WAITALL)) > 0 &&
+		(cmsg = CMSG_FIRSTHDR(&msg)) != NULL &&
+		cmsg->cmsg_len == CMSG_LEN(sizeof(int)) &&
+		cmsg->cmsg_level == SOL_SOCKET &&
+		cmsg->cmsg_type == SCM_RIGHTS)
+		*fd = *((int *) CMSG_DATA(cmsg));
+
+	return(received);
+}
+
+static int send_reply(int sock, char *buf, ssize_t bufsize, int fd)
+{
+	int i, ac;
+	char **av = NULL;
+
+	/* minimal sanity check */
+	if (0 != *(buf + bufsize - 1))
+		return -1;
+
+	/* make fd passed by client our stdout/stderr */
+	dup2(fd, STDOUT_FILENO);
+	dup2(fd, STDERR_FILENO);
+	close(fd);
+
+	/* apt's .Parse skips av[0], so fake it */
+	ac = argz_count(buf, bufsize) + 1;
+	av = (char **)calloc(ac + 1, sizeof(char *));
+	*av = "";
+
+	argz_extract(buf, bufsize, ++av);
+	
+	ac = i = aptpipe_main(ac, (const char **)--av);
+	fflush(stdout);
+	fflush(stderr);
+
+	free(av);
+
+	if ((fd = open("/dev/null", O_RDWR)) < 0)
+		return 1;
+
+	dup2(fd, STDOUT_FILENO);
+	dup2(fd, STDERR_FILENO);
+	close(fd);
+
+	i = (i < 0);
+	ac = (ac > 0);
+
+	/* send last reply later */
+	if (!ac)
+		write(sock, &i, sizeof(int));
+
+	return(ac);
+}
+
+static int mainloop(int servsock) {
+	int cl;
+	int done = 0;
+	char buf[65536];
+
+	while(!signalled && !done) {
+		int fd = -1;
+		size_t received;
+
+		/* TODO check for pending errors on socket */
+
+		/* enable EINTR while in accept */
+		set_sighandler(0);
+		if((cl = accept(servsock, NULL, 0)) < 0) continue;
+
+		set_sighandler(SA_RESTART);
+		if ((received = recv_query(cl, buf, sizeof(buf), &fd)) > 0 && fd != -1)
+			done = send_reply(cl, buf, received, fd);
+		if (!done)
+			close(cl);
+	}
+
+	close(servsock);
+	return(cl);
+}
+
+static int daemonize()
+{
+	pid_t pid;
+	int i, fd;
+	int fds[2] = {-1, -1};
+
+	if (pipe(fds) < 0)
+		return -1;
+
+	if ((pid = fork()) < 0)
+		return -1;
+
+	if (pid) {
+		/* parent */
+		close(fds[1]);
+		/* get child's status */
+		if (read(fds[0], &i, (sizeof(int))) != sizeof(int))
+			return -1;
+		return i;
+	}
+
+	/* child */
+	close(fds[0]);
+	setsid();
+	chdir("/");
+	while (fds[1] <= 2) {
+		fds[1] = dup(fds[1]);
+		if (fds[1] < 0)
+			exit(1);
+	}
+	
+	if ((fd = open("/dev/null", O_RDWR)) < 0)
+		exit(1);
+
+	dup2(fd, 0);
+	dup2(fd, 1);
+	dup2(fd, 2);
+
+	/* closeall */
+	i = sysconf (_SC_OPEN_MAX);
+	for (fd = 3; fd < i; fd++) 
+		if (fd != fds[1])
+			close (fd);
+
+	/* ignore some signals */
+	signal(SIGHUP, SIG_IGN);
+	signal(SIGPIPE, SIG_IGN);
+	signal(SIGUSR1, SIG_IGN);
+	signal(SIGUSR2, SIG_IGN);
+	/* no EINTR please */
+	set_sighandler(SA_RESTART);
+
+	/* open listening socket */
+	if ((fd = do_listen()) < 0)
+		exit(1);
+
+	/* init apt */
+	if (aptpipe_init() < 0)
+		exit(1);
+
+	/* clean up proc title */
+	setproctitle("%s", "ready");
+
+	/* we're still alive, notify parent */
+	i = 0;
+	write(fds[1], &i, sizeof(int));
+	close(fds[1]);
+
+	/* enter main loop */
+	fd = mainloop(fd);
+
+	/* cleanup */
+	aptpipe_fini();
+	unlink(APT_PIPE_PATH);
+	if (fd)
+		write(fd, &i, sizeof(int));
+	exit(EXIT_SUCCESS);
+}
+
+/* ----------------------------------------------------------------------------
+   client
+*/
+static int do_connect()
+{
+	int sock;
+	struct sockaddr_un servaddr;
+
+	if ((sock = socket(AF_LOCAL, SOCK_STREAM, 0)) < 0)
+		return sock;
+
+	memset(&servaddr, 0, sizeof(servaddr));
+	servaddr.sun_family = AF_LOCAL;
+	strncpy(servaddr.sun_path, APT_PIPE_PATH, sizeof(servaddr.sun_path));
+	for(;;) {
+		if (connect(sock, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0) {
+			/* ENOENT ECONNREFUSED : (re)spawn daemon */
+			if (errno == ENOENT || errno == ECONNREFUSED) {
+				if (daemonize() < 0) {
+					fprintf(stderr, "daemonize(): %s\n", strerror(errno));
+					exit(1);
+				}
+				continue;
+			} else {
+				/* EACCESS etc -- just die */
+				fprintf(stderr, "connect(): %s\n", strerror(errno));
+				exit(1);
+			}
+		}
+		break;
+	}
+
+	return sock;
+}
+
+static ssize_t send_query(int fd, int ac, char *av[])
+{
+	int i;
+	struct msghdr msg;
+	struct iovec *iov = NULL;
+
+	union {
+		struct cmsghdr cm;
+		char control[CMSG_SPACE(sizeof(int))];
+	} control_un;
+	struct cmsghdr	*cmsg;
+
+	msg.msg_name = NULL;
+	msg.msg_namelen = 0;
+
+	if ((iov = (struct iovec *)calloc(ac, sizeof(struct iovec))) == NULL)
+		return -1;
+
+	msg.msg_iov = iov;
+	msg.msg_iovlen = ac;
+
+	for (i=0; i < ac; iov++, i++) {
+		iov->iov_base = (void *)av[i];
+		iov->iov_len = strlen(av[i]) + 1;
+	}
+
+	/* keep final 0 for a while */
+	(--iov)->iov_len--;
+
+	msg.msg_control = NULL;
+	msg.msg_controllen = 0;
+
+	if (sendmsg(fd, &msg, 0) < 0)
+		return -1;
+
+	/* pass fd and final 0 */
+	i = 0;
+	iov = msg.msg_iov;
+	iov->iov_base = &i;
+	iov->iov_len = 1;
+	msg.msg_iovlen = 1;
+	
+	msg.msg_control = control_un.control;
+	msg.msg_controllen = sizeof(control_un.control);
+
+	cmsg = CMSG_FIRSTHDR(&msg);
+	cmsg->cmsg_len = CMSG_LEN(sizeof(int));
+	cmsg->cmsg_level = SOL_SOCKET;
+	cmsg->cmsg_type = SCM_RIGHTS;
+	*((int *) CMSG_DATA(cmsg)) = STDOUT_FILENO;
+
+	return (sendmsg(fd, &msg, 0));
+}
+
+static int recv_reply(int fd)
+{
+	int i;
+
+	if (read(fd, &i, (sizeof(int))) != sizeof(int))
+		return -1;
+	return i;
+}
+
+/*----------------------------------------------------------------------------*/
+int main(int ac, char *av[])
+{
+	int i, fd;
+
+	if (ac < 2) {
+		fprintf(stderr, "usage: %s <query>\n", av[0]);
+		exit(EXIT_FAILURE);
+	}
+
+	if ((fd = do_connect()) < 0) {
+		fprintf(stderr, "do_connect: %s\n", strerror(errno));
+		exit(EXIT_FAILURE);
+	}
+
+	/* pass our query in av[] and stdout fd to server */
+	if (send_query(fd, --ac, ++av) < 0) {
+		fprintf(stderr, "send_query: %s\n", strerror(errno));
+		exit(EXIT_FAILURE);
+	}
+
+	/* wait for status responce
+	   actual server reply will be passed via passed stdout */
+	if ((i = recv_reply(fd)) < 0) {
+		fprintf(stderr, "recv_reply\n");
+		exit(EXIT_FAILURE);
+	}
+
+	return i;
+}
--- apt-0.5.15cnc6/cmdline/apt-shell.cc..pipe	2005-06-27 22:09:57 +0400
+++ apt-0.5.15cnc6/cmdline/apt-shell.cc	2005-06-27 22:09:57 +0400
@@ -1,4 +1,4 @@
-// -*- mode: cpp; mode: fold -*-
+// -*- mode: c++; mode: folding -*-
 // Description								/*{{{*/
 // $Id: apt-get.cc,v 1.126 2003/02/12 16:14:08 doogie Exp $
 /* ######################################################################
@@ -65,8 +65,10 @@
 #include <regex.h>
 #include <sys/wait.h>
 
+#ifndef APT_PIPE
 #include <readline/readline.h>
 #include <readline/history.h>
+#endif
 #include <fnmatch.h>
 									/*}}}*/
 
@@ -3724,9 +3726,7 @@
         return true;
    return _error->Error(_("No packages found"));
 }
-									/*}}}*/
-// --- End of stuff from apt-cache.
-
+/*}}}*/
 
 // ShowHelp - Show a help screen					/*{{{*/
 // ---------------------------------------------------------------------
@@ -4105,6 +4105,7 @@
 }
 									/*}}}*/
 
+#ifndef APT_PIPE
 // ReadLine* - readline library stuff					/*{{{*/
 // ---------------------------------------------------------------------
 /* */
@@ -4272,6 +4273,7 @@
       write_history(History.c_str());
 }
 									/*}}}*/
+#endif
 
 CommandLine::Args *CommandArgs(const char *Name)
 {
@@ -4392,6 +4394,138 @@
    }
 }
 									/*}}}*/
+
+#ifdef APT_PIPE
+bool DumpConfig(CommandLine &CmdL)
+{
+	_config->Dump(cout);
+	return true;
+}
+
+bool DoErrors(CommandLine &CmdL)
+{
+	if (_error->empty() == false) {
+		_error->DumpErrors();
+	}
+
+	return true;
+}
+
+extern "C" {
+	int aptpipe_init(void);
+	int aptpipe_main(int ac, const char *av[]);
+	int aptpipe_fini(void);
+}
+
+int aptpipe_init(void)
+{
+	// initialize config
+	CommandLine CmdL(CommandArgs(""), _config);
+
+	// Setup the output streams
+	c0out.rdbuf(devnull.rdbuf());
+	c1out.rdbuf(cout.rdbuf());
+	c2out.rdbuf(cout.rdbuf());
+
+	// Initialize the package library
+	if (pkgInitConfig(*_config) == false ||
+		pkgInitSystem(*_config, _system) == false) {
+		_error->DumpErrors();
+		return 100;
+	}
+
+	// add our nasty defaults
+	_config->Set("Acquire::CDROM::Copy", "false");
+	_config->Set("Acquire::CDROM::Copy-All", "false");
+
+	// Prepare the cache
+	GCache = new CacheFile();
+	GCache->Open();
+
+	if (_error->empty() == false) {
+		bool Errors = _error->PendingError();
+		_error->DumpErrors();
+		return Errors == true?100:0;
+	}
+
+	// TODO check for unmets
+
+#ifdef WITH_LUA
+	_lua->SetDepCache(*GCache);
+	_lua->RunScripts("Scripts::AptShell::Init");
+	_lua->ResetCaches();
+	bool HasCmdScripts = (_lua->HasScripts("Scripts::AptGet::Command") ||
+						  _lua->HasScripts("Scripts::AptCache::Command"));
+#endif
+
+	return 0;
+}
+
+int aptpipe_main(int ac, const char *av[])
+{
+	int rc;
+	CommandLine::Dispatch Cmds[] = {
+		{"update", &DoUpdate},
+		{"upgrade", &DoUpgrade},
+		{"install", &DoInstall},
+		{"remove", &DoInstall},
+		{"keep", &DoInstall},
+		{"dist-upgrade", &DoDistUpgrade},
+		{"dselect-upgrade", &DoDSelectUpgrade},
+		{"build-dep", &DoBuildDep},
+		{"clean", &DoClean},
+		{"autoclean", &DoAutoClean},
+		{"check", &DoCheck},
+		{"help", &ShowHelp},
+		{"commit", &DoCommit},
+		{"quit", &DoQuit},
+		{"exit", &DoQuit},
+		{"status", &DoStatus},
+		{"script", &DoScript},
+		{"errors", &DoErrors},
+		// apt-cache
+		{"showpkg", &DumpPackage},
+		{"unmet", &UnMet},
+		{"search", &Search},
+		{"list", &DoList},
+		{"ls", &DoList},
+		{"depends", &Depends},
+		{"whatdepends", &WhatDepends},
+		{"rdepends", &RDepends},
+		{"show", &ShowPackage},
+		// apt-config
+		{"dumpconfig", &DumpConfig},
+		{0, 0}
+	};
+
+	// Make our own copy of the configuration.
+	Configuration _Config(*_config);
+
+	delete _config;
+	_config = new Configuration(_Config);
+
+	// Parse skips av[0]
+	CommandLine CmdL(CommandArgs(av[1]), _config);
+	CmdL.Parse(ac, av);
+	CmdL.DispatchArg(Cmds);
+
+	rc = (_error->PendingError() == false ?
+		  ((_config->FindB("quit") == true) ? 1 : 0) : -1);
+
+	// restore saved config
+	delete _config;
+	_config = new Configuration(_Config);
+
+	return rc;
+}
+
+int aptpipe_fini()
+{
+   delete GCache;
+   return 0;
+}
+
+#else
 int main(int argc,const char *argv[])
 {
    CommandLine::Dispatch Cmds[] = {{"update",&DoUpdate},
@@ -4610,5 +4744,5 @@
    
    return 0;   
 }
-
+#endif
 // vim:sts=3:sw=3
--- apt-0.5.15cnc6/cmdline/Makefile.am..pipe	2005-06-27 22:09:57 +0400
+++ apt-0.5.15cnc6/cmdline/Makefile.am	2005-06-27 22:09:57 +0400
@@ -4,7 +4,7 @@
 bin_PROGRAMS = apt-get apt-cache apt-cdrom apt-config
 
 if COMPILE_APTSHELL
-bin_PROGRAMS += apt-shell
+bin_PROGRAMS += apt-shell apt-pipe
 endif
 if COMPILE_STATIC
 bin_PROGRAMS += apt-get-static apt-cache-static apt-cdrom-static
@@ -16,6 +16,9 @@
 apt_cache_SOURCES = apt-cache.cc
 apt_shell_SOURCES = apt-shell.cc acqprogress.cc acqprogress.h
 apt_shell_LDADD = $(LDADD) -lreadline
+apt_pipe_SOURCES = $(apt_shell_SOURCES) apt-pipe.c
+apt_pipe_CPPFLAGS = -DAPT_PIPE
+apt_pipe_LDADD = $(LDADD) -lsetproctitle
 apt_config_SOURCES = apt-config.cc
 apt_cdrom_SOURCES = apt-cdrom.cc rpmindexcopy.cc rpmindexcopy.h
 
 
дизайн и разработка: Vladimir Lettiev aka crux © 2004-2005, Andrew Avramenko aka liks © 2007-2008
текущий майнтейнер: Michael Shigorin