copy from intranet.
This commit is contained in:
366
libopts/compat/compat.h
Normal file
366
libopts/compat/compat.h
Normal file
@@ -0,0 +1,366 @@
|
||||
/* -*- Mode: C -*- */
|
||||
|
||||
/* compat.h --- fake the preprocessor into handlng portability
|
||||
*
|
||||
* Time-stamp: "2008-06-14 09:36:25 bkorb"
|
||||
*
|
||||
* $Id: compat.h,v 4.22 2009/01/01 16:49:26 bkorb Exp $
|
||||
*
|
||||
* compat.h is free software.
|
||||
* This file is part of AutoGen.
|
||||
*
|
||||
* AutoGen copyright (c) 1992-2009 by Bruce Korb - all rights reserved
|
||||
*
|
||||
* AutoGen is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* AutoGen is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* As a special exception, Bruce Korb gives permission for additional
|
||||
* uses of the text contained in the release of compat.h.
|
||||
*
|
||||
* The exception is that, if you link the compat.h library with other
|
||||
* files to produce an executable, this does not by itself cause the
|
||||
* resulting executable to be covered by the GNU General Public License.
|
||||
* Your use of that executable is in no way restricted on account of
|
||||
* linking the compat.h library code into it.
|
||||
*
|
||||
* This exception does not however invalidate any other reasons why
|
||||
* the executable file might be covered by the GNU General Public License.
|
||||
*
|
||||
* This exception applies only to the code released by Bruce Korb under
|
||||
* the name compat.h. If you copy code from other sources under the
|
||||
* General Public License into a copy of compat.h, as the General Public
|
||||
* License permits, the exception does not apply to the code that you add
|
||||
* in this way. To avoid misleading anyone as to the status of such
|
||||
* modified files, you must delete this exception notice from them.
|
||||
*
|
||||
* If you write modifications of your own for compat.h, it is your choice
|
||||
* whether to permit this exception to apply to your modifications.
|
||||
* If you do not wish that, delete this exception notice.
|
||||
*/
|
||||
#ifndef COMPAT_H_GUARD
|
||||
#define COMPAT_H_GUARD 1
|
||||
|
||||
#if defined(HAVE_CONFIG_H)
|
||||
# include <config.h>
|
||||
|
||||
#elif defined(_WIN32) && !defined(__CYGWIN__)
|
||||
# include "windows-config.h"
|
||||
|
||||
#else
|
||||
# error "compat.h" requires "config.h"
|
||||
choke me.
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef HAVE_STRSIGNAL
|
||||
char * strsignal( int signo );
|
||||
#endif
|
||||
|
||||
#define _GNU_SOURCE 1 /* for strsignal in GNU's libc */
|
||||
#define __USE_GNU 1 /* exact same thing as above */
|
||||
#define __EXTENSIONS__ 1 /* and another way to call for it */
|
||||
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* SYSTEM HEADERS:
|
||||
*/
|
||||
#include <sys/types.h>
|
||||
#ifdef HAVE_SYS_MMAN_H
|
||||
# include <sys/mman.h>
|
||||
#endif
|
||||
#include <sys/param.h>
|
||||
#if HAVE_SYS_PROCSET_H
|
||||
# include <sys/procset.h>
|
||||
#endif
|
||||
#include <sys/stat.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
#if defined( HAVE_SOLARIS_SYSINFO )
|
||||
# include <sys/systeminfo.h>
|
||||
#elif defined( HAVE_UNAME_SYSCALL )
|
||||
# include <sys/utsname.h>
|
||||
#endif
|
||||
|
||||
#ifdef DAEMON_ENABLED
|
||||
# if HAVE_SYS_STROPTS_H
|
||||
# include <sys/stropts.h>
|
||||
# endif
|
||||
|
||||
# if HAVE_SYS_SOCKET_H
|
||||
# include <sys/socket.h>
|
||||
# endif
|
||||
|
||||
# if ! defined(HAVE_SYS_POLL_H) && ! defined(HAVE_SYS_SELECT_H)
|
||||
# error This system cannot support daemon processing
|
||||
Choke Me.
|
||||
# endif
|
||||
|
||||
# if HAVE_SYS_POLL_H
|
||||
# include <sys/poll.h>
|
||||
# endif
|
||||
|
||||
# if HAVE_SYS_SELECT_H
|
||||
# include <sys/select.h>
|
||||
# endif
|
||||
|
||||
# if HAVE_NETINET_IN_H
|
||||
# include <netinet/in.h>
|
||||
# endif
|
||||
|
||||
# if HAVE_SYS_UN_H
|
||||
# include <sys/un.h>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* USER HEADERS:
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
|
||||
/*
|
||||
* Directory opening stuff:
|
||||
*/
|
||||
# if defined (_POSIX_SOURCE)
|
||||
/* Posix does not require that the d_ino field be present, and some
|
||||
systems do not provide it. */
|
||||
# define REAL_DIR_ENTRY(dp) 1
|
||||
# else /* !_POSIX_SOURCE */
|
||||
# define REAL_DIR_ENTRY(dp) (dp->d_ino != 0)
|
||||
# endif /* !_POSIX_SOURCE */
|
||||
|
||||
# if defined (HAVE_DIRENT_H)
|
||||
# include <dirent.h>
|
||||
# define D_NAMLEN(dirent) strlen((dirent)->d_name)
|
||||
# else /* !HAVE_DIRENT_H */
|
||||
# define dirent direct
|
||||
# define D_NAMLEN(dirent) (dirent)->d_namlen
|
||||
# if defined (HAVE_SYS_NDIR_H)
|
||||
# include <sys/ndir.h>
|
||||
# endif /* HAVE_SYS_NDIR_H */
|
||||
# if defined (HAVE_SYS_DIR_H)
|
||||
# include <sys/dir.h>
|
||||
# endif /* HAVE_SYS_DIR_H */
|
||||
# if defined (HAVE_NDIR_H)
|
||||
# include <ndir.h>
|
||||
# endif /* HAVE_NDIR_H */
|
||||
# endif /* !HAVE_DIRENT_H */
|
||||
|
||||
#include <errno.h>
|
||||
#ifdef HAVE_FCNTL_H
|
||||
# include <fcntl.h>
|
||||
#endif
|
||||
#ifndef O_NONBLOCK
|
||||
# define O_NONBLOCK FNDELAY
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_LIBGEN) && defined(HAVE_LIBGEN_H)
|
||||
# include <libgen.h>
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_LIMITS_H) /* this is also in options.h */
|
||||
# include <limits.h>
|
||||
#elif defined(HAVE_SYS_LIMITS_H)
|
||||
# include <sys/limits.h>
|
||||
#endif /* HAVE_LIMITS/SYS_LIMITS_H */
|
||||
|
||||
#include <memory.h>
|
||||
#include <setjmp.h>
|
||||
#include <signal.h>
|
||||
|
||||
#if defined( HAVE_STDINT_H )
|
||||
# include <stdint.h>
|
||||
#elif defined( HAVE_INTTYPES_H )
|
||||
# include <inttypes.h>
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <time.h>
|
||||
|
||||
#ifdef HAVE_UTIME_H
|
||||
# include <utime.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_UNISTD_H
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* FIXUPS and CONVIENCE STUFF:
|
||||
*/
|
||||
#ifdef __cplusplus
|
||||
# define EXTERN extern "C"
|
||||
#else
|
||||
# define EXTERN extern
|
||||
#endif
|
||||
|
||||
/* some systems #def errno! and others do not declare it!! */
|
||||
#ifndef errno
|
||||
extern int errno;
|
||||
#endif
|
||||
|
||||
/* Some machines forget this! */
|
||||
|
||||
# ifndef EXIT_FAILURE
|
||||
# define EXIT_SUCCESS 0
|
||||
# define EXIT_FAILURE 1
|
||||
# endif
|
||||
|
||||
#ifndef NUL
|
||||
# define NUL '\0'
|
||||
#endif
|
||||
|
||||
#ifndef NULL
|
||||
# define NULL 0
|
||||
#endif
|
||||
|
||||
#if !defined (MAXPATHLEN) && defined (HAVE_SYS_PARAM_H)
|
||||
# include <sys/param.h>
|
||||
#endif /* !MAXPATHLEN && HAVE_SYS_PARAM_H */
|
||||
|
||||
#if !defined (MAXPATHLEN) && defined (PATH_MAX)
|
||||
# define MAXPATHLEN PATH_MAX
|
||||
#endif /* !MAXPATHLEN && PATH_MAX */
|
||||
|
||||
#if !defined (MAXPATHLEN) && defined(_MAX_PATH)
|
||||
# define PATH_MAX _MAX_PATH
|
||||
# define MAXPATHLEN _MAX_PATH
|
||||
#endif
|
||||
|
||||
#if !defined (MAXPATHLEN)
|
||||
# define MAXPATHLEN ((size_t)4096)
|
||||
#endif /* MAXPATHLEN */
|
||||
|
||||
#define AG_PATH_MAX ((size_t)MAXPATHLEN)
|
||||
|
||||
#ifndef LONG_MAX
|
||||
# define LONG_MAX ~(1L << (8*sizeof(long) -1))
|
||||
# define INT_MAX ~(1 << (8*sizeof(int) -1))
|
||||
#endif
|
||||
|
||||
#ifndef ULONG_MAX
|
||||
# define ULONG_MAX ~(OUL)
|
||||
# define UINT_MAX ~(OU)
|
||||
#endif
|
||||
|
||||
#ifndef SHORT_MAX
|
||||
# define SHORT_MAX ~(1 << (8*sizeof(short) -1))
|
||||
#else
|
||||
# define USHORT_MAX ~(OUS)
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_INT8_T
|
||||
typedef signed char int8_t;
|
||||
#endif
|
||||
#ifndef HAVE_UINT8_T
|
||||
typedef unsigned char uint8_t;
|
||||
#endif
|
||||
#ifndef HAVE_INT16_T
|
||||
typedef signed short int16_t;
|
||||
#endif
|
||||
#ifndef HAVE_UINT16_T
|
||||
typedef unsigned short uint16_t;
|
||||
#endif
|
||||
#ifndef HAVE_UINT_T
|
||||
typedef unsigned int uint_t;
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_INT32_T
|
||||
# if SIZEOF_INT == 4
|
||||
typedef signed int int32_t;
|
||||
# elif SIZEOF_LONG == 4
|
||||
typedef signed long int32_t;
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_UINT32_T
|
||||
# if SIZEOF_INT == 4
|
||||
typedef unsigned int uint32_t;
|
||||
# elif SIZEOF_LONG == 4
|
||||
typedef unsigned long uint32_t;
|
||||
# else
|
||||
# error Cannot create a uint32_t type.
|
||||
Choke Me.
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_INTPTR_T
|
||||
typedef signed long intptr_t;
|
||||
#endif
|
||||
#ifndef HAVE_UINTPTR_T
|
||||
typedef unsigned long uintptr_t;
|
||||
#endif
|
||||
#ifndef HAVE_SIZE_T
|
||||
typedef unsigned int size_t;
|
||||
#endif
|
||||
#ifndef HAVE_WINT_T
|
||||
typedef unsigned int wint_t;
|
||||
#endif
|
||||
#ifndef HAVE_PID_T
|
||||
typedef signed int pid_t;
|
||||
#endif
|
||||
|
||||
/* redefine these for BSD style string libraries */
|
||||
#ifndef HAVE_STRCHR
|
||||
# define strchr index
|
||||
# define strrchr rindex
|
||||
#endif
|
||||
|
||||
#ifdef USE_FOPEN_BINARY
|
||||
# ifndef FOPEN_BINARY_FLAG
|
||||
# define FOPEN_BINARY_FLAG "b"
|
||||
# endif
|
||||
# ifndef FOPEN_TEXT_FLAG
|
||||
# define FOPEN_TEXT_FLAG "t"
|
||||
# endif
|
||||
#else
|
||||
# ifndef FOPEN_BINARY_FLAG
|
||||
# define FOPEN_BINARY_FLAG
|
||||
# endif
|
||||
# ifndef FOPEN_TEXT_FLAG
|
||||
# define FOPEN_TEXT_FLAG
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef STR
|
||||
# define _STR(s) #s
|
||||
# define STR(s) _STR(s)
|
||||
#endif
|
||||
|
||||
/* ##### Pointer sized word ##### */
|
||||
|
||||
/* FIXME: the MAX stuff in here is broken! */
|
||||
#if SIZEOF_CHARP > SIZEOF_INT
|
||||
typedef long t_word;
|
||||
#define WORD_MAX LONG_MAX
|
||||
#define WORD_MIN LONG_MIN
|
||||
#else /* SIZEOF_CHARP <= SIZEOF_INT */
|
||||
typedef int t_word;
|
||||
#define WORD_MAX INT_MAX
|
||||
#define WORD_MIN INT_MIN
|
||||
#endif
|
||||
|
||||
#endif /* COMPAT_H_GUARD */
|
||||
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: C
|
||||
* c-file-style: "stroustrup"
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
* end of compat/compat.h */
|
||||
338
libopts/compat/pathfind.c
Normal file
338
libopts/compat/pathfind.c
Normal file
@@ -0,0 +1,338 @@
|
||||
/* -*- Mode: C -*- */
|
||||
|
||||
/* pathfind.c --- find a FILE MODE along PATH */
|
||||
|
||||
/*
|
||||
* Author: Gary V Vaughan <gvaughan@oranda.demon.co.uk>
|
||||
* Time-stamp: "2006-09-23 19:46:16 bkorb"
|
||||
* Last Modified: $Date: 2007/10/07 16:54:54 $
|
||||
* by: bkorb
|
||||
*
|
||||
* $Id: pathfind.c,v 4.12 2007/10/07 16:54:54 bkorb Exp $
|
||||
*/
|
||||
|
||||
/* Code: */
|
||||
|
||||
#include "compat.h"
|
||||
#ifndef HAVE_PATHFIND
|
||||
#if defined(__windows__) && !defined(__CYGWIN__)
|
||||
char*
|
||||
pathfind( char const* path,
|
||||
char const* fileName,
|
||||
char const* mode )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
#else
|
||||
|
||||
static char* make_absolute( char const *string, char const *dot_path );
|
||||
static char* canonicalize_pathname( char *path );
|
||||
static char* extract_colon_unit( char* dir, char const *string, int *p_index );
|
||||
|
||||
|
||||
/*=export_func pathfind
|
||||
*
|
||||
* what: fild a file in a list of directories
|
||||
*
|
||||
* ifndef: HAVE_PATHFIND
|
||||
*
|
||||
* arg: + char const* + path + colon separated list of search directories +
|
||||
* arg: + char const* + file + the name of the file to look for +
|
||||
* arg: + char const* + mode + the mode bits that must be set to match +
|
||||
*
|
||||
* ret_type: char*
|
||||
* ret_desc: the path to the located file
|
||||
*
|
||||
* doc:
|
||||
*
|
||||
* pathfind looks for a a file with name "FILE" and "MODE" access
|
||||
* along colon delimited "PATH", and returns the full pathname as a
|
||||
* string, or NULL if not found. If "FILE" contains a slash, then
|
||||
* it is treated as a relative or absolute path and "PATH" is ignored.
|
||||
*
|
||||
* @strong{NOTE}: this function is compiled into @file{libopts} only if
|
||||
* it is not natively supplied.
|
||||
*
|
||||
* The "MODE" argument is a string of option letters chosen from the
|
||||
* list below:
|
||||
* @example
|
||||
* Letter Meaning
|
||||
* r readable
|
||||
* w writable
|
||||
* x executable
|
||||
* f normal file (NOT IMPLEMENTED)
|
||||
* b block special (NOT IMPLEMENTED)
|
||||
* c character special (NOT IMPLEMENTED)
|
||||
* d directory (NOT IMPLEMENTED)
|
||||
* p FIFO (pipe) (NOT IMPLEMENTED)
|
||||
* u set user ID bit (NOT IMPLEMENTED)
|
||||
* g set group ID bit (NOT IMPLEMENTED)
|
||||
* k sticky bit (NOT IMPLEMENTED)
|
||||
* s size nonzero (NOT IMPLEMENTED)
|
||||
* @end example
|
||||
*
|
||||
* example:
|
||||
* To find the "ls" command using the "PATH" environment variable:
|
||||
* @example
|
||||
* #include <stdlib.h>
|
||||
* char* pz_ls = pathfind( getenv("PATH"), "ls", "rx" );
|
||||
* <<do whatever with pz_ls>>
|
||||
* free( pz_ls );
|
||||
* @end example
|
||||
* The path is allocated with @code{malloc(3C)}, so you must @code{free(3C)}
|
||||
* the result. Also, do not use unimplemented file modes. :-)
|
||||
*
|
||||
* err: returns NULL if the file is not found.
|
||||
=*/
|
||||
char*
|
||||
pathfind( char const* path,
|
||||
char const* fileName,
|
||||
char const* mode )
|
||||
{
|
||||
int p_index = 0;
|
||||
int mode_bits = 0;
|
||||
char* pathName = NULL;
|
||||
char zPath[ AG_PATH_MAX + 1 ];
|
||||
|
||||
if (strchr( mode, 'r' )) mode_bits |= R_OK;
|
||||
if (strchr( mode, 'w' )) mode_bits |= W_OK;
|
||||
if (strchr( mode, 'x' )) mode_bits |= X_OK;
|
||||
|
||||
/*
|
||||
* FOR each non-null entry in the colon-separated path, DO ...
|
||||
*/
|
||||
for (;;) {
|
||||
DIR* dirP;
|
||||
char* colon_unit = extract_colon_unit( zPath, path, &p_index );
|
||||
|
||||
/*
|
||||
* IF no more entries, THEN quit
|
||||
*/
|
||||
if (colon_unit == NULL)
|
||||
break;
|
||||
|
||||
dirP = opendir( colon_unit );
|
||||
|
||||
/*
|
||||
* IF the directory is inaccessable, THEN next directory
|
||||
*/
|
||||
if (dirP == NULL)
|
||||
continue;
|
||||
|
||||
/*
|
||||
* FOR every entry in the given directory, ...
|
||||
*/
|
||||
for (;;) {
|
||||
struct dirent *entP = readdir( dirP );
|
||||
|
||||
if (entP == (struct dirent*)NULL)
|
||||
break;
|
||||
|
||||
/*
|
||||
* IF the file name matches the one we are looking for, ...
|
||||
*/
|
||||
if (strcmp( entP->d_name, fileName ) == 0) {
|
||||
char* pzFullName = make_absolute( fileName, colon_unit);
|
||||
|
||||
/*
|
||||
* Make sure we can access it in the way we want
|
||||
*/
|
||||
if (access( pzFullName, mode_bits ) >= 0) {
|
||||
/*
|
||||
* We can, so normalize the name and return it below
|
||||
*/
|
||||
pathName = canonicalize_pathname( pzFullName );
|
||||
}
|
||||
|
||||
free( (void*)pzFullName );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
closedir( dirP );
|
||||
|
||||
if (pathName != NULL)
|
||||
break;
|
||||
}
|
||||
|
||||
return pathName;
|
||||
}
|
||||
|
||||
/*
|
||||
* Turn STRING (a pathname) into an absolute pathname, assuming that
|
||||
* DOT_PATH contains the symbolic location of `.'. This always returns
|
||||
* a new string, even if STRING was an absolute pathname to begin with.
|
||||
*/
|
||||
static char*
|
||||
make_absolute( char const *string, char const *dot_path )
|
||||
{
|
||||
char *result;
|
||||
int result_len;
|
||||
|
||||
if (!dot_path || *string == '/') {
|
||||
result = strdup( string );
|
||||
} else {
|
||||
if (dot_path && dot_path[0]) {
|
||||
result = malloc( 2 + strlen( dot_path ) + strlen( string ) );
|
||||
strcpy( result, dot_path );
|
||||
result_len = strlen( result );
|
||||
if (result[result_len - 1] != '/') {
|
||||
result[result_len++] = '/';
|
||||
result[result_len] = '\0';
|
||||
}
|
||||
} else {
|
||||
result = malloc( 3 + strlen( string ) );
|
||||
result[0] = '.'; result[1] = '/'; result[2] = '\0';
|
||||
result_len = 2;
|
||||
}
|
||||
|
||||
strcpy( result + result_len, string );
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Canonicalize PATH, and return a new path. The new path differs from
|
||||
* PATH in that:
|
||||
*
|
||||
* Multiple `/'s are collapsed to a single `/'.
|
||||
* Leading `./'s are removed.
|
||||
* Trailing `/.'s are removed.
|
||||
* Trailing `/'s are removed.
|
||||
* Non-leading `../'s and trailing `..'s are handled by removing
|
||||
* portions of the path.
|
||||
*/
|
||||
static char*
|
||||
canonicalize_pathname( char *path )
|
||||
{
|
||||
int i, start;
|
||||
char stub_char, *result;
|
||||
|
||||
/* The result cannot be larger than the input PATH. */
|
||||
result = strdup( path );
|
||||
|
||||
stub_char = (*path == '/') ? '/' : '.';
|
||||
|
||||
/* Walk along RESULT looking for things to compact. */
|
||||
i = 0;
|
||||
while (result[i]) {
|
||||
while (result[i] != '\0' && result[i] != '/')
|
||||
i++;
|
||||
|
||||
start = i++;
|
||||
|
||||
/* If we didn't find any slashes, then there is nothing left to
|
||||
* do.
|
||||
*/
|
||||
if (!result[start])
|
||||
break;
|
||||
|
||||
/* Handle multiple `/'s in a row. */
|
||||
while (result[i] == '/')
|
||||
i++;
|
||||
|
||||
#if !defined (apollo)
|
||||
if ((start + 1) != i)
|
||||
#else
|
||||
if ((start + 1) != i && (start != 0 || i != 2))
|
||||
#endif /* apollo */
|
||||
{
|
||||
strcpy( result + start + 1, result + i );
|
||||
i = start + 1;
|
||||
}
|
||||
|
||||
/* Handle backquoted `/'. */
|
||||
if (start > 0 && result[start - 1] == '\\')
|
||||
continue;
|
||||
|
||||
/* Check for trailing `/', and `.' by itself. */
|
||||
if ((start && !result[i])
|
||||
|| (result[i] == '.' && !result[i+1])) {
|
||||
result[--i] = '\0';
|
||||
break;
|
||||
}
|
||||
|
||||
/* Check for `../', `./' or trailing `.' by itself. */
|
||||
if (result[i] == '.') {
|
||||
/* Handle `./'. */
|
||||
if (result[i + 1] == '/') {
|
||||
strcpy( result + i, result + i + 1 );
|
||||
i = (start < 0) ? 0 : start;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Handle `../' or trailing `..' by itself. */
|
||||
if (result[i + 1] == '.' &&
|
||||
(result[i + 2] == '/' || !result[i + 2])) {
|
||||
while (--start > -1 && result[start] != '/')
|
||||
;
|
||||
strcpy( result + start + 1, result + i + 2 );
|
||||
i = (start < 0) ? 0 : start;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!*result) {
|
||||
*result = stub_char;
|
||||
result[1] = '\0';
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Given a string containing units of information separated by colons,
|
||||
* return the next one pointed to by (P_INDEX), or NULL if there are no
|
||||
* more. Advance (P_INDEX) to the character after the colon.
|
||||
*/
|
||||
static char*
|
||||
extract_colon_unit( char* pzDir, char const *string, int *p_index )
|
||||
{
|
||||
char* pzDest = pzDir;
|
||||
int ix = *p_index;
|
||||
|
||||
if (string == NULL)
|
||||
return NULL;
|
||||
|
||||
if ((unsigned)ix >= strlen( string ))
|
||||
return NULL;
|
||||
|
||||
{
|
||||
char const* pzSrc = string + ix;
|
||||
|
||||
while (*pzSrc == ':') pzSrc++;
|
||||
|
||||
for (;;) {
|
||||
char ch = (*(pzDest++) = *(pzSrc++));
|
||||
switch (ch) {
|
||||
case ':':
|
||||
pzDest[-1] = NUL;
|
||||
case NUL:
|
||||
goto copy_done;
|
||||
}
|
||||
|
||||
if ((pzDest - pzDir) >= AG_PATH_MAX)
|
||||
break;
|
||||
} copy_done:;
|
||||
|
||||
ix = pzSrc - string;
|
||||
}
|
||||
|
||||
if (*pzDir == NUL)
|
||||
return NULL;
|
||||
|
||||
*p_index = ix;
|
||||
return pzDir;
|
||||
}
|
||||
#endif /* __windows__ / __CYGWIN__ */
|
||||
#endif /* HAVE_PATHFIND */
|
||||
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: C
|
||||
* c-file-style: "stroustrup"
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
* end of compat/pathfind.c */
|
||||
60
libopts/compat/snprintf.c
Normal file
60
libopts/compat/snprintf.c
Normal file
@@ -0,0 +1,60 @@
|
||||
|
||||
#ifndef HAVE_VPRINTF
|
||||
#include "choke-me: no vprintf and no snprintf"
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_STDARG_H)
|
||||
# include <stdarg.h>
|
||||
# ifndef VA_START
|
||||
# define VA_START(a, f) va_start(a, f)
|
||||
# define VA_END(a) va_end(a)
|
||||
# endif /* VA_START */
|
||||
# define SNV_USING_STDARG_H
|
||||
|
||||
#elif defined(HAVE_VARARGS_H)
|
||||
# include <varargs.h>
|
||||
# ifndef VA_START
|
||||
# define VA_START(a, f) va_start(a)
|
||||
# define VA_END(a) va_end(a)
|
||||
# endif /* VA_START */
|
||||
# undef SNV_USING_STDARG_H
|
||||
|
||||
#else
|
||||
# include "must-have-stdarg-or-varargs"
|
||||
#endif
|
||||
|
||||
static int
|
||||
snprintf(char *str, size_t n, char const *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
int rval;
|
||||
|
||||
#ifdef VSPRINTF_CHARSTAR
|
||||
char *rp;
|
||||
VA_START(ap, fmt);
|
||||
rp = vsprintf(str, fmt, ap);
|
||||
VA_END(ap);
|
||||
rval = strlen(rp);
|
||||
|
||||
#else
|
||||
VA_START(ap, fmt);
|
||||
rval = vsprintf(str, fmt, ap);
|
||||
VA_END(ap);
|
||||
#endif
|
||||
|
||||
if (rval > n) {
|
||||
fprintf(stderr, "snprintf buffer overrun %d > %d\n", rval, (int)n);
|
||||
abort();
|
||||
}
|
||||
return rval;
|
||||
}
|
||||
|
||||
static int
|
||||
vsnprintf( char *str, size_t n, char const *fmt, va_list ap )
|
||||
{
|
||||
#ifdef VSPRINTF_CHARSTAR
|
||||
return (strlen(vsprintf(str, fmt, ap)));
|
||||
#else
|
||||
return (vsprintf(str, fmt, ap));
|
||||
#endif
|
||||
}
|
||||
60
libopts/compat/strchr.c
Normal file
60
libopts/compat/strchr.c
Normal file
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
SYNOPSIS
|
||||
#include <string.h>
|
||||
|
||||
char *strchr(char const *s, int c);
|
||||
|
||||
char *strrchr(char const *s, int c);
|
||||
|
||||
DESCRIPTION
|
||||
The strchr() function returns a pointer to the first occurrence of the
|
||||
character c in the string s.
|
||||
|
||||
The strrchr() function returns a pointer to the last occurrence of the
|
||||
character c in the string s.
|
||||
|
||||
Here "character" means "byte" - these functions do not work with wide
|
||||
or multi-byte characters.
|
||||
|
||||
RETURN VALUE
|
||||
The strchr() and strrchr() functions return a pointer to the matched
|
||||
character or NULL if the character is not found.
|
||||
|
||||
CONFORMING TO
|
||||
SVID 3, POSIX, BSD 4.3, ISO 9899
|
||||
*/
|
||||
|
||||
char*
|
||||
strchr( char const *s, int c)
|
||||
{
|
||||
do {
|
||||
if ((unsigned)*s == (unsigned)c)
|
||||
return s;
|
||||
|
||||
} while (*(++s) != NUL);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char*
|
||||
strrchr( char const *s, int c)
|
||||
{
|
||||
char const *e = s + strlen(s);
|
||||
|
||||
for (;;) {
|
||||
if (--e < s)
|
||||
break;
|
||||
|
||||
if ((unsigned)*e == (unsigned)c)
|
||||
return e;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: C
|
||||
* c-file-style: "stroustrup"
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
* end of compat/strsignal.c */
|
||||
19
libopts/compat/strdup.c
Normal file
19
libopts/compat/strdup.c
Normal file
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Platforms without strdup ?!?!?!
|
||||
*/
|
||||
|
||||
static char *
|
||||
strdup( char const *s )
|
||||
{
|
||||
char *cp;
|
||||
|
||||
if (s == NULL)
|
||||
return NULL;
|
||||
|
||||
cp = (char *) AGALOC((unsigned) (strlen(s)+1), "strdup");
|
||||
|
||||
if (cp != NULL)
|
||||
(void) strcpy(cp, s);
|
||||
|
||||
return cp;
|
||||
}
|
||||
147
libopts/compat/windows-config.h
Normal file
147
libopts/compat/windows-config.h
Normal file
@@ -0,0 +1,147 @@
|
||||
|
||||
/*
|
||||
* Time-stamp: "2009-07-22 18:53:59 bkorb"
|
||||
* by: bkorb
|
||||
* Last Committed: $Date: 2009/07/23 02:05:55 $
|
||||
*
|
||||
* This file is part of AutoGen.
|
||||
*
|
||||
* AutoGen copyright (c) 1992-2009 by Bruce Korb - all rights reserved
|
||||
*
|
||||
* AutoGen is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* AutoGen is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef WINDOWS_CONFIG_HACKERY
|
||||
#define WINDOWS_CONFIG_HACKERY 1
|
||||
|
||||
/*
|
||||
* The definitions below have been stolen from NTP's config.h for Windows.
|
||||
* However, they may be kept here in order to keep libopts independent from
|
||||
* the NTP project.
|
||||
*/
|
||||
#ifndef __windows__
|
||||
# define __windows__ 4
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Miscellaneous functions that Microsoft maps
|
||||
* to other names
|
||||
*
|
||||
* #define inline __inline
|
||||
* #define vsnprintf _vsnprintf
|
||||
*/
|
||||
#define snprintf _snprintf
|
||||
/*
|
||||
* #define stricmp _stricmp
|
||||
* #define strcasecmp _stricmp
|
||||
* #define isascii __isascii
|
||||
* #define finite _finite
|
||||
* #define random rand
|
||||
* #define srandom srand
|
||||
*/
|
||||
|
||||
#define SIZEOF_INT 4
|
||||
#define SIZEOF_CHARP 4
|
||||
#define SIZEOF_LONG 4
|
||||
#define SIZEOF_SHORT 2
|
||||
|
||||
typedef unsigned long uintptr_t;
|
||||
|
||||
/*
|
||||
* # define HAVE_NET_IF_H
|
||||
* # define QSORT_USES_VOID_P
|
||||
* # define HAVE_SETVBUF
|
||||
* # define HAVE_VSPRINTF
|
||||
* # define HAVE_SNPRINTF
|
||||
* # define HAVE_VSNPRINTF
|
||||
* # define HAVE_PROTOTYPES /* from ntpq.mak * /
|
||||
* # define HAVE_MEMMOVE
|
||||
* # define HAVE_TERMIOS_H
|
||||
* # define HAVE_ERRNO_H
|
||||
* # define HAVE_STDARG_H
|
||||
* # define HAVE_NO_NICE
|
||||
* # define HAVE_MKTIME
|
||||
* # define TIME_WITH_SYS_TIME
|
||||
* # define HAVE_IO_COMPLETION_PORT
|
||||
* # define ISC_PLATFORM_NEEDNTOP
|
||||
* # define ISC_PLATFORM_NEEDPTON
|
||||
* # define NEED_S_CHAR_TYPEDEF
|
||||
* # define USE_PROTOTYPES /* for ntp_types.h * /
|
||||
*
|
||||
* #define ULONG_CONST(a) a ## UL
|
||||
*/
|
||||
|
||||
#define HAVE_LIMITS_H 1
|
||||
#define HAVE_STRDUP 1
|
||||
#define HAVE_STRCHR 1
|
||||
#define HAVE_FCNTL_H 1
|
||||
|
||||
/*
|
||||
* VS.NET's version of wspiapi.h has a bug in it
|
||||
* where it assigns a value to a variable inside
|
||||
* an if statement. It should be comparing them.
|
||||
* We prevent inclusion since we are not using this
|
||||
* code so we don't have to see the warning messages
|
||||
*/
|
||||
#ifndef _WSPIAPI_H_
|
||||
#define _WSPIAPI_H_
|
||||
#endif
|
||||
|
||||
/* Prevent inclusion of winsock.h in windows.h */
|
||||
#ifndef _WINSOCKAPI_
|
||||
#define _WINSOCKAPI_
|
||||
#endif
|
||||
|
||||
#ifndef __RPCASYNC_H__
|
||||
#define __RPCASYNC_H__
|
||||
#endif
|
||||
|
||||
/* Include Windows headers */
|
||||
#include <windows.h>
|
||||
#include <winsock2.h>
|
||||
#include <limits.h>
|
||||
|
||||
/*
|
||||
* Compatibility declarations for Windows, assuming SYS_WINNT
|
||||
* has been defined.
|
||||
*/
|
||||
#define strdup _strdup
|
||||
#define stat _stat /* struct stat from <sys/stat.h> */
|
||||
#define unlink _unlink
|
||||
#define fchmod( _x, _y );
|
||||
#define ssize_t SSIZE_T
|
||||
|
||||
#include <io.h>
|
||||
#define open _open
|
||||
#define close _close
|
||||
#define read _read
|
||||
#define write _write
|
||||
#define lseek _lseek
|
||||
#define pipe _pipe
|
||||
#define dup2 _dup2
|
||||
|
||||
#define O_RDWR _O_RDWR
|
||||
#define O_RDONLY _O_RDONLY
|
||||
#define O_EXCL _O_EXCL
|
||||
|
||||
#ifndef S_ISREG
|
||||
# define S_IFREG _S_IFREG
|
||||
# define S_ISREG(mode) (((mode) & S_IFREG) == S_IFREG)
|
||||
#endif
|
||||
|
||||
#ifndef S_ISDIR
|
||||
# define S_IFDIR _S_IFDIR
|
||||
# define S_ISDIR(mode) (((mode) & S_IFDIR) == S_IFDIR)
|
||||
#endif
|
||||
|
||||
#endif /* WINDOWS_CONFIG_HACKERY */
|
||||
Reference in New Issue
Block a user