static int files_setservent(void *retval, void *mdata, va_list ap) { struct files_state *st; int rv; int f; rv = files_getstate(&st); if (rv != 0) return (NS_UNAVAIL); switch ((enum constants)mdata) { case SETSERVENT: f = va_arg(ap,int); if (st->fp == NULL) st->fp = fopen(_PATH_SERVICES, "r"); else rewind(st->fp); st->stayopen |= f; break; case ENDSERVENT: if (st->fp != NULL) { fclose(st->fp); st->fp = NULL; } st->stayopen = 0; break; default: break; }; st->compat_mode_active = 0; return (NS_UNAVAIL); }
static int files_setrpcent(void *retval, void *mdata, va_list ap) { struct files_state *st; int rv; int f; rv = files_getstate(&st); if (rv != 0) return (NS_UNAVAIL); switch ((enum constants)mdata) { case SETRPCENT: f = va_arg(ap,int); if (st->fp == NULL) st->fp = fopen(RPCDB, "r"); else rewind(st->fp); st->stayopen |= f; break; case ENDRPCENT: if (st->fp != NULL) { fclose(st->fp); st->fp = NULL; } st->stayopen = 0; break; default: break; } return (NS_UNAVAIL); }
/* * compat structures. compat and files sources functionalities are almost * equal, so they all are managed by files_servent function */ static int files_servent(void *retval, void *mdata, va_list ap) { static const ns_src compat_src[] = { #ifdef YP { NSSRC_NIS, NS_SUCCESS }, #endif { NULL, 0 } }; ns_dtab compat_dtab[] = { { NSSRC_DB, db_servent, (void *)((struct servent_mdata *)mdata)->how }, #ifdef YP { NSSRC_NIS, nis_servent, (void *)((struct servent_mdata *)mdata)->how }, #endif { NULL, NULL, NULL } }; struct files_state *st; int rv; int stayopen; struct servent_mdata *serv_mdata; char *name; char *proto; int port; struct servent *serv; char *buffer; size_t bufsize; int *errnop; size_t linesize; char *line; char **cp; name = NULL; proto = NULL; serv_mdata = (struct servent_mdata *)mdata; switch (serv_mdata->how) { case nss_lt_name: name = va_arg(ap, char *); proto = va_arg(ap, char *); break; case nss_lt_id: port = va_arg(ap, int); proto = va_arg(ap, char *); break; case nss_lt_all: break; default: return NS_NOTFOUND; }; serv = va_arg(ap, struct servent *); buffer = va_arg(ap, char *); bufsize = va_arg(ap, size_t); errnop = va_arg(ap,int *); *errnop = files_getstate(&st); if (*errnop != 0) return (NS_UNAVAIL); if (st->fp == NULL) st->compat_mode_active = 0; if (st->fp == NULL && (st->fp = fopen(_PATH_SERVICES, "r")) == NULL) { *errnop = errno; return (NS_UNAVAIL); } if (serv_mdata->how == nss_lt_all) stayopen = 1; else { rewind(st->fp); stayopen = st->stayopen; } rv = NS_NOTFOUND; do { if (!st->compat_mode_active) { if ((line = fgetln(st->fp, &linesize)) == NULL) { *errnop = errno; rv = NS_RETURN; break; } if (*line=='+' && serv_mdata->compat_mode != 0) st->compat_mode_active = 1; } if (st->compat_mode_active != 0) { switch (serv_mdata->how) { case nss_lt_name: rv = nsdispatch(retval, compat_dtab, NSDB_SERVICES_COMPAT, "getservbyname_r", compat_src, name, proto, serv, buffer, bufsize, errnop); break; case nss_lt_id: rv = nsdispatch(retval, compat_dtab, NSDB_SERVICES_COMPAT, "getservbyport_r", compat_src, port, proto, serv, buffer, bufsize, errnop); break; case nss_lt_all: rv = nsdispatch(retval, compat_dtab, NSDB_SERVICES_COMPAT, "getservent_r", compat_src, serv, buffer, bufsize, errnop); break; } if (!(rv & NS_TERMINATE) || serv_mdata->how != nss_lt_all) st->compat_mode_active = 0; continue; } rv = parse_result(serv, buffer, bufsize, line, linesize, errnop); if (rv == NS_NOTFOUND) continue; if (rv == NS_RETURN) break; rv = NS_NOTFOUND; switch (serv_mdata->how) { case nss_lt_name: if (strcmp(name, serv->s_name) == 0) goto gotname; for (cp = serv->s_aliases; *cp; cp++) if (strcmp(name, *cp) == 0) goto gotname; continue; gotname: if (proto == 0 || strcmp(serv->s_proto, proto) == 0) rv = NS_SUCCESS; break; case nss_lt_id: if (port != serv->s_port) continue; if (proto == 0 || strcmp(serv->s_proto, proto) == 0) rv = NS_SUCCESS; break; case nss_lt_all: rv = NS_SUCCESS; break; } } while (!(rv & NS_TERMINATE)); if (!stayopen && st->fp != NULL) { fclose(st->fp); st->fp = NULL; } if ((rv == NS_SUCCESS) && (retval != NULL)) *(struct servent **)retval=serv; return (rv); }
static int files_rpcent(void *retval, void *mdata, va_list ap) { char *name; int number; struct rpcent *rpc; char *buffer; size_t bufsize; int *errnop; char *line; size_t linesize; char **aliases; int aliases_size; char **rp; struct files_state *st; int rv; int stayopen; enum nss_lookup_type how; how = (enum nss_lookup_type)mdata; switch (how) { case nss_lt_name: name = va_arg(ap, char *); break; case nss_lt_id: number = va_arg(ap, int); break; case nss_lt_all: break; default: return (NS_NOTFOUND); } rpc = va_arg(ap, struct rpcent *); buffer = va_arg(ap, char *); bufsize = va_arg(ap, size_t); errnop = va_arg(ap, int *); *errnop = files_getstate(&st); if (*errnop != 0) return (NS_UNAVAIL); if (st->fp == NULL && (st->fp = fopen(RPCDB, "r")) == NULL) { *errnop = errno; return (NS_UNAVAIL); } if (how == nss_lt_all) stayopen = 1; else { rewind(st->fp); stayopen = st->stayopen; } do { if ((line = fgetln(st->fp, &linesize)) == NULL) { *errnop = errno; rv = NS_RETURN; break; } if (bufsize <= linesize + _ALIGNBYTES + sizeof(char *)) { *errnop = ERANGE; rv = NS_RETURN; break; } aliases = (char **)_ALIGN(&buffer[linesize+1]); aliases_size = (buffer + bufsize - (char *)aliases)/sizeof(char *); if (aliases_size < 1) { *errnop = ERANGE; rv = NS_RETURN; break; } memcpy(buffer, line, linesize); buffer[linesize] = '\0'; rv = rpcent_unpack(buffer, rpc, aliases, aliases_size, errnop); if (rv != 0) { if (*errnop == 0) { rv = NS_NOTFOUND; continue; } else { rv = NS_RETURN; break; } } switch (how) { case nss_lt_name: if (strcmp(rpc->r_name, name) == 0) goto done; for (rp = rpc->r_aliases; *rp != NULL; rp++) { if (strcmp(*rp, name) == 0) goto done; } rv = NS_NOTFOUND; continue; done: rv = NS_SUCCESS; break; case nss_lt_id: rv = (rpc->r_number == number) ? NS_SUCCESS : NS_NOTFOUND; break; case nss_lt_all: rv = NS_SUCCESS; break; } } while (!(rv & NS_TERMINATE)); if (!stayopen && st->fp!=NULL) { fclose(st->fp); st->fp = NULL; } if ((rv == NS_SUCCESS) && (retval != NULL)) *((struct rpcent **)retval) = rpc; return (rv); }