From 4f6655c287738665b16dc5103a3e68c5939d900c Mon Sep 17 00:00:00 2001 From: ewt Date: Tue, 15 Oct 1996 03:15:52 +0000 Subject: [PATCH] Initial revision CVS patchset: 1098 CVS date: 1996/10/15 03:15:52 --- lib/tread.c | 35 ++++++++++ lib/tread.h | 6 ++ url.c | 207 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ url.h | 17 +++++ 4 files changed, 265 insertions(+) create mode 100644 lib/tread.c create mode 100644 lib/tread.h create mode 100644 url.c create mode 100644 url.h diff --git a/lib/tread.c b/lib/tread.c new file mode 100644 index 0000000..cf1525b --- /dev/null +++ b/lib/tread.c @@ -0,0 +1,35 @@ +#include +#include +#include + +#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 index 0000000..b172583 --- /dev/null +++ b/lib/tread.h @@ -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 index 0000000..78de69b --- /dev/null +++ b/url.c @@ -0,0 +1,207 @@ +#include +#include +#include +#include +#include +#include +#include + +#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 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 -- 2.7.4