summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYang Tse <yangsita@gmail.com>2011-09-19 18:18:17 +0200
committerYang Tse <yangsita@gmail.com>2011-09-19 18:18:17 +0200
commitfdecb56cbfcafe5b770c4181133655b89973f41e (patch)
tree13c66fdeef3fb672b3ee1e075b9361d0f5e901e6
parent00532341b568653e78bc676feedf225fe7c2948f (diff)
downloadcurl-fdecb56cbfcafe5b770c4181133655b89973f41e.tar.gz
curl tool: reviewed code moved to tool_*.[ch] files
-rw-r--r--packages/Symbian/group/curl.mmp5
-rw-r--r--src/Makefile.inc11
-rw-r--r--src/Makefile.vc630
-rw-r--r--src/main.c359
-rw-r--r--src/setup.h38
-rw-r--r--src/tool_bname.c50
-rw-r--r--src/tool_bname.h35
-rw-r--r--src/tool_cfgable.h1
-rw-r--r--src/tool_convert.h1
-rw-r--r--src/tool_dirhie.c151
-rw-r--r--src/tool_dirhie.h29
-rw-r--r--src/tool_doswin.c202
-rw-r--r--src/tool_doswin.h33
-rw-r--r--src/tool_mfiles.c1
-rw-r--r--src/tool_mfiles.h1
-rw-r--r--src/tool_vms.c (renamed from src/os-specific.c)2
-rw-r--r--src/tool_vms.h (renamed from src/os-specific.h)7
-rw-r--r--src/urlglob.c2
-rw-r--r--src/vc6curlsrc.dsp40
19 files changed, 629 insertions, 369 deletions
diff --git a/packages/Symbian/group/curl.mmp b/packages/Symbian/group/curl.mmp
index d5a87b7d9..5294f6f62 100644
--- a/packages/Symbian/group/curl.mmp
+++ b/packages/Symbian/group/curl.mmp
@@ -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 \
diff --git a/src/Makefile.inc b/src/Makefile.inc
index 97d7f0056..38036260b 100644
--- a/src/Makefile.inc
+++ b/src/Makefile.inc
@@ -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)
diff --git a/src/Makefile.vc6 b/src/Makefile.vc6
index 435970f85..e1f75120f 100644
--- a/src/Makefile.vc6
+++ b/src/Makefile.vc6
@@ -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
diff --git a/src/main.c b/src/main.c
index 8ea8f0507..a5163a65f 100644
--- a/src/main.c
+++ b/src/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_cfgable.h"
#include "tool_convert.h"
+#include "tool_dirhie.h"
+#include "tool_doswin.h"
#include "tool_mfiles.h"
-#include "tool_cfgable.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
@@ -221,47 +184,6 @@ char **__crt0_glob_function (char *arg)
#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 */
diff --git a/src/setup.h b/src/setup.h
index c7e7cf98e..414aac73b 100644
--- a/src/setup.h
+++ b/src/setup.h
@@ -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 */
+
diff --git a/src/tool_bname.c b/src/tool_bname.c
new file mode 100644
index 000000000..2ac6e483b
--- /dev/null
+++ b/src/tool_bname.c
@@ -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 */
+
diff --git a/src/tool_bname.h b/src/tool_bname.h
new file mode 100644
index 000000000..ed7ba0632
--- /dev/null
+++ b/src/tool_bname.h
@@ -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 */
+
diff --git a/src/tool_cfgable.h b/src/tool_cfgable.h
index 63e9f04e4..ef3169583 100644
--- a/src/tool_cfgable.h
+++ b/src/tool_cfgable.h
@@ -242,3 +242,4 @@ struct Configurable {
void free_config_fields(struct Configurable *config);
#endif /* HEADER_CURL_TOOL_CFGABLE_H */
+
diff --git a/src/tool_convert.h b/src/tool_convert.h
index 4cc94b030..d3ef676b2 100644
--- a/src/tool_convert.h
+++ b/src/tool_convert.h
@@ -42,3 +42,4 @@ char convert_char(curl_infotype infotype, char this_char);
#endif
#endif /* HEADER_CURL_TOOL_CONVERT_H */
+
diff --git a/src/tool_dirhie.c b/src/tool_dirhie.c
new file mode 100644
index 000000000..f538d8b2f
--- /dev/null
+++ b/src/tool_dirhie.c
@@ -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;
+}
+
diff --git a/src/tool_dirhie.h b/src/tool_dirhie.h
new file mode 100644
index 000000000..eee30c47f
--- /dev/null
+++ b/src/tool_dirhie.h
@@ -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 */
+
diff --git a/src/tool_doswin.c b/src/tool_doswin.c
new file mode 100644
index 000000000..2b900e161
--- /dev/null
+++ b/src/tool_doswin.c
@@ -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 */
+
diff --git a/src/tool_doswin.h b/src/tool_doswin.h
new file mode 100644
index 000000000..218a5a3f1
--- /dev/null
+++ b/src/tool_doswin.h
@@ -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 */
+
diff --git a/src/tool_mfiles.c b/src/tool_mfiles.c
index b87b5b550..17edbfaab 100644
--- a/src/tool_mfiles.c
+++ b/src/tool_mfiles.c
@@ -126,3 +126,4 @@ void FreeMultiInfo(struct multi_files **multi_first,
if(multi_last)
*multi_last = NULL;
}
+
diff --git a/src/tool_mfiles.h b/src/tool_mfiles.h
index 157fc53f4..8a3b53935 100644
--- a/src/tool_mfiles.h
+++ b/src/tool_mfiles.h
@@ -43,3 +43,4 @@ void FreeMultiInfo(struct multi_files **multi_first,
struct multi_files **multi_last);
#endif /* HEADER_CURL_TOOL_MFILES_H */
+
diff --git a/src/os-specific.c b/src/tool_vms.c
index f95871761..b1ecfe551 100644
--- a/src/os-specific.c
+++ b/src/tool_vms.c
@@ -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 */
diff --git a/src/os-specific.h b/src/tool_vms.h
index 4e6ac6247..56db34ba1 100644
--- a/src/os-specific.h
+++ b/src/tool_vms.h
@@ -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 */
+
diff --git a/src/urlglob.c b/src/urlglob.c
index 2227cec95..aa870d833 100644
--- a/src/urlglob.c
+++ b/src/urlglob.c
@@ -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 */
diff --git a/src/vc6curlsrc.dsp b/src/vc6curlsrc.dsp
index 9959db8ee..603b4bfdb 100644
--- a/src/vc6curlsrc.dsp
+++ b/src/vc6curlsrc.dsp
@@ -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