comparison libnnchat.c @ 386:4523fc0941e8

Cosmetics.
author Matti Hamalainen <ccr@tnsp.org>
date Thu, 29 Dec 2011 00:39:20 +0200
parents 812af6823eb7
children acea18a741e3
comparison
equal deleted inserted replaced
385:bbd5edbf1143 386:4523fc0941e8
20 } 20 }
21 21
22 const char *nn_get_socket_errstr(int err) 22 const char *nn_get_socket_errstr(int err)
23 { 23 {
24 static char buf[64]; 24 static char buf[64];
25 switch (err) { 25 switch (err)
26 {
26 case WSAEADDRINUSE: return "Address already in use"; 27 case WSAEADDRINUSE: return "Address already in use";
27 case WSAECONNABORTED: return "Software caused connection abort"; 28 case WSAECONNABORTED: return "Software caused connection abort";
28 case WSAECONNREFUSED: return "Connection refused"; 29 case WSAECONNREFUSED: return "Connection refused";
29 case WSAECONNRESET: return "Connection reset by peer"; 30 case WSAECONNRESET: return "Connection reset by peer";
30 case WSAEHOSTUNREACH: return "No route to host"; 31 case WSAEHOSTUNREACH: return "No route to host";
51 #endif 52 #endif
52 53
53 54
54 void nn_conn_err(nn_conn_t *conn, const char *fmt, ...) 55 void nn_conn_err(nn_conn_t *conn, const char *fmt, ...)
55 { 56 {
56 if (conn->errfunc) { 57 if (conn->errfunc != NULL)
58 {
57 va_list ap; 59 va_list ap;
58 va_start(ap, fmt); 60 va_start(ap, fmt);
59 conn->errfunc(conn, fmt, ap); 61 conn->errfunc(conn, fmt, ap);
60 va_end(ap); 62 va_end(ap);
61 } 63 }
62 } 64 }
63 65
64 66
65 static void nn_conn_msg(nn_conn_t *conn, const char *fmt, ...) 67 static void nn_conn_msg(nn_conn_t *conn, const char *fmt, ...)
66 { 68 {
67 if (conn->msgfunc) { 69 if (conn->msgfunc != NULL)
70 {
68 va_list ap; 71 va_list ap;
69 va_start(ap, fmt); 72 va_start(ap, fmt);
70 conn->msgfunc(conn, fmt, ap); 73 conn->msgfunc(conn, fmt, ap);
71 va_end(ap); 74 va_end(ap);
72 } 75 }
81 nn_conn_msg(conn, "True hostname for %s is %s\n", name, res->h_name); 84 nn_conn_msg(conn, "True hostname for %s is %s\n", name, res->h_name);
82 85
83 return res; 86 return res;
84 } 87 }
85 88
86 static const char *nn_proxy_types[] = { 89 static const char *nn_proxy_types[] =
90 {
87 "none", 91 "none",
88 "SOCKS 4", 92 "SOCKS 4",
89 "SOCKS 4a", 93 "SOCKS 4a",
90 NULL 94 NULL
91 }; 95 };
106 return conn; 110 return conn;
107 } 111 }
108 112
109 static BOOL nn_get_addr(struct in_addr *addr, struct hostent *hst) 113 static BOOL nn_get_addr(struct in_addr *addr, struct hostent *hst)
110 { 114 {
111 if (hst != NULL) { 115 if (hst != NULL)
116 {
112 *addr = *(struct in_addr *) (hst->h_addr); 117 *addr = *(struct in_addr *) (hst->h_addr);
113 return TRUE; 118 return TRUE;
114 } else { 119 }
120 else
121 {
115 addr->s_addr = 0; 122 addr->s_addr = 0;
116 return FALSE; 123 return FALSE;
117 } 124 }
118 } 125 }
119 126
124 131
125 conn->proxy.type = type; 132 conn->proxy.type = type;
126 conn->proxy.port = port; 133 conn->proxy.port = port;
127 conn->proxy.host = th_strdup(host); 134 conn->proxy.host = th_strdup(host);
128 135
129 if (host != NULL) { 136 if (host != NULL)
137 {
130 conn->proxy.hst = nn_resolve_host(conn, host); 138 conn->proxy.hst = nn_resolve_host(conn, host);
131 nn_get_addr(&(conn->proxy.addr), conn->proxy.hst); 139 nn_get_addr(&(conn->proxy.addr), conn->proxy.hst);
132 } else 140 } else
133 return -2; 141 return -2;
134 142
142 150
143 if (conn == NULL) 151 if (conn == NULL)
144 return -1; 152 return -1;
145 153
146 conn->port = port; 154 conn->port = port;
147 if (host != NULL) { 155 if (host != NULL)
156 {
148 conn->host = th_strdup(host); 157 conn->host = th_strdup(host);
149 conn->hst = nn_resolve_host(conn, host); 158 conn->hst = nn_resolve_host(conn, host);
150 } 159 }
151 160
152 nn_get_addr(&(conn->addr), conn->hst); 161 nn_get_addr(&(conn->addr), conn->hst);
153 162
154 /* Prepare for connection */ 163 /* Prepare for connection */
155 dest.sin_family = AF_INET; 164 dest.sin_family = AF_INET;
156 165
157 if (conn->proxy.type > NN_PROXY_NONE && conn->proxy.type < NN_PROXY_LAST) { 166 if (conn->proxy.type > NN_PROXY_NONE && conn->proxy.type < NN_PROXY_LAST)
167 {
158 dest.sin_port = htons(conn->proxy.port); 168 dest.sin_port = htons(conn->proxy.port);
159 dest.sin_addr = conn->proxy.addr; 169 dest.sin_addr = conn->proxy.addr;
160 170
161 nn_conn_msg(conn, "Connecting to %s proxy %s:%d ...\n", 171 nn_conn_msg(conn, "Connecting to %s proxy %s:%d ...\n",
162 nn_proxy_types[conn->proxy.type], 172 nn_proxy_types[conn->proxy.type],
163 inet_ntoa(conn->proxy.addr), conn->proxy.port); 173 inet_ntoa(conn->proxy.addr), conn->proxy.port);
164 } else { 174 }
175 else
176 {
165 dest.sin_port = htons(conn->port); 177 dest.sin_port = htons(conn->port);
166 dest.sin_addr = conn->addr; 178 dest.sin_addr = conn->addr;
167 179
168 nn_conn_msg(conn, "Connecting to %s:%d ...\n", 180 nn_conn_msg(conn, "Connecting to %s:%d ...\n",
169 inet_ntoa(conn->addr), conn->port); 181 inet_ntoa(conn->addr), conn->port);
170 } 182 }
171 183
172 if ((conn->socket = socket(PF_INET, SOCK_STREAM, 0)) == -1) { 184 if ((conn->socket = socket(PF_INET, SOCK_STREAM, 0)) == -1)
185 {
173 conn->err = nn_get_socket_errno(); 186 conn->err = nn_get_socket_errno();
174 nn_conn_err(conn, "Could not open socket: %s\n", nn_get_socket_errstr(conn->err)); 187 nn_conn_err(conn, "Could not open socket: %s\n", nn_get_socket_errstr(conn->err));
175 goto error; 188 goto error;
176 } 189 }
177 190
178 nn_conn_msg(conn, "Using socket %d.\n", conn->socket); 191 nn_conn_msg(conn, "Using socket %d.\n", conn->socket);
179 192
180 if (connect(conn->socket, (struct sockaddr *) &dest, sizeof(dest)) == -1) { 193 if (connect(conn->socket, (struct sockaddr *) &dest, sizeof(dest)) == -1)
194 {
181 conn->err = nn_get_socket_errno(); 195 conn->err = nn_get_socket_errno();
182 nn_conn_err(conn, "Could not connect: %s\n", nn_get_socket_errstr(conn->err)); 196 nn_conn_err(conn, "Could not connect: %s\n", nn_get_socket_errstr(conn->err));
183 goto error; 197 goto error;
184 } 198 }
185 199
186 FD_ZERO(&(conn->sockfds)); 200 FD_ZERO(&(conn->sockfds));
187 FD_SET(conn->socket, &(conn->sockfds)); 201 FD_SET(conn->socket, &(conn->sockfds));
188 202
189 /* Proxy-specific setup */ 203 /* Proxy-specific setup */
190 if (conn->proxy.type == NN_PROXY_SOCKS4 || conn->proxy.type == NN_PROXY_SOCKS4A) { 204 if (conn->proxy.type == NN_PROXY_SOCKS4 || conn->proxy.type == NN_PROXY_SOCKS4A)
205 {
191 struct nn_socks_t *socksh; 206 struct nn_socks_t *socksh;
192 size_t bufsiz = sizeof(struct nn_socks_t) + strlen(userid) + 1; 207 size_t bufsiz = sizeof(struct nn_socks_t) + strlen(userid) + 1;
193 char *ptr, *buf; 208 char *ptr, *buf;
194 int tries, status = -1; 209 int tries, status = -1;
195 210
196 if (conn->proxy.type == NN_PROXY_SOCKS4A) 211 if (conn->proxy.type == NN_PROXY_SOCKS4A)
197 bufsiz += strlen(conn->host) + 1; 212 bufsiz += strlen(conn->host) + 1;
198 213
199 ptr = buf = th_malloc(bufsiz); 214 ptr = buf = th_malloc(bufsiz);
200 if (buf == NULL) { 215 if (buf == NULL)
216 {
201 conn->err = -1; 217 conn->err = -1;
202 nn_conn_err(conn, "Could not allocate memory for SOCKS negotiation buffer, %d bytes.\n", bufsiz); 218 nn_conn_err(conn, "Could not allocate memory for SOCKS negotiation buffer, %d bytes.\n", bufsiz);
203 goto error; 219 goto error;
204 } 220 }
205 221
215 socksh->addr = conn->addr.s_addr; 231 socksh->addr = conn->addr.s_addr;
216 ptr += sizeof(struct nn_socks_t); 232 ptr += sizeof(struct nn_socks_t);
217 233
218 strcpy(ptr, userid); 234 strcpy(ptr, userid);
219 235
220 if (conn->proxy.type == NN_PROXY_SOCKS4A) { 236 if (conn->proxy.type == NN_PROXY_SOCKS4A)
237 {
221 ptr += strlen(userid) + 1; 238 ptr += strlen(userid) + 1;
222 strcpy(ptr, conn->host); 239 strcpy(ptr, conn->host);
223 } 240 }
224 241
225 /* Send request */ 242 /* Send request */
226 nn_conn_reset(conn); 243 nn_conn_reset(conn);
227 if (!nn_conn_send_buf(conn, buf, bufsiz)) { 244 if (!nn_conn_send_buf(conn, buf, bufsiz))
245 {
228 th_free(buf); 246 th_free(buf);
229 nn_conn_err(conn, "Error sending SOCKS proxy request.\n"); 247 nn_conn_err(conn, "Error sending SOCKS proxy request.\n");
230 goto error; 248 goto error;
231 } 249 }
232 th_free(buf); 250 th_free(buf);
233 251
234 /* Wait for SOCKS server to reply */ 252 /* Wait for SOCKS server to reply */
235 for (status = tries = 1; tries <= 20 && status > 0; tries++) { 253 for (status = tries = 1; tries <= 20 && status > 0; tries++)
254 {
236 #ifdef __WIN32 255 #ifdef __WIN32
237 Sleep(50); 256 Sleep(50);
238 #else 257 #else
239 usleep(50000); 258 usleep(50000);
240 #endif 259 #endif
241 nn_conn_reset(conn); 260 nn_conn_reset(conn);
242 status = nn_conn_pull(conn); 261 status = nn_conn_pull(conn);
243 } 262 }
244 263
245 /* Check results */ 264 /* Check results */
246 if (status == 0) { 265 if (status == 0)
266 {
247 struct nn_socks_res_t *res = (struct nn_socks_res_t *) &(conn->buf); 267 struct nn_socks_res_t *res = (struct nn_socks_res_t *) &(conn->buf);
248 if (res->nb != 0) { 268 if (res->nb != 0)
269 {
249 nn_conn_err(conn, "Invalid SOCKS server reply, does not begin with NUL byte (%d).\n", res->nb); 270 nn_conn_err(conn, "Invalid SOCKS server reply, does not begin with NUL byte (%d).\n", res->nb);
250 goto error; 271 goto error;
251 } 272 }
252 if (res->result != 0x5a) { 273 if (res->result != 0x5a)
274 {
253 char *s = NULL; 275 char *s = NULL;
254 switch (res->result) { 276 switch (res->result)
277 {
255 case 0x5b: s = "Request rejected or failed"; break; 278 case 0x5b: s = "Request rejected or failed"; break;
256 case 0x5c: s = "Request failed because client is not running identd (or not reachable from the server)"; break; 279 case 0x5c: s = "Request failed because client is not running identd (or not reachable from the server)"; break;
257 case 0x5d: s = "Request failed because client's identd could not confirm the user ID string in the request"; break; 280 case 0x5d: s = "Request failed because client's identd could not confirm the user ID string in the request"; break;
258 default: s = "Unknown SOCKS error response"; break; 281 default: s = "Unknown SOCKS error response"; break;
259 } 282 }
260 nn_conn_err(conn, "SOCKS setup failed, 0x%02x: %s.\n", res->result, s); 283 nn_conn_err(conn, "SOCKS setup failed, 0x%02x: %s.\n", res->result, s);
261 goto error; 284 goto error;
262 } 285 }
263 nn_conn_msg(conn, "SOCKS connection established!\n"); 286 nn_conn_msg(conn, "SOCKS connection established!\n");
264 } 287 }
265 else if (status < 0) { 288 else if (status < 0)
289 {
266 nn_conn_err(conn, "Proxy negotiation failed at try %d with network error: %d\n", tries, status); 290 nn_conn_err(conn, "Proxy negotiation failed at try %d with network error: %d\n", tries, status);
267 goto error; 291 goto error;
268 } 292 }
269 else { 293 else
294 {
270 nn_conn_err(conn, "Proxy negotiation timed out.\n"); 295 nn_conn_err(conn, "Proxy negotiation timed out.\n");
271 goto error; 296 goto error;
272 } 297 }
273 } 298 }
274 299
285 void nn_conn_close(nn_conn_t *conn) 310 void nn_conn_close(nn_conn_t *conn)
286 { 311 {
287 if (conn == NULL) 312 if (conn == NULL)
288 return; 313 return;
289 314
290 if (conn->socket >= 0) { 315 if (conn->socket >= 0)
316 {
291 #ifdef __WIN32 317 #ifdef __WIN32
292 closesocket(conn->socket); 318 closesocket(conn->socket);
293 #else 319 #else
294 close(conn->socket); 320 close(conn->socket);
295 #endif 321 #endif
308 BOOL nn_conn_send_buf(nn_conn_t *conn, const char *buf, const size_t len) 334 BOOL nn_conn_send_buf(nn_conn_t *conn, const char *buf, const size_t len)
309 { 335 {
310 size_t bufLeft = len; 336 size_t bufLeft = len;
311 const char *bufPtr = buf; 337 const char *bufPtr = buf;
312 338
313 while (bufLeft > 0) { 339 while (bufLeft > 0)
340 {
314 ssize_t bufSent; 341 ssize_t bufSent;
315 bufSent = send(conn->socket, bufPtr, bufLeft, 0); 342 bufSent = send(conn->socket, bufPtr, bufLeft, 0);
316 if (bufSent < 0) { 343 if (bufSent < 0)
344 {
317 conn->err = nn_get_socket_errno(); 345 conn->err = nn_get_socket_errno();
318 nn_conn_err(conn, "nn_conn_send_buf() failed: %s", nn_get_socket_errstr(conn->err)); 346 nn_conn_err(conn, "nn_conn_send_buf() failed: %s", nn_get_socket_errstr(conn->err));
319 return FALSE; 347 return FALSE;
320 } 348 }
321 bufLeft -= bufSent; 349 bufLeft -= bufSent;
325 return TRUE; 353 return TRUE;
326 } 354 }
327 355
328 void nn_conn_reset(nn_conn_t *conn) 356 void nn_conn_reset(nn_conn_t *conn)
329 { 357 {
330 if (conn != NULL) { 358 if (conn != NULL)
359 {
331 conn->ptr = conn->buf; 360 conn->ptr = conn->buf;
332 conn->got = conn->total = 0; 361 conn->got = conn->total = 0;
333 } 362 }
334 } 363 }
335 364
345 /* Check for incoming data */ 374 /* Check for incoming data */
346 socktv.tv_sec = 0; 375 socktv.tv_sec = 0;
347 socktv.tv_usec = NN_DELAY_USEC; 376 socktv.tv_usec = NN_DELAY_USEC;
348 tmpfds = conn->sockfds; 377 tmpfds = conn->sockfds;
349 378
350 if ((result = select(conn->socket + 1, &tmpfds, NULL, NULL, &socktv)) == -1) { 379 if ((result = select(conn->socket + 1, &tmpfds, NULL, NULL, &socktv)) == -1)
380 {
351 conn->err = nn_get_socket_errno(); 381 conn->err = nn_get_socket_errno();
352 if (conn->err != EINTR) { 382 if (conn->err != EINTR)
383 {
353 nn_conn_err(conn, "Error occured in select(%d, sockfds): %d, %s\n", 384 nn_conn_err(conn, "Error occured in select(%d, sockfds): %d, %s\n",
354 socket, conn->err, nn_get_socket_errstr(conn->err)); 385 socket, conn->err, nn_get_socket_errstr(conn->err));
355 return -1; 386 return -1;
356 } 387 }
357 } else 388 } else
358 if (FD_ISSET(conn->socket, &tmpfds)) { 389 if (FD_ISSET(conn->socket, &tmpfds))
390 {
359 conn->got = recv(conn->socket, conn->ptr, NN_CONNBUF_SIZE - conn->total, 0); 391 conn->got = recv(conn->socket, conn->ptr, NN_CONNBUF_SIZE - conn->total, 0);
360 if (conn->got < 0) { 392 if (conn->got < 0)
393 {
361 conn->err = nn_get_socket_errno(); 394 conn->err = nn_get_socket_errno();
362 nn_conn_err(conn, "Error in recv: %d, %s\n", conn->err, nn_get_socket_errstr(conn->err)); 395 nn_conn_err(conn, "Error in recv: %d, %s\n", conn->err, nn_get_socket_errstr(conn->err));
363 return -2; 396 return -2;
364 } else if (conn->got == 0) { 397 } else if (conn->got == 0)
398 {
365 nn_conn_err(conn, "Server closed connection.\n"); 399 nn_conn_err(conn, "Server closed connection.\n");
366 conn->status = NN_CONN_CLOSED; 400 conn->status = NN_CONN_CLOSED;
367 return -3; 401 return -3;
368 } else { 402 }
403 else
404 {
369 /* Handle protocol data */ 405 /* Handle protocol data */
370 conn->total += conn->got; 406 conn->total += conn->got;
371 conn->ptr += conn->got; 407 conn->ptr += conn->got;
372 return 0; 408 return 0;
373 } 409 }
390 { 426 {
391 #ifdef __WIN32 427 #ifdef __WIN32
392 /* Initialize WinSock, if needed */ 428 /* Initialize WinSock, if needed */
393 WSADATA wsaData; 429 WSADATA wsaData;
394 int err = WSAStartup(0x0101, &wsaData); 430 int err = WSAStartup(0x0101, &wsaData);
395 if (err != 0) { 431 if (err != 0)
432 {
396 THERR("Could not initialize WinSock library (err=%d).\n", err); 433 THERR("Could not initialize WinSock library (err=%d).\n", err);
397 return FALSE; 434 return FALSE;
398 } 435 }
399 #endif 436 #endif
400 return TRUE; 437 return TRUE;
422 459
423 resSize = strlen(str) + NN_ALLOC_SIZE; 460 resSize = strlen(str) + NN_ALLOC_SIZE;
424 if ((result = th_malloc(resSize)) == NULL) 461 if ((result = th_malloc(resSize)) == NULL)
425 return NULL; 462 return NULL;
426 463
427 while (*s) { 464 while (*s)
428 switch (*s) { 465 {
466 switch (*s)
467 {
429 case 32: 468 case 32:
430 PUSHCHAR('+'); 469 PUSHCHAR('+');
431 break; 470 break;
432 471
433 default: 472 default:
434 if (th_isalnum(*s)) 473 if (th_isalnum(*s))
435 PUSHCHAR(*s); 474 PUSHCHAR(*s);
436 else { 475 else
476 {
437 char tmpStr[4]; 477 char tmpStr[4];
438 snprintf(tmpStr, sizeof(tmpStr), "%2X", (unsigned char) *s); 478 snprintf(tmpStr, sizeof(tmpStr), "%2X", (unsigned char) *s);
439 PUSHCHAR('%'); 479 PUSHCHAR('%');
440 PUSHSTR(tmpStr); 480 PUSHSTR(tmpStr);
441 } 481 }
477 517
478 resSize = strlen(str) + NN_ALLOC_SIZE; 518 resSize = strlen(str) + NN_ALLOC_SIZE;
479 if ((result = th_malloc(resSize)) == NULL) 519 if ((result = th_malloc(resSize)) == NULL)
480 return NULL; 520 return NULL;
481 521
482 while (*s) { 522 while (*s)
483 switch (*s) { 523 {
524 switch (*s)
525 {
484 case '+': 526 case '+':
485 PUSHCHAR(' '); 527 PUSHCHAR(' ');
486 s++; 528 s++;
487 break; 529 break;
488 530
502 s++; 544 s++;
503 if (*s == '%') 545 if (*s == '%')
504 PUSHCHAR('%'); 546 PUSHCHAR('%');
505 else if ((c = getHexDigit(*s, 4)) >= 0) { 547 else if ((c = getHexDigit(*s, 4)) >= 0) {
506 int i = getHexDigit(*(++s), 0); 548 int i = getHexDigit(*(++s), 0);
507 if (i >= 0) { 549 if (i >= 0)
550 {
508 PUSHCHAR(c | i); 551 PUSHCHAR(c | i);
509 } else { 552 }
553 else
554 {
510 PUSHCHAR('§'); 555 PUSHCHAR('§');
511 PUSHCHAR(*s); 556 PUSHCHAR(*s);
512 } 557 }
513 } else { 558 }
559 else
560 {
514 PUSHCHAR('§'); 561 PUSHCHAR('§');
515 PUSHCHAR(*s); 562 PUSHCHAR(*s);
516 } 563 }
517 s++; 564 s++;
518 break; 565 break;
538 585
539 resSize = strlen(str) + NN_ALLOC_SIZE; 586 resSize = strlen(str) + NN_ALLOC_SIZE;
540 if ((result = th_malloc(resSize)) == NULL) 587 if ((result = th_malloc(resSize)) == NULL)
541 return NULL; 588 return NULL;
542 589
543 while (*s) { 590 while (*s)
544 if (*s == '<') { 591 {
592 if (*s == '<')
593 {
545 while (*s && *s != '>') s++; 594 while (*s && *s != '>') s++;
546 if (*s == '>') s++; 595 if (*s == '>') s++;
547 } else 596 } else
548 PUSHCHAR(*s++); 597 PUSHCHAR(*s++);
549 } 598 }
551 600
552 return result; 601 return result;
553 } 602 }
554 603
555 604
556 typedef struct { 605 typedef struct
606 {
557 char c; 607 char c;
558 char *ent; 608 char *ent;
559 } html_entity_t; 609 } html_entity_t;
560 610
561 611
562 static const html_entity_t HTMLEntities[] = { 612 static const html_entity_t HTMLEntities[] =
613 {
563 { '<', "&lt;" }, 614 { '<', "&lt;" },
564 { '>', "&gt;" }, 615 { '>', "&gt;" },
565 }; 616 };
566 617
567 static const int numHTMLEntities = sizeof(HTMLEntities) / sizeof(HTMLEntities[0]); 618 static const int numHTMLEntities = sizeof(HTMLEntities) / sizeof(HTMLEntities[0]);
577 628
578 resSize = strlen(str) + NN_ALLOC_SIZE; 629 resSize = strlen(str) + NN_ALLOC_SIZE;
579 if ((result = th_malloc(resSize)) == NULL) 630 if ((result = th_malloc(resSize)) == NULL)
580 return NULL; 631 return NULL;
581 632
582 while (*s) { 633 while (*s)
634 {
583 int i; 635 int i;
584 BOOL found = FALSE; 636 BOOL found = FALSE;
585 for (i = 0; i < numHTMLEntities; i++) 637 for (i = 0; i < numHTMLEntities; i++)
586 if (HTMLEntities[i].c == *s) { 638 if (HTMLEntities[i].c == *s)
639 {
587 PUSHSTR(HTMLEntities[i].ent); 640 PUSHSTR(HTMLEntities[i].ent);
588 found = TRUE; 641 found = TRUE;
589 break; 642 break;
590 } 643 }
591 if (!found) PUSHCHAR(*s); 644 if (!found) PUSHCHAR(*s);
608 661
609 resSize = strlen(str); 662 resSize = strlen(str);
610 if ((result = th_malloc(resSize)) == NULL) 663 if ((result = th_malloc(resSize)) == NULL)
611 return NULL; 664 return NULL;
612 665
613 while (*s) { 666 while (*s)
614 if (*s == '&') { 667 {
668 if (*s == '&')
669 {
615 int i; 670 int i;
616 BOOL found = FALSE; 671 BOOL found = FALSE;
617 for (i = 0; i < numHTMLEntities; i++) { 672 for (i = 0; i < numHTMLEntities; i++)
673 {
618 const html_entity_t *ent = &HTMLEntities[i]; 674 const html_entity_t *ent = &HTMLEntities[i];
619 int len = strlen(ent->ent); 675 int len = strlen(ent->ent);
620 if (!strncmp(s, ent->ent, len)) { 676 if (!strncmp(s, ent->ent, len))
677 {
621 PUSHCHAR(ent->c); 678 PUSHCHAR(ent->c);
622 s += len; 679 s += len;
623 found = TRUE; 680 found = TRUE;
624 break; 681 break;
625 } 682 }
675 return FALSE; 732 return FALSE;
676 733
677 msg = th_strdup_printf("<USER>%s</USER><MESSAGE>%s</MESSAGE>", user, tmp); 734 msg = th_strdup_printf("<USER>%s</USER><MESSAGE>%s</MESSAGE>", user, tmp);
678 th_free(tmp); 735 th_free(tmp);
679 736
680 if (msg != NULL) { 737 if (msg != NULL)
738 {
681 BOOL ret = nn_conn_send_buf(conn, msg, strlen(msg) + 1); 739 BOOL ret = nn_conn_send_buf(conn, msg, strlen(msg) + 1);
682 th_free(msg); 740 th_free(msg);
683 return ret; 741 return ret;
684 } else 742 } else
685 return FALSE; 743 return FALSE;
690 { 748 {
691 if (buf->len+1 >= buf->size) return -3; 749 if (buf->len+1 >= buf->size) return -3;
692 750
693 if (pos < 0) 751 if (pos < 0)
694 return -1; 752 return -1;
695 else if (pos >= buf->len) { 753 else if (pos >= buf->len)
696 buf->data[buf->len++] = ch; 754 buf->data[buf->len++] = ch;
697 } else { 755 else
698 buf->data[pos] = ch; 756 buf->data[pos] = ch;
699 } 757
700 return 0; 758 return 0;
701 } 759 }
702 760
703 761
704 int nn_editbuf_insert(nn_editbuf_t *buf, ssize_t pos, int ch) 762 int nn_editbuf_insert(nn_editbuf_t *buf, ssize_t pos, int ch)
705 { 763 {
706 if (buf->len+1 >= buf->size) return -3; 764 if (buf->len+1 >= buf->size) return -3;
707 765
708 if (pos < 0) 766 if (pos < 0)
709 return -1; 767 return -1;
710 else if (pos >= buf->len) { 768 else if (pos >= buf->len)
769 {
711 buf->data[buf->len] = ch; 770 buf->data[buf->len] = ch;
712 } else { 771 }
772 else
773 {
713 memmove(&(buf->data[pos+1]), &(buf->data[pos]), buf->len - pos + 1); 774 memmove(&(buf->data[pos+1]), &(buf->data[pos]), buf->len - pos + 1);
714 buf->data[pos] = ch; 775 buf->data[pos] = ch;
715 } 776 }
716 buf->len++; 777 buf->len++;
717 return 0; 778 return 0;
720 781
721 int nn_editbuf_delete(nn_editbuf_t *buf, ssize_t pos) 782 int nn_editbuf_delete(nn_editbuf_t *buf, ssize_t pos)
722 { 783 {
723 if (pos < 0) 784 if (pos < 0)
724 return -1; 785 return -1;
725 else if (pos < buf->len) { 786 else if (pos < buf->len)
787 {
726 memmove(&(buf->data[pos]), &(buf->data[pos+1]), buf->len - pos); 788 memmove(&(buf->data[pos]), &(buf->data[pos+1]), buf->len - pos);
727 buf->len--; 789 buf->len--;
728 return 0; 790 return 0;
729 } else 791 } else
730 return -2; 792 return -2;
749 } 811 }
750 812
751 813
752 void nn_editbuf_free(nn_editbuf_t *buf) 814 void nn_editbuf_free(nn_editbuf_t *buf)
753 { 815 {
754 if (buf != NULL) { 816 if (buf != NULL)
817 {
755 th_free(buf->data); 818 th_free(buf->data);
756 th_free(buf); 819 th_free(buf);
757 } 820 }
758 } 821 }
759 822
785 return NULL; 848 return NULL;
786 849
787 if (start < 0 || end > buf->len || start >= buf->len) 850 if (start < 0 || end > buf->len || start >= buf->len)
788 return NULL; 851 return NULL;
789 852
790 if (end < 0) { 853 if (end < 0)
854 {
791 siz = buf->len - start + 1; 855 siz = buf->len - start + 1;
792 } else if (start <= end) { 856 }
857 else if (start <= end)
858 {
793 siz = end - start + 1; 859 siz = end - start + 1;
794 } else 860 } else
795 return NULL; 861 return NULL;
796 862
797 if ((str = th_malloc(siz + 1)) == NULL) 863 if ((str = th_malloc(siz + 1)) == NULL)
822 /* 888 /*
823 int n = 0; 889 int n = 0;
824 const uint8_t *c = (uint8_t *)name; 890 const uint8_t *c = (uint8_t *)name;
825 uint8_t hash = 0xff; 891 uint8_t hash = 0xff;
826 892
827 while (*c && n < 4) { 893 while (*c && n < 4)
894 {
828 hash = (hash << 1) ^ tolower(*c); 895 hash = (hash << 1) ^ tolower(*c);
829 c++; n++; 896 c++; n++;
830 } 897 }
831 898
832 return (hash & 0xff); 899 return (hash & 0xff);
847 int i; 914 int i;
848 915
849 if (list == NULL) return NULL; 916 if (list == NULL) return NULL;
850 917
851 for (i = 0; i < NN_NUM_BUCKETS; i++) 918 for (i = 0; i < NN_NUM_BUCKETS; i++)
852 if (list->buckets[i] != NULL) { 919 if (list->buckets[i] != NULL)
920 {
853 nn_user_t *curr = list->buckets[i]; 921 nn_user_t *curr = list->buckets[i];
854 while (curr != NULL) { 922 while (curr != NULL)
923 {
855 if (func(curr) != 0) 924 if (func(curr) != 0)
856 return curr; 925 return curr;
857 curr = curr->next; 926 curr = curr->next;
858 } 927 }
859 } 928 }
867 uint8_t hash; 936 uint8_t hash;
868 937
869 if (list == NULL) return NULL; 938 if (list == NULL) return NULL;
870 939
871 hash = nn_hash_user(name); 940 hash = nn_hash_user(name);
872 if (list->buckets[hash] != NULL) { 941 if (list->buckets[hash] != NULL)
942 {
873 nn_user_t *curr = list->buckets[hash]; 943 nn_user_t *curr = list->buckets[hash];
874 while (curr != NULL) { 944 while (curr != NULL)
945 {
875 if (th_strcasecmp(curr->name, name) == 0) 946 if (th_strcasecmp(curr->name, name) == 0)
876 return curr; 947 return curr;
877 curr = curr->next; 948 curr = curr->next;
878 } 949 }
879 } 950 }
883 954
884 955
885 static nn_user_t *nn_user_match_do(nn_user_t *list, const char *pattern, size_t len) 956 static nn_user_t *nn_user_match_do(nn_user_t *list, const char *pattern, size_t len)
886 { 957 {
887 nn_user_t *curr = list; 958 nn_user_t *curr = list;
888 while (curr != NULL) { 959
960 while (curr != NULL)
961 {
889 if (len <= strlen(curr->name) && th_strncasecmp(curr->name, pattern, len) == 0) 962 if (len <= strlen(curr->name) && th_strncasecmp(curr->name, pattern, len) == 0)
890 return curr; 963 return curr;
891 curr = curr->next; 964 curr = curr->next;
892 } 965 }
893 return NULL; 966 return NULL;
899 uint8_t hash; 972 uint8_t hash;
900 973
901 if (list == NULL || pattern == NULL) return NULL; 974 if (list == NULL || pattern == NULL) return NULL;
902 975
903 hash = nn_hash_user(pattern); 976 hash = nn_hash_user(pattern);
904 if (list->buckets[hash] != NULL) { 977 if (list->buckets[hash] != NULL)
978 {
905 nn_user_t *curr = list->buckets[hash]; 979 nn_user_t *curr = list->buckets[hash];
906 size_t len = strlen(pattern); 980 size_t len = strlen(pattern);
907 981
908 if (current != NULL) { 982 if (current != NULL)
983 {
909 nn_user_t *found = NULL; 984 nn_user_t *found = NULL;
910 while (curr != NULL) { 985 while (curr != NULL)
911 if (th_strcasecmp(curr->name, current) == 0) { 986 {
987 if (th_strcasecmp(curr->name, current) == 0)
988 {
912 if (again) 989 if (again)
913 return curr; 990 return curr;
914 found = curr->next; 991 found = curr->next;
915 break; 992 break;
916 } 993 }
971 if (list == NULL || name == NULL) 1048 if (list == NULL || name == NULL)
972 return -1; 1049 return -1;
973 1050
974 /* Check if username is already there */ 1051 /* Check if username is already there */
975 hash = nn_hash_user(name); 1052 hash = nn_hash_user(name);
976 if (list->buckets[hash] != NULL) { 1053 if (list->buckets[hash] != NULL)
1054 {
977 nn_user_t *curr, *prev; 1055 nn_user_t *curr, *prev;
978 curr = list->buckets[hash]; 1056 curr = list->buckets[hash];
979 prev = NULL; 1057 prev = NULL;
980 while (curr != NULL) { 1058 while (curr != NULL)
981 if (th_strcasecmp(curr->name, name) == 0) { 1059 {
1060 if (th_strcasecmp(curr->name, name) == 0)
1061 {
982 if (prev) 1062 if (prev)
983 prev->next = curr->next; 1063 prev->next = curr->next;
984 else 1064 else
985 list->buckets[hash] = curr->next; 1065 list->buckets[hash] = curr->next;
986 1066
987 nn_user_free(curr); 1067 nn_user_free(curr);
988 1068
989 return 0; 1069 return 0;
990 } else { 1070 }
1071 else
1072 {
991 prev = curr; 1073 prev = curr;
992 curr = curr->next; 1074 curr = curr->next;
993 } 1075 }
994 } 1076 }
995 } 1077 }
1024 1106
1025 1107
1026 void nn_user_free_list(nn_user_t *list) 1108 void nn_user_free_list(nn_user_t *list)
1027 { 1109 {
1028 nn_user_t *next, *curr = list; 1110 nn_user_t *next, *curr = list;
1029 while (curr != NULL) { 1111
1112 while (curr != NULL)
1113 {
1030 next = curr->next; 1114 next = curr->next;
1031 nn_user_free(curr); 1115 nn_user_free(curr);
1032 curr = next; 1116 curr = next;
1033 } 1117 }
1034 } 1118 }
1037 { 1121 {
1038 int i; 1122 int i;
1039 if (hash == NULL) 1123 if (hash == NULL)
1040 return; 1124 return;
1041 1125
1042 for (i = 0; i < NN_NUM_BUCKETS; i++) { 1126 for (i = 0; i < NN_NUM_BUCKETS; i++)
1127 {
1043 nn_user_free_list(hash->buckets[i]); 1128 nn_user_free_list(hash->buckets[i]);
1044 hash->buckets[i] = NULL; 1129 hash->buckets[i] = NULL;
1045 } 1130 }
1046 1131
1047 th_free(hash); 1132 th_free(hash);
1073 nn_window_t *res = th_calloc(1, sizeof(nn_window_t)); 1158 nn_window_t *res = th_calloc(1, sizeof(nn_window_t));
1074 1159
1075 if (res == NULL) return NULL; 1160 if (res == NULL) return NULL;
1076 1161
1077 res->data = th_ringbuf_new(NN_BACKBUF_LEN, th_free); 1162 res->data = th_ringbuf_new(NN_BACKBUF_LEN, th_free);
1078 if (res->data == NULL) { 1163 if (res->data == NULL)
1164 {
1079 th_free(res); 1165 th_free(res);
1080 return NULL; 1166 return NULL;
1081 } 1167 }
1082 1168
1083 res->id = th_strdup(id); 1169 res->id = th_strdup(id);
1086 } 1172 }
1087 1173
1088 1174
1089 void nn_window_free(nn_window_t *win) 1175 void nn_window_free(nn_window_t *win)
1090 { 1176 {
1091 if (win != NULL) { 1177 if (win != NULL)
1178 {
1092 th_ringbuf_free(win->data); 1179 th_ringbuf_free(win->data);
1093 th_free(win->id); 1180 th_free(win->id);
1094 th_free(win); 1181 th_free(win);
1095 } 1182 }
1096 } 1183 }