home *** CD-ROM | disk | FTP | other *** search
- #include "miscfn.h"
-
- #include <fcntl.h>
- #include <pwd.h>
- #include <string.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <unistd.h>
-
- #if HAVE_ALLOCA_H
- # include <alloca.h>
- #endif
-
- #include "ftp.h"
- #include "messages.h"
- #include "miscfn.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;
- char * portStr, * endPtr;
- int port;
- int ftpconn;
-
- rpmMessage(RPMMESS_DEBUG, "getting %s via anonymous ftp\n", url);
-
- buf = alloca(strlen(url) + 1);
- strcpy(buf, url);
-
- urlFtpSplit(buf, &userName, &password, &machineName, &fileName);
-
- rpmMessage(RPMMESS_DEBUG, "logging into %s as %s, pw %s\n", machineName,
- userName ? userName : "ftp",
- password ? password : "(username)");
-
- proxy = rpmGetVar(RPMVAR_FTPPROXY);
- portStr = rpmGetVar(RPMVAR_FTPPORT);
- if (!portStr) {
- port = -1;
- } else {
- port = strtol(portStr, &endPtr, 0);
- if (*endPtr) {
- fprintf(stderr, "error: ftpport must be a number\n");
- return -1;
- }
- }
-
- ftpconn = ftpOpen(machineName, userName, password, proxy, port);
-
- 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;
-
- rpmMessage(RPMMESS_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;
-
- rpmMessage(RPMMESS_DEBUG, "getting %s via anonymous ftp\n", url);
-
- if ((ftpconn = urlFtpLogin(url, &fileName)) < 0) return ftpconn;
-
- fd = creat(dest, 0600);
-
- if (fd < 0) {
- rpmMessage(RPMMESS_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 rc;
- }
-
- int urlIsURL(char * url) {
- if (!strncmp(url, "ftp://", 6)) return 1;
-
- return 0;
- }
-