masqmail-0.2

annotate 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
rev   line source
meillo@0 1 /*
meillo@0 2 ** id_parse.c Receive and parse a reply from an IDENT server
meillo@0 3 **
meillo@0 4 ** Author: Peter Eriksson <pen@lysator.liu.se>
meillo@0 5 ** Fiddling: Pär Emanuelsson <pell@lysator.liu.se>
meillo@0 6 */
meillo@0 7
meillo@0 8 #ifdef NeXT3
meillo@0 9 # include <libc.h>
meillo@0 10 #endif
meillo@0 11
meillo@0 12 #include <stdio.h>
meillo@0 13 #include <string.h>
meillo@0 14 #include <errno.h>
meillo@0 15 #include <ctype.h>
meillo@0 16
meillo@0 17 #ifdef HAVE_ANSIHEADERS
meillo@0 18 # include <stdlib.h>
meillo@0 19 # include <string.h>
meillo@0 20 # include <unistd.h>
meillo@0 21 #endif
meillo@0 22
meillo@0 23 #include <sys/types.h>
meillo@0 24 #include <sys/wait.h>
meillo@0 25 #include <sys/time.h>
meillo@0 26
meillo@0 27 #ifdef _AIX
meillo@0 28 # include <sys/select.h>
meillo@0 29 #endif
meillo@0 30
meillo@0 31 #ifdef _AIX
meillo@0 32 # include <sys/select.h>
meillo@0 33 #endif
meillo@0 34 #ifdef VMS
meillo@10 35 # include <sys/socket.h> /* for fd_set */
meillo@0 36 #endif
meillo@0 37 #define IN_LIBIDENT_SRC
meillo@0 38 #include "ident.h"
meillo@0 39
meillo@0 40
meillo@0 41 /*
meillo@10 42 int
meillo@10 43 id_parse __P7(ident_t *, id,
meillo@10 44 struct timeval *, timeout,
meillo@10 45 int *, lport,
meillo@10 46 int *, fport,
meillo@10 47 char **, identifier,
meillo@10 48 char **, opsys,
meillo@10 49 char **, charset)
meillo@0 50 */
meillo@0 51
meillo@10 52 int
meillo@10 53 id_parse __P((ident_t * id,
meillo@10 54 __STRUCT_TIMEVAL_P timeout,
meillo@10 55 int *lport,
meillo@10 56 int *fport,
meillo@10 57 char **identifier,
meillo@10 58 char **opsys,
meillo@10 59 char **charset))
meillo@0 60 {
meillo@10 61 char c, *cp, *tmp_charset;
meillo@10 62 fd_set rs;
meillo@10 63 int pos, res = 0, lp, fp;
meillo@10 64
meillo@10 65 errno = 0;
meillo@10 66
meillo@10 67 tmp_charset = 0;
meillo@10 68
meillo@10 69 if (!id)
meillo@10 70 return -1;
meillo@10 71 if (lport)
meillo@10 72 *lport = 0;
meillo@10 73 if (fport)
meillo@10 74 *fport = 0;
meillo@10 75 if (identifier)
meillo@10 76 *identifier = 0;
meillo@10 77 if (opsys)
meillo@10 78 *opsys = 0;
meillo@10 79 if (charset)
meillo@10 80 *charset = 0;
meillo@10 81
meillo@10 82 pos = strlen(id->buf);
meillo@10 83
meillo@10 84 if (timeout) {
meillo@10 85 FD_ZERO(&rs);
meillo@10 86 FD_SET(id->fd, &rs);
meillo@0 87
meillo@0 88 #ifdef __hpux
meillo@10 89 if ((res = select(FD_SETSIZE, (int *) &rs, (int *) 0, (int *) 0, timeout)) < 0)
meillo@0 90 #else
meillo@10 91 if ((res = select(FD_SETSIZE, &rs, (fd_set *) 0, (fd_set *) 0, timeout)) < 0)
meillo@0 92 #endif
meillo@10 93 return -1;
meillo@10 94
meillo@10 95 if (res == 0) {
meillo@10 96 errno = ETIMEDOUT;
meillo@10 97 return -1;
meillo@10 98 }
meillo@0 99 }
meillo@10 100
meillo@10 101 /* Every octal value is allowed except 0, \n and \r */
meillo@10 102 while (pos < sizeof(id->buf)
meillo@10 103 && (res = read(id->fd, id->buf + pos, 1)) == 1
meillo@10 104 && id->buf[pos] != '\n' && id->buf[pos] != '\r')
meillo@10 105 pos++;
meillo@10 106
meillo@10 107 if (res < 0)
meillo@10 108 return -1;
meillo@10 109
meillo@10 110 if (res == 0) {
meillo@10 111 errno = ENOTCONN;
meillo@10 112 return -1;
meillo@0 113 }
meillo@10 114
meillo@10 115 if (id->buf[pos] != '\n' && id->buf[pos] != '\r')
meillo@10 116 return 0; /* Not properly terminated string */
meillo@10 117
meillo@10 118 id->buf[pos++] = '\0';
meillo@10 119
meillo@10 120 /*
meillo@10 121 ** Get first field (<lport> , <fport>)
meillo@10 122 */
meillo@10 123 cp = id_strtok(id->buf, ":", &c);
meillo@0 124 if (!cp)
meillo@10 125 return -2;
meillo@10 126
meillo@10 127 if (sscanf(cp, " %d , %d", &lp, &fp) != 2) {
meillo@10 128 if (identifier) {
meillo@10 129 *identifier = id_strdup(cp);
meillo@10 130 if (*identifier == NULL)
meillo@10 131 return -4;
meillo@10 132 }
meillo@10 133 return -2;
meillo@0 134 }
meillo@10 135
meillo@10 136 if (lport)
meillo@10 137 *lport = lp;
meillo@10 138 if (fport)
meillo@10 139 *fport = fp;
meillo@10 140
meillo@0 141 /*
meillo@10 142 ** Get second field (USERID or ERROR)
meillo@10 143 */
meillo@10 144 cp = id_strtok((char *) 0, ":", &c);
meillo@0 145 if (!cp)
meillo@10 146 return -2;
meillo@10 147
meillo@10 148 if (strcmp(cp, "ERROR") == 0) {
meillo@10 149 cp = id_strtok((char *) 0, "\n\r", &c);
meillo@10 150 if (!cp)
meillo@10 151 return -2;
meillo@10 152
meillo@10 153 if (identifier) {
meillo@10 154 *identifier = id_strdup(cp);
meillo@10 155 if (*identifier == NULL)
meillo@10 156 return -4;
meillo@10 157 }
meillo@10 158
meillo@10 159 return 2;
meillo@10 160 } else if (strcmp(cp, "USERID") == 0) {
meillo@10 161 /*
meillo@10 162 ** Get first subfield of third field <opsys>
meillo@10 163 */
meillo@10 164 cp = id_strtok((char *) 0, ",:", &c);
meillo@10 165 if (!cp)
meillo@10 166 return -2;
meillo@10 167
meillo@10 168 if (opsys) {
meillo@10 169 *opsys = id_strdup(cp);
meillo@10 170 if (*opsys == NULL)
meillo@10 171 return -4;
meillo@10 172 }
meillo@10 173
meillo@10 174 /*
meillo@10 175 ** We have a second subfield (<charset>)
meillo@10 176 */
meillo@10 177 if (c == ',') {
meillo@10 178 cp = id_strtok((char *) 0, ":", &c);
meillo@10 179 if (!cp)
meillo@10 180 return -2;
meillo@10 181
meillo@10 182 tmp_charset = cp;
meillo@10 183 if (charset) {
meillo@10 184 *charset = id_strdup(cp);
meillo@10 185 if (*charset == NULL)
meillo@10 186 return -4;
meillo@10 187 }
meillo@10 188
meillo@10 189 /*
meillo@10 190 ** We have even more subfields - ignore them
meillo@10 191 */
meillo@10 192 if (c == ',')
meillo@10 193 id_strtok((char *) 0, ":", &c);
meillo@10 194 }
meillo@10 195
meillo@10 196 if (tmp_charset && strcmp(tmp_charset, "OCTET") == 0)
meillo@10 197 cp = id_strtok((char *) 0, (char *) 0, &c);
meillo@10 198 else
meillo@10 199 cp = id_strtok((char *) 0, "\n\r", &c);
meillo@10 200
meillo@10 201 if (identifier) {
meillo@10 202 *identifier = id_strdup(cp);
meillo@10 203 if (*identifier == NULL)
meillo@10 204 return -4;
meillo@10 205 }
meillo@10 206 return 1;
meillo@10 207 } else {
meillo@10 208 if (identifier) {
meillo@10 209 *identifier = id_strdup(cp);
meillo@10 210 if (*identifier == NULL)
meillo@10 211 return -4;
meillo@10 212 }
meillo@10 213 return -3;
meillo@0 214 }
meillo@0 215 }