1/*	$NetBSD: update.c,v 1.8 2002/06/06 21:45:20 itojun Exp $	*/
2
3 /*
4  * Routines for controlled update/initialization of request structures.
5  *
6  * request_init() initializes its argument. Pointers and string-valued members
7  * are initialized to zero, to indicate that no lookup has been attempted.
8  *
9  * request_set() adds information to an already initialized request structure.
10  *
11  * Both functions take a variable-length name-value list.
12  *
13  * Diagnostics are reported through syslog(3).
14  *
15  * Author: Wietse Venema, Eindhoven University of Technology, The Netherlands.
16  */
17
18#include <sys/cdefs.h>
19#ifndef lint
20#if 0
21static char sccsid[] = "@(#) update.c 1.1 94/12/28 17:42:56";
22#else
23__RCSID("$NetBSD: update.c,v 1.8 2002/06/06 21:45:20 itojun Exp $");
24#endif
25#endif
26
27/* System libraries */
28
29#include <stdio.h>
30#include <syslog.h>
31#include <string.h>
32#include <unistd.h>
33
34/* Local stuff. */
35
36#include "mystdarg.h"
37#include "tcpd.h"
38
39static struct request_info *request_fill(struct request_info *, va_list);
40
41/* request_fill - request update engine */
42
43static struct request_info *
44request_fill(struct request_info *request, va_list ap)
45{
46    int     key;
47    char   *ptr;
48
49    while ((key = va_arg(ap, int)) > 0) {
50	switch (key) {
51	default:
52	    tcpd_warn("request_fill: invalid key: %d", key);
53	    return (request);
54	case RQ_FILE:
55	    request->fd = va_arg(ap, int);
56	    continue;
57	case RQ_CLIENT_SIN:
58	    request->client->sin = va_arg(ap, struct sockaddr *);
59	    continue;
60	case RQ_SERVER_SIN:
61	    request->server->sin = va_arg(ap, struct sockaddr *);
62	    continue;
63
64	    /*
65	     * All other fields are strings with the same maximal length.
66	     */
67
68	case RQ_DAEMON:
69	    ptr = request->daemon;
70	    break;
71	case RQ_USER:
72	    ptr = request->user;
73	    break;
74	case RQ_CLIENT_NAME:
75	    ptr = request->client->name;
76	    break;
77	case RQ_CLIENT_ADDR:
78	    ptr = request->client->addr;
79	    break;
80	case RQ_SERVER_NAME:
81	    ptr = request->server->name;
82	    break;
83	case RQ_SERVER_ADDR:
84	    ptr = request->server->addr;
85	    break;
86	}
87	strlcpy(ptr, va_arg(ap, char *), STRING_LENGTH);
88    }
89    return (request);
90}
91
92/* request_init - initialize request structure */
93
94struct request_info *VARARGS(request_init, struct request_info *, request)
95{
96    static struct request_info default_info;
97    struct request_info *r;
98    va_list ap;
99
100    /*
101     * Initialize data members. We do not assign default function pointer
102     * members, to avoid pulling in the whole socket module when it is not
103     * really needed.
104     */
105    VASTART(ap, struct request_info *, request);
106    *request = default_info;
107    request->fd = -1;
108    (void)strlcpy(request->daemon, unknown, sizeof(request->daemon));
109    (void)snprintf(request->pid, sizeof(request->pid), "%d", getpid());
110    request->client->request = request;
111    request->server->request = request;
112    r = request_fill(request, ap);
113    VAEND(ap);
114    return (r);
115}
116
117/* request_set - update request structure */
118
119struct request_info *VARARGS(request_set, struct request_info *, request)
120{
121    struct request_info *r;
122    va_list ap;
123
124    VASTART(ap, struct request_info *, request);
125    r = request_fill(request, ap);
126    VAEND(ap);
127    return (r);
128}
129