Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/usr.bin/ftp more refactoring:



details:   https://anonhg.NetBSD.org/src/rev/1f7724c4e74c
branches:  trunk
changeset: 342325:1f7724c4e74c
user:      christos <christos%NetBSD.org@localhost>
date:      Wed Dec 16 19:17:16 2015 +0000

description:
more refactoring:
        - introduce authinfo and urlinfo structures
        - split negotiation code out.

diffstat:

 usr.bin/ftp/fetch.c |  1105 ++++++++++++++++++++++++++++----------------------
 1 files changed, 609 insertions(+), 496 deletions(-)

diffs (truncated from 1502 to 300 lines):

diff -r fdc88b9c5972 -r 1f7724c4e74c usr.bin/ftp/fetch.c
--- a/usr.bin/ftp/fetch.c       Wed Dec 16 18:54:03 2015 +0000
+++ b/usr.bin/ftp/fetch.c       Wed Dec 16 19:17:16 2015 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: fetch.c,v 1.213 2015/12/16 01:20:05 nonaka Exp $       */
+/*     $NetBSD: fetch.c,v 1.214 2015/12/16 19:17:16 christos Exp $     */
 
 /*-
  * Copyright (c) 1997-2015 The NetBSD Foundation, Inc.
@@ -37,7 +37,7 @@
 
 #include <sys/cdefs.h>
 #ifndef lint
-__RCSID("$NetBSD: fetch.c,v 1.213 2015/12/16 01:20:05 nonaka Exp $");
+__RCSID("$NetBSD: fetch.c,v 1.214 2015/12/16 19:17:16 christos Exp $");
 #endif /* not lint */
 
 /*
@@ -80,19 +80,35 @@
        CLASSIC_URL_T
 } url_t;
 
+struct authinfo {
+       char *auth;
+       char *user;
+       char *pass;
+};
+
+struct urlinfo {
+       char *host;
+       char *port;
+       char *path;
+       url_t utype;
+       in_port_t portnum;
+};
+
 __dead static void     aborthttp(int);
 __dead static void     timeouthttp(int);
 #ifndef NO_AUTH
-static int     auth_url(const char *, char **, const char *, const char *);
+static int     auth_url(const char *, char **, const struct authinfo *);
 static void    base64_encode(const unsigned char *, size_t, unsigned char *);
 #endif
 static int     go_fetch(const char *);
 static int     fetch_ftp(const char *);
 static int     fetch_url(const char *, const char *, char *, char *);
 static const char *match_token(const char **, const char *);
-static int     parse_url(const char *, const char *, url_t *, char **,
-                           char **, char **, char **, in_port_t *, char **);
+static int     parse_url(const char *, const char *, struct urlinfo *,
+    struct authinfo *);
 static void    url_decode(char *);
+static void    freeauthinfo(struct authinfo *);
+static void    freeurlinfo(struct urlinfo *);
 
 static int     redirect_loop;
 
@@ -144,6 +160,38 @@
        return orig;
 }
 
+static void
+initauthinfo(struct authinfo *ai, char *auth)
+{
+       ai->auth = auth;
+       ai->user = ai->pass = 0;
+}
+
+static void
+freeauthinfo(struct authinfo *a)
+{
+       FREEPTR(a->user);
+       if (a->pass != NULL)
+               memset(a->pass, 0, strlen(a->pass));
+       FREEPTR(a->pass);
+}
+
+static void
+initurlinfo(struct urlinfo *ui)
+{
+       ui->host = ui->port = ui->path = 0;
+       ui->utype = UNKNOWN_URL_T;
+       ui->portnum = 0;
+}
+
+static void
+freeurlinfo(struct urlinfo *ui)
+{
+       FREEPTR(ui->host);
+       FREEPTR(ui->port);
+       FREEPTR(ui->path);
+}
+
 #ifndef NO_AUTH
 /*
  * Generate authorization response based on given authentication challenge.
@@ -151,8 +199,7 @@
  * Sets response to a malloc(3)ed string; caller should free.
  */
 static int
-auth_url(const char *challenge, char **response, const char *guser,
-       const char *gpass)
+auth_url(const char *challenge, char **response, const struct authinfo *auth)
 {
        const char      *cp, *scheme, *errormsg;
        char            *ep, *clear, *realm;
@@ -196,8 +243,8 @@
        }
 
        fprintf(ttyout, "Username for `%s': ", realm);
-       if (guser != NULL) {
-               (void)strlcpy(uuser, guser, sizeof(uuser));
+       if (auth->user != NULL) {
+               (void)strlcpy(uuser, auth->user, sizeof(uuser));
                fprintf(ttyout, "%s\n", uuser);
        } else {
                (void)fflush(ttyout);
@@ -206,8 +253,8 @@
                        goto cleanup_auth_url;
                }
        }
-       if (gpass != NULL)
-               upass = gpass;
+       if (auth->pass != NULL)
+               upass = auth->pass;
        else {
                gotpass = getpass("Password: ");
                if (gotpass == NULL) {
@@ -227,7 +274,7 @@
 
                                                /* scheme + " " + enc + "\0" */
        rlen = strlen(scheme) + 1 + (clen + 2) * 4 / 3 + 1;
-       *response = (char *)ftp_malloc(rlen);
+       *response = ftp_malloc(rlen);
        (void)strlcpy(*response, scheme, rlen);
        len = strlcat(*response, " ", rlen);
                        /* use  `clen - 1'  to not encode the trailing NUL */
@@ -326,57 +373,47 @@
  *     "ftp://host/dir/file";           "dir/file"
  *     "ftp://host//dir/file";          "/dir/file"
  */
+
 static int
-parse_url(const char *url, const char *desc, url_t *utype,
-               char **uuser, char **pass, char **host, char **port,
-               in_port_t *portnum, char **path)
+parse_url(const char *url, const char *desc, struct urlinfo *ui,
+    struct authinfo *auth) 
 {
        const char      *origurl, *tport;
        char            *cp, *ep, *thost;
        size_t           len;
 
-       if (url == NULL || desc == NULL || utype == NULL || uuser == NULL
-           || pass == NULL || host == NULL || port == NULL || portnum == NULL
-           || path == NULL)
+       if (url == NULL || desc == NULL || ui == NULL || auth == NULL)
                errx(1, "parse_url: invoked with NULL argument!");
        DPRINTF("parse_url: %s `%s'\n", desc, url);
 
        origurl = url;
-       *utype = UNKNOWN_URL_T;
-       *uuser = *pass = *host = *port = *path = NULL;
-       *portnum = 0;
        tport = NULL;
 
        if (STRNEQUAL(url, HTTP_URL)) {
                url += sizeof(HTTP_URL) - 1;
-               *utype = HTTP_URL_T;
-               *portnum = HTTP_PORT;
+               ui->utype = HTTP_URL_T;
+               ui->portnum = HTTP_PORT;
                tport = httpport;
        } else if (STRNEQUAL(url, FTP_URL)) {
                url += sizeof(FTP_URL) - 1;
-               *utype = FTP_URL_T;
-               *portnum = FTP_PORT;
+               ui->utype = FTP_URL_T;
+               ui->portnum = FTP_PORT;
                tport = ftpport;
        } else if (STRNEQUAL(url, FILE_URL)) {
                url += sizeof(FILE_URL) - 1;
-               *utype = FILE_URL_T;
+               ui->utype = FILE_URL_T;
 #ifdef WITH_SSL
        } else if (STRNEQUAL(url, HTTPS_URL)) {
                url += sizeof(HTTPS_URL) - 1;
-               *utype = HTTPS_URL_T;
-               *portnum = HTTPS_PORT;
+               ui->utype = HTTPS_URL_T;
+               ui->portnum = HTTPS_PORT;
                tport = httpsport;
 #endif
        } else {
                warnx("Invalid %s `%s'", desc, url);
  cleanup_parse_url:
-               FREEPTR(*uuser);
-               if (*pass != NULL)
-                       memset(*pass, 0, strlen(*pass));
-               FREEPTR(*pass);
-               FREEPTR(*host);
-               FREEPTR(*port);
-               FREEPTR(*path);
+               freeauthinfo(auth);
+               freeurlinfo(ui);
                return (-1);
        }
 
@@ -391,26 +428,26 @@
                len = ep - url;
                thost = (char *)ftp_malloc(len + 1);
                (void)strlcpy(thost, url, len + 1);
-               if (*utype == FTP_URL_T)        /* skip first / for ftp URLs */
+               if (ui->utype == FTP_URL_T)     /* skip first / for ftp URLs */
                        ep++;
-               *path = ftp_strdup(ep);
+               ui->path = ftp_strdup(ep);
        }
 
        cp = strchr(thost, '@');        /* look for user[:pass]@ in URLs */
        if (cp != NULL) {
-               if (*utype == FTP_URL_T)
+               if (ui->utype == FTP_URL_T)
                        anonftp = 0;    /* disable anonftp */
-               *uuser = thost;
+               auth->user = thost;
                *cp = '\0';
                thost = ftp_strdup(cp + 1);
-               cp = strchr(*uuser, ':');
+               cp = strchr(auth->user, ':');
                if (cp != NULL) {
                        *cp = '\0';
-                       *pass = ftp_strdup(cp + 1);
+                       auth->pass = ftp_strdup(cp + 1);
                }
-               url_decode(*uuser);
-               if (*pass)
-                       url_decode(*pass);
+               url_decode(auth->user);
+               if (auth->pass)
+                       url_decode(auth->pass);
        }
 
 #ifdef INET6
@@ -444,7 +481,7 @@
 #endif /* INET6 */
                if ((cp = strchr(thost, ':')) != NULL)
                        *cp++ = '\0';
-       *host = thost;
+       ui->host = thost;
 
                        /* look for [:port] */
        if (cp != NULL) {
@@ -457,24 +494,24 @@
                            cp, desc, origurl);
                        goto cleanup_parse_url;
                }
-               *portnum = nport;
+               ui->portnum = nport;
                tport = cp;
        }
 
        if (tport != NULL)
-               *port = ftp_strdup(tport);
-       if (*path == NULL) {
+               ui->port = ftp_strdup(tport);
+       if (ui->path == NULL) {
                const char *emptypath = "/";
-               if (*utype == FTP_URL_T)        /* skip first / for ftp URLs */
+               if (ui->utype == FTP_URL_T)     /* skip first / for ftp URLs */
                        emptypath++;
-               *path = ftp_strdup(emptypath);
+               ui->path = ftp_strdup(emptypath);
        }
 
        DPRINTF("parse_url: user `%s' pass `%s' host %s port %s(%d) "
            "path `%s'\n",
-           STRorNULL(*uuser), STRorNULL(*pass),
-           STRorNULL(*host), STRorNULL(*port),
-           *portnum ? *portnum : -1, STRorNULL(*path));
+           STRorNULL(auth->user), STRorNULL(auth->pass),
+           STRorNULL(ui->host), STRorNULL(ui->port),
+           ui->portnum ? ui->portnum : -1, STRorNULL(ui->path));
 
        return (0);
 }
@@ -482,11 +519,16 @@
 sigjmp_buf     httpabort;
 
 static int
-ftp_socket(const char *host, const char *port, void **ssl)
+ftp_socket(const struct urlinfo *ui, void **ssl)
 {
        struct addrinfo hints, *res, *res0 = NULL;
        int error;
        int s;
+       const char *host = ui->host;
+       const char *port = ui->port;
+
+       if (ui->utype != HTTPS_URL_T)



Home | Main Index | Thread Index | Old Index