From: <bi...@us...> - 2008-08-11 22:04:52
|
Revision: 2942 http://oorexx.svn.sourceforge.net/oorexx/?rev=2942&view=rev Author: bigrixx Date: 2008-08-11 22:04:46 +0000 (Mon, 11 Aug 2008) Log Message: ----------- move rexxutils and rxftp Modified Paths: -------------- main/trunk/Makefile.am main/trunk/orxdb.bat main/trunk/platform/windows/buildorx.bat Added Paths: ----------- main/trunk/extensions/platform/ main/trunk/extensions/platform/unix/ main/trunk/extensions/platform/windows/ main/trunk/extensions/rexxutil/platform/unix/rexxutil.cpp main/trunk/extensions/rexxutil/platform/windows/rexxutil.cpp main/trunk/extensions/rexxutil/platform/windows/rexxutil.def main/trunk/extensions/rexxutil/platform/windows/rexxutil.mak main/trunk/extensions/rxftp/ main/trunk/extensions/rxftp/rxftp.cls main/trunk/platform/windows/rxftp.mak main/trunk/utilities/platform/ main/trunk/utilities/platform/windows/ main/trunk/utilities/platform/windows/unix/ Removed Paths: ------------- main/trunk/rexutils/rexxutil.mak main/trunk/rexutils/rxftp.cls main/trunk/rexutils/unix/rexxutil.cpp main/trunk/rexutils/windows/rexxutil.cpp main/trunk/rexutils/windows/rexxutil.def Modified: main/trunk/Makefile.am =================================================================== --- main/trunk/Makefile.am 2008-08-11 11:42:17 UTC (rev 2941) +++ main/trunk/Makefile.am 2008-08-11 22:04:46 UTC (rev 2942) @@ -90,6 +90,7 @@ build_samples_dir = $(top_srcdir)/samples build_rexxclasses_dir = $(build_interpreter_dir)/RexxClasses build_utilities_dir = $(top_srcdir)/utilities +build_extensions_dir = $(top_srcdir)/extensions # These are the *nix directories utils_unix_dir = $(build_utils_dir)/unix @@ -785,7 +786,7 @@ # # Sources for librexxutil.so # -librexxutil_la_SOURCES = $(build_rexutils_platform_dir)/rexxutil.cpp +librexxutil_la_SOURCES = $(build_extensions_dir)/platform/unix/rexxutil.cpp # # Preprocessor flags for librexxutil.so # @@ -793,11 +794,7 @@ -I$(build_lib_dir) \ -I$(build_api_dir) \ -I$(build_api_platform_dir) \ - -I$(build_interpreter_dir) \ - -I$(build_messages_dir) \ - -I$(build_interpreter_common_dir) \ - -I$(build_interpreter_platform_dir) \ - -I$(build_rexxapi_platform_dir) + -I$(build_messages_dir) # # Extra libraries for librexxutil.so (maybe) # @@ -816,12 +813,7 @@ -I$(build_lib_dir) \ -I$(build_api_dir) \ -I$(build_api_platform_dir) \ - -I$(build_interpreter_dir) \ - -I$(build_messages_dir) \ - -I$(build_interpreter_common_dir) \ - -I$(build_runtime_dir) \ - -I$(build_interpreter_platform_dir) \ - -I$(build_rexxapi_platform_dir) + -I$(build_messages_dir) # # Extra libraries for librxmath.so (maybe) # @@ -909,7 +901,7 @@ # ooTest: cp $(build_rxregexp_dir)/rxregexp.cls . - cp $(build_rexutils_dir)/rxftp.cls . + cp $(build_extensions_dir)/extensions/rxftp/rxftp.cls . # # distribution files @@ -995,7 +987,7 @@ fi $(install_sh_SCRIPT) $(build_utils_platform_dir)/oorexx-config $(DESTDIR)$(prefix)/bin/oorexx-config $(install_sh_SCRIPT) $(build_rxregexp_dir)/rxregexp.cls $(DESTDIR)$(prefix)/bin/rxregexp.cls - $(install_sh_SCRIPT) $(build_rexutils_dir)/rxftp.cls $(DESTDIR)$(prefix)/bin/rxftp.cls + $(install_sh_SCRIPT) $(build_extensions_dir)/rxftp/rxftp.cls $(DESTDIR)$(prefix)/bin/rxftp.cls for a in $(build_samples_dir)/*.rex; do \ bn=`basename $$a`; \ $(install_sh_SCRIPT) $$a $(DESTDIR)$(prefix)/share/ooRexx/$$bn; \ Copied: main/trunk/extensions/rexxutil/platform/unix/rexxutil.cpp (from rev 2930, main/trunk/rexutils/unix/rexxutil.cpp) =================================================================== --- main/trunk/extensions/rexxutil/platform/unix/rexxutil.cpp (rev 0) +++ main/trunk/extensions/rexxutil/platform/unix/rexxutil.cpp 2008-08-11 22:04:46 UTC (rev 2942) @@ -0,0 +1,5244 @@ +/*----------------------------------------------------------------------------*/ +/* */ +/* Copyright (c) 1995, 2004 IBM Corporation. All rights reserved. */ +/* Copyright (c) 2005-2006 Rexx Language Association. All rights reserved. */ +/* */ +/* This program and the accompanying materials are made available under */ +/* the terms of the Common Public License v1.0 which accompanies this */ +/* distribution. A copy is also available at the following address: */ +/* http://www.oorexx.org/license.html */ +/* */ +/* Redistribution and use in source and binary forms, with or */ +/* without modification, are permitted provided that the following */ +/* conditions are met: */ +/* */ +/* Redistributions of source code must retain the above copyright */ +/* notice, this list of conditions and the following disclaimer. */ +/* Redistributions in binary form must reproduce the above copyright */ +/* notice, this list of conditions and the following disclaimer in */ +/* the documentation and/or other materials provided with the distribution. */ +/* */ +/* Neither the name of Rexx Language Association nor the names */ +/* of its contributors may be used to endorse or promote products */ +/* derived from this software without specific prior written permission. */ +/* */ +/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */ +/* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */ +/* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS */ +/* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */ +/* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */ +/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED */ +/* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, */ +/* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY */ +/* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING */ +/* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS */ +/* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +/* */ +/*----------------------------------------------------------------------------*/ +/******************************************************************************/ +/* REXX AIX/LINUX Support lrxutil.c */ +/* */ +/* AIX system utility functions */ +/* */ +/******************************************************************************/ +/********************************************************************** +* LRXUTIL.C * +* * +* This program extends the REXX language by providing many * +* REXX external functions. * +* These functions are: * +* SysCls -- Clear the screen in an OS/2 fullscreen * +* or windowed command prompt session. * +* SysCurPos -- Set and/or Query the cursor position * +* in an OS/2 fullscreen or windowed * +* command prompt session. * +* SysCurState -- Make the cursor visible or invisible * +* in an OS/2 fullscreen or windowed * +* command prompt session. * +* SysDriveInfo -- Returns information about a specific * +* drive. * +* SysDriveMap -- Returns a list of the drives on the * +* machine * +* SysDropFuncs -- Makes all functions in this package * +* unknown to REXX. * +* SysFileDelete -- Deletes a file * +* SysFileSearch -- Searches for a file matching a given * +* filespec. * +* SysFileTree -- Searches for files matching a given * +* filespec, including files in * +* subdirectories. * +* SysGetKey -- Returns one by of data indicating the * +* key which was pressed, * +* in an OS/2 fullscreen or windowed * +* command prompt session. * +* SysGetMessage -- Retrieves a message text from an OS/2 * +* message file, substituting values * +* provided. * +* SysIni -- Reads and/or updates entries in .INI * +* files. * +* SysLoadFuncs -- Makes all functions in this package * +* known to REXX so REXX programs may * +* call them. * +* SysMkDir -- Creates a directory * +* SysVersion -- Returns the AIX Version number * +* SysLinVer -- Returns the OS/2 Version number * +* SysRmDir -- Removes a directory * +* SysSearchPath -- Searches throught a specified path * +* for a file. * +* SysSleep -- Suspends execution for a number of * +* seconds. * +* SysTempFilename -- Creates a unique filename * +* SysTextScreenRead -- Reads characters from the screen, * +* in an OS/2 fullscreen or windowed * +* command prompt session. * +* SysTextScreenSize -- Returns the size of the window in * +* rows and columns, * +* in an OS/2 fullscreen or windowed * +* command prompt session. * +*EX SysGetEA -- Reads an extended attribute * +* for a file. * +*EX SysPutEA -- Writes an extended attribute * +* for a file. * +*EX SysWaitNamedPipe -- Wait on a named pipe. * +*EX SysSetIcon -- Set a file icon * +*EX SysRegisterObjectClass -- Register a new object class * +*EX SysDeregisterObjectClass -- Remove class registration * +*EX SysQueryClassList -- Get list of registered classes * +*EX SysCreateObject -- Create an object instance * +*EX SysDestroyObject -- Delete an object instance * +*EX SysSetObjectData -- Change object settings data * +*EX SysElapsedTime -- Return the OS/2 elapsed time count * +*EX SysBootDrive -- Return the OS/2 boot drive * +*EX SysQueryEAList -- Return list of file EA names * +*EX SysWildCard -- Perform file wild card editting * +*EX SysFileSystemType -- Return drive file system type * +*EX SysAddFileHandle -- Add file handles to a process * +*EX SysSetFileHandle -- Set file handles for a process * +* SysCreateMutexSem -- Create a Mutex semaphore * +* SysOpenMutexSem -- Open a Mutex semaphore * +* SysCloseMutexSem -- Close a Mutex semaphore * +* SysRequestMutexSem -- Request a Mutex semaphore * +* SysReleaseMutexSem -- Release a Mutex semaphore * +* SysCreateEventSem -- Create an Event semaphore * +* SysOpenEventSem -- Open an Event semaphore * +* SysCloseEventSem -- Close an Event semaphore * +* SysPostEventSem -- Post an Event semaphore * +* SysResetEventSem -- Reset an Event semaphore * +* SysWaitEventSem -- Wait on an Event semaphore * +*EX SysProcessType -- Return type of process * +*EX SysSetPriority -- Set current thread priority * +*EX SysGetCollate -- Get country/codepage collating sequence* +*EX SysNationalLanguageCompare -- NLS strict compare * +*EX SysMapCase -- NLS uppercasing * +*EX SysSetProcessCodePage -- Set current code page * +*EX SysQueryProcessCodePage -- Get current code page * +* SysAddRexxMacro -- Load program into macro space * +* SysDropRexxMacro -- Drop program from macro space * +* SysReorderRexxMacro -- Reorder program in macro space * +* SysQueryRexxMacro -- Query ordering of macro space program * +* SysClearRexxMacroSpace -- Remove all programs from macro space* +* SysLoadRexxMacroSpace -- Load a Rexx macro space * +* SysSaveRexxMacroSpace -- Save a Rexx macro space * +*EX SysShutDownSystem -- Shutdown the system * +*EX SysSwitchSession -- Switch to a named session * +*EX SysDropLibrary -- Drop a function package * +* EX SysPi -- Return Pi to given precision * +* EX SysSqrt -- Calculate a square root * +* EX SysExp -- Calculate an exponent * +* EX SysLog -- Return natural log of a number * +* EX SysLog10 -- Return log base 10 of a number * +* EX SysSinh -- Hyperbolic sine function * +* EX SysCosh -- Hyperbolic cosine function * +* EX SysTanh -- Hyperbolic tangent function * +* EX SysPower -- raise number to non-integer power * +* EX SysSin -- Sine function * +* EX SysCos -- Cosine function * +* EX SysTan -- Tangent function * +* EX SysCotan -- Cotangent function * +* EX SysArcSin -- ArcSine function * +* EX SysArcCos -- ArcCosine function * +* EX SysArcTan -- ArcTangent function * +*EX SysSaveObject -- Save an object either Async or Sync * +*EX SysOpenObject -- Open a view of an object * +*EX SysMoveObject -- Move an object from the existing folder* +* to the destination folder * +*EX SysCopyObject -- Copy an object from the existing folder* +* to the destination folder * +*EX SysCreateShadow -- Create a shadow of an object * +*EX SysWaitForShell -- Wait for WPS initialization * +* (Merlin only). * +*EX SysQuerySwitchList -- query the entries of the switch list * +* (for SysSwitchSession) * +* SysDumpVariables -- Dump current variables to a file * +* SysSetFileDateTime -- Set the last modified date of a file * +* SysGetFileDateTime -- Get the last modified date of a file * +* SysStemSort -- sort a stem array * +* SysStemDelete -- delete items in a stem array * +* SysStemInsert -- insert items into a stem array * +* SysStemCopy -- copy items from one stem array to other* +* SysGetErrortext -- Retrieve textual desc. of error number * +* SysQueryProcess -- Get information on current proc/thread * +* SysUtilVersion -- query version of REXXUTIL.DLL * +* * +* SysAddFuncPkg -- CREXX for AIX function support * +* SysAddCmdPkg -- CREXX for AIX function support * +* SysDropFuncPkg -- CREXX for AIX function support * +* SysDropCmdPkg -- CREXX for AIX function support * +* SysGetpid -- CREXX for AIX function support * +* SysFork -- CREXX for AIX function support * +* SysWait -- CREXX for AIX function support * +* SysCreatePipe -- CREXX for AIX function support * +* * +* SysIsFile -- does file exist? * +* SysIsFileDirectory -- is file a subdirectory? * +* SysIsFileLink -- is file a link? * +* * +**********************************************************************/ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include "PlatformDefinitions.h" +#if defined( HAVE_LOCALE_H ) +# include <locale.h> +#endif + +#include "oorexxapi.h" + +#if defined( HAVE_SYS_WAIT_H ) +# include <sys/wait.h> +#endif + +#include <sys/ipc.h> +#include <memory.h> + +#if defined( HAVE_MALLOC_H ) +# include <malloc.h> +#endif + +#include <fcntl.h> +#include <ctype.h> +#include <string.h> +#include <stdlib.h> +#include <stdio.h> +#include <unistd.h> +#include <limits.h> +#include <math.h> +#include <limits.h> +#include <sys/stat.h> /* mkdir() function */ +#include <errno.h> /* get the errno variable */ +#include <stddef.h> +#include <sys/types.h> +#include <sys/ipc.h> +#include <pthread.h> +#include <semaphore.h> + +#if defined( HAVE_SYS_SEM_H ) +# include <sys/sem.h> +#endif + +#include <dirent.h> /* directory functions */ +#include <sys/time.h> /* needed for the select func */ + +#include <time.h> /* needed for the select func */ + +#if defined( HAVE_SYS_SELECT_H ) +# include <sys/select.h> /* needed for the select func */ +#endif + +#if defined( HAVE_SYS_LDR_H ) +# include <sys/ldr.h> /* needed for the load func */ +#endif + +#if defined( HAVE_STRINGS_H ) +# include <strings.h> +#endif + +#include <utime.h> /* moved, used by AIX & Linux */ + +#if defined( HAVE_SYS_UTSNAME_H ) +# include <sys/utsname.h> /* get the uname() function */ +#endif + +#include <signal.h> + +#if defined( HAVE_SYS_RESOURCE_H ) +# include <sys/resource.h> /* get the getpriority() func */ +#endif + +#if defined( HAVE_FEATURES_H ) +# include <features.h> /* catopen() */ +#endif + +#if defined( HAVE_NL_TYPES_H ) +# include <nl_types.h> /* catopen() */ +#endif + +#include <termios.h> /* needed for SysGetKey */ +#include <fnmatch.h> /* fnmatch() */ + +#if !defined( HAVE_UNION_SEMUN ) +union semun { + int val; + struct semid_ds *buf; + unsigned short *array; +}; +#endif + +extern thread_id_t opencnt[][2]; /* open count array for sems */ +extern char *resolve_tilde(const char *); + +#define INVALID_ROUTINE 40 +#define MAX_DIGITS 9 +#define NO_UTIL_ERROR "0" /* No error whatsoever */ +#define VALID_ROUTINE 0 /* Successful completion */ +//#define MAX_LINE_LEN 2048 /* max line length */ +#define MAX_LINE_LEN 4096 /* max line length */ +#define MAX_READ 0x10000 /* full segment of buffer */ +#define CH_EOF 0x1A /* end of file marker */ +#define CH_CR '\r' /* carriage return character */ +#define CH_NL '\n' /* new line character */ +#define MAX 256 /* temporary buffer length */ +#define IBUF_LEN 4096 /* Input buffer length */ +#define CURRENT_DIR_FIRST 0 /* search flag 'C' */ +#define ENVIRONMENT_ONLY 1 /* search flag 'N' */ +#define OFFSET 1000 /* needed to prevent collision*/ + /* with the return codes */ +#define MAXUSECOUNT 65535 /* max semaphore usecount */ + + +/*********************************************************************/ +/* Various definitions used by the math functions */ +/*********************************************************************/ +#define SINE 0 /* trig function defines... */ +#define COSINE 3 /* the ordering is important, */ +#define TANGENT 1 /* as these get transformed */ +#define COTANGENT 2 /* depending on the angle */ +#define MAXTRIG 3 /* value */ +#define ARCSINE 0 /* defines for arc trig */ +#define ARCCOSINE 1 /* functions. Ordering is */ +#define ARCTANGENT 2 /* not as important here */ + + +#define pi 3.14159265358979323846l /* pi value */ + +#define DEGREES 'D' /* degrees option */ +#define RADIANS 'R' /* radians option */ +#define GRADES 'G' /* grades option */ + +#define DEFAULT_PRECISION 9 /* default precision to use */ +#define MAX_PRECISION 16 /* maximum available precision*/ + + + +/*********************************************************************/ +/* Numeric Error Return Strings */ +/*********************************************************************/ + +#define NO_UTIL_ERROR "0" /* No error whatsoever */ +#define ERROR_NOMEM "2" /* Insufficient memory */ +#define ERROR_FILEOPEN "3" /* Error opening text file */ + +/*********************************************************************/ +/* Alpha Numeric Return Strings */ +/*********************************************************************/ + +#define ERROR_RETSTR "ERROR:" + +/*********************************************************************/ +/* Numeric Return calls */ +/*********************************************************************/ + +#define INVALID_ROUTINE 40 /* Raise Rexx error */ +#define VALID_ROUTINE 0 /* Successful completion */ + +/*********************************************************************/ +/* Defines used by SysStemSort */ +/*********************************************************************/ +#define SORT_CASESENSITIVE 0 +#define SORT_CASEIGNORE 1 + + +#define SORT_ASCENDING 0 +#define SORT_DECENDING 1 + +#define SORT_NUMERIC 3 + +#define SORT_DEF_AVG_SIZE 20 + +/*********************************************************************/ +/* Some useful macros */ +/*********************************************************************/ + +#define BUILDRXSTRING(t, s) { \ + strcpy((t)->strptr,(s));\ + (t)->strlength = strlen((s)); \ +} + + +#define RETVAL(retc) { \ + sprintf(retstr->strptr, "%d", retc); \ + retstr->strlength = strlen(retstr->strptr); \ + return VALID_ROUTINE; \ +} + +/*********************************************************************/ +/* Defines uses by SysTree */ +/*********************************************************************/ + +#define RECURSE 0x0002 +#define DO_DIRS 0x0004 +#define DO_FILES 0x0008 +#define NAME_ONLY 0x0010 +#define EDITABLE_TIME 0x0020 +#define LONG_TIME 0x0040 +#define CASELESS 0x0080 +#define IGNORE 2 /* Ignore attributes entirely */ + + +/******************************************************************************/ +/* Defines used by SysGetKey */ +/******************************************************************************/ + +#define stty(a,b) (void)tcsetattr(a,TCSANOW,b) /* simple set attr. */ +#define gtty(a,b) (void)tcgetattr(a,b) /* simple get attr. */ +#define discard_input(a) tcflush(a,TCIFLUSH) /* simple flush */ +#define restore_tty(a) stty(ttyfd,a) /* new settings STDIN */ + + +/* original terminal settings */ +struct termios in_orig; /* original settings (important!!) */ + + +/*********************************************************************/ +/* RxTree Structure used by SysTree. */ +/*********************************************************************/ + +typedef struct RxTreeData { + size_t count; /* Number of lines processed */ + SHVBLOCK shvb; /* Request block for RxVar */ + size_t stemlen; /* Length of stem */ + size_t vlen; /* Length of variable value */ + char TargetSpec[MAX+1]; /* Target filespec */ + char truefile[MAX+1]; /* expanded file name */ + char Temp[MAX+80]; /* buffer for returned values */ + char varname[MAX]; /* Buffer for variable name */ + size_t nattrib; /* New attrib, diff for each */ +} RXTREEDATA; + + +/*********************************************************************/ +/* RxTree Structure used by GetLine, OpenFile and CloseFile */ +/*********************************************************************/ + +typedef struct _GetFileData { + char * buffer; /* file read buffer */ + size_t size; /* file size */ + size_t data; /* data left in buffer */ + size_t residual; /* size left to read */ + const char *scan; /* current scan position */ + FILE *handle; /* file handle */ +} GetFileData; + +/*********************************************************************/ +/* RxStemData */ +/* Structure which describes as generic */ +/* stem variable. */ +/*********************************************************************/ + +typedef struct RxStemData { + SHVBLOCK shvb; /* Request block for RxVar */ + char ibuf[IBUF_LEN]; /* Input buffer */ + char varname[MAX]; /* Buffer for the variable */ + /* name */ + char stemname[MAX]; /* Buffer for the variable */ + /* name */ + size_t stemlen; /* Length of stem. */ + size_t vlen; /* Length of variable value */ + size_t j; /* Temp counter */ + size_t tlong; /* Temp counter */ + size_t count; /* Number of elements */ + /* processed */ +} RXSTEMDATA; + +/*********************************************************************/ +/* SORTMEM used by SysStemSort */ +/*********************************************************************/ +typedef struct _SORT_MEM { + size_t ulSize; + size_t ulRemaining; + size_t ulItems; + char * pNextBlock; + struct _SORT_MEM *pNext; + char pData; +} SORTMEM, *PSORTMEM; + + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************** +* Function: string2ulong(string, number) * +* * +* Purpose: Validates and converts an ASCII-Z string from string * +* form to an unsigned long. Returns false if the number * +* is not valid, true if the number was successfully * +* converted. * +* * +* RC: true - Good number converted * +* false - Invalid number supplied. * +*********************************************************************/ +bool string2size_t( + const char *string, /* string to convert */ + size_t *number) /* converted number */ +{ + size_t accumulator; /* converted number */ + size_t length; /* length of number */ + + length = strlen(string); /* get length of string */ + if (length == 0 || /* if null string */ + length > MAX_DIGITS + 1) /* or too long */ + return false; /* not valid */ + + accumulator = 0; /* start with zero */ + + while (length) { /* while more digits */ + if (!isdigit(*string)) /* not a digit? */ + return false; /* tell caller */ + /* add to accumulator */ + accumulator = accumulator * 10 + (*string - '0'); + length--; /* reduce length */ + string++; /* step pointer */ + } + *number = accumulator; /* return the value */ + return true; /* good number */ +} + +/*********************************************************************/ +/**************** REXXUTIL Supporting Functions ********************/ +/**************** REXXUTIL Supporting Functions ********************/ +/**************** REXXUTIL Supporting Functions ********************/ +/*********************************************************************/ + +/******************************************************************** +* Function: ReadNextBuffer(filedata) * +* * +* Purpose: Reads the next buffer of data. * +* * +* RC: 0 buffer was read * +* 1 - error occurred reading buffer * +*********************************************************************/ +int ReadNextBuffer( + GetFileData *filedata ) /* global file information */ +{ + size_t size; /* size to read */ + char *endptr; /* end of file pointer */ + /* get size of this read */ + if(filedata->residual >= MAX_READ) + size = MAX_READ; /* read as much as possible */ + else + size = filedata->residual; /* take the rest */ + /* read the file in */ + filedata->data = fread(filedata->buffer, 1, size, filedata->handle); + if(!filedata->data) /* problems ? */ + return (1); /* get out */ + if (filedata->data != size) /* not get all of it? */ + filedata->residual = 0; /* no residual */ + else /* residual is remainder */ + filedata->residual = filedata->residual - size; + /* look for a EOF mark */ + endptr = (char *)memchr(filedata->buffer, CH_EOF, filedata->data); + + if (endptr) { /* found an EOF mark */ + /* set new length */ + filedata->data = (size_t)(endptr - filedata->buffer); + filedata->residual = 0; /* no residual */ + } + filedata->scan = filedata->buffer; /* set position to beginning */ + return 0; +} + +/***********************************************************************/ +/* Function: strupr(string) */ +/* Purpose: Uppercas the given string */ +/***********************************************************************/ +void strupr(char * string){ + + for(;*string != '\0';string++){ /* while not at the end */ + *string = toupper(*string); + } +} + +/******************************************************************** +* Function: OpenFile(file, filedata) * +* * +* Purpose: Prepares a file for reading. * +* * +* RC: 0 - file was opened successfully * +* 1 - file open error occurred * +*********************************************************************/ + +int OpenFile( + const char *file, /* file name */ + GetFileData *filedata ) /* global file information */ +{ + struct stat finfo; /* file information */ + char * endptr = NULL; /* end of buffer pointer */ + + /* try to open the file */ + if((filedata->handle = fopen(file,"r")) == NULL) + return (1); /* return failure */ + /* retrieve the file size */ + if((stat(file,&finfo) == -1)||(!finfo.st_size)){ + fclose(filedata->handle); /* close the file */ + return (1); /* and quit */ + } + if (finfo.st_size <= MAX_READ) { /* less than a single buffer */ + /* allocate buffer for file */ + if((filedata->buffer = (char *)malloc(finfo.st_size)) == NULL ){ + fclose(filedata->handle); /* close the file */ + return (1); /* and quit */ + } + filedata->size = finfo.st_size; /* save file size */ + filedata->residual = 0; /* no left over information */ + /* read the file in */ + filedata->data = fread(filedata->buffer, 1, + finfo.st_size, filedata->handle); + if(filedata->data != (size_t)finfo.st_size){/* problems ? */ + free(filedata->buffer); /* free the buffer */ + fclose(filedata->handle); /* close the file */ + return (1); /* and quit */ + } /* look for a EOF mark */ + endptr = (char *)memchr(filedata->buffer, CH_EOF, filedata->data); + if (endptr) /* found an EOF mark */ + /* set new length */ + filedata->data = (size_t)(endptr - filedata->buffer); + filedata->scan = filedata->buffer; /* set position to beginning */ + } + else { /* need to read partial */ + /* allocate buffer for read */ + if((filedata->buffer = (char *)malloc(MAX_READ)) == NULL ){ + fclose(filedata->handle); /* close the file */ + return (1); /* and quit */ + } + filedata->size = finfo.st_size; /* save file size */ + /* and set remainder */ + filedata->residual = filedata->size; + /* read the file in */ + if (ReadNextBuffer(filedata)) { + free(filedata->buffer); /* free the buffer */ + fclose(filedata->handle); /* close the file */ + return 1; + } + } + return 0; /* file is opened */ +} + +/******************************************************************** +* Function: CloseFile(filedata) * +* * +* Purpose: Close a file * +*********************************************************************/ +void CloseFile( + GetFileData *filedata ) /* global file information */ +{ + fclose(filedata->handle); /* close the file */ + free(filedata->buffer); /* release the file buffer */ +} + +/********************************************************************* +* Function: GetLine(line, size, filedata) * +* * +* Purpose: Reads a line of data using buffered reads. At end of * +* file, zero is returned to indicate nothing left. * +* * +* RC: true - line was read successfully * +* false - end of file was reached * +*********************************************************************/ + +int GetLine( + char *line, /* returned line */ + size_t size, /* size of line buffer */ + GetFileData *filedata ) /* file handle */ +{ + const char *scan; /* current scan pointer */ + size_t length; /* line length */ + size_t copylength; /* copied length */ + + + if (!(filedata->data)) { /* if out of current buffer */ + if (filedata->residual) { /* may be another buffer */ + ReadNextBuffer(filedata); /* try to read one */ + if (!filedata->data) /* nothing more? */ + return 1; /* all done */ + } + else + return (1); /* return EOF condition */ + } + /* look for a line feed */ + scan = (const char *)memchr(filedata->scan, CH_NL, filedata->data); + if (scan) { /* found one */ + /* calculate the length */ + length = scan - filedata->scan; + copylength = length; + if (copylength > size) + { + copylength = size; + } + /* copy over the data */ + memcpy(line, filedata->scan, copylength); + line[copylength] = '\0'; /* make into ASCIIZ string */ + + /* we don't want the CR character in the result string*/ + if ( line[copylength - 1] == CH_CR ) { + line[copylength - 1] = '\0'; + } + + filedata->data -= length + 1; /* reduce the length */ + filedata->scan = scan + 1; /* set new scan point */ + + if (!filedata->data) { /* all used up */ + if (filedata->residual) /* more to read */ + ReadNextBuffer(filedata); /* read the next buffer */ + } + return 0; /* this worked ok */ + } + else /* ran off the end */ + { +/* now we have scanned the whole buffer, but didn't find LF. */ +/* we have two situation that can appear: */ +/* 1.) size > filedata->data ==> there is still room in the working */ +/* buffer, we can see whether we have scanned the whole file */ +/* --> ReadNextBuffer, or this was it, and we return */ +/* 2.) size < filedata->buffer ==> we have scanned to the end of the */ +/* buffer, more than what would fit into it, but still we */ +/* haven't had a hit. So copy all elements into the buffer */ +/* read the next buffer, GetLine to get the next LF */ +/* and return what was put into buffer. Be ALWAYS AWARE that */ +/* that buffer limits to 2047 bytes, and that we only return up */ +/* to 2047 bytes of a line. The rest of the line is not returned */ +/* and not checked for search argument. Nevertheless, this */ +/* garantees, that the line counter (argument 'N') corresponds */ +/* with the input file */ + + /* get length to copy */ + if (size > filedata->data) + { + copylength = filedata->data; /* copy the rest into linebuffer */ + /* copy over the data */ + memcpy(line, filedata->scan, copylength); + line[copylength] = '\0'; /* make into ASCIIZ string */ + + /* all data should be read, filedata->data must be zero */ + filedata->data -= copylength; + /* scan should be at the end */ + filedata->scan += copylength; /* set new scan point */ + + /* if no more data to read in the file, return OK */ + if (!filedata->residual) + return 0; + else + return GetLine(line + copylength, size - copylength, filedata); + } + else /* the line is full, scan until LF found but no copy */ + { + copylength = filedata->data; + if (size < copylength) + { + copylength = size; + } + /* copy over the data */ + memcpy(line, filedata->scan, copylength); + line[copylength] = '\0'; /* make into ASCIIZ string */ + + /* we don't want the CR character in the result string*/ + filedata->data = 0; /* no data in buffer */ + filedata->scan += filedata->data; /* set scan point to end */ + + if (filedata->residual) /* more to read */ + { + ReadNextBuffer(filedata); /* read the next buffer */ + return GetLine(line + copylength, 0, filedata); + } + else + return 0; + } + } +} + +/******************************************************************** +* Function: mystrstr(haystack, needle, hlen, nlen, sensitive) * +* * +* Purpose: Determines if the string 'needle' is in the * +* string 'haystack' by returning it's position or * +* a NULL if not found. The length of haystack and * +* needle are given by 'hlen' and 'nlen' respectively. * +* * +* If 'sensitive' is true, then the search is case * +* sensitive, else it is case insensitive. * +* * +* RC: num - The pos where needle was found. * +* NULL - needle not found. * +* * +* Used By: SysFileSearch() * +*********************************************************************/ + +const char *mystrstr( + const char *haystack, + const char *needle, + size_t hlen, + size_t nlen, + bool sensitive) + +{ + char line[MAX_LINE_LEN]; + char target[MAX_LINE_LEN]; + size_t p; + + /* Copy line - Change nulls to spaces and uppercase if needed */ + + for (p = 0; p < hlen; p++) { + + if (haystack[p] == '\0') + line[p] = ' '; + else if (sensitive) + line[p] = haystack[p]; + else line[p] = toupper(haystack[p]); + } + line[p] = '\0'; + /* Copy target - Change nulls to spaces and uppercase if needed */ + + for (p = 0; p < nlen; p++) { + + if (needle[p] == '\0') + target[p] = ' '; + else if (sensitive) + target[p] = needle[p]; + else target[p] = toupper(needle[p]); + } + target[p] = '\0'; + const char *hit = strstr(line, target); + if (hit == NULL) + { + return NULL; + } + // adjust original pointer to offset + return haystack + (hit - line); +} + +/************************************************************************* +* Function: get_next_path * +* * +* Purpose: Read one path out of an environment value pointed to by * +* ppenv. * +* Used by the 'SearchPath' func. * +* Return: 0 - read successful * +* 1 - end of environment entry * +*************************************************************************/ +int get_next_path( + char * *ppenv, /* environment pointer */ + char * path_buf) /* path buffer */ +{ + int i; /* counter */ + + if(*ppenv == NULL) /* environment entry available ? */ + return (1); /* return end of envrionment */ + if(**ppenv == ':') /* if we point to the seperator */ + (*ppenv)++; /* jump over */ + if(**ppenv == '\0') /* if end of environment entry */ + return (1); /* return so */ + /* copy the path out of the */ + /* environment entry */ + for(i=0;(**ppenv != ':')&&(**ppenv != '\0');(*ppenv)++){ + if(i>MAX_LINE_LEN) /* if buffer to short */ + return (1); /* get out */ + path_buf[i++] = **ppenv; /* copy this character */ + } + path_buf[i] = '\0'; /* terminate the string */ + return (0); /* found another path */ +} + +/************************************************************************* +* Function: SearchPath * +* * +* Purpose: Search a file along the given environment entry and return * +* the full filespec if found. * +* * +* Return: 0 - found the file(=>buf is modified) * +* 1 - not found * +*************************************************************************/ +int SearchPath( + int SearchFlag, /* search curr dir first ? */ + const char * path, /* environment variable name */ + const char * filename, /* searched file */ + char * buf, /* returned filespec if found */ + size_t buf_size) /* size of the return buffer */ +{ + + int rc = 1; /* init rc to not found */ + DIR *dp; /* directory pointer */ + struct dirent *ep; /* directory entry pointer */ + int length; /* path length */ + char path_buf[IBUF_LEN]; /* current search path */ + char * penv; /* ptr to the environment */ + + if(!SearchFlag){ /* search curr dir first ? */ + dp = opendir("./"); /* open current directory */ + if(dp != NULL){ /* worked well ? */ + while((ep = readdir(dp))){ /* while entries in the dir */ + /* if we have a match */ + if(!strcmp(ep->d_name,filename)){ + if(!getcwd(buf,buf_size)) /* copy the cwd to return buf */ + return rc; /* failed, get out */ + length = strlen(buf); /* get the length of the path */ + if((length+2+strlen(filename))>buf_size)/* check buf space */ + return rc; /* not enough, get out */ + buf[length] = '/'; /* add a slash */ + buf[length+1] = '\0'; /* and update the terminater */ + strcat(buf,filename); /* now complete the filespec */ + rc = 0; /* Yep,found ! */ + } + } + (void)closedir(dp); /* close the directory */ + } + } + if(!rc) /* if we already found it */ + return rc; /* return to caller */ + + /* Now search along the environment entry */ + penv = getenv(path); /* get the environment entry */ + if(!penv) /* if couldn't get the env */ + return rc; /* get out */ + /* while we have another path */ + /* to search for the file */ + while(!get_next_path(&penv,path_buf)){ + dp = opendir(path_buf); /* open the directory */ + if(dp != NULL){ /* worked well ? */ + while((ep = readdir(dp))){ /* while entries in the dir */ + /* if we have a match */ + if(!strcmp(ep->d_name,filename)){ + if(strlen(path_buf)>buf_size)/* check the size */ + return rc; /* get out */ + strcpy(buf,path_buf); /* copy path to the return buf*/ + length = strlen(buf); /* get the length of the path */ + if((length+2+strlen(filename))>buf_size)/* check buf space */ + return rc; /* not enough, get out */ + buf[length] = '/'; /* add a slash */ + buf[length+1] = '\0'; /* and update the terminater */ + strcat(buf,filename); /* now complete the filespec */ + (void)closedir(dp); /* close the directory */ + return 0; /* Yep,found ! */ + } + } + (void)closedir(dp); /* close the directory */ + } + } + return rc; /* return not found */ +} + + +/***************************************************************** +* Function: getpath(string, path, filename) * +* * +* Purpose: This function gets the PATH and FILENAME of the file * +* target contained in STRING. The path will end with * +* the '/' char if a path is supplied. * +* * +*****************************************************************/ + +void getpath( + char *string, + char *path, + char *filename ) +{ + int iLen; /* length of filespec */ + int LastSlashPos; /* position of last slash */ + char szSavePath[IBUF_LEN]; /* Keep path to get back to */ + + if (!strcmp(string, ".")) /* period case? */ + strcpy(string, "./*"); /* make it a * request */ + else if (!strcmp(string, "..")) /* double period case? */ + strcpy(string, "../*"); /* make it a ../ * request */ + iLen = strlen(string); /* Get length of full file */ + /* spec */ + LastSlashPos = iLen-1; /* Get max pos of last '/' */ + + /* Step back through string until it begins or at last '/' char */ + do + LastSlashPos--; + while((string[LastSlashPos] != '/') && (LastSlashPos>=0)); + + if (string[LastSlashPos] == '/'){ /* if we have a slash */ + /* Get file name from filespec (just after last '/') */ + if (string[LastSlashPos+1]) /* have a real name? */ + /* copy it over */ + strcpy(filename, &string[LastSlashPos+1]); + else + strcpy(filename, "*"); /* just use wildcards */ + } + else { /* no '/' just filename */ + strcpy(filename, &string[LastSlashPos+1]); + } + + /* Now resolve to fully qualified path ---------------------------- */ + iLen = strlen(filename); /* Get file name length */ + if (string[LastSlashPos] != '/') /* if we have no slash */ + { /* resolve current dir */ + if (!getcwd(path, (IBUF_LEN - iLen - 2))) + strcpy(path, "./"); /* if no cwd set current dir */ + else + strcat(path, "/"); + } + else { /* there is path info */ + strncpy(path, string, LastSlashPos+1);/* copy the path out */ + *(path+LastSlashPos+1) = '\0'; /* make ASCII-Z string */ + if (getcwd(szSavePath, (IBUF_LEN - 1 ))) + { + if (!chdir(path)) /* If successful get */ + { /* reolved path name */ + if ((getcwd(path, (IBUF_LEN - iLen - 2 ))) && + ( LastSlashPos > 0 )) + strcat(path, "/"); /* Add if not root dir */ + chdir(szSavePath); /* Back to current dir */ + } + } + } +} + + +/***************************************************************************** +* Function: LinFindNextFile(path, dir_handle, finfo, d_name, caseless) * +* * +* Purpose: This function finds the next file in the directory PATH pointed * +* by DIR_HANDLE which matchs the filespec. All needed info is * +* returned via the FINFO struct and the D_NAME pointer. * +* * +* Note: '?' is currently not supported. Add the impletmentation here ! * +******************************************************************************/ +int LinFindNextFile( + const char * filespec, /* filespec to search for */ + const char * path, /* current path */ + DIR *dir_handle, /* directory handle */ + struct stat *finfo, /* return buf for the finfo */ + char * *d_name, /* name of the file found */ + size_t caseless) /* case insensitive matching */ +{ + struct dirent *dir_entry; /* Directory entry */ + char full_path[IBUF_LEN+1]; + /* strtok routine */ + + if(!(dir_entry = readdir(dir_handle)))/* get first entry */ + return 0; /* no entry or EOF */ + + do{ + + /* make full spec */ + sprintf(full_path, "%s%s", path, dir_entry->d_name); + lstat(full_path, finfo); /* read the info about it */ + + if(S_ISREG(finfo->st_mode) || /* if it is a file */ + S_ISCHR(finfo->st_mode) || /* or a device special */ + S_ISBLK(finfo->st_mode) || /* file */ + S_ISSOCK(finfo->st_mode) || /* or a socket */ + S_ISLNK(finfo->st_mode) || /* or a symbolic link */ + S_ISFIFO(finfo->st_mode)){ /* or a FIFO */ + + if (caseless) { /* if caseless search */ + char dup_d_name[IBUF_LEN+1]; /* compare upper cased copy */ + char * pDest = dup_d_name; /* of the entry name */ + char * pSrc = dir_entry->d_name; + + for ( ; *pSrc; pDest++, pSrc++ ) + *pDest = toupper(*pSrc); + *pDest = '\x0'; + + if(fnmatch(filespec,dup_d_name,FNM_NOESCAPE|FNM_PATHNAME|FNM_PERIOD)==0){ + *d_name = dir_entry->d_name; /* retptr to the name location*/ + return 1; /* return success */ + } + } + else { /* else compare normally */ + if(fnmatch(filespec,dir_entry->d_name,FNM_NOESCAPE|FNM_PATHNAME|FNM_PERIOD)==0){ + *d_name = dir_entry->d_name; /* retptr to the name location*/ + return 1; /* return success */ + } + } + } + } + while((dir_entry = readdir(dir_handle)));/* while have entries */ + return 0; /* no file found or EOF ... [truncated message content] |