masqmail-0.2

view src/libident/id_parse.c @ 179:ec3fe72a3e99

Fixed an important bug with folded headers! g_strconcat() returns a *copy* of the string, but hdr->value still pointed to the old header (which probably was a memory leak, too). If the folded part had been quite small it was likely that the new string was at the same position as the old one, thus making everything go well. But if pretty long headers were folded several times it was likely that the new string was allocated somewhere else in memory, thus breaking things. In result mails to lots of recipients (folded header) were frequently only sent to the ones in the first line. Sorry for the inconvenience.
author meillo@marmaro.de
date Fri, 03 Jun 2011 09:52:17 +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 }