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