00001 /*************************************************************************** 00002 * _ _ ____ _ 00003 * Project ___| | | | _ \| | 00004 * / __| | | | |_) | | 00005 * | (__| |_| | _ <| |___ 00006 * \___|\___/|_| \_\_____| 00007 * 00008 * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al. 00009 * 00010 * This software is licensed as described in the file COPYING, which 00011 * you should have received as part of this distribution. The terms 00012 * are also available at https://curl.haxx.se/docs/copyright.html. 00013 * 00014 * You may opt to use, copy, modify, merge, publish, distribute and/or sell 00015 * copies of the Software, and permit persons to whom the Software is 00016 * furnished to do so, under the terms of the COPYING file. 00017 * 00018 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 00019 * KIND, either express or implied. 00020 * 00021 ***************************************************************************/ 00022 00023 #include "curl_setup.h" 00024 00025 #include <curl/curl.h> 00026 00027 #include "slist.h" 00028 00029 /* The last #include files should be: */ 00030 #include "curl_memory.h" 00031 #include "memdebug.h" 00032 00033 /* returns last node in linked list */ 00034 static struct curl_slist *slist_get_last(struct curl_slist *list) 00035 { 00036 struct curl_slist *item; 00037 00038 /* if caller passed us a NULL, return now */ 00039 if(!list) 00040 return NULL; 00041 00042 /* loop through to find the last item */ 00043 item = list; 00044 while(item->next) { 00045 item = item->next; 00046 } 00047 return item; 00048 } 00049 00050 /* 00051 * Curl_slist_append_nodup() appends a string to the linked list. Rather than 00052 * copying the string in dynamic storage, it takes its ownership. The string 00053 * should have been malloc()ated. Curl_slist_append_nodup always returns 00054 * the address of the first record, so that you can use this function as an 00055 * initialization function as well as an append function. 00056 * If an error occurs, NULL is returned and the string argument is NOT 00057 * released. 00058 */ 00059 struct curl_slist *Curl_slist_append_nodup(struct curl_slist *list, char *data) 00060 { 00061 struct curl_slist *last; 00062 struct curl_slist *new_item; 00063 00064 DEBUGASSERT(data); 00065 00066 new_item = malloc(sizeof(struct curl_slist)); 00067 if(!new_item) 00068 return NULL; 00069 00070 new_item->next = NULL; 00071 new_item->data = data; 00072 00073 /* if this is the first item, then new_item *is* the list */ 00074 if(!list) 00075 return new_item; 00076 00077 last = slist_get_last(list); 00078 last->next = new_item; 00079 return list; 00080 } 00081 00082 /* 00083 * curl_slist_append() appends a string to the linked list. It always returns 00084 * the address of the first record, so that you can use this function as an 00085 * initialization function as well as an append function. If you find this 00086 * bothersome, then simply create a separate _init function and call it 00087 * appropriately from within the program. 00088 */ 00089 struct curl_slist *curl_slist_append(struct curl_slist *list, 00090 const char *data) 00091 { 00092 char *dupdata = strdup(data); 00093 00094 if(!dupdata) 00095 return NULL; 00096 00097 list = Curl_slist_append_nodup(list, dupdata); 00098 if(!list) 00099 free(dupdata); 00100 00101 return list; 00102 } 00103 00104 /* 00105 * Curl_slist_duplicate() duplicates a linked list. It always returns the 00106 * address of the first record of the cloned list or NULL in case of an 00107 * error (or if the input list was NULL). 00108 */ 00109 struct curl_slist *Curl_slist_duplicate(struct curl_slist *inlist) 00110 { 00111 struct curl_slist *outlist = NULL; 00112 struct curl_slist *tmp; 00113 00114 while(inlist) { 00115 tmp = curl_slist_append(outlist, inlist->data); 00116 00117 if(!tmp) { 00118 curl_slist_free_all(outlist); 00119 return NULL; 00120 } 00121 00122 outlist = tmp; 00123 inlist = inlist->next; 00124 } 00125 return outlist; 00126 } 00127 00128 /* be nice and clean up resources */ 00129 void curl_slist_free_all(struct curl_slist *list) 00130 { 00131 struct curl_slist *next; 00132 struct curl_slist *item; 00133 00134 if(!list) 00135 return; 00136 00137 item = list; 00138 do { 00139 next = item->next; 00140 Curl_safefree(item->data); 00141 free(item); 00142 item = next; 00143 } while(next); 00144 } 00145