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 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 "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