Complete <netdb.h>.
Add all the missing <netdb.h> functions.
Also fix getservbyport to handle a null protocol correctly.
Also fix getservbyname/getservbyport to not interfere with getservent.
Also fix endservent to reset getservent iteration.
Also reduce unnecessary differences from upstream NetBSD sethostent.c.
The servent implementation is still horrific, and we should
probably support protoent too so that debugging tools can use
getprotobyname/getprotobynumber.
Bug: N/A
Test: ran tests
Change-Id: I639108c46df0a768af297cf3bbce857cb1bef9d9
diff --git a/libc/dns/net/getservent.c b/libc/dns/net/getservent.c
index 0a727c7..03add59 100644
--- a/libc/dns/net/getservent.c
+++ b/libc/dns/net/getservent.c
@@ -25,32 +25,17 @@
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
-#include <sys/types.h>
-#include <endian.h>
-#include <malloc.h>
+
#include <netdb.h>
-#include "servent.h"
+
+#include <endian.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "resolv_static.h"
#include "services.h"
-void
-setservent(int f)
-{
- res_static rs = __res_get_static();
- if (rs) {
- rs->servent_ptr = NULL;
- }
-}
-
-void
-endservent(void)
-{
- /* nothing to do */
-}
-
-struct servent *
-getservent_r( res_static rs )
-{
+struct servent* getservent_r(res_static rs) {
const char* p;
const char* q;
int namelen;
@@ -119,12 +104,48 @@
return &rs->servent;
}
-struct servent *
-getservent(void)
-{
- res_static rs = __res_get_static();
+void setservent(int stayopen) {
+ endservent();
+}
- if (rs == NULL) return NULL;
+void endservent(void) {
+ res_static rs = __res_get_static();
+ if (rs) rs->servent_ptr = NULL;
+}
- return getservent_r(rs);
+struct servent* getservent(void) {
+ res_static rs = __res_get_static();
+ return rs ? getservent_r(rs) : NULL;
+}
+
+struct servent* getservbyname(const char* name, const char* proto) {
+ res_static rs = __res_get_static();
+ if (rs == NULL) return NULL;
+
+ const char* old_servent_ptr = rs->servent_ptr;
+ rs->servent_ptr = NULL;
+ struct servent* s;
+ while ((s = getservent_r(rs)) != NULL) {
+ if (strcmp(s->s_name, name) == 0 && (proto == NULL || strcmp(s->s_proto, proto) == 0)) {
+ break;
+ }
+ }
+ rs->servent_ptr = old_servent_ptr;
+ return s;
+}
+
+struct servent* getservbyport(int port, const char* proto) {
+ res_static rs = __res_get_static();
+ if (rs == NULL) return NULL;
+
+ const char* old_servent_ptr = rs->servent_ptr;
+ rs->servent_ptr = NULL;
+ struct servent* s;
+ while ((s = getservent_r(rs)) != NULL) {
+ if (s->s_port == port && (proto == NULL || strcmp(s->s_proto, proto) == 0)) {
+ break;
+ }
+ }
+ rs->servent_ptr = old_servent_ptr;
+ return s;
}