Newer
Older
Daniel Stenberg
committed
continue;
}
/* the option keywords starts here */
option = line;
while(*line && !isspace((int)*line) && !isseparator(*line))
line++;
/* ... and has ended here */
*line++=0; /* zero terminate, we have a local copy of the data */
#ifdef DEBUG_CONFIG
fprintf(stderr, "GOT: %s\n", option);
#endif
/* pass spaces and separator(s) */
while(isspace((int)*line) || isseparator(*line))
line++;
/* the parameter starts here (unless quoted) */
if(*line == '\"') {
char *ptr;
/* quoted parameter, do the qoute dance */
line++;
param=strdup(line); /* parameter */
alloced_param=TRUE;
ptr=param;
while(*line && (*line != '\"')) {
if(*line == '\\') {
line++;
/* default is to output the letter after the backslah */
switch(out = *line) {
case '\0':
continue; /* this'll break out of the loop */
case 't':
out='\t';
break;
case 'n':
out='\n';
break;
case 'r':
out='\r';
break;
case 'v':
out='\v';
break;
}
*ptr++=out;
line++;
}
else
*ptr++=*line++;
}
*ptr=0; /* always zero terminate */
else {
param=line; /* parameter starts here */
while(*line && !isspace((int)*line))
line++;
*line=0; /* zero terminate */
#ifdef DEBUG_CONFIG
fprintf(stderr, "PARAM: \"%s\"\n", param);
#endif
res = getparameter(option, param, &usedarg, config);
Daniel Stenberg
committed
if(*param && !usedarg)
/* we passed in a parameter that wasn't used! */
res = PARAM_GOT_EXTRA_PARAMETER;
Daniel Stenberg
committed
if(res != PARAM_OK) {
/* the help request isn't really an error */
if(!strcmp(filename, "-")) {
}
if(PARAM_HELP_REQUESTED != res) {
switch(res) {
default:
case PARAM_GOT_EXTRA_PARAMETER:
reason = "had unsupported trailing garbage";
break;
case PARAM_OPTION_UNKNOWN:
reason = "is unknown";
break;
case PARAM_OPTION_AMBIGUOUS:
reason = "is ambiguous";
break;
case PARAM_REQUIRES_PARAMETER:
reason = "requires parameter";
break;
case PARAM_BAD_USE:
reason = "is badly used here";
Daniel Stenberg
committed
break;
}
fprintf(stderr, "%s:%d: warning: '%s' %s\n",
filename, lineno, option, reason);
Daniel Stenberg
committed
}
Daniel Stenberg
committed
}
if(alloced_param)
free(param);
free(aline);
return 0;
#ifdef HAVE_POLL
/* portable subsecond "sleep" */
poll((void *)0, 0, ms);
#else
/* systems without poll() need other solutions */
#ifdef WIN32
/* Windows offers a millisecond sleep */
Sleep(ms);
#else
/* Other systems must use select() for this */
struct timeval timeout;
timeout.tv_sec = 0;
timeout.tv_usec = ms * 1000;
select(0, NULL, NULL, NULL, &timeout);
#endif
#endif
struct OutStruct {
char *filename;
FILE *stream;
struct Configurable *config;
int my_fwrite(void *buffer, size_t size, size_t nmemb, void *stream)
Daniel Stenberg
committed
int rc;
if(out && !out->stream) {
/* open file for writing */
out->stream=fopen(out->filename, "wb");
if(!out->stream)
return -1; /* failure */
}
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
if(config->recvpersecond) {
/*
* We know when we received data the previous time. We know how much data
* we get now. Make sure that this is not faster than we are told to run.
* If we're faster, sleep a while *before* doing the fwrite() here.
*/
time_t timediff;
time_t now;
now = time(NULL);
timediff = now - config->lastrecvtime;
if( size*nmemb > config->recvpersecond*timediff) {
/* figure out how many milliseconds to rest */
go_sleep ( (size*nmemb)*1000/config->recvpersecond - timediff*1000 );
now = time(NULL);
}
config->lastrecvtime = now;
}
Daniel Stenberg
committed
rc = fwrite(buffer, size, nmemb, out->stream);
if(config->nobuffer)
/* disable output buffering */
fflush(out->stream);
return rc;
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
struct InStruct {
FILE *stream;
struct Configurable *config;
};
int my_fread(void *buffer, size_t size, size_t nmemb, void *userp)
{
struct InStruct *in=(struct InStruct *)userp;
struct Configurable *config = in->config;
if(config->sendpersecond) {
/*
* We know when we sent data the previous time. We know how much data
* we sent. Make sure that this was not faster than we are told to run.
* If we're faster, sleep a while *before* doing the fread() here.
* Also, make no larger fread() than should be sent this second!
*/
time_t timediff;
time_t now;
now = time(NULL);
timediff = now - config->lastsendtime;
if( config->lastsendsize > config->sendpersecond*timediff) {
/* figure out how many milliseconds to rest */
go_sleep ( config->lastsendsize*1000/config->sendpersecond -
timediff*1000 );
now = time(NULL);
}
config->lastsendtime = now;
if(size*nmemb > config->sendpersecond) {
/* lower the size to actually read */
nmemb = config->sendpersecond;
size = 1;
}
config->lastsendsize = size*nmemb;
}
return fread(buffer, size, nmemb, in->stream);
}
struct ProgressData {
Daniel Stenberg
committed
int calls;
double prev;
int width;
FILE *out; /* where to write everything to */
int initial_size;
};
int myprogress (void *clientp,
Daniel Stenberg
committed
double dltotal,
double dlnow,
double ultotal,
double ulnow)
{
/* The original progress-bar source code was written for curl by Lars Aas,
and this new edition inherites some of his concepts. */
char line[256];
char outline[256];
char format[40];
double frac;
double percent;
int barwidth;
int num;
int i;
struct ProgressData *bar = (struct ProgressData *)clientp;
double total = dltotal + ultotal + bar->initial_size;
double point = dlnow + ulnow + bar->initial_size; /* we've come this far */
Daniel Stenberg
committed
bar->calls++; /* simply count invokes */
if(0 == total) {
int prevblock = (int)bar->prev / 1024;
int thisblock = (int)point / 1024;
while ( thisblock > prevblock ) {
fprintf( bar->out, "#" );
prevblock++;
}
}
else {
frac = point / total;
percent = frac * 100.0f;
barwidth = bar->width - 7;
num = (int) (((double)barwidth) * frac);
i = 0;
for ( i = 0; i < num; i++ ) {
line[i] = '#';
}
line[i] = '\0';
sprintf( format, "%%-%ds %%5.1f%%%%", barwidth );
sprintf( outline, format, line, percent );
fprintf( bar->out, "\r%s", outline );
}
bar->prev = point;
return 0;
}
static
void progressbarinit(struct ProgressData *bar,
struct Configurable *config)
{
#ifdef __EMX__
/* 20000318 mgs */
int scr_size [2];
#endif
char *colp;
memset(bar, 0, sizeof(struct ProgressData));
/* pass this through to progress function so
* it can display progress towards total file
* not just the part that's left. (21-may-03, dbyron) */
if (config->use_resume)
bar->initial_size = config->resume_from;
/* TODO: get terminal width through ansi escapes or something similar.
try to update width when xterm is resized... - 19990617 larsa */
#ifndef __EMX__
/* 20000318 mgs
* OS/2 users most likely won't have this env var set, and besides that
* we're using our own way to determine screen width */
colp = curl_getenv("COLUMNS");
if (colp != NULL) {
bar->width = atoi(colp);
}
else
bar->width = 79;
#else
/* 20000318 mgs
* We use this emx library call to get the screen width, and subtract
* one from what we got in order to avoid a problem with the cursor
* advancing to the next line if we print a string that is as long as
* the screen is wide. */
_scrsize(scr_size);
bar->width = scr_size[0] - 1;
#endif
bar->out = config->errors;
}
Daniel Stenberg
committed
static
void dump(const char *text,
FILE *stream, unsigned char *ptr, size_t size,
bool nohex)
Daniel Stenberg
committed
{
size_t i;
size_t c;
unsigned int width=0x10;
if(nohex)
/* without the hex output, we can fit more on screen */
width = 0x40;
Daniel Stenberg
committed
fprintf(stream, "%s, %d bytes (0x%x)\n", text, size, size);
Daniel Stenberg
committed
Daniel Stenberg
committed
fprintf(stream, "%04x: ", i);
if(!nohex) {
/* hex not disabled, show it */
for(c = 0; c < width; c++)
if(i+c < size)
fprintf(stream, "%02x ", ptr[i+c]);
else
fputs(" ", stream);
}
for(c = 0; (c < width) && (i+c < size); c++) {
/* check for 0D0A; if found, skip past and start a new line of output */
if (nohex && (i+c+1 < size) && ptr[i+c]==0x0D && ptr[i+c+1]==0x0A) {
i+=(c+2-width);
break;
}
Daniel Stenberg
committed
fprintf(stream, "%c",
(ptr[i+c]>=0x20) && (ptr[i+c]<0x80)?ptr[i+c]:'.');
/* check again for 0D0A, to avoid an extra \n if it's at width */
if (nohex && (i+c+2 < size) && ptr[i+c+1]==0x0D && ptr[i+c+2]==0x0A) {
i+=(c+3-width);
break;
}
}
Daniel Stenberg
committed
fputc('\n', stream); /* newline */
}
Daniel Stenberg
committed
}
static
int my_trace(CURL *handle, curl_infotype type,
unsigned char *data, size_t size,
void *userp)
{
struct Configurable *config = (struct Configurable *)userp;
FILE *output=config->errors;
Daniel Stenberg
committed
(void)handle; /* prevent compiler warning */
if(!config->trace_stream) {
Daniel Stenberg
committed
/* open for append */
Daniel Stenberg
committed
if(curl_strequal("-", config->trace_dump))
config->trace_stream = stdout;
else {
config->trace_stream = fopen(config->trace_dump, "w");
config->trace_fopened = TRUE;
}
}
Daniel Stenberg
committed
if(config->trace_stream)
output = config->trace_stream;
switch (type) {
case CURLINFO_TEXT:
fprintf(output, "== Info: %s", data);
default: /* in case a new one is introduced to shock us */
return 0;
Daniel Stenberg
committed
case CURLINFO_HEADER_OUT:
Daniel Stenberg
committed
break;
case CURLINFO_DATA_OUT:
text = "=> Send data";
Daniel Stenberg
committed
break;
case CURLINFO_HEADER_IN:
Daniel Stenberg
committed
break;
case CURLINFO_DATA_IN:
Daniel Stenberg
committed
break;
}
dump(text, output, data, size, config->trace_ascii);
Daniel Stenberg
committed
return 0;
}
void free_config_fields(struct Configurable *config)
{
if(config->random_file)
free(config->random_file);
if(config->egd_file)
free(config->egd_file);
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
if(config->userpwd)
free(config->userpwd);
if(config->postfields)
free(config->postfields);
if(config->proxy)
free(config->proxy);
if(config->proxyuserpwd)
free(config->proxyuserpwd);
if(config->cookie)
free(config->cookie);
if(config->cookiefile)
free(config->cookiefile);
if(config->krb4level)
free(config->krb4level);
if(config->headerfile)
free(config->headerfile);
if(config->ftpport)
free(config->ftpport);
if(config->range)
free(config->range);
if(config->customrequest)
free(config->customrequest);
if(config->writeout)
free(config->writeout);
if(config->httppost)
curl_formfree(config->httppost);
if(config->cacert)
free(config->cacert);
if(config->capath)
free(config->capath);
if(config->cookiejar)
free(config->cookiejar);
curl_slist_free_all(config->quote); /* checks for config->quote == NULL */
curl_slist_free_all(config->postquote); /* */
curl_slist_free_all(config->headers); /* */
}
Daniel Stenberg
committed
#if defined(WIN32) && !defined(__CYGWIN32__)
/* Function to find CACert bundle on a Win32 platform using SearchPath.
* (SearchPath is defined in windows.h, which is #included into libcurl)
* (Use the ASCII version instead of the unicode one!)
* The order of the directories it searches is:
* 1. application's directory
* 2. current working directory
* 3. Windows System directory (e.g. C:\windows\system32)
* 4. Windows Directory (e.g. C:\windows)
* 5. all directories along %PATH%
*/
static void FindWin32CACert(struct Configurable *config,
const char *bundle_file)
{
/* only check for cert file if "we" support SSL */
if(curlinfo->features & CURL_VERSION_SSL) {
Daniel Stenberg
committed
DWORD buflen;
char *ptr = NULL;
char *retval = (char *) malloc(sizeof (TCHAR) * (MAX_PATH + 1));
if (!retval)
return;
retval[0] = '\0';
buflen = SearchPathA(NULL, bundle_file, NULL, MAX_PATH+2, retval, &ptr);
if (buflen > 0) {
GetStr(&config->cacert, retval);
}
free(retval);
}
}
#endif
static int
operate(struct Configurable *config, int argc, char *argv[])
char errorbuffer[CURL_ERROR_SIZE];
char useragent[128]; /* buah, we don't want a larger default user agent */
struct ProgressData progressbar;
struct getout *urlnode;
struct getout *nextnode;
Daniel Stenberg
committed
struct OutStruct heads;
Daniel Stenberg
committed
URLGlob *urls=NULL;
URLGlob *inglob=NULL;
int infilenum;
char *infiles; /* might a glob pattern */
char *uploadfile=NULL; /* a single file, never a glob */
FILE *infd;
bool infdfopen;
FILE *headerfilep = NULL;
char *urlbuffer=NULL;
long uploadfilesize; /* -1 means unknown */
Daniel Stenberg
committed
char *httpgetfields=NULL;
int res = 0;
int up; /* upload file counter within a single upload glob */
Daniel Stenberg
committed
char *env;
/* this sends all memory debug messages to a logfile named memdump */
env = curl_getenv("CURL_MEMDEBUG");
if(env) {
curl_memdebug("memdump");
}
env = curl_getenv("CURL_MEMLIMIT");
if(env) {
curl_memlimit(atoi(env));
curl_free(env);
}
/* we get libcurl info right away */
curlinfo = curl_version_info(CURLVERSION_NOW);
errorbuffer[0]=0; /* prevent junk from being output */
Daniel Stenberg
committed
main_init(); /* inits */
config->showerror=TRUE;
config->conf=CONF_DEFAULT;
Daniel Stenberg
committed
config->use_httpget=FALSE;
config->create_dirs=FALSE;
Daniel Stenberg
committed
(!curl_strnequal("--", argv[1], 2) && (argv[1][0] == '-')) &&
strchr(argv[1], 'q')) {
/*
* The first flag, that is not a verbose name, but a shortname
* and it includes the 'q' flag!
*/
;
}
else {
res = parseconfig(NULL, config);
}
/* Parse options */
for (i = 1; i < argc; i++) {
if(stillflags &&
('-' == argv[i][0])) {
char *nextarg;
bool passarg;
char *origopt=argv[i];
char *flag = argv[i];
Daniel Stenberg
committed
if(curl_strequal("--", argv[i]))
/* this indicates the end of the flags and thus enables the
following (URL) argument to start with -. */
stillflags=FALSE;
else {
nextarg= (i < argc - 1)? argv[i+1]: NULL;
res = getparameter(flag, nextarg, &passarg, config);
if(res) {
switch(res) {
case PARAM_OPTION_AMBIGUOUS:
helpf("option %s is ambiguous\n", origopt);
break;
case PARAM_OPTION_UNKNOWN:
helpf("option %s is unknown\n", origopt);
break;
case PARAM_REQUIRES_PARAMETER:
helpf("option %s requires an extra argument!\n", origopt);
break;
case PARAM_BAD_USE:
helpf("option %s was wrongly used!\n", origopt);
break;
case PARAM_HELP_REQUESTED:
/* no text */
break;
}
return CURLE_FAILED_INIT;
}
if(passarg) /* we're supposed to skip this */
i++;
}
}
else {
bool used;
/* just add the URL please */
res = getparameter((char *)"--url", argv[i], &used, config);
if(!config->url_list || !config->url_list->url) {
if(NULL == config->useragent) {
/* set non-zero default values: */
snprintf(useragent, sizeof(useragent),
CURL_NAME "/" CURL_VERSION " (" OS ") " "%s", curl_version());
config->useragent= useragent;
Daniel Stenberg
committed
/* On WIN32 (non-cygwin), we can't set the path to curl-ca-bundle.crt
* at compile time. So we look here for the file in two ways:
* 1: look at the environment variable CURL_CA_BUNDLE for a path
* 2: if #1 isn't found, use the windows API function SearchPath()
* to find it along the app's path (includes app's dir and CWD)
*
* We support the environment variable thing for non-Windows platforms
* too. Just for the sake of it.
*/
if (!config->cacert &&
!config->capath &&
!config->insecure_ok) {
Daniel Stenberg
committed
env = curl_getenv("CURL_CA_BUNDLE");
if(env) {
GetStr(&config->cacert, env);
Daniel Stenberg
committed
}
#if defined(WIN32) && !defined(__CYGWIN32__)
else
FindWin32CACert(config, "curl-ca-bundle.crt");
Daniel Stenberg
committed
#endif
Daniel Stenberg
committed
Daniel Stenberg
committed
if (config->postfields) {
if (config->use_httpget) {
/* Use the postfields data for a http get */
httpgetfields = strdup(config->postfields);
free(config->postfields);
config->postfields = NULL;
if(SetHTTPrequest((config->conf&CONF_NOBODY?HTTPREQ_HEAD:HTTPREQ_GET),
&config->httpreq)) {
Daniel Stenberg
committed
free(httpgetfields);
return PARAM_BAD_USE;
}
}
else {
if(SetHTTPrequest(HTTPREQ_SIMPLEPOST, &config->httpreq))
return PARAM_BAD_USE;
}
}
/*
* Get a curl handle to use for all forthcoming curl transfers. Cleanup
* when all transfers are done.
*/
curl = curl_easy_init();
if(!curl)
return CURLE_FAILED_INIT;
/* After this point, we should call curl_easy_cleanup() if we decide to bail
* out from this function! */
Daniel Stenberg
committed
Daniel Stenberg
committed
if(config->headerfile) {
/* open file for output: */
if(strcmp(config->headerfile,"-")) {
heads.filename = config->headerfile;
headerfilep=NULL;
}
else
headerfilep=stdout;
heads.stream = headerfilep;
heads.config = config;
}
while(urlnode && !res) {
char *dourl;
/* get the full URL (it might be NULL) */
dourl=urlnode->url;
url = dourl;
if(NULL == url) {
/* This node had no URL, skip it and continue to the next */
if(urlnode->outfile)
free(urlnode->outfile);
/* move on to the next URL */
nextnode=urlnode->next;
free(urlnode); /* free the node */
urlnode = nextnode;
continue; /* next please */
}
/* default output stream is stdout */
outs.stream = stdout;
outs.config = config;
Daniel Stenberg
committed
/* save outfile pattern before expansion */
outfiles = urlnode->outfile?strdup(urlnode->outfile):NULL;
infiles = urlnode->infile;
if(!config->globoff && infiles) {
/* Unless explicitly shut off */
res = glob_url(&inglob, infiles, &infilenum,
config->showerror?
(config->errors?config->errors:stderr):NULL);
if(res != CURLE_OK) {
clean_getout(config);
break;
}
Daniel Stenberg
committed
}
/* Here's the loop for uploading multiple files within the same
single globbed string. If no upload, we enter the loop once anyway. */
for(up = 0;
(!up && !infiles) ||
(uploadfile = inglob?
glob_next_url(inglob):
(!up?strdup(infiles):NULL));
up++) {
uploadfilesize=-1;
if(!config->globoff) {
/* Unless explicitly shut off, we expand '{...}' and '[...]'
expressions and return total number of URLs in pattern set */
res = glob_url(&urls, dourl, &urlnum,
config->showerror?
(config->errors?config->errors:stderr):NULL);
if(res != CURLE_OK) {
break;
}
}
/* if multiple files extracted to stdout, insert separators! */
separator= ((!outfiles || curl_strequal(outfiles, "-")) && urlnum > 1);
/* Here's looping around each globbed URL */
for(i = 0;
(url = urls?glob_next_url(urls):(i?NULL:strdup(url)));
i++) {
char *outfile;
outfile = outfiles?strdup(outfiles):NULL;
if((urlnode->flags&GETOUT_USEREMOTE) ||
(outfile && !curl_strequal("-", outfile)) ) {
/*
* We have specified a file name to store the result in, or we have
* decided we want to use the remote file name.
*/
if(!outfile) {
/* Find and get the remote file name */
char * pc =strstr(url, "://");
if(pc)
pc+=3;
else
pc=url;
pc = strrchr(pc, '/');
if(pc) {
/* duplicate the string beyond the slash */
pc++;
outfile = *pc ? strdup(pc): NULL;
}
if(!outfile || !*outfile) {
helpf("Remote file name has no length!\n");
res = CURLE_WRITE_ERROR;
free(url);
break;
}
#if defined(__DJGPP__)
{
/* This is for DOS, and then we do some major replacing of
bad characters in the file name before using it */
char *file1=xmalloc(PATH_MAX);
strcpy(file1, msdosify(outfile));
strcpy(outfile, rename_if_dos_device_name(file1));
xfree(file1);
}
#endif /* __DJGPP__ */
}
else if(urls) {
/* fill '#1' ... '#9' terms from URL pattern */
char *storefile = outfile;
outfile = glob_match_url(storefile, urls);
free(storefile);
if(!outfile) {
/* bad globbing */
fprintf(stderr, "bad output glob!\n");
free(url);
res = CURLE_FAILED_INIT;
break;
}
}
/* Create the directory hierarchy, if not pre-existant to a multiple
file output call */
Daniel Stenberg
committed
if(config->create_dirs)
if (-1 == create_dir_hierarchy(outfile)) {
return CURLE_WRITE_ERROR;
}
Daniel Stenberg
committed
if(config->resume_from_current) {
/* We're told to continue from where we are now. Get the
size of the file as it is now and open it for append instead */
struct stat fileinfo;
/*VMS?? -- Danger, the filesize is only valid for stream files */
if(0 == stat(outfile, &fileinfo))
/* set offset to current file size: */
config->resume_from = fileinfo.st_size;
else
/* let offset be 0 */
config->resume_from = 0;
}
Daniel Stenberg
committed
if(config->resume_from) {
/* open file for output: */
outs.stream=(FILE *) fopen(outfile, config->resume_from?"ab":"wb");
if (!outs.stream) {
helpf("Can't open '%s'!\n", outfile);
return CURLE_WRITE_ERROR;
}
}
else {
outs.filename = outfile;
outs.stream = NULL; /* open when needed */
infdfopen=FALSE;
if(uploadfile && !curl_strequal(uploadfile, "-")) {
/*
* We have specified a file to upload and it isn't "-".
*/
struct stat fileinfo;
/* If no file name part is given in the URL, we add this file name */
char *ptr=strstr(url, "://");
if(ptr)
ptr+=3;
else
ptr=url;
ptr = strrchr(ptr, '/');
if(!ptr || !strlen(++ptr)) {
/* The URL has no file name part, add the local file name. In order
to be able to do so, we have to create a new URL in another
buffer.*/
/* We only want the part of the local path that is on the right
side of the rightmost slash and backslash. */
char *filep = strrchr(uploadfile, '/');
char *file2 = strrchr(filep?filep:uploadfile, '\\');
if(file2)
filep = file2+1;
else if(filep)
filep++;
else
filep = uploadfile;
/* URL encode the file name */
filep = curl_escape(filep, 0 /* use strlen */);
if(filep) {
urlbuffer=(char *)malloc(strlen(url) + strlen(filep) + 3);
if(!urlbuffer) {
helpf("out of memory\n");
return CURLE_OUT_OF_MEMORY;
}
if(ptr)
/* there is a trailing slash on the URL */
sprintf(urlbuffer, "%s%s", url, filep);
else
/* thers is no trailing slash on the URL */
sprintf(urlbuffer, "%s/%s", url, filep);
curl_free(filep);
free(url);
url = urlbuffer; /* use our new URL instead! */
}
/*VMS??-- Reading binary from files can be a problem... */
/*VMS?? Only FIXED, VAR etc WITHOUT implied CC will work */
/*VMS?? Others need a \n appended to a line */
/*VMS??-- Stat gives a size but this is UNRELIABLE in VMS */
/*VMS?? As a f.e. a fixed file with implied CC needs to have a byte added */
/*VMS?? for every record processed, this can by derived from Filesize & recordsize */
/*VMS?? for VARiable record files the records need to be counted! */
/*VMS?? for every record add 1 for linefeed and subtract 2 for the record header */
/*VMS?? for VARIABLE header files only the bare record data needs to be considered with one appended if implied CC */
infd=(FILE *) fopen(uploadfile, "rb");
if (!infd || stat(uploadfile, &fileinfo)) {
helpf("Can't open '%s'!\n", uploadfile);
return CURLE_READ_ERROR;
}
infdfopen=TRUE;
uploadfilesize=fileinfo.st_size;
}
else if(uploadfile && curl_strequal(uploadfile, "-")) {
infd = stdin;
}
if(uploadfile && config->resume_from_current)
config->resume_from = -1; /* -1 will then force get-it-yourself */
if(outs.stream && isatty(fileno(outs.stream)))
/* we send the output to a tty, therefore we switch off the progress
meter */
config->conf |= CONF_NOPROGRESS;
if (urlnum > 1 && !(config->conf&CONF_MUTE)) {
fprintf(stderr, "\n[%d/%d]: %s --> %s\n",
i+1, urlnum, url, outfile ? outfile : "<stdout>");
if (separator)
printf("%s%s\n", CURLseparator, url);
Daniel Stenberg
committed
}
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
if (httpgetfields) {
/* Find out whether the url contains a file name */
char *pc =strstr(url, "://");
char separator='?';
if(pc)
pc+=3;
else
pc=url;
pc = strrchr(pc, '/'); /* check for a slash */
if(pc) {
/* there is a slash present in the URL */
if(strchr(pc, '?'))
/* Ouch, there's already a question mark in the URL string, we
then appead the data with an amperand separator instead! */
separator='&';
}
/*
* Then append ? followed by the get fields to the url.