1 /*
2  * Ostatnia aktualizacja:
3  *
4  * - $Id: utils.c,v 1.28 2003/01/09 12:21:02 mati Exp $
5  *
6  */
7 
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <unistd.h>
11 #include <string.h>
12 #include <sys/types.h>
13 
14 #include "libtlen.h"
15 
16 /*
17  * int debug
18  *
19  * zmienna ze stanem wiadomo�ci debuga (w�/wy�)
20  * domy�lnie wy��czone
21  *
22  */
23 
24 int debug = 0;
25 
26 /*
27  * tlen_ping()
28  *
29  * Wysy�a pakiet kontrolny keep-alive do serwera
30  *
31  * - sesja - identyfikator sesji
32  *
33  * Ping powinien by� wysy�any co oko�o 60 sekund
34  */
35 
tlen_ping(struct tlen_session * sesja)36 void tlen_ping(struct tlen_session *sesja)
37 {
38 	tlen_socket_write_string (sesja, "  \t  ");
39 }
40 
41 /*
42  * tlen_encode()
43  *
44  * Koduje tekst przy pomocy urlencode
45  *
46  * - what - tekst kt�ry chcemy zakodowa�
47  *
48  * Dla zwracanego tekstu alokowana jest pami��, trzeba go
49  * zwolni� przy u�yciu free()
50  *
51  */
52 
tlen_encode(const char * what)53 char *tlen_encode (const char *what)
54 {
55 	if (what)
56 	{
57 		const unsigned char *s = what;
58 		unsigned char *ptr, *str;
59 
60 		str = ptr = (unsigned char *) calloc (3 * strlen (s) + 1,1);
61 		if (!str)
62 			return 0;
63 		while (*s)
64 		{
65 			if (*s == ' ')
66 				*ptr++ = '+';
67 			else if ((*s < '0' && *s != '-' && *s != '.')
68 				 || (*s < 'A' && *s > '9') || (*s > 'Z'
69 							       && *s < 'a'
70 							       && *s != '_')
71 				 || (*s > 'z'))
72 			{
73 				sprintf (ptr, "%%%02X", *s);
74 				ptr += 3;
75 			}
76 			else
77 				*ptr++ = *s;
78 			s++;
79 		}
80 		return str;
81 	}
82 	return 0;
83 }
84 
85 /*
86  * tlen_decode()
87  *
88  * Dekoduje tekst przy pomocy urldecode
89  *
90  * - what - tekst kt�ry chcemy rozkodowa�
91  *
92  * Dla zwracanego tekstu alokowana jest pami��, trzeba go
93  * zwolni� przy u�yciu free()
94  *
95  */
96 
tlen_decode(const char * what)97 char *tlen_decode(const char *what)
98 {
99 	if (what)
100 	{
101 		unsigned char *dest, *data, *retval;
102 		dest = data = retval = strdup (what);
103 		if (!data)
104 			return 0;
105 
106 		while (*data)
107 		{
108 			if (*data == '+')
109 				*dest++ = ' ';
110 			else if ((*data == '%') && isxdigit ((int) data[1])
111 				 && isxdigit ((int) data[2]))
112 			{
113 				int code;
114 				sscanf (data + 1, "%2x", &code);
115 				if (code != '\r')
116 					*dest++ = (unsigned char) code;
117 				data += 2;
118 			}
119 			else
120 				*dest++ = *data;
121 			data++;
122 		}
123 		*dest = '\0';
124 		return retval;
125 	}
126 	return 0;
127 }
128 
129 /*
130  * tlen_debug_raw()
131  *
132  * Wy�wietla na stderr tekst pomocniczy przy debugowaniu
133  *
134  * - name - nazwa funkcji z kt�rej debug zosta� wywo�any
135  * - format - format tekstu do wy�wietlenia
136  * - ... - wy�wietlany tekst(y)
137  *
138  * Funkcja wewn�trzna, nale�y u�ywa� wrappera tlen_debug(),
139  * kt�ry automatycznie wype�nia pierwsze pole (name)
140  *
141  */
142 
tlen_debug_raw(const char * name,char * format,...)143 void tlen_debug_raw(const char *name, char *format, ...) {
144     if (debug==1) {
145 	va_list ap;
146 	va_start (ap, format);
147 	printf("--- %s ---\n",name);
148 	vprintf (format, ap);
149 	va_end (ap);
150     }
151 }
152 
153 /*
154  * tlen_stripresource()
155  *
156  * Usuwa z podanego tekstu wszystko co po znaku /
157  *
158  * - jid - tekst z kt�rego ma zosta� usuniety "resource"
159  *
160  * U�ywane dla identyfikator�w jabbera dla przychodz�cych
161  * zapyta� (u�ytkownik@tlen.pl/t). Tekst zamieniany jest
162  * bezpo�rednio w pami�ci.
163  *
164  */
165 
tlen_stripresource(char * jid)166 int tlen_stripresource (char *jid)
167 {
168     if (strchr(jid,'/')) *strchr(jid,'/')=0;
169     return 1;
170 }
171 
172 /*
173  * tlen_setdebug()
174  *
175  * Pozwala na ustawianie, czy wiadomo�ci debug maj� by�
176  * wy�wietlane, czy nie
177  *
178  * - dbg - w��cz/wy��cz, odpowiednio 0/1
179  *
180  */
181 
tlen_setdebug(int dbg)182 int tlen_setdebug (int dbg)
183 {
184     debug = dbg;
185     return debug;
186 }
187 
188 /*
189  * static char tlen_base64_charset[]
190  *
191  * Tablica znak�w dla funkcji koduj�cych base64
192  *
193  */
194 
195 static char tlen_base64_charset[] =
196 	"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
197 
198 /*
199  * tlen_base64_encode()
200  *
201  * Funkcja koduj�ca tekst przy u�yciu base64
202  *
203  * - buf - tekst do zakodowania
204  *
205  * Warto�� zwracana jest alokowana, nale�y zwolni� przez free()
206  *
207  */
208 
tlen_base64_encode(const char * buf)209 char *tlen_base64_encode(const char *buf)
210 {
211     char *out, *res;
212     int i = 0, j = 0, k = 0, len = strlen(buf);
213 
214     res = out = malloc((len / 3 + 1) * 4 + 2);
215 
216     if (!res)
217 	return NULL;
218 
219     while (j <= len) {
220 	switch (i % 4) {
221 	    case 0:
222 		k = (buf[j] & 252) >> 2;
223 		break;
224 	    case 1:
225 		if (j < len)
226 		    k = ((buf[j] & 3) << 4) | ((buf[j + 1] & 240) >> 4);
227 		else
228 		    k = (buf[j] & 3) << 4;
229 
230 		j++;
231 		break;
232 	    case 2:
233 		if (j < len)
234 		    k = ((buf[j] & 15) << 2) | ((buf[j + 1] & 192) >> 6);
235 		else
236 		    k = (buf[j] & 15) << 2;
237 
238 		j++;
239 		break;
240 	    case 3:
241 		k = buf[j++] & 63;
242 		break;
243 	}
244 	*out++ = tlen_base64_charset[k];
245 	i++;
246     }
247 
248     if (i % 4)
249 	for (j = 0; j < 4 - (i % 4); j++, out++)
250 	    *out = '=';
251 
252     *out = 0;
253 
254     return res;
255 }
256 
257 /*
258  * tlen_base64_decode()
259  *
260  * Funkcja dekoduj�ca tekst przy u�yciu base64
261  *
262  * - buf - tekst do zdekodowania
263  *
264  * Warto�� zwracana jest alokowana, nale�y zwolni� przez free()
265  *
266  */
267 
tlen_base64_decode(const char * buf)268 char *tlen_base64_decode(const char *buf)
269 {
270     char *res, *save, *foo, val;
271     const char *end;
272     int index = 0;
273 
274     if (!buf)
275         return NULL;
276 
277     save = res = calloc(1, (strlen(buf) / 4 + 1) * 3 + 2);
278 
279     if (!save)
280         return NULL;
281 
282     end = buf + strlen(buf);
283 
284     while (*buf && buf < end) {
285         if (*buf == '\r' || *buf == '\n') {
286             buf++;
287 	    continue;
288 	}
289 
290         if (!(foo = strchr(tlen_base64_charset, *buf)))
291             foo = tlen_base64_charset;
292 
293         val = (int)foo - (int)tlen_base64_charset;
294 																													                buf++;
295         switch (index) {
296 	    case 0:
297 		*res |= val << 2;
298 		break;
299 	    case 1:
300                 *res++ |= val >> 4;
301                 *res |= val << 4;
302                 break;
303             case 2:
304                 *res++ |= val >> 2;
305                 *res |= val << 6;
306                 break;
307             case 3:
308                 *res++ |= val;
309                 break;
310 	}
311 	index++;
312 	index %= 4;
313     }
314     *res = 0;
315 
316     return save;
317 }
318