mirror of
https://github.com/curl/curl.git
synced 2024-11-27 05:50:21 +08:00
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/stat.h>
|
||||
#include <ctype.h>
|
||||
#include <sys/errno.h> /* NICO */
|
||||
|
||||
#include <curl/curl.h>
|
||||
|
||||
@ -410,7 +411,8 @@ static void help(void)
|
||||
" -1/--tlsv1 Force usage of TLSv1 (H)\n"
|
||||
" -2/--sslv2 Force usage of SSLv2 (H)\n"
|
||||
" -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 {
|
||||
@ -484,6 +486,7 @@ struct Configurable {
|
||||
bool globoff;
|
||||
bool use_httpget;
|
||||
bool insecure_ok; /* set TRUE to allow insecure SSL connects */
|
||||
bool create_dirs; /* NICO */
|
||||
|
||||
char *writeout; /* %-styled format string to output */
|
||||
bool writeenv; /* write results to environment, if available */
|
||||
@ -523,6 +526,7 @@ struct Configurable {
|
||||
static int parseconfig(const char *filename,
|
||||
struct Configurable *config);
|
||||
static char *my_get_line(FILE *fp);
|
||||
static int create_dir_hierarchy(char *outfile); /* NICO */
|
||||
|
||||
static void GetStr(char **string,
|
||||
char *value)
|
||||
@ -1069,6 +1073,7 @@ static ParameterError getparameter(char *flag, /* f or -long-flag */
|
||||
{"z", "time-cond", TRUE},
|
||||
{"Z", "max-redirs", TRUE},
|
||||
{"#", "progress-bar",FALSE},
|
||||
{"@", "create-dirs", FALSE}, /* NICO */
|
||||
};
|
||||
|
||||
if(('-' != flag[0]) ||
|
||||
@ -1704,6 +1709,11 @@ static ParameterError getparameter(char *flag, /* f or -long-flag */
|
||||
config->maxredirs = atoi(nextarg);
|
||||
break;
|
||||
|
||||
case '@':
|
||||
/* NICO */
|
||||
config->create_dirs = TRUE;
|
||||
break;
|
||||
|
||||
default: /* unknown flag */
|
||||
return PARAM_OPTION_UNKNOWN;
|
||||
}
|
||||
@ -2333,6 +2343,7 @@ operate(struct Configurable *config, int argc, char *argv[])
|
||||
config->showerror=TRUE;
|
||||
config->conf=CONF_DEFAULT;
|
||||
config->use_httpget=FALSE;
|
||||
config->create_dirs=FALSE; /* NICO */
|
||||
|
||||
if(argc>1 &&
|
||||
(!strnequal("--", argv[1], 2) && (argv[1][0] == '-')) &&
|
||||
@ -2555,13 +2566,19 @@ operate(struct Configurable *config, int argc, char *argv[])
|
||||
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) {
|
||||
/* we're told to continue where we are now, then we get the size of
|
||||
the file as it is now and open it for append instead */
|
||||
|
||||
/* 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 */
|
||||
/*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;
|
||||
@ -2569,7 +2586,7 @@ operate(struct Configurable *config, int argc, char *argv[])
|
||||
/* let offset be 0 */
|
||||
config->resume_from = 0;
|
||||
}
|
||||
|
||||
|
||||
if(config->resume_from) {
|
||||
/* open file for output: */
|
||||
outs.stream=(FILE *) fopen(outfile, config->resume_from?"ab":"wb");
|
||||
@ -3020,3 +3037,87 @@ static char *my_get_line(FILE *fp)
|
||||
|
||||
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…
Reference in New Issue
Block a user