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, "\nftp> %s", 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, "ftp -detv %s\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