aboutsummaryrefslogtreecommitdiff
path: root/src/main.c
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 /src/main.c
parent00532341b568653e78bc676feedf225fe7c2948f (diff)
curl tool: reviewed code moved to tool_*.[ch] files
Diffstat (limited to 'src/main.c')
-rw-r--r--src/main.c359
1 files changed, 16 insertions, 343 deletions
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 */