curl tool: reviewed code moved to tool_*.[ch] files

This commit is contained in:
Yang Tse 2011-09-19 18:18:17 +02:00
Родитель 00532341b5
Коммит fdecb56cbf
19 изменённых файлов: 630 добавлений и 370 удалений

Просмотреть файл

@ -9,8 +9,9 @@ UID 0x00000000 0xF0206442
SOURCEPATH ../../../src
SOURCE \
main.c hugehelp.c urlglob.c writeout.c writeenv.c \
getpass.c homedir.c curlutil.c os-specific.c xattr.c \
tool_cfgable.c tool_convert.c tool_mfiles.c tool_myfunc.c
getpass.c homedir.c curlutil.c xattr.c \
tool_bname.c tool_cfgable.c tool_convert.c tool_dirhie.c \
tool_doswin.c tool_mfiles.c tool_myfunc.c tool_vms.c
SOURCEPATH ../../../lib
SOURCE \

Просмотреть файл

@ -15,14 +15,15 @@ CURLX_ONES = $(top_srcdir)/lib/strtoofft.c \
$(top_srcdir)/lib/nonblock.c
CURL_CFILES = main.c hugehelp.c urlglob.c writeout.c writeenv.c \
getpass.c homedir.c curlutil.c os-specific.c xattr.c \
tool_cfgable.c tool_convert.c tool_mfiles.c tool_myfunc.c
getpass.c homedir.c curlutil.c xattr.c \
tool_bname.c tool_cfgable.c tool_convert.c tool_dirhie.c \
tool_doswin.c tool_mfiles.c tool_myfunc.c tool_vms.c
CURL_HFILES = hugehelp.h setup.h config-win32.h config-mac.h \
config-riscos.h urlglob.h version.h os-specific.h \
config-riscos.h urlglob.h version.h xattr.h \
writeout.h writeenv.h getpass.h homedir.h curlutil.h \
xattr.h tool_cfgable.h tool_convert.h tool_mfiles.h \
tool_myfunc.h
tool_bname.h tool_cfgable.h tool_convert.h tool_dirhie.h \
tool_doswin.h tool_mfiles.h tool_myfunc.h tool_vms.h
curl_SOURCES = $(CURL_CFILES) $(CURLX_ONES) $(CURL_HFILES)

Просмотреть файл

@ -139,13 +139,16 @@ RELEASE_OBJS= \
hugehelpr.obj \
mainr.obj \
nonblockr.obj \
os-specificr.obj \
rawstrr.obj \
strtoofftr.obj \
tool_bnamer.obj \
tool_cfgabler.obj \
tool_convertr.obj \
tool_dirhier.obj \
tool_doswinr.obj \
tool_mfilesr.obj \
tool_myfuncr.obj \
tool_vmsr.obj \
urlglobr.obj \
writeoutr.obj \
xattrr.obj \
@ -158,13 +161,16 @@ DEBUG_OBJS= \
hugehelpd.obj \
maind.obj \
nonblockd.obj \
os-specificd.obj \
rawstrd.obj \
strtoofftd.obj \
tool_bnamed.obj \
tool_cfgabled.obj \
tool_convertd.obj \
tool_dirhied.obj \
tool_doswind.obj \
tool_mfilesd.obj \
tool_myfuncd.obj \
tool_vmsd.obj \
urlglobd.obj \
writeoutd.obj \
xattrd.obj \
@ -302,22 +308,28 @@ homedirr.obj: homedir.c
$(CCR) $(CFLAGS) /Fo"$@" homedir.c
curlutilr.obj: curlutil.c
$(CCR) $(CFLAGS) /Fo"$@" curlutil.c
os-specificr.obj: os-specific.c
$(CCR) $(CFLAGS) /Fo"$@" os-specific.c
nonblockr.obj: ../lib/nonblock.c
$(CCR) $(CFLAGS) /Fo"$@" ../lib/nonblock.c
rawstrr.obj: ../lib/rawstr.c
$(CCR) $(CFLAGS) /Fo"$@" ../lib/rawstr.c
strtoofftr.obj: ../lib/strtoofft.c
$(CCR) $(CFLAGS) /Fo"$@" ../lib/strtoofft.c
tool_bnamer.obj: tool_bname.c
$(CCR) $(CFLAGS) /Fo"$@" tool_bname.c
tool_cfgabler.obj: tool_cfgable.c
$(CCR) $(CFLAGS) /Fo"$@" tool_cfgable.c
tool_convertr.obj: tool_convert.c
$(CCR) $(CFLAGS) /Fo"$@" tool_convert.c
tool_dirhier.obj: tool_dirhie.c
$(CCR) $(CFLAGS) /Fo"$@" tool_dirhie.c
tool_doswinr.obj: tool_doswin.c
$(CCR) $(CFLAGS) /Fo"$@" tool_doswin.c
tool_mfilesr.obj: tool_mfiles.c
$(CCR) $(CFLAGS) /Fo"$@" tool_mfiles.c
tool_myfuncr.obj: tool_myfunc.c
$(CCR) $(CFLAGS) /Fo"$@" tool_myfunc.c
tool_vmsr.obj: tool_vms.c
$(CCR) $(CFLAGS) /Fo"$@" tool_vms.c
xattrr.obj: xattr.c
$(CCR) $(CFLAGS) /Fo"$@" xattr.c
mainr.obj: main.c
@ -338,22 +350,28 @@ homedird.obj: homedir.c
$(CCD) $(CFLAGS) /Fo"$@" homedir.c
curlutild.obj: curlutil.c
$(CCD) $(CFLAGS) /Fo"$@" curlutil.c
os-specificd.obj: os-specific.c
$(CCD) $(CFLAGS) /Fo"$@" os-specific.c
nonblockd.obj: ../lib/nonblock.c
$(CCD) $(CFLAGS) /Fo"$@" ../lib/nonblock.c
rawstrd.obj: ../lib/rawstr.c
$(CCD) $(CFLAGS) /Fo"$@" ../lib/rawstr.c
strtoofftd.obj: ../lib/strtoofft.c
$(CCD) $(CFLAGS) /Fo"$@" ../lib/strtoofft.c
tool_bnamed.obj: tool_bname.c
$(CCD) $(CFLAGS) /Fo"$@" tool_bname.c
tool_cfgabled.obj: tool_cfgable.c
$(CCD) $(CFLAGS) /Fo"$@" tool_cfgable.c
tool_convertd.obj: tool_convert.c
$(CCD) $(CFLAGS) /Fo"$@" tool_convert.c
tool_dirhied.obj: tool_dirhie.c
$(CCD) $(CFLAGS) /Fo"$@" tool_dirhie.c
tool_doswind.obj: tool_doswin.c
$(CCD) $(CFLAGS) /Fo"$@" tool_doswin.c
tool_mfilesd.obj: tool_mfiles.c
$(CCD) $(CFLAGS) /Fo"$@" tool_mfiles.c
tool_myfuncd.obj: tool_myfunc.c
$(CCD) $(CFLAGS) /Fo"$@" tool_myfunc.c
tool_vmsd.obj: tool_vms.c
$(CCD) $(CFLAGS) /Fo"$@" tool_vms.c
xattrd.obj: xattr.c
$(CCD) $(CFLAGS) /Fo"$@" xattr.c
maind.obj: main.c

Просмотреть файл

@ -30,18 +30,11 @@
#include <sys/types.h>
#include <sys/stat.h>
#if defined(MSDOS) || defined(WIN32)
# if defined(HAVE_LIBGEN_H) && defined(HAVE_BASENAME)
# include <libgen.h>
# endif
#endif
#ifdef NETWARE
# ifdef __NOVELL_LIBC__
# include <screen.h>
# else
# include <nwconio.h>
# define mkdir mkdir_510
# endif
#endif
@ -89,16 +82,6 @@
# include <dos.h>
#endif
#if defined(USE_WIN32_LARGE_FILES) || defined(USE_WIN32_SMALL_FILES)
# include <io.h>
# include <sys/types.h>
# include <sys/stat.h>
#endif
#ifdef WIN32
# include <direct.h>
#endif
/*
** src subdirectory headers
*/
@ -108,13 +91,15 @@
#include "getpass.h"
#include "homedir.h"
#include "curlutil.h"
#include "os-specific.h"
#include "version.h"
#include "xattr.h"
#include "tool_convert.h"
#include "tool_mfiles.h"
#include "tool_cfgable.h"
#include "tool_convert.h"
#include "tool_dirhie.h"
#include "tool_doswin.h"
#include "tool_mfiles.h"
#include "tool_myfunc.h"
#include "tool_vms.h"
#ifdef USE_MANUAL
# include "hugehelp.h"
#endif
@ -169,28 +154,6 @@ static int vms_show = 0;
#define O_BINARY 0
#endif
#if defined(MSDOS) || defined(WIN32)
static const char *msdosify(const char *);
static char *rename_if_dos_device_name(char *);
static char *sanitize_dos_name(char *);
#ifndef S_ISCHR
# ifdef S_IFCHR
# define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR)
# else
# define S_ISCHR(m) (0) /* cannot tell if file is a device */
# endif
#endif
#ifdef WIN32
# define _use_lfn(f) (1) /* long file names always available */
#elif !defined(__DJGPP__) || (__DJGPP__ < 2) /* DJGPP 2.0 has _use_lfn() */
# define _use_lfn(f) (0) /* long file names never available */
#endif
#endif /* MSDOS || WIN32 */
#ifdef MSDOS
#define USE_WATT32
#ifdef DJGPP
@ -220,47 +183,6 @@ char **__crt0_glob_function (char *arg)
#define CURL_PROGRESS_STATS 0 /* default progress display */
#define CURL_PROGRESS_BAR 1
/*
* Large file support (>2Gb) using WIN32 functions.
*/
#ifdef USE_WIN32_LARGE_FILES
# define lseek(fdes,offset,whence) _lseeki64(fdes, offset, whence)
# define fstat(fdes,stp) _fstati64(fdes, stp)
# define stat(fname,stp) _stati64(fname, stp)
# define struct_stat struct _stati64
# define LSEEK_ERROR (__int64)-1
#endif
/*
* Small file support (<2Gb) using WIN32 functions.
*/
#ifdef USE_WIN32_SMALL_FILES
# define lseek(fdes,offset,whence) _lseek(fdes, (long)offset, whence)
# define fstat(fdes,stp) _fstat(fdes, stp)
# define stat(fname,stp) _stat(fname, stp)
# define struct_stat struct _stat
# define LSEEK_ERROR (long)-1
#endif
#ifndef struct_stat
# define struct_stat struct stat
#endif
#ifndef LSEEK_ERROR
# define LSEEK_ERROR (off_t)-1
#endif
#ifdef WIN32
# define mkdir(x,y) (mkdir)(x)
# undef PATH_MAX
# define PATH_MAX MAX_PATH
# ifndef __POCC__
# define F_OK 0
# endif
#endif
/*
* Default sizeof(off_t) in case it hasn't been defined in config file.
*/
@ -648,7 +570,6 @@ static curl_version_info_data *curlinfo;
static int parseconfig(const char *filename,
struct Configurable *config);
static char *my_get_line(FILE *fp);
static int create_dir_hierarchy(const char *outfile, FILE *errors);
#if 0
static void GetStr(char **string,
@ -4496,8 +4417,8 @@ operate(struct Configurable *config, int argc, argv_item_t argv[])
outfile = get_url_file_name(url);
if((!outfile || !*outfile) && !config->content_disposition) {
helpf(config->errors, "Remote file name has no length!\n");
res = CURLE_WRITE_ERROR;
Curl_safefree(url);
res = CURLE_WRITE_ERROR;
break;
}
#if defined(MSDOS) || defined(WIN32)
@ -4505,6 +4426,8 @@ operate(struct Configurable *config, int argc, argv_item_t argv[])
bad characters in the file name before using it */
outfile = sanitize_dos_name(outfile);
if(!outfile) {
warnf(config, "out of memory\n");
Curl_safefree(url);
res = CURLE_OUT_OF_MEMORY;
break;
}
@ -4527,11 +4450,15 @@ operate(struct Configurable *config, int argc, argv_item_t argv[])
/* Create the directory hierarchy, if not pre-existent to a multiple
file output call */
if(config->create_dirs &&
(-1 == create_dir_hierarchy(outfile, config->errors))) {
Curl_safefree(url);
res = CURLE_WRITE_ERROR;
break;
if(config->create_dirs) {
res = create_dir_hierarchy(outfile, config->errors);
/* create_dir_hierarchy shows error upon CURLE_WRITE_ERROR */
if(res == CURLE_OUT_OF_MEMORY)
warnf(config, "out of memory\n");
if(res) {
Curl_safefree(url);
break;
}
}
if(config->resume_from_current) {
@ -5499,257 +5426,3 @@ static char *my_get_line(FILE *fp)
return retval;
}
static void show_dir_errno(FILE *errors, const char *name)
{
switch (ERRNO) {
#ifdef EACCES
case EACCES:
fprintf(errors,"You don't have permission to create %s.\n", name);
break;
#endif
#ifdef ENAMETOOLONG
case ENAMETOOLONG:
fprintf(errors,"The directory name %s is too long.\n", name);
break;
#endif
#ifdef EROFS
case EROFS:
fprintf(errors,"%s resides on a read-only file system.\n", name);
break;
#endif
#ifdef ENOSPC
case ENOSPC:
fprintf(errors,"No space left on the file system that will "
"contain the directory %s.\n", name);
break;
#endif
#ifdef EDQUOT
case EDQUOT:
fprintf(errors,"Cannot create directory %s because you "
"exceeded your quota.\n", name);
break;
#endif
default :
fprintf(errors,"Error creating directory %s.\n", name);
break;
}
}
/* 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(const char *outfile, FILE *errors)
{
char *tempdir;
char *tempdir2;
char *outdup;
char *dirbuildup;
int result=0;
outdup = strdup(outfile);
if(!outdup)
return -1;
dirbuildup = malloc(sizeof(char) * strlen(outfile));
if(!dirbuildup) {
Curl_safefree(outdup);
return -1;
}
dirbuildup[0] = '\0';
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) {
size_t dlen = strlen(dirbuildup);
if(dlen)
sprintf(&dirbuildup[dlen], "%s%s", DIR_CHAR, tempdir);
else {
if(0 != strncmp(outdup, DIR_CHAR, 1))
strcpy(dirbuildup, tempdir);
else
sprintf(dirbuildup, "%s%s", DIR_CHAR, tempdir);
}
if(access(dirbuildup, F_OK) == -1) {
result = mkdir(dirbuildup,(mode_t)0000750);
if(-1 == result) {
show_dir_errno(errors, dirbuildup);
break; /* get out of loop */
}
}
}
tempdir = tempdir2;
}
Curl_safefree(dirbuildup);
Curl_safefree(outdup);
return result; /* 0 is fine, -1 is badness */
}
#if defined(MSDOS) || defined(WIN32)
#ifndef HAVE_BASENAME
/* basename() returns a pointer to the last component of a pathname.
* Ripped from lib/formdata.c.
*/
static char *Curl_basename(char *path)
{
/* Ignore all the details above for now and make a quick and simple
implementaion here */
char *s1;
char *s2;
s1=strrchr(path, '/');
s2=strrchr(path, '\\');
if(s1 && s2) {
path = (s1 > s2? s1 : s2)+1;
}
else if(s1)
path = s1 + 1;
else if(s2)
path = s2 + 1;
return path;
}
#define basename(x) Curl_basename((x))
#endif /* HAVE_BASENAME */
/* The following functions are taken with modification from the DJGPP
* port of tar 1.12. They use algorithms originally from DJTAR. */
static const char *
msdosify (const char *file_name)
{
static char dos_name[PATH_MAX];
static const char illegal_chars_dos[] = ".+, ;=[]" /* illegal in DOS */
"|<>\\\":?*"; /* illegal in DOS & W95 */
static const char *illegal_chars_w95 = &illegal_chars_dos[8];
int idx, dot_idx;
const char *s = file_name;
char *d = dos_name;
const char * const dlimit = dos_name + sizeof(dos_name) - 1;
const char *illegal_aliens = illegal_chars_dos;
size_t len = sizeof (illegal_chars_dos) - 1;
/* Support for Windows 9X VFAT systems, when available. */
if(_use_lfn (file_name)) {
illegal_aliens = illegal_chars_w95;
len -= (illegal_chars_w95 - illegal_chars_dos);
}
/* Get past the drive letter, if any. */
if(s[0] >= 'A' && s[0] <= 'z' && s[1] == ':') {
*d++ = *s++;
*d++ = *s++;
}
for(idx = 0, dot_idx = -1; *s && d < dlimit; s++, d++) {
if(memchr (illegal_aliens, *s, len)) {
/* Dots are special: DOS doesn't allow them as the leading character,
and a file name cannot have more than a single dot. We leave the
first non-leading dot alone, unless it comes too close to the
beginning of the name: we want sh.lex.c to become sh_lex.c, not
sh.lex-c. */
if(*s == '.') {
if(idx == 0 && (s[1] == '/' || (s[1] == '.' && s[2] == '/'))) {
/* Copy "./" and "../" verbatim. */
*d++ = *s++;
if(*s == '.')
*d++ = *s++;
*d = *s;
}
else if(idx == 0)
*d = '_';
else if(dot_idx >= 0) {
if(dot_idx < 5) { /* 5 is a heuristic ad-hoc'ery */
d[dot_idx - idx] = '_'; /* replace previous dot */
*d = '.';
}
else
*d = '-';
}
else
*d = '.';
if(*s == '.')
dot_idx = idx;
}
else if(*s == '+' && s[1] == '+') {
if(idx - 2 == dot_idx) { /* .c++, .h++ etc. */
*d++ = 'x';
*d = 'x';
}
else {
/* libg++ etc. */
memcpy (d, "plus", 4);
d += 3;
}
s++;
idx++;
}
else
*d = '_';
}
else
*d = *s;
if(*s == '/') {
idx = 0;
dot_idx = -1;
}
else
idx++;
}
*d = '\0';
return dos_name;
}
static char *
rename_if_dos_device_name (char *file_name)
{
/* We could have a file whose name is a device on MS-DOS. Trying to
* retrieve such a file would fail at best and wedge us at worst. We need
* to rename such files. */
char *base;
struct_stat st_buf;
char fname[PATH_MAX];
strncpy(fname, file_name, PATH_MAX-1);
fname[PATH_MAX-1] = 0;
base = basename(fname);
if(((stat(base, &st_buf)) == 0) && (S_ISCHR(st_buf.st_mode))) {
size_t blen = strlen (base);
if(strlen(fname) >= PATH_MAX-1) {
/* Make room for the '_' */
blen--;
base[blen] = 0;
}
/* Prepend a '_'. */
memmove (base + 1, base, blen + 1);
base[0] = '_';
strcpy (file_name, fname);
}
return file_name;
}
/* Replace bad characters in the file name before using it.
* fn will always be freed before return
* The returned pointer must be freed by the caller if not NULL
*/
static char *sanitize_dos_name(char *fn)
{
char tmpfn[PATH_MAX];
if(strlen(fn) >= PATH_MAX)
fn[PATH_MAX-1]=0; /* truncate it */
strcpy(tmpfn, msdosify(fn));
Curl_safefree(fn);
return strdup(rename_if_dos_device_name(tmpfn));
}
#endif /* MSDOS || WIN32 */

Просмотреть файл

@ -158,6 +158,43 @@
#include <floss.h>
#endif
/*
* Large file (>2Gb) support using WIN32 functions.
*/
#ifdef USE_WIN32_LARGE_FILES
# include <io.h>
# include <sys/types.h>
# include <sys/stat.h>
# define lseek(fdes,offset,whence) _lseeki64(fdes, offset, whence)
# define fstat(fdes,stp) _fstati64(fdes, stp)
# define stat(fname,stp) _stati64(fname, stp)
# define struct_stat struct _stati64
# define LSEEK_ERROR (__int64)-1
#endif
/*
* Small file (<2Gb) support using WIN32 functions.
*/
#ifdef USE_WIN32_SMALL_FILES
# include <io.h>
# include <sys/types.h>
# include <sys/stat.h>
# define lseek(fdes,offset,whence) _lseek(fdes, (long)offset, whence)
# define fstat(fdes,stp) _fstat(fdes, stp)
# define stat(fname,stp) _stat(fname, stp)
# define struct_stat struct _stat
# define LSEEK_ERROR (long)-1
#endif
#ifndef struct_stat
# define struct_stat struct stat
#endif
#ifndef LSEEK_ERROR
# define LSEEK_ERROR (off_t)-1
#endif
#ifndef OS
#define OS "unknown"
@ -254,3 +291,4 @@ int fileno( FILE *stream);
#endif
#endif /* HEADER_CURL_SRC_SETUP_H */

50
src/tool_bname.c Normal file
Просмотреть файл

@ -0,0 +1,50 @@
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html.
*
* 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 COPYING file.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
***************************************************************************/
#include "setup.h"
#include "tool_bname.h"
#include "memdebug.h" /* keep this as LAST include */
#ifndef HAVE_BASENAME
char *tool_basename(char *path)
{
char *s1;
char *s2;
s1 = strrchr(path, '/');
s2 = strrchr(path, '\\');
if(s1 && s2) {
path = (s1 > s2) ? s1 + 1 : s2 + 1;
}
else if(s1)
path = s1 + 1;
else if(s2)
path = s2 + 1;
return path;
}
#endif /* HAVE_BASENAME */

35
src/tool_bname.h Normal file
Просмотреть файл

@ -0,0 +1,35 @@
#ifndef HEADER_CURL_TOOL_BNAME_H
#define HEADER_CURL_TOOL_BNAME_H
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html.
*
* 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 COPYING file.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
***************************************************************************/
#include "setup.h"
#ifndef HAVE_BASENAME
char *tool_basename(char *path);
#define basename(x) tool_basename((x))
#endif /* HAVE_BASENAME */
#endif /* HEADER_CURL_TOOL_BNAME_H */

Просмотреть файл

@ -242,3 +242,4 @@ struct Configurable {
void free_config_fields(struct Configurable *config);
#endif /* HEADER_CURL_TOOL_CFGABLE_H */

Просмотреть файл

@ -42,3 +42,4 @@ char convert_char(curl_infotype infotype, char this_char);
#endif
#endif /* HEADER_CURL_TOOL_CONVERT_H */

151
src/tool_dirhie.c Normal file
Просмотреть файл

@ -0,0 +1,151 @@
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html.
*
* 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 COPYING file.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
***************************************************************************/
#include "setup.h"
#include <curl/curl.h>
#include <sys/stat.h>
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
#ifdef WIN32
# include <direct.h>
#endif
#define ENABLE_CURLX_PRINTF
/* use our own printf() functions */
#include "curlx.h"
#include "tool_dirhie.h"
#include "memdebug.h" /* keep this as LAST include */
#ifdef NETWARE
# ifndef __NOVELL_LIBC__
# define mkdir mkdir_510
# endif
#endif
#ifdef WIN32
# define mkdir(x,y) (mkdir)((x))
# ifndef __POCC__
# define F_OK 0
# endif
#endif
static void show_dir_errno(FILE *errors, const char *name)
{
switch(ERRNO) {
#ifdef EACCES
case EACCES:
fprintf(errors, "You don't have permission to create %s.\n", name);
break;
#endif
#ifdef ENAMETOOLONG
case ENAMETOOLONG:
fprintf(errors, "The directory name %s is too long.\n", name);
break;
#endif
#ifdef EROFS
case EROFS:
fprintf(errors, "%s resides on a read-only file system.\n", name);
break;
#endif
#ifdef ENOSPC
case ENOSPC:
fprintf(errors, "No space left on the file system that will "
"contain the directory %s.\n", name);
break;
#endif
#ifdef EDQUOT
case EDQUOT:
fprintf(errors, "Cannot create directory %s because you "
"exceeded your quota.\n", name);
break;
#endif
default :
fprintf(errors, "Error creating directory %s.\n", name);
break;
}
}
/*
* 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
*/
CURLcode create_dir_hierarchy(const char *outfile, FILE *errors)
{
char *tempdir;
char *tempdir2;
char *outdup;
char *dirbuildup;
CURLcode result = CURLE_OK;
outdup = strdup(outfile);
if(!outdup)
return CURLE_OUT_OF_MEMORY;
dirbuildup = malloc(strlen(outfile) + 1);
if(!dirbuildup) {
Curl_safefree(outdup);
return CURLE_OUT_OF_MEMORY;
}
dirbuildup[0] = '\0';
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) {
size_t dlen = strlen(dirbuildup);
if(dlen)
sprintf(&dirbuildup[dlen], "%s%s", DIR_CHAR, tempdir);
else {
if(0 != strncmp(outdup, DIR_CHAR, 1))
strcpy(dirbuildup, tempdir);
else
sprintf(dirbuildup, "%s%s", DIR_CHAR, tempdir);
}
if(access(dirbuildup, F_OK) == -1) {
if(-1 == mkdir(dirbuildup,(mode_t)0000750)) {
show_dir_errno(errors, dirbuildup);
result = CURLE_WRITE_ERROR;
break; /* get out of loop */
}
}
}
tempdir = tempdir2;
}
Curl_safefree(dirbuildup);
Curl_safefree(outdup);
return result;
}

29
src/tool_dirhie.h Normal file
Просмотреть файл

@ -0,0 +1,29 @@
#ifndef HEADER_CURL_TOOL_DIRHIE_H
#define HEADER_CURL_TOOL_DIRHIE_H
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html.
*
* 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 COPYING file.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
***************************************************************************/
#include "setup.h"
CURLcode create_dir_hierarchy(const char *outfile, FILE *errors);
#endif /* HEADER_CURL_TOOL_DIRHIE_H */

202
src/tool_doswin.c Normal file
Просмотреть файл

@ -0,0 +1,202 @@
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html.
*
* 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 COPYING file.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
***************************************************************************/
#include "setup.h"
#if defined(MSDOS) || defined(WIN32)
#if defined(HAVE_LIBGEN_H) && defined(HAVE_BASENAME)
# include <libgen.h>
#endif
#include "tool_bname.h"
#include "tool_doswin.h"
#include "memdebug.h" /* keep this as LAST include */
#ifdef WIN32
# undef PATH_MAX
# define PATH_MAX MAX_PATH
#endif
#ifndef S_ISCHR
# ifdef S_IFCHR
# define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR)
# else
# define S_ISCHR(m) (0) /* cannot tell if file is a device */
# endif
#endif
#ifdef WIN32
# define _use_lfn(f) (0, 1) /* long file names always available */
#elif !defined(__DJGPP__) || (__DJGPP__ < 2) /* DJGPP 2.0 has _use_lfn() */
# define _use_lfn(f) (1, 0) /* long file names never available */
#endif
static const char *msdosify (const char *file_name);
static char *rename_if_dos_device_name (char *file_name);
/*
* sanitize_dos_name: returns a newly allocated string holding a
* valid file name which will be a transformation of given argument
* in case this wasn't already a valid file name.
*
* This function takes ownership of given argument, free'ing it before
* returning. Caller is responsible of free'ing returned string. Upon
* out of memory condition function returns NULL.
*/
char *sanitize_dos_name(char *file_name)
{
char new_name[PATH_MAX];
if(!file_name)
return NULL;
if(strlen(file_name) >= PATH_MAX)
file_name[PATH_MAX-1] = '\0'; /* truncate it */
strcpy(new_name, msdosify(file_name));
free(file_name);
return strdup(rename_if_dos_device_name(new_name));
}
/* The following functions are taken with modification from the DJGPP
* port of tar 1.12. They use algorithms originally from DJTAR. */
static const char *msdosify (const char *file_name)
{
static char dos_name[PATH_MAX];
static const char illegal_chars_dos[] = ".+, ;=[]" /* illegal in DOS */
"|<>\\\":?*"; /* illegal in DOS & W95 */
static const char *illegal_chars_w95 = &illegal_chars_dos[8];
int idx, dot_idx;
const char *s = file_name;
char *d = dos_name;
const char *const dlimit = dos_name + sizeof(dos_name) - 1;
const char *illegal_aliens = illegal_chars_dos;
size_t len = sizeof(illegal_chars_dos) - 1;
/* Support for Windows 9X VFAT systems, when available. */
if(_use_lfn(file_name)) {
illegal_aliens = illegal_chars_w95;
len -= (illegal_chars_w95 - illegal_chars_dos);
}
/* Get past the drive letter, if any. */
if(s[0] >= 'A' && s[0] <= 'z' && s[1] == ':') {
*d++ = *s++;
*d++ = *s++;
}
for(idx = 0, dot_idx = -1; *s && d < dlimit; s++, d++) {
if(memchr(illegal_aliens, *s, len)) {
/* Dots are special: DOS doesn't allow them as the leading character,
and a file name cannot have more than a single dot. We leave the
first non-leading dot alone, unless it comes too close to the
beginning of the name: we want sh.lex.c to become sh_lex.c, not
sh.lex-c. */
if(*s == '.') {
if(idx == 0 && (s[1] == '/' || (s[1] == '.' && s[2] == '/'))) {
/* Copy "./" and "../" verbatim. */
*d++ = *s++;
if(*s == '.')
*d++ = *s++;
*d = *s;
}
else if(idx == 0)
*d = '_';
else if(dot_idx >= 0) {
if(dot_idx < 5) { /* 5 is a heuristic ad-hoc'ery */
d[dot_idx - idx] = '_'; /* replace previous dot */
*d = '.';
}
else
*d = '-';
}
else
*d = '.';
if(*s == '.')
dot_idx = idx;
}
else if(*s == '+' && s[1] == '+') {
if(idx - 2 == dot_idx) { /* .c++, .h++ etc. */
*d++ = 'x';
*d = 'x';
}
else {
/* libg++ etc. */
memcpy (d, "plus", 4);
d += 3;
}
s++;
idx++;
}
else
*d = '_';
}
else
*d = *s;
if(*s == '/') {
idx = 0;
dot_idx = -1;
}
else
idx++;
}
*d = '\0';
return dos_name;
}
static char *rename_if_dos_device_name (char *file_name)
{
/* We could have a file whose name is a device on MS-DOS. Trying to
* retrieve such a file would fail at best and wedge us at worst. We need
* to rename such files. */
char *base;
struct_stat st_buf;
char fname[PATH_MAX];
strncpy(fname, file_name, PATH_MAX-1);
fname[PATH_MAX-1] = '\0';
base = basename(fname);
if(((stat(base, &st_buf)) == 0) && (S_ISCHR(st_buf.st_mode))) {
size_t blen = strlen(base);
if(strlen(fname) >= PATH_MAX-1) {
/* Make room for the '_' */
blen--;
base[blen] = '\0';
}
/* Prepend a '_'. */
memmove(base + 1, base, blen + 1);
base[0] = '_';
strcpy(file_name, fname);
}
return file_name;
}
#endif /* MSDOS || WIN32 */

33
src/tool_doswin.h Normal file
Просмотреть файл

@ -0,0 +1,33 @@
#ifndef HEADER_CURL_TOOL_DOSWIN_H
#define HEADER_CURL_TOOL_DOSWIN_H
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html.
*
* 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 COPYING file.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
***************************************************************************/
#include "setup.h"
#if defined(MSDOS) || defined(WIN32)
char *sanitize_dos_name(char *file_name);
#endif /* MSDOS || WIN32 */
#endif /* HEADER_CURL_TOOL_DOSWIN_H */

Просмотреть файл

@ -126,3 +126,4 @@ void FreeMultiInfo(struct multi_files **multi_first,
if(multi_last)
*multi_last = NULL;
}

Просмотреть файл

@ -43,3 +43,4 @@ void FreeMultiInfo(struct multi_files **multi_first,
struct multi_files **multi_last);
#endif /* HEADER_CURL_TOOL_MFILES_H */

Просмотреть файл

@ -34,7 +34,7 @@
#include "curlx.h"
#include "curlmsg_vms.h"
#include "os-specific.h"
#include "tool_vms.h"
#include "memdebug.h" /* keep this as LAST include */

Просмотреть файл

@ -1,5 +1,5 @@
#ifndef HEADER_CURL_OS_SPECIFIC_H
#define HEADER_CURL_OS_SPECIFIC_H
#ifndef HEADER_CURL_TOOL_VMS_H
#define HEADER_CURL_TOOL_VMS_H
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
@ -36,4 +36,5 @@ void vms_special_exit(int code, int vms_show);
#endif /* __VMS */
#endif /* HEADER_CURL_OS_SPECIFIC_H */
#endif /* HEADER_CURL_TOOL_VMS_H */

Просмотреть файл

@ -27,7 +27,7 @@
#include <curl/mprintf.h>
#include "urlglob.h"
#include "os-specific.h"
#include "tool_vms.h"
#include "memdebug.h" /* keep this as LAST include */

Просмотреть файл

@ -159,10 +159,6 @@ SOURCE=.\main.c
# End Source File
# Begin Source File
SOURCE=.\os-specific.c
# End Source File
# Begin Source File
SOURCE=..\lib\nonblock.c
# End Source File
# Begin Source File
@ -175,6 +171,10 @@ SOURCE=..\lib\strtoofft.c
# End Source File
# Begin Source File
SOURCE=.\tool_bname.c
# End Source File
# Begin Source File
SOURCE=.\tool_cfgable.c
# End Source File
# Begin Source File
@ -183,6 +183,14 @@ SOURCE=.\tool_convert.c
# End Source File
# Begin Source File
SOURCE=.\tool_dirhie.c
# End Source File
# Begin Source File
SOURCE=.\tool_doswin.c
# End Source File
# Begin Source File
SOURCE=.\tool_mfiles.c
# End Source File
# Begin Source File
@ -191,6 +199,10 @@ SOURCE=.\tool_myfunc.c
# End Source File
# Begin Source File
SOURCE=.\tool_vms.c
# End Source File
# Begin Source File
SOURCE=.\urlglob.c
# End Source File
# Begin Source File
@ -231,10 +243,6 @@ SOURCE=.\hugehelp.h
# End Source File
# Begin Source File
SOURCE=.\os-specific.h
# End Source File
# Begin Source File
SOURCE=.\setup.h
# End Source File
# Begin Source File
@ -251,6 +259,10 @@ SOURCE=..\lib\strtoofft.h
# End Source File
# Begin Source File
SOURCE=.\tool_bname.h
# End Source File
# Begin Source File
SOURCE=.\tool_cfgable.h
# End Source File
# Begin Source File
@ -259,6 +271,14 @@ SOURCE=.\tool_convert.h
# End Source File
# Begin Source File
SOURCE=.\tool_dirhie.h
# End Source File
# Begin Source File
SOURCE=.\tool_doswin.h
# End Source File
# Begin Source File
SOURCE=.\tool_mfiles.h
# End Source File
# Begin Source File
@ -267,6 +287,10 @@ SOURCE=.\tool_myfunc.h
# End Source File
# Begin Source File
SOURCE=.\tool_vms.h
# End Source File
# Begin Source File
SOURCE=.\urlglob.h
# End Source File
# Begin Source File