irp_pr.c revision 1.1.1.2
1/* $NetBSD: irp_pr.c,v 1.1.1.2 2012/09/09 16:07:56 christos Exp $ */ 2 3/* 4 * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") 5 * Portions Copyright (c) 1996 by Internet Software Consortium. 6 * 7 * Permission to use, copy, modify, and distribute this software for any 8 * purpose with or without fee is hereby granted, provided that the above 9 * copyright notice and this permission notice appear in all copies. 10 * 11 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES 12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR 14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 17 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 18 */ 19 20#if defined(LIBC_SCCS) && !defined(lint) 21static const char rcsid[] = "Id: irp_pr.c,v 1.3 2005/04/27 04:56:29 sra Exp "; 22#endif /* LIBC_SCCS and not lint */ 23 24/* extern */ 25 26#include "port_before.h" 27 28#include <syslog.h> 29#include <sys/types.h> 30 31#include <errno.h> 32#include <fcntl.h> 33#include <string.h> 34#include <stdio.h> 35#include <stdlib.h> 36#include <netdb.h> 37#include <syslog.h> 38 39#include <irs.h> 40#include <irp.h> 41#include <isc/memcluster.h> 42#include <isc/irpmarshall.h> 43 44#include "irs_p.h" 45#include "lcl_p.h" 46#include "irp_p.h" 47 48#include "port_after.h" 49 50 51#define MAXALIASES 35 52 53/* Types */ 54 55struct pvt { 56 struct irp_p *girpdata; 57 int warned; 58 struct protoent proto; 59}; 60 61/* Forward */ 62 63static void pr_close(struct irs_pr *); 64static struct protoent * pr_next(struct irs_pr *); 65static struct protoent * pr_byname(struct irs_pr *, const char *); 66static struct protoent * pr_bynumber(struct irs_pr *, int); 67static void pr_rewind(struct irs_pr *); 68static void pr_minimize(struct irs_pr *); 69 70static void free_proto(struct protoent *pr); 71 72/* Public */ 73 74/*% 75 * struct irs_pr * irs_irp_pr(struct irs_acc *this) 76 * 77 */ 78 79struct irs_pr * 80irs_irp_pr(struct irs_acc *this) { 81 struct irs_pr *pr; 82 struct pvt *pvt; 83 84 if (!(pr = memget(sizeof *pr))) { 85 errno = ENOMEM; 86 return (NULL); 87 } 88 memset(pr, 0x0, sizeof *pr); 89 90 if (!(pvt = memget(sizeof *pvt))) { 91 memput(pr, sizeof *pr); 92 errno = ENOMEM; 93 return (NULL); 94 } 95 memset(pvt, 0, sizeof *pvt); 96 pvt->girpdata = this->private; 97 98 pr->private = pvt; 99 pr->close = pr_close; 100 pr->byname = pr_byname; 101 pr->bynumber = pr_bynumber; 102 pr->next = pr_next; 103 pr->rewind = pr_rewind; 104 pr->minimize = pr_minimize; 105 return (pr); 106} 107 108/* Methods */ 109 110/*% 111 * void pr_close(struct irs_pr *this) 112 * 113 */ 114 115static void 116pr_close(struct irs_pr *this) { 117 struct pvt *pvt = (struct pvt *)this->private; 118 119 pr_minimize(this); 120 121 free_proto(&pvt->proto); 122 123 memput(pvt, sizeof *pvt); 124 memput(this, sizeof *this); 125} 126 127/*% 128 * struct protoent * pr_byname(struct irs_pr *this, const char *name) 129 * 130 */ 131 132static struct protoent * 133pr_byname(struct irs_pr *this, const char *name) { 134 struct pvt *pvt = (struct pvt *)this->private; 135 struct protoent *pr = &pvt->proto; 136 char *body = NULL; 137 size_t bodylen; 138 int code; 139 int i; 140 char text[256]; 141 142 if (pr->p_name != NULL && strcmp(name, pr->p_name) == 0) { 143 return (pr); 144 } 145 146 if (irs_irp_connection_setup(pvt->girpdata, &pvt->warned) != 0) { 147 return (NULL); 148 } 149 150 i = irs_irp_send_command(pvt->girpdata, "getprotobyname %s", name); 151 if (i != 0) 152 return (NULL); 153 154 if (irs_irp_get_full_response(pvt->girpdata, &code, 155 text, sizeof text, 156 &body, &bodylen) != 0) { 157 return (NULL); 158 } 159 160 if (code == IRPD_GETPROTO_OK) { 161 free_proto(pr); 162 if (irp_unmarshall_pr(pr, body) != 0) { 163 pr = NULL; 164 } 165 } else { 166 pr = NULL; 167 } 168 169 if (body != NULL) { 170 memput(body, bodylen); 171 } 172 173 return (pr); 174} 175 176/*% 177 * struct protoent * pr_bynumber(struct irs_pr *this, int proto) 178 * 179 */ 180 181static struct protoent * 182pr_bynumber(struct irs_pr *this, int proto) { 183 struct pvt *pvt = (struct pvt *)this->private; 184 struct protoent *pr = &pvt->proto; 185 char *body = NULL; 186 size_t bodylen; 187 int code; 188 int i; 189 char text[256]; 190 191 if (pr->p_name != NULL && proto == pr->p_proto) { 192 return (pr); 193 } 194 195 if (irs_irp_connection_setup(pvt->girpdata, &pvt->warned) != 0) { 196 return (NULL); 197 } 198 199 i = irs_irp_send_command(pvt->girpdata, "getprotobynumber %d", proto); 200 if (i != 0) 201 return (NULL); 202 203 if (irs_irp_get_full_response(pvt->girpdata, &code, 204 text, sizeof text, 205 &body, &bodylen) != 0) { 206 return (NULL); 207 } 208 209 if (code == IRPD_GETPROTO_OK) { 210 free_proto(pr); 211 if (irp_unmarshall_pr(pr, body) != 0) { 212 pr = NULL; 213 } 214 } else { 215 pr = NULL; 216 } 217 218 if (body != NULL) { 219 memput(body, bodylen); 220 } 221 222 return (pr); 223} 224 225/*% 226 * void pr_rewind(struct irs_pr *this) 227 * 228 */ 229 230static void 231pr_rewind(struct irs_pr *this) { 232 struct pvt *pvt = (struct pvt *)this->private; 233 char text[256]; 234 int code; 235 236 if (irs_irp_connection_setup(pvt->girpdata, &pvt->warned) != 0) { 237 return; 238 } 239 240 if (irs_irp_send_command(pvt->girpdata, "setprotoent") != 0) { 241 return; 242 } 243 244 code = irs_irp_read_response(pvt->girpdata, text, sizeof text); 245 if (code != IRPD_GETPROTO_SETOK) { 246 if (irp_log_errors) { 247 syslog(LOG_WARNING, "setprotoent failed: %s", text); 248 } 249 } 250 251 return; 252} 253 254/*% 255 * Prepares the cache if necessary and returns the next item in it. 256 * 257 */ 258 259static struct protoent * 260pr_next(struct irs_pr *this) { 261 struct pvt *pvt = (struct pvt *)this->private; 262 struct protoent *pr = &pvt->proto; 263 char *body; 264 size_t bodylen; 265 int code; 266 char text[256]; 267 268 if (irs_irp_connection_setup(pvt->girpdata, &pvt->warned) != 0) { 269 return (NULL); 270 } 271 272 if (irs_irp_send_command(pvt->girpdata, "getprotoent") != 0) { 273 return (NULL); 274 } 275 276 if (irs_irp_get_full_response(pvt->girpdata, &code, 277 text, sizeof text, 278 &body, &bodylen) != 0) { 279 return (NULL); 280 } 281 282 if (code == IRPD_GETPROTO_OK) { 283 free_proto(pr); 284 if (irp_unmarshall_pr(pr, body) != 0) { 285 pr = NULL; 286 } 287 } else { 288 pr = NULL; 289 } 290 291 if (body != NULL) { 292 memput(body, bodylen); 293 } 294 295 return (pr); 296} 297 298/*% 299 * void pr_minimize(struct irs_pr *this) 300 * 301 */ 302 303static void 304pr_minimize(struct irs_pr *this) { 305 struct pvt *pvt = (struct pvt *)this->private; 306 307 irs_irp_disconnect(pvt->girpdata); 308} 309 310/*% 311 * Deallocate all the memory irp_unmarshall_pr allocated. 312 * 313 */ 314 315static void 316free_proto(struct protoent *pr) { 317 char **p; 318 319 if (pr == NULL) 320 return; 321 322 if (pr->p_name != NULL) 323 free(pr->p_name); 324 325 for (p = pr->p_aliases ; p != NULL && *p != NULL ; p++) 326 free(*p); 327} 328 329/*! \file */ 330