source: util.c @ a252c1a

Last change on this file since a252c1a was a252c1a, checked in by Wilmer van der Gaast <wilmer@…>, at 2005-12-31T20:29:15Z

Removed useless UTF8-related functions (iconv works a lot better).

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