comparison libnnchat.c @ 62:ff5d74f0d428

Moved some functions to "libnnchat".
author Matti Hamalainen <ccr@tnsp.org>
date Tue, 11 Nov 2008 21:57:51 +0200
parents
children 6a3a917303e4
comparison
equal deleted inserted replaced
61:b802a799c31a 62:ff5d74f0d428
1 /*
2 * NNChat - Custom chat client for NewbieNudes.com chatrooms
3 * Written by Matti 'ccr' Hämäläinen
4 * (C) Copyright 2008 Tecnic Software productions (TNSP)
5 */
6 #include "libnnchat.h"
7
8
9 typedef struct {
10 char c;
11 char *ent;
12 } html_entity_t;
13
14
15 html_entity_t HTMLEntities[] = {
16 { '<', "&lt;" },
17 { '>', "&gt;" },
18 };
19
20 const int numHTMLEntities = (sizeof(HTMLEntities) / sizeof(HTMLEntities[0]));
21
22
23 int openConnection(struct in_addr *addr, const int port)
24 {
25 struct sockaddr_in tmpAddr;
26 int sock = -1;
27
28 tmpAddr.sin_family = AF_INET;
29 tmpAddr.sin_port = htons(port);
30 tmpAddr.sin_addr = *addr;
31
32 THMSG(1, "Connecting to %s:%d ...\n",
33 inet_ntoa(tmpAddr.sin_addr), port);
34
35 if ((sock = socket(PF_INET, SOCK_STREAM, 0)) == -1) {
36 THERR("Could not open socket: %s\n", strerror(errno));
37 return -2;
38 }
39
40 THMSG(2, "Using socket %d.\n", sock);
41
42 if (connect(sock, (struct sockaddr *) &tmpAddr, sizeof(tmpAddr)) == -1) {
43 THERR("Could not connect: %s\n", strerror(errno));
44 return -5;
45 }
46
47 return sock;
48 }
49
50
51 void closeConnection(const int sock)
52 {
53 if (sock >= 0) {
54 close(sock);
55 }
56 }
57
58
59 BOOL sendToSocket(const int sock, char *buf, const size_t bufLen)
60 {
61 size_t bufLeft = bufLen;
62 char *bufPtr = buf;
63
64 while (bufLeft > 0) {
65 ssize_t bufSent;
66 bufSent = send(sock, bufPtr, bufLeft, 0);
67 if (bufSent < 0) return FALSE;
68 bufLeft -= bufSent;
69 bufPtr += bufSent;
70 }
71 return TRUE;
72 }
73
74
75 BOOL bufRealloc(char **buf, size_t *size, size_t add)
76 {
77 return ((*buf = th_realloc(*buf, *size + add)) != NULL);
78 }
79
80 #define PUSHCHAR(x) bufPushChar(&result, &resSize, &resPos, x)
81 BOOL bufPushChar(char **buf, size_t *size, size_t *pos, char ch)
82 {
83 if (*pos >= *size && !bufRealloc(buf, size, SET_ALLOC_SIZE))
84 return FALSE;
85
86 (*buf)[*pos] = ch;
87 (*pos)++;
88 return TRUE;
89 }
90
91 #define PUSHSTR(x) bufPushStr(&result, &resSize, &resPos, x)
92 BOOL bufPushStr(char **buf, size_t *size, size_t *pos, char *str)
93 {
94 size_t tmpLen;
95
96 if (!str) return FALSE;
97 tmpLen = strlen(str);
98
99 if ((*pos + tmpLen) >= *size && !bufRealloc(buf, size, tmpLen + SET_ALLOC_SIZE))
100 return FALSE;
101
102 strcpy(*buf + *pos, str);
103 (*pos) += tmpLen;
104 return TRUE;
105 }
106
107
108 char *encodeStr1(const char *str)
109 {
110 const char *s = str;
111 char *result;
112 size_t resSize, resPos = 0;
113
114 if (!str) return NULL;
115
116 resSize = strlen(str) + SET_ALLOC_SIZE;
117 if ((result = th_malloc(resSize)) == NULL)
118 return NULL;
119
120 while (*s) {
121 switch (*s) {
122 case 32:
123 PUSHCHAR('+');
124 break;
125
126 default:
127 if (th_isalnum(*s))
128 PUSHCHAR(*s);
129 else {
130 char tmpStr[4];
131 sprintf(tmpStr, "%2X", (unsigned char) *s);
132 PUSHCHAR('%');
133 PUSHSTR(tmpStr);
134 }
135 break;
136 }
137 s++;
138 }
139 PUSHCHAR(0);
140
141 return result;
142 }
143
144
145 static int getHexDigit(const int c, const int shift)
146 {
147 int i;
148
149 if (c >= 'A' && c <= 'F')
150 i = c - 'A' + 10;
151 else if (c >= 'a' && c <= 'f')
152 i = c - 'a' + 10;
153 else if (c >= '0' && c <= '9')
154 i = c - '0';
155 else
156 return -1;
157
158 return i << shift;
159 }
160
161
162 char *decodeStr1(const char *str)
163 {
164 const char *s = str;
165 char *result;
166 size_t resSize, resPos = 0;
167 int c;
168
169 if (!str) return NULL;
170
171 resSize = strlen(str) + SET_ALLOC_SIZE;
172 if ((result = th_malloc(resSize)) == NULL)
173 return NULL;
174
175 while (*s) {
176 switch (*s) {
177 case '+':
178 PUSHCHAR(' ');
179 s++;
180 break;
181
182 case '½':
183 /* Escape these .. */
184 PUSHCHAR('½');
185 PUSHCHAR('½');
186 s++;
187 break;
188
189 case '\r':
190 PUSHCHAR(' ');
191 s++;
192 break;
193
194 case '%':
195 s++;
196 if (*s == '%')
197 PUSHCHAR('%');
198 else if ((c = getHexDigit(*s, 4)) >= 0) {
199 int i = getHexDigit(*(++s), 0);
200 if (i >= 0) {
201 PUSHCHAR(c | i);
202 } else {
203 PUSHCHAR('§');
204 PUSHCHAR(*s);
205 }
206 } else {
207 PUSHCHAR('§');
208 PUSHCHAR(*s);
209 }
210 s++;
211 break;
212
213 default:
214 PUSHCHAR(*s);
215 s++;
216 }
217 }
218 PUSHCHAR(0);
219
220 return result;
221 }
222
223
224 char *stripXMLTags(const char *str)
225 {
226 const char *s = str;
227 char *result;
228 size_t resSize, resPos = 0;
229
230 if (!str) return NULL;
231
232 resSize = strlen(str) + SET_ALLOC_SIZE;
233 if ((result = th_malloc(resSize)) == NULL)
234 return NULL;
235
236 while (*s) {
237 if (*s == '<') {
238 while (*s && *s != '>') s++;
239 if (*s == '>') s++;
240 } else
241 PUSHCHAR(*s++);
242 }
243 PUSHCHAR(0);
244
245 return result;
246 }
247
248
249 char *encodeStr2(const char *str)
250 {
251 const char *s = str;
252 char *result;
253 size_t resSize, resPos = 0;
254
255 if (!str) return NULL;
256
257 resSize = strlen(str) + SET_ALLOC_SIZE;
258 if ((result = th_malloc(resSize)) == NULL)
259 return NULL;
260
261 while (*s) {
262 int i;
263 BOOL found = FALSE;
264 for (i = 0; i < numHTMLEntities; i++)
265 if (HTMLEntities[i].c == *s) {
266 PUSHSTR(HTMLEntities[i].ent);
267 found = TRUE;
268 break;
269 }
270 if (!found) PUSHCHAR(*s);
271
272 s++;
273 }
274 PUSHCHAR(0);
275
276 return result;
277 }
278
279
280 char *decodeStr2(const char *str)
281 {
282 const char *s = str;
283 char *result;
284 size_t resSize, resPos = 0;
285
286 if (!str) return NULL;
287
288 resSize = strlen(str);
289 if ((result = th_malloc(resSize)) == NULL)
290 return NULL;
291
292 while (*s) {
293 if (*s == '&') {
294 int i;
295 BOOL found = FALSE;
296 for (i = 0; i < numHTMLEntities; i++) {
297 html_entity_t *ent = &HTMLEntities[i];
298 int len = strlen(ent->ent);
299 if (!strncmp(s, ent->ent, len)) {
300 PUSHCHAR(ent->c);
301 s += len;
302 found = TRUE;
303 break;
304 }
305 }
306 if (!found) PUSHCHAR(*s++);
307 } else
308 PUSHCHAR(*s++);
309 }
310 PUSHCHAR(0);
311
312 return result;
313 }
314
315
316 BOOL sendUserMsg(const int sock, const char *user, const char *fmt, ...)
317 {
318 char tmpBuf[SET_BUFSIZE], tmpBuf2[SET_BUFSIZE + 256];
319 int n;
320 va_list ap;
321
322 va_start(ap, fmt);
323 n = vsnprintf(tmpBuf, sizeof(tmpBuf), fmt, ap);
324 va_end(ap);
325
326 if (n < 0) return FALSE;
327
328 snprintf(tmpBuf2, sizeof(tmpBuf2),
329 "<USER>%s</USER><MESSAGE>%s</MESSAGE>",
330 user, tmpBuf);
331
332 return sendToSocket(sock, tmpBuf2, strlen(tmpBuf2) + 1);
333 }
334