source: protocols/util.c @ 3d64e5b

Last change on this file since 3d64e5b was c572dd6, checked in by Wilmer van der Gaast <wilmer@…>, at 2005-11-18T12:41:58Z

HTML stripping is optional again (but still safer than before 0.93), but now enabled by default.

  • Property mode set to 100644
File size: 8.0 KB
Line 
1  /********************************************************************\
2  * BitlBee -- An IRC to other IM-networks gateway                     *
3  *                                                                    *
4  * Copyright 2002-2004 Wilmer van der Gaast and others                *
5  \********************************************************************/
6
7/*
8 * nogaim
9 *
10 * Gaim without gaim - for BitlBee
11 *
12 * Copyright (C) 1998-1999, Mark Spencer <markster@marko.net>
13 *                          (and possibly other members of the Gaim team)
14 * Copyright 2002-2004 Wilmer van der Gaast <lintux@lintux.cx>
15 */
16
17/*
18  This program is free software; you can redistribute it and/or modify
19  it under the terms of the GNU General Public License as published by
20  the Free Software Foundation; either version 2 of the License, or
21  (at your option) any later version.
22
23  This program is distributed in the hope that it will be useful,
24  but WITHOUT ANY WARRANTY; without even the implied warranty of
25  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
26  GNU General Public License for more details.
27
28  You should have received a copy of the GNU General Public License with
29  the Debian GNU/Linux distribution in /usr/share/common-licenses/GPL;
30  if not, write to the Free Software Foundation, Inc., 59 Temple Place,
31  Suite 330, Boston, MA  02111-1307  USA
32*/
33
34/* Parts from util.c from gaim needed by nogaim */
35#define BITLBEE_CORE
36#include "nogaim.h"
37#include <stdio.h>
38#include <stdlib.h>
39#include <string.h>
40#include <glib.h>
41#include <time.h>
42
43char *utf8_to_str(const char *in)
44{
45        int n = 0, i = 0;
46        int inlen;
47        char *result;
48
49        if (!in)
50                return NULL;
51
52        inlen = strlen(in);
53
54        result = g_malloc(inlen + 1);
55
56        while (n <= inlen - 1) {
57                long c = (long)in[n];
58                if (c < 0x80)
59                        result[i++] = (char)c;
60                else {
61                        if ((c & 0xC0) == 0xC0)
62                                result[i++] =
63                                    (char)(((c & 0x03) << 6) | (((unsigned char)in[++n]) & 0x3F));
64                        else if ((c & 0xE0) == 0xE0) {
65                                if (n + 2 <= inlen) {
66                                        result[i] =
67                                            (char)(((c & 0xF) << 4) | (((unsigned char)in[++n]) & 0x3F));
68                                        result[i] =
69                                            (char)(((unsigned char)result[i]) |
70                                                   (((unsigned char)in[++n]) & 0x3F));
71                                        i++;
72                                } else
73                                        n += 2;
74                        } else if ((c & 0xF0) == 0xF0)
75                                n += 3;
76                        else if ((c & 0xF8) == 0xF8)
77                                n += 4;
78                        else if ((c & 0xFC) == 0xFC)
79                                n += 5;
80                }
81                n++;
82        }
83        result[i] = '\0';
84
85        return result;
86}
87
88char *str_to_utf8(const char *in)
89{
90        int n = 0, i = 0;
91        int inlen;
92        char *result = NULL;
93
94        if (!in)
95                return NULL;
96
97        inlen = strlen(in);
98
99        result = g_malloc(inlen * 2 + 1);
100
101        while (n < inlen) {
102                long c = (long)in[n];
103                if (c == 27) {
104                        n += 2;
105                        if (in[n] == 'x')
106                                n++;
107                        if (in[n] == '3')
108                                n++;
109                        n += 2;
110                        continue;
111                }
112                /* why are we removing newlines and carriage returns?
113                if ((c == 0x0D) || (c == 0x0A)) {
114                        n++;
115                        continue;
116                }
117                */
118                if (c < 128)
119                        result[i++] = (char)c;
120                else {
121                        result[i++] = (char)((c >> 6) | 192);
122                        result[i++] = (char)((c & 63) | 128);
123                }
124                n++;
125        }
126        result[i] = '\0';
127
128        return result;
129}
130
131void strip_linefeed(gchar *text)
132{
133        int i, j;
134        gchar *text2 = g_malloc(strlen(text) + 1);
135
136        for (i = 0, j = 0; text[i]; i++)
137                if (text[i] != '\r')
138                        text2[j++] = text[i];
139        text2[j] = '\0';
140
141        strcpy(text, text2);
142        g_free(text2);
143}
144
145char *add_cr(char *text)
146{
147        char *ret = NULL;
148        int count = 0, j;
149        unsigned int i;
150
151        if (text[0] == '\n')
152                count++;
153        for (i = 1; i < strlen(text); i++)
154                if (text[i] == '\n' && text[i - 1] != '\r')
155                        count++;
156
157        if (count == 0)
158                return g_strdup(text);
159
160        ret = g_malloc0(strlen(text) + count + 1);
161
162        i = 0; j = 0;
163        if (text[i] == '\n')
164                ret[j++] = '\r';
165        ret[j++] = text[i++];
166        for (; i < strlen(text); i++) {
167                if (text[i] == '\n' && text[i - 1] != '\r')
168                        ret[j++] = '\r';
169                ret[j++] = text[i];
170        }
171
172        return ret;
173}
174
175static char alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" "0123456789+/";
176
177/* XXX Find bug */
178char *tobase64(const char *text)
179{
180        char *out = NULL;
181        const char *c;
182        unsigned int tmp = 0;
183        int len = 0, n = 0;
184
185        c = text;
186
187        while (*c) {
188                tmp = tmp << 8;
189                tmp += *c;
190                n++;
191
192                if (n == 3) {
193                        out = g_realloc(out, len + 4);
194                        out[len] = alphabet[(tmp >> 18) & 0x3f];
195                        out[len + 1] = alphabet[(tmp >> 12) & 0x3f];
196                        out[len + 2] = alphabet[(tmp >> 6) & 0x3f];
197                        out[len + 3] = alphabet[tmp & 0x3f];
198                        len += 4;
199                        tmp = 0;
200                        n = 0;
201                }
202                c++;
203        }
204        switch (n) {
205
206        case 2:
207                tmp <<= 8;
208                out = g_realloc(out, len + 5);
209                out[len] = alphabet[(tmp >> 18) & 0x3f];
210                out[len + 1] = alphabet[(tmp >> 12) & 0x3f];
211                out[len + 2] = alphabet[(tmp >> 6) & 0x3f];
212                out[len + 3] = '=';
213                out[len + 4] = 0;
214                break;
215        case 1:
216                tmp <<= 16;
217                out = g_realloc(out, len + 5);
218                out[len] = alphabet[(tmp >> 18) & 0x3f];
219                out[len + 1] = alphabet[(tmp >> 12) & 0x3f];
220                out[len + 2] = '=';
221                out[len + 3] = '=';
222                out[len + 4] = 0;
223                break;
224        case 0:
225                out = g_realloc(out, len + 1);
226                out[len] = 0;
227                break;
228        }
229        return out;
230}
231
232char *normalize(const char *s)
233{
234        static char buf[BUF_LEN];
235        char *t, *u;
236        int x = 0;
237
238        g_return_val_if_fail((s != NULL), NULL);
239
240        u = t = g_strdup(s);
241
242        strcpy(t, s);
243        g_strdown(t);
244
245        while (*t && (x < BUF_LEN - 1)) {
246                if (*t != ' ') {
247                        buf[x] = *t;
248                        x++;
249                }
250                t++;
251        }
252        buf[x] = '\0';
253        g_free(u);
254        return buf;
255}
256
257time_t get_time(int year, int month, int day, int hour, int min, int sec)
258{
259        struct tm tm;
260
261        tm.tm_year = year - 1900;
262        tm.tm_mon = month - 1;
263        tm.tm_mday = day;
264        tm.tm_hour = hour;
265        tm.tm_min = min;
266        tm.tm_sec = sec >= 0 ? sec : time(NULL) % 60;
267        return mktime(&tm);
268}
269
270typedef struct htmlentity
271{
272        char code[8];
273        char is;
274} htmlentity_t;
275
276/* FIXME: This is ISO8859-1(5) centric, so might cause problems with other charsets. */
277
278static htmlentity_t ent[] =
279{
280        { "lt",     '<' },
281        { "gt",     '>' },
282        { "amp",    '&' },
283        { "quot",   '"' },
284        { "aacute", 'á' },
285        { "eacute", 'é' },
286        { "iacute", 'é' },
287        { "oacute", 'ó' },
288        { "uacute", 'ú' },
289        { "agrave", 'à' },
290        { "egrave", 'è' },
291        { "igrave", 'ì' },
292        { "ograve", 'ò' },
293        { "ugrave", 'ù' },
294        { "acirc",  'â' },
295        { "ecirc",  'ê' },
296        { "icirc",  'î' },
297        { "ocirc",  'ô' },
298        { "ucirc",  'û' },
299        { "nbsp",   ' ' },
300        { "",        0  }
301};
302
303void strip_html( char *in )
304{
305        char *start = in;
306        char *out = g_malloc( strlen( in ) + 1 );
307        char *s = out, *cs;
308        int i, matched;
309       
310        memset( out, 0, strlen( in ) + 1 );
311       
312        while( *in )
313        {
314                if( *in == '<' && ( isalpha( *(in+1) ) || *(in+1) == '/' ) )
315                {
316                        /* If in points at a < and in+1 points at a letter or a slash, this is probably
317                           a HTML-tag. Try to find a closing > and continue there. If the > can't be
318                           found, assume that it wasn't a HTML-tag after all. */
319                       
320                        cs = in;
321                       
322                        while( *in && *in != '>' )
323                                in ++;
324                       
325                        if( *in )
326                        {
327                                if( g_strncasecmp( cs+1, "br", 2) == 0 )
328                                        *(s++) = '\n';
329                                in ++;
330                        }
331                        else
332                        {
333                                in = cs;
334                                *(s++) = *(in++);
335                        }
336                }
337                else if( *in == '&' )
338                {
339                        cs = ++in;
340                        while( *in && isalpha( *in ) )
341                                in ++;
342                       
343                        if( *in == ';' ) in ++;
344                        matched = 0;
345                       
346                        for( i = 0; *ent[i].code; i ++ )
347                                if( g_strncasecmp( ent[i].code, cs, strlen( ent[i].code ) ) == 0 )
348                                {
349                                        *(s++) = ent[i].is;
350                                        matched = 1;
351                                        break;
352                                }
353
354                        /* None of the entities were matched, so return the string */
355                        if( !matched )
356                        {
357                                in = cs - 1;
358                                *(s++) = *(in++);
359                        }
360                }
361                else
362                {
363                        *(s++) = *(in++);
364                }
365        }
366       
367        strcpy( start, out );
368        g_free( out );
369}
370
371char *escape_html( const char *html )
372{
373        const char *c = html;
374        GString *ret;
375        char *str;
376       
377        if( html == NULL )
378                return( NULL );
379       
380        ret = g_string_new( "" );
381       
382        while( *c )
383        {
384                switch( *c )
385                {
386                        case '&':
387                                ret = g_string_append( ret, "&amp;" );
388                                break;
389                        case '<':
390                                ret = g_string_append( ret, "&lt;" );
391                                break;
392                        case '>':
393                                ret = g_string_append( ret, "&gt;" );
394                                break;
395                        case '"':
396                                ret = g_string_append( ret, "&quot;" );
397                                break;
398                        default:
399                                ret = g_string_append_c( ret, *c );
400                }
401                c ++;
402        }
403       
404        str = ret->str;
405        g_string_free( ret, FALSE );
406        return( str );
407}
408
409void info_string_append(GString *str, char *newline, char *name, char *value)
410{
411        if( value && value[0] )
412                g_string_sprintfa( str, "%s%s: %s", newline, name, value );
413}
Note: See TracBrowser for help on using the repository browser.