home *** CD-ROM | disk | FTP | other *** search
/ Chip 1998 February / CHIP_2_98.iso / misc / src / rpm / url.c < prev    next >
C/C++ Source or Header  |  1997-09-17  |  5KB  |  226 lines

  1. #include "miscfn.h"
  2.  
  3. #include <fcntl.h>
  4. #include <pwd.h>
  5. #include <string.h>
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include <unistd.h>
  9.  
  10. #if HAVE_ALLOCA_H
  11. # include <alloca.h>
  12. #endif
  13.  
  14. #include "ftp.h"
  15. #include "messages.h"
  16. #include "miscfn.h"
  17. #include "rpmlib.h"
  18. #include "url.h"
  19.  
  20. struct pwcacheEntry {
  21.     char * machine;
  22.     char * account;
  23.     char * pw;
  24. } ;
  25.  
  26. static char * getFtpPassword(char * machine, char * account, int mustAsk);
  27. static int urlFtpLogin(char * url, char ** fileNamePtr);
  28. static int urlFtpSplit(char * url, char ** user, char ** pw, char ** host, 
  29.         char ** path);
  30.  
  31. static char * getFtpPassword(char * machine, char * account, int mustAsk) {
  32.     static struct pwcacheEntry * pwCache = NULL;
  33.     static int pwCount = 0;
  34.     int i;
  35.     char * prompt;
  36.  
  37.     for (i = 0; i < pwCount; i++) {
  38.     if (!strcmp(pwCache[i].machine, machine) &&
  39.         !strcmp(pwCache[i].account, account))
  40.         break;
  41.     }
  42.  
  43.     if (i < pwCount && !mustAsk) {
  44.     return pwCache[i].pw;
  45.     } else if (i == pwCount) {
  46.     pwCount++;
  47.     if (pwCache)
  48.         pwCache = realloc(pwCache, sizeof(*pwCache) * pwCount);
  49.     else
  50.         pwCache = malloc(sizeof(*pwCache));
  51.  
  52.     pwCache[i].machine = strdup(machine);
  53.     pwCache[i].account = strdup(account);
  54.     } else
  55.     free(pwCache[i].pw);
  56.  
  57.     prompt = alloca(strlen(machine) + strlen(account) + 50);
  58.     sprintf(prompt, "Password for %s@%s: ", account, machine);
  59.  
  60.     pwCache[i].pw = strdup(getpass(prompt));
  61.  
  62.     return pwCache[i].pw;
  63. }
  64.  
  65. static int urlFtpSplit(char * url, char ** user, char ** pw, char ** host, 
  66.         char ** path) {
  67.     char * chptr, * machineName, * fileName;
  68.     char * userName = NULL;
  69.     char * password = NULL;
  70.  
  71.     url += 6;            /* skip ftp:// */
  72.  
  73.     chptr = url;
  74.     while (*chptr && (*chptr != '/')) chptr++;
  75.     if (!*chptr) return -1;
  76.  
  77.     machineName = url;        /* could still have user:pass@ though */
  78.     fileName = chptr;
  79.  
  80.     *path = strdup(chptr);
  81.  
  82.     *chptr = '\0';
  83.  
  84.     chptr = fileName;
  85.     while (chptr > url && *chptr != '@') chptr--;
  86.     if (chptr > url) {        /* we have a username */
  87.     *chptr = '\0';
  88.     userName = machineName;
  89.     machineName = chptr + 1;
  90.     
  91.     chptr = userName;
  92.     while (*chptr && *chptr != ':') chptr++;
  93.     if (*chptr) {        /* we have a password */
  94.         *chptr = '\0';
  95.         password = chptr + 1;
  96.     }
  97.     }
  98.     
  99.     if (userName && !password) {
  100.     password = getFtpPassword(machineName, userName, 0);
  101.     } 
  102.  
  103.     if (userName)
  104.     *user = strdup(userName);
  105.  
  106.     if (password)
  107.     *pw = strdup(password);
  108.  
  109.     *host = strdup(machineName);
  110.  
  111.     return 0;
  112. }
  113.  
  114. static int urlFtpLogin(char * url, char ** fileNamePtr) {
  115.     char * buf;
  116.     char * machineName, * fileName;
  117.     char * userName = NULL;
  118.     char * password = NULL;
  119.     char * proxy;
  120.     char * portStr, * endPtr;
  121.     int port;
  122.     int ftpconn;
  123.    
  124.     rpmMessage(RPMMESS_DEBUG, "getting %s via anonymous ftp\n", url);
  125.  
  126.     buf = alloca(strlen(url) + 1);
  127.     strcpy(buf, url);
  128.  
  129.     urlFtpSplit(buf, &userName, &password, &machineName, &fileName);
  130.  
  131.     rpmMessage(RPMMESS_DEBUG, "logging into %s as %s, pw %s\n", machineName,
  132.         userName ? userName : "ftp", 
  133.         password ? password : "(username)");
  134.  
  135.     proxy = rpmGetVar(RPMVAR_FTPPROXY);
  136.     portStr = rpmGetVar(RPMVAR_FTPPORT);
  137.     if (!portStr) {
  138.     port = -1;
  139.     } else {
  140.     port = strtol(portStr, &endPtr, 0);
  141.     if (*endPtr) {
  142.         fprintf(stderr, "error: ftpport must be a number\n");
  143.         return -1;
  144.     }
  145.     }
  146.  
  147.     ftpconn = ftpOpen(machineName, userName, password, proxy, port);
  148.  
  149.     free(machineName);
  150.     free(userName);
  151.     free(password);
  152.  
  153.     if (ftpconn < 0) {
  154.     free(fileName);
  155.     return ftpconn;
  156.     }
  157.  
  158.     *fileNamePtr = fileName;
  159.  
  160.     return ftpconn;
  161. }
  162.  
  163. int urlGetFd(char * url, struct urlContext * context) {
  164.     char * fileName;
  165.     int fd;
  166.  
  167.     rpmMessage(RPMMESS_DEBUG, "getting %s via anonymous ftp\n", url);
  168.  
  169.     if ((context->ftpControl = urlFtpLogin(url, &fileName)) < 0) 
  170.     return context->ftpControl;
  171.  
  172.     fd = ftpGetFileDesc(context->ftpControl, fileName);
  173.  
  174.     free(fileName);
  175.  
  176.     if (fd < 0) ftpClose(context->ftpControl);
  177.  
  178.     return fd;
  179. }
  180.  
  181. int urlFinishedFd(struct urlContext * context) {
  182.     ftpClose(context->ftpControl);
  183.  
  184.     return 0;
  185. }
  186.  
  187. int urlGetFile(char * url, char * dest) {
  188.     char * fileName;
  189.     int ftpconn;
  190.     int rc;
  191.     int fd;
  192.  
  193.     rpmMessage(RPMMESS_DEBUG, "getting %s via anonymous ftp\n", url);
  194.  
  195.     if ((ftpconn = urlFtpLogin(url, &fileName)) < 0) return ftpconn;
  196.  
  197.     fd = creat(dest, 0600);
  198.  
  199.     if (fd < 0) {
  200.     rpmMessage(RPMMESS_DEBUG, "failed to create %s\n", dest);
  201.     ftpClose(ftpconn);
  202.     free(fileName);
  203.     return FTPERR_UNKNOWN;
  204.     }
  205.  
  206.     if ((rc = ftpGetFile(ftpconn, fileName, fd))) {
  207.     free(fileName);
  208.     unlink(dest);
  209.     close(fd);
  210.     ftpClose(ftpconn);
  211.     return rc;
  212.     }    
  213.  
  214.     free(fileName);
  215.  
  216.     ftpClose(ftpconn);
  217.  
  218.     return rc;
  219. }
  220.  
  221. int urlIsURL(char * url) {
  222.     if (!strncmp(url, "ftp://", 6)) return 1;
  223.  
  224.     return 0;
  225. }
  226.