Files
Arquivotheca.SunOS-4.1.3/lib/libc/net/getservent.c
seta75D 2e8a93c394 Init
2021-10-11 18:20:23 -03:00

287 lines
5.4 KiB
C

#if !defined(lint) && defined(SCCSIDS)
static char sccsid[] = "@(#)getservent.c 1.1 92/07/30 Copyr 1990 Sun Micro";
#endif
/*
* Copyright (c) 1990 by Sun Microsystems, Inc.
*/
/*
* unlike gethost, getpw, etc, this doesn't implement getservbyxxx
* directly
*/
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <netinet/in.h>
#include <rpcsvc/ypclnt.h>
/*
* Internet version.
*/
static struct servdata {
FILE *servf;
char *current;
int currentlen;
int stayopen;
#define MAXALIASES 35
char *serv_aliases[MAXALIASES];
struct servent serv;
char line[BUFSIZ+1];
char *domain;
int usingyellow;
} *servdata, *_servdata();
static struct servent *interpret();
struct servent *getservent();
char *inet_ntoa();
char *malloc();
static char *strpbrk();
static char *SERVDB = "/etc/services";
static char *YPMAP = "services.byname";
static struct servdata *
_servdata()
{
register struct servdata *d = servdata;
if (d == 0) {
d = (struct servdata *)calloc(1, sizeof (struct servdata));
servdata = d;
}
return (d);
}
struct servent *
getservbyport(svc_port, proto)
int svc_port;
char *proto;
{
register struct servdata *d = _servdata();
register struct servent *p = NULL;
register u_short port = svc_port;
register int status;
if (d == 0)
return (0);
/*
* first try to do very fast NIS lookup.
*/
yellowup();
if (d->usingyellow && (proto != 0)) {
char portstr[12];
char *key, *val;
int keylen, vallen;
sprintf(portstr, "%d", ntohs(port));
keylen = strlen(portstr) + 1 + strlen(proto);
key = malloc(keylen + 1);
sprintf(key, "%s/%s", portstr, proto);
if (!(status=yp_match(d->domain, YPMAP, key, keylen,
&val, &vallen))) {
p = interpret(val, vallen);
free(val);
free(key);
return(p);
}
free(key);
if (yp_ismapthere(status)){
return(p);
}
else d->usingyellow=0;
}
setservent(0);
while (p = getservent()) {
if (p->s_port != port)
continue;
if (proto == 0 || strcmp(p->s_proto, proto) == 0)
break;
}
endservent();
return (p);
}
struct servent *
getservbyname(name, proto)
register char *name, *proto;
{
register struct servdata *d = _servdata();
register struct servent *p;
register char **cp;
if (d == 0)
return (0);
setservent(0);
while (p = getservent()) {
if (strcmp(name, p->s_name) == 0)
goto gotname;
for (cp = p->s_aliases; *cp; cp++)
if (strcmp(name, *cp) == 0)
goto gotname;
continue;
gotname:
if (proto == 0 || strcmp(p->s_proto, proto) == 0)
break;
}
endservent();
return (p);
}
setservent(f)
int f;
{
register struct servdata *d = _servdata();
if (d == 0)
return;
if (d->servf == NULL)
d->servf = fopen(SERVDB, "r");
else
rewind(d->servf);
if (d->current)
free(d->current);
d->current = NULL;
d->stayopen |= f;
yellowup(); /* recompute whether NIS are up */
}
endservent()
{
register struct servdata *d = _servdata();
if (d == 0)
return;
if (d->current && !d->stayopen) {
free(d->current);
d->current = NULL;
}
if (d->servf && !d->stayopen) {
fclose(d->servf);
d->servf = NULL;
}
}
struct servent *
getservent()
{
register struct servdata *d = _servdata();
int reason;
char *key = NULL, *val = NULL;
int keylen, vallen;
struct servent *sp;
if (d == 0)
return NULL;
yellowup();
if (!d->usingyellow) {
if (d->servf == NULL && (d->servf = fopen(SERVDB, "r")) == NULL)
return (NULL);
if (fgets(d->line, BUFSIZ, d->servf) == NULL)
return (NULL);
return interpret(d->line, strlen(d->line));
}
if (d->current == NULL) {
if (reason = yp_first(d->domain, YPMAP,
&key, &keylen, &val, &vallen)) {
if (yp_ismapthere(reason)==0) {
d->usingyellow=0;
return(getservent());
}
#ifdef DEBUG
fprintf(stderr, "reason yp_first failed is %d\n",
reason);
#endif
return NULL;
}
}
else {
if (reason = yp_next(d->domain, YPMAP,
d->current, d->currentlen, &key, &keylen, &val, &vallen)) {
if (yp_ismapthere(reason)==0) {
d->usingyellow=0;
return(getservent());
}
#ifdef DEBUG
fprintf(stderr, "reason yp_next failed is %d\n",
reason);
#endif
return NULL;
}
}
if (d->current)
free(d->current);
d->current = key;
d->currentlen = keylen;
sp = interpret(val, vallen);
free(val);
return (sp);
}
static struct servent *
interpret(val, len)
{
register struct servdata *d = _servdata();
char *p;
register char *cp, **q;
if (d == 0)
return (0);
strncpy(d->line, val, len);
p = d->line;
d->line[len] = '\n';
if ((*p == '#') || (*p == '\n'))
return (getservent());
cp = strpbrk(p, "#\n");
if (cp == NULL)
return (getservent());
*cp = '\0';
d->serv.s_name = p;
p = strpbrk(p, " \t");
if (p == NULL)
return (getservent());
*p++ = '\0';
while (*p == ' ' || *p == '\t')
p++;
cp = strpbrk(p, ",/");
if (cp == NULL)
return (getservent());
*cp++ = '\0';
d->serv.s_port = htons((u_short)atoi(p));
d->serv.s_proto = cp;
q = d->serv.s_aliases = d->serv_aliases;
cp = strpbrk(cp, " \t");
if (cp != NULL)
*cp++ = '\0';
while (cp && *cp) {
if (*cp == ' ' || *cp == '\t') {
cp++;
continue;
}
if (q < &(d->serv_aliases[MAXALIASES - 1]))
*q++ = cp;
cp = strpbrk(cp, " \t");
if (cp != NULL)
*cp++ = '\0';
}
*q = NULL;
return (&d->serv);
}
/*
* check to see if NIS are up, and store that fact in d->usingyellow.
*/
static
yellowup()
{
register struct servdata *d = _servdata();
if (d->domain == NULL) {
yp_get_default_domain(&d->domain);
if (d->domain) d->usingyellow=1;
else d->usingyellow=0;
}
}