masqmail

view src/libident/id_parse.c @ 117:5ec5e6637049

added server-side SMTP SIZE support (patch by Paolo) ``SIZE 0'' (= unlimited) is currently not supported client-side support was already implemented
author meillo@marmaro.de
date Thu, 01 Jul 2010 13:08:53 +0200
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 }