17edbfaabe51c963b5a0e0813d44566bf0d441ea
[platform/upstream/curl.git] / src / tool_mfiles.c
1 /***************************************************************************
2  *                                  _   _ ____  _
3  *  Project                     ___| | | |  _ \| |
4  *                             / __| | | | |_) | |
5  *                            | (__| |_| |  _ <| |___
6  *                             \___|\___/|_| \_\_____|
7  *
8  * Copyright (C) 1998 - 2011, 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 http://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 "setup.h"
23
24 #include <curl/curl.h>
25
26 #include "tool_mfiles.h"
27
28 #include "memdebug.h" /* keep this as LAST include */
29
30 static void AppendNode(struct multi_files **first,
31                        struct multi_files **last,
32                        struct multi_files  *new)
33 {
34   DEBUGASSERT(((*first) && (*last)) || ((!*first) && (!*last)));
35
36   if(*last)
37     (*last)->next = new;
38   else
39     *first = new;
40   *last = new;
41 }
42
43 /*
44  * AddMultiFiles: Add a new list node possibly followed with a type_name.
45  *
46  * multi_first argument is the address of a pointer to the first element
47  * of the multi_files linked list. A NULL pointer indicates empty list.
48  *
49  * multi_last argument is the address of a pointer to the last element
50  * of the multi_files linked list. A NULL pointer indicates empty list.
51  *
52  * Pointers stored in multi_first and multi_last are modified while
53  * function is executed. An out of memory condition free's the whole
54  * list and returns with pointers stored in multi_first and multi_last
55  * set to NULL and a NULL function result.
56  *
57  * Function returns same pointer as stored at multi_last.
58  */
59
60 struct multi_files *AddMultiFiles(const char *file_name,
61                                   const char *type_name,
62                                   const char *show_filename,
63                                   struct multi_files **multi_first,
64                                   struct multi_files **multi_last)
65 {
66   struct multi_files *multi;
67   struct multi_files *multi_type;
68   struct multi_files *multi_name;
69
70   multi = calloc(1, sizeof(struct multi_files));
71   if(multi) {
72     multi->form.option = CURLFORM_FILE;
73     multi->form.value = file_name;
74     AppendNode(multi_first, multi_last, multi);
75   }
76   else {
77     FreeMultiInfo(multi_first, multi_last);
78     return NULL;
79   }
80
81   if(type_name) {
82     multi_type = calloc(1, sizeof(struct multi_files));
83     if(multi_type) {
84       multi_type->form.option = CURLFORM_CONTENTTYPE;
85       multi_type->form.value = type_name;
86       AppendNode(multi_first, multi_last, multi_type);
87     }
88     else {
89       FreeMultiInfo(multi_first, multi_last);
90       return NULL;
91     }
92   }
93
94   if(show_filename) {
95     multi_name = calloc(1, sizeof(struct multi_files));
96     if(multi_name) {
97       multi_name->form.option = CURLFORM_FILENAME;
98       multi_name->form.value = show_filename;
99       AppendNode(multi_first, multi_last, multi_name);
100     }
101     else {
102       FreeMultiInfo(multi_first, multi_last);
103       return NULL;
104     }
105   }
106
107   return *multi_last;
108 }
109
110 /*
111  * FreeMultiInfo: Free the items of the list.
112  */
113
114 void FreeMultiInfo(struct multi_files **multi_first,
115                    struct multi_files **multi_last)
116 {
117   struct multi_files *next;
118   struct multi_files *item = *multi_first;
119
120   while(item) {
121     next = item->next;
122     Curl_safefree(item);
123     item = next;
124   }
125   *multi_first = NULL;
126   if(multi_last)
127     *multi_last = NULL;
128 }
129