1 const char list_rcs[] = "$Id: list.c,v 1.3 2001/06/03 19:12:24 oes Exp $";
2 /*********************************************************************
4 * File : $Source: /cvsroot/ijbswa/current/list.c,v $
6 * Purpose : Declares functions to handle lists.
7 * Functions declared include:
8 * `destroy_list', `enlist' and `list_to_text'
10 * Copyright : Written by and Copyright (C) 2001 the SourceForge
11 * IJBSWA team. http://ijbswa.sourceforge.net
13 * Based on the Internet Junkbuster originally written
14 * by and Copyright (C) 1997 Anonymous Coders and
15 * Junkbusters Corporation. http://www.junkbusters.com
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.
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.
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.
37 * Revision 1.3 2001/06/03 19:12:24 oes
38 * functions for new struct map, extended enlist_unique
40 * Revision 1.2 2001/06/01 18:49:17 jongfoster
41 * Replaced "list_share" with "list" - the tiny memory gain was not
42 * worth the extra complexity.
44 * Revision 1.1 2001/05/31 21:11:53 jongfoster
45 * - Moved linked list support to new "list.c" file.
46 * Structure definitions are still in project.h,
47 * function prototypes are now in "list.h".
48 * - Added support for "struct list_share", which is identical
49 * to "struct list" except it saves memory by not duplicating
50 * the strings. Obviously, this only works if there is some
51 * other way of managing the memory used by the strings.
52 * (These list_share lists are used for lists which last
53 * for only 1 request, and where all the list entries are
54 * just coming directly from entries in the actionsfile.)
55 * Note that you still need to destroy list_share lists
56 * properly to free the nodes - it's only the strings
60 *********************************************************************/
66 #include <sys/types.h>
80 const char list_h_rcs[] = LIST_H_VERSION;
82 /*********************************************************************
86 * Description : Append a string into a specified string list.
89 * 1 : header = pointer to list 'dummy' header
90 * 2 : str = string to add to the list (maybe NULL)
94 *********************************************************************/
95 void enlist(struct list *header, const char *str)
97 struct list *cur = (struct list *)malloc(sizeof(*cur));
102 cur->str = (str ? strdup(str) : NULL);
118 /*********************************************************************
120 * Function : enlist_first
122 * Description : Append a string as first element into a specified
126 * 1 : header = pointer to list 'dummy' header
127 * 2 : str = string to add to the list (maybe NULL)
131 *********************************************************************/
132 void enlist_first(struct list *header, const char *str)
134 struct list *cur = (struct list *)malloc(sizeof(*cur));
138 cur->str = (str ? strdup(str) : NULL);
139 cur->next = header->next;
142 if (header->last == NULL)
151 /*********************************************************************
153 * Function : enlist_unique
155 * Description : Append a string into a specified string list,
156 * if & only if it's not there already.
157 * If the n argument is nonzero, only compare up to
161 * 1 : header = pointer to list 'dummy' header
162 * 2 : str = string to add to the list (maybe NULL)
163 * 3 : n = number of chars to use for uniqueness test
167 *********************************************************************/
168 void enlist_unique(struct list *header, const char *str, int n)
171 struct list *cur = header->next;
175 if ((cur->str != NULL) && (
176 (n && (0 == strncmp(str, cur->str, n))) ||
177 (!n && (0 == strcmp(str, cur->str)))))
185 cur = (struct list *)malloc(sizeof(*cur));
189 cur->str = (str ? strdup(str) : NULL); /* FIXME check retval */
203 /*********************************************************************
205 * Function : enlist_unique_header
207 * Description : Make a HTTP header from the two strings name and value,
208 * and append the result into a specified string list,
209 * if & only if there isn't already a header with that name.
212 * 1 : header = pointer to list 'dummy' header
213 * 2 : first = first string to add to the list (maybe NULL)
214 * 3 : second = number of chars to use for uniqueness test
218 *********************************************************************/
219 void enlist_unique_header(struct list *header, const char *name, const char *value)
222 struct list *cur = header->next;
226 if (name == NULL || value == NULL) return;
228 dummy = strdup(name);
229 dummy = strsav(dummy, ": ");
230 length = strlen(dummy);
234 if ((cur->str != NULL) &&
235 (0 == strncmp(dummy, cur->str, length)))
243 cur = (struct list *)malloc(sizeof(*cur));
247 cur->str = strsav(dummy, value);
261 /*********************************************************************
263 * Function : destroy_list
265 * Description : Destroy a string list (opposite of enlist)
268 * 1 : header = pointer to list 'dummy' header
272 *********************************************************************/
273 void destroy_list(struct list *header)
277 for (p = header->next; p ; p = n)
284 memset(header, '\0', sizeof(*header));
289 /*********************************************************************
291 * Function : list_to_text
293 * Description : "Flaten" a string list into 1 long \r\n delimited string.
296 * 1 : h = pointer to list 'dummy' header
298 * Returns : NULL on malloc error, else new long string.
300 *********************************************************************/
301 char *list_to_text(struct list *h)
310 for (p = h->next; p ; p = p->next)
314 size += strlen(p->str) + 2;
318 if ((ret = (char *)malloc(size + 1)) == NULL)
327 for (p = h->next; p ; p = p->next)
333 *s++ = '\r'; *s++ = '\n';
342 /*********************************************************************
344 * Function : list_remove_item
346 * Description : Remove a string from a specified string list.
349 * 1 : header = pointer to list 'dummy' header
350 * 2 : str = string to remove from the list
352 * Returns : Number of times it was removed.
354 *********************************************************************/
355 int list_remove_item(struct list *header, const char *str)
357 struct list *prev = header;
358 struct list *cur = prev->next;
363 if ((cur->str != NULL) && (0 == strcmp(str, cur->str)))
367 prev->next = cur->next;
384 /*********************************************************************
386 * Function : list_remove_list
388 * Description : Remove all strings in one list from another list.
389 * This is currently a brute-force algorithm
390 * (it compares every pair of strings).
393 * 1 : dest = list to change
394 * 2 : src = list of strings to remove
396 * Returns : Total number of strings removed.
398 *********************************************************************/
399 int list_remove_list(struct list *dest, const struct list *src)
401 struct list *cur = src->next;
406 if (cur->str != NULL)
408 count += list_remove_item(dest, cur->str);
417 /*********************************************************************
419 * Function : list_duplicate
421 * Description : Duplicate a string list
424 * 1 : dest = pointer to destination for copy. Caller allocs.
425 * 2 : src = pointer to source for copy.
429 *********************************************************************/
430 void list_duplicate(struct list *dest, const struct list *src)
432 struct list * cur_src = src->next;
433 struct list * cur_dest = dest;
435 memset(dest, '\0', sizeof(*dest));
439 cur_dest = cur_dest->next = (struct list *)zalloc(sizeof(*cur_dest));
440 if (cur_dest == NULL)
444 cur_dest->str = strdup(cur_src->str);
445 cur_src = cur_src->next;
448 dest->last = cur_dest;
453 /*********************************************************************
455 * Function : list_append_list_unique
457 * Description : Append a string list to another list.
458 * Duplicate items are not added.
461 * 1 : dest = pointer to destination for merge. Caller allocs.
462 * 2 : src = pointer to source for merge.
466 *********************************************************************/
467 void list_append_list_unique(struct list *dest, const struct list *src)
469 struct list * cur = src->next;
473 enlist_unique(dest, cur->str, 0);
479 /*********************************************************************
483 * Description : Add a mapping from given name to given value to a
486 * Note: Since all strings will be free()d in free_map()
487 * later, use the copy flags for constants or
488 * strings that will be independantly free()d.
491 * 1 : map = map to add to
492 * 2 : name = name to add
493 * 3 : nc = flag set if a copy of name should be used
494 * 4 : value = value to add
495 * 5 : vc = flag set if a copy of value should be used
497 * Returns : pointer to extended map, or NULL if failiure
499 *********************************************************************/
500 struct map *map(struct map *map, char *name, int nc, char *value, int vc)
504 if (NULL == (cur = zalloc(sizeof(*cur))))
509 cur->name = nc ? strdup(name) : name;
510 cur->value = vc ? strdup(value) : value;
518 /*********************************************************************
522 * Description : Look up an item with a given name in a map, and
526 * 1 : name = name parameter to look for
528 * Returns : the value if found, else the empty string
530 *********************************************************************/
531 char *lookup(struct map *map, char *name)
537 if (!strcmp(name, p->name))
547 /*********************************************************************
549 * Function : free_map
551 * Description : Free the memory occupied by a map and its
555 * 1 : list = list to bee freed
559 *********************************************************************/
560 void free_map(struct map *map)