1e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET/***************************************************************************
2e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET *                                  _   _ ____  _
3e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET *  Project                     ___| | | |  _ \| |
4e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET *                             / __| | | | |_) | |
5e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET *                            | (__| |_| |  _ <| |___
6e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET *                             \___|\___/|_| \_\_____|
7e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET *
8486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
9e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET *
10e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * This software is licensed as described in the file COPYING, which
11e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * you should have received as part of this distribution. The terms
128f1a214b8a21b66f33454790dfba97ae2f818289Alex Deymo * are also available at https://curl.haxx.se/docs/copyright.html.
13e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET *
14e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * You may opt to use, copy, modify, merge, publish, distribute and/or sell
15e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * copies of the Software, and permit persons to whom the Software is
16e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * furnished to do so, under the terms of the COPYING file.
17e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET *
18e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * KIND, either express or implied.
20e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET *
21e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET ***************************************************************************/
22e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#include "tool_setup.h"
23e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
24486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo#include "mime.h"
25cee0338be80bb81b15101686d6f60864455f1e6eElliott Hughes#include "strcase.h"
26e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
27e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#define ENABLE_CURLX_PRINTF
28e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET/* use our own printf() functions */
29e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#include "curlx.h"
30e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
31e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#include "tool_cfgable.h"
3282be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughes#include "tool_convert.h"
33e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#include "tool_msgs.h"
34486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo#include "tool_binmode.h"
35486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo#include "tool_getparam.h"
36486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo#include "tool_paramhlp.h"
37e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#include "tool_formparse.h"
38e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
39e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#include "memdebug.h" /* keep this as LAST include */
40e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
41486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo/* Stdin parameters. */
42486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymotypedef struct {
43486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo  char *data;  /* Memory data. */
44486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo  curl_off_t origin;  /* File read origin offset. */
45486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo  curl_off_t size; /* Data size. */
46486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo  curl_off_t curpos; /* Current read position. */
47486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo}  standard_input;
48486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo
49e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
50e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET/*
51e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * helper function to get a word from form param
52e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * after call get_parm_word, str either point to string end
53e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * or point to any of end chars.
54e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET */
55486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymostatic char *get_param_word(char **str, char **end_pos, char endchar)
56e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET{
57e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET  char *ptr = *str;
58e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET  char *word_begin = NULL;
59e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET  char *ptr2;
60e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET  char *escape = NULL;
61e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
62e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET  /* the first non-space char is here */
63e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET  word_begin = ptr;
64e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET  if(*ptr == '"') {
65e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    ++ptr;
66e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    while(*ptr) {
67e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET      if(*ptr == '\\') {
68e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET        if(ptr[1] == '\\' || ptr[1] == '"') {
69e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET          /* remember the first escape position */
70e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET          if(!escape)
71e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET            escape = ptr;
72e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET          /* skip escape of back-slash or double-quote */
73e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET          ptr += 2;
74e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET          continue;
75e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET        }
76e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET      }
77e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET      if(*ptr == '"') {
78e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET        *end_pos = ptr;
79e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET        if(escape) {
80e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET          /* has escape, we restore the unescaped string here */
81e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET          ptr = ptr2 = escape;
82e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET          do {
83e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET            if(*ptr == '\\' && (ptr[1] == '\\' || ptr[1] == '"'))
84e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET              ++ptr;
85e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET            *ptr2++ = *ptr++;
86e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET          }
87e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET          while(ptr < *end_pos);
88e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET          *end_pos = ptr2;
89e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET        }
90486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        while(*ptr && *ptr != ';' && *ptr != endchar)
91e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET          ++ptr;
92e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET        *str = ptr;
93486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        return word_begin + 1;
94e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET      }
95e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET      ++ptr;
96e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    }
97e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    /* end quote is missing, treat it as non-quoted. */
98e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    ptr = word_begin;
99e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET  }
100e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
101486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo  while(*ptr && *ptr != ';' && *ptr != endchar)
102e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    ++ptr;
103e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET  *str = *end_pos = ptr;
104e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET  return word_begin;
105e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET}
106e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
107486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo/* Append slist item and return -1 if failed. */
108486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymostatic int slist_append(struct curl_slist **plist, const char *data)
109486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo{
110486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo  struct curl_slist *s = curl_slist_append(*plist, data);
111486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo
112486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo  if(!s)
113486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo    return -1;
114486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo
115486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo  *plist = s;
116486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo  return 0;
117486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo}
118486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo
119486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo/* Read headers from a file and append to list. */
120486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymostatic int read_field_headers(struct OperationConfig *config,
121486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo                              const char *filename, FILE *fp,
122486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo                              struct curl_slist **pheaders)
123486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo{
124486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo  size_t hdrlen = 0;
125486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo  size_t pos = 0;
126486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo  int c;
127486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo  bool incomment = FALSE;
128486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo  int lineno = 1;
129486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo  char hdrbuf[999]; /* Max. header length + 1. */
130486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo
131486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo  for(;;) {
132486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo    c = getc(fp);
133486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo    if(c == EOF || (!pos && !ISSPACE(c))) {
134486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo      /* Strip and flush the current header. */
135486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo      while(hdrlen && ISSPACE(hdrbuf[hdrlen - 1]))
136486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        hdrlen--;
137486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo      if(hdrlen) {
138486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        hdrbuf[hdrlen] = '\0';
139486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        if(slist_append(pheaders, hdrbuf)) {
140486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo          fprintf(config->global->errors,
141486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo                  "Out of memory for field headers!\n");
142486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo          return -1;
143486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        }
144486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        hdrlen = 0;
145486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo      }
146486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo    }
147486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo
148486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo    switch(c) {
149486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo    case EOF:
150486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo      if(ferror(fp)) {
151486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        fprintf(config->global->errors,
152486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo                "Header file %s read error: %s\n", filename, strerror(errno));
153486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        return -1;
154486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo      }
155486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo      return 0;    /* Done. */
156486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo    case '\r':
157486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo      continue;    /* Ignore. */
158486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo    case '\n':
159486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo      pos = 0;
160486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo      incomment = FALSE;
161486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo      lineno++;
162486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo      continue;
163486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo    case '#':
164486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo      if(!pos)
165486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        incomment = TRUE;
166486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo      break;
167486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo    }
168486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo
169486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo    pos++;
170486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo    if(!incomment) {
171486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo      if(hdrlen == sizeof hdrbuf - 1) {
172486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        warnf(config->global, "File %s line %d: header too long (truncated)\n",
173486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo              filename, lineno);
174486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        c = ' ';
175486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo      }
176486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo      if(hdrlen <= sizeof hdrbuf - 1)
177486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        hdrbuf[hdrlen++] = (char) c;
178486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo    }
179486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo  }
180486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo  /* NOTREACHED */
181486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo}
182486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo
183486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymostatic int get_param_part(struct OperationConfig *config, char endchar,
184486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo                          char **str, char **pdata, char **ptype,
185486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo                          char **pfilename, char **pencoder,
186486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo                          struct curl_slist **pheaders)
187486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo{
188486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo  char *p = *str;
189486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo  char *type = NULL;
190486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo  char *filename = NULL;
191486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo  char *encoder = NULL;
192486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo  char *endpos;
193486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo  char *tp;
194486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo  char sep;
195486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo  char type_major[128] = "";
196486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo  char type_minor[128] = "";
197486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo  char *endct = NULL;
198486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo  struct curl_slist *headers = NULL;
199486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo
200486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo  if(ptype)
201486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo    *ptype = NULL;
202486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo  if(pfilename)
203486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo    *pfilename = NULL;
204486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo  if(pheaders)
205486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo    *pheaders = NULL;
206486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo  if(pencoder)
207486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo    *pencoder = NULL;
208486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo  while(ISSPACE(*p))
209486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo    p++;
210486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo  tp = p;
211486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo  *pdata = get_param_word(&p, &endpos, endchar);
212486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo  /* If not quoted, strip trailing spaces. */
213486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo  if(*pdata == tp)
214486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo    while(endpos > *pdata && ISSPACE(endpos[-1]))
215486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo      endpos--;
216486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo  sep = *p;
217486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo  *endpos = '\0';
218486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo  while(sep == ';') {
219486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo    while(ISSPACE(*++p))
220486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo      ;
221486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo
222486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo    if(!endct && checkprefix("type=", p)) {
223486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo      for(p += 5; ISSPACE(*p); p++)
224486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        ;
225486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo      /* set type pointer */
226486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo      type = p;
227486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo
228486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo      /* verify that this is a fine type specifier */
229486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo      if(2 != sscanf(type, "%127[^/ ]/%127[^;, \n]", type_major, type_minor)) {
230486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        warnf(config->global, "Illegally formatted content-type field!\n");
231486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        curl_slist_free_all(headers);
232486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        return -1; /* illegal content-type syntax! */
233486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo      }
234486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo
235486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo      /* now point beyond the content-type specifier */
236486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo      p = type + strlen(type_major) + strlen(type_minor) + 1;
237486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo      for(endct = p; *p && *p != ';' && *p != endchar; p++)
238486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        if(!ISSPACE(*p))
239486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo          endct = p + 1;
240486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo      sep = *p;
241486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo    }
242486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo    else if(checkprefix("filename=", p)) {
243486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo      if(endct) {
244486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        *endct = '\0';
245486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        endct = NULL;
246486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo      }
247486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo      for(p += 9; ISSPACE(*p); p++)
248486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        ;
249486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo      tp = p;
250486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo      filename = get_param_word(&p, &endpos, endchar);
251486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo      /* If not quoted, strip trailing spaces. */
252486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo      if(filename == tp)
253486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        while(endpos > filename && ISSPACE(endpos[-1]))
254486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo          endpos--;
255486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo      sep = *p;
256486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo      *endpos = '\0';
257486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo    }
258486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo    else if(checkprefix("headers=", p)) {
259486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo      if(endct) {
260486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        *endct = '\0';
261486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        endct = NULL;
262486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo      }
263486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo      p += 8;
264486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo      if(*p == '@' || *p == '<') {
265486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        char *hdrfile;
266486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        FILE *fp;
267486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        /* Read headers from a file. */
268486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo
269486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        do {
270486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo          p++;
271486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        } while(ISSPACE(*p));
272486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        tp = p;
273486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        hdrfile = get_param_word(&p, &endpos, endchar);
274486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        /* If not quoted, strip trailing spaces. */
275486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        if(hdrfile == tp)
276486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo          while(endpos > hdrfile && ISSPACE(endpos[-1]))
277486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo            endpos--;
278486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        sep = *p;
279486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        *endpos = '\0';
280486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        /* TODO: maybe special fopen for VMS? */
281486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        fp = fopen(hdrfile, FOPEN_READTEXT);
282486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        if(!fp)
283486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo          warnf(config->global, "Cannot read from %s: %s\n", hdrfile,
284486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo                strerror(errno));
285486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        else {
286486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo          int i = read_field_headers(config, hdrfile, fp, &headers);
287486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo
288486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo          fclose(fp);
289486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo          if(i) {
290486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo            curl_slist_free_all(headers);
291486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo            return -1;
292486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo          }
293486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        }
294486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo      }
295486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo      else {
296486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        char *hdr;
297486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo
298486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        while(ISSPACE(*p))
299486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo          p++;
300486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        tp = p;
301486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        hdr = get_param_word(&p, &endpos, endchar);
302486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        /* If not quoted, strip trailing spaces. */
303486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        if(hdr == tp)
304486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo          while(endpos > hdr && ISSPACE(endpos[-1]))
305486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo            endpos--;
306486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        sep = *p;
307486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        *endpos = '\0';
308486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        if(slist_append(&headers, hdr)) {
309486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo          fprintf(config->global->errors, "Out of memory for field header!\n");
310486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo          curl_slist_free_all(headers);
311486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo          return -1;
312486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        }
313486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo      }
314486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo    }
315486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo    else if(checkprefix("encoder=", p)) {
316486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo      if(endct) {
317486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        *endct = '\0';
318486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        endct = NULL;
319486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo      }
320486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo      for(p += 8; ISSPACE(*p); p++)
321486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        ;
322486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo      tp = p;
323486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo      encoder = get_param_word(&p, &endpos, endchar);
324486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo      /* If not quoted, strip trailing spaces. */
325486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo      if(encoder == tp)
326486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        while(endpos > encoder && ISSPACE(endpos[-1]))
327486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo          endpos--;
328486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo      sep = *p;
329486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo      *endpos = '\0';
330486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo    }
331486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo    else if(endct) {
332486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo      /* This is part of content type. */
333486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo      for(endct = p; *p && *p != ';' && *p != endchar; p++)
334486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        if(!ISSPACE(*p))
335486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo          endct = p + 1;
336486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo      sep = *p;
337486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo    }
338486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo    else {
339486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo      /* unknown prefix, skip to next block */
340486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo      char *unknown = get_param_word(&p, &endpos, endchar);
341486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo
342486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo      sep = *p;
343486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo      *endpos = '\0';
344486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo      if(*unknown)
345486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        warnf(config->global, "skip unknown form field: %s\n", unknown);
346486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo    }
347486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo  }
348486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo
349486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo  /* Terminate content type. */
350486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo  if(endct)
351486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo    *endct = '\0';
352486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo
353486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo  if(ptype)
354486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo    *ptype = type;
355486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo  else if(type)
356486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo    warnf(config->global, "Field content type not allowed here: %s\n", type);
357486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo
358486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo  if(pfilename)
359486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo    *pfilename = filename;
360486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo  else if(filename)
361486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo    warnf(config->global,
362486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo          "Field file name not allowed here: %s\n", filename);
363486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo
364486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo  if(pencoder)
365486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo    *pencoder = encoder;
366486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo  else if(encoder)
367486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo    warnf(config->global,
368486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo          "Field encoder not allowed here: %s\n", encoder);
369486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo
370486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo  if(pheaders)
371486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo    *pheaders = headers;
372486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo  else if(headers) {
373486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo    warnf(config->global,
374486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo          "Field headers not allowed here: %s\n", headers->data);
375486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo    curl_slist_free_all(headers);
376486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo  }
377486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo
378486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo  *str = p;
379486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo  return sep & 0xFF;
380486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo}
381486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo
382486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo
383486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo/* Mime part callbacks for stdin. */
384486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymostatic size_t stdin_read(char *buffer, size_t size, size_t nitems, void *arg)
385486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo{
386486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo  standard_input *sip = (standard_input *) arg;
387486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo  curl_off_t bytesleft;
388486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo  (void) size;  /* Always 1: ignored. */
389486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo
390486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo  if(sip->curpos >= sip->size)
391486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo    return 0;  /* At eof. */
392486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo  bytesleft = sip->size - sip->curpos;
393486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo  if((curl_off_t) nitems > bytesleft)
394486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo    nitems = (size_t) bytesleft;
395486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo  if(sip->data) {
396486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo    /* Return data from memory. */
397486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo    memcpy(buffer, sip->data + (size_t) sip->curpos, nitems);
398486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo  }
399486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo  else {
400486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo    /* Read from stdin. */
401486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo    nitems = fread(buffer, 1, nitems, stdin);
402486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo  }
403486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo  sip->curpos += nitems;
404486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo  return nitems;
405486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo}
406486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo
407486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymostatic int stdin_seek(void *instream, curl_off_t offset, int whence)
408486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo{
409486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo  standard_input *sip = (standard_input *) instream;
410486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo
411486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo  switch(whence) {
412486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo  case SEEK_CUR:
413486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo    offset += sip->curpos;
414486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo    break;
415486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo  case SEEK_END:
416486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo    offset += sip->size;
417486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo    break;
418486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo  }
419486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo  if(offset < 0)
420486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo    return CURL_SEEKFUNC_CANTSEEK;
421486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo  if(!sip->data) {
422486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo    if(fseek(stdin, (long) (offset + sip->origin), SEEK_SET))
423486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo      return CURL_SEEKFUNC_CANTSEEK;
424486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo  }
425486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo  sip->curpos = offset;
426486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo  return CURL_SEEKFUNC_OK;
427486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo}
428486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo
429486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymostatic void stdin_free(void *ptr)
430486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo{
431486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo  standard_input *sip = (standard_input *) ptr;
432486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo
433486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo  Curl_safefree(sip->data);
434486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo  free(sip);
435486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo}
436486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo
437486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo/* Set a part's data from a file, taking care about the pseudo filename "-" as
438486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo * a shortcut to read stdin: if so, use a callback to read OUR stdin (to
439486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo * workaround Windows DLL file handle caveat).
440486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo * If stdin is a regular file opened in binary mode, save current offset as
441486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo * origin for rewind and do not buffer data. Else read to EOF and keep in
442486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo * memory. In all cases, compute the stdin data size.
443486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo */
444486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymostatic CURLcode file_or_stdin(curl_mimepart *part, const char *file)
445486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo{
446486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo  standard_input *sip = NULL;
447486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo  int fd = -1;
448486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo  CURLcode result = CURLE_OK;
449486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo  struct_stat sbuf;
450486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo
451486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo  if(strcmp(file, "-"))
452486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo    return curl_mime_filedata(part, file);
453486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo
454486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo  sip = (standard_input *) malloc(sizeof *sip);
455486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo  if(!sip)
456486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo    return CURLE_OUT_OF_MEMORY;
457486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo
458486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo  memset((char *) sip, 0, sizeof *sip);
459486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo  set_binmode(stdin);
460486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo
461486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo  /* If stdin is a regular file, do not buffer data but read it when needed. */
462486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo  fd = fileno(stdin);
463486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo  sip->origin = ftell(stdin);
464486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo  if(fd >= 0 && sip->origin >= 0 && !fstat(fd, &sbuf) &&
465486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo#ifdef __VMS
466486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo     sbuf.st_fab_rfm != FAB$C_VAR && sbuf.st_fab_rfm != FAB$C_VFC &&
467486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo#endif
468486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo     S_ISREG(sbuf.st_mode)) {
469486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo    sip->size = sbuf.st_size - sip->origin;
470486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo    if(sip->size < 0)
471486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo      sip->size = 0;
472486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo  }
473486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo  else {  /* Not suitable for direct use, buffer stdin data. */
474486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo    size_t stdinsize = 0;
475486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo
476486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo    sip->origin = 0;
477486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo    if(file2memory(&sip->data, &stdinsize, stdin) != PARAM_OK)
478486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo      result = CURLE_OUT_OF_MEMORY;
479486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo    else {
480486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo      if(!stdinsize)
481486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        sip->data = NULL;  /* Has been freed if no data. */
482486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo      sip->size = stdinsize;
483486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo      if(ferror(stdin))
484486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        result = CURLE_READ_ERROR;
485486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo    }
486486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo  }
487486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo
488486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo  /* Set remote file name. */
489486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo  if(!result)
490486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo    result = curl_mime_filename(part, file);
491486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo
492486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo  /* Set part's data from callback. */
493486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo  if(!result)
494486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo    result = curl_mime_data_cb(part, sip->size,
495486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo                               stdin_read, stdin_seek, stdin_free, sip);
496486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo  if(result)
497486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo    stdin_free(sip);
498486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo  return result;
499486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo}
500486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo
501486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo
502e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET/***************************************************************************
503e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET *
504e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * formparse()
505e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET *
506e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * Reads a 'name=value' parameter and builds the appropriate linked list.
507e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET *
508e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * Specify files to upload with 'name=@filename', or 'name=@"filename"'
509e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * in case the filename contain ',' or ';'. Supports specified
510e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * given Content-Type of the files. Such as ';type=<content-type>'.
511e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET *
512e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * If literal_value is set, any initial '@' or '<' in the value string
513e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * loses its special meaning, as does any embedded ';type='.
514e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET *
515e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * You may specify more than one file for a single name (field). Specify
516e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * multiple files by writing it like:
517e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET *
518e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * 'name=@filename,filename2,filename3'
519e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET *
520e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * or use double-quotes quote the filename:
521e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET *
522e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * 'name=@"filename","filename2","filename3"'
523e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET *
524e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * If you want content-types specified for each too, write them like:
525e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET *
526e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * 'name=@filename;type=image/gif,filename2,filename3'
527e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET *
528e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * If you want custom headers added for a single part, write them in a separate
529e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * file and do like this:
530e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET *
531e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * 'name=foo;headers=@headerfile' or why not
532e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * 'name=@filemame;headers=@headerfile'
533e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET *
534e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * To upload a file, but to fake the file name that will be included in the
535e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * formpost, do like this:
536e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET *
537e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * 'name=@filename;filename=/dev/null' or quote the faked filename like:
538e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * 'name=@filename;filename="play, play, and play.txt"'
539e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET *
540e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * If filename/path contains ',' or ';', it must be quoted by double-quotes,
541e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * else curl will fail to figure out the correct filename. if the filename
542e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * tobe quoted contains '"' or '\', '"' and '\' must be escaped by backslash.
543e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET *
544e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * This function uses curl_formadd to fulfill it's job. Is heavily based on
545e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * the old curl_formparse code.
546e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET *
547e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET ***************************************************************************/
548e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
549e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNETint formparse(struct OperationConfig *config,
550e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET              const char *input,
551486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo              curl_mime **mimepost,
552486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo              curl_mime **mimecurrent,
553e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET              bool literal_value)
554e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET{
555486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo  /* input MUST be a string in the format 'name=contents' and we'll
556e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET     build a linked list with the info */
557486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo  char *name = NULL;
558e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET  char *contents = NULL;
559e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET  char *contp;
560486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo  char *data;
56182be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughes  char *type = NULL;
562486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo  char *filename = NULL;
563486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo  char *encoder = NULL;
564486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo  struct curl_slist *headers = NULL;
565486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo  curl_mimepart *part = NULL;
566486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo  CURLcode res;
567486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo  int sep = '\0';
568486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo
569486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo  /* Allocate the main mime structure if needed. */
570486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo  if(!*mimepost) {
571486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo    *mimepost = curl_mime_init(config->easy);
572486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo    if(!*mimepost) {
573486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo      warnf(config->global, "curl_mime_init failed!\n");
574e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET      return 1;
575e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    }
576486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo    *mimecurrent = *mimepost;
577486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo  }
578e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
579486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo  /* Make a copy we can overwrite. */
580486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo  contents = strdup(input);
581486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo  if(!contents) {
582486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo    fprintf(config->global->errors, "out of memory\n");
583486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo    return 2;
584486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo  }
585e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
586486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo  /* Scan for the end of the name. */
587486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo  contp = strchr(contents, '=');
588486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo  if(contp) {
589486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo    if(contp > contents)
590486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo      name = contents;
591486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo    *contp++ = '\0';
592486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo
593486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo    if(*contp == '(' && !literal_value) {
594486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo      curl_mime *subparts;
595486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo
596486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo      /* Starting a multipart. */
597486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo      sep = get_param_part(config, '\0',
598486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo                           &contp, &data, &type, NULL, NULL, &headers);
599486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo      if(sep < 0) {
600486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        Curl_safefree(contents);
601486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        return 3;
602486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo      }
603486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo      subparts = curl_mime_init(config->easy);
604486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo      if(!subparts) {
605486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        warnf(config->global, "curl_mime_init failed!\n");
606486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        curl_slist_free_all(headers);
607486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        Curl_safefree(contents);
608486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        return 4;
609486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo      }
610486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo      part = curl_mime_addpart(*mimecurrent);
611486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo      if(!part) {
612486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        warnf(config->global, "curl_mime_addpart failed!\n");
613486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        curl_mime_free(subparts);
614486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        curl_slist_free_all(headers);
615486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        Curl_safefree(contents);
616486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        return 5;
617486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo      }
618486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo      if(curl_mime_subparts(part, subparts)) {
619486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        warnf(config->global, "curl_mime_subparts failed!\n");
620486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        curl_mime_free(subparts);
621486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        curl_slist_free_all(headers);
622486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        Curl_safefree(contents);
623486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        return 6;
624486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo      }
625486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo      *mimecurrent = subparts;
626486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo      if(curl_mime_headers(part, headers, 1)) {
627486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        warnf(config->global, "curl_mime_headers failed!\n");
628486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        curl_slist_free_all(headers);
629486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        Curl_safefree(contents);
630486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        return 7;
631486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo      }
632486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo      if(curl_mime_type(part, type)) {
633486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        warnf(config->global, "curl_mime_type failed!\n");
634486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        Curl_safefree(contents);
635486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        return 8;
636486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo      }
637486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo    }
638486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo    else if(!name && !strcmp(contp, ")") && !literal_value) {
639486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo      /* Ending a mutipart. */
640486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo      if(*mimecurrent == *mimepost) {
641486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        warnf(config->global, "no multipart to terminate!\n");
642486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        Curl_safefree(contents);
643486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        return 9;
644486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        }
645486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo      *mimecurrent = (*mimecurrent)->parent->parent;
646486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo    }
647486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo    else if('@' == contp[0] && !literal_value) {
648e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
649486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo      /* we use the @-letter to indicate file name(s) */
650e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
651486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo      curl_mime *subparts = NULL;
652e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
653e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET      do {
654e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET        /* since this was a file, it may have a content-type specifier
655e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET           at the end too, or a filename. Or both. */
656486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        ++contp;
657486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        sep = get_param_part(config, ',', &contp,
658486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo                             &data, &type, &filename, &encoder, &headers);
659486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        if(sep < 0) {
660486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo          if(subparts != *mimecurrent)
661486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo            curl_mime_free(subparts);
662486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo          Curl_safefree(contents);
663486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo          return 10;
664486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        }
665e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
666486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        /* now contp point to comma or string end.
667486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo           If more files to come, make sure we have multiparts. */
668486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        if(!subparts) {
669486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo          if(sep != ',')    /* If there is a single file. */
670486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo            subparts = *mimecurrent;
671e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET          else {
672486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo            subparts = curl_mime_init(config->easy);
673486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo            if(!subparts) {
674486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo              warnf(config->global, "curl_mime_init failed!\n");
675486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo              curl_slist_free_all(headers);
676486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo              Curl_safefree(contents);
677486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo              return 11;
678e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET            }
679e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET          }
680e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET        }
681e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
682486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        /* Allocate a part for that file. */
683486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        part = curl_mime_addpart(subparts);
684486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        if(!part) {
685486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo          warnf(config->global, "curl_mime_addpart failed!\n");
686486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo          if(subparts != *mimecurrent)
687486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo            curl_mime_free(subparts);
688486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo          curl_slist_free_all(headers);
689486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo          Curl_safefree(contents);
690486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo          return 12;
691486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        }
692e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
693486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        /* Set part headers. */
694486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        if(curl_mime_headers(part, headers, 1)) {
695486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo          warnf(config->global, "curl_mime_headers failed!\n");
696486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo          if(subparts != *mimecurrent)
697486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo            curl_mime_free(subparts);
698486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo          curl_slist_free_all(headers);
699486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo          Curl_safefree(contents);
700486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo          return 13;
701486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        }
702e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
703486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        /* Setup file in part. */
704486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        res = file_or_stdin(part, data);
705486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        if(res) {
706486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo          warnf(config->global, "setting file %s  failed!\n", data);
707486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo          if(res != CURLE_READ_ERROR) {
708486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo            if(subparts != *mimecurrent)
709486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo              curl_mime_free(subparts);
710486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo            Curl_safefree(contents);
711486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo            return 14;
712486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo          }
713486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        }
714486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        if(filename && curl_mime_filename(part, filename)) {
715486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo          warnf(config->global, "curl_mime_filename failed!\n");
716486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo          if(subparts != *mimecurrent)
717486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo            curl_mime_free(subparts);
718486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo          Curl_safefree(contents);
719486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo          return 15;
720486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        }
721486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        if(curl_mime_type(part, type)) {
722486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo          warnf(config->global, "curl_mime_type failed!\n");
723486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo          if(subparts != *mimecurrent)
724486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo            curl_mime_free(subparts);
725486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo          Curl_safefree(contents);
726486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo          return 16;
727486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        }
728486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        if(curl_mime_encoder(part, encoder)) {
729486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo          warnf(config->global, "curl_mime_encoder failed!\n");
730486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo          if(subparts != *mimecurrent)
731486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo            curl_mime_free(subparts);
732e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET          Curl_safefree(contents);
733486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo          return 17;
734e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET        }
735e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
736486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        /* *contp could be '\0', so we just check with the delimiter */
737486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo      } while(sep); /* loop if there's another file name */
738e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
739e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET      /* now we add the multiple files section */
740486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo      if(subparts != *mimecurrent) {
741486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        part = curl_mime_addpart(*mimecurrent);
742486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        if(!part) {
743486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo          warnf(config->global, "curl_mime_addpart failed!\n");
744486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo          curl_mime_free(subparts);
745e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET          Curl_safefree(contents);
746486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo          return 18;
747e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET        }
748486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        if(curl_mime_subparts(part, subparts)) {
749486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo          warnf(config->global, "curl_mime_subparts failed!\n");
750486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo          curl_mime_free(subparts);
751e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET          Curl_safefree(contents);
752486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo          return 19;
753e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET        }
754e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET      }
755e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    }
756e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    else {
757486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        /* Allocate a mime part. */
758486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        part = curl_mime_addpart(*mimecurrent);
759486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        if(!part) {
760486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo          warnf(config->global, "curl_mime_addpart failed!\n");
761486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo          Curl_safefree(contents);
762486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo          return 20;
763486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        }
764e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
765486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo      if(*contp == '<' && !literal_value) {
766486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        ++contp;
767486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        sep = get_param_part(config, '\0', &contp,
768486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo                             &data, &type, NULL, &encoder, &headers);
769486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        if(sep < 0) {
770486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo          Curl_safefree(contents);
771486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo          return 21;
772486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        }
773e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
774486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        /* Set part headers. */
775486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        if(curl_mime_headers(part, headers, 1)) {
776486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo          warnf(config->global, "curl_mime_headers failed!\n");
777486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo          curl_slist_free_all(headers);
778e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET          Curl_safefree(contents);
779486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo          return 22;
780486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        }
781486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo
782486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        /* Setup file in part. */
783486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        res = file_or_stdin(part, data);
784486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        if(res) {
785486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo          warnf(config->global, "setting file %s failed!\n", data);
786486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo          if(res != CURLE_READ_ERROR) {
787486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo            Curl_safefree(contents);
788486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo            return 23;
789486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo          }
790e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET        }
791e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET      }
792e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET      else {
793486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        if(literal_value)
794486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo          data = contp;
795486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        else {
796486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo          sep = get_param_part(config, '\0', &contp,
797486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo                               &data, &type, &filename, &encoder, &headers);
798486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo          if(sep < 0) {
799486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo            Curl_safefree(contents);
800486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo            return 24;
801486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo          }
802486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        }
803486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo
804486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        /* Set part headers. */
805486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        if(curl_mime_headers(part, headers, 1)) {
806486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo          warnf(config->global, "curl_mime_headers failed!\n");
807486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo          curl_slist_free_all(headers);
808486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo          Curl_safefree(contents);
809486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo          return 25;
810486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        }
811486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo
812e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#ifdef CURL_DOES_CONVERSIONS
813486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        if(convert_to_network(data, strlen(data))) {
814e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET          warnf(config->global, "curl_formadd failed!\n");
815e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET          Curl_safefree(contents);
816486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo          return 26;
817e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET        }
818e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#endif
819486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo
820486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        if(curl_mime_data(part, data, CURL_ZERO_TERMINATED)) {
821486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo          warnf(config->global, "curl_mime_data failed!\n");
822e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET          Curl_safefree(contents);
823486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo          return 27;
824e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET        }
825e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET      }
826486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo
827486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo      if(curl_mime_filename(part, filename)) {
828486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        warnf(config->global, "curl_mime_filename failed!\n");
829486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        Curl_safefree(contents);
830486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        return 28;
831486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo      }
832486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo      if(curl_mime_type(part, type)) {
833486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        warnf(config->global, "curl_mime_type failed!\n");
834486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        Curl_safefree(contents);
835486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        return 29;
836486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo      }
837486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo      if(curl_mime_encoder(part, encoder)) {
838486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        warnf(config->global, "curl_mime_encoder failed!\n");
839486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        Curl_safefree(contents);
840486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        return 30;
841486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo      }
842486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo
843486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo      if(sep) {
844486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        *contp = (char) sep;
845486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo        warnf(config->global,
846486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo              "garbage at end of field specification: %s\n", contp);
847486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo      }
848e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    }
849e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
850486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo    /* Set part name. */
851486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo    if(name && curl_mime_name(part, name)) {
852486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo      warnf(config->global, "curl_mime_name failed!\n");
853486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo      Curl_safefree(contents);
854486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo      return 31;
855486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo    }
856e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET  }
857e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET  else {
858e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    warnf(config->global, "Illegally formatted input field!\n");
859486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo    Curl_safefree(contents);
860486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo    return 32;
861e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET  }
862e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET  Curl_safefree(contents);
863e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET  return 0;
864e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET}
865