masqmail
view src/libident/id_parse.c @ 281:ea5f86e0a81c
modes are now enforced exclusive
Other MTAs (exim, postfix) are more relaxing, but as combinations
of exclusive modes are senseless we behave more obvious if we
fail early. This makes understanding the behavior easier too.
author | markus schnalke <meillo@marmaro.de> |
---|---|
date | Tue, 07 Dec 2010 14:04:56 -0300 |
parents | 08114f7dcc23 |
children |
line source
1 /*
2 ** id_parse.c Receive and parse a reply from an IDENT server
3 **
4 ** Author: Peter Eriksson <pen@lysator.liu.se>
5 ** Fiddling: Pär Emanuelsson <pell@lysator.liu.se>
6 */
8 #ifdef NeXT3
9 # include <libc.h>
10 #endif
12 #include <stdio.h>
13 #include <string.h>
14 #include <errno.h>
15 #include <ctype.h>
17 #ifdef HAVE_ANSIHEADERS
18 # include <stdlib.h>
19 # include <string.h>
20 # include <unistd.h>
21 #endif
23 #include <sys/types.h>
24 #include <sys/wait.h>
25 #include <sys/time.h>
27 #ifdef _AIX
28 # include <sys/select.h>
29 #endif
31 #ifdef _AIX
32 # include <sys/select.h>
33 #endif
34 #ifdef VMS
35 # include <sys/socket.h> /* for fd_set */
36 #endif
37 #define IN_LIBIDENT_SRC
38 #include "ident.h"
41 /*
42 int
43 id_parse __P7(ident_t *, id,
44 struct timeval *, timeout,
45 int *, lport,
46 int *, fport,
47 char **, identifier,
48 char **, opsys,
49 char **, charset)
50 */
52 int
53 id_parse __P((ident_t * id,
54 __STRUCT_TIMEVAL_P timeout,
55 int *lport,
56 int *fport,
57 char **identifier,
58 char **opsys,
59 char **charset))
60 {
61 char c, *cp, *tmp_charset;
62 fd_set rs;
63 int pos, res = 0, lp, fp;
65 errno = 0;
67 tmp_charset = 0;
69 if (!id)
70 return -1;
71 if (lport)
72 *lport = 0;
73 if (fport)
74 *fport = 0;
75 if (identifier)
76 *identifier = 0;
77 if (opsys)
78 *opsys = 0;
79 if (charset)
80 *charset = 0;
82 pos = strlen(id->buf);
84 if (timeout) {
85 FD_ZERO(&rs);
86 FD_SET(id->fd, &rs);
88 #ifdef __hpux
89 if ((res = select(FD_SETSIZE, (int *) &rs, (int *) 0, (int *) 0, timeout)) < 0)
90 #else
91 if ((res = select(FD_SETSIZE, &rs, (fd_set *) 0, (fd_set *) 0, timeout)) < 0)
92 #endif
93 return -1;
95 if (res == 0) {
96 errno = ETIMEDOUT;
97 return -1;
98 }
99 }
101 /* Every octal value is allowed except 0, \n and \r */
102 while (pos < sizeof(id->buf)
103 && (res = read(id->fd, id->buf + pos, 1)) == 1
104 && id->buf[pos] != '\n' && id->buf[pos] != '\r')
105 pos++;
107 if (res < 0)
108 return -1;
110 if (res == 0) {
111 errno = ENOTCONN;
112 return -1;
113 }
115 if (id->buf[pos] != '\n' && id->buf[pos] != '\r')
116 return 0; /* Not properly terminated string */
118 id->buf[pos++] = '\0';
120 /*
121 ** Get first field (<lport> , <fport>)
122 */
123 cp = id_strtok(id->buf, ":", &c);
124 if (!cp)
125 return -2;
127 if (sscanf(cp, " %d , %d", &lp, &fp) != 2) {
128 if (identifier) {
129 *identifier = id_strdup(cp);
130 if (*identifier == NULL)
131 return -4;
132 }
133 return -2;
134 }
136 if (lport)
137 *lport = lp;
138 if (fport)
139 *fport = fp;
141 /*
142 ** Get second field (USERID or ERROR)
143 */
144 cp = id_strtok((char *) 0, ":", &c);
145 if (!cp)
146 return -2;
148 if (strcmp(cp, "ERROR") == 0) {
149 cp = id_strtok((char *) 0, "\n\r", &c);
150 if (!cp)
151 return -2;
153 if (identifier) {
154 *identifier = id_strdup(cp);
155 if (*identifier == NULL)
156 return -4;
157 }
159 return 2;
160 } else if (strcmp(cp, "USERID") == 0) {
161 /*
162 ** Get first subfield of third field <opsys>
163 */
164 cp = id_strtok((char *) 0, ",:", &c);
165 if (!cp)
166 return -2;
168 if (opsys) {
169 *opsys = id_strdup(cp);
170 if (*opsys == NULL)
171 return -4;
172 }
174 /*
175 ** We have a second subfield (<charset>)
176 */
177 if (c == ',') {
178 cp = id_strtok((char *) 0, ":", &c);
179 if (!cp)
180 return -2;
182 tmp_charset = cp;
183 if (charset) {
184 *charset = id_strdup(cp);
185 if (*charset == NULL)
186 return -4;
187 }
189 /*
190 ** We have even more subfields - ignore them
191 */
192 if (c == ',')
193 id_strtok((char *) 0, ":", &c);
194 }
196 if (tmp_charset && strcmp(tmp_charset, "OCTET") == 0)
197 cp = id_strtok((char *) 0, (char *) 0, &c);
198 else
199 cp = id_strtok((char *) 0, "\n\r", &c);
201 if (identifier) {
202 *identifier = id_strdup(cp);
203 if (*identifier == NULL)
204 return -4;
205 }
206 return 1;
207 } else {
208 if (identifier) {
209 *identifier = id_strdup(cp);
210 if (*identifier == NULL)
211 return -4;
212 }
213 return -3;
214 }
215 }