1 /*
2  *  This program is free software; you can redistribute it and/or modify
3  *  it under the terms of the GNU General Public License as published by
4  *  the Free Software Foundation; either version 2 of the License, or
5  *  (at your option) any later version.
6  *
7  *  This program is distributed in the hope that it will be useful,
8  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
9  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  *  GNU General Public License for more details.
11  *
12  *  You should have received a copy of the GNU General Public License
13  *  along with this program; if not, write to the Free Software
14  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
15  *
16  *  Jabber
17  *  Copyright (C) 1998-1999 The Jabber Team http://jabber.org/
18  */
19 
20 #include "libxode.h"
21 
j_strdup(const char * str)22 char *j_strdup(const char *str)
23 {
24     if(str == NULL)
25         return NULL;
26     else
27         return strdup(str);
28 }
29 
j_strcat(char * dest,char * txt)30 char *j_strcat(char *dest, char *txt)
31 {
32     if(!txt) return(dest);
33 
34     while(*txt)
35         *dest++ = *txt++;
36     *dest = '\0';
37 
38     return(dest);
39 }
40 
j_strcmp(const char * a,const char * b)41 int j_strcmp(const char *a, const char *b)
42 {
43     if(a == NULL || b == NULL)
44         return -1;
45     else
46         return strcmp(a, b);
47 }
48 
j_strcasecmp(const char * a,const char * b)49 int j_strcasecmp(const char *a, const char *b)
50 {
51     if(a == NULL || b == NULL)
52         return -1;
53     else
54         return strcasecmp(a, b);
55 }
56 
j_strncmp(const char * a,const char * b,int i)57 int j_strncmp(const char *a, const char *b, int i)
58 {
59     if(a == NULL || b == NULL)
60         return -1;
61     else
62         return strncmp(a, b, i);
63 }
64 
j_strncasecmp(const char * a,const char * b,int i)65 int j_strncasecmp(const char *a, const char *b, int i)
66 {
67     if(a == NULL || b == NULL)
68         return -1;
69     else
70         return strncasecmp(a, b, i);
71 }
72 
j_strlen(const char * a)73 int j_strlen(const char *a)
74 {
75     if(a == NULL)
76         return 0;
77     else
78         return strlen(a);
79 }
80 
j_atoi(const char * a,int def)81 int j_atoi(const char *a, int def)
82 {
83     if(a == NULL)
84         return def;
85     else
86         return atoi(a);
87 }
88 
spool_new(pool p)89 spool spool_new(pool p)
90 {
91     spool s;
92 
93     s = pmalloc(p, sizeof(struct spool_struct));
94     s->p = p;
95     s->len = 0;
96     s->last = NULL;
97     s->first = NULL;
98     return s;
99 }
100 
spool_add(spool s,char * str)101 void spool_add(spool s, char *str)
102 {
103     struct spool_node *sn;
104     int len;
105 
106     if(str == NULL)
107         return;
108 
109     len = strlen(str);
110     if(len == 0)
111         return;
112 
113     sn = pmalloc(s->p, sizeof(struct spool_node));
114     sn->c = pstrdup(s->p, str);
115     sn->next = NULL;
116 
117     s->len += len;
118     if(s->last != NULL)
119         s->last->next = sn;
120     s->last = sn;
121     if(s->first == NULL)
122         s->first = sn;
123 }
124 
spooler(spool s,...)125 void spooler(spool s, ...)
126 {
127     va_list ap;
128     char *arg = NULL;
129 
130     if(s == NULL)
131         return;
132 
133     va_start(ap, s);
134 
135     /* loop till we hit our end flag, the first arg */
136     while(1)
137     {
138         arg = va_arg(ap,char *);
139         if((void *)arg == (void *)s)
140             break;
141         else
142             spool_add(s, arg);
143     }
144 
145     va_end(ap);
146 }
147 
spool_print(spool s)148 char *spool_print(spool s)
149 {
150     char *ret,*tmp;
151     struct spool_node *next;
152 
153     if(s == NULL || s->len == 0 || s->first == NULL)
154         return NULL;
155 
156     ret = pmalloc(s->p, s->len + 1);
157     *ret = '\0';
158 
159     next = s->first;
160     tmp = ret;
161     while(next != NULL)
162     {
163         tmp = j_strcat(tmp,next->c);
164         next = next->next;
165     }
166 
167     return ret;
168 }
169 
170 /* convenience :) */
spools(pool p,...)171 char *spools(pool p, ...)
172 {
173     va_list ap;
174     spool s;
175     char *arg = NULL;
176 
177     if(p == NULL)
178         return NULL;
179 
180     s = spool_new(p);
181 
182     va_start(ap, p);
183 
184     /* loop till we hit our end flag, the first arg */
185     while(1)
186     {
187         arg = va_arg(ap,char *);
188         if((void *)arg == (void *)p)
189             break;
190         else
191             spool_add(s, arg);
192     }
193 
194     va_end(ap);
195 
196     return spool_print(s);
197 }
198 
199 
strunescape(pool p,char * buf)200 char *strunescape(pool p, char *buf)
201 {
202     int i,j=0;
203     char *temp;
204 
205     if (p == NULL || buf == NULL) return(NULL);
206 
207     if (strchr(buf,'&') == NULL) return(buf);
208 
209     temp = pmalloc(p,strlen(buf)+1);
210 
211     if (temp == NULL) return(NULL);
212 
213     for(i=0;i<strlen(buf);i++)
214     {
215         if (buf[i]=='&')
216         {
217             if (strncmp(&buf[i],"&amp;",5)==0)
218             {
219                 temp[j] = '&';
220                 i += 4;
221             } else if (strncmp(&buf[i],"&quot;",6)==0) {
222                 temp[j] = '\"';
223                 i += 5;
224             } else if (strncmp(&buf[i],"&apos;",6)==0) {
225                 temp[j] = '\'';
226                 i += 5;
227             } else if (strncmp(&buf[i],"&lt;",4)==0) {
228                 temp[j] = '<';
229                 i += 3;
230             } else if (strncmp(&buf[i],"&gt;",4)==0) {
231                 temp[j] = '>';
232                 i += 3;
233             }
234         } else {
235             temp[j]=buf[i];
236         }
237         j++;
238     }
239     temp[j]='\0';
240     return(temp);
241 }
242 
243 
strescape(pool p,char * buf)244 char *strescape(pool p, char *buf)
245 {
246     int i,j,oldlen,newlen;
247     char *temp;
248 
249     if (p == NULL || buf == NULL) return(NULL);
250 
251     oldlen = newlen = strlen(buf);
252     for(i=0;i<oldlen;i++)
253     {
254         switch(buf[i])
255         {
256         case '&':
257             newlen+=5;
258             break;
259         case '\'':
260             newlen+=6;
261             break;
262         case '\"':
263             newlen+=6;
264             break;
265         case '<':
266             newlen+=4;
267             break;
268         case '>':
269             newlen+=4;
270             break;
271         }
272     }
273 
274     if(oldlen == newlen) return buf;
275 
276     temp = pmalloc(p,newlen+1);
277 
278     if (temp==NULL) return(NULL);
279 
280     for(i=j=0;i<oldlen;i++)
281     {
282         switch(buf[i])
283         {
284         case '&':
285             memcpy(&temp[j],"&amp;",5);
286             j += 5;
287             break;
288         case '\'':
289             memcpy(&temp[j],"&apos;",6);
290             j += 6;
291             break;
292         case '\"':
293             memcpy(&temp[j],"&quot;",6);
294             j += 6;
295             break;
296         case '<':
297             memcpy(&temp[j],"&lt;",4);
298             j += 4;
299             break;
300         case '>':
301             memcpy(&temp[j],"&gt;",4);
302             j += 4;
303             break;
304         default:
305             temp[j++] = buf[i];
306         }
307     }
308     temp[j] = '\0';
309     return temp;
310 }
311 
zonestr(char * file,int line)312 char *zonestr(char *file, int line)
313 {
314     static char buff[64];
315     int i;
316 
317     i = snprintf(buff,63,"%s:%d",file,line);
318     buff[i] = '\0';
319 
320     return buff;
321 }
322 
str_b64decode(char * str)323 void str_b64decode(char* str)
324 {
325     char *cur;
326     int d, dlast, phase;
327     unsigned char c;
328     static int table[256] = {
329         -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,  /* 00-0F */
330         -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,  /* 10-1F */
331         -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,62,-1,-1,-1,63,  /* 20-2F */
332         52,53,54,55,56,57,58,59,60,61,-1,-1,-1,-1,-1,-1,  /* 30-3F */
333         -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,  /* 40-4F */
334         15,16,17,18,19,20,21,22,23,24,25,-1,-1,-1,-1,-1,  /* 50-5F */
335         -1,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,  /* 60-6F */
336         41,42,43,44,45,46,47,48,49,50,51,-1,-1,-1,-1,-1,  /* 70-7F */
337         -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,  /* 80-8F */
338         -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,  /* 90-9F */
339         -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,  /* A0-AF */
340         -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,  /* B0-BF */
341         -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,  /* C0-CF */
342         -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,  /* D0-DF */
343         -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,  /* E0-EF */
344         -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1   /* F0-FF */
345     };
346 
347     phase = 0;
348     dlast = 0;
349     for (cur = str; *cur != '\0'; ++cur )
350     {
351         d = table[(int)*cur];
352         if(d != -1)
353         {
354             switch(phase)
355             {
356             case 0:
357                 ++phase;
358                 break;
359             case 1:
360                 c = ((dlast << 2) | ((d & 0x30) >> 4));
361                 *str++ = c;
362                 ++phase;
363                 break;
364             case 2:
365                 c = (((dlast & 0xf) << 4) | ((d & 0x3c) >> 2));
366                 *str++ = c;
367                 ++phase;
368                 break;
369             case 3:
370                 c = (((dlast & 0x03 ) << 6) | d);
371                 *str++ = c;
372                 phase = 0;
373                 break;
374             }
375             dlast = d;
376         }
377     }
378     *str = '\0';
379 }
380