144743Smarkm /*
244743Smarkm  * Routines for controlled update/initialization of request structures.
344743Smarkm  *
444743Smarkm  * request_init() initializes its argument. Pointers and string-valued members
544743Smarkm  * are initialized to zero, to indicate that no lookup has been attempted.
644743Smarkm  *
744743Smarkm  * request_set() adds information to an already initialized request structure.
844743Smarkm  *
944743Smarkm  * Both functions take a variable-length name-value list.
1044743Smarkm  *
1144743Smarkm  * Diagnostics are reported through syslog(3).
1244743Smarkm  *
1344743Smarkm  * Author: Wietse Venema, Eindhoven University of Technology, The Netherlands.
1456977Sshin  *
1556977Sshin  * $FreeBSD$
1644743Smarkm  */
1744743Smarkm
1844743Smarkm#ifndef lint
1944743Smarkmstatic char sccsid[] = "@(#) update.c 1.1 94/12/28 17:42:56";
2044743Smarkm#endif
2144743Smarkm
2244743Smarkm/* System libraries */
2344743Smarkm
2444743Smarkm#include <stdio.h>
2544743Smarkm#include <syslog.h>
2644743Smarkm#include <string.h>
2744743Smarkm
2844743Smarkm/* Local stuff. */
2944743Smarkm
3044743Smarkm#include "mystdarg.h"
3144743Smarkm#include "tcpd.h"
3244743Smarkm
3344743Smarkm/* request_fill - request update engine */
3444743Smarkm
3544743Smarkmstatic struct request_info *request_fill(request, ap)
3644743Smarkmstruct request_info *request;
3744743Smarkmva_list ap;
3844743Smarkm{
3944743Smarkm    int     key;
4044743Smarkm    char   *ptr;
4144743Smarkm
4244743Smarkm    while ((key = va_arg(ap, int)) > 0) {
4344743Smarkm	switch (key) {
4444743Smarkm	default:
4544743Smarkm	    tcpd_warn("request_fill: invalid key: %d", key);
4644743Smarkm	    return (request);
4744743Smarkm	case RQ_FILE:
4844743Smarkm	    request->fd = va_arg(ap, int);
4944743Smarkm	    continue;
5044743Smarkm	case RQ_CLIENT_SIN:
5156977Sshin#ifdef INET6
5256977Sshin	    request->client->sin = va_arg(ap, struct sockaddr *);
5356977Sshin#else
5444743Smarkm	    request->client->sin = va_arg(ap, struct sockaddr_in *);
5556977Sshin#endif
5644743Smarkm	    continue;
5744743Smarkm	case RQ_SERVER_SIN:
5856977Sshin#ifdef INET6
5956977Sshin	    request->server->sin = va_arg(ap, struct sockaddr *);
6056977Sshin#else
6144743Smarkm	    request->server->sin = va_arg(ap, struct sockaddr_in *);
6256977Sshin#endif
6344743Smarkm	    continue;
6444743Smarkm
6544743Smarkm	    /*
6644743Smarkm	     * All other fields are strings with the same maximal length.
6744743Smarkm	     */
6844743Smarkm
6944743Smarkm	case RQ_DAEMON:
7044743Smarkm	    ptr = request->daemon;
7144743Smarkm	    break;
7244743Smarkm	case RQ_USER:
7344743Smarkm	    ptr = request->user;
7444743Smarkm	    break;
7544743Smarkm	case RQ_CLIENT_NAME:
7644743Smarkm	    ptr = request->client->name;
7744743Smarkm	    break;
7844743Smarkm	case RQ_CLIENT_ADDR:
7944743Smarkm	    ptr = request->client->addr;
8044743Smarkm	    break;
8144743Smarkm	case RQ_SERVER_NAME:
8244743Smarkm	    ptr = request->server->name;
8344743Smarkm	    break;
8444743Smarkm	case RQ_SERVER_ADDR:
8544743Smarkm	    ptr = request->server->addr;
8644743Smarkm	    break;
8744743Smarkm	}
8844743Smarkm	STRN_CPY(ptr, va_arg(ap, char *), STRING_LENGTH);
8944743Smarkm    }
9044743Smarkm    return (request);
9144743Smarkm}
9244743Smarkm
9344743Smarkm/* request_init - initialize request structure */
9444743Smarkm
9544743Smarkmstruct request_info *VARARGS(request_init, struct request_info *, request)
9644743Smarkm{
9744743Smarkm    static struct request_info default_info;
9844743Smarkm    struct request_info *r;
9944743Smarkm    va_list ap;
10044743Smarkm
10144743Smarkm    /*
10244743Smarkm     * Initialize data members. We do not assign default function pointer
10344743Smarkm     * members, to avoid pulling in the whole socket module when it is not
10444743Smarkm     * really needed.
10544743Smarkm     */
10644743Smarkm    VASTART(ap, struct request_info *, request);
10744743Smarkm    *request = default_info;
10844743Smarkm    request->fd = -1;
10944743Smarkm    strcpy(request->daemon, unknown);
11044743Smarkm    sprintf(request->pid, "%d", getpid());
11144743Smarkm    request->client->request = request;
11244743Smarkm    request->server->request = request;
11344743Smarkm    r = request_fill(request, ap);
11444743Smarkm    VAEND(ap);
11544743Smarkm    return (r);
11644743Smarkm}
11744743Smarkm
11844743Smarkm/* request_set - update request structure */
11944743Smarkm
12044743Smarkmstruct request_info *VARARGS(request_set, struct request_info *, request)
12144743Smarkm{
12244743Smarkm    struct request_info *r;
12344743Smarkm    va_list ap;
12444743Smarkm
12544743Smarkm    VASTART(ap, struct request_info *, request);
12644743Smarkm    r = request_fill(request, ap);
12744743Smarkm    VAEND(ap);
12844743Smarkm    return (r);
12944743Smarkm}
130