1/*************************************************************************** 2 * _ _ ____ _ 3 * Project ___| | | | _ \| | 4 * / __| | | | |_) | | 5 * | (__| |_| | _ <| |___ 6 * \___|\___/|_| \_\_____| 7 * 8 * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al. 9 * 10 * This software is licensed as described in the file COPYING, which 11 * you should have received as part of this distribution. The terms 12 * are also available at https://curl.haxx.se/docs/copyright.html. 13 * 14 * You may opt to use, copy, modify, merge, publish, distribute and/or sell 15 * copies of the Software, and permit persons to whom the Software is 16 * furnished to do so, under the terms of the COPYING file. 17 * 18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 19 * KIND, either express or implied. 20 * 21 ***************************************************************************/ 22#include "tool_setup.h" 23 24#include "tool_mfiles.h" 25 26#include "memdebug.h" /* keep this as LAST include */ 27 28static void AppendNode(struct multi_files **first, 29 struct multi_files **last, 30 struct multi_files *new) 31{ 32 DEBUGASSERT(((*first) && (*last)) || ((!*first) && (!*last))); 33 34 if(*last) 35 (*last)->next = new; 36 else 37 *first = new; 38 *last = new; 39} 40 41/* 42 * AddMultiFiles: Add a new list node possibly followed with a type_name. 43 * 44 * multi_first argument is the address of a pointer to the first element 45 * of the multi_files linked list. A NULL pointer indicates empty list. 46 * 47 * multi_last argument is the address of a pointer to the last element 48 * of the multi_files linked list. A NULL pointer indicates empty list. 49 * 50 * Pointers stored in multi_first and multi_last are modified while 51 * function is executed. An out of memory condition free's the whole 52 * list and returns with pointers stored in multi_first and multi_last 53 * set to NULL and a NULL function result. 54 * 55 * Function returns same pointer as stored at multi_last. 56 */ 57 58struct multi_files *AddMultiFiles(const char *file_name, 59 const char *type_name, 60 const char *show_filename, 61 struct multi_files **multi_first, 62 struct multi_files **multi_last) 63{ 64 struct multi_files *multi; 65 struct multi_files *multi_type; 66 struct multi_files *multi_name; 67 68 multi = calloc(1, sizeof(struct multi_files)); 69 if(multi) { 70 multi->form.option = CURLFORM_FILE; 71 multi->form.value = file_name; 72 AppendNode(multi_first, multi_last, multi); 73 } 74 else { 75 FreeMultiInfo(multi_first, multi_last); 76 return NULL; 77 } 78 79 if(type_name) { 80 multi_type = calloc(1, sizeof(struct multi_files)); 81 if(multi_type) { 82 multi_type->form.option = CURLFORM_CONTENTTYPE; 83 multi_type->form.value = type_name; 84 AppendNode(multi_first, multi_last, multi_type); 85 } 86 else { 87 FreeMultiInfo(multi_first, multi_last); 88 return NULL; 89 } 90 } 91 92 if(show_filename) { 93 multi_name = calloc(1, sizeof(struct multi_files)); 94 if(multi_name) { 95 multi_name->form.option = CURLFORM_FILENAME; 96 multi_name->form.value = show_filename; 97 AppendNode(multi_first, multi_last, multi_name); 98 } 99 else { 100 FreeMultiInfo(multi_first, multi_last); 101 return NULL; 102 } 103 } 104 105 return *multi_last; 106} 107 108/* 109 * FreeMultiInfo: Free the items of the list. 110 */ 111 112void FreeMultiInfo(struct multi_files **multi_first, 113 struct multi_files **multi_last) 114{ 115 struct multi_files *next; 116 struct multi_files *item = *multi_first; 117 118 while(item) { 119 next = item->next; 120 Curl_safefree(item); 121 item = next; 122 } 123 *multi_first = NULL; 124 if(multi_last) 125 *multi_last = NULL; 126} 127 128