spif_bool_t spif_socket_done(spif_socket_t self) { ASSERT_RVAL(!SPIF_SOCKET_ISNULL(self), FALSE); if (self->fd >= 0) { spif_socket_close(self); } self->fam = AF_INET; self->type = SOCK_STREAM; self->proto = 0; if (self->addr != (spif_sockaddr_t) NULL) { SPIF_DEALLOC(self->addr); self->addr = (spif_sockaddr_t) NULL; } self->len = 0; self->flags = 0; if (!SPIF_URL_ISNULL(self->local_url)) { spif_url_del(self->local_url); self->local_url = (spif_url_t) NULL; } if (!SPIF_URL_ISNULL(self->remote_url)) { spif_url_del(self->remote_url); self->remote_url = (spif_url_t) NULL; } return TRUE; }
spif_bool_t spif_socket_init_from_urls(spif_socket_t self, spif_url_t surl, spif_url_t durl) { ASSERT_RVAL(!SPIF_SOCKET_ISNULL(self), FALSE); /* ***NOT NEEDED*** spif_obj_init(SPIF_OBJ(self)); */ spif_obj_set_class(SPIF_OBJ(self), SPIF_CLASS_VAR(socket)); self->fd = -1; self->fam = AF_INET; self->type = SOCK_STREAM; self->proto = 0; self->addr = (spif_sockaddr_t) NULL; self->len = 0; self->flags = 0; if (!SPIF_URL_ISNULL(surl)) { self->local_url = spif_url_dup(surl); } else { self->local_url = (spif_url_t) NULL; } if (!SPIF_URL_ISNULL(durl)) { self->remote_url = spif_url_dup(durl); } else { self->remote_url = (spif_url_t) NULL; } return TRUE; }
spif_socket_t spif_socket_dup(spif_socket_t self) { spif_socket_t tmp; ASSERT_RVAL(!SPIF_SOCKET_ISNULL(self), (spif_socket_t) NULL); tmp = spif_socket_new(); if (self->fd >= 0) { tmp->fd = dup(self->fd); } tmp->fam = self->fam; tmp->type = self->type; tmp->proto = self->proto; tmp->len = self->len; if (self->addr != (spif_sockaddr_t) NULL) { tmp->addr = (spif_sockaddr_t) MALLOC(tmp->len); memcpy(tmp->addr, self->addr, tmp->len); } tmp->flags = self->flags; if (!SPIF_URL_ISNULL(self->local_url)) { tmp->local_url = spif_url_dup(self->local_url); } if (!SPIF_URL_ISNULL(self->remote_url)) { tmp->remote_url = spif_url_dup(self->remote_url); } return tmp; }
spif_str_t spif_url_show(spif_url_t self, spif_charptr_t name, spif_str_t buff, size_t indent) { spif_char_t tmp[4096]; if (SPIF_URL_ISNULL(self)) { SPIF_OBJ_SHOW_NULL(url, name, buff, indent, tmp); return buff; } memset(tmp, ' ', indent); snprintf((char *) tmp + indent, sizeof(tmp) - indent, "(spif_url_t) %s: %10p {\n", name, (spif_ptr_t) self); if (SPIF_STR_ISNULL(buff)) { buff = spif_str_new_from_ptr(tmp); } else { spif_str_append_from_ptr(buff, tmp); } buff = spif_str_show(self->proto, SPIF_CHARPTR("proto"), buff, indent + 2); buff = spif_str_show(self->user, SPIF_CHARPTR("user"), buff, indent + 2); buff = spif_str_show(self->passwd, SPIF_CHARPTR("passwd"), buff, indent + 2); buff = spif_str_show(self->host, SPIF_CHARPTR("host"), buff, indent + 2); buff = spif_str_show(self->port, SPIF_CHARPTR("port"), buff, indent + 2); buff = spif_str_show(self->path, SPIF_CHARPTR("path"), buff, indent + 2); buff = spif_str_show(self->query, SPIF_CHARPTR("query"), buff, indent + 2); snprintf((char *) tmp + indent, sizeof(tmp) - indent, "}\n"); spif_str_append_from_ptr(buff, tmp); return buff; }
static spif_bool_t spif_url_init_from_ipaddr(spif_url_t self, spif_ipsockaddr_t ipaddr) { spif_uint8_t tries; spif_hostinfo_t hinfo; ASSERT_RVAL(!SPIF_URL_ISNULL(self), FALSE); spif_str_init(SPIF_STR(self)); spif_obj_set_class(SPIF_OBJ(self), SPIF_CLASS_VAR(url)); self->proto = (spif_str_t) NULL; self->user = (spif_str_t) NULL; self->passwd = (spif_str_t) NULL; self->path = (spif_str_t) NULL; self->query = (spif_str_t) NULL; /* Try up to 3 times to resolve the hostname. */ h_errno = 0; tries = 0; do { tries++; hinfo = gethostbyaddr((const char *) &(ipaddr->sin_addr), sizeof(ipaddr->sin_addr), AF_INET); } while ((tries <= 3) && (!hinfo) && (h_errno == TRY_AGAIN)); if (!hinfo || !hinfo->h_name) { spif_charptr_t buff; buff = SPIF_CHARPTR(inet_ntoa(ipaddr->sin_addr)); self->host = spif_str_new_from_ptr(buff); } else { self->host = spif_str_new_from_ptr(SPIF_CHARPTR(hinfo->h_name)); } self->port = spif_str_new_from_num(ntohs(ipaddr->sin_port)); return TRUE; }
spif_bool_t spif_url_done(spif_url_t self) { ASSERT_RVAL(!SPIF_URL_ISNULL(self), FALSE); if (!SPIF_STR_ISNULL(self->proto)) { spif_str_del(self->proto); self->proto = (spif_str_t) NULL; } if (!SPIF_STR_ISNULL(self->user)) { spif_str_del(self->user); self->user = (spif_str_t) NULL; } if (!SPIF_STR_ISNULL(self->passwd)) { spif_str_del(self->passwd); self->passwd = (spif_str_t) NULL; } if (!SPIF_STR_ISNULL(self->host)) { spif_str_del(self->host); self->host = (spif_str_t) NULL; } if (!SPIF_STR_ISNULL(self->port)) { spif_str_del(self->port); self->port = (spif_str_t) NULL; } if (!SPIF_STR_ISNULL(self->path)) { spif_str_del(self->path); self->path = (spif_str_t) NULL; } if (!SPIF_STR_ISNULL(self->query)) { spif_str_del(self->query); self->query = (spif_str_t) NULL; } spif_str_done(SPIF_STR(self)); return TRUE; }
spif_bool_t spif_url_del(spif_url_t self) { ASSERT_RVAL(!SPIF_URL_ISNULL(self), FALSE); spif_url_done(self); SPIF_DEALLOC(self); return TRUE; }
spif_url_t spif_url_dup(spif_url_t self) { spif_url_t tmp; ASSERT_RVAL(!SPIF_URL_ISNULL(self), (spif_url_t) NULL); tmp = spif_url_new_from_str(SPIF_STR(self)); return tmp; }
static spif_unixsockaddr_t spif_url_get_unixaddr(spif_url_t self) { spif_unixsockaddr_t addr; ASSERT_RVAL(!SPIF_URL_ISNULL(self), (spif_unixsockaddr_t) NULL); /* No address to look up, just a file path. */ addr = SPIF_ALLOC(unixsockaddr); addr->sun_family = AF_UNIX; addr->sun_path[0] = 0; strncat(addr->sun_path, (char *) SPIF_STR_STR(spif_url_get_path(self)), sizeof(addr->sun_path) - 1); return addr; }
spif_bool_t spif_url_unparse(spif_url_t self) { ASSERT_RVAL(!SPIF_URL_ISNULL(self), FALSE); spif_str_done(SPIF_STR(self)); spif_str_init_from_ptr(SPIF_STR(self), SPIF_CHARPTR("")); /* First, proto followed by a colon. */ if (!SPIF_STR_ISNULL(self->proto)) { spif_str_append(SPIF_STR(self), self->proto); spif_str_append_char(SPIF_STR(self), ':'); } /* If we have a port but no host, make it localhost. */ if (!SPIF_STR_ISNULL(self->port) && SPIF_STR_ISNULL(self->host)) { self->host = spif_str_new_from_ptr(SPIF_CHARPTR("localhost")); } /* We need the // if we have a hostname. */ if (!SPIF_STR_ISNULL(self->host)) { spif_str_append_from_ptr(SPIF_STR(self), SPIF_CHARPTR("//")); } if (!SPIF_STR_ISNULL(self->user)) { spif_str_append(SPIF_STR(self), self->user); if (!SPIF_STR_ISNULL(self->passwd)) { spif_str_append_char(SPIF_STR(self), ':'); spif_str_append(SPIF_STR(self), self->passwd); } spif_str_append_char(SPIF_STR(self), '@'); } if (!SPIF_STR_ISNULL(self->host)) { spif_str_append(SPIF_STR(self), self->host); if (!SPIF_STR_ISNULL(self->port)) { spif_str_append_char(SPIF_STR(self), ':'); spif_str_append(SPIF_STR(self), self->port); } } if (!SPIF_STR_ISNULL(self->path)) { spif_str_append(SPIF_STR(self), self->path); } if (!SPIF_STR_ISNULL(self->query)) { spif_str_append_char(SPIF_STR(self), '?'); spif_str_append(SPIF_STR(self), self->query); } return TRUE; }
static spif_sockport_t spif_url_get_portnum(spif_url_t self) { spif_str_t port_str; ASSERT_RVAL(!SPIF_URL_ISNULL(self), (spif_sockport_t) NULL); /* Return the integer form of the port number for a URL */ port_str = spif_url_get_port(self); if (!SPIF_STR_ISNULL(port_str)) { return (spif_sockport_t) spif_str_to_num(port_str, 10); } return (spif_sockport_t) 0; }
spif_bool_t spif_url_init(spif_url_t self) { ASSERT_RVAL(!SPIF_URL_ISNULL(self), FALSE); if (!spif_str_init(SPIF_STR(self))) { return FALSE; } spif_obj_set_class(SPIF_OBJ(self), SPIF_CLASS_VAR(url)); self->proto = (spif_str_t) NULL; self->user = (spif_str_t) NULL; self->passwd = (spif_str_t) NULL; self->host = (spif_str_t) NULL; self->port = (spif_str_t) NULL; self->path = (spif_str_t) NULL; self->query = (spif_str_t) NULL; return TRUE; }
spif_bool_t spif_url_init_from_ptr(spif_url_t self, spif_charptr_t other) { ASSERT_RVAL(!SPIF_URL_ISNULL(self), FALSE); if (!spif_str_init_from_ptr(SPIF_STR(self), other)) { return FALSE; } spif_obj_set_class(SPIF_OBJ(self), SPIF_CLASS_VAR(url)); self->proto = (spif_str_t) NULL; self->user = (spif_str_t) NULL; self->passwd = (spif_str_t) NULL; self->host = (spif_str_t) NULL; self->port = (spif_str_t) NULL; self->path = (spif_str_t) NULL; self->query = (spif_str_t) NULL; spif_url_parse(self); return TRUE; }
static spif_bool_t spif_url_init_from_unixaddr(spif_url_t self, spif_unixsockaddr_t unixaddr) { ASSERT_RVAL(!SPIF_URL_ISNULL(self), FALSE); spif_str_init(SPIF_STR(self)); spif_obj_set_class(SPIF_OBJ(self), SPIF_CLASS_VAR(url)); self->proto = (spif_str_t) NULL; self->user = (spif_str_t) NULL; self->passwd = (spif_str_t) NULL; self->host = (spif_str_t) NULL; self->port = (spif_str_t) NULL; self->query = (spif_str_t) NULL; if (unixaddr->sun_path) { self->path = spif_str_new_from_ptr(SPIF_CHARPTR(unixaddr->sun_path)); } else { self->path = (spif_str_t) NULL; } return TRUE; }
static spif_ipsockaddr_t spif_url_get_ipaddr(spif_url_t self) { spif_uint8_t tries; spif_hostinfo_t hinfo; spif_ipsockaddr_t addr; spif_str_t hostname; ASSERT_RVAL(!SPIF_URL_ISNULL(self), (spif_ipsockaddr_t) NULL); /* We need a hostname of some type to connect to. */ hostname = SPIF_STR(spif_url_get_host(self)); REQUIRE_RVAL(!SPIF_STR_ISNULL(hostname), (spif_ipsockaddr_t) NULL); /* Try up to 3 times to resolve the hostname. */ h_errno = 0; tries = 0; do { tries++; hinfo = gethostbyname((char *) SPIF_STR_STR(hostname)); } while ((tries <= 3) && (!hinfo) && (h_errno == TRY_AGAIN)); if (!hinfo) { libast_print_error("Unable to resolve hostname \"%s\" -- %s\n", SPIF_STR_STR(hostname), hstrerror(h_errno)); return (spif_ipsockaddr_t) NULL; } if (!hinfo->h_addr_list) { libast_print_error("Invalid address list returned by gethostbyname()\n"); return (spif_ipsockaddr_t) NULL; } /* Grab the host IP address and port number, both in network byte order. */ addr = SPIF_ALLOC(ipsockaddr); addr->sin_family = AF_INET; addr->sin_port = htons(spif_url_get_portnum(self)); memcpy(&(addr->sin_addr), (void *) (hinfo->h_addr_list[0]), sizeof(addr->sin_addr)); D_OBJ(("Got address 0x%08x and port %d for name \"%s\"\n", (long) ntohl(*((int *) (&addr->sin_addr))), (int) ntohs(addr->sin_port), SPIF_STR_STR(hostname))); return addr; }
static spif_bool_t spif_socket_get_proto(spif_socket_t self) { spif_url_t url; spif_protoinfo_t proto; spif_str_t proto_str; spif_servinfo_t serv; ASSERT_RVAL(!SPIF_URL_ISNULL(self), FALSE); /* If we have a remote URL, use it. Otherwise, use the local one. */ url = ((SPIF_URL_ISNULL(self->remote_url)) ? (self->local_url) : (self->remote_url)); REQUIRE_RVAL(!SPIF_URL_ISNULL(url), FALSE); proto_str = spif_url_get_proto(url); if (!SPIF_STR_ISNULL(proto_str)) { if (SPIF_CMP_IS_EQUAL(spif_str_cmp_with_ptr(proto_str, SPIF_CHARPTR("raw")))) { spif_str_t target; /* Raw socket. Could be raw UNIX or raw IP. */ SPIF_SOCKET_FLAGS_SET(self, SPIF_SOCKET_FLAGS_TYPE_RAW); /* If we have a hostname, it's IP. If we have a path only, it's UNIX. */ target = spif_url_get_host(url); if (SPIF_STR_ISNULL(target)) { target = spif_url_get_path(url); if (!SPIF_STR_ISNULL(target)) { SPIF_SOCKET_FLAGS_SET(self, SPIF_SOCKET_FLAGS_FAMILY_UNIX); } } else { SPIF_SOCKET_FLAGS_SET(self, SPIF_SOCKET_FLAGS_FAMILY_INET); } } else if (SPIF_CMP_IS_EQUAL(spif_str_cmp_with_ptr(proto_str, SPIF_CHARPTR("unix")))) { /* UNIX socket. Assume stream-based. */ SPIF_SOCKET_FLAGS_SET(self, SPIF_SOCKET_FLAGS_FAMILY_UNIX); SPIF_SOCKET_FLAGS_SET(self, SPIF_SOCKET_FLAGS_TYPE_STREAM); } else { /* IP socket. See if they gave us a protocol name. */ SPIF_SOCKET_FLAGS_SET(self, SPIF_SOCKET_FLAGS_FAMILY_INET); proto = getprotobyname((char *) SPIF_STR_STR(proto_str)); if (!proto) { /* If it's not a protocol, it's probably a service. */ serv = getservbyname((char *) SPIF_STR_STR(proto_str), "tcp"); if (!serv) { serv = getservbyname((char *) SPIF_STR_STR(proto_str), "udp"); } if (serv) { /* If we found one, get the protocol info too. */ proto = getprotobyname(serv->s_proto); REQUIRE_RVAL(proto != NULL, FALSE); } } if (proto) { /* Bingo. Set the flags appropriately. */ self->proto = proto->p_proto; if (!strcmp(proto->p_name, "tcp")) { SPIF_SOCKET_FLAGS_SET(self, SPIF_SOCKET_FLAGS_TYPE_STREAM); } else if (!strcmp(proto->p_name, "udp")) { SPIF_SOCKET_FLAGS_SET(self, SPIF_SOCKET_FLAGS_TYPE_DGRAM); } } } } else { /* No protocol? Assume a UNIX socket. */ SPIF_SOCKET_FLAGS_SET(self, SPIF_SOCKET_FLAGS_FAMILY_UNIX); SPIF_SOCKET_FLAGS_SET(self, SPIF_SOCKET_FLAGS_TYPE_STREAM); } return TRUE; }
spif_bool_t spif_socket_open(spif_socket_t self) { ASSERT_RVAL(!SPIF_SOCKET_ISNULL(self), FALSE); if (!(self->addr)) { /* Set family, protocol, and type flags. */ spif_socket_get_proto(self); /* Get remote address, if we have one. */ if (SPIF_SOCKET_FLAGS_IS_SET(self, SPIF_SOCKET_FLAGS_FAMILY_INET)) { self->fam = AF_INET; if (!SPIF_URL_ISNULL(self->remote_url)) { self->addr = (spif_sockaddr_t) spif_url_get_ipaddr(self->remote_url); } else { self->addr = (spif_sockaddr_t) NULL; } if (self->addr == (spif_sockaddr_t) NULL) { self->len = 0; } else { self->len = SPIF_SIZEOF_TYPE(ipsockaddr); } } else if (SPIF_SOCKET_FLAGS_IS_SET(self, SPIF_SOCKET_FLAGS_FAMILY_UNIX)) { self->fam = AF_UNIX; if (!SPIF_URL_ISNULL(self->remote_url)) { self->addr = (spif_sockaddr_t) spif_url_get_unixaddr(self->remote_url); } else { self->addr = (spif_sockaddr_t) NULL; } if (self->addr == (spif_sockaddr_t) NULL) { self->len = 0; } else { self->len = SPIF_SIZEOF_TYPE(unixsockaddr); } } else { D_OBJ(("Unknown socket family 0x%08x!\n", SPIF_SOCKET_FLAGS_IS_SET(self, SPIF_SOCKET_FLAGS_FAMILY))); ASSERT_NOTREACHED_RVAL(FALSE); } } /* If the socket isn't open yet, open it and get a file descriptor. */ if (self->fd < 0) { if (SPIF_SOCKET_FLAGS_IS_SET(self, SPIF_SOCKET_FLAGS_TYPE_STREAM)) { self->type = SOCK_STREAM; } else if (SPIF_SOCKET_FLAGS_IS_SET(self, SPIF_SOCKET_FLAGS_TYPE_DGRAM)) { self->type = SOCK_DGRAM; } else if (SPIF_SOCKET_FLAGS_IS_SET(self, SPIF_SOCKET_FLAGS_TYPE_RAW)) { self->type = SOCK_RAW; } else { D_OBJ(("Unknown socket type 0x%08x!\n", SPIF_SOCKET_FLAGS_IS_SET(self, SPIF_SOCKET_FLAGS_TYPE))); ASSERT_NOTREACHED_RVAL(FALSE); } self->fd = (spif_sockfd_t) socket(self->fam, self->type, self->proto); if (self->fd < 0) { libast_print_error("Unable to create socket(%d, %d, %d) -- %s\n", (int) self->fam, (int) self->type, (int) self->proto, strerror(errno)); return FALSE; } /* If we have a local URL, bind it to the appropriate address and port. */ if (!SPIF_URL_ISNULL(self->local_url)) { if (SPIF_SOCKET_FLAGS_IS_SET(self, SPIF_SOCKET_FLAGS_FAMILY_INET)) { spif_ipsockaddr_t addr; addr = spif_url_get_ipaddr(self->local_url); D_OBJ(("Binding to port %d\n", ntohs(addr->sin_port))); if (bind(self->fd, (spif_sockaddr_t) addr, SPIF_SIZEOF_TYPE(ipsockaddr))) { libast_print_error("Unable to bind socket %d to %s -- %s\n", (int) self->fd, SPIF_STR_STR(self->local_url), strerror(errno)); FREE(addr); return FALSE; } FREE(addr); } else if (SPIF_SOCKET_FLAGS_IS_SET(self, SPIF_SOCKET_FLAGS_FAMILY_UNIX)) { spif_unixsockaddr_t addr; addr = spif_url_get_unixaddr(self->local_url); if (bind(self->fd, (spif_sockaddr_t) addr, SPIF_SIZEOF_TYPE(unixsockaddr))) { libast_print_error("Unable to bind socket %d to %s -- %s\n", (int) self->fd, SPIF_STR_STR(self->local_url), strerror(errno)); FREE(addr); return FALSE; } FREE(addr); } } SPIF_SOCKET_FLAGS_SET(self, SPIF_SOCKET_FLAGS_OPEN); } /* Connect if we have a destination. If not, open a listening socket. */ if (!SPIF_URL_ISNULL(self->remote_url)) { spif_socket_clear_nbio(self); if ((connect(self->fd, self->addr, self->len)) < 0) { libast_print_error("Unable to connect socket %d to %s -- %s\n", (int) self->fd, SPIF_STR_STR(self->remote_url), strerror(errno)); return FALSE; } SPIF_SOCKET_FLAGS_SET(self, SPIF_SOCKET_FLAGS_CONNECTED); } else if (!SPIF_URL_ISNULL(self->local_url)) { if ((listen(self->fd, 5)) < 0) { libast_print_error("Unable to listen at %s on socket %d -- %s\n", SPIF_STR_STR(self->local_url), (int) self->fd, strerror(errno)); return FALSE; } SPIF_SOCKET_FLAGS_SET(self, SPIF_SOCKET_FLAGS_LISTEN); } return TRUE; }
spif_classname_t spif_url_type(spif_url_t self) { ASSERT_RVAL(!SPIF_URL_ISNULL(self), (spif_classname_t) NULL); return SPIF_OBJ_CLASSNAME(self); }
static spif_bool_t spif_url_parse(spif_url_t self) { spif_charptr_t s = SPIF_STR_STR(SPIF_STR(self)); spif_charptr_t pstr, pend, ptmp; ASSERT_RVAL(!SPIF_URL_ISNULL(self), FALSE); pstr = s; /* Check for "proto:" at the beginning. */ pend = SPIF_CHARPTR(strchr((char *) s, ':')); if (pend) { for (; pstr < pend; pstr++) { if (!isalnum(*pstr)) { break; } } if (pstr == pend) { /* Got one. */ self->proto = spif_str_new_from_buff(s, pend - s); pstr++; } else { /* Nope, reset. */ pstr = s; } } if ((*pstr == '/') && (pstr[1] == '/')) { pstr += 2; } /* Knock out the path and query if they're there. */ pend = SPIF_CHARPTR(strchr((char *) pstr, '/')); if (pend) { spif_charptr_t tmp = SPIF_CHARPTR(strchr((char *) pend, '?')); if (tmp) { self->query = spif_str_new_from_ptr(tmp + 1); self->path = spif_str_new_from_buff(pend, tmp - pend); } else { self->path = spif_str_new_from_ptr(pend); } } else if ((pend = SPIF_CHARPTR(strchr((char *)pstr, '?')))) { self->query = spif_str_new_from_ptr(pend + 1); } else { for (pend = pstr; *pend; pend++); } /* At this point, pend *must* point to the end of the user/pass/host/port part. */ /* Check for an @ sign, which would mean we have auth info. */ ptmp = SPIF_CHARPTR(strchr((char *) pstr, '@')); if ((ptmp) && (ptmp < pend)) { spif_charptr_t tmp = SPIF_CHARPTR(strchr((char *) pstr, ':')); if ((tmp) && (tmp < ptmp)) { /* Both username and password. */ self->user = spif_str_new_from_buff(pstr, tmp - pstr); self->passwd = spif_str_new_from_buff((tmp + 1), ptmp - tmp - 1); } else { self->user = spif_str_new_from_buff(pstr, ptmp - pstr); } pstr = ptmp + 1; } /* All that remains now between pstr and pend is host and maybe port. */ ptmp = SPIF_CHARPTR(strchr((char *) pstr, ':')); if ((ptmp) && (ptmp < pend)) { self->host = spif_str_new_from_buff(pstr, ptmp - pstr); self->port = spif_str_new_from_buff((ptmp + 1), pend - ptmp - 1); } else if (pstr != pend) { self->host = spif_str_new_from_buff(pstr, pend - pstr); } /* If we have a proto but no port, see if we can resolve the port using the proto. */ if (SPIF_STR_ISNULL(self->port) && !SPIF_STR_ISNULL(self->proto)) { spif_protoinfo_t proto; spif_servinfo_t serv; proto = getprotobyname((char *) SPIF_STR_STR(self->proto)); if (!proto) { /* If it's not a protocol, it's probably a service. */ serv = getservbyname((char *) SPIF_STR_STR(self->proto), "tcp"); if (!serv) { serv = getservbyname((char *) SPIF_STR_STR(self->proto), "udp"); } if (serv) { proto = getprotobyname(serv->s_proto); REQUIRE_RVAL(proto != NULL, FALSE); } } if (proto) { spif_char_t buff[32]; snprintf((char *) buff, sizeof(buff), "%d", ntohs(serv->s_port)); self->port = spif_str_new_from_ptr(buff); } } return TRUE; }