summaryrefslogtreecommitdiff
path: root/src/lib/libc/net/getprotoent.c
diff options
context:
space:
mode:
authormillert <>2004-10-17 20:24:23 +0000
committermillert <>2004-10-17 20:24:23 +0000
commiteae90a29f226809527585d7ba688d0af8627db58 (patch)
treebeb43deef803247f4e915dfbd6ef663407e7dd2b /src/lib/libc/net/getprotoent.c
parent91294475ad30114d23728b4a7599c81a0e1a99a3 (diff)
downloadopenbsd-eae90a29f226809527585d7ba688d0af8627db58.tar.gz
openbsd-eae90a29f226809527585d7ba688d0af8627db58.tar.bz2
openbsd-eae90a29f226809527585d7ba688d0af8627db58.zip
Reentrant versions of getprotoent(3) and getservent(3). Adapted from
changes in NetBSD by Christos. OK otto@
Diffstat (limited to 'src/lib/libc/net/getprotoent.c')
-rw-r--r--src/lib/libc/net/getprotoent.c121
1 files changed, 82 insertions, 39 deletions
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}