Nicolas Berloquin's added code for dealing with -@/--create-dirs to create
the necessary directories as specified with -o.
This commit is contained in:
parent
ff5308a5af
commit
7d9eabb981
113
src/main.c
113
src/main.c
@ -31,6 +31,7 @@
|
|||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
#include <sys/errno.h> /* NICO */
|
||||||
|
|
||||||
#include <curl/curl.h>
|
#include <curl/curl.h>
|
||||||
|
|
||||||
@ -410,7 +411,8 @@ static void help(void)
|
|||||||
" -1/--tlsv1 Force usage of TLSv1 (H)\n"
|
" -1/--tlsv1 Force usage of TLSv1 (H)\n"
|
||||||
" -2/--sslv2 Force usage of SSLv2 (H)\n"
|
" -2/--sslv2 Force usage of SSLv2 (H)\n"
|
||||||
" -3/--sslv3 Force usage of SSLv3 (H)");
|
" -3/--sslv3 Force usage of SSLv3 (H)");
|
||||||
puts(" -#/--progress-bar Display transfer progress as a progress bar");
|
puts(" -#/--progress-bar Display transfer progress as a progress bar\n"
|
||||||
|
" -@/--create-dirs Create the necessary local directory hierarchy");
|
||||||
}
|
}
|
||||||
|
|
||||||
struct LongShort {
|
struct LongShort {
|
||||||
@ -484,6 +486,7 @@ struct Configurable {
|
|||||||
bool globoff;
|
bool globoff;
|
||||||
bool use_httpget;
|
bool use_httpget;
|
||||||
bool insecure_ok; /* set TRUE to allow insecure SSL connects */
|
bool insecure_ok; /* set TRUE to allow insecure SSL connects */
|
||||||
|
bool create_dirs; /* NICO */
|
||||||
|
|
||||||
char *writeout; /* %-styled format string to output */
|
char *writeout; /* %-styled format string to output */
|
||||||
bool writeenv; /* write results to environment, if available */
|
bool writeenv; /* write results to environment, if available */
|
||||||
@ -523,6 +526,7 @@ struct Configurable {
|
|||||||
static int parseconfig(const char *filename,
|
static int parseconfig(const char *filename,
|
||||||
struct Configurable *config);
|
struct Configurable *config);
|
||||||
static char *my_get_line(FILE *fp);
|
static char *my_get_line(FILE *fp);
|
||||||
|
static int create_dir_hierarchy(char *outfile); /* NICO */
|
||||||
|
|
||||||
static void GetStr(char **string,
|
static void GetStr(char **string,
|
||||||
char *value)
|
char *value)
|
||||||
@ -1069,6 +1073,7 @@ static ParameterError getparameter(char *flag, /* f or -long-flag */
|
|||||||
{"z", "time-cond", TRUE},
|
{"z", "time-cond", TRUE},
|
||||||
{"Z", "max-redirs", TRUE},
|
{"Z", "max-redirs", TRUE},
|
||||||
{"#", "progress-bar",FALSE},
|
{"#", "progress-bar",FALSE},
|
||||||
|
{"@", "create-dirs", FALSE}, /* NICO */
|
||||||
};
|
};
|
||||||
|
|
||||||
if(('-' != flag[0]) ||
|
if(('-' != flag[0]) ||
|
||||||
@ -1704,6 +1709,11 @@ static ParameterError getparameter(char *flag, /* f or -long-flag */
|
|||||||
config->maxredirs = atoi(nextarg);
|
config->maxredirs = atoi(nextarg);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case '@':
|
||||||
|
/* NICO */
|
||||||
|
config->create_dirs = TRUE;
|
||||||
|
break;
|
||||||
|
|
||||||
default: /* unknown flag */
|
default: /* unknown flag */
|
||||||
return PARAM_OPTION_UNKNOWN;
|
return PARAM_OPTION_UNKNOWN;
|
||||||
}
|
}
|
||||||
@ -2333,6 +2343,7 @@ operate(struct Configurable *config, int argc, char *argv[])
|
|||||||
config->showerror=TRUE;
|
config->showerror=TRUE;
|
||||||
config->conf=CONF_DEFAULT;
|
config->conf=CONF_DEFAULT;
|
||||||
config->use_httpget=FALSE;
|
config->use_httpget=FALSE;
|
||||||
|
config->create_dirs=FALSE; /* NICO */
|
||||||
|
|
||||||
if(argc>1 &&
|
if(argc>1 &&
|
||||||
(!strnequal("--", argv[1], 2) && (argv[1][0] == '-')) &&
|
(!strnequal("--", argv[1], 2) && (argv[1][0] == '-')) &&
|
||||||
@ -2555,13 +2566,19 @@ operate(struct Configurable *config, int argc, char *argv[])
|
|||||||
free(storefile);
|
free(storefile);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Create the directory hierarchy, if not pre-existant to a multiple
|
||||||
|
file output call */
|
||||||
|
|
||||||
|
if(config->create_dirs) /* NICO */
|
||||||
|
create_dir_hierarchy(outfile);
|
||||||
|
|
||||||
if(config->resume_from_current) {
|
if(config->resume_from_current) {
|
||||||
/* we're told to continue where we are now, then we get the size of
|
/* We're told to continue from where we are now. Get the
|
||||||
the file as it is now and open it for append instead */
|
size of the file as it is now and open it for append instead */
|
||||||
|
|
||||||
struct stat fileinfo;
|
struct stat fileinfo;
|
||||||
|
|
||||||
/*VMS?? -- Danger, the filesize is only valid for stream files */
|
/*VMS?? -- Danger, the filesize is only valid for stream files */
|
||||||
if(0 == stat(outfile, &fileinfo))
|
if(0 == stat(outfile, &fileinfo))
|
||||||
/* set offset to current file size: */
|
/* set offset to current file size: */
|
||||||
config->resume_from = fileinfo.st_size;
|
config->resume_from = fileinfo.st_size;
|
||||||
@ -2569,7 +2586,7 @@ operate(struct Configurable *config, int argc, char *argv[])
|
|||||||
/* let offset be 0 */
|
/* let offset be 0 */
|
||||||
config->resume_from = 0;
|
config->resume_from = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(config->resume_from) {
|
if(config->resume_from) {
|
||||||
/* open file for output: */
|
/* open file for output: */
|
||||||
outs.stream=(FILE *) fopen(outfile, config->resume_from?"ab":"wb");
|
outs.stream=(FILE *) fopen(outfile, config->resume_from?"ab":"wb");
|
||||||
@ -3020,3 +3037,87 @@ static char *my_get_line(FILE *fp)
|
|||||||
|
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Create the needed directory hierarchy recursively in order to save
|
||||||
|
multi-GETs in file output, ie:
|
||||||
|
curl "http://my.site/dir[1-5]/file[1-5].txt" -o "dir#1/file#2.txt"
|
||||||
|
should create all the dir* automagically
|
||||||
|
*/
|
||||||
|
static int create_dir_hierarchy(char *outfile)
|
||||||
|
{
|
||||||
|
char *tempdir;
|
||||||
|
char *tempdir2;
|
||||||
|
char *outdup;
|
||||||
|
char *dirbuildup;
|
||||||
|
int result=0;
|
||||||
|
|
||||||
|
outdup = strdup(outfile);
|
||||||
|
dirbuildup = malloc(sizeof(char) * strlen(outfile));
|
||||||
|
|
||||||
|
tempdir = strtok(outdup, DIR_CHAR);
|
||||||
|
|
||||||
|
while (tempdir != NULL) {
|
||||||
|
tempdir2 = strtok(NULL, DIR_CHAR);
|
||||||
|
/* since strtok returns a token for the last word even
|
||||||
|
if not ending with DIR_CHAR, we need to prune it */
|
||||||
|
if (tempdir2 != NULL) {
|
||||||
|
if (strlen(dirbuildup) > 0)
|
||||||
|
sprintf(dirbuildup,"%s%s%s",dirbuildup, DIR_CHAR, tempdir);
|
||||||
|
else {
|
||||||
|
/* TODO: BEEEP this is not portable, we need to fix the '/' here! */
|
||||||
|
if (outdup[0] != '/')
|
||||||
|
sprintf(dirbuildup,"%s",tempdir);
|
||||||
|
else
|
||||||
|
sprintf(dirbuildup,"%s%s", DIR_CHAR, tempdir);
|
||||||
|
}
|
||||||
|
if (access(dirbuildup,F_OK) == -1) {
|
||||||
|
result = mkdir(dirbuildup,(mode_t)0000750);
|
||||||
|
if (-1 == result) {
|
||||||
|
switch (errno) {
|
||||||
|
#ifdef EACCES
|
||||||
|
case EACCES:
|
||||||
|
fprintf(stderr,"You don't have permission to create %s.\n",
|
||||||
|
dirbuildup);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
#ifdef ENAMETOOLONG
|
||||||
|
case ENAMETOOLONG:
|
||||||
|
fprintf(stderr,"The directory name %s is too long.\n",
|
||||||
|
dirbuildup);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
#ifdef EROFS
|
||||||
|
case EROFS:
|
||||||
|
fprintf(stderr,"%s resides on a read-only file system.\n",
|
||||||
|
dirbuildup);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
#ifdef ENOSPC
|
||||||
|
case ENOSPC:
|
||||||
|
fprintf(stderr,"No space left on the file system that will "
|
||||||
|
"contain the directory %s.\n", dirbuildup);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
#ifdef EDQUOT
|
||||||
|
case EDQUOT:
|
||||||
|
fprintf(stderr,"Cannot create directory %s because you "
|
||||||
|
"exceeded your quota.\n", dirbuildup);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
default :
|
||||||
|
fprintf(stderr,"Error creating directory %s.\n", dirbuildup);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break; /* get out of loop */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tempdir = tempdir2;
|
||||||
|
}
|
||||||
|
free(dirbuildup);
|
||||||
|
free(outdup);
|
||||||
|
|
||||||
|
return result; /* 0 is fine, -1 is badness */
|
||||||
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user