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