Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/netbsd-1-4]: src/usr.sbin/pkg_install/lib Pull up revisions 1.1-1.9 (new...
details: https://anonhg.NetBSD.org/src/rev/ead6dca6aa72
branches: netbsd-1-4
changeset: 470237:ead6dca6aa72
user: he <he%NetBSD.org@localhost>
date: Mon Jan 31 20:59:28 2000 +0000
description:
Pull up revisions 1.1-1.9 (new, requested by hubertf):
Implement FTP wildcard depends, to give NetBSD full wildcard support
not only in pkgsrc but also for binary packages installed from
local disk or via FTP.
diffstat:
usr.sbin/pkg_install/lib/ftpio.c | 753 +++++++++++++++++++++++++++++++++++++++
1 files changed, 753 insertions(+), 0 deletions(-)
diffs (truncated from 757 to 300 lines):
diff -r 1b9a71af5a0c -r ead6dca6aa72 usr.sbin/pkg_install/lib/ftpio.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/usr.sbin/pkg_install/lib/ftpio.c Mon Jan 31 20:59:28 2000 +0000
@@ -0,0 +1,753 @@
+/* $NetBSD: ftpio.c,v 1.11.2.2 2000/01/31 20:59:28 he Exp $ */
+/* Id: foo2.c,v 1.12 1999/12/17 02:31:57 feyrer Exp feyrer */
+
+/*
+ * Work to implement wildcard dependency processing via FTP for the
+ * NetBSD pkg_* package tools.
+ *
+ * Copyright (c) 1999 Hubert Feyrer <hubertf%netbsd.org@localhost>
+ */
+
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/signal.h>
+#include <assert.h>
+#include <ctype.h>
+#include <err.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <regex.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <vis.h>
+
+#include "../lib/lib.h"
+
+/*
+ * Names of environment variables used to pass things to
+ * subprocesses, for connection caching.
+ */
+#define PKG_FTPIO_COMMAND "PKG_FTPIO_COMMAND"
+#define PKG_FTPIO_ANSWER "PKG_FTPIO_ANSWER"
+#define PKG_FTPIO_CNT "PKG_FTPIO_CNT"
+#define PKG_FTPIO_CURRENTHOST "PKG_FTPIO_CURRENTHOST"
+#define PKG_FTPIO_CURRENTDIR "PKG_FTPIO_CURRENTDIR"
+
+#undef STANDALONE /* define for standalone debugging */
+
+/* File descriptors */
+typedef struct {
+ int command;
+ int answer;
+} fds;
+
+
+#if EXPECT_DEBUG
+static int expect_debug = 1;
+#endif /* EXPECT_DEBUG */
+#ifdef STANDALONE
+int Verbose=1;
+#endif
+static int needclose=0;
+static int ftp_started=0;
+static fds ftpio;
+
+
+/*
+ * expect "str" (a regular expression) on file descriptor "fd", storing
+ * the FTP return code of the command in the integer "ftprc". The "str"
+ * string is expected to match some FTP return codes after a '\n', e.g.
+ * "\n(550|226).*\n"
+ */
+static int
+expect(int fd, const char *str, int *ftprc)
+{
+ int rc;
+ char buf[90];
+#if EXPECT_DEBUG
+ char *vstr;
+#endif /* EXPECT_DEBUG */
+ regex_t rstr;
+ int done;
+ struct timeval timeout;
+ int retval;
+ regmatch_t pmatch;
+ int verbose_expect=0;
+
+#if EXPECT_DEBUG
+ vstr=malloc(2*sizeof(buf));
+ if (vstr == NULL)
+ err(1, "expect: malloc() failed");
+ strvis(vstr, str, VIS_NL|VIS_SAFE|VIS_CSTYLE);
+#endif /* EXPECT_DEBUG */
+
+ if (regcomp(&rstr, str, REG_EXTENDED) != 0)
+ err(1, "expect: regcomp() failed");
+
+#if EXPECT_DEBUG
+ if (expect_debug)
+ printf("expecting \"%s\" on fd %d ...\n", vstr, fd);
+#endif /* EXPECT_DEBUG */
+
+ if(0) setbuf(stdout, NULL);
+
+ memset(buf, '#', sizeof(buf));
+
+ timeout.tv_sec=5*60;
+ timeout.tv_usec=0;
+ done=0;
+ retval=0;
+ while(!done) {
+ fd_set fdset;
+
+ FD_ZERO(&fdset);
+ FD_SET(fd, &fdset);
+ rc = select(FD_SETSIZE, &fdset, NULL, NULL, &timeout);
+ switch (rc) {
+ case -1:
+ warn("expect: select() failed (probably ftp died because of bad args)");
+ done = 1;
+ retval = -1;
+ break;
+ case 0:
+ warnx("expect: select() timeout!");
+ done = 1; /* hope that's ok */
+ retval = -1;
+ break;
+ default:
+ rc=read(fd,&buf[sizeof(buf)-1],1);
+
+ if (verbose_expect)
+ putchar(buf[sizeof(buf)-1]);
+
+#if EXPECT_DEBUG
+ {
+ char *v=malloc(2*sizeof(buf));
+ strvis(v, buf, VIS_NL|VIS_SAFE|VIS_CSTYLE);
+ if (expect_debug)
+ printf("expect=<%s>, buf=<%*s>\n", vstr, strlen(v), v);
+ free(v);
+ }
+#endif /* EXPECT_DEBUG */
+
+ if (regexec(&rstr, buf, 1, &pmatch, 0) == 0) {
+#if EXPECT_DEBUG
+ if (expect_debug)
+ printf("Gotcha -> %s!\n", buf+pmatch.rm_so+1);
+ fflush(stdout);
+#endif /* EXPECT_DEBUG */
+
+ if (ftprc && isdigit(buf[pmatch.rm_so+1]))
+ *ftprc = atoi(buf+pmatch.rm_so+1);
+
+ done=1;
+ retval=0;
+ }
+
+ memmove(buf, buf+1, sizeof(buf)-1); /* yes, this is non-performant */
+ break;
+ }
+ }
+
+#if EXPECT_DEBUG
+ printf("done.\n");
+
+ if (str)
+ free(vstr);
+#endif /* EXPECT_DEBUG */
+
+ return retval;
+}
+
+/*
+ * send a certain ftp-command "cmd" to our FTP coprocess, and wait for
+ * "expectstr" to be returned. Return numeric FTP return code.
+ */
+static int
+ftp_cmd(const char *cmd, const char *expectstr)
+{
+ int rc=0, verbose_ftp=0;
+
+ if (Verbose)
+ verbose_ftp=1;
+
+ if (verbose_ftp)
+ fprintf(stderr, "\n[1mftp> %s[0m", cmd);
+
+ fflush(stdout);
+ rc=write(ftpio.command, cmd, strlen(cmd));
+ if (rc == strlen(cmd)) {
+ if (expectstr) {
+ expect(ftpio.answer, expectstr, &rc);
+ }
+ } else {
+ if (Verbose)
+ warn("short write");
+ }
+
+ return rc;
+}
+
+
+/*
+ * Really fire up FTP coprocess
+ */
+static int
+setupCoproc(const char *base)
+{
+ int command_pipe[2];
+ int answer_pipe[2];
+ int rc1, rc2;
+ char buf[20];
+
+ rc1 = pipe(command_pipe);
+ rc2 = pipe(answer_pipe);
+
+ if(rc1==-1 || rc2==-1) {
+ warn("setupCoproc: pipe() failed");
+ return -1;
+ }
+
+ rc1=fork();
+ switch (rc1) {
+ case -1:
+ /* Error */
+
+ warn("setupCoproc: fork() failed");
+ return -1;
+ break;
+
+ case 0:
+ /* Child */
+
+ close(command_pipe[1]);
+ dup2(command_pipe[0], 0);
+ close(command_pipe[0]);
+
+ close(answer_pipe[0]);
+ dup2(answer_pipe[1], 1);
+ close(answer_pipe[1]);
+
+ setbuf(stdout, NULL);
+
+ if (Verbose)
+ fprintf(stderr, "[1mftp -detv %s[0m\n", base);
+ rc1 = execl("/usr/bin/ftp", "ftp", "-detv", base, NULL);
+ warn("setupCoproc: execl() failed");
+ exit(-1);
+ break;
+ default:
+ /* Parent */
+ close(command_pipe[0]);
+ close(answer_pipe[1]);
+
+ snprintf(buf, sizeof(buf), "%d", command_pipe[1]);
+ setenv(PKG_FTPIO_COMMAND, buf, 1);
+ snprintf(buf, sizeof(buf), "%d", answer_pipe[0]);
+ setenv(PKG_FTPIO_ANSWER, buf, 1);
+
+ ftpio.command = command_pipe[1];
+ ftpio.answer = answer_pipe[0];
+
+ fcntl(ftpio.command, F_SETFL, O_NONBLOCK);
+ fcntl(ftpio.answer , F_SETFL, O_NONBLOCK);
+
+ break;
+ }
+
+ return 0;
+}
+
+
+/*
+ * SIGPIPE only happens when there's something wrong with the FTP
+ * coprocess. In that case, set mark to not try to close shut down
+ * the coprocess.
+ */
+static void
+sigpipe_handler(int n)
+{
+ /* aparently our ftp companion died */
+ if (Verbose)
+ fprintf(stderr, "SIGPIPE!\n");
+ needclose = 0;
+}
+
+
+/*
+ * Close the FTP coprocess' current connection, but
+ * keep the process itself alive.
+ */
+void
+ftp_stop(void)
+{
+ char *tmp1, *tmp2;
+
+ if (!ftp_started)
+ return;
+
+ tmp1=getenv(PKG_FTPIO_COMMAND);
+ tmp2=getenv(PKG_FTPIO_ANSWER);
+
+ /* (Only) the last one closes the link */
+ if (tmp1 != NULL && tmp2 != NULL) {
+ if (needclose)
Home |
Main Index |
Thread Index |
Old Index