1 /* $NetBSD: update.c,v 1.9 2012/03/21 10:10:37 matt 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 21 static char sccsid[] = "@(#) update.c 1.1 94/12/28 17:42:56"; 22 #else 23 __RCSID("$NetBSD: update.c,v 1.9 2012/03/21 10:10:37 matt 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 39 static struct request_info *request_fill(struct request_info *, va_list); 40 41 /* request_fill - request update engine */ 42 43 static struct request_info * request_fill(struct request_info * request,va_list ap)44 request_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 VARARGS(request_init,struct request_info *,request)94 struct 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 VARARGS(request_set,struct request_info *,request)119 struct 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