file.c
Go to the documentation of this file.
1 /***************************************************************************
2  * _ _ ____ _
3  * Project ___| | | | _ \| |
4  * / __| | | | |_) | |
5  * | (__| |_| | _ <| |___
6  * \___|\___/|_| \_\_____|
7  *
8  * Copyright (C) 1998 - 2017, 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 
23 #include "curl_setup.h"
24 
25 #ifndef CURL_DISABLE_FILE
26 
27 #ifdef HAVE_NETINET_IN_H
28 #include <netinet/in.h>
29 #endif
30 #ifdef HAVE_NETDB_H
31 #include <netdb.h>
32 #endif
33 #ifdef HAVE_ARPA_INET_H
34 #include <arpa/inet.h>
35 #endif
36 #ifdef HAVE_NET_IF_H
37 #include <net/if.h>
38 #endif
39 #ifdef HAVE_SYS_IOCTL_H
40 #include <sys/ioctl.h>
41 #endif
42 
43 #ifdef HAVE_SYS_PARAM_H
44 #include <sys/param.h>
45 #endif
46 
47 #ifdef HAVE_FCNTL_H
48 #include <fcntl.h>
49 #endif
50 
51 #include "strtoofft.h"
52 #include "urldata.h"
53 #include <curl/curl.h>
54 #include "progress.h"
55 #include "sendf.h"
56 #include "escape.h"
57 #include "file.h"
58 #include "speedcheck.h"
59 #include "getinfo.h"
60 #include "transfer.h"
61 #include "url.h"
62 #include "parsedate.h" /* for the week day and month names */
63 #include "warnless.h"
64 /* The last 3 #include files should be in this order */
65 #include "curl_printf.h"
66 #include "curl_memory.h"
67 #include "memdebug.h"
68 
69 #if defined(WIN32) || defined(MSDOS) || defined(__EMX__) || \
70  defined(__SYMBIAN32__)
71 #define DOS_FILESYSTEM 1
72 #endif
73 
74 #ifdef OPEN_NEEDS_ARG3
75 # define open_readonly(p,f) open((p),(f),(0))
76 #else
77 # define open_readonly(p,f) open((p),(f))
78 #endif
79 
80 /*
81  * Forward declarations.
82  */
83 
84 static CURLcode file_do(struct connectdata *, bool *done);
85 static CURLcode file_done(struct connectdata *conn,
86  CURLcode status, bool premature);
87 static CURLcode file_connect(struct connectdata *conn, bool *done);
88 static CURLcode file_disconnect(struct connectdata *conn,
89  bool dead_connection);
90 static CURLcode file_setup_connection(struct connectdata *conn);
91 
92 /*
93  * FILE scheme handler.
94  */
95 
97  "FILE", /* scheme */
98  file_setup_connection, /* setup_connection */
99  file_do, /* do_it */
100  file_done, /* done */
101  ZERO_NULL, /* do_more */
102  file_connect, /* connect_it */
103  ZERO_NULL, /* connecting */
104  ZERO_NULL, /* doing */
105  ZERO_NULL, /* proto_getsock */
106  ZERO_NULL, /* doing_getsock */
107  ZERO_NULL, /* domore_getsock */
108  ZERO_NULL, /* perform_getsock */
109  file_disconnect, /* disconnect */
110  ZERO_NULL, /* readwrite */
111  ZERO_NULL, /* connection_check */
112  0, /* defport */
113  CURLPROTO_FILE, /* protocol */
115 };
116 
117 
119 {
120  /* allocate the FILE specific struct */
121  conn->data->req.protop = calloc(1, sizeof(struct FILEPROTO));
122  if(!conn->data->req.protop)
123  return CURLE_OUT_OF_MEMORY;
124 
125  return CURLE_OK;
126 }
127 
128  /*
129  Check if this is a range download, and if so, set the internal variables
130  properly. This code is copied from the FTP implementation and might as
131  well be factored out.
132  */
133 static CURLcode file_range(struct connectdata *conn)
134 {
135  curl_off_t from, to;
136  curl_off_t totalsize = -1;
137  char *ptr;
138  char *ptr2;
139  struct Curl_easy *data = conn->data;
140 
141  if(data->state.use_range && data->state.range) {
142  CURLofft from_t;
143  CURLofft to_t;
144  from_t = curlx_strtoofft(data->state.range, &ptr, 0, &from);
145  if(from_t == CURL_OFFT_FLOW)
146  return CURLE_RANGE_ERROR;
147  while(*ptr && (ISSPACE(*ptr) || (*ptr == '-')))
148  ptr++;
149  to_t = curlx_strtoofft(ptr, &ptr2, 0, &to);
150  if(to_t == CURL_OFFT_FLOW)
151  return CURLE_RANGE_ERROR;
152  if((to_t == CURL_OFFT_INVAL) && !from_t) {
153  /* X - */
154  data->state.resume_from = from;
155  DEBUGF(infof(data, "RANGE %" CURL_FORMAT_CURL_OFF_T " to end of file\n",
156  from));
157  }
158  else if((from_t == CURL_OFFT_INVAL) && !to_t) {
159  /* -Y */
160  data->req.maxdownload = to;
161  data->state.resume_from = -to;
162  DEBUGF(infof(data, "RANGE the last %" CURL_FORMAT_CURL_OFF_T " bytes\n",
163  to));
164  }
165  else {
166  /* X-Y */
167  totalsize = to-from;
168  if(totalsize == CURL_OFF_T_MAX)
169  /* this is too big to increase, so bail out */
170  return CURLE_RANGE_ERROR;
171  data->req.maxdownload = totalsize + 1; /* include last byte */
172  data->state.resume_from = from;
173  DEBUGF(infof(data, "RANGE from %" CURL_FORMAT_CURL_OFF_T
174  " getting %" CURL_FORMAT_CURL_OFF_T " bytes\n",
175  from, data->req.maxdownload));
176  }
177  DEBUGF(infof(data, "range-download from %" CURL_FORMAT_CURL_OFF_T
178  " to %" CURL_FORMAT_CURL_OFF_T ", totally %"
179  CURL_FORMAT_CURL_OFF_T " bytes\n",
180  from, to, data->req.maxdownload));
181  }
182  else
183  data->req.maxdownload = -1;
184  return CURLE_OK;
185 }
186 
187 /*
188  * file_connect() gets called from Curl_protocol_connect() to allow us to
189  * do protocol-specific actions at connect-time. We emulate a
190  * connect-then-transfer protocol and "connect" to the file here
191  */
192 static CURLcode file_connect(struct connectdata *conn, bool *done)
193 {
194  struct Curl_easy *data = conn->data;
195  char *real_path;
196  struct FILEPROTO *file = data->req.protop;
197  int fd;
198 #ifdef DOS_FILESYSTEM
199  size_t i;
200  char *actual_path;
201 #endif
202  size_t real_path_len;
203 
204  CURLcode result = Curl_urldecode(data, data->state.path, 0, &real_path,
205  &real_path_len, FALSE);
206  if(result)
207  return result;
208 
209 #ifdef DOS_FILESYSTEM
210  /* If the first character is a slash, and there's
211  something that looks like a drive at the beginning of
212  the path, skip the slash. If we remove the initial
213  slash in all cases, paths without drive letters end up
214  relative to the current directory which isn't how
215  browsers work.
216 
217  Some browsers accept | instead of : as the drive letter
218  separator, so we do too.
219 
220  On other platforms, we need the slash to indicate an
221  absolute pathname. On Windows, absolute paths start
222  with a drive letter.
223  */
224  actual_path = real_path;
225  if((actual_path[0] == '/') &&
226  actual_path[1] &&
227  (actual_path[2] == ':' || actual_path[2] == '|')) {
228  actual_path[2] = ':';
229  actual_path++;
230  real_path_len--;
231  }
232 
233  /* change path separators from '/' to '\\' for DOS, Windows and OS/2 */
234  for(i = 0; i < real_path_len; ++i)
235  if(actual_path[i] == '/')
236  actual_path[i] = '\\';
237  else if(!actual_path[i]) { /* binary zero */
238  Curl_safefree(real_path);
239  return CURLE_URL_MALFORMAT;
240  }
241 
242  fd = open_readonly(actual_path, O_RDONLY|O_BINARY);
243  file->path = actual_path;
244 #else
245  if(memchr(real_path, 0, real_path_len)) {
246  /* binary zeroes indicate foul play */
247  Curl_safefree(real_path);
248  return CURLE_URL_MALFORMAT;
249  }
250 
251  fd = open_readonly(real_path, O_RDONLY);
252  file->path = real_path;
253 #endif
254  file->freepath = real_path; /* free this when done */
255 
256  file->fd = fd;
257  if(!data->set.upload && (fd == -1)) {
258  failf(data, "Couldn't open file %s", data->state.path);
261  }
262  *done = TRUE;
263 
264  return CURLE_OK;
265 }
266 
267 static CURLcode file_done(struct connectdata *conn,
268  CURLcode status, bool premature)
269 {
270  struct FILEPROTO *file = conn->data->req.protop;
271  (void)status; /* not used */
272  (void)premature; /* not used */
273 
274  if(file) {
275  Curl_safefree(file->freepath);
276  file->path = NULL;
277  if(file->fd != -1)
278  close(file->fd);
279  file->fd = -1;
280  }
281 
282  return CURLE_OK;
283 }
284 
286  bool dead_connection)
287 {
288  struct FILEPROTO *file = conn->data->req.protop;
289  (void)dead_connection; /* not used */
290 
291  if(file) {
292  Curl_safefree(file->freepath);
293  file->path = NULL;
294  if(file->fd != -1)
295  close(file->fd);
296  file->fd = -1;
297  }
298 
299  return CURLE_OK;
300 }
301 
302 #ifdef DOS_FILESYSTEM
303 #define DIRSEP '\\'
304 #else
305 #define DIRSEP '/'
306 #endif
307 
308 static CURLcode file_upload(struct connectdata *conn)
309 {
310  struct FILEPROTO *file = conn->data->req.protop;
311  const char *dir = strchr(file->path, DIRSEP);
312  int fd;
313  int mode;
315  struct Curl_easy *data = conn->data;
316  char *buf = data->state.buffer;
317  size_t nread;
318  size_t nwrite;
319  curl_off_t bytecount = 0;
320  struct_stat file_stat;
321  const char *buf2;
322 
323  /*
324  * Since FILE: doesn't do the full init, we need to provide some extra
325  * assignments here.
326  */
327  conn->data->req.upload_fromhere = buf;
328 
329  if(!dir)
330  return CURLE_FILE_COULDNT_READ_FILE; /* fix: better error code */
331 
332  if(!dir[1])
333  return CURLE_FILE_COULDNT_READ_FILE; /* fix: better error code */
334 
335 #ifdef O_BINARY
336 #define MODE_DEFAULT O_WRONLY|O_CREAT|O_BINARY
337 #else
338 #define MODE_DEFAULT O_WRONLY|O_CREAT
339 #endif
340 
341  if(data->state.resume_from)
342  mode = MODE_DEFAULT|O_APPEND;
343  else
344  mode = MODE_DEFAULT|O_TRUNC;
345 
346  fd = open(file->path, mode, conn->data->set.new_file_perms);
347  if(fd < 0) {
348  failf(data, "Can't open %s for writing", file->path);
349  return CURLE_WRITE_ERROR;
350  }
351 
352  if(-1 != data->state.infilesize)
353  /* known size of data to "upload" */
355 
356  /* treat the negative resume offset value as the case of "-" */
357  if(data->state.resume_from < 0) {
358  if(fstat(fd, &file_stat)) {
359  close(fd);
360  failf(data, "Can't get the size of %s", file->path);
361  return CURLE_WRITE_ERROR;
362  }
363  data->state.resume_from = (curl_off_t)file_stat.st_size;
364  }
365 
366  while(!result) {
367  int readcount;
368  result = Curl_fillreadbuffer(conn, (int)data->set.buffer_size, &readcount);
369  if(result)
370  break;
371 
372  if(readcount <= 0) /* fix questionable compare error. curlvms */
373  break;
374 
375  nread = (size_t)readcount;
376 
377  /*skip bytes before resume point*/
378  if(data->state.resume_from) {
379  if((curl_off_t)nread <= data->state.resume_from) {
380  data->state.resume_from -= nread;
381  nread = 0;
382  buf2 = buf;
383  }
384  else {
385  buf2 = buf + data->state.resume_from;
386  nread -= (size_t)data->state.resume_from;
387  data->state.resume_from = 0;
388  }
389  }
390  else
391  buf2 = buf;
392 
393  /* write the data to the target */
394  nwrite = write(fd, buf2, nread);
395  if(nwrite != nread) {
396  result = CURLE_SEND_ERROR;
397  break;
398  }
399 
400  bytecount += nread;
401 
402  Curl_pgrsSetUploadCounter(data, bytecount);
403 
404  if(Curl_pgrsUpdate(conn))
405  result = CURLE_ABORTED_BY_CALLBACK;
406  else
407  result = Curl_speedcheck(data, Curl_tvnow());
408  }
409  if(!result && Curl_pgrsUpdate(conn))
410  result = CURLE_ABORTED_BY_CALLBACK;
411 
412  close(fd);
413 
414  return result;
415 }
416 
417 /*
418  * file_do() is the protocol-specific function for the do-phase, separated
419  * from the connect-phase above. Other protocols merely setup the transfer in
420  * the do-phase, to have it done in the main transfer loop but since some
421  * platforms we support don't allow select()ing etc on file handles (as
422  * opposed to sockets) we instead perform the whole do-operation in this
423  * function.
424  */
425 static CURLcode file_do(struct connectdata *conn, bool *done)
426 {
427  /* This implementation ignores the host name in conformance with
428  RFC 1738. Only local files (reachable via the standard file system)
429  are supported. This means that files on remotely mounted directories
430  (via NFS, Samba, NT sharing) can be accessed through a file:// URL
431  */
433  struct_stat statbuf; /* struct_stat instead of struct stat just to allow the
434  Windows version to have a different struct without
435  having to redefine the simple word 'stat' */
436  curl_off_t expected_size = 0;
437  bool size_known;
438  bool fstated = FALSE;
439  ssize_t nread;
440  struct Curl_easy *data = conn->data;
441  char *buf = data->state.buffer;
442  curl_off_t bytecount = 0;
443  int fd;
444  struct FILEPROTO *file;
445 
446  *done = TRUE; /* unconditionally */
447 
448  Curl_initinfo(data);
449  Curl_pgrsStartNow(data);
450 
451  if(data->set.upload)
452  return file_upload(conn);
453 
454  file = conn->data->req.protop;
455 
456  /* get the fd from the connection phase */
457  fd = file->fd;
458 
459  /* VMS: This only works reliable for STREAMLF files */
460  if(-1 != fstat(fd, &statbuf)) {
461  /* we could stat it, then read out the size */
462  expected_size = statbuf.st_size;
463  /* and store the modification time */
464  data->info.filetime = (long)statbuf.st_mtime;
465  fstated = TRUE;
466  }
467 
468  if(fstated && !data->state.range && data->set.timecondition) {
469  if(!Curl_meets_timecondition(data, (time_t)data->info.filetime)) {
470  *done = TRUE;
471  return CURLE_OK;
472  }
473  }
474 
475  /* If we have selected NOBODY and HEADER, it means that we only want file
476  information. Which for FILE can't be much more than the file size and
477  date. */
478  if(data->set.opt_no_body && data->set.include_header && fstated) {
479  time_t filetime;
480  struct tm buffer;
481  const struct tm *tm = &buffer;
482  char header[80];
483  snprintf(header, sizeof(header),
484  "Content-Length: %" CURL_FORMAT_CURL_OFF_T "\r\n", expected_size);
485  result = Curl_client_write(conn, CLIENTWRITE_BOTH, header, 0);
486  if(result)
487  return result;
488 
489  result = Curl_client_write(conn, CLIENTWRITE_BOTH,
490  (char *)"Accept-ranges: bytes\r\n", 0);
491  if(result)
492  return result;
493 
494  filetime = (time_t)statbuf.st_mtime;
495  result = Curl_gmtime(filetime, &buffer);
496  if(result)
497  return result;
498 
499  /* format: "Tue, 15 Nov 1994 12:45:26 GMT" */
500  snprintf(header, sizeof(header),
501  "Last-Modified: %s, %02d %s %4d %02d:%02d:%02d GMT\r\n",
502  Curl_wkday[tm->tm_wday?tm->tm_wday-1:6],
503  tm->tm_mday,
504  Curl_month[tm->tm_mon],
505  tm->tm_year + 1900,
506  tm->tm_hour,
507  tm->tm_min,
508  tm->tm_sec);
509  result = Curl_client_write(conn, CLIENTWRITE_BOTH, header, 0);
510  if(!result)
511  /* set the file size to make it available post transfer */
512  Curl_pgrsSetDownloadSize(data, expected_size);
513  return result;
514  }
515 
516  /* Check whether file range has been specified */
517  file_range(conn);
518 
519  /* Adjust the start offset in case we want to get the N last bytes
520  * of the stream iff the filesize could be determined */
521  if(data->state.resume_from < 0) {
522  if(!fstated) {
523  failf(data, "Can't get the size of file.");
524  return CURLE_READ_ERROR;
525  }
526  data->state.resume_from += (curl_off_t)statbuf.st_size;
527  }
528 
529  if(data->state.resume_from <= expected_size)
530  expected_size -= data->state.resume_from;
531  else {
532  failf(data, "failed to resume file:// transfer");
534  }
535 
536  /* A high water mark has been specified so we obey... */
537  if(data->req.maxdownload > 0)
538  expected_size = data->req.maxdownload;
539 
540  if(!fstated || (expected_size == 0))
541  size_known = FALSE;
542  else
543  size_known = TRUE;
544 
545  /* The following is a shortcut implementation of file reading
546  this is both more efficient than the former call to download() and
547  it avoids problems with select() and recv() on file descriptors
548  in Winsock */
549  if(fstated)
550  Curl_pgrsSetDownloadSize(data, expected_size);
551 
552  if(data->state.resume_from) {
553  if(data->state.resume_from !=
554  lseek(fd, data->state.resume_from, SEEK_SET))
556  }
557 
559 
560  while(!result) {
561  /* Don't fill a whole buffer if we want less than all data */
562  size_t bytestoread;
563 
564  if(size_known) {
565  bytestoread = (expected_size < data->set.buffer_size) ?
566  curlx_sotouz(expected_size) : (size_t)data->set.buffer_size;
567  }
568  else
569  bytestoread = data->set.buffer_size-1;
570 
571  nread = read(fd, buf, bytestoread);
572 
573  if(nread > 0)
574  buf[nread] = 0;
575 
576  if(nread <= 0 || (size_known && (expected_size == 0)))
577  break;
578 
579  bytecount += nread;
580  if(size_known)
581  expected_size -= nread;
582 
583  result = Curl_client_write(conn, CLIENTWRITE_BODY, buf, nread);
584  if(result)
585  return result;
586 
587  Curl_pgrsSetDownloadCounter(data, bytecount);
588 
589  if(Curl_pgrsUpdate(conn))
590  result = CURLE_ABORTED_BY_CALLBACK;
591  else
592  result = Curl_speedcheck(data, Curl_tvnow());
593  }
594  if(Curl_pgrsUpdate(conn))
595  result = CURLE_ABORTED_BY_CALLBACK;
596 
597  return result;
598 }
599 
600 #endif
static CURLcode file_done(struct connectdata *conn, CURLcode status, bool premature)
Definition: file.c:267
#define CLIENTWRITE_BOTH
Definition: sendf.h:52
static CURLcode file_disconnect(struct connectdata *conn, bool dead_connection)
Definition: file.c:285
#define CLIENTWRITE_BODY
Definition: sendf.h:50
char * upload_fromhere
Definition: urldata.h:603
#define CURLPROTO_FILE
Definition: curl.h:854
CURLcode Curl_urldecode(struct Curl_easy *data, const char *string, size_t length, char **ostring, size_t *olen, bool reject_ctrl)
Definition: escape.c:146
const char *const Curl_wkday[]
Definition: parsedate.c:87
struct UserDefined set
Definition: urldata.h:1762
void Curl_pgrsSetUploadCounter(struct Curl_easy *data, curl_off_t size)
Definition: progress.c:304
curl_off_t resume_from
Definition: urldata.h:1338
#define MODE_DEFAULT
bool opt_no_body
Definition: urldata.h:1631
void Curl_pgrsTime(struct Curl_easy *data, timerid timer)
Definition: progress.c:162
char * range
Definition: urldata.h:1336
#define PROTOPT_NOURLQUERY
Definition: urldata.h:711
int fd
Definition: file.h:33
long filetime
Definition: urldata.h:1055
bool include_header
Definition: urldata.h:1628
#define failf
Definition: sendf.h:48
const char *const Curl_month[]
Definition: parsedate.c:92
#define DIRSEP
Definition: file.c:305
Definition: file.h:29
UNITTEST_START char * ptr
Definition: unit1330.c:38
CURLcode
Definition: curl.h:454
CURLcode Curl_initinfo(struct Curl_easy *data)
Definition: lib/getinfo.c:45
void Curl_pgrsStartNow(struct Curl_easy *data)
Definition: progress.c:226
UNITTEST_START int result
Definition: unit1304.c:49
char buffer[]
Definition: unit1308.c:48
#define O_BINARY
Definition: tool_operate.c:92
unsigned int i
Definition: unit1303.c:79
static srvr_sockaddr_union_t from
Definition: tftpd.c:197
static CURLcode file_do(struct connectdata *, bool *done)
Definition: file.c:425
int Curl_pgrsUpdate(struct connectdata *conn)
Definition: progress.c:350
#define ZERO_NULL
Definition: curlx.c:131
#define FALSE
char * buffer
Definition: urldata.h:1253
static CURLcode file_range(struct connectdata *conn)
Definition: file.c:133
#define open_readonly(p, f)
Definition: file.c:77
curl_easy_setopt expects a curl_off_t argument for this option curl_easy_setopt expects a curl_write_callback argument for this option curl_easy_setopt expects a curl_ioctl_callback argument for this option curl_easy_setopt expects a curl_opensocket_callback argument for this option curl_easy_setopt expects a curl_debug_callback argument for this option curl_easy_setopt expects a curl_conv_callback argument for this option curl_easy_setopt expects a private data pointer as argument for this option curl_easy_setopt expects a FILE *argument for this option curl_easy_setopt expects a struct curl_httppost *argument for this option curl_easy_setopt expects a struct curl_slist *argument for this option curl_easy_getinfo expects a pointer to char *for this info curl_easy_getinfo expects a pointer to double for this info curl_easy_getinfo expects a pointer to struct curl_tlssessioninfo *for this info curl_easy_getinfo expects a pointer to curl_socket_t for this info size_t
struct SingleRequest req
Definition: urldata.h:1761
long new_file_perms
Definition: urldata.h:1659
curl_off_t infilesize
Definition: urldata.h:1345
static CURLcode file_connect(struct connectdata *conn, bool *done)
Definition: file.c:192
static CURLcode file_setup_connection(struct connectdata *conn)
Definition: file.c:118
CURLofft curlx_strtoofft(const char *str, char **endp, int base, curl_off_t *num)
Definition: strtoofft.c:215
bool use_range
Definition: urldata.h:1333
bool Curl_meets_timecondition(struct Curl_easy *data, time_t timeofdoc)
Definition: transfer.c:393
void Curl_pgrsSetUploadSize(struct Curl_easy *data, curl_off_t size)
Definition: progress.c:334
void Curl_pgrsSetDownloadSize(struct Curl_easy *data, curl_off_t size)
Definition: progress.c:322
#define Curl_tvnow()
Definition: timeval.h:57
CURL_TYPEOF_CURL_OFF_T curl_off_t
Definition: system.h:420
CURLcode Curl_fillreadbuffer(struct connectdata *conn, int bytes, int *nreadp)
Definition: transfer.c:112
char * path
Definition: urldata.h:1329
Definition: curl.h:455
CURLcode Curl_speedcheck(struct Curl_easy *data, struct curltime now)
Definition: speedcheck.c:39
void * protop
Definition: urldata.h:614
CURLofft
Definition: strtoofft.h:51
CURLcode Curl_client_write(struct connectdata *conn, int type, char *ptr, size_t len)
Definition: sendf.c:624
#define Curl_safefree(ptr)
Definition: memdebug.h:170
#define PROTOPT_NONETWORK
Definition: urldata.h:708
#define ISSPACE(x)
struct UrlState state
Definition: urldata.h:1769
char * freepath
Definition: file.h:31
struct PureInfo info
Definition: urldata.h:1772
#define ssize_t
Definition: config-win32.h:382
const struct Curl_handler Curl_handler_file
Definition: file.c:96
void Curl_pgrsSetDownloadCounter(struct Curl_easy *data, curl_off_t size)
Definition: progress.c:286
CURLcode Curl_gmtime(time_t intime, struct tm *store)
Definition: parsedate.c:570
curl_TimeCond timecondition
Definition: urldata.h:1580
static CURLcode file_upload(struct connectdata *conn)
Definition: file.c:308
#define CURL_OFF_T_MAX
Definition: strtoofft.h:47
char buf[3]
Definition: unit1398.c:32
#define infof
Definition: sendf.h:44
#define snprintf
Definition: curl_printf.h:42
#define TRUE
size_t curlx_sotouz(curl_off_t sonum)
Definition: warnless.c:347
long buffer_size
Definition: urldata.h:1591
bool upload
Definition: urldata.h:1632
Definition: debug.c:29
#define calloc(nbelem, size)
Definition: curl_memory.h:126
#define struct_stat
Definition: curl_setup.h:385
curl_off_t maxdownload
Definition: urldata.h:522
char * path
Definition: file.h:30
#define CURL_FORMAT_CURL_OFF_T
Definition: system.h:373
#define DEBUGF(x)
struct Curl_easy * data
Definition: urldata.h:791


rc_tagdetect_client
Author(s): Monika Florek-Jasinska , Raphael Schaller
autogenerated on Sat Feb 13 2021 03:42:09