list.c 30 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150
  1. /*********************************************************************
  2. *
  3. * File : $Source: /cvsroot/ijbswa/current/list.c,v $
  4. *
  5. * Purpose : Declares functions to handle lists.
  6. *
  7. * Copyright : Written by and Copyright (C) 2001-2007 members of the
  8. * Privoxy team. https://www.privoxy.org/
  9. *
  10. * Based on the Internet Junkbuster originally written
  11. * by and Copyright (C) 1997 Anonymous Coders and
  12. * Junkbusters Corporation. http://www.junkbusters.com
  13. *
  14. * This program is free software; you can redistribute it
  15. * and/or modify it under the terms of the GNU General
  16. * Public License as published by the Free Software
  17. * Foundation; either version 2 of the License, or (at
  18. * your option) any later version.
  19. *
  20. * This program is distributed in the hope that it will
  21. * be useful, but WITHOUT ANY WARRANTY; without even the
  22. * implied warranty of MERCHANTABILITY or FITNESS FOR A
  23. * PARTICULAR PURPOSE. See the GNU General Public
  24. * License for more details.
  25. *
  26. * The GNU General Public License should be included with
  27. * this file. If not, you can view it at
  28. * http://www.gnu.org/copyleft/gpl.html
  29. * or write to the Free Software Foundation, Inc., 59
  30. * Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  31. *
  32. *********************************************************************/
  33. #include "config.h"
  34. #ifndef _WIN32
  35. /* FIXME: The following headers are not needed for Win32. Are they
  36. * needed on other platforms?
  37. */
  38. #include <stdio.h>
  39. #include <sys/types.h>
  40. #include <stdlib.h>
  41. #include <ctype.h>
  42. #endif
  43. #include <string.h>
  44. #if !defined(_WIN32)
  45. #include <unistd.h>
  46. #endif
  47. #include <assert.h>
  48. #include "project.h"
  49. #include "list.h"
  50. #include "miscutil.h"
  51. static int list_is_valid (const struct list *the_list);
  52. /*********************************************************************
  53. *
  54. * Function : init_list
  55. *
  56. * Description : Create a new, empty list in user-allocated memory.
  57. * Caller should allocate a "struct list" variable,
  58. * then pass it to this function.
  59. * (Implementation note: Rather than calling this
  60. * function, you can also just memset the memory to
  61. * zero, e.g. if you have a larger structure you
  62. * want to initialize quickly. However, that isn't
  63. * really good design.)
  64. *
  65. * Parameters :
  66. * 1 : the_list = pointer to list
  67. *
  68. * Returns : N/A
  69. *
  70. *********************************************************************/
  71. void init_list(struct list *the_list)
  72. {
  73. memset(the_list, '\0', sizeof(*the_list));
  74. }
  75. /*********************************************************************
  76. *
  77. * Function : destroy_list
  78. *
  79. * Description : Destroy a string list (opposite of list_init).
  80. * On return, the memory used by the list entries has
  81. * been freed, but not the memory used by the_list
  82. * itself. You should not re-use the_list without
  83. * calling list_init().
  84. *
  85. * (Implementation note: You *can* reuse the_list
  86. * without calling list_init(), but please don't.
  87. * If you want to remove all entries from a list
  88. * and still have a usable list, then use
  89. * list_remove_all().)
  90. *
  91. * Parameters :
  92. * 1 : the_list = pointer to list
  93. *
  94. * Returns : N/A
  95. *
  96. *********************************************************************/
  97. void destroy_list (struct list *the_list)
  98. {
  99. struct list_entry *cur_entry, *next_entry;
  100. assert(the_list);
  101. for (cur_entry = the_list->first; cur_entry ; cur_entry = next_entry)
  102. {
  103. next_entry = cur_entry->next;
  104. freez(cur_entry->str);
  105. free(cur_entry);
  106. }
  107. the_list->first = NULL;
  108. the_list->last = NULL;
  109. }
  110. /*********************************************************************
  111. *
  112. * Function : list_is_valid
  113. *
  114. * Description : Check that a string list is valid. The intended
  115. * usage is "assert(list_is_valid(the_list))".
  116. * Currently this checks that "the_list->last"
  117. * is correct, and that the list doesn't contain
  118. * circular references. It is likely to crash if
  119. * it's passed complete garbage.
  120. *
  121. * Parameters :
  122. * 1 : the_list = pointer to list. Must be non-null.
  123. *
  124. * Returns : 1 if list is valid, 0 otherwise.
  125. *
  126. *********************************************************************/
  127. static int list_is_valid (const struct list *the_list)
  128. {
  129. /*
  130. * If you don't want this check, just change the line below
  131. * from "#if 1" to "#if 0".
  132. */
  133. #if 1
  134. const struct list_entry *cur_entry;
  135. const struct list_entry *last_entry = NULL;
  136. int entry = 0;
  137. assert(the_list);
  138. for (cur_entry = the_list->first; cur_entry ; cur_entry = cur_entry->next)
  139. {
  140. last_entry = cur_entry;
  141. if (cur_entry->str)
  142. {
  143. /*
  144. * Just check that this string can be accessed - i.e. it's a valid
  145. * pointer.
  146. */
  147. (void)strlen(cur_entry->str);
  148. }
  149. /*
  150. * Check for looping back to first
  151. */
  152. if ((entry++ != 0) && (cur_entry == the_list->first))
  153. {
  154. return 0;
  155. }
  156. /*
  157. * Arbitrarily limit list length to prevent infinite loops.
  158. * Note that the 1000 limit was hit by a real user in tracker 911950;
  159. * removing it for now. Real circular references should eventually
  160. * be caught by the check above, anyway.
  161. */
  162. /*
  163. if (entry > 1000)
  164. {
  165. return 0;
  166. }
  167. */
  168. /*
  169. * Check this isn't marked as the last entry, unless of course it's
  170. * *really* the last entry.
  171. */
  172. if ((the_list->last == cur_entry) && (cur_entry->next != NULL))
  173. {
  174. /* This is the last entry, but there's data after it !!?? */
  175. return 0;
  176. }
  177. }
  178. return (the_list->last == last_entry);
  179. #else
  180. return 1;
  181. #endif
  182. }
  183. /*********************************************************************
  184. *
  185. * Function : enlist
  186. *
  187. * Description : Append a string into a specified string list.
  188. *
  189. * Parameters :
  190. * 1 : the_list = pointer to list
  191. * 2 : str = string to add to the list (maybe NULL)
  192. *
  193. * Returns : JB_ERR_OK on success
  194. * JB_ERR_MEMORY on out-of-memory error.
  195. * On error, the_list will be unchanged.
  196. *
  197. *********************************************************************/
  198. jb_err enlist(struct list *the_list, const char *str)
  199. {
  200. struct list_entry *cur;
  201. assert(the_list);
  202. assert(list_is_valid(the_list));
  203. if (NULL == (cur = (struct list_entry *)zalloc(sizeof(*cur))))
  204. {
  205. return JB_ERR_MEMORY;
  206. }
  207. if (str)
  208. {
  209. if (NULL == (cur->str = strdup(str)))
  210. {
  211. free(cur);
  212. return JB_ERR_MEMORY;
  213. }
  214. }
  215. /* else { cur->str = NULL; } - implied by zalloc */
  216. /* cur->next = NULL; - implied by zalloc */
  217. if (the_list->last)
  218. {
  219. the_list->last->next = cur;
  220. the_list->last = cur;
  221. }
  222. else
  223. {
  224. the_list->first = cur;
  225. the_list->last = cur;
  226. }
  227. assert(list_is_valid(the_list));
  228. return JB_ERR_OK;
  229. }
  230. /*********************************************************************
  231. *
  232. * Function : enlist_first
  233. *
  234. * Description : Append a string as first element into a specified
  235. * string list.
  236. *
  237. * Parameters :
  238. * 1 : the_list = pointer to list
  239. * 2 : str = string to add to the list (maybe NULL)
  240. *
  241. * Returns : JB_ERR_OK on success
  242. * JB_ERR_MEMORY on out-of-memory error.
  243. * On error, the_list will be unchanged.
  244. *
  245. *********************************************************************/
  246. jb_err enlist_first(struct list *the_list, const char *str)
  247. {
  248. struct list_entry *cur;
  249. assert(the_list);
  250. assert(list_is_valid(the_list));
  251. if (NULL == (cur = (struct list_entry *)zalloc(sizeof(*cur))))
  252. {
  253. return JB_ERR_MEMORY;
  254. }
  255. if (str)
  256. {
  257. if (NULL == (cur->str = strdup(str)))
  258. {
  259. free(cur);
  260. return JB_ERR_MEMORY;
  261. }
  262. }
  263. /* else { cur->str = NULL; } - implied by zalloc */
  264. cur->next = the_list->first;
  265. the_list->first = cur;
  266. if (the_list->last == NULL)
  267. {
  268. the_list->last = cur;
  269. }
  270. assert(list_is_valid(the_list));
  271. return JB_ERR_OK;
  272. }
  273. /*********************************************************************
  274. *
  275. * Function : enlist_unique
  276. *
  277. * Description : Append a string into a specified string list,
  278. * if & only if it's not there already.
  279. * If the num_significant_chars argument is nonzero,
  280. * only compare up to the nth character.
  281. *
  282. * Parameters :
  283. * 1 : the_list = pointer to list
  284. * 2 : str = string to add to the list
  285. * 3 : num_significant_chars = number of chars to use
  286. * for uniqueness test, or 0 to require an exact match.
  287. *
  288. * Returns : JB_ERR_OK on success
  289. * JB_ERR_MEMORY on out-of-memory error.
  290. * On error, the_list will be unchanged.
  291. * "Success" does not indicate whether or not the
  292. * item was already in the list.
  293. *
  294. *********************************************************************/
  295. jb_err enlist_unique(struct list *the_list, const char *str,
  296. size_t num_significant_chars)
  297. {
  298. struct list_entry *cur_entry;
  299. assert(the_list);
  300. assert(list_is_valid(the_list));
  301. assert(str);
  302. assert(num_significant_chars >= 0);
  303. assert(num_significant_chars <= strlen(str));
  304. if (num_significant_chars > 0)
  305. {
  306. for (cur_entry = the_list->first; cur_entry != NULL; cur_entry = cur_entry->next)
  307. {
  308. if ((cur_entry->str != NULL)
  309. && (0 == strncmp(str, cur_entry->str, num_significant_chars)))
  310. {
  311. /* Already there */
  312. return JB_ERR_OK;
  313. }
  314. }
  315. }
  316. else
  317. {
  318. /* Test whole string */
  319. for (cur_entry = the_list->first; cur_entry != NULL; cur_entry = cur_entry->next)
  320. {
  321. if ((cur_entry->str != NULL) && (0 == strcmp(str, cur_entry->str)))
  322. {
  323. /* Already there */
  324. return JB_ERR_OK;
  325. }
  326. }
  327. }
  328. return enlist(the_list, str);
  329. }
  330. /*********************************************************************
  331. *
  332. * Function : enlist_unique_header
  333. *
  334. * Description : Make a HTTP header from the two strings name and value,
  335. * and append the result into a specified string list,
  336. * if & only if there isn't already a header with that name.
  337. *
  338. * Parameters :
  339. * 1 : the_list = pointer to list
  340. * 2 : name = HTTP header name (e.g. "Content-type")
  341. * 3 : value = HTTP header value (e.g. "text/html")
  342. *
  343. * Returns : JB_ERR_OK on success
  344. * JB_ERR_MEMORY on out-of-memory error.
  345. * On error, the_list will be unchanged.
  346. * "Success" does not indicate whether or not the
  347. * header was already in the list.
  348. *
  349. *********************************************************************/
  350. jb_err enlist_unique_header(struct list *the_list, const char *name,
  351. const char *value)
  352. {
  353. jb_err result = JB_ERR_MEMORY;
  354. char *header;
  355. size_t header_size;
  356. assert(the_list);
  357. assert(list_is_valid(the_list));
  358. assert(name);
  359. assert(value);
  360. /* + 2 for the ': ', + 1 for the \0 */
  361. header_size = strlen(name) + 2 + strlen(value) + 1;
  362. header = (char *)malloc(header_size);
  363. if (NULL != header)
  364. {
  365. const size_t bytes_to_compare = strlen(name) + 2;
  366. char *p = header;
  367. snprintf(header, header_size, "%s: %s", name, value);
  368. /*
  369. * The trailing "\r\n" is added by list_to_text(),
  370. * if the caller passed them anyway, cut the header
  371. * at the first one or dump core if this is a debug
  372. * build.
  373. */
  374. do
  375. {
  376. if ((*p == '\r') || (*p == '\n'))
  377. {
  378. assert(*p != '\r');
  379. assert(*p != '\n');
  380. *p = '\0';
  381. }
  382. } while (*p++);
  383. result = enlist_unique(the_list, header, bytes_to_compare);
  384. free(header);
  385. assert(list_is_valid(the_list));
  386. }
  387. return result;
  388. }
  389. /*********************************************************************
  390. *
  391. * Function : list_remove_all
  392. *
  393. * Description : Remove all entries from a list. On return, the_list
  394. * is a valid, empty list. Note that this is similar
  395. * to destroy_list(), but the difference is that this
  396. * function guarantees that the list structure is still
  397. * valid after the call.
  398. *
  399. * Parameters :
  400. * 1 : the_list = pointer to list
  401. *
  402. * Returns : N/A
  403. *
  404. *********************************************************************/
  405. void list_remove_all(struct list *the_list)
  406. {
  407. struct list_entry *cur_entry;
  408. struct list_entry *next_entry;
  409. assert(the_list);
  410. assert(list_is_valid(the_list));
  411. for (cur_entry = the_list->first; cur_entry ; cur_entry = next_entry)
  412. {
  413. next_entry = cur_entry->next;
  414. freez(cur_entry->str);
  415. free(cur_entry);
  416. }
  417. the_list->first = the_list->last = NULL;
  418. assert(list_is_valid(the_list));
  419. }
  420. /*********************************************************************
  421. *
  422. * Function : list_to_text
  423. *
  424. * Description : "Flatten" a string list into 1 long \r\n delimited string,
  425. * adding an empty line at the end. NULL entries are ignored.
  426. * This function does not change the_list.
  427. *
  428. * XXX: Should probably be renamed as it's only
  429. * useful (and used) to flatten header lists.
  430. *
  431. * Parameters :
  432. * 1 : the_list = pointer to list
  433. *
  434. * Returns : NULL on malloc error, else new long string.
  435. * Caller must free() it.
  436. *
  437. *********************************************************************/
  438. char *list_to_text(const struct list *the_list)
  439. {
  440. struct list_entry *cur_entry;
  441. char *text;
  442. size_t text_length;
  443. char *cursor;
  444. size_t bytes_left;
  445. assert(the_list);
  446. assert(list_is_valid(the_list));
  447. /*
  448. * Calculate the length of the final text.
  449. * '2' because of the '\r\n' at the end of
  450. * each string and at the end of the text.
  451. */
  452. text_length = 2;
  453. for (cur_entry = the_list->first; cur_entry; cur_entry = cur_entry->next)
  454. {
  455. if (cur_entry->str)
  456. {
  457. text_length += strlen(cur_entry->str) + 2;
  458. }
  459. }
  460. bytes_left = text_length + 1;
  461. text = (char *)malloc(bytes_left);
  462. if (NULL == text)
  463. {
  464. return NULL;
  465. }
  466. cursor = text;
  467. for (cur_entry = the_list->first; cur_entry; cur_entry = cur_entry->next)
  468. {
  469. if (cur_entry->str)
  470. {
  471. const int written = snprintf(cursor, bytes_left, "%s\r\n", cur_entry->str);
  472. assert(written > 0);
  473. assert(written < bytes_left);
  474. bytes_left -= (size_t)written;
  475. cursor += (size_t)written;
  476. }
  477. }
  478. assert(bytes_left == 3);
  479. *cursor++ = '\r';
  480. *cursor++ = '\n';
  481. *cursor = '\0';
  482. assert(text_length == cursor - text);
  483. assert(text[text_length] == '\0');
  484. return text;
  485. }
  486. /*********************************************************************
  487. *
  488. * Function : list_remove_item
  489. *
  490. * Description : Remove a string from a specified string list.
  491. *
  492. * Parameters :
  493. * 1 : the_list = pointer to list
  494. * 2 : str = string to remove from the list - non-NULL
  495. *
  496. * Returns : Number of times it was removed.
  497. *
  498. *********************************************************************/
  499. int list_remove_item(struct list *the_list, const char *str)
  500. {
  501. struct list_entry *prev = NULL;
  502. struct list_entry *cur;
  503. struct list_entry *next;
  504. int count = 0;
  505. assert(the_list);
  506. assert(list_is_valid(the_list));
  507. assert(str);
  508. cur = the_list->first;
  509. while (cur != NULL)
  510. {
  511. next = cur->next;
  512. if ((cur->str != NULL) && (0 == strcmp(str, cur->str)))
  513. {
  514. count++;
  515. if (prev != NULL)
  516. {
  517. prev->next = next;
  518. }
  519. else
  520. {
  521. the_list->first = next;
  522. }
  523. free((char *)cur->str);
  524. free(cur);
  525. }
  526. else
  527. {
  528. prev = cur;
  529. }
  530. cur = next;
  531. }
  532. the_list->last = prev;
  533. assert(list_is_valid(the_list));
  534. return count;
  535. }
  536. /*********************************************************************
  537. *
  538. * Function : list_remove_list
  539. *
  540. * Description : Remove all strings in one list from another list.
  541. * This is currently a brute-force algorithm
  542. * (it compares every pair of strings).
  543. *
  544. * Parameters :
  545. * 1 : dest = list to change
  546. * 2 : src = list of strings to remove
  547. *
  548. * Returns : Total number of strings removed.
  549. *
  550. *********************************************************************/
  551. int list_remove_list(struct list *dest, const struct list *src)
  552. {
  553. struct list_entry *cur;
  554. int count = 0;
  555. assert(src);
  556. assert(dest);
  557. assert(list_is_valid(src));
  558. assert(list_is_valid(dest));
  559. for (cur = src->first; cur != NULL; cur = cur->next)
  560. {
  561. if (cur->str != NULL)
  562. {
  563. count += list_remove_item(dest, cur->str);
  564. }
  565. }
  566. assert(list_is_valid(src));
  567. assert(list_is_valid(dest));
  568. return count;
  569. }
  570. /*********************************************************************
  571. *
  572. * Function : list_duplicate
  573. *
  574. * Description : Copy a string list
  575. *
  576. * Parameters :
  577. * 1 : dest = Destination list. Must be a valid list.
  578. * All existing entries will be removed.
  579. * 1 : src = pointer to source list for copy.
  580. *
  581. * Returns : JB_ERR_OK on success
  582. * JB_ERR_MEMORY on out-of-memory error.
  583. * On error, dest will be empty.
  584. *
  585. *********************************************************************/
  586. jb_err list_duplicate(struct list *dest, const struct list *src)
  587. {
  588. struct list_entry * cur_src;
  589. struct list_entry * cur_dest;
  590. assert(src);
  591. assert(dest);
  592. assert(list_is_valid(src));
  593. assert(list_is_valid(dest));
  594. list_remove_all(dest);
  595. /* Need to process first entry specially so we can set dest->first */
  596. cur_src = src->first;
  597. if (cur_src)
  598. {
  599. cur_dest = dest->first = (struct list_entry *)zalloc(sizeof(*cur_dest));
  600. if (cur_dest == NULL)
  601. {
  602. destroy_list(dest);
  603. assert(list_is_valid(src));
  604. assert(list_is_valid(dest));
  605. return JB_ERR_MEMORY;
  606. }
  607. if (cur_src->str)
  608. {
  609. cur_dest->str = strdup(cur_src->str);
  610. if (cur_dest->str == NULL)
  611. {
  612. destroy_list(dest);
  613. assert(list_is_valid(src));
  614. assert(list_is_valid(dest));
  615. return JB_ERR_MEMORY;
  616. }
  617. }
  618. /* else { cur_dest->str = NULL; } - implied by zalloc */
  619. /* Now process the rest */
  620. for (cur_src = cur_src->next; cur_src; cur_src = cur_src->next)
  621. {
  622. cur_dest = cur_dest->next = (struct list_entry *)zalloc(sizeof(*cur_dest));
  623. if (cur_dest == NULL)
  624. {
  625. destroy_list(dest);
  626. assert(list_is_valid(src));
  627. assert(list_is_valid(dest));
  628. return JB_ERR_MEMORY;
  629. }
  630. if (cur_src->str)
  631. {
  632. cur_dest->str = strdup(cur_src->str);
  633. if (cur_dest->str == NULL)
  634. {
  635. destroy_list(dest);
  636. assert(list_is_valid(src));
  637. assert(list_is_valid(dest));
  638. return JB_ERR_MEMORY;
  639. }
  640. }
  641. /* else { cur_dest->str = NULL; } - implied by zalloc */
  642. }
  643. dest->last = cur_dest;
  644. }
  645. assert(list_is_valid(src));
  646. assert(list_is_valid(dest));
  647. return JB_ERR_OK;
  648. }
  649. /*********************************************************************
  650. *
  651. * Function : list_append_list_unique
  652. *
  653. * Description : Append a string list to another list.
  654. * Duplicate items are not added.
  655. *
  656. * Parameters :
  657. * 1 : dest = pointer to destination list for merge.
  658. * 2 : src = pointer to source for merge.
  659. *
  660. * Returns : JB_ERR_OK on success
  661. * JB_ERR_MEMORY on out-of-memory error.
  662. * On error, some (but not all) of src might have
  663. * been copied into dest.
  664. *
  665. *********************************************************************/
  666. jb_err list_append_list_unique(struct list *dest, const struct list *src)
  667. {
  668. struct list_entry * cur;
  669. assert(src);
  670. assert(dest);
  671. assert(list_is_valid(src));
  672. assert(list_is_valid(dest));
  673. for (cur = src->first; cur; cur = cur->next)
  674. {
  675. if (cur->str)
  676. {
  677. if (enlist_unique(dest, cur->str, 0))
  678. {
  679. assert(list_is_valid(src));
  680. assert(list_is_valid(dest));
  681. return JB_ERR_MEMORY;
  682. }
  683. }
  684. }
  685. assert(list_is_valid(src));
  686. assert(list_is_valid(dest));
  687. return JB_ERR_OK;
  688. }
  689. /*********************************************************************
  690. *
  691. * Function : list_is_empty
  692. *
  693. * Description : Test whether a list is empty. Does not change the list.
  694. *
  695. * Parameters :
  696. * 1 : the_list = pointer to list to test.
  697. *
  698. * Returns : Nonzero if the list contains no entries.
  699. *
  700. *********************************************************************/
  701. int list_is_empty(const struct list *the_list)
  702. {
  703. assert(the_list);
  704. assert(list_is_valid(the_list));
  705. return (the_list->first == NULL);
  706. }
  707. /*********************************************************************
  708. *
  709. * Function : list_contains_item
  710. *
  711. * Description : Tests whether a list item is already set.
  712. * Does not change the list.
  713. *
  714. * Parameters :
  715. * 1 : the_list = list to search in
  716. * 2 : str = string to search for
  717. *
  718. * Returns : TRUE if the item was found,
  719. * FALSE otherwise.
  720. *
  721. *********************************************************************/
  722. int list_contains_item(const struct list *the_list, const char *str)
  723. {
  724. struct list_entry *entry;
  725. assert(the_list);
  726. assert(list_is_valid(the_list));
  727. assert(str);
  728. for (entry = the_list->first; entry != NULL; entry = entry->next)
  729. {
  730. if (entry->str == NULL)
  731. {
  732. /*
  733. * NULL pointers are allowed in some lists.
  734. * For example for csp->headers in case a
  735. * header was removed.
  736. */
  737. continue;
  738. }
  739. if (0 == strcmp(str, entry->str))
  740. {
  741. /* Item found */
  742. return TRUE;
  743. }
  744. }
  745. return FALSE;
  746. }
  747. /*********************************************************************
  748. *
  749. * Function : new_map
  750. *
  751. * Description : Create a new, empty map.
  752. * Causes program exit if the memory allocation fails.
  753. *
  754. * Parameters : N/A
  755. *
  756. * Returns : A new, empty map
  757. *
  758. *********************************************************************/
  759. struct map *new_map(void)
  760. {
  761. struct map *empty_map = zalloc(sizeof(struct map));
  762. if (NULL == empty_map)
  763. {
  764. exit(1);
  765. }
  766. return empty_map;
  767. }
  768. /*********************************************************************
  769. *
  770. * Function : free_map
  771. *
  772. * Description : Free the memory occupied by a map and its
  773. * dependent strings
  774. *
  775. * Parameters :
  776. * 1 : the_map = map to be freed. May be NULL.
  777. *
  778. * Returns : N/A
  779. *
  780. *********************************************************************/
  781. void free_map(struct map *the_map)
  782. {
  783. struct map_entry *cur_entry;
  784. struct map_entry *next_entry;
  785. if (the_map == NULL)
  786. {
  787. return;
  788. }
  789. for (cur_entry = the_map->first; cur_entry != NULL; cur_entry = next_entry)
  790. {
  791. freez(cur_entry->name);
  792. freez(cur_entry->value);
  793. next_entry = cur_entry->next;
  794. free(cur_entry);
  795. }
  796. the_map->first = the_map->last = NULL;
  797. free(the_map);
  798. }
  799. /*********************************************************************
  800. *
  801. * Function : map
  802. *
  803. * Description : Add a mapping from given name to given value to a
  804. * given map.
  805. *
  806. * Note: Since all strings will be free()d in free_map()
  807. * later, set the copy flags for constants or
  808. * strings that will be independently free()d.
  809. *
  810. * Note2: This function allows NULL parameters - it
  811. * returns JB_ERR_MEMORY in that case.
  812. *
  813. * Note3: If this function returns JB_ERR_MEMORY,
  814. * it will free(name) unless you specify
  815. * name_needs_copying, and similarly it will
  816. * free(value) unless you specify
  817. * value_needs_copying.
  818. *
  819. * Due to Note2 and Note3 above, the following code
  820. * is legal, and will never crash or leak memory even
  821. * if the system runs out of memory:
  822. *
  823. * err = map(mymap, "xyz", 1, html_encode(somestring), 0);
  824. *
  825. * err will be set to JB_ERR_MEMORY if either call runs
  826. * out-of-memory. Without these features, you would
  827. * need to check the return value of html_encode in the
  828. * above example for NULL, which (at least) doubles the
  829. * amount of error-checking code needed.
  830. *
  831. * Parameters :
  832. * 1 : the_map = map to add to
  833. * 2 : name = name to add
  834. * 3 : name_needs_copying = flag set if a copy of name should be used
  835. * 4 : value = value to add
  836. * 5 : value_needs_copying = flag set if a copy of value should be used
  837. *
  838. * Returns : JB_ERR_OK on success
  839. * JB_ERR_MEMORY on out-of-memory error.
  840. *
  841. *********************************************************************/
  842. jb_err map(struct map *the_map,
  843. const char *name, int name_needs_copying,
  844. const char *value, int value_needs_copying)
  845. {
  846. struct map_entry *new_entry;
  847. assert(the_map);
  848. if ( (NULL == value)
  849. || (NULL == name)
  850. || (NULL == (new_entry = zalloc(sizeof(*new_entry)))))
  851. {
  852. if ((name != NULL) && (!name_needs_copying))
  853. {
  854. free((char *)name);
  855. }
  856. if ((value != NULL) && (!value_needs_copying))
  857. {
  858. free((char *)value);
  859. }
  860. return JB_ERR_MEMORY;
  861. }
  862. if (name_needs_copying)
  863. {
  864. if (NULL == (name = strdup(name)))
  865. {
  866. free(new_entry);
  867. if (!value_needs_copying)
  868. {
  869. free((char *)value);
  870. }
  871. return JB_ERR_MEMORY;
  872. }
  873. }
  874. if (value_needs_copying)
  875. {
  876. if (NULL == (value = strdup(value)))
  877. {
  878. free((char *)name);
  879. free(new_entry);
  880. return JB_ERR_MEMORY;
  881. }
  882. }
  883. new_entry->name = name;
  884. new_entry->value = value;
  885. /* new_entry->next = NULL; - implied by zalloc */
  886. if (the_map->last)
  887. {
  888. the_map->last->next = new_entry;
  889. the_map->last = new_entry;
  890. }
  891. else
  892. {
  893. the_map->first = new_entry;
  894. the_map->last = new_entry;
  895. }
  896. return JB_ERR_OK;
  897. }
  898. /*********************************************************************
  899. *
  900. * Function : unmap
  901. *
  902. * Description : Remove all map_entry structs with a given name from
  903. * a given map.
  904. *
  905. * Parameters :
  906. * 1 : the_map = map to look in
  907. * 2 : name = name to unmap
  908. *
  909. * Returns : JB_ERR_OK
  910. *
  911. *********************************************************************/
  912. jb_err unmap(struct map *the_map, const char *name)
  913. {
  914. struct map_entry *cur_entry, *last_entry;
  915. assert(the_map);
  916. assert(name);
  917. last_entry = NULL;
  918. for (cur_entry = the_map->first; cur_entry != NULL; cur_entry = cur_entry->next)
  919. {
  920. if (!strcmp(name, cur_entry->name))
  921. {
  922. /*
  923. * Update the incoming pointer
  924. */
  925. if (cur_entry == the_map->first)
  926. {
  927. the_map->first = cur_entry->next;
  928. }
  929. else
  930. {
  931. last_entry->next = cur_entry->next;
  932. }
  933. /*
  934. * Update the map's last pointer
  935. */
  936. if (cur_entry == the_map->last)
  937. {
  938. the_map->last = last_entry;
  939. }
  940. /*
  941. * Free the map_entry
  942. */
  943. freez(cur_entry->name);
  944. freez(cur_entry->value);
  945. freez(cur_entry);
  946. if (last_entry == NULL)
  947. {
  948. /* The map only had a single entry which has just been removed. */
  949. break;
  950. }
  951. cur_entry = last_entry;
  952. }
  953. else
  954. {
  955. last_entry = cur_entry;
  956. }
  957. }
  958. return JB_ERR_OK;
  959. }
  960. /*********************************************************************
  961. *
  962. * Function : lookup
  963. *
  964. * Description : Look up an item with a given name in a map, and
  965. * return its value
  966. *
  967. * Parameters :
  968. * 1 : the_map = map to look in
  969. * 2 : name = name parameter to look for
  970. *
  971. * Returns : the value if found, else the empty string.
  972. * Return value is allocated as part of the map, so
  973. * it is freed when the map is destroyed. Caller
  974. * must not free or modify it.
  975. *
  976. *********************************************************************/
  977. const char *lookup(const struct map *the_map, const char *name)
  978. {
  979. const struct map_entry *cur_entry;
  980. assert(the_map);
  981. assert(name);
  982. for (cur_entry = the_map->first; cur_entry != NULL; cur_entry = cur_entry->next)
  983. {
  984. if (!strcmp(name, cur_entry->name))
  985. {
  986. return cur_entry->value;
  987. }
  988. }
  989. return "";
  990. }
  991. /*
  992. Local Variables:
  993. tab-width: 3
  994. end:
  995. */