Initial revision
authorewt <devnull@localhost>
Tue, 15 Oct 1996 03:15:52 +0000 (03:15 +0000)
committerewt <devnull@localhost>
Tue, 15 Oct 1996 03:15:52 +0000 (03:15 +0000)
CVS patchset: 1098
CVS date: 1996/10/15 03:15:52

lib/tread.c [new file with mode: 0644]
lib/tread.h [new file with mode: 0644]
url.c [new file with mode: 0644]
url.h [new file with mode: 0644]

diff --git a/lib/tread.c b/lib/tread.c
new file mode 100644 (file)
index 0000000..cf1525b
--- /dev/null
@@ -0,0 +1,35 @@
+#include <sys/time.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include "tread.h"
+
+int timedRead(int fd, void * bufptr, int length) {
+    int bytesRead;
+    int total = 0;
+    char * buf = bufptr;
+    struct fd_set readSet;
+    struct timeval tv;
+
+    while  (total < length) {
+       FD_ZERO(&readSet);
+       FD_SET(fd, &readSet);
+
+       tv.tv_sec = 5;                  /* FIXME: this should be configurable */
+       tv.tv_usec = 0;
+
+       if (select(fd + 1, &readSet, NULL, NULL, &tv) != 1) 
+           return total;
+
+       bytesRead = read(fd, buf + total, length - total);
+
+       if (bytesRead < 0)
+           return bytesRead;
+       else if (bytesRead == 0) 
+           return total;
+
+       total += bytesRead;
+    }
+
+    return length;
+}
diff --git a/lib/tread.h b/lib/tread.h
new file mode 100644 (file)
index 0000000..b172583
--- /dev/null
@@ -0,0 +1,6 @@
+#ifndef H_TREAD
+#define H_TREAD
+
+int timedRead(int fd, void * bufptr, int length);
+
+#endif
diff --git a/url.c b/url.c
new file mode 100644 (file)
index 0000000..78de69b
--- /dev/null
+++ b/url.c
@@ -0,0 +1,207 @@
+#include <alloca.h>
+#include <fcntl.h>
+#include <pwd.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "ftp.h"
+#include "messages.h"
+#include "rpmlib.h"
+#include "url.h"
+
+struct pwcacheEntry {
+    char * machine;
+    char * account;
+    char * pw;
+} ;
+
+static char * getFtpPassword(char * machine, char * account, int mustAsk);
+static int urlFtpLogin(char * url, char ** fileNamePtr);
+static int urlFtpSplit(char * url, char ** user, char ** pw, char ** host, 
+               char ** path);
+
+static char * getFtpPassword(char * machine, char * account, int mustAsk) {
+    static struct pwcacheEntry * pwCache = NULL;
+    static int pwCount = 0;
+    int i;
+    char * prompt;
+
+    for (i = 0; i < pwCount; i++) {
+       if (!strcmp(pwCache[i].machine, machine) &&
+           !strcmp(pwCache[i].account, account))
+               break;
+    }
+
+    if (i < pwCount && !mustAsk) {
+       return pwCache[i].pw;
+    } else if (i == pwCount) {
+       pwCount++;
+       if (pwCache)
+           pwCache = realloc(pwCache, sizeof(*pwCache) * pwCount);
+       else
+           pwCache = malloc(sizeof(*pwCache));
+
+       pwCache[i].machine = strdup(machine);
+       pwCache[i].account = strdup(account);
+    } else
+       free(pwCache[i].pw);
+
+    prompt = alloca(strlen(machine) + strlen(account) + 50);
+    sprintf(prompt, "Password for %s@%s: ", account, machine);
+
+    pwCache[i].pw = strdup(getpass(prompt));
+
+    return pwCache[i].pw;
+}
+
+static int urlFtpSplit(char * url, char ** user, char ** pw, char ** host, 
+               char ** path) {
+    char * chptr, * machineName, * fileName;
+    char * userName = NULL;
+    char * password = NULL;
+
+    url += 6;                  /* skip ftp:// */
+
+    chptr = url;
+    while (*chptr && (*chptr != '/')) chptr++;
+    if (!*chptr) return -1;
+
+    machineName = url;         /* could still have user:pass@ though */
+    fileName = chptr;
+
+    *path = strdup(chptr);
+    *chptr = '\0';
+
+    chptr = fileName;
+    while (chptr > url && *chptr != '@') chptr--;
+    if (chptr > url) {         /* we have a username */
+       *chptr = '\0';
+       userName = machineName;
+       machineName = chptr + 1;
+       
+       chptr = userName;
+       while (*chptr && *chptr != ':') chptr++;
+       if (*chptr) {           /* we have a password */
+           *chptr = '\0';
+           password = chptr + 1;
+       }
+    }
+       
+    if (userName && !password) {
+       password = getFtpPassword(machineName, userName, 0);
+    } 
+
+    if (userName)
+       *user = strdup(userName);
+
+    if (password)
+       *pw = strdup(password);
+
+    *host = strdup(machineName);
+
+    return 0;
+}
+
+static int urlFtpLogin(char * url, char ** fileNamePtr) {
+    char * buf;
+    char * machineName, * fileName;
+    char * userName = NULL;
+    char * password = NULL;
+    char * proxy;
+    int ftpconn;
+   
+    message(MESS_DEBUG, "getting %s via anonymous ftp\n", url);
+
+    buf = alloca(strlen(url) + 1);
+    strcpy(buf, url);
+
+    urlFtpSplit(buf, &userName, &password, &machineName, &fileName);
+
+    message(MESS_DEBUG, "logging into %s as %s, pw %s\n", machineName,
+               userName ? userName : "ftp", 
+               password ? password : "(username)");
+
+    proxy = getVar(RPMVAR_FTPPROXY);
+
+    ftpconn = ftpOpen(machineName, userName, password, proxy);
+
+    free(machineName);
+    free(userName);
+    free(password);
+
+    if (ftpconn < 0) {
+       free(fileName);
+       return ftpconn;
+    }
+
+    *fileNamePtr = fileName;
+
+    return ftpconn;
+}
+
+int urlGetFd(char * url, struct urlContext * context) {
+    char * fileName;
+    int fd;
+
+    message(MESS_DEBUG, "getting %s via anonymous ftp\n", url);
+
+    if ((context->ftpControl = urlFtpLogin(url, &fileName)) < 0) 
+       return context->ftpControl;
+
+    fd = ftpGetFileDesc(context->ftpControl, fileName);
+
+    free(fileName);
+
+    if (fd < 0) ftpClose(context->ftpControl);
+
+    return fd;
+}
+
+int urlFinishedFd(struct urlContext * context) {
+    ftpClose(context->ftpControl);
+
+    return 0;
+}
+
+int urlGetFile(char * url, char * dest) {
+    char * fileName;
+    int ftpconn;
+    int rc;
+    int fd;
+
+    message(MESS_DEBUG, "getting %s via anonymous ftp\n", url);
+
+    if ((ftpconn = urlFtpLogin(url, &fileName)) < 0) return ftpconn;
+
+    fd = creat(dest, 0600);
+
+    if (fd < 0) {
+       message(MESS_DEBUG, "failed to create %s\n", dest);
+       ftpClose(ftpconn);
+       free(fileName);
+       return FTPERR_UNKNOWN;
+    }
+
+    if ((rc = ftpGetFile(ftpconn, fileName, fd))) {
+       free(fileName);
+       unlink(dest);
+       close(fd);
+       ftpClose(ftpconn);
+       return rc;
+    }    
+
+    free(fileName);
+
+    ftpClose(ftpconn);
+
+    return fd;
+}
+
+int urlIsURL(char * url) {
+    if (!strncmp(url, "ftp://", 6)) return 1;
+
+    return 0;
+}
diff --git a/url.h b/url.h
new file mode 100644 (file)
index 0000000..5403b19
--- /dev/null
+++ b/url.h
@@ -0,0 +1,17 @@
+#ifndef H_URL
+#define H_URL
+
+#include "ftp.h"
+
+/* right now, only ftp type URL's are supported */
+
+struct urlContext {
+    int ftpControl;
+};
+
+int urlIsURL(char * url);
+int urlGetFile(char * url, char * dest);
+int urlGetFd(char * url, struct urlContext * context);
+int urlFinishedFd(struct urlContext * context);
+
+#endif