Adding definition of BUFFER_SIZE.
[privoxy.git] / list.c
1 const char list_rcs[] = "$Id: list.c,v 1.3 2001/06/03 11:03:48 oes Exp $";
2 /*********************************************************************
3  *
4  * File        :  $Source: /cvsroot/ijbswa/current/list.c,v $
5  *
6  * Purpose     :  Declares functions to handle lists.
7  *                Functions declared include:
8  *                   `destroy_list', `enlist' and `list_to_text'
9  *
10  * Copyright   :  Written by and Copyright (C) 2001 the SourceForge
11  *                IJBSWA team.  http://ijbswa.sourceforge.net
12  *
13  *                Based on the Internet Junkbuster originally written
14  *                by and Copyright (C) 1997 Anonymous Coders and 
15  *                Junkbusters Corporation.  http://www.junkbusters.com
16  *
17  *                This program is free software; you can redistribute it 
18  *                and/or modify it under the terms of the GNU General
19  *                Public License as published by the Free Software
20  *                Foundation; either version 2 of the License, or (at
21  *                your option) any later version.
22  *
23  *                This program is distributed in the hope that it will
24  *                be useful, but WITHOUT ANY WARRANTY; without even the
25  *                implied warranty of MERCHANTABILITY or FITNESS FOR A
26  *                PARTICULAR PURPOSE.  See the GNU General Public
27  *                License for more details.
28  *
29  *                The GNU General Public License should be included with
30  *                this file.  If not, you can view it at
31  *                http://www.gnu.org/copyleft/gpl.html
32  *                or write to the Free Software Foundation, Inc., 59
33  *                Temple Place - Suite 330, Boston, MA  02111-1307, USA.
34  *
35  * Revisions   :
36  *    $Log: list.c,v $
37  *    Revision 1.3  2001/06/03 11:03:48  oes
38  *    Makefile/in
39  *
40  *    introduced cgi.c
41  *
42  *    actions.c:
43  *
44  *    adapted to new enlist_unique arg format
45  *
46  *    conf loadcfg.c
47  *
48  *    introduced confdir option
49  *
50  *    filters.c filtrers.h
51  *
52  *     extracted-CGI relevant stuff
53  *
54  *    jbsockets.c
55  *
56  *     filled comment
57  *
58  *    jcc.c
59  *
60  *     support for new cgi mechansim
61  *
62  *    list.c list.h
63  *
64  *    functions for new list type: "map"
65  *    extended enlist_unique
66  *
67  *    miscutil.c .h
68  *    introduced bindup()
69  *
70  *    parsers.c parsers.h
71  *
72  *    deleted const struct interceptors
73  *
74  *    pcrs.c
75  *    added FIXME
76  *
77  *    project.h
78  *
79  *    added struct map
80  *    added struct http_response
81  *    changes struct interceptors to struct cgi_dispatcher
82  *    moved HTML stuff to cgi.h
83  *
84  *    re_filterfile:
85  *
86  *    changed
87  *
88  *    showargs.c
89  *    NO TIME LEFT
90  *
91  *    Revision 1.2  2001/06/01 18:49:17  jongfoster
92  *    Replaced "list_share" with "list" - the tiny memory gain was not
93  *    worth the extra complexity.
94  *
95  *    Revision 1.1  2001/05/31 21:11:53  jongfoster
96  *    - Moved linked list support to new "list.c" file.
97  *      Structure definitions are still in project.h,
98  *      function prototypes are now in "list.h".
99  *    - Added support for "struct list_share", which is identical
100  *      to "struct list" except it saves memory by not duplicating
101  *      the strings.  Obviously, this only works if there is some
102  *      other way of managing the memory used by the strings.
103  *      (These list_share lists are used for lists which last
104  *      for only 1 request, and where all the list entries are
105  *      just coming directly from entries in the actionsfile.)
106  *      Note that you still need to destroy list_share lists
107  *      properly to free the nodes - it's only the strings
108  *      which are shared.
109  *
110  *
111  *********************************************************************/
112 \f
113
114 #include "config.h"
115
116 #include <stdio.h>
117 #include <sys/types.h>
118 #include <stdlib.h>
119 #include <ctype.h>
120 #include <string.h>
121
122 #ifndef _WIN32
123 #include <unistd.h>
124 #endif
125
126 #include "project.h"
127 #include "jcc.h"
128 #include "list.h"
129 #include "miscutil.h"
130
131 const char list_h_rcs[] = LIST_H_VERSION;
132
133 /*********************************************************************
134  *
135  * Function    :  enlist
136  *
137  * Description :  Append a string into a specified string list.
138  *
139  * Parameters  :
140  *          1  :  header = pointer to list 'dummy' header
141  *          2  :  str = string to add to the list (maybe NULL)
142  *
143  * Returns     :  N/A
144  *
145  *********************************************************************/
146 void enlist(struct list *header, const char *str)
147 {
148    struct list *cur = (struct list *)malloc(sizeof(*cur));
149    struct list *last;
150
151    if (cur)
152    {
153       cur->str  = (str ? strdup(str) : NULL);
154       cur->next = NULL;
155
156       last = header->last;
157       if (last == NULL)
158       {
159          last = header;
160       }
161
162       last->next   = cur;
163       header->last = cur;
164    }
165
166 }
167
168
169 /*********************************************************************
170  *
171  * Function    :  enlist_first
172  *
173  * Description :  Append a string as first element into a specified
174  *                string list.
175  *
176  * Parameters  :
177  *          1  :  header = pointer to list 'dummy' header
178  *          2  :  str = string to add to the list (maybe NULL)
179  *
180  * Returns     :  N/A
181  *
182  *********************************************************************/
183 void enlist_first(struct list *header, const char *str)
184 {
185    struct list *cur = (struct list *)malloc(sizeof(*cur));
186
187    if (cur)
188    {
189       cur->str  = (str ? strdup(str) : NULL);
190       cur->next = header->next;
191
192       header->next = cur;
193       if (header->last == NULL)
194       {
195          header->last = cur;
196       }
197    }
198
199 }
200
201
202 /*********************************************************************
203  *
204  * Function    :  enlist_unique
205  *
206  * Description :  Append a string into a specified string list,
207  *                if & only if it's not there already.
208  *                If the n argument is nonzero, only compare up to
209  *                the nth character. 
210  *
211  * Parameters  :
212  *          1  :  header = pointer to list 'dummy' header
213  *          2  :  str = string to add to the list (maybe NULL)
214  *          3  :  n = number of chars to use for uniqueness test
215  *
216  * Returns     :  N/A
217  *
218  *********************************************************************/
219 void enlist_unique(struct list *header, const char *str, int n)
220 {
221    struct list *last;
222    struct list *cur = header->next;
223
224    while (cur != NULL)
225    {
226       if ((cur->str != NULL) && (
227          (n && (0 == strncmp(str, cur->str, n))) || 
228          (!n && (0 == strcmp(str, cur->str)))))
229       {
230          /* Already there */
231          return;
232       }
233       cur = cur->next;
234    }
235
236    cur = (struct list *)malloc(sizeof(*cur));
237
238    if (cur != NULL)
239    {
240       cur->str  = (str ? strdup(str) : NULL); /* FIXME check retval */
241       cur->next = NULL;
242
243       last = header->last;
244       if (last == NULL)
245       {
246          last = header;
247       }
248       last->next   = cur;
249       header->last = cur;
250    }
251 }
252
253
254 /*********************************************************************
255  *
256  * Function    :  destroy_list
257  *
258  * Description :  Destroy a string list (opposite of enlist)
259  *
260  * Parameters  :
261  *          1  :  header = pointer to list 'dummy' header
262  *
263  * Returns     :  N/A
264  *
265  *********************************************************************/
266 void destroy_list(struct list *header)
267 {
268    struct list *p, *n;
269
270    for (p = header->next; p ; p = n)
271    {
272       n = p->next;
273       freez(p->str);
274       free(p);
275    }
276
277    memset(header, '\0', sizeof(*header));
278
279 }
280
281
282 /*********************************************************************
283  *
284  * Function    :  list_to_text
285  *
286  * Description :  "Flaten" a string list into 1 long \r\n delimited string.
287  *
288  * Parameters  :
289  *          1  :  h = pointer to list 'dummy' header
290  *
291  * Returns     :  NULL on malloc error, else new long string.
292  *
293  *********************************************************************/
294 char *list_to_text(struct list *h)
295 {
296    struct list *p;
297    char *ret = NULL;
298    char *s;
299    int size;
300
301    size = 0;
302
303    for (p = h->next; p ; p = p->next)
304    {
305       if (p->str)
306       {
307          size += strlen(p->str) + 2;
308       }
309    }
310
311    if ((ret = (char *)malloc(size + 1)) == NULL)
312    {
313       return(NULL);
314    }
315
316    ret[size] = '\0';
317
318    s = ret;
319
320    for (p = h->next; p ; p = p->next)
321    {
322       if (p->str)
323       {
324          strcpy(s, p->str);
325          s += strlen(s);
326          *s++ = '\r'; *s++ = '\n';
327       }
328    }
329
330    return(ret);
331
332 }
333
334
335 /*********************************************************************
336  *
337  * Function    :  list_remove_item
338  *
339  * Description :  Remove a string from a specified string list.
340  *
341  * Parameters  :
342  *          1  :  header = pointer to list 'dummy' header
343  *          2  :  str = string to remove from the list
344  *
345  * Returns     :  Number of times it was removed.
346  *
347  *********************************************************************/
348 int list_remove_item(struct list *header, const char *str)
349 {
350    struct list *prev = header;
351    struct list *cur = prev->next;
352    int count = 0;
353
354    while (cur != NULL)
355    {
356       if ((cur->str != NULL) && (0 == strcmp(str, cur->str)))
357       {
358          count++;
359
360          prev->next = cur->next;
361          free(cur->str);
362          free(cur);
363       }
364       else
365       {
366          prev = cur;
367       }
368       cur = prev->next;
369    }
370
371    header->last = prev;
372
373    return count;
374 }
375
376
377 /*********************************************************************
378  *
379  * Function    :  list_remove_list
380  *
381  * Description :  Remove all strings in one list from another list.
382  *                This is currently a brute-force algorithm
383  *                (it compares every pair of strings).
384  *
385  * Parameters  :
386  *          1  :  dest = list to change
387  *          2  :  src = list of strings to remove
388  *
389  * Returns     :  Total number of strings removed.
390  *
391  *********************************************************************/
392 int list_remove_list(struct list *dest, const struct list *src)
393 {
394    struct list *cur = src->next;
395    int count = 0;
396
397    while (cur != NULL)
398    {
399       if (cur->str != NULL)
400       {
401          count += list_remove_item(dest, cur->str);
402       }
403       cur = cur->next;
404    }
405
406    return count;
407 }
408
409
410 /*********************************************************************
411  *
412  * Function    :  list_duplicate
413  *
414  * Description :  Duplicate a string list
415  *
416  * Parameters  :
417  *          1  :  dest = pointer to destination for copy.  Caller allocs.
418  *          2  :  src = pointer to source for copy.
419  *
420  * Returns     :  N/A
421  *
422  *********************************************************************/
423 void list_duplicate(struct list *dest, const struct list *src)
424 {
425    struct list * cur_src = src->next;
426    struct list * cur_dest = dest;
427
428    memset(dest, '\0', sizeof(*dest));
429
430    while (cur_src)
431    {
432       cur_dest = cur_dest->next = (struct list *)zalloc(sizeof(*cur_dest));
433       if (cur_dest == NULL)
434       {
435          return;
436       }
437       cur_dest->str = strdup(cur_src->str);
438       cur_src = cur_src->next;
439    }
440
441    dest->last = cur_dest;
442
443 }
444
445
446 /*********************************************************************
447  *
448  * Function    :  list_append_list_unique
449  *
450  * Description :  Append a string list to another list.
451  *                Duplicate items are not added.
452  *
453  * Parameters  :
454  *          1  :  dest = pointer to destination for merge.  Caller allocs.
455  *          2  :  src = pointer to source for merge.
456  *
457  * Returns     :  N/A
458  *
459  *********************************************************************/
460 void list_append_list_unique(struct list *dest, const struct list *src)
461 {
462    struct list * cur = src->next;
463
464    while (cur)
465    {
466       enlist_unique(dest, cur->str, 0);
467       cur = cur->next;
468    }
469 }
470
471
472 /*********************************************************************
473  *
474  * Function    :  map
475  *
476  * Description :  Add a mapping from given name to given value to a
477  *                given map.
478  *
479  * Parameters  :
480  *          1  :  map = map to add to
481  *          2  :  name = name to add
482  *          3  :  nc = flag set if name is string constant, and
483  *                must be strdup()d, so it can later be free()d (FIXME!)
484  *          4  :  value = value to add
485  *          5  :  vc = flag set if value is string constant
486  *
487  * Returns     :  pointer to extended map, or NULL if failiure
488  *
489  *********************************************************************/
490 struct map *map(struct map *map, char *name, int nc, char *value, int vc)
491 {
492    struct map *cur;
493
494    if (NULL == (cur = zalloc(sizeof(*cur))))
495    {
496       return(NULL);
497    }
498
499    cur->name  = nc ? strdup(name) : name;
500    cur->value = vc ? strdup(value) : value;
501    cur->next = map;
502
503    return(cur);
504
505 }
506
507
508 /*********************************************************************
509  *
510  * Function    :  lookup
511  *
512  * Description :  Look up an item with a given name in a map, and
513  *                return its value
514  *
515  * Parameters  :
516  *          1  :  name = name parameter to look for
517  *
518  * Returns     :  the value if found, else the empty string
519  *
520  *********************************************************************/
521 char *lookup(struct map *map, char *name)
522 {
523    struct map *p = map;
524
525    while (p)
526    {
527       if (!strcmp(name, p->name))
528       {
529          return p->value;
530       }
531       p = p->next;
532    }
533    return "";
534 }
535
536
537 /*********************************************************************
538  *
539  * Function    :  free_map
540  *
541  * Description :  Free the memory occupied by a map and its
542  *                depandant strings
543  *
544  * Parameters  :
545  *          1  :  list = list to bee freed
546  *
547  * Returns     :  N/A
548  *
549  *********************************************************************/
550 void free_map(struct map *map)
551 {
552    struct map *p = map;
553
554    while (p)
555    {
556       free(p->name);
557       free(p->value);
558
559       map = p->next;
560       free(p);
561       p = map;
562    }
563
564 }
565
566
567 /*
568   Local Variables:
569   tab-width: 3
570   end:
571 */