Newer
Older
/*****************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
Daniel Stenberg
committed
* Copyright (C) 2001, Daniel Stenberg, <daniel@haxx.se>, et al.
* In order to be useful for every potential user, curl and libcurl are
* dual-licensed under the MPL and the MIT/X-derivate licenses.
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the MPL or the MIT/X-derivate
* licenses. You may pick one of these licenses.
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
* $Id$
*****************************************************************************/
/* This is now designed to have its own local setup.h */
#include "setup.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <sys/stat.h>
#include <ctype.h>
#include <curl/curl.h>
#define _MPRINTF_REPLACE /* we want curl-functions instead of native ones */
#if defined(WIN32)&&!defined(__CYGWIN32__)
#include "version.h"
#ifdef HAVE_IO_H /* typical win32 habit */
#include <io.h>
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef HAVE_FCNTL_H
#include <fcntl.h>
#endif
#ifdef HAVE_UTIME_H
Daniel Stenberg
committed
#include <utime.h>
Daniel Stenberg
committed
#ifdef HAVE_SYS_UTIME_H
#include <sys/utime.h>
#endif
#endif
/* The last #include file should be: */
#ifdef MALLOCDEBUG
/* this is low-level hard-hacking memory leak tracking shit */
#include "../lib/memdebug.h"
#endif
#define DEFAULT_MAXREDIRS 50L
#define CURL_PROGRESS_STATS 0 /* default progress display */
#define CURL_PROGRESS_BAR 1
Daniel Stenberg
committed
typedef enum {
HTTPREQ_UNSPEC,
HTTPREQ_GET,
HTTPREQ_HEAD,
HTTPREQ_POST,
HTTPREQ_SIMPLEPOST,
HTTPREQ_CUSTOM,
HTTPREQ_LAST
} HttpReq;
/* Just a set of bits */
#define CONF_DEFAULT 0
#define CONF_AUTO_REFERER (1<<4) /* the automatic referer-system please! */
#define CONF_VERBOSE (1<<5) /* talk a lot */
#define CONF_HEADER (1<<8) /* throw the header out too */
#define CONF_NOPROGRESS (1<<10) /* shut off the progress meter */
#define CONF_NOBODY (1<<11) /* use HEAD to get http document */
#define CONF_FAILONERROR (1<<12) /* no output on http error codes >= 300 */
#define CONF_UPLOAD (1<<14) /* this is an upload */
#define CONF_FTPLISTONLY (1<<16) /* Use NLST when listing ftp dir */
#define CONF_FTPAPPEND (1<<20) /* Append instead of overwrite on upload! */
#define CONF_NETRC (1<<22) /* read user+password from .netrc */
#define CONF_FOLLOWLOCATION (1<<23) /* use Location: Luke! */
#define CONF_GETTEXT (1<<24) /* use ASCII/text for transfer */
#define CONF_HTTPPOST (1<<25) /* multipart/form-data HTTP POST */
#define CONF_MUTE (1<<28) /* force NOPROGRESS */
#ifndef HAVE_STRDUP
/* Ultrix doesn't have strdup(), so make a quick clone: */
char *strdup(char *str)
{
int len;
char *newstr;
len = strlen(str);
newstr = (char *) malloc((len+1)*sizeof(char));
if (!newstr)
return (char *)NULL;
strcpy(newstr,str);
return newstr;
}
#endif
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
#ifdef VMS
int vms_show = 0;
#define FAC_CURL 0xC01
#define FAC_SYSTEM 0
#define MSG_NORMAL 0
#define VMS_STS(c,f,e,s) (((c&0xF)<<28)|((f&0xFFF)<<16)|((e&0x1FFF)<3)|(s&7))
#define VMSSTS_HIDE VMS_STS(1,0,0,0)
#define SEV_WARNING 0
#define SEV_SUCCESS 1
#define SEV_ERROR 2
#define SEV_INFO 3 /* success, with an extra hint */
#define SEV_FATAL 4
globalvalue int CURL_UNSUPPROTO; /* these are from curlmsg.msg file..... */
globalvalue int CURL_FAILINIT;
globalvalue int CURL_BADURLSYN;
globalvalue int CURL_BADURLUSER;
globalvalue int CURL_BADPROXY;
globalvalue int CURL_BADHOST;
globalvalue int CURL_FAILHOST;
globalvalue int CURL_FTPUNKREPLY;
globalvalue int CURL_FTPNOACC;
globalvalue int CURL_FTPUSRPW;
globalvalue int CURL_FTPBADPASS;
globalvalue int CURL_FTPBADUSER;
globalvalue int CURL_FTPBADPASV;
globalvalue int CURL_FTPBAD227;
globalvalue int CURL_FTPBADHOST227;
globalvalue int CURL_FTPNORECONN;
globalvalue int CURL_FTPNOBIN;
globalvalue int CURL_PARTIALFILE;
globalvalue int CURL_FTPNORETR;
globalvalue int CURL_FTPWRITERR;
globalvalue int CURL_FTPNOQUOTE;
globalvalue int CURL_HTTPPNF;
globalvalue int CURL_WRITERR;
globalvalue int CURL_BADUSER;
globalvalue int CURL_FTPNOSTOR;
globalvalue int CURL_READERR;
globalvalue int CURL_OUTOFMEM;
globalvalue int CURL_TIMEOUT;
globalvalue int CURL_FTPNOASCII;
globalvalue int CURL_FTPNOPORT;
globalvalue int CURL_FTPNOREST;
globalvalue int CURL_FTPNOSIZE;
globalvalue int CURL_HTTPRNGERR;
globalvalue int CURL_HTTPPOSTERR;
globalvalue int CURL_SSLNOCONN;
globalvalue int CURL_FTPBADRESUME;
globalvalue int CURL_FILENOACC;
globalvalue int CURL_LDAPNOBIND;
globalvalue int CURL_LDAPNOSRCH;
globalvalue int CURL_LDAPNOLIB;
globalvalue int CURL_LDAPNOFUNC;
globalvalue int CURL_ABORTCB;
globalvalue int CURL_BADPARAM;
globalvalue int CURL_BADORDER;
globalvalue int CURL_BADPWD;
globalvalue int CURL_MNYREDIR;
long vms_cond[] = {
VMS_STS(1,FAC_SYSTEM,MSG_NORMAL,SEV_SUCCESS),
CURL_UNSUPPROTO, /* these are from curlmsg.msg file..... */
CURL_FAILINIT,
CURL_BADURLSYN,
CURL_BADURLUSER,
CURL_BADPROXY,
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
CURL_BADHOST,
CURL_FAILHOST,
CURL_FTPUNKREPLY,
CURL_FTPNOACC,
CURL_FTPUSRPW,
CURL_FTPBADPASS,
CURL_FTPBADUSER,
CURL_FTPBADPASV,
CURL_FTPBAD227,
CURL_FTPBADHOST227,
CURL_FTPNORECONN,
CURL_FTPNOBIN,
CURL_PARTIALFILE,
CURL_FTPNORETR,
CURL_FTPWRITERR,
CURL_FTPNOQUOTE,
CURL_HTTPPNF,
CURL_WRITERR,
CURL_BADUSER,
CURL_FTPNOSTOR,
CURL_READERR,
CURL_OUTOFMEM,
CURL_TIMEOUT,
CURL_FTPNOASCII,
CURL_FTPNOPORT,
CURL_FTPNOREST,
CURL_FTPNOSIZE,
CURL_HTTPRNGERR,
CURL_HTTPPOSTERR,
CURL_SSLNOCONN,
CURL_FTPBADRESUME,
CURL_FILENOACC,
CURL_LDAPNOBIND,
CURL_LDAPNOSRCH,
CURL_LDAPNOLIB,
CURL_LDAPNOFUNC,
CURL_ABORTCB,
CURL_BADPARAM,
CURL_BADORDER,
CURL_BADPWD,
CURL_MNYREDIR
};
#endif
/*
* This is the main global constructor for the app. Call this before
* _any_ libcurl usage. If this fails, *NO* libcurl functions may be
* used, or havoc may be the result.
*/
return curl_global_init(CURL_GLOBAL_DEFAULT);
}
/*
* This is the main global destructor for the app. Call this after
* _all_ libcurl usage is done.
*/
void main_free(void)
{
Daniel Stenberg
committed
curl_global_cleanup();
Daniel Stenberg
committed
int SetHTTPrequest(HttpReq req, HttpReq *store)
{
if((*store == HTTPREQ_UNSPEC) ||
(*store == req)) {
*store = req;
return 0;
Daniel Stenberg
committed
}
fprintf(stderr, "You can only select one HTTP request!\n");
return 1;
Daniel Stenberg
committed
}
{
va_list ap;
if(fmt) {
va_start(ap, fmt);
fputs("curl: ", stderr); /* prefix it */
vfprintf(stderr, fmt, ap);
va_end(ap);
}
fprintf(stderr, "curl: try 'curl --help' for more information\n");
}
/*
* A chain of these nodes contain URL to get and where to put the URL's
* contents.
*/
struct getout {
struct getout *next;
char *url;
char *outfile;
int flags;
};
#define GETOUT_OUTFILE (1<<0) /* set when outfile is deemed done */
#define GETOUT_URL (1<<1) /* set when URL is deemed done */
#define GETOUT_USEREMOTE (1<<2) /* use remote file name locally */
static void help(void)
{
printf(CURL_ID "%s\n"
"Usage: curl [options...] <url>\n"
"Options: (H) means HTTP/HTTPS only, (F) means FTP only\n"
" -a/--append Append to target file when uploading (F)\n"
" -A/--user-agent <string> User-Agent to send to server (H)\n"
" -b/--cookie <name=string/file> Cookie string or file to read cookies from (H)\n"
" -B/--use-ascii Use ASCII/text transfer\n",
curl_version());
puts(" -c/--cookie-jar <file> Write all cookies to this file after operation (H)\n"
" -C/--continue-at <offset> Specify absolute resume offset\n"
" -d/--data <data> HTTP POST data (H)\n"
" --data-ascii <data> HTTP POST ASCII data (H)\n"
" --data-binary <data> HTTP POST binary data (H)\n"
" -D/--dump-header <file> Write the headers to this file\n"
" --egd-file <file> EGD socket path for random data (SSL)\n"
" -e/--referer Referer page (H)");
puts(" -E/--cert <cert[:passwd]> Specifies your certificate file and password (HTTPS)\n"
" --cert-type <type> Specifies your certificate file type (DER/PEM/ENG) (HTTPS)\n"
" --key <key> Specifies your private key file (HTTPS)\n"
" --key-type <type> Specifies your private key file type (DER/PEM/ENG) (HTTPS)\n"
" --pass <pass> Specifies your passphrase for the private key (HTTPS)");
puts(" --engine <eng> Specifies the crypto engine to use (HTTPS)\n"
" --cacert <file> CA certifciate to verify peer against (SSL)\n"
" --ciphers <list> What SSL ciphers to use (SSL)\n"
" --connect-timeout <seconds> Maximum time allowed for connection\n"
" -f/--fail Fail silently (no output at all) on errors (H)\n"
" -F/--form <name=content> Specify HTTP POST data (H)\n"
Daniel Stenberg
committed
" -g/--globoff Disable URL sequences and ranges using {} and []\n"
" -G/--get Send the -d data with a HTTP GET (H)");
puts(" -h/--help This help text\n"
" -H/--header <line> Custom header to pass to server. (H)\n"
" -i/--include Include the HTTP-header in the output (H)\n"
" -I/--head Fetch document info only (HTTP HEAD/FTP SIZE)\n"
" --interface <interface> Specify the interface to be used\n"
" --krb4 <level> Enable krb4 with specified security level (F)\n"
" -l/--list-only List only names of an FTP directory (F)");
puts(" -L/--location Follow Location: hints (H)\n"
" -m/--max-time <seconds> Maximum time allowed for the transfer\n"
" -M/--manual Display huge help text\n"
" -n/--netrc Read .netrc for user name and password\n"
" -N/--no-buffer Disables the buffering of the output stream");
puts(" -o/--output <file> Write output to <file> instead of stdout\n"
" -O/--remote-name Write output to a file named as the remote file\n"
" -p/--proxytunnel Perform non-HTTP services through a HTTP proxy\n"
" -P/--ftpport <address> Use PORT with address instead of PASV when ftping (F)\n"
" -q When used as the first parameter disables .curlrc\n"
" -Q/--quote <cmd> Send QUOTE command to FTP before file transfer (F)");
puts(" -r/--range <range> Retrieve a byte range from a HTTP/1.1 or FTP server\n"
" -R/--remote-time Set the remote file's time on the local output\n"
" -s/--silent Silent mode. Don't output anything\n"
" -S/--show-error Show error. With -s, make curl show errors when they occur\n"
" --stderr <file> Where to redirect stderr. - means stdout.\n"
" -t/--telnet-option <OPT=val> Set telnet option\n"
" -T/--upload-file <file> Transfer/upload <file> to remote site\n"
" --url <URL> Another way to specify URL to work with");
puts(" -u/--user <user[:password]> Specify user and password to use\n"
Daniel Stenberg
committed
" -U/--proxy-user <user[:password]> Specify Proxy authentication\n"
" -v/--verbose Makes the operation more talkative\n"
" -V/--version Outputs version number then quits\n"
Daniel Stenberg
committed
" -w/--write-out [format] What to output after completion\n"
" -x/--proxy <host[:port]> Use proxy. (Default port is 1080)\n"
" --random-file <file> File to use for reading random data from (SSL)\n"
" -X/--request <command> Specific request command to use");
puts(" -y/--speed-time Time needed to trig speed-limit abort. Defaults to 30\n"
" -Y/--speed-limit Stop transfer if below speed-limit for 'speed-time' secs\n"
" -z/--time-cond <time> Includes a time condition to the server (H)\n"
" -Z/--max-redirs <num> Set maximum number of redirections allowed (H)\n"
" -0/--http1.0 Force usage of HTTP 1.0 (H)\n"
" -1/--tlsv1 Force usage of TLSv1 (H)\n"
" -3/--sslv3 Force usage of SSLv3 (H)");
puts(" -#/--progress-bar Display transfer progress as a progress bar\n"
" --crlf Convert LF to CRLF in upload. Useful for MVS (OS/390)");
const char *letter;
const char *lname;
bool extraparam;
};
struct Configurable {
bool remote_time;
char *random_file;
char *egd_file;
char *cookie; /* single line with specified cookies */
char *cookiejar; /* write to this file */
char *cookiefile; /* read from this file */
Daniel Stenberg
committed
bool resume_from_current;
unsigned short porttouse;
char *range;
int low_speed_limit;
int low_speed_time;
bool showerror;
char *infile;
char *userpwd;
char *proxyuserpwd;
char *proxy;
bool configread;
struct getout *url_list; /* point to the first node */
struct getout *url_last; /* point to the last/current node */
struct getout *url_get; /* point to the node to fill in URL */
struct getout *url_out; /* point to the node to fill in outfile */
char *key;
char *key_type;
char *key_passwd;
char *engine;
bool nobuffer;
Daniel Stenberg
committed
bool globoff;
Daniel Stenberg
committed
bool use_httpget;
Daniel Stenberg
committed
char *writeout; /* %-styled format string to output */
FILE *errors; /* if stderr redirect is requested */
struct curl_slist *quote;
curl_TimeCond timecond;
struct curl_slist *headers;
struct HttpPost *httppost;
struct HttpPost *last_post;
Daniel Stenberg
committed
struct curl_slist *telnet_options;
Daniel Stenberg
committed
HttpReq httpreq;
};
static int parseconfig(char *filename,
struct Configurable *config);
Daniel Stenberg
committed
static char *my_get_line(FILE *fp);
static void GetStr(char **string,
char *value)
{
if(*string)
free(*string);
if(value && *value)
*string = strdup(value);
else
*string = NULL;
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
}
static char *file2string(FILE *file)
{
char buffer[256];
char *ptr;
char *string=NULL;
int len=0;
int stringlen;
if(file) {
while(fgets(buffer, sizeof(buffer), file)) {
ptr= strchr(buffer, '\r');
if(ptr)
*ptr=0;
ptr= strchr(buffer, '\n');
if(ptr)
*ptr=0;
stringlen=strlen(buffer);
if(string)
string = realloc(string, len+stringlen+1);
else
string = malloc(stringlen+1);
strcpy(string+len, buffer);
len+=stringlen;
}
return string;
}
else
return NULL; /* no string */
}
static char *file2memory(FILE *file, long *size)
{
char buffer[1024];
char *string=NULL;
char *newstring=NULL;
long len=0;
long stringlen=0;
if(file) {
while((len = fread(buffer, 1, sizeof(buffer), file))) {
if(string) {
newstring = realloc(string, len+stringlen);
if(newstring)
string = newstring;
else
break; /* no more strings attached! :-) */
}
else
string = malloc(len);
memcpy(&string[stringlen], buffer, len);
stringlen+=len;
}
*size = stringlen;
return string;
}
else
return NULL; /* no string */
}
Loading
Loading full blame...