From fdecb56cbfcafe5b770c4181133655b89973f41e Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Mon, 19 Sep 2011 18:18:17 +0200 Subject: curl tool: reviewed code moved to tool_*.[ch] files --- packages/Symbian/group/curl.mmp | 5 +- src/Makefile.inc | 11 +- src/Makefile.vc6 | 30 +++- src/main.c | 359 ++-------------------------------------- src/os-specific.c | 221 ------------------------- src/os-specific.h | 39 ----- src/setup.h | 38 +++++ src/tool_bname.c | 50 ++++++ src/tool_bname.h | 35 ++++ src/tool_cfgable.h | 1 + src/tool_convert.h | 1 + src/tool_dirhie.c | 151 +++++++++++++++++ src/tool_dirhie.h | 29 ++++ src/tool_doswin.c | 202 ++++++++++++++++++++++ src/tool_doswin.h | 33 ++++ src/tool_mfiles.c | 1 + src/tool_mfiles.h | 1 + src/tool_vms.c | 221 +++++++++++++++++++++++++ src/tool_vms.h | 40 +++++ src/urlglob.c | 2 +- src/vc6curlsrc.dsp | 40 ++++- 21 files changed, 885 insertions(+), 625 deletions(-) delete mode 100644 src/os-specific.c delete mode 100644 src/os-specific.h create mode 100644 src/tool_bname.c create mode 100644 src/tool_bname.h create mode 100644 src/tool_dirhie.c create mode 100644 src/tool_dirhie.h create mode 100644 src/tool_doswin.c create mode 100644 src/tool_doswin.h create mode 100644 src/tool_vms.c create mode 100644 src/tool_vms.h 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 #include -#if defined(MSDOS) || defined(WIN32) -# if defined(HAVE_LIBGEN_H) && defined(HAVE_BASENAME) -# include -# endif -#endif - #ifdef NETWARE # ifdef __NOVELL_LIBC__ # include # else # include -# define mkdir mkdir_510 # endif #endif @@ -89,16 +82,6 @@ # include #endif -#if defined(USE_WIN32_LARGE_FILES) || defined(USE_WIN32_SMALL_FILES) -# include -# include -# include -#endif - -#ifdef WIN32 -# include -#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 @@ -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 */ diff --git a/src/os-specific.c b/src/os-specific.c deleted file mode 100644 index f95871761..000000000 --- a/src/os-specific.c +++ /dev/null @@ -1,221 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2011, Daniel Stenberg, , 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" - -#ifdef __VMS - -#if defined(__DECC) && !defined(__VAX) && \ - defined(__CRTL_VER) && (__CRTL_VER >= 70301000) -#include -#endif - -#include - -#define ENABLE_CURLX_PRINTF -#include "curlx.h" - -#include "curlmsg_vms.h" -#include "os-specific.h" - -#include "memdebug.h" /* keep this as LAST include */ - -void decc$__posix_exit(int __status); -void decc$exit(int __status); - -static int vms_shell = -1; - -/* VMS has a DCL shell and and also has Unix shells ported to it. - * When curl is running under a Unix shell, we want it to be as much - * like Unix as possible. - */ -int is_vms_shell(void) -{ - char *shell; - - /* Have we checked the shell yet? */ - if(vms_shell >= 0) - return vms_shell; - - shell = getenv("SHELL"); - - /* No shell, means DCL */ - if(shell == NULL) { - vms_shell = 1; - return 1; - } - - /* Have to make sure some one did not set shell to DCL */ - if(strcmp(shell, "DCL") == 0) { - vms_shell = 1; - return 1; - } - - vms_shell = 0; - return 0; -} - -/* - * VMS has two exit() routines. When running under a Unix style shell, then - * Unix style and the __posix_exit() routine is used. - * - * When running under the DCL shell, then the VMS encoded codes and decc$exit() - * is used. - * - * We can not use exit() or return a code from main() because the actual - * routine called depends on both the compiler version, compile options, and - * feature macro settings, and one of the exit routines is hidden at compile - * time. - * - * Since we want Curl to work properly under the VMS DCL shell and Unix - * shells under VMS, this routine should compile correctly regardless of - * the settings. - */ - -void vms_special_exit(int code, int vms_show) -{ - int vms_code; - - /* The Posix exit mode is only available after VMS 7.0 */ -#if __CRTL_VER >= 70000000 - if(is_vms_shell() == 0) { - decc$__posix_exit(code); - } -#endif - - if(code > CURL_LAST) { /* If CURL_LAST exceeded then */ - vms_code = CURL_LAST; /* curlmsg.h is out of sync. */ - } - else { - vms_code = vms_cond[code] | vms_show; - } - decc$exit(vms_code); -} - -#if defined(__DECC) && !defined(__VAX) && \ - defined(__CRTL_VER) && (__CRTL_VER >= 70301000) - -/* - * 2004-09-19 SMS. - * - * decc_init() - * - * On non-VAX systems, use LIB$INITIALIZE to set a collection of C - * RTL features without using the DECC$* logical name method, nor - * requiring the user to define the corresponding logical names. - */ - -/* Structure to hold a DECC$* feature name and its desired value. */ -typedef struct { - char *name; - int value; -} decc_feat_t; - -/* Array of DECC$* feature names and their desired values. */ -static decc_feat_t decc_feat_array[] = { - /* Preserve command-line case with SET PROCESS/PARSE_STYLE=EXTENDED */ - { "DECC$ARGV_PARSE_STYLE", 1 }, - /* Preserve case for file names on ODS5 disks. */ - { "DECC$EFS_CASE_PRESERVE", 1 }, - /* Enable multiple dots (and most characters) in ODS5 file names, - while preserving VMS-ness of ";version". */ - { "DECC$EFS_CHARSET", 1 }, - /* List terminator. */ - { (char *)NULL, 0 } -}; - -/* Flag to sense if decc_init() was called. */ -static int decc_init_done = -1; - -/* LIB$INITIALIZE initialization function. */ -static void decc_init(void) -{ - int feat_index; - int feat_value; - int feat_value_max; - int feat_value_min; - int i; - int sts; - - /* Set the global flag to indicate that LIB$INITIALIZE worked. */ - decc_init_done = 1; - - /* Loop through all items in the decc_feat_array[]. */ - for(i = 0; decc_feat_array[i].name != NULL; i++) { - - /* Get the feature index. */ - feat_index = decc$feature_get_index( decc_feat_array[i].name); - - if(feat_index >= 0) { - /* Valid item. Collect its properties. */ - feat_value = decc$feature_get_value( feat_index, 1); - feat_value_min = decc$feature_get_value( feat_index, 2); - feat_value_max = decc$feature_get_value( feat_index, 3); - - if((decc_feat_array[i].value >= feat_value_min) && - (decc_feat_array[i].value <= feat_value_max)) { - /* Valid value. Set it if necessary. */ - if(feat_value != decc_feat_array[i].value) { - sts = decc$feature_set_value( feat_index, 1, - decc_feat_array[i].value); - } - } - else { - /* Invalid DECC feature value. */ - printf(" INVALID DECC FEATURE VALUE, %d: %d <= %s <= %d.\n", - feat_value, - feat_value_min, decc_feat_array[i].name, feat_value_max); - } - } - else { - /* Invalid DECC feature name. */ - printf(" UNKNOWN DECC FEATURE: %s.\n", decc_feat_array[i].name); - } - - } -} - -/* Get "decc_init()" into a valid, loaded LIB$INITIALIZE PSECT. */ - -#pragma nostandard - -/* Establish the LIB$INITIALIZE PSECTs, with proper alignment and - other attributes. Note that "nopic" is significant only on VAX. */ -#pragma extern_model save -#pragma extern_model strict_refdef "LIB$INITIALIZ" 2, nopic, nowrt -const int spare[8] = {0}; -#pragma extern_model strict_refdef "LIB$INITIALIZE" 2, nopic, nowrt -void (*const x_decc_init)() = decc_init; -#pragma extern_model restore - -/* Fake reference to ensure loading the LIB$INITIALIZE PSECT. */ -#pragma extern_model save -int LIB$INITIALIZE(void); -#pragma extern_model strict_refdef -int dmy_lib$initialize = (int) LIB$INITIALIZE; -#pragma extern_model restore - -#pragma standard - -#endif /* __DECC && !__VAX && __CRTL_VER && __CRTL_VER >= 70301000 */ - -#endif /* __VMS */ - diff --git a/src/os-specific.h b/src/os-specific.h deleted file mode 100644 index 4e6ac6247..000000000 --- a/src/os-specific.h +++ /dev/null @@ -1,39 +0,0 @@ -#ifndef HEADER_CURL_OS_SPECIFIC_H -#define HEADER_CURL_OS_SPECIFIC_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2011, Daniel Stenberg, , 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" - -#ifdef __VMS - -int is_vms_shell(void); -void vms_special_exit(int code, int vms_show); - -#undef exit -#define exit(__code) vms_special_exit((__code), (0)) - -#define VMS_STS(c,f,e,s) (((c&0xF)<<28)|((f&0xFFF)<<16)|((e&0x1FFF)<3)|(s&7)) -#define VMSSTS_HIDE VMS_STS(1,0,0,0) - -#endif /* __VMS */ - -#endif /* HEADER_CURL_OS_SPECIFIC_H */ 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 #endif +/* + * Large file (>2Gb) support using WIN32 functions. + */ + +#ifdef USE_WIN32_LARGE_FILES +# include +# include +# include +# 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 +# include +# include +# 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, , 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, , 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, , 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 + +#include + +#ifdef HAVE_UNISTD_H +# include +#endif + +#ifdef WIN32 +# include +#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, , 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, , 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 +#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, , 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/tool_vms.c b/src/tool_vms.c new file mode 100644 index 000000000..b1ecfe551 --- /dev/null +++ b/src/tool_vms.c @@ -0,0 +1,221 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2011, Daniel Stenberg, , 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" + +#ifdef __VMS + +#if defined(__DECC) && !defined(__VAX) && \ + defined(__CRTL_VER) && (__CRTL_VER >= 70301000) +#include +#endif + +#include + +#define ENABLE_CURLX_PRINTF +#include "curlx.h" + +#include "curlmsg_vms.h" +#include "tool_vms.h" + +#include "memdebug.h" /* keep this as LAST include */ + +void decc$__posix_exit(int __status); +void decc$exit(int __status); + +static int vms_shell = -1; + +/* VMS has a DCL shell and and also has Unix shells ported to it. + * When curl is running under a Unix shell, we want it to be as much + * like Unix as possible. + */ +int is_vms_shell(void) +{ + char *shell; + + /* Have we checked the shell yet? */ + if(vms_shell >= 0) + return vms_shell; + + shell = getenv("SHELL"); + + /* No shell, means DCL */ + if(shell == NULL) { + vms_shell = 1; + return 1; + } + + /* Have to make sure some one did not set shell to DCL */ + if(strcmp(shell, "DCL") == 0) { + vms_shell = 1; + return 1; + } + + vms_shell = 0; + return 0; +} + +/* + * VMS has two exit() routines. When running under a Unix style shell, then + * Unix style and the __posix_exit() routine is used. + * + * When running under the DCL shell, then the VMS encoded codes and decc$exit() + * is used. + * + * We can not use exit() or return a code from main() because the actual + * routine called depends on both the compiler version, compile options, and + * feature macro settings, and one of the exit routines is hidden at compile + * time. + * + * Since we want Curl to work properly under the VMS DCL shell and Unix + * shells under VMS, this routine should compile correctly regardless of + * the settings. + */ + +void vms_special_exit(int code, int vms_show) +{ + int vms_code; + + /* The Posix exit mode is only available after VMS 7.0 */ +#if __CRTL_VER >= 70000000 + if(is_vms_shell() == 0) { + decc$__posix_exit(code); + } +#endif + + if(code > CURL_LAST) { /* If CURL_LAST exceeded then */ + vms_code = CURL_LAST; /* curlmsg.h is out of sync. */ + } + else { + vms_code = vms_cond[code] | vms_show; + } + decc$exit(vms_code); +} + +#if defined(__DECC) && !defined(__VAX) && \ + defined(__CRTL_VER) && (__CRTL_VER >= 70301000) + +/* + * 2004-09-19 SMS. + * + * decc_init() + * + * On non-VAX systems, use LIB$INITIALIZE to set a collection of C + * RTL features without using the DECC$* logical name method, nor + * requiring the user to define the corresponding logical names. + */ + +/* Structure to hold a DECC$* feature name and its desired value. */ +typedef struct { + char *name; + int value; +} decc_feat_t; + +/* Array of DECC$* feature names and their desired values. */ +static decc_feat_t decc_feat_array[] = { + /* Preserve command-line case with SET PROCESS/PARSE_STYLE=EXTENDED */ + { "DECC$ARGV_PARSE_STYLE", 1 }, + /* Preserve case for file names on ODS5 disks. */ + { "DECC$EFS_CASE_PRESERVE", 1 }, + /* Enable multiple dots (and most characters) in ODS5 file names, + while preserving VMS-ness of ";version". */ + { "DECC$EFS_CHARSET", 1 }, + /* List terminator. */ + { (char *)NULL, 0 } +}; + +/* Flag to sense if decc_init() was called. */ +static int decc_init_done = -1; + +/* LIB$INITIALIZE initialization function. */ +static void decc_init(void) +{ + int feat_index; + int feat_value; + int feat_value_max; + int feat_value_min; + int i; + int sts; + + /* Set the global flag to indicate that LIB$INITIALIZE worked. */ + decc_init_done = 1; + + /* Loop through all items in the decc_feat_array[]. */ + for(i = 0; decc_feat_array[i].name != NULL; i++) { + + /* Get the feature index. */ + feat_index = decc$feature_get_index( decc_feat_array[i].name); + + if(feat_index >= 0) { + /* Valid item. Collect its properties. */ + feat_value = decc$feature_get_value( feat_index, 1); + feat_value_min = decc$feature_get_value( feat_index, 2); + feat_value_max = decc$feature_get_value( feat_index, 3); + + if((decc_feat_array[i].value >= feat_value_min) && + (decc_feat_array[i].value <= feat_value_max)) { + /* Valid value. Set it if necessary. */ + if(feat_value != decc_feat_array[i].value) { + sts = decc$feature_set_value( feat_index, 1, + decc_feat_array[i].value); + } + } + else { + /* Invalid DECC feature value. */ + printf(" INVALID DECC FEATURE VALUE, %d: %d <= %s <= %d.\n", + feat_value, + feat_value_min, decc_feat_array[i].name, feat_value_max); + } + } + else { + /* Invalid DECC feature name. */ + printf(" UNKNOWN DECC FEATURE: %s.\n", decc_feat_array[i].name); + } + + } +} + +/* Get "decc_init()" into a valid, loaded LIB$INITIALIZE PSECT. */ + +#pragma nostandard + +/* Establish the LIB$INITIALIZE PSECTs, with proper alignment and + other attributes. Note that "nopic" is significant only on VAX. */ +#pragma extern_model save +#pragma extern_model strict_refdef "LIB$INITIALIZ" 2, nopic, nowrt +const int spare[8] = {0}; +#pragma extern_model strict_refdef "LIB$INITIALIZE" 2, nopic, nowrt +void (*const x_decc_init)() = decc_init; +#pragma extern_model restore + +/* Fake reference to ensure loading the LIB$INITIALIZE PSECT. */ +#pragma extern_model save +int LIB$INITIALIZE(void); +#pragma extern_model strict_refdef +int dmy_lib$initialize = (int) LIB$INITIALIZE; +#pragma extern_model restore + +#pragma standard + +#endif /* __DECC && !__VAX && __CRTL_VER && __CRTL_VER >= 70301000 */ + +#endif /* __VMS */ + diff --git a/src/tool_vms.h b/src/tool_vms.h new file mode 100644 index 000000000..56db34ba1 --- /dev/null +++ b/src/tool_vms.h @@ -0,0 +1,40 @@ +#ifndef HEADER_CURL_TOOL_VMS_H +#define HEADER_CURL_TOOL_VMS_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2011, Daniel Stenberg, , 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" + +#ifdef __VMS + +int is_vms_shell(void); +void vms_special_exit(int code, int vms_show); + +#undef exit +#define exit(__code) vms_special_exit((__code), (0)) + +#define VMS_STS(c,f,e,s) (((c&0xF)<<28)|((f&0xFFF)<<16)|((e&0x1FFF)<3)|(s&7)) +#define VMSSTS_HIDE VMS_STS(1,0,0,0) + +#endif /* __VMS */ + +#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 #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 -- cgit v1.2.3