diff --git a/libexec/ftpd/ftpd.c b/libexec/ftpd/ftpd.c index 6b6fc5dea051..431949506a36 100644 --- a/libexec/ftpd/ftpd.c +++ b/libexec/ftpd/ftpd.c @@ -651,10 +651,12 @@ sigquit(int signo) static void inithosts(void) { + int insert; size_t len; FILE *fp; char *cp, *mp, *line; char *hostname; + char *vhost, *anonuser, *statfile, *welcome, *loginmsg; struct ftphost *hrp, *lhrp; struct addrinfo hints, *res, *ai; @@ -708,11 +710,46 @@ inithosts(void) /* skip empty lines */ if (cp == NULL) goto nextline; + vhost = cp; + + /* set defaults */ + anonuser = "ftp"; + statfile = _PATH_FTPDSTATFILE; + welcome = _PATH_FTPWELCOME; + loginmsg = _PATH_FTPLOGINMESG; + + /* + * Preparse the line so we can use its info + * for all the addresses associated with + * the virtual host name. + * Field 0, the virtual host name, is special: + * it's already parsed off and will be strdup'ed + * later, after we know its canonical form. + */ + for (i = 1; i < 5 && (cp = strtok(NULL, " \t")); i++) + if (*cp != '-' && (cp = strdup(cp))) + switch (i) { + case 1: /* anon user permissions */ + anonuser = cp; + break; + case 2: /* statistics file */ + statfile = cp; + break; + case 3: /* welcome message */ + welcome = cp; + break; + case 4: /* login message */ + loginmsg = cp; + break; + default: /* programming error */ + abort(); + /* NOTREACHED */ + } hints.ai_flags = 0; hints.ai_family = AF_UNSPEC; hints.ai_flags = AI_PASSIVE; - error = getaddrinfo(cp, NULL, &hints, &res); + error = getaddrinfo(vhost, NULL, &hints, &res); if (error != NULL) goto nextline; for (ai = res; ai != NULL && ai->ai_addr != NULL; @@ -737,15 +774,9 @@ inithosts(void) if (hrp == NULL) { if ((hrp = malloc(sizeof(struct ftphost))) == NULL) goto nextline; - /* defaults */ - hrp->statfile = _PATH_FTPDSTATFILE; - hrp->welcome = _PATH_FTPWELCOME; - hrp->loginmsg = _PATH_FTPLOGINMESG; - hrp->anonuser = "ftp"; - hrp->next = NULL; - lhrp->next = hrp; - lhrp = hrp; - } + insert = 1; + } else + insert = 0; /* host already in the chain */ hrp->hostinfo = res; /* @@ -774,44 +805,31 @@ inithosts(void) if ((hp = getipnodebyaddr((char*)addr, addrsize, hrp->hostinfo->ai_family, &hp_error)) != NULL) { - if (strcmp(cp, hp->h_name) != 0) { + if (strcmp(vhost, hp->h_name) != 0) { if (hp->h_aliases == NULL) - cp = hp->h_name; + vhost = hp->h_name; else { i = 0; while (hp->h_aliases[i] && - strcmp(cp, hp->h_aliases[i]) != 0) + strcmp(vhost, hp->h_aliases[i]) != 0) ++i; if (hp->h_aliases[i] == NULL) - cp = hp->h_name; + vhost = hp->h_name; } } } - hrp->hostname = strdup(cp); + if ((hrp->hostname = strdup(vhost)) == NULL) + goto nextline; + hrp->anonuser = anonuser; + hrp->statfile = statfile; + hrp->welcome = welcome; + hrp->loginmsg = loginmsg; + if (insert) { + hrp->next = NULL; + lhrp->next = hrp; + lhrp = hrp; + } freehostent(hp); - /* ok, now we now peel off the rest */ - i = 0; - while (i < 4 && (cp = strtok(NULL, " \t")) != NULL) { - if (*cp != '-' && (cp = strdup(cp)) != NULL) { - switch (i) { - case 0: /* anon user permissions */ - hrp->anonuser = cp; - break; - case 1: /* statistics file */ - hrp->statfile = cp; - break; - case 2: /* welcome message */ - hrp->welcome = cp; - break; - case 3: /* login message */ - hrp->loginmsg = cp; - break; - } - } - ++i; - } - /* XXX: re-initialization for getaddrinfo() loop */ - cp = strtok(line, " \t"); } nextline: if (mp)