/*
 * Retreive the port number for the service name "servname" and
 * the protocol "proto".
 */
static int
get_port(const char *servname, const char *proto, int numonly)
{
	struct servent		se;
	struct servent_data	sed;
	int			port, r;
	const char*		e;

	if (servname == NULL)
		return (0);

	e = NULL;
	port = strtonum(servname, 0, USHRT_MAX, &e);
	if (e == NULL)
		return (port);
	if (errno == ERANGE)
		return (-2); /* invalid */
	if (numonly)
		return (-2);

	memset(&sed, 0, sizeof(sed));
	r = getservbyname_r(servname, proto, &se, &sed);
	port = ntohs(se.s_port);
	endservent_r(&sed);

	if (r == -1)
		return (-1); /* not found */

	return (port);
}
Exemple #2
0
/*
 * Set the service name on the result buffer is not NULL.
 * return (-1) if the buffer is too small.
 */
static int
_servname(struct asr_query *as)
{
	struct servent		 s;
#ifdef HAVE_STRUCT_SERVENT_DATA
	struct servent_data	 sd;
#endif
	int			 port, r;
	char			*buf = as->as.ni.servname;
	size_t			 buflen = as->as.ni.servnamelen;

	if (as->as.ni.servname == NULL || as->as.ni.servnamelen == 0)
		return (0);

	if (as->as.ni.sa.sa.sa_family == AF_INET)
		port = as->as.ni.sa.sain.sin_port;
	else
		port = as->as.ni.sa.sain6.sin6_port;

	if (!(as->as.ni.flags & NI_NUMERICSERV)) {
#ifdef HAVE_STRUCT_SERVENT_DATA
		memset(&sd, 0, sizeof (sd));
#endif
#ifdef HAVE_GETSERVBYPORT_R_4_ARGS
		r = getservbyport_r(port,
		    (as->as.ni.flags & NI_DGRAM) ? "udp" : "tcp",
		    &s, &sd);
#else
		r = -1;
#endif
		if (r != -1) {
			r = strlcpy(buf, s.s_name, buflen) >= buflen;
#ifdef HAVE_ENDSERVENT_R
			endservent_r(&sd);
#endif
			return (r ? -1 : 0);
		}
	}

	r = snprintf(buf, buflen, "%u", ntohs(port));
	if (r == -1 || r >= (int)buflen)
		return (-1);

	return (0);
}
EXPORT_C void
endservent(void)
{
	struct servdata *sd;

#ifndef __SYMBIAN32__
	if ((sd = __servdata_init()) == NULL)
		return;
#else
      sd= reentfunction(_REENT);
      sd->serv.s_name=0;
      sd->serv.s_port=0;
      sd->serv.s_proto=0;
      sd->serv.s_aliases=0;
      if(sd->data.fp)
      	fclose(sd->data.fp);
      sd->data.fp=0;
#endif /*__SYMBIAN32__*/
	endservent_r(&sd->data);
#ifdef __SYMBIAN32__
       num_line=0;
#endif//__SYMBIAN32__
}
Exemple #4
0
/* 
 * Print the textual representation of the port set on "sa".
 *
 * If proto is not NULL, it is used as parameter to "getservbyport_r(3)" to
 * return a service name. If it's not set, or if no matching service is found,
 * it prints the portno.
 *
 * Return the total length of the string it tried to create or 0 if an error
 * occured, in which case errno is set.  On success, the constructed string
 * is guaranteed to be NUL-terminated.  Overflow must be detected by checking
 * the returned size against buflen.
 */
static size_t
asr_print_port(const struct sockaddr *sa, const char *proto, char *buf, size_t buflen)
{
	struct servent s;
	struct servent_data sd;
	int port, r, saved_errno;
	size_t n;

	switch(sa->sa_family) {
	case AF_INET:
		port = SA_IN(sa)->sin_port;
		break;
	case AF_INET6:
		port = SA_IN6(sa)->sin6_port;
		break;
	default:
		errno = EINVAL;
		return (0);
	}

	if (proto) {
		memset(&sd, 0, sizeof (sd));
		saved_errno = errno;
		if (getservbyport_r(port, proto, &s, &sd) != -1) {
			n = strlcpy(buf, s.s_name, buflen);
			endservent_r(&sd);
			return (n);
		}
		errno = saved_errno;
	}

	r = snprintf(buf, buflen, "%u", ntohs(port));
	if (r == -1) 	/* Actually, this can not happen */
		return (0);

	return (r);
}
Exemple #5
0
/*
 * Retreive the port number for the service name "servname" and
 * the protocol "proto".
 */
static int
get_port(const char *servname, const char *proto, int numonly)
{
	struct servent		se;
#ifdef HAVE_STRUCT_SERVENT_DATA
	struct servent_data	sed;
#endif
	int			port;
	const char		*e;

	if (servname == NULL)
		return (0);

	e = NULL;
	port = strtonum(servname, 0, USHRT_MAX, &e);
	if (e == NULL)
		return (port);
	if (errno == ERANGE)
		return (-2); /* invalid */
	if (numonly)
		return (-2);

	port = -1;
#ifdef HAVE_STRUCT_SERVENT_DATA
	memset(&sed, 0, sizeof(sed));
#endif
#ifdef HAVE_GETSERVBYNAME_R_4_ARGS
	if (getservbyname_r(servname, proto, &se, &sed) != -1)
		port = ntohs(se.s_port);
#endif
#ifdef HAVE_ENDSERVENT_R
	endservent_r(&sed);
#endif

	return (port);
}
int
getservent_r(struct servent *se, struct servent_data *sd)
{
	char *p, *cp, **q, *endp;
	size_t len;
	long l;
	int serrno;

	if (sd->fp == NULL && (sd->fp = fopen(_PATH_SERVICES, "re" )) == NULL)
		return (-1);
again:
	if ((p = fgetln(sd->fp, &len)) == NULL)
		return (-1);
	if (len == 0 || *p == '#' || *p == '\n')
		goto again;
	if (p[len-1] == '\n')
		len--;
	if ((cp = memchr(p, '#', len)) != NULL)
		len = cp - p;
	cp = realloc(sd->line, len + 1);
	if (cp == NULL)
		return (-1);
	sd->line = se->s_name = memcpy(cp, p, len);
	cp[len] = '\0';
	p = strpbrk(cp, " \t");
	if (p == NULL)
		goto again;
	*p++ = '\0';
	while (*p == ' ' || *p == '\t')
		p++;
	cp = strpbrk(p, ",/");
	if (cp == NULL)
		goto again;
	*cp++ = '\0';
	l = strtol(p, &endp, 10);
	if (endp == p || *endp != '\0' || l < 0 || l > USHRT_MAX)
		goto again;
	se->s_port = htons((in_port_t)l);
	se->s_proto = cp;
	if (sd->aliases == NULL) {
		sd->maxaliases = 10;
		sd->aliases = calloc(sd->maxaliases, sizeof(char *));
		if (sd->aliases == NULL) {
			serrno = errno;
			endservent_r(sd);
			errno = serrno;
			return (-1);
		}
	}
	q = se->s_aliases = sd->aliases;
	cp = strpbrk(cp, " \t");
	if (cp != NULL)
		*cp++ = '\0';
	while (cp && *cp) {
		if (*cp == ' ' || *cp == '\t') {
			cp++;
			continue;
		}
		if (q == &se->s_aliases[sd->maxaliases - 1]) {
			p = reallocarray(se->s_aliases, sd->maxaliases,
			    2 * sizeof(char *));
			if (p == NULL) {
				serrno = errno;
				endservent_r(sd);
				errno = serrno;
				return (-1);
			}
			sd->maxaliases *= 2;
			q = (char **)p + (q - se->s_aliases);
			se->s_aliases = sd->aliases = (char **)p;
		}
		*q++ = cp;
		cp = strpbrk(cp, " \t");
		if (cp != NULL)
			*cp++ = '\0';
	}
	*q = NULL;
	return (0);
}
void
endservent(void)
{
	endservent_r(&_servent_data);
}