summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/lib/libc/net/getproto.c31
-rw-r--r--src/lib/libc/net/getprotoent.359
-rw-r--r--src/lib/libc/net/getprotoent.c121
-rw-r--r--src/lib/libc/net/getprotoname.c32
-rw-r--r--src/lib/libc/net/getservbyname.c33
-rw-r--r--src/lib/libc/net/getservbyport.c31
-rw-r--r--src/lib/libc/net/getservent.359
-rw-r--r--src/lib/libc/net/getservent.c122
8 files changed, 346 insertions, 142 deletions
diff --git a/src/lib/libc/net/getproto.c b/src/lib/libc/net/getproto.c
index dee089d5c2..3f05a93cce 100644
--- a/src/lib/libc/net/getproto.c
+++ b/src/lib/libc/net/getproto.c
@@ -28,24 +28,33 @@
28 */ 28 */
29 29
30#if defined(LIBC_SCCS) && !defined(lint) 30#if defined(LIBC_SCCS) && !defined(lint)
31static char rcsid[] = "$OpenBSD: getproto.c,v 1.4 2003/06/02 20:18:35 millert Exp $"; 31static char rcsid[] = "$OpenBSD: getproto.c,v 1.5 2004/10/17 20:24:23 millert Exp $";
32#endif /* LIBC_SCCS and not lint */ 32#endif /* LIBC_SCCS and not lint */
33 33
34#include <netdb.h> 34#include <netdb.h>
35 35#include <stdio.h>
36extern int _proto_stayopen;
37 36
38struct protoent * 37struct protoent *
39getprotobynumber(proto) 38getprotobynumber_r(int num, struct protoent *pe, struct protoent_data *pd)
40 register int proto;
41{ 39{
42 register struct protoent *p; 40 struct protoent *p;
43 41
44 setprotoent(_proto_stayopen); 42 setprotoent_r(pd->stayopen, pd);
45 while ((p = getprotoent())) 43 while ((p = getprotoent_r(pe, pd)))
46 if (p->p_proto == proto) 44 if (p->p_proto == num)
47 break; 45 break;
48 if (!_proto_stayopen) 46 if (!pd->stayopen && pd->fp != NULL) {
49 endprotoent(); 47 (void)fclose(pd->fp);
48 pd->fp = NULL;
49 }
50 return (p); 50 return (p);
51} 51}
52
53struct protoent *
54getprotobynumber(int num)
55{
56 extern struct protoent_data _protoent_data;
57 static struct protoent proto;
58
59 return getprotobynumber_r(num, &proto, &_protoent_data);
60}
diff --git a/src/lib/libc/net/getprotoent.3 b/src/lib/libc/net/getprotoent.3
index 5c41e6fb7c..2497f9f7ca 100644
--- a/src/lib/libc/net/getprotoent.3
+++ b/src/lib/libc/net/getprotoent.3
@@ -1,4 +1,4 @@
1.\" $OpenBSD: getprotoent.3,v 1.10 2004/02/01 19:45:00 nordin Exp $ 1.\" $OpenBSD: getprotoent.3,v 1.11 2004/10/17 20:24:23 millert Exp $
2.\" 2.\"
3.\" Copyright (c) 1983, 1991, 1993 3.\" Copyright (c) 1983, 1991, 1993
4.\" The Regents of the University of California. All rights reserved. 4.\" The Regents of the University of California. All rights reserved.
@@ -27,28 +27,43 @@
27.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28.\" SUCH DAMAGE. 28.\" SUCH DAMAGE.
29.\" 29.\"
30.Dd June 4, 1993 30.Dd October 13, 2004
31.Dt GETPROTOENT 3 31.Dt GETPROTOENT 3
32.Os 32.Os
33.Sh NAME 33.Sh NAME
34.Nm getprotoent , 34.Nm getprotoent ,
35.Nm getprotoent_r ,
35.Nm getprotobynumber , 36.Nm getprotobynumber ,
37.Nm getprotobynumber_r ,
36.Nm getprotobyname , 38.Nm getprotobyname ,
39.Nm getprotobyname_r ,
37.Nm setprotoent , 40.Nm setprotoent ,
38.Nm endprotoent 41.Nm setprotoent_r ,
42.Nm endprotoent ,
43.Nm endprotoent_r
39.Nd get protocol entry 44.Nd get protocol entry
40.Sh SYNOPSIS 45.Sh SYNOPSIS
41.Fd #include <netdb.h> 46.Fd #include <netdb.h>
42.Ft struct protoent * 47.Ft struct protoent *
43.Fn getprotoent "void" 48.Fn getprotoent "void"
44.Ft struct protoent * 49.Ft struct protoent *
50.Fn getprotoent_r "struct protoent *protoent" "struct protoent_data *protoent_data"
51.Ft struct protoent *
45.Fn getprotobyname "const char *name" 52.Fn getprotobyname "const char *name"
46.Ft struct protoent * 53.Ft struct protoent *
54.Fn getprotobyname_r "const char *name" "struct protoent *protoent" "struct protoent_data *protoent_data"
55.Ft struct protoent *
47.Fn getprotobynumber "int proto" 56.Fn getprotobynumber "int proto"
57.Ft struct protoent *
58.Fn getprotobynumber_r "int proto" "struct protoent *protoent" "struct protoent_data *protoent_data"
48.Ft void 59.Ft void
49.Fn setprotoent "int stayopen" 60.Fn setprotoent "int stayopen"
50.Ft void 61.Ft void
62.Fn setprotoent_r "int stayopen" "struct protoent_data *protoent_data"
63.Ft void
51.Fn endprotoent "void" 64.Fn endprotoent "void"
65.Ft void
66.Fn endprotoent_r "void" "struct protoent_data *protoent_data"
52.Sh DESCRIPTION 67.Sh DESCRIPTION
53The 68The
54.Fn getprotoent , 69.Fn getprotoent ,
@@ -104,6 +119,30 @@ functions sequentially search from the beginning of the file until a
104matching protocol name or protocol number is found, or until 119matching protocol name or protocol number is found, or until
105.Dv EOF 120.Dv EOF
106is encountered. 121is encountered.
122.Pp
123The
124.Fn getprotoent_r ,
125.Fn getprotobyport_r ,
126.Fn getprotobyname_r ,
127.Fn setprotoent_r ,
128and
129.Fn endprotoent_r
130functions are reentrant versions of the above functions that take a
131pointer to a
132.Fa protoent_data
133structure which is used to store state information.
134The structure must be zero-filled before it is used
135and should be considered opaque for the sake of portability.
136.Pp
137The
138.Fn getprotoent_r ,
139.Fn getprotobyport_r ,
140and
141.Fn getprotobyname_r
142functions
143also take a pointer to a
144.Fa protoent
145structure which is used to store the results of the database lookup.
107.Sh RETURN VALUES 146.Sh RETURN VALUES
108Null pointer (0) returned on 147Null pointer (0) returned on
109.Dv EOF 148.Dv EOF
@@ -124,7 +163,17 @@ and
124.Fn endprotoent 163.Fn endprotoent
125functions appeared in 164functions appeared in
126.Bx 4.2 . 165.Bx 4.2 .
166.Pp
167The
168.Fn getprotoent_r ,
169.Fn getprotobyport_r ,
170.Fn getprotobyname_r ,
171.Fn setprotoent_r ,
172and
173.Fn endprotoent_r
174functions appeared in
175.Ox 3.7 .
127.Sh BUGS 176.Sh BUGS
128These functions use a static data space; if the data is needed for future use, 177The non-reentrant functions use a static data space; if the data is needed
129it should be copied before any subsequent calls overwrite it. 178for future use, it should be copied before any subsequent calls overwrite it.
130Only the Internet protocols are currently understood. 179Only the Internet protocols are currently understood.
diff --git a/src/lib/libc/net/getprotoent.c b/src/lib/libc/net/getprotoent.c
index b2bdd2e164..f3327db9bd 100644
--- a/src/lib/libc/net/getprotoent.c
+++ b/src/lib/libc/net/getprotoent.c
@@ -28,69 +28,68 @@
28 */ 28 */
29 29
30#if defined(LIBC_SCCS) && !defined(lint) 30#if defined(LIBC_SCCS) && !defined(lint)
31static char rcsid[] = "$OpenBSD: getprotoent.c,v 1.5 2003/06/02 20:18:35 millert Exp $"; 31static char rcsid[] = "$OpenBSD: getprotoent.c,v 1.6 2004/10/17 20:24:23 millert Exp $";
32#endif /* LIBC_SCCS and not lint */ 32#endif /* LIBC_SCCS and not lint */
33 33
34#include <sys/types.h> 34#include <sys/types.h>
35#include <sys/socket.h> 35#include <sys/socket.h>
36
37#include <errno.h>
36#include <netdb.h> 38#include <netdb.h>
37#include <stdio.h> 39#include <stdio.h>
38#include <stdlib.h> 40#include <stdlib.h>
39#include <string.h> 41#include <string.h>
40 42
41#define MAXALIASES 35
42
43static FILE *protof = NULL;
44static char line[BUFSIZ+1];
45static struct protoent proto;
46static char *proto_aliases[MAXALIASES];
47int _proto_stayopen;
48
49void 43void
50setprotoent(f) 44setprotoent_r(int f, struct protoent_data *pd)
51 int f;
52{ 45{
53 if (protof == NULL) 46 if (pd->fp == NULL)
54 protof = fopen(_PATH_PROTOCOLS, "r" ); 47 pd->fp = fopen(_PATH_PROTOCOLS, "r" );
55 else 48 else
56 rewind(protof); 49 rewind(pd->fp);
57 _proto_stayopen |= f; 50 pd->stayopen |= f;
58} 51}
59 52
60void 53void
61endprotoent() 54endprotoent_r(struct protoent_data *pd)
62{ 55{
63 if (protof) { 56 if (pd->fp) {
64 fclose(protof); 57 fclose(pd->fp);
65 protof = NULL; 58 pd->fp = NULL;
66 } 59 }
67 _proto_stayopen = 0; 60 free(pd->aliases);
61 pd->aliases = NULL;
62 pd->maxaliases = 0;
63 free(pd->line);
64 pd->line = NULL;
65 pd->stayopen = 0;
68} 66}
69 67
70struct protoent * 68struct protoent *
71getprotoent() 69getprotoent_r(struct protoent *pe, struct protoent_data *pd)
72{ 70{
73 char *p, *cp, **q, *endp; 71 char *p, *cp, **q, *endp;
74 long l;
75 size_t len; 72 size_t len;
73 long l;
74 int serrno;
76 75
77 if (protof == NULL && (protof = fopen(_PATH_PROTOCOLS, "r" )) == NULL) 76 if (pd->fp == NULL && (pd->fp = fopen(_PATH_PROTOCOLS, "r" )) == NULL)
78 return (NULL); 77 return (NULL);
79again: 78again:
80 if ((p = fgetln(protof, &len)) == NULL) 79 if ((p = fgetln(pd->fp, &len)) == NULL)
81 return (NULL); 80 return (NULL);
81 if (len == 0 || *p == '#' || *p == '\n')
82 goto again;
82 if (p[len-1] == '\n') 83 if (p[len-1] == '\n')
83 len--; 84 len--;
84 if (len >= sizeof(line) || len == 0) 85 if ((cp = memchr(p, '#', len)) != NULL)
85 goto again; 86 len = cp - p;
86 p = memcpy(line, p, len); 87 cp = realloc(pd->line, len + 1);
87 line[len] = '\0'; 88 if (cp == NULL)
88 if (*p == '#') 89 return (NULL);
89 goto again; 90 pd->line = pe->p_name = memcpy(cp, p, len);
90 if ((cp = strchr(p, '#')) != NULL) 91 cp[len] = '\0';
91 *cp = '\0'; 92 cp = strpbrk(cp, " \t");
92 proto.p_name = p;
93 cp = strpbrk(p, " \t");
94 if (cp == NULL) 93 if (cp == NULL)
95 goto again; 94 goto again;
96 *cp++ = '\0'; 95 *cp++ = '\0';
@@ -102,8 +101,18 @@ again:
102 l = strtol(cp, &endp, 10); 101 l = strtol(cp, &endp, 10);
103 if (endp == cp || *endp != '\0' || l < 0 || l >= INT_MAX) 102 if (endp == cp || *endp != '\0' || l < 0 || l >= INT_MAX)
104 goto again; 103 goto again;
105 proto.p_proto = l; 104 pe->p_proto = l;
106 q = proto.p_aliases = proto_aliases; 105 if (pd->aliases == NULL) {
106 pd->maxaliases = 5;
107 pd->aliases = malloc(pd->maxaliases * sizeof(char *));
108 if (pd->aliases == NULL) {
109 serrno = errno;
110 endprotoent_r(pd);
111 errno = serrno;
112 return (NULL);
113 }
114 }
115 q = pe->p_aliases = pd->aliases;
107 if (p != NULL) { 116 if (p != NULL) {
108 cp = p; 117 cp = p;
109 while (cp && *cp) { 118 while (cp && *cp) {
@@ -111,13 +120,47 @@ again:
111 cp++; 120 cp++;
112 continue; 121 continue;
113 } 122 }
114 if (q < &proto_aliases[MAXALIASES - 1]) 123 if (q == &pe->p_aliases[pd->maxaliases - 1]) {
115 *q++ = cp; 124 p = realloc(pe->p_aliases,
125 2 * pd->maxaliases * sizeof(char *));
126 if (p == NULL) {
127 serrno = errno;
128 endprotoent_r(pd);
129 errno = serrno;
130 return (NULL);
131 }
132 pd->maxaliases *= 2;
133 q = (char **)p + (q - pe->p_aliases);
134 pe->p_aliases = pd->aliases = (char **)p;
135 }
136 *q++ = cp;
116 cp = strpbrk(cp, " \t"); 137 cp = strpbrk(cp, " \t");
117 if (cp != NULL) 138 if (cp != NULL)
118 *cp++ = '\0'; 139 *cp++ = '\0';
119 } 140 }
120 } 141 }
121 *q = NULL; 142 *q = NULL;
122 return (&proto); 143 return (pe);
144}
145
146struct protoent_data _protoent_data; /* shared with getproto{,name}.c */
147
148void
149setprotoent(int f)
150{
151 setprotoent_r(f, &_protoent_data);
152}
153
154void
155endprotoent(void)
156{
157 endprotoent_r(&_protoent_data);
158}
159
160struct protoent *
161getprotoent(void)
162{
163 static struct protoent proto;
164
165 return getprotoent_r(&proto, &_protoent_data);
123} 166}
diff --git a/src/lib/libc/net/getprotoname.c b/src/lib/libc/net/getprotoname.c
index 4742a60a04..429304e7a1 100644
--- a/src/lib/libc/net/getprotoname.c
+++ b/src/lib/libc/net/getprotoname.c
@@ -28,23 +28,22 @@
28 */ 28 */
29 29
30#if defined(LIBC_SCCS) && !defined(lint) 30#if defined(LIBC_SCCS) && !defined(lint)
31static char rcsid[] = "$OpenBSD: getprotoname.c,v 1.4 2003/06/02 20:18:35 millert Exp $"; 31static char rcsid[] = "$OpenBSD: getprotoname.c,v 1.5 2004/10/17 20:24:23 millert Exp $";
32#endif /* LIBC_SCCS and not lint */ 32#endif /* LIBC_SCCS and not lint */
33 33
34#include <netdb.h> 34#include <netdb.h>
35#include <stdio.h>
35#include <string.h> 36#include <string.h>
36 37
37extern int _proto_stayopen;
38
39struct protoent * 38struct protoent *
40getprotobyname(name) 39getprotobyname_r(const char *name, struct protoent *pe,
41 register const char *name; 40 struct protoent_data *pd)
42{ 41{
43 register struct protoent *p; 42 struct protoent *p;
44 register char **cp; 43 char **cp;
45 44
46 setprotoent(_proto_stayopen); 45 setprotoent_r(pd->stayopen, pd);
47 while ((p = getprotoent())) { 46 while ((p = getprotoent_r(pe, pd))) {
48 if (strcmp(p->p_name, name) == 0) 47 if (strcmp(p->p_name, name) == 0)
49 break; 48 break;
50 for (cp = p->p_aliases; *cp != 0; cp++) 49 for (cp = p->p_aliases; *cp != 0; cp++)
@@ -52,7 +51,18 @@ getprotobyname(name)
52 goto found; 51 goto found;
53 } 52 }
54found: 53found:
55 if (!_proto_stayopen) 54 if (!pd->stayopen && pd->fp != NULL) {
56 endprotoent(); 55 fclose(pd->fp);
56 pd->fp = NULL;
57 }
57 return (p); 58 return (p);
58} 59}
60
61struct protoent *
62getprotobyname(const char *name)
63{
64 extern struct protoent_data _protoent_data;
65 static struct protoent proto;
66
67 return getprotobyname_r(name, &proto, &_protoent_data);
68}
diff --git a/src/lib/libc/net/getservbyname.c b/src/lib/libc/net/getservbyname.c
index c5f42a7b9c..597c42497f 100644
--- a/src/lib/libc/net/getservbyname.c
+++ b/src/lib/libc/net/getservbyname.c
@@ -28,27 +28,22 @@
28 */ 28 */
29 29
30#if defined(LIBC_SCCS) && !defined(lint) 30#if defined(LIBC_SCCS) && !defined(lint)
31static char rcsid[] = "$OpenBSD: getservbyname.c,v 1.7 2004/09/16 03:16:50 deraadt Exp $"; 31static char rcsid[] = "$OpenBSD: getservbyname.c,v 1.8 2004/10/17 20:24:23 millert Exp $";
32#endif /* LIBC_SCCS and not lint */ 32#endif /* LIBC_SCCS and not lint */
33 33
34#include <netdb.h> 34#include <netdb.h>
35#include <stdio.h>
35#include <string.h> 36#include <string.h>
36#include "thread_private.h"
37
38extern int _serv_stayopen;
39
40_THREAD_PRIVATE_MUTEX(getservbyname_r);
41 37
42struct servent * 38struct servent *
43getservbyname_r(const char *name, const char *proto, struct servent *se, 39getservbyname_r(const char *name, const char *proto, struct servent *se,
44 char *buf, int buflen) 40 struct servent_data *sd)
45{ 41{
46 struct servent *p; 42 struct servent *p;
47 char **cp; 43 char **cp;
48 44
49 _THREAD_PRIVATE_MUTEX_LOCK(getservbyname_r); 45 setservent_r(sd->stayopen, sd);
50 setservent(_serv_stayopen); 46 while ((p = getservent_r(se, sd))) {
51 while ((p = getservent())) {
52 if (strcmp(name, p->s_name) == 0) 47 if (strcmp(name, p->s_name) == 0)
53 goto gotname; 48 goto gotname;
54 for (cp = p->s_aliases; *cp; cp++) 49 for (cp = p->s_aliases; *cp; cp++)
@@ -59,22 +54,18 @@ gotname:
59 if (proto == 0 || strcmp(p->s_proto, proto) == 0) 54 if (proto == 0 || strcmp(p->s_proto, proto) == 0)
60 break; 55 break;
61 } 56 }
62 if (!_serv_stayopen) 57 if (!sd->stayopen && sd->fp != NULL) {
63 endservent(); 58 fclose(sd->fp);
64 _THREAD_PRIVATE_MUTEX_UNLOCK(getservbyname_r); 59 sd->fp = NULL;
60 }
65 return (p); 61 return (p);
66} 62}
67 63
68struct servent * 64struct servent *
69getservbyname(const char *name, const char *proto) 65getservbyname(const char *name, const char *proto)
70{ 66{
71 _THREAD_PRIVATE_KEY(getservbyname); 67 extern struct servent_data _servent_data;
72 static char buf[4096]; 68 static struct servent serv;
73 char *bufp = (char*)_THREAD_PRIVATE(getservbyname, buf, NULL);
74 69
75 if (bufp == NULL) 70 return (getservbyname_r(name, proto, &serv, &_servent_data));
76 return (NULL);
77 return getservbyname_r(name, proto, (struct servent*) bufp,
78 bufp + sizeof(struct servent),
79 sizeof buf - sizeof(struct servent) );
80} 71}
diff --git a/src/lib/libc/net/getservbyport.c b/src/lib/libc/net/getservbyport.c
index 992a77d638..e8b8efc504 100644
--- a/src/lib/libc/net/getservbyport.c
+++ b/src/lib/libc/net/getservbyport.c
@@ -28,29 +28,38 @@
28 */ 28 */
29 29
30#if defined(LIBC_SCCS) && !defined(lint) 30#if defined(LIBC_SCCS) && !defined(lint)
31static char rcsid[] = "$OpenBSD: getservbyport.c,v 1.4 2003/06/02 20:18:35 millert Exp $"; 31static char rcsid[] = "$OpenBSD: getservbyport.c,v 1.5 2004/10/17 20:24:23 millert Exp $";
32#endif /* LIBC_SCCS and not lint */ 32#endif /* LIBC_SCCS and not lint */
33 33
34#include <netdb.h> 34#include <netdb.h>
35#include <stdio.h>
35#include <string.h> 36#include <string.h>
36 37
37extern int _serv_stayopen;
38
39struct servent * 38struct servent *
40getservbyport(port, proto) 39getservbyport_r(int port, const char *proto, struct servent *se,
41 int port; 40 struct servent_data *sd)
42 const char *proto;
43{ 41{
44 register struct servent *p; 42 struct servent *p;
45 43
46 setservent(_serv_stayopen); 44 setservent_r(sd->stayopen, sd);
47 while ((p = getservent())) { 45 while ((p = getservent_r(se, sd))) {
48 if (p->s_port != port) 46 if (p->s_port != port)
49 continue; 47 continue;
50 if (proto == 0 || strcmp(p->s_proto, proto) == 0) 48 if (proto == 0 || strcmp(p->s_proto, proto) == 0)
51 break; 49 break;
52 } 50 }
53 if (!_serv_stayopen) 51 if (!sd->stayopen && sd->fp != NULL) {
54 endservent(); 52 fclose(sd->fp);
53 sd->fp = NULL;
54 }
55 return (p); 55 return (p);
56} 56}
57
58struct servent *
59getservbyport(int port, const char *proto)
60{
61 extern struct servent_data _servent_data;
62 static struct servent serv;
63
64 return (getservbyport_r(port, proto, &serv, &_servent_data));
65}
diff --git a/src/lib/libc/net/getservent.3 b/src/lib/libc/net/getservent.3
index af75f5037b..f5294b8f70 100644
--- a/src/lib/libc/net/getservent.3
+++ b/src/lib/libc/net/getservent.3
@@ -1,4 +1,4 @@
1.\" $OpenBSD: getservent.3,v 1.13 2003/12/30 10:35:36 jmc Exp $ 1.\" $OpenBSD: getservent.3,v 1.14 2004/10/17 20:24:23 millert Exp $
2.\" 2.\"
3.\" Copyright (c) 1983, 1991, 1993 3.\" Copyright (c) 1983, 1991, 1993
4.\" The Regents of the University of California. All rights reserved. 4.\" The Regents of the University of California. All rights reserved.
@@ -27,28 +27,43 @@
27.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28.\" SUCH DAMAGE. 28.\" SUCH DAMAGE.
29.\" 29.\"
30.Dd January 12, 1994 30.Dd October 13, 2004
31.Dt GETSERVENT 3 31.Dt GETSERVENT 3
32.Os 32.Os
33.Sh NAME 33.Sh NAME
34.Nm getservent , 34.Nm getservent ,
35.Nm getservent_r ,
35.Nm getservbyport , 36.Nm getservbyport ,
37.Nm getservbyport_r ,
36.Nm getservbyname , 38.Nm getservbyname ,
39.Nm getservbyname_r ,
37.Nm setservent , 40.Nm setservent ,
38.Nm endservent 41.Nm setservent_r ,
42.Nm endservent ,
43.Nm endservent_r
39.Nd get service entry 44.Nd get service entry
40.Sh SYNOPSIS 45.Sh SYNOPSIS
41.Fd #include <netdb.h> 46.Fd #include <netdb.h>
42.Ft struct servent * 47.Ft struct servent *
43.Fn getservent "void" 48.Fn getservent "void"
44.Ft struct servent * 49.Ft struct servent *
50.Fn getservent_r "struct servent *servent" "struct servent_data *servent_data"
51.Ft struct servent *
45.Fn getservbyname "const char *name" "const char *proto" 52.Fn getservbyname "const char *name" "const char *proto"
46.Ft struct servent * 53.Ft struct servent *
54.Fn getservbyname_r "const char *name" "const char *proto" "struct servent *servent" "struct servent_data *servent_data"
55.Ft struct servent *
47.Fn getservbyport "int port" "const char *proto" 56.Fn getservbyport "int port" "const char *proto"
57.Ft struct servent *
58.Fn getservbyport_r "int port" "const char *proto" "struct servent *servent" "struct servent_data *servent_data"
48.Ft void 59.Ft void
49.Fn setservent "int stayopen" 60.Fn setservent "int stayopen"
50.Ft void 61.Ft void
62.Fn setservent_r "int stayopen" "struct servent_data *servent_data"
63.Ft void
51.Fn endservent "void" 64.Fn endservent "void"
65.Ft void
66.Fn endservent_r "struct servent_data *servent_data"
52.Sh DESCRIPTION 67.Sh DESCRIPTION
53The 68The
54.Fn getservent , 69.Fn getservent ,
@@ -110,6 +125,30 @@ is found, or until
110is encountered. 125is encountered.
111If a protocol name is also supplied (non-null), 126If a protocol name is also supplied (non-null),
112searches must also match the protocol. 127searches must also match the protocol.
128.Pp
129The
130.Fn getservent_r ,
131.Fn getservbyport_r ,
132.Fn getservbyname_r ,
133.Fn setservent_r ,
134and
135.Fn endservent_r
136functions are reentrant versions of the above functions that take a
137pointer to a
138.Fa servent_data
139structure which is used to store state information.
140The structure must be zero-filled before it is used
141and should be considered opaque for the sake of portability.
142.Pp
143The
144.Fn getservent_r ,
145.Fn getservbyport_r ,
146and
147.Fn getservbyname_r
148functions
149also take a pointer to a
150.Fa servent
151structure which is used to store the results of the database lookup.
113.Sh FILES 152.Sh FILES
114.Bl -tag -width /etc/services -compact 153.Bl -tag -width /etc/services -compact
115.It Pa /etc/services 154.It Pa /etc/services
@@ -130,8 +169,18 @@ The
130and 169and
131.Fn endservent 170.Fn endservent
132functions appeared in 171functions appeared in
172.Pp
133.Bx 4.2 . 173.Bx 4.2 .
174The
175.Fn getservent_r ,
176.Fn getservbyport_r ,
177.Fn getservbyname_r ,
178.Fn setservent_r ,
179and
180.Fn endservent_r
181functions appeared in
182.Ox 3.7 .
134.Sh BUGS 183.Sh BUGS
135These functions use static data storage; if the data is needed for future use, 184The non-reentrant functions use static data storage; if the data is needed
136it should be copied before any subsequent calls overwrite it. 185for future use, it should be copied before any subsequent calls overwrite it.
137Expecting port numbers to fit in a 32-bit quantity is probably naive. 186Expecting port numbers to fit in a 32-bit quantity is probably naive.
diff --git a/src/lib/libc/net/getservent.c b/src/lib/libc/net/getservent.c
index 475e25a1f8..9cf53774d6 100644
--- a/src/lib/libc/net/getservent.c
+++ b/src/lib/libc/net/getservent.c
@@ -28,68 +28,68 @@
28 */ 28 */
29 29
30#if defined(LIBC_SCCS) && !defined(lint) 30#if defined(LIBC_SCCS) && !defined(lint)
31static char rcsid[] = "$OpenBSD: getservent.c,v 1.7 2004/09/16 03:13:22 deraadt Exp $"; 31static char rcsid[] = "$OpenBSD: getservent.c,v 1.8 2004/10/17 20:24:23 millert Exp $";
32#endif /* LIBC_SCCS and not lint */ 32#endif /* LIBC_SCCS and not lint */
33 33
34#include <sys/types.h> 34#include <sys/types.h>
35#include <sys/socket.h> 35#include <sys/socket.h>
36
37#include <errno.h>
36#include <netdb.h> 38#include <netdb.h>
37#include <stdio.h> 39#include <stdio.h>
38#include <string.h> 40#include <string.h>
39#include <stdlib.h> 41#include <stdlib.h>
40 42
41#define MAXALIASES 35
42
43static FILE *servf = NULL;
44static char line[BUFSIZ+1];
45static struct servent serv;
46static char *serv_aliases[MAXALIASES];
47int _serv_stayopen;
48
49void 43void
50setservent(int f) 44setservent_r(int f, struct servent_data *sd)
51{ 45{
52 if (servf == NULL) 46 if (sd->fp == NULL)
53 servf = fopen(_PATH_SERVICES, "r" ); 47 sd->fp = fopen(_PATH_SERVICES, "r" );
54 else 48 else
55 rewind(servf); 49 rewind(sd->fp);
56 _serv_stayopen |= f; 50 sd->stayopen |= f;
57} 51}
58 52
59void 53void
60endservent(void) 54endservent_r(struct servent_data *sd)
61{ 55{
62 if (servf) { 56 if (sd->fp) {
63 fclose(servf); 57 fclose(sd->fp);
64 servf = NULL; 58 sd->fp = NULL;
65 } 59 }
66 _serv_stayopen = 0; 60 free(sd->aliases);
61 sd->aliases = NULL;
62 sd->maxaliases = 0;
63 free(sd->line);
64 sd->line = NULL;
65 sd->stayopen = 0;
67} 66}
68 67
69struct servent * 68struct servent *
70getservent(void) 69getservent_r(struct servent *se, struct servent_data *sd)
71{ 70{
72 char *p, *cp, **q, *endp; 71 char *p, *cp, **q, *endp;
73 long l;
74 size_t len; 72 size_t len;
73 long l;
74 int serrno;
75 75
76 if (servf == NULL && (servf = fopen(_PATH_SERVICES, "r" )) == NULL) 76 if (sd->fp == NULL && (sd->fp = fopen(_PATH_SERVICES, "r" )) == NULL)
77 return (NULL); 77 return (NULL);
78again: 78again:
79 if ((p = fgetln(servf, &len)) == NULL) 79 if ((p = fgetln(sd->fp, &len)) == NULL)
80 return (NULL); 80 return (NULL);
81 if (len == 0 || *p == '#' || *p == '\n')
82 goto again;
81 if (p[len-1] == '\n') 83 if (p[len-1] == '\n')
82 len--; 84 len--;
83 if (len >= sizeof(line) || len == 0) 85 if ((cp = memchr(p, '#', len)) != NULL)
84 goto again; 86 len = cp - p;
85 p = memcpy(line, p, len); 87 cp = realloc(sd->line, len + 1);
86 line[len] = '\0'; 88 if (cp == NULL)
87 if (*p == '#') 89 return (NULL);
88 goto again; 90 sd->line = se->s_name = memcpy(cp, p, len);
89 if ((cp = strchr(p, '#')) != NULL) 91 cp[len] = '\0';
90 *cp = '\0'; 92 p = strpbrk(cp, " \t");
91 serv.s_name = p;
92 p = strpbrk(p, " \t");
93 if (p == NULL) 93 if (p == NULL)
94 goto again; 94 goto again;
95 *p++ = '\0'; 95 *p++ = '\0';
@@ -102,9 +102,19 @@ again:
102 l = strtol(p, &endp, 10); 102 l = strtol(p, &endp, 10);
103 if (endp == p || *endp != '\0' || l < 0 || l > USHRT_MAX) 103 if (endp == p || *endp != '\0' || l < 0 || l > USHRT_MAX)
104 goto again; 104 goto again;
105 serv.s_port = htons((in_port_t)l); 105 se->s_port = htons((in_port_t)l);
106 serv.s_proto = cp; 106 se->s_proto = cp;
107 q = serv.s_aliases = serv_aliases; 107 if (sd->aliases == NULL) {
108 sd->maxaliases = 10;
109 sd->aliases = malloc(sd->maxaliases * sizeof(char *));
110 if (sd->aliases == NULL) {
111 serrno = errno;
112 endservent_r(sd);
113 errno = serrno;
114 return (NULL);
115 }
116 }
117 q = se->s_aliases = sd->aliases;
108 cp = strpbrk(cp, " \t"); 118 cp = strpbrk(cp, " \t");
109 if (cp != NULL) 119 if (cp != NULL)
110 *cp++ = '\0'; 120 *cp++ = '\0';
@@ -113,12 +123,46 @@ again:
113 cp++; 123 cp++;
114 continue; 124 continue;
115 } 125 }
116 if (q < &serv_aliases[MAXALIASES - 1]) 126 if (q == &se->s_aliases[sd->maxaliases - 1]) {
117 *q++ = cp; 127 p = realloc(se->s_aliases,
128 2 * sd->maxaliases * sizeof(char *));
129 if (p == NULL) {
130 serrno = errno;
131 endservent_r(sd);
132 errno = serrno;
133 return (NULL);
134 }
135 sd->maxaliases *= 2;
136 q = (char **)p + (q - se->s_aliases);
137 se->s_aliases = sd->aliases = (char **)p;
138 }
139 *q++ = cp;
118 cp = strpbrk(cp, " \t"); 140 cp = strpbrk(cp, " \t");
119 if (cp != NULL) 141 if (cp != NULL)
120 *cp++ = '\0'; 142 *cp++ = '\0';
121 } 143 }
122 *q = NULL; 144 *q = NULL;
123 return (&serv); 145 return (se);
146}
147
148struct servent_data _servent_data; /* shared with getservby{name,port}.c */
149
150void
151setservent(int f)
152{
153 setservent_r(f, &_servent_data);
154}
155
156void
157endservent(void)
158{
159 endservent_r(&_servent_data);
160}
161
162struct servent *
163getservent(void)
164{
165 static struct servent serv;
166
167 return getservent_r(&serv, &_servent_data);
124} 168}