/* * 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); }
/* * 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__ }
/* * 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); }
/* * 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); }