Added state retention APIs. Implemented for check_snmp with --rate option.

See http://nagiosplugin.org/c-api-private for more details on the API.

Also updated check_snmp -l option to change the perfdata label.
This commit is contained in:
Ton Voon 2010-06-17 10:16:43 +01:00 committed by tonvoon
parent f61412478c
commit 18f6835eda
63 changed files with 2320 additions and 1020 deletions

6
NEWS
View file

@ -5,7 +5,10 @@ This file documents the major additions and syntax changes between releases.
New check_ntp_peer -m and -n options to check the number of usable time sources ("truechimers")
New check_disk_smb -a option which allows for specifying the IP address of the remote server
New check_radius -N option which allows for specifying the value of the NAS-IP-Address attribute
Updated Nagios::Plugin perl module
New check_snmp --rate option to store differences between invocations. Saves state in PREFIX/var/{plugin}
check_snmp -l label option now also changes the perfdata label. See WARNINGS
Updated Nagios::Plugin perl module
Updated gnulib to June 2010
FIXES
Fix check_ircd binding to wrong interface (#668778)
Add proxy-authorization option to check_http (Marcel Kuiper - #1323230, Bryan Irvine - #2863925)
@ -28,6 +31,7 @@ This file documents the major additions and syntax changes between releases.
Updated developer documentation to say that performance labels should not have an equals sign or
single quote in the label
check_http 1.4.14 introduced SSL SNI support - you now have to enable it explicitly with "--sni"
check_snmp -l label option is also used for the performance label. This could change history from previous uses
1.4.14 16th September 2009
check_http has options to specify the HTTP method (#2155152)

View file

@ -221,10 +221,20 @@
_GL_CXXALIASWARN_1 (func, GNULIB_NAMESPACE)
# define _GL_CXXALIASWARN_1(func,namespace) \
_GL_CXXALIASWARN_2 (func, namespace)
# define _GL_CXXALIASWARN_2(func,namespace) \
_GL_WARN_ON_USE (func, \
"The symbol ::" #func " refers to the system function. " \
"Use " #namespace "::" #func " instead.")
/* To work around GCC bug <http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43881>,
we enable the warning only when not optimizing. */
# if !__OPTIMIZE__
# define _GL_CXXALIASWARN_2(func,namespace) \
_GL_WARN_ON_USE (func, \
"The symbol ::" #func " refers to the system function. " \
"Use " #namespace "::" #func " instead.")
# elif __GNUC__ >= 3 && GNULIB_STRICT_CHECKING
# define _GL_CXXALIASWARN_2(func,namespace) \
extern __typeof__ (func) func
# else
# define _GL_CXXALIASWARN_2(func,namespace) \
_GL_EXTERN_C int _gl_cxxalias_dummy
# endif
#else
# define _GL_CXXALIASWARN(func) \
_GL_EXTERN_C int _gl_cxxalias_dummy
@ -239,10 +249,20 @@
GNULIB_NAMESPACE)
# define _GL_CXXALIASWARN1_1(func,rettype,parameters_and_attributes,namespace) \
_GL_CXXALIASWARN1_2 (func, rettype, parameters_and_attributes, namespace)
# define _GL_CXXALIASWARN1_2(func,rettype,parameters_and_attributes,namespace) \
_GL_WARN_ON_USE_CXX (func, rettype, parameters_and_attributes, \
"The symbol ::" #func " refers to the system function. " \
"Use " #namespace "::" #func " instead.")
/* To work around GCC bug <http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43881>,
we enable the warning only when not optimizing. */
# if !__OPTIMIZE__
# define _GL_CXXALIASWARN1_2(func,rettype,parameters_and_attributes,namespace) \
_GL_WARN_ON_USE_CXX (func, rettype, parameters_and_attributes, \
"The symbol ::" #func " refers to the system function. " \
"Use " #namespace "::" #func " instead.")
# elif __GNUC__ >= 3 && GNULIB_STRICT_CHECKING
# define _GL_CXXALIASWARN1_2(func,rettype,parameters_and_attributes,namespace) \
extern __typeof__ (func) func
# else
# define _GL_CXXALIASWARN1_2(func,rettype,parameters_and_attributes,namespace) \
_GL_EXTERN_C int _gl_cxxalias_dummy
# endif
#else
# define _GL_CXXALIASWARN1(func,rettype,parameters_and_attributes) \
_GL_EXTERN_C int _gl_cxxalias_dummy

View file

@ -67,7 +67,10 @@
/* A compiler attribute is available in gcc versions 4.3.0 and later. */
# define _GL_WARN_ON_USE(function, message) \
extern __typeof__ (function) function __attribute__ ((__warning__ (message)))
# elif __GNUC__ >= 3 && GNULIB_STRICT_CHECKING
/* Verify the existence of the function. */
# define _GL_WARN_ON_USE(function, message) \
extern __typeof__ (function) function
# else /* Unsupported. */
# define _GL_WARN_ON_USE(function, message) \
_GL_WARN_EXTERN_C int _gl_warn_on_use
@ -85,6 +88,10 @@ _GL_WARN_EXTERN_C int _gl_warn_on_use
# define _GL_WARN_ON_USE_CXX(function,rettype,parameters_and_attributes,msg) \
extern rettype function parameters_and_attributes \
__attribute__ ((__warning__ (msg)))
# elif __GNUC__ >= 3 && GNULIB_STRICT_CHECKING
/* Verify the existence of the function. */
# define _GL_WARN_ON_USE_CXX(function,rettype,parameters_and_attributes,msg) \
extern rettype function parameters_and_attributes
# else /* Unsupported. */
# define _GL_WARN_ON_USE_CXX(function,rettype,parameters_and_attributes,msg) \
_GL_WARN_EXTERN_C int _gl_warn_on_use

View file

@ -9,7 +9,7 @@
# the same distribution terms as the rest of that program.
#
# Generated by gnulib-tool.
# Reproduce by: gnulib-tool --import --dir=. --lib=libgnu --source-base=gl --m4-base=gl/m4 --doc-base=doc --tests-base=tests --aux-dir=build-aux --no-libtool --macro-prefix=gl base64 dirname floorf fsusage getaddrinfo gethostname getloadavg getopt gettext mountlist regex timegm vasprintf vsnprintf
# Reproduce by: gnulib-tool --import --dir=. --lib=libgnu --source-base=gl --m4-base=gl/m4 --doc-base=doc --tests-base=tests --aux-dir=build-aux --no-libtool --macro-prefix=gl --no-vc-files base64 crypto/sha1 dirname floorf fsusage getaddrinfo gethostname getloadavg getopt gettext mountlist regex timegm vasprintf vsnprintf
AUTOMAKE_OPTIONS = 1.5 gnits
@ -44,17 +44,6 @@ EXTRA_DIST += alignof.h
## end gnulib module alignof
## begin gnulib module alloca
EXTRA_DIST += alloca.c
EXTRA_libgnu_a_SOURCES += alloca.c
libgnu_a_LIBADD += @ALLOCA@
libgnu_a_DEPENDENCIES += @ALLOCA@
## end gnulib module alloca
## begin gnulib module alloca-opt
BUILT_SOURCES += $(ALLOCA_H)
@ -253,6 +242,15 @@ CLEANFILES += configmake.h configmake.h-t
## end gnulib module configmake
## begin gnulib module crypto/sha1
EXTRA_DIST += sha1.c sha1.h
EXTRA_libgnu_a_SOURCES += sha1.c
## end gnulib module crypto/sha1
## begin gnulib module dirname
@ -833,11 +831,11 @@ EXTRA_libgnu_a_SOURCES += mountlist.c
## begin gnulib module netdb
BUILT_SOURCES += $(NETDB_H)
BUILT_SOURCES += netdb.h
# We need the following in order to create <netdb.h> when the system
# doesn't have one that works with the given compiler.
netdb.h: netdb.in.h $(ARG_NONNULL_H)
netdb.h: netdb.in.h $(ARG_NONNULL_H) $(WARN_ON_USE_H)
$(AM_V_GEN)rm -f $@-t $@ && \
{ echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \
sed -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \
@ -851,6 +849,7 @@ netdb.h: netdb.in.h $(ARG_NONNULL_H)
-e 's|@''HAVE_DECL_GETADDRINFO''@|$(HAVE_DECL_GETADDRINFO)|g' \
-e 's|@''HAVE_DECL_GETNAMEINFO''@|$(HAVE_DECL_GETNAMEINFO)|g' \
-e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \
-e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \
< $(srcdir)/netdb.in.h; \
} > $@-t && \
mv $@-t $@
@ -1140,6 +1139,7 @@ stdio.h: stdio.in.h $(CXXDEFS_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H)
-e 's|@''REPLACE_VPRINTF''@|$(REPLACE_VPRINTF)|g' \
-e 's|@''REPLACE_VSNPRINTF''@|$(REPLACE_VSNPRINTF)|g' \
-e 's|@''REPLACE_VSPRINTF''@|$(REPLACE_VSPRINTF)|g' \
-e 's|@''ASM_SYMBOL_PREFIX''@|$(ASM_SYMBOL_PREFIX)|g' \
-e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \
-e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \
-e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)'; \
@ -1333,6 +1333,7 @@ string.h: string.in.h $(CXXDEFS_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H)
-e 's|@''REPLACE_STRERROR''@|$(REPLACE_STRERROR)|g' \
-e 's|@''REPLACE_STRNCAT''@|$(REPLACE_STRNCAT)|g' \
-e 's|@''REPLACE_STRNDUP''@|$(REPLACE_STRNDUP)|g' \
-e 's|@''REPLACE_STRNLEN''@|$(REPLACE_STRNLEN)|g' \
-e 's|@''REPLACE_STRSIGNAL''@|$(REPLACE_STRSIGNAL)|g' \
-e 's|@''REPLACE_STRTOK_R''@|$(REPLACE_STRTOK_R)|g' \
-e 's|@''UNDEFINE_STRTOK_R''@|$(UNDEFINE_STRTOK_R)|g' \
@ -1506,6 +1507,7 @@ time.h: time.in.h $(CXXDEFS_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H)
-e 's|@''REPLACE_MKTIME''@|$(REPLACE_MKTIME)|g' \
-e 's|@''REPLACE_NANOSLEEP''@|$(REPLACE_NANOSLEEP)|g' \
-e 's|@''REPLACE_TIMEGM''@|$(REPLACE_TIMEGM)|g' \
-e 's|@''PTHREAD_H_DEFINES_STRUCT_TIMESPEC''@|$(PTHREAD_H_DEFINES_STRUCT_TIMESPEC)|g' \
-e 's|@''SYS_TIME_H_DEFINES_STRUCT_TIMESPEC''@|$(SYS_TIME_H_DEFINES_STRUCT_TIMESPEC)|g' \
-e 's|@''TIME_H_DEFINES_STRUCT_TIMESPEC''@|$(TIME_H_DEFINES_STRUCT_TIMESPEC)|g' \
-e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \
@ -1577,6 +1579,7 @@ unistd.h: unistd.in.h $(CXXDEFS_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H)
-e 's|@''GNULIB_LSEEK''@|$(GNULIB_LSEEK)|g' \
-e 's|@''GNULIB_PIPE2''@|$(GNULIB_PIPE2)|g' \
-e 's|@''GNULIB_PREAD''@|$(GNULIB_PREAD)|g' \
-e 's|@''GNULIB_PWRITE''@|$(GNULIB_PWRITE)|g' \
-e 's|@''GNULIB_READLINK''@|$(GNULIB_READLINK)|g' \
-e 's|@''GNULIB_READLINKAT''@|$(GNULIB_READLINKAT)|g' \
-e 's|@''GNULIB_RMDIR''@|$(GNULIB_RMDIR)|g' \
@ -1611,6 +1614,7 @@ unistd.h: unistd.in.h $(CXXDEFS_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H)
-e 's|@''HAVE_LINKAT''@|$(HAVE_LINKAT)|g' \
-e 's|@''HAVE_PIPE2''@|$(HAVE_PIPE2)|g' \
-e 's|@''HAVE_PREAD''@|$(HAVE_PREAD)|g' \
-e 's|@''HAVE_PWRITE''@|$(HAVE_PWRITE)|g' \
-e 's|@''HAVE_READLINK''@|$(HAVE_READLINK)|g' \
-e 's|@''HAVE_READLINKAT''@|$(HAVE_READLINKAT)|g' \
-e 's|@''HAVE_SLEEP''@|$(HAVE_SLEEP)|g' \
@ -1638,10 +1642,12 @@ unistd.h: unistd.in.h $(CXXDEFS_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H)
-e 's|@''REPLACE_LINKAT''@|$(REPLACE_LINKAT)|g' \
-e 's|@''REPLACE_LSEEK''@|$(REPLACE_LSEEK)|g' \
-e 's|@''REPLACE_PREAD''@|$(REPLACE_PREAD)|g' \
-e 's|@''REPLACE_PWRITE''@|$(REPLACE_PWRITE)|g' \
-e 's|@''REPLACE_READLINK''@|$(REPLACE_READLINK)|g' \
-e 's|@''REPLACE_RMDIR''@|$(REPLACE_RMDIR)|g' \
-e 's|@''REPLACE_SLEEP''@|$(REPLACE_SLEEP)|g' \
-e 's|@''REPLACE_SYMLINK''@|$(REPLACE_SYMLINK)|g' \
-e 's|@''REPLACE_TTYNAME_R''@|$(REPLACE_TTYNAME_R)|g' \
-e 's|@''REPLACE_UNLINK''@|$(REPLACE_UNLINK)|g' \
-e 's|@''REPLACE_UNLINKAT''@|$(REPLACE_UNLINKAT)|g' \
-e 's|@''REPLACE_USLEEP''@|$(REPLACE_USLEEP)|g' \

View file

@ -1,489 +0,0 @@
/* alloca.c -- allocate automatically reclaimed memory
(Mostly) portable public-domain implementation -- D A Gwyn
This implementation of the PWB library alloca function,
which is used to allocate space off the run-time stack so
that it is automatically reclaimed upon procedure exit,
was inspired by discussions with J. Q. Johnson of Cornell.
J.Otto Tennant <jot@cray.com> contributed the Cray support.
There are some preprocessor constants that can
be defined when compiling for your specific system, for
improved efficiency; however, the defaults should be okay.
The general concept of this implementation is to keep
track of all alloca-allocated blocks, and reclaim any
that are found to be deeper in the stack than the current
invocation. This heuristic does not reclaim storage as
soon as it becomes invalid, but it will do so eventually.
As a special case, alloca(0) reclaims storage without
allocating any. It is a good idea to use alloca(0) in
your main control loop, etc. to force garbage collection. */
#include <config.h>
#include <alloca.h>
#include <string.h>
#include <stdlib.h>
#ifdef emacs
# include "lisp.h"
# include "blockinput.h"
# ifdef EMACS_FREE
# undef free
# define free EMACS_FREE
# endif
#else
# define memory_full() abort ()
#endif
/* If compiling with GCC 2, this file's not needed. */
#if !defined (__GNUC__) || __GNUC__ < 2
/* If someone has defined alloca as a macro,
there must be some other way alloca is supposed to work. */
# ifndef alloca
# ifdef emacs
# ifdef static
/* actually, only want this if static is defined as ""
-- this is for usg, in which emacs must undefine static
in order to make unexec workable
*/
# ifndef STACK_DIRECTION
you
lose
-- must know STACK_DIRECTION at compile-time
/* Using #error here is not wise since this file should work for
old and obscure compilers. */
# endif /* STACK_DIRECTION undefined */
# endif /* static */
# endif /* emacs */
/* If your stack is a linked list of frames, you have to
provide an "address metric" ADDRESS_FUNCTION macro. */
# if defined (CRAY) && defined (CRAY_STACKSEG_END)
long i00afunc ();
# define ADDRESS_FUNCTION(arg) (char *) i00afunc (&(arg))
# else
# define ADDRESS_FUNCTION(arg) &(arg)
# endif
/* Define STACK_DIRECTION if you know the direction of stack
growth for your system; otherwise it will be automatically
deduced at run-time.
STACK_DIRECTION > 0 => grows toward higher addresses
STACK_DIRECTION < 0 => grows toward lower addresses
STACK_DIRECTION = 0 => direction of growth unknown */
# ifndef STACK_DIRECTION
# define STACK_DIRECTION 0 /* Direction unknown. */
# endif
# if STACK_DIRECTION != 0
# define STACK_DIR STACK_DIRECTION /* Known at compile-time. */
# else /* STACK_DIRECTION == 0; need run-time code. */
static int stack_dir; /* 1 or -1 once known. */
# define STACK_DIR stack_dir
static void
find_stack_direction (void)
{
static char *addr = NULL; /* Address of first `dummy', once known. */
auto char dummy; /* To get stack address. */
if (addr == NULL)
{ /* Initial entry. */
addr = ADDRESS_FUNCTION (dummy);
find_stack_direction (); /* Recurse once. */
}
else
{
/* Second entry. */
if (ADDRESS_FUNCTION (dummy) > addr)
stack_dir = 1; /* Stack grew upward. */
else
stack_dir = -1; /* Stack grew downward. */
}
}
# endif /* STACK_DIRECTION == 0 */
/* An "alloca header" is used to:
(a) chain together all alloca'ed blocks;
(b) keep track of stack depth.
It is very important that sizeof(header) agree with malloc
alignment chunk size. The following default should work okay. */
# ifndef ALIGN_SIZE
# define ALIGN_SIZE sizeof(double)
# endif
typedef union hdr
{
char align[ALIGN_SIZE]; /* To force sizeof(header). */
struct
{
union hdr *next; /* For chaining headers. */
char *deep; /* For stack depth measure. */
} h;
} header;
static header *last_alloca_header = NULL; /* -> last alloca header. */
/* Return a pointer to at least SIZE bytes of storage,
which will be automatically reclaimed upon exit from
the procedure that called alloca. Originally, this space
was supposed to be taken from the current stack frame of the
caller, but that method cannot be made to work for some
implementations of C, for example under Gould's UTX/32. */
void *
alloca (size_t size)
{
auto char probe; /* Probes stack depth: */
register char *depth = ADDRESS_FUNCTION (probe);
# if STACK_DIRECTION == 0
if (STACK_DIR == 0) /* Unknown growth direction. */
find_stack_direction ();
# endif
/* Reclaim garbage, defined as all alloca'd storage that
was allocated from deeper in the stack than currently. */
{
register header *hp; /* Traverses linked list. */
# ifdef emacs
BLOCK_INPUT;
# endif
for (hp = last_alloca_header; hp != NULL;)
if ((STACK_DIR > 0 && hp->h.deep > depth)
|| (STACK_DIR < 0 && hp->h.deep < depth))
{
register header *np = hp->h.next;
free (hp); /* Collect garbage. */
hp = np; /* -> next header. */
}
else
break; /* Rest are not deeper. */
last_alloca_header = hp; /* -> last valid storage. */
# ifdef emacs
UNBLOCK_INPUT;
# endif
}
if (size == 0)
return NULL; /* No allocation required. */
/* Allocate combined header + user data storage. */
{
/* Address of header. */
register header *new;
size_t combined_size = sizeof (header) + size;
if (combined_size < sizeof (header))
memory_full ();
new = malloc (combined_size);
if (! new)
memory_full ();
new->h.next = last_alloca_header;
new->h.deep = depth;
last_alloca_header = new;
/* User storage begins just after header. */
return (void *) (new + 1);
}
}
# if defined (CRAY) && defined (CRAY_STACKSEG_END)
# ifdef DEBUG_I00AFUNC
# include <stdio.h>
# endif
# ifndef CRAY_STACK
# define CRAY_STACK
# ifndef CRAY2
/* Stack structures for CRAY-1, CRAY X-MP, and CRAY Y-MP */
struct stack_control_header
{
long shgrow:32; /* Number of times stack has grown. */
long shaseg:32; /* Size of increments to stack. */
long shhwm:32; /* High water mark of stack. */
long shsize:32; /* Current size of stack (all segments). */
};
/* The stack segment linkage control information occurs at
the high-address end of a stack segment. (The stack
grows from low addresses to high addresses.) The initial
part of the stack segment linkage control information is
0200 (octal) words. This provides for register storage
for the routine which overflows the stack. */
struct stack_segment_linkage
{
long ss[0200]; /* 0200 overflow words. */
long sssize:32; /* Number of words in this segment. */
long ssbase:32; /* Offset to stack base. */
long:32;
long sspseg:32; /* Offset to linkage control of previous
segment of stack. */
long:32;
long sstcpt:32; /* Pointer to task common address block. */
long sscsnm; /* Private control structure number for
microtasking. */
long ssusr1; /* Reserved for user. */
long ssusr2; /* Reserved for user. */
long sstpid; /* Process ID for pid based multi-tasking. */
long ssgvup; /* Pointer to multitasking thread giveup. */
long sscray[7]; /* Reserved for Cray Research. */
long ssa0;
long ssa1;
long ssa2;
long ssa3;
long ssa4;
long ssa5;
long ssa6;
long ssa7;
long sss0;
long sss1;
long sss2;
long sss3;
long sss4;
long sss5;
long sss6;
long sss7;
};
# else /* CRAY2 */
/* The following structure defines the vector of words
returned by the STKSTAT library routine. */
struct stk_stat
{
long now; /* Current total stack size. */
long maxc; /* Amount of contiguous space which would
be required to satisfy the maximum
stack demand to date. */
long high_water; /* Stack high-water mark. */
long overflows; /* Number of stack overflow ($STKOFEN) calls. */
long hits; /* Number of internal buffer hits. */
long extends; /* Number of block extensions. */
long stko_mallocs; /* Block allocations by $STKOFEN. */
long underflows; /* Number of stack underflow calls ($STKRETN). */
long stko_free; /* Number of deallocations by $STKRETN. */
long stkm_free; /* Number of deallocations by $STKMRET. */
long segments; /* Current number of stack segments. */
long maxs; /* Maximum number of stack segments so far. */
long pad_size; /* Stack pad size. */
long current_address; /* Current stack segment address. */
long current_size; /* Current stack segment size. This
number is actually corrupted by STKSTAT to
include the fifteen word trailer area. */
long initial_address; /* Address of initial segment. */
long initial_size; /* Size of initial segment. */
};
/* The following structure describes the data structure which trails
any stack segment. I think that the description in 'asdef' is
out of date. I only describe the parts that I am sure about. */
struct stk_trailer
{
long this_address; /* Address of this block. */
long this_size; /* Size of this block (does not include
this trailer). */
long unknown2;
long unknown3;
long link; /* Address of trailer block of previous
segment. */
long unknown5;
long unknown6;
long unknown7;
long unknown8;
long unknown9;
long unknown10;
long unknown11;
long unknown12;
long unknown13;
long unknown14;
};
# endif /* CRAY2 */
# endif /* not CRAY_STACK */
# ifdef CRAY2
/* Determine a "stack measure" for an arbitrary ADDRESS.
I doubt that "lint" will like this much. */
static long
i00afunc (long *address)
{
struct stk_stat status;
struct stk_trailer *trailer;
long *block, size;
long result = 0;
/* We want to iterate through all of the segments. The first
step is to get the stack status structure. We could do this
more quickly and more directly, perhaps, by referencing the
$LM00 common block, but I know that this works. */
STKSTAT (&status);
/* Set up the iteration. */
trailer = (struct stk_trailer *) (status.current_address
+ status.current_size
- 15);
/* There must be at least one stack segment. Therefore it is
a fatal error if "trailer" is null. */
if (trailer == 0)
abort ();
/* Discard segments that do not contain our argument address. */
while (trailer != 0)
{
block = (long *) trailer->this_address;
size = trailer->this_size;
if (block == 0 || size == 0)
abort ();
trailer = (struct stk_trailer *) trailer->link;
if ((block <= address) && (address < (block + size)))
break;
}
/* Set the result to the offset in this segment and add the sizes
of all predecessor segments. */
result = address - block;
if (trailer == 0)
{
return result;
}
do
{
if (trailer->this_size <= 0)
abort ();
result += trailer->this_size;
trailer = (struct stk_trailer *) trailer->link;
}
while (trailer != 0);
/* We are done. Note that if you present a bogus address (one
not in any segment), you will get a different number back, formed
from subtracting the address of the first block. This is probably
not what you want. */
return (result);
}
# else /* not CRAY2 */
/* Stack address function for a CRAY-1, CRAY X-MP, or CRAY Y-MP.
Determine the number of the cell within the stack,
given the address of the cell. The purpose of this
routine is to linearize, in some sense, stack addresses
for alloca. */
static long
i00afunc (long address)
{
long stkl = 0;
long size, pseg, this_segment, stack;
long result = 0;
struct stack_segment_linkage *ssptr;
/* Register B67 contains the address of the end of the
current stack segment. If you (as a subprogram) store
your registers on the stack and find that you are past
the contents of B67, you have overflowed the segment.
B67 also points to the stack segment linkage control
area, which is what we are really interested in. */
stkl = CRAY_STACKSEG_END ();
ssptr = (struct stack_segment_linkage *) stkl;
/* If one subtracts 'size' from the end of the segment,
one has the address of the first word of the segment.
If this is not the first segment, 'pseg' will be
nonzero. */
pseg = ssptr->sspseg;
size = ssptr->sssize;
this_segment = stkl - size;
/* It is possible that calling this routine itself caused
a stack overflow. Discard stack segments which do not
contain the target address. */
while (!(this_segment <= address && address <= stkl))
{
# ifdef DEBUG_I00AFUNC
fprintf (stderr, "%011o %011o %011o\n", this_segment, address, stkl);
# endif
if (pseg == 0)
break;
stkl = stkl - pseg;
ssptr = (struct stack_segment_linkage *) stkl;
size = ssptr->sssize;
pseg = ssptr->sspseg;
this_segment = stkl - size;
}
result = address - this_segment;
/* If you subtract pseg from the current end of the stack,
you get the address of the previous stack segment's end.
This seems a little convoluted to me, but I'll bet you save
a cycle somewhere. */
while (pseg != 0)
{
# ifdef DEBUG_I00AFUNC
fprintf (stderr, "%011o %011o\n", pseg, size);
# endif
stkl = stkl - pseg;
ssptr = (struct stack_segment_linkage *) stkl;
size = ssptr->sssize;
pseg = ssptr->sspseg;
result += size;
}
return (result);
}
# endif /* not CRAY2 */
# endif /* CRAY */
# endif /* no alloca */
#endif /* not GCC version 3 */

View file

@ -30,21 +30,21 @@
# The current list of GNU canonical charset names is as follows.
#
# name MIME? used by which systems
# ASCII, ANSI_X3.4-1968 glibc solaris freebsd netbsd darwin
# ISO-8859-1 Y glibc aix hpux irix osf solaris freebsd netbsd openbsd darwin
# ISO-8859-2 Y glibc aix hpux irix osf solaris freebsd netbsd openbsd darwin
# ISO-8859-3 Y glibc solaris
# ASCII, ANSI_X3.4-1968 glibc solaris freebsd netbsd darwin cygwin
# ISO-8859-1 Y glibc aix hpux irix osf solaris freebsd netbsd openbsd darwin cygwin
# ISO-8859-2 Y glibc aix hpux irix osf solaris freebsd netbsd openbsd darwin cygwin
# ISO-8859-3 Y glibc solaris cygwin
# ISO-8859-4 Y osf solaris freebsd netbsd openbsd darwin
# ISO-8859-5 Y glibc aix hpux irix osf solaris freebsd netbsd openbsd darwin
# ISO-8859-6 Y glibc aix hpux solaris
# ISO-8859-7 Y glibc aix hpux irix osf solaris netbsd openbsd darwin
# ISO-8859-8 Y glibc aix hpux osf solaris
# ISO-8859-9 Y glibc aix hpux irix osf solaris darwin
# ISO-8859-13 glibc netbsd openbsd darwin
# ISO-8859-14 glibc
# ISO-8859-15 glibc aix osf solaris freebsd netbsd openbsd darwin
# ISO-8859-5 Y glibc aix hpux irix osf solaris freebsd netbsd openbsd darwin cygwin
# ISO-8859-6 Y glibc aix hpux solaris cygwin
# ISO-8859-7 Y glibc aix hpux irix osf solaris netbsd openbsd darwin cygwin
# ISO-8859-8 Y glibc aix hpux osf solaris cygwin
# ISO-8859-9 Y glibc aix hpux irix osf solaris darwin cygwin
# ISO-8859-13 glibc netbsd openbsd darwin cygwin
# ISO-8859-14 glibc cygwin
# ISO-8859-15 glibc aix osf solaris freebsd netbsd openbsd darwin cygwin
# KOI8-R Y glibc solaris freebsd netbsd openbsd darwin
# KOI8-U Y glibc freebsd netbsd openbsd darwin
# KOI8-U Y glibc freebsd netbsd openbsd darwin cygwin
# KOI8-T glibc
# CP437 dos
# CP775 dos
@ -61,7 +61,7 @@
# CP869 dos
# CP874 woe32 dos
# CP922 aix
# CP932 aix woe32 dos
# CP932 aix cygwin woe32 dos
# CP943 aix
# CP949 osf darwin woe32 dos
# CP950 woe32 dos
@ -71,7 +71,7 @@
# CP1129 aix
# CP1131 darwin
# CP1250 woe32
# CP1251 glibc solaris netbsd openbsd darwin woe32
# CP1251 glibc solaris netbsd openbsd darwin cygwin woe32
# CP1252 aix woe32
# CP1253 woe32
# CP1254 woe32
@ -80,19 +80,19 @@
# CP1257 woe32
# GB2312 Y glibc aix hpux irix solaris freebsd netbsd darwin
# EUC-JP Y glibc aix hpux irix osf solaris freebsd netbsd darwin
# EUC-KR Y glibc aix hpux irix osf solaris freebsd netbsd darwin
# EUC-KR Y glibc aix hpux irix osf solaris freebsd netbsd darwin cygwin
# EUC-TW glibc aix hpux irix osf solaris netbsd
# BIG5 Y glibc aix hpux osf solaris freebsd netbsd darwin
# BIG5 Y glibc aix hpux osf solaris freebsd netbsd darwin cygwin
# BIG5-HKSCS glibc solaris darwin
# GBK glibc aix osf solaris darwin woe32 dos
# GBK glibc aix osf solaris darwin cygwin woe32 dos
# GB18030 glibc solaris netbsd darwin
# SHIFT_JIS Y hpux osf solaris freebsd netbsd darwin
# JOHAB glibc solaris woe32
# TIS-620 glibc aix hpux osf solaris
# TIS-620 glibc aix hpux osf solaris cygwin
# VISCII Y glibc
# TCVN5712-1 glibc
# ARMSCII-8 glibc darwin
# GEORGIAN-PS glibc
# GEORGIAN-PS glibc cygwin
# PT154 glibc
# HP-ROMAN8 hpux
# HP-ARABIC8 hpux
@ -102,7 +102,7 @@
# HP-KANA8 hpux
# DEC-KANJI osf
# DEC-HANYU osf
# UTF-8 Y glibc aix hpux osf solaris netbsd darwin
# UTF-8 Y glibc aix hpux osf solaris netbsd darwin cygwin
#
# Note: Names which are not marked as being a MIME name should not be used in
# Internet protocols for information interchange (mail, news, etc.).

View file

@ -88,6 +88,15 @@ extern void __error_at_line (int status, int errnum, const char *file_name,
# include <fcntl.h>
# include <unistd.h>
# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
/* Get declarations of the Win32 API functions. */
# define WIN32_LEAN_AND_MEAN
# include <windows.h>
# endif
/* The gnulib override of fcntl is not needed in this file. */
# undef fcntl
# if !HAVE_DECL_STRERROR_R && STRERROR_R_CHAR_P
# ifndef HAVE_DECL_STRERROR_R
"this configure-time declaration test was not run"
@ -104,10 +113,29 @@ extern char *program_name;
# endif /* HAVE_STRERROR_R || defined strerror_r */
#endif /* not _LIBC */
#if !_LIBC
/* Return non-zero if FD is open. */
static inline int
is_open (int fd)
{
# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
/* On Win32: The initial state of unassigned standard file descriptors is
that they are open but point to an INVALID_HANDLE_VALUE. There is no
fcntl, and the gnulib replacement fcntl does not support F_GETFL. */
return (HANDLE) _get_osfhandle (fd) != INVALID_HANDLE_VALUE;
# else
# ifndef F_GETFL
# error Please port fcntl to your platform
# endif
return 0 <= fcntl (fd, F_GETFL);
# endif
}
#endif
static inline void
flush_stdout (void)
{
#if !_LIBC && defined F_GETFL
#if !_LIBC
int stdout_fd;
# if GNULIB_FREOPEN_SAFER
@ -124,7 +152,7 @@ flush_stdout (void)
/* POSIX states that fflush (stdout) after fclose is unspecified; it
is safe in glibc, but not on all other platforms. fflush (NULL)
is always defined, but too draconian. */
if (0 <= stdout_fd && 0 <= fcntl (stdout_fd, F_GETFL))
if (0 <= stdout_fd && is_open (stdout_fd))
#endif
fflush (stdout);
}

View file

@ -348,8 +348,6 @@ _getopt_internal_r (int argc, char **argv, const char *optstring,
int long_only, struct _getopt_data *d, int posixly_correct)
{
int print_errors = d->opterr;
if (optstring[0] == ':')
print_errors = 0;
if (argc < 1)
return -1;
@ -364,6 +362,10 @@ _getopt_internal_r (int argc, char **argv, const char *optstring,
posixly_correct);
d->__initialized = 1;
}
else if (optstring[0] == '-' || optstring[0] == '+')
optstring++;
if (optstring[0] == ':')
print_errors = 0;
/* Test whether ARGV[optind] points to a non-option argument.
Either it does not have option syntax, or there is an environment flag
@ -633,8 +635,8 @@ _getopt_internal_r (int argc, char **argv, const char *optstring,
char *buf;
if (__asprintf (&buf, _("\
%s: option '%s' requires an argument\n"),
argv[0], argv[d->optind - 1]) >= 0)
%s: option '--%s' requires an argument\n"),
argv[0], pfound->name) >= 0)
{
_IO_flockfile (stderr);
@ -651,8 +653,8 @@ _getopt_internal_r (int argc, char **argv, const char *optstring,
}
#else
fprintf (stderr,
_("%s: option '%s' requires an argument\n"),
argv[0], argv[d->optind - 1]);
_("%s: option '--%s' requires an argument\n"),
argv[0], pfound->name);
#endif
}
d->__nextchar += strlen (d->__nextchar);
@ -736,13 +738,13 @@ _getopt_internal_r (int argc, char **argv, const char *optstring,
{
char c = *d->__nextchar++;
char *temp = strchr (optstring, c);
const char *temp = strchr (optstring, c);
/* Increment `optind' when we start to process its last character. */
if (*d->__nextchar == '\0')
++d->optind;
if (temp == NULL || c == ':')
if (temp == NULL || c == ':' || c == ';')
{
if (print_errors)
{
@ -864,7 +866,10 @@ _getopt_internal_r (int argc, char **argv, const char *optstring,
pfound = p;
indfound = option_index;
}
else
else if (long_only
|| pfound->has_arg != p->has_arg
|| pfound->flag != p->flag
|| pfound->val != p->val)
/* Second or later nonexact match found. */
ambig = 1;
}
@ -876,7 +881,7 @@ _getopt_internal_r (int argc, char **argv, const char *optstring,
char *buf;
if (__asprintf (&buf, _("%s: option '-W %s' is ambiguous\n"),
argv[0], argv[d->optind]) >= 0)
argv[0], d->optarg) >= 0)
{
_IO_flockfile (stderr);
@ -892,7 +897,7 @@ _getopt_internal_r (int argc, char **argv, const char *optstring,
}
#else
fprintf (stderr, _("%s: option '-W %s' is ambiguous\n"),
argv[0], argv[d->optind]);
argv[0], d->optarg);
#endif
}
d->__nextchar += strlen (d->__nextchar);
@ -955,8 +960,8 @@ _getopt_internal_r (int argc, char **argv, const char *optstring,
char *buf;
if (__asprintf (&buf, _("\
%s: option '%s' requires an argument\n"),
argv[0], argv[d->optind - 1]) >= 0)
%s: option '-W %s' requires an argument\n"),
argv[0], pfound->name) >= 0)
{
_IO_flockfile (stderr);
@ -972,15 +977,17 @@ _getopt_internal_r (int argc, char **argv, const char *optstring,
free (buf);
}
#else
fprintf (stderr,
_("%s: option '%s' requires an argument\n"),
argv[0], argv[d->optind - 1]);
fprintf (stderr, _("\
%s: option '-W %s' requires an argument\n"),
argv[0], pfound->name);
#endif
}
d->__nextchar += strlen (d->__nextchar);
return optstring[0] == ':' ? ':' : '?';
}
}
else
d->optarg = NULL;
d->__nextchar += strlen (d->__nextchar);
if (longind != NULL)
*longind = option_index;

View file

@ -30,6 +30,40 @@ extern int _getopt_internal (int ___argc, char **___argv,
/* Reentrant versions which can handle parsing multiple argument
vectors at the same time. */
/* Describe how to deal with options that follow non-option ARGV-elements.
If the caller did not specify anything,
the default is REQUIRE_ORDER if the environment variable
POSIXLY_CORRECT is defined, PERMUTE otherwise.
REQUIRE_ORDER means don't recognize them as options;
stop option processing when the first non-option is seen.
This is what Unix does.
This mode of operation is selected by either setting the environment
variable POSIXLY_CORRECT, or using `+' as the first character
of the list of option characters, or by calling getopt.
PERMUTE is the default. We permute the contents of ARGV as we
scan, so that eventually all the non-options are at the end.
This allows options to be given in any order, even with programs
that were not written to expect this.
RETURN_IN_ORDER is an option available to programs that were
written to expect options and other ARGV-elements in any order
and that care about the ordering of the two. We describe each
non-option ARGV-element as if it were the argument of an option
with character code 1. Using `-' as the first character of the
list of option characters selects this mode of operation.
The special argument `--' forces an end of option-scanning regardless
of the value of `ordering'. In the case of RETURN_IN_ORDER, only
`--' can cause `getopt' to return -1 with `optind' != ARGC. */
enum __ord
{
REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
};
/* Data type for reentrant functions. */
struct _getopt_data
{
@ -54,39 +88,8 @@ struct _getopt_data
by advancing to the next ARGV-element. */
char *__nextchar;
/* Describe how to deal with options that follow non-option ARGV-elements.
If the caller did not specify anything,
the default is REQUIRE_ORDER if the environment variable
POSIXLY_CORRECT is defined, PERMUTE otherwise.
REQUIRE_ORDER means don't recognize them as options;
stop option processing when the first non-option is seen.
This is what Unix does.
This mode of operation is selected by either setting the environment
variable POSIXLY_CORRECT, or using `+' as the first character
of the list of option characters, or by calling getopt.
PERMUTE is the default. We permute the contents of ARGV as we
scan, so that eventually all the non-options are at the end.
This allows options to be given in any order, even with programs
that were not written to expect this.
RETURN_IN_ORDER is an option available to programs that were
written to expect options and other ARGV-elements in any order
and that care about the ordering of the two. We describe each
non-option ARGV-element as if it were the argument of an option
with character code 1. Using `-' as the first character of the
list of option characters selects this mode of operation.
The special argument `--' forces an end of option-scanning regardless
of the value of `ordering'. In the case of RETURN_IN_ORDER, only
`--' can cause `getopt' to return -1 with `optind' != ARGC. */
enum
{
REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
} __ordering;
/* See __ord above. */
enum __ord __ordering;
/* If the POSIXLY_CORRECT environment variable is set
or getopt was called. */

View file

@ -369,10 +369,9 @@ locale_charset (void)
codeset = nl_langinfo (CODESET);
# ifdef __CYGWIN__
/* Cygwin 1.5.x does not have locales. nl_langinfo (CODESET) always
returns "US-ASCII". As long as this is not fixed, return the suffix
of the locale name from the environment variables (if present) or
the codepage as a number. */
/* Cygwin < 1.7 does not have locales. nl_langinfo (CODESET) always
returns "US-ASCII". Return the suffix of the locale name from the
environment variables (if present) or the codepage as a number. */
if (codeset != NULL && strcmp (codeset, "US-ASCII") == 0)
{
const char *locale;

48
gl/m4/asm-underscore.m4 Normal file
View file

@ -0,0 +1,48 @@
# asm-underscore.m4 serial 1
dnl Copyright (C) 2010 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
dnl From Bruno Haible. Based on as-underscore.m4 in GNU clisp.
# gl_ASM_SYMBOL_PREFIX
# Tests for the prefix of C symbols at the assembly language level and the
# linker level. This prefix is either an underscore or empty. Defines the
# C macro USER_LABEL_PREFIX to this prefix, and sets ASM_SYMBOL_PREFIX to
# a stringified variant of this prefix.
AC_DEFUN([gl_ASM_SYMBOL_PREFIX],
[
dnl We don't use GCC's __USER_LABEL_PREFIX__ here, because
dnl 1. It works only for GCC.
dnl 2. It is incorrectly defined on some platforms, in some GCC versions.
AC_CACHE_CHECK(
[whether C symbols are prefixed with underscore at the linker level],
[gl_cv_prog_as_underscore],
[cat > conftest.c <<EOF
#ifdef __cplusplus
extern "C" int foo (void);
#endif
int foo(void) { return 0; }
EOF
# Look for the assembly language name in the .s file.
AC_TRY_COMMAND(${CC-cc} $CFLAGS $CPPFLAGS -S conftest.c) >/dev/null 2>&1
if grep _foo conftest.s >/dev/null ; then
gl_cv_prog_as_underscore=yes
else
gl_cv_prog_as_underscore=no
fi
rm -f conftest*
])
if test $gl_cv_prog_as_underscore = yes; then
USER_LABEL_PREFIX=_
else
USER_LABEL_PREFIX=
fi
AC_DEFINE_UNQUOTED([USER_LABEL_PREFIX], [$USER_LABEL_PREFIX],
[Define to the prefix of C symbols at the assembler and linker level,
either an underscore or empty.])
ASM_SYMBOL_PREFIX='"'${USER_LABEL_PREFIX}'"'
AC_SUBST([ASM_SYMBOL_PREFIX])
])

View file

@ -1,4 +1,4 @@
# getopt.m4 serial 24
# getopt.m4 serial 28
dnl Copyright (C) 2002-2006, 2008-2010 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
@ -79,8 +79,13 @@ AC_DEFUN([gl_GETOPT_CHECK_HEADERS],
dnl Existence of the variable, in and of itself, is not a reason to replace
dnl getopt, but knowledge of the variable is needed to determine how to
dnl reset and whether a reset reparses the environment.
if test -z "$gl_replace_getopt" && test $gl_getopt_required = GNU; then
AC_CHECK_DECLS([optreset], [], [],
dnl Solaris supports neither optreset nor optind=0, but keeps no state that
dnl needs a reset beyond setting optind=1; detect Solaris by getopt_clip.
if test -z "$gl_replace_getopt"; then
AC_CHECK_DECLS([optreset], [],
[AC_CHECK_DECLS([getopt_clip], [], [],
[[#include <getopt.h>]])
],
[[#include <getopt.h>]])
fi
@ -89,6 +94,10 @@ AC_DEFUN([gl_GETOPT_CHECK_HEADERS],
dnl is left over from earlier calls, and neither setting optind = 0 nor
dnl setting optreset = 1 get rid of this internal state.
dnl POSIX is silent on optind vs. optreset, so we allow either behavior.
dnl POSIX 2008 does not specify leading '+' behavior, but see
dnl http://austingroupbugs.net/view.php?id=191 for a recommendation on
dnl the next version of POSIX. For now, we only guarantee leading '+'
dnl behavior with getopt-gnu.
if test -z "$gl_replace_getopt"; then
AC_CACHE_CHECK([whether getopt is POSIX compatible],
[gl_cv_func_getopt_posix],
@ -99,7 +108,7 @@ AC_DEFUN([gl_GETOPT_CHECK_HEADERS],
#include <stdlib.h>
#include <string.h>
#if !HAVE_DECL_OPTRESET
#if !HAVE_DECL_OPTRESET && !HAVE_DECL_GETOPT_CLIP
# define OPTIND_MIN 0
#else
# define OPTIND_MIN 1
@ -167,6 +176,20 @@ main ()
if (!(optind == 1))
return 12;
}
/* Detect MacOS 10.5 bug. */
{
char *argv[3] = { "program", "-ab", NULL };
optind = OPTIND_MIN;
opterr = 0;
if (getopt (2, argv, "ab:") != 'a')
return 13;
if (getopt (2, argv, "ab:") != '?')
return 14;
if (optopt != 'b')
return 15;
if (optind != 2)
return 16;
}
return 0;
}
@ -174,6 +197,7 @@ main ()
[gl_cv_func_getopt_posix=yes], [gl_cv_func_getopt_posix=no],
[case "$host_os" in
mingw*) gl_cv_func_getopt_posix="guessing no";;
darwin*) gl_cv_func_getopt_posix="guessing no";;
*) gl_cv_func_getopt_posix="guessing yes";;
esac
])
@ -234,6 +258,15 @@ main ()
if (getopt (3, argv, "-p") != 'p')
return 7;
}
/* This code fails on glibc 2.11. */
{
char *argv[] = { "program", "-b", "-a", NULL };
optind = opterr = 0;
if (getopt (3, argv, "+:a:b") != 'b')
return 8;
if (getopt (3, argv, "+:a:b") != ':')
return 9;
}
return 0;
]])],
[gl_cv_func_getopt_gnu=yes],

View file

@ -1,4 +1,4 @@
# gettext.m4 serial 62 (gettext-0.18)
# gettext.m4 serial 63 (gettext-0.18)
dnl Copyright (C) 1995-2010 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
@ -15,7 +15,7 @@ dnl They are *not* in the public domain.
dnl Authors:
dnl Ulrich Drepper <drepper@cygnus.com>, 1995-2000.
dnl Bruno Haible <haible@clisp.cons.org>, 2000-2006.
dnl Bruno Haible <haible@clisp.cons.org>, 2000-2006, 2008-2010.
dnl Macro to add for using GNU gettext.
@ -60,6 +60,8 @@ AC_DEFUN([AM_GNU_GETTEXT],
ifelse([$1], [], , [ifelse([$1], [external], , [ifelse([$1], [no-libtool], , [ifelse([$1], [use-libtool], ,
[errprint([ERROR: invalid first argument to AM_GNU_GETTEXT
])])])])])
ifelse(ifelse([$1], [], [old])[]ifelse([$1], [no-libtool], [old]), [old],
[AC_DIAGNOSE([obsolete], [Use of AM_GNU_GETTEXT without [external] argument is deprecated.])])
ifelse([$2], [], , [ifelse([$2], [need-ngettext], , [ifelse([$2], [need-formatstring-macros], ,
[errprint([ERROR: invalid second argument to AM_GNU_GETTEXT
])])])])

View file

@ -15,12 +15,13 @@
# Specification in the form of a command-line invocation:
# gnulib-tool --import --dir=. --lib=libgnu --source-base=gl --m4-base=gl/m4 --doc-base=doc --tests-base=tests --aux-dir=build-aux --no-libtool --macro-prefix=gl base64 dirname floorf fsusage getaddrinfo gethostname getloadavg getopt gettext mountlist regex timegm vasprintf vsnprintf
# gnulib-tool --import --dir=. --lib=libgnu --source-base=gl --m4-base=gl/m4 --doc-base=doc --tests-base=tests --aux-dir=build-aux --no-libtool --macro-prefix=gl --no-vc-files base64 crypto/sha1 dirname floorf fsusage getaddrinfo gethostname getloadavg getopt gettext mountlist regex timegm vasprintf vsnprintf
# Specification in the form of a few gnulib-tool.m4 macro invocations:
gl_LOCAL_DIR([])
gl_MODULES([
base64
crypto/sha1
dirname
floorf
fsusage
@ -45,3 +46,4 @@ gl_LIB([libgnu])
gl_MAKEFILE_NAME([])
gl_MACRO_PREFIX([gl])
gl_PO_DOMAIN([])
gl_VC_FILES([false])

View file

@ -1,4 +1,4 @@
# gnulib-common.m4 serial 18
# gnulib-common.m4 serial 20
dnl Copyright (C) 2007-2010 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
@ -35,6 +35,12 @@ AC_DEFUN([gl_COMMON_BODY], [
is a misnomer outside of parameter lists. */
#define _UNUSED_PARAMETER_ _GL_UNUSED
])
dnl Preparation for running test programs:
dnl Tell glibc to write diagnostics from -D_FORTIFY_SOURCE=2 to stderr, not
dnl to /dev/tty, so they can be redirected to log files. Such diagnostics
dnl arise e.g., in the macros gl_PRINTF_DIRECTIVE_N, gl_SNPRINTF_DIRECTIVE_N.
LIBC_FATAL_STDERR_=1
export LIBC_FATAL_STDERR_
])
# gl_MODULE_INDICATOR_CONDITION
@ -132,6 +138,7 @@ m4_ifdef([AC_PROG_MKDIR_P], [
# so that mixed use of GNU C and GNU C++ and mixed use of Sun C and Sun C++
# works.
# This definition can be removed once autoconf >= 2.62 can be assumed.
m4_if(m4_version_compare(m4_defn([m4_PACKAGE_VERSION]),[2.62]),[-1],[
AC_DEFUN([AC_C_RESTRICT],
[AC_CACHE_CHECK([for C/C++ restrict keyword], [ac_cv_c_restrict],
[ac_cv_c_restrict=no
@ -169,6 +176,7 @@ AC_DEFUN([AC_C_RESTRICT],
*) AC_DEFINE_UNQUOTED([restrict], [$ac_cv_c_restrict]) ;;
esac
])
])
# gl_BIGENDIAN
# is like AC_C_BIGENDIAN, except that it can be AC_REQUIREd.

View file

@ -26,7 +26,6 @@ AC_DEFUN([gl_EARLY],
m4_pattern_allow([^gl_LTLIBOBJS$])dnl a variable
AC_REQUIRE([AC_PROG_RANLIB])
# Code from module alignof:
# Code from module alloca:
# Code from module alloca-opt:
# Code from module arg-nonnull:
# Code from module arpa_inet:
@ -37,6 +36,7 @@ AC_DEFUN([gl_EARLY],
# Code from module cloexec:
# Code from module close-hook:
# Code from module configmake:
# Code from module crypto/sha1:
# Code from module dirname:
# Code from module dirname-lgpl:
# Code from module double-slash-root:
@ -146,7 +146,6 @@ AC_DEFUN([gl_INIT],
gl_COMMON
gl_source_base='gl'
# Code from module alignof:
# Code from module alloca:
# Code from module alloca-opt:
gl_FUNC_ALLOCA
# Code from module arg-nonnull:
@ -166,6 +165,8 @@ AC_DEFUN([gl_INIT],
gl_MODULE_INDICATOR_FOR_TESTS([cloexec])
# Code from module close-hook:
# Code from module configmake:
# Code from module crypto/sha1:
gl_SHA1
# Code from module dirname:
gl_DIRNAME
gl_MODULE_INDICATOR([dirname])
@ -222,7 +223,7 @@ AC_DEFUN([gl_INIT],
gl_FUNC_GETOPT_POSIX
# Code from module gettext:
dnl you must add AM_GNU_GETTEXT([external]) or similar to configure.ac.
AM_GNU_GETTEXT_VERSION([0.17])
AM_GNU_GETTEXT_VERSION([0.18.1])
# Code from module gettext-h:
AC_SUBST([LIBINTL])
AC_SUBST([LTLIBINTL])
@ -522,7 +523,6 @@ AC_DEFUN([gl_FILE_LIST], [
build-aux/config.rpath
build-aux/warn-on-use.h
lib/alignof.h
lib/alloca.c
lib/alloca.in.h
lib/arpa_inet.in.h
lib/asnprintf.c
@ -613,6 +613,8 @@ AC_DEFUN([gl_FILE_LIST], [
lib/safe-read.h
lib/safe-write.c
lib/safe-write.h
lib/sha1.c
lib/sha1.h
lib/size_max.h
lib/snprintf.c
lib/sockets.c
@ -660,6 +662,7 @@ AC_DEFUN([gl_FILE_LIST], [
m4/00gnulib.m4
m4/alloca.m4
m4/arpa_inet_h.m4
m4/asm-underscore.m4
m4/base64.m4
m4/btowc.m4
m4/c-strtod.m4
@ -740,6 +743,7 @@ AC_DEFUN([gl_FILE_LIST], [
m4/safe-read.m4
m4/safe-write.m4
m4/servent.m4
m4/sha1.m4
m4/size_max.m4
m4/snprintf.m4
m4/sockets.m4

View file

@ -1,4 +1,4 @@
# iconv.m4 serial 9 (gettext-0.18)
# iconv.m4 serial 11 (gettext-0.18.1)
dnl Copyright (C) 2000-2002, 2007-2010 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
@ -170,7 +170,22 @@ int main ()
AC_SUBST([LTLIBICONV])
])
AC_DEFUN([AM_ICONV],
dnl Define AM_ICONV using AC_DEFUN_ONCE for Autoconf >= 2.64, in order to
dnl avoid warnings like
dnl "warning: AC_REQUIRE: `AM_ICONV' was expanded before it was required".
dnl This is tricky because of the way 'aclocal' is implemented:
dnl - It requires defining an auxiliary macro whose name ends in AC_DEFUN.
dnl Otherwise aclocal's initial scan pass would miss the macro definition.
dnl - It requires a line break inside the AC_DEFUN_ONCE and AC_DEFUN expansions.
dnl Otherwise aclocal would emit many "Use of uninitialized value $1"
dnl warnings.
m4_define([gl_iconv_AC_DEFUN],
m4_version_prereq([2.64],
[[AC_DEFUN_ONCE(
[$1], [$2])]],
[[AC_DEFUN(
[$1], [$2])]]))
gl_iconv_AC_DEFUN([AM_ICONV],
[
AM_ICONV_LINK
if test "$am_cv_func_iconv" = yes; then

View file

@ -1,5 +1,5 @@
# intl.m4 serial 8 (gettext-0.17)
dnl Copyright (C) 1995-2007, 2009-2010 Free Software Foundation, Inc.
# intl.m4 serial 17 (gettext-0.18)
dnl Copyright (C) 1995-2009 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
@ -15,9 +15,9 @@ dnl They are *not* in the public domain.
dnl Authors:
dnl Ulrich Drepper <drepper@cygnus.com>, 1995-2000.
dnl Bruno Haible <haible@clisp.cons.org>, 2000-2006.
dnl Bruno Haible <haible@clisp.cons.org>, 2000-2009.
AC_PREREQ(2.52)
AC_PREREQ([2.52])
dnl Checks for all prerequisites of the intl subdirectory,
dnl except for INTL_LIBTOOL_SUFFIX_PREFIX (and possibly LIBTOOL), INTLOBJS,
@ -40,14 +40,24 @@ AC_DEFUN([AM_INTL_SUBDIR],
AC_REQUIRE([gt_PRINTF_POSIX])
AC_REQUIRE([gl_GLIBC21])dnl
AC_REQUIRE([gl_XSIZE])dnl
AC_REQUIRE([gl_FCNTL_O_FLAGS])dnl
AC_REQUIRE([gt_INTL_MACOSX])dnl
dnl Support for automake's --enable-silent-rules.
case "$enable_silent_rules" in
yes) INTL_DEFAULT_VERBOSITY=0;;
no) INTL_DEFAULT_VERBOSITY=1;;
*) INTL_DEFAULT_VERBOSITY=1;;
esac
AC_SUBST([INTL_DEFAULT_VERBOSITY])
AC_CHECK_TYPE([ptrdiff_t], ,
[AC_DEFINE([ptrdiff_t], [long],
[Define as the type of the result of subtracting two pointers, if the system doesn't define it.])
])
AC_CHECK_HEADERS([stddef.h stdlib.h string.h])
AC_CHECK_FUNCS([asprintf fwprintf putenv setenv setlocale snprintf wcslen])
AC_CHECK_FUNCS([asprintf fwprintf newlocale putenv setenv setlocale \
snprintf strnlen wcslen wcsnlen mbrtowc wcrtomb])
dnl Use the _snprintf function only if it is declared (because on NetBSD it
dnl is defined as a weak alias of snprintf; we prefer to use the latter).
@ -78,6 +88,12 @@ AC_DEFUN([AM_INTL_SUBDIR],
HAVE_SNPRINTF=0
fi
AC_SUBST([HAVE_SNPRINTF])
if test "$ac_cv_func_newlocale" = yes; then
HAVE_NEWLOCALE=1
else
HAVE_NEWLOCALE=0
fi
AC_SUBST([HAVE_NEWLOCALE])
if test "$ac_cv_func_wprintf" = yes; then
HAVE_WPRINTF=1
else
@ -146,22 +162,31 @@ AC_DEFUN([AM_INTL_SUBDIR],
#define __libc_lock_lock_recursive gl_recursive_lock_lock
#define __libc_lock_unlock_recursive gl_recursive_lock_unlock
#define glthread_in_use libintl_thread_in_use
#define glthread_lock_init libintl_lock_init
#define glthread_lock_lock libintl_lock_lock
#define glthread_lock_unlock libintl_lock_unlock
#define glthread_lock_destroy libintl_lock_destroy
#define glthread_rwlock_init libintl_rwlock_init
#define glthread_rwlock_rdlock libintl_rwlock_rdlock
#define glthread_rwlock_wrlock libintl_rwlock_wrlock
#define glthread_rwlock_unlock libintl_rwlock_unlock
#define glthread_rwlock_destroy libintl_rwlock_destroy
#define glthread_recursive_lock_init libintl_recursive_lock_init
#define glthread_recursive_lock_lock libintl_recursive_lock_lock
#define glthread_recursive_lock_unlock libintl_recursive_lock_unlock
#define glthread_recursive_lock_destroy libintl_recursive_lock_destroy
#define glthread_once libintl_once
#define glthread_once_call libintl_once_call
#define glthread_lock_init_func libintl_lock_init_func
#define glthread_lock_lock_func libintl_lock_lock_func
#define glthread_lock_unlock_func libintl_lock_unlock_func
#define glthread_lock_destroy_func libintl_lock_destroy_func
#define glthread_rwlock_init_multithreaded libintl_rwlock_init_multithreaded
#define glthread_rwlock_init_func libintl_rwlock_init_func
#define glthread_rwlock_rdlock_multithreaded libintl_rwlock_rdlock_multithreaded
#define glthread_rwlock_rdlock_func libintl_rwlock_rdlock_func
#define glthread_rwlock_wrlock_multithreaded libintl_rwlock_wrlock_multithreaded
#define glthread_rwlock_wrlock_func libintl_rwlock_wrlock_func
#define glthread_rwlock_unlock_multithreaded libintl_rwlock_unlock_multithreaded
#define glthread_rwlock_unlock_func libintl_rwlock_unlock_func
#define glthread_rwlock_destroy_multithreaded libintl_rwlock_destroy_multithreaded
#define glthread_rwlock_destroy_func libintl_rwlock_destroy_func
#define glthread_recursive_lock_init_multithreaded libintl_recursive_lock_init_multithreaded
#define glthread_recursive_lock_init_func libintl_recursive_lock_init_func
#define glthread_recursive_lock_lock_multithreaded libintl_recursive_lock_lock_multithreaded
#define glthread_recursive_lock_lock_func libintl_recursive_lock_lock_func
#define glthread_recursive_lock_unlock_multithreaded libintl_recursive_lock_unlock_multithreaded
#define glthread_recursive_lock_unlock_func libintl_recursive_lock_unlock_func
#define glthread_recursive_lock_destroy_multithreaded libintl_recursive_lock_destroy_multithreaded
#define glthread_recursive_lock_destroy_func libintl_recursive_lock_destroy_func
#define glthread_once_func libintl_once_func
#define glthread_once_singlethreaded libintl_once_singlethreaded
#define glthread_once_multithreaded libintl_once_multithreaded
])
])
@ -198,40 +223,24 @@ AC_DEFUN([gt_INTL_SUBDIR_CORE],
AC_TRY_LINK(
[int foo (int a) { a = __builtin_expect (a, 10); return a == 10 ? 0 : 1; }],
[],
[AC_DEFINE([HAVE_BUILTIN_EXPECT], 1,
[AC_DEFINE([HAVE_BUILTIN_EXPECT], [1],
[Define to 1 if the compiler understands __builtin_expect.])])
AC_CHECK_HEADERS([argz.h inttypes.h limits.h unistd.h sys/param.h])
AC_CHECK_FUNCS([getcwd getegid geteuid getgid getuid mempcpy munmap \
stpcpy strcasecmp strdup strtoul tsearch argz_count argz_stringify \
argz_next __fsetlocking])
stpcpy strcasecmp strdup strtoul tsearch uselocale argz_count \
argz_stringify argz_next __fsetlocking])
dnl Use the *_unlocked functions only if they are declared.
dnl (because some of them were defined without being declared in Solaris
dnl 2.5.1 but were removed in Solaris 2.6, whereas we want binaries built
dnl on Solaris 2.5.1 to run on Solaris 2.6).
dnl Don't use AC_CHECK_DECLS because it isn't supported in autoconf-2.13.
gt_CHECK_DECL(feof_unlocked, [#include <stdio.h>])
gt_CHECK_DECL(fgets_unlocked, [#include <stdio.h>])
gt_CHECK_DECL([feof_unlocked], [#include <stdio.h>])
gt_CHECK_DECL([fgets_unlocked], [#include <stdio.h>])
AM_ICONV
dnl glibc >= 2.4 has a NL_LOCALE_NAME macro when _GNU_SOURCE is defined,
dnl and a _NL_LOCALE_NAME macro always.
AC_CACHE_CHECK([for NL_LOCALE_NAME macro], gt_cv_nl_locale_name,
[AC_TRY_LINK([#include <langinfo.h>
#include <locale.h>],
[char* cs = nl_langinfo(_NL_LOCALE_NAME(LC_MESSAGES));
return !cs;
],
gt_cv_nl_locale_name=yes,
gt_cv_nl_locale_name=no)
])
if test $gt_cv_nl_locale_name = yes; then
AC_DEFINE(HAVE_NL_LOCALE_NAME, 1,
[Define if you have <langinfo.h> and it defines the NL_LOCALE_NAME macro if _GNU_SOURCE is defined.])
fi
dnl intl/plural.c is generated from intl/plural.y. It requires bison,
dnl because plural.y uses bison specific features. It requires at least
dnl bison-1.26 because earlier versions generate a plural.c that doesn't
@ -269,7 +278,7 @@ dnl gt_CHECK_DECL(FUNC, INCLUDES)
dnl Check whether a function is declared.
AC_DEFUN([gt_CHECK_DECL],
[
AC_CACHE_CHECK([whether $1 is declared], ac_cv_have_decl_$1,
AC_CACHE_CHECK([whether $1 is declared], [ac_cv_have_decl_$1],
[AC_TRY_COMPILE([$2], [
#ifndef $1
char *p = (char *) $1;

View file

@ -1,4 +1,4 @@
# lib-link.m4 serial 20 (gettext-0.18)
# lib-link.m4 serial 23 (gettext-0.18.2)
dnl Copyright (C) 2001-2010 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
@ -18,9 +18,9 @@ AC_DEFUN([AC_LIB_LINKFLAGS],
[
AC_REQUIRE([AC_LIB_PREPARE_PREFIX])
AC_REQUIRE([AC_LIB_RPATH])
pushdef([Name],[translit([$1],[./-], [___])])
pushdef([NAME],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-],
[ABCDEFGHIJKLMNOPQRSTUVWXYZ___])])
pushdef([Name],[m4_translit([$1],[./+-], [____])])
pushdef([NAME],[m4_translit([$1],[abcdefghijklmnopqrstuvwxyz./+-],
[ABCDEFGHIJKLMNOPQRSTUVWXYZ____])])
AC_CACHE_CHECK([how to link with lib[]$1], [ac_cv_lib[]Name[]_libs], [
AC_LIB_LINKFLAGS_BODY([$1], [$2])
ac_cv_lib[]Name[]_libs="$LIB[]NAME"
@ -58,9 +58,9 @@ AC_DEFUN([AC_LIB_HAVE_LINKFLAGS],
[
AC_REQUIRE([AC_LIB_PREPARE_PREFIX])
AC_REQUIRE([AC_LIB_RPATH])
pushdef([Name],[translit([$1],[./-], [___])])
pushdef([NAME],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-],
[ABCDEFGHIJKLMNOPQRSTUVWXYZ___])])
pushdef([Name],[m4_translit([$1],[./+-], [____])])
pushdef([NAME],[m4_translit([$1],[abcdefghijklmnopqrstuvwxyz./+-],
[ABCDEFGHIJKLMNOPQRSTUVWXYZ____])])
dnl Search for lib[]Name and define LIB[]NAME, LTLIB[]NAME and INC[]NAME
dnl accordingly.
@ -74,7 +74,17 @@ AC_DEFUN([AC_LIB_HAVE_LINKFLAGS],
AC_CACHE_CHECK([for lib[]$1], [ac_cv_lib[]Name], [
ac_save_LIBS="$LIBS"
LIBS="$LIBS $LIB[]NAME"
dnl If $LIB[]NAME contains some -l options, add it to the end of LIBS,
dnl because these -l options might require -L options that are present in
dnl LIBS. -l options benefit only from the -L options listed before it.
dnl Otherwise, add it to the front of LIBS, because it may be a static
dnl library that depends on another static library that is present in LIBS.
dnl Static libraries benefit only from the static libraries listed after
dnl it.
case " $LIB[]NAME" in
*" -l"*) LIBS="$LIBS $LIB[]NAME" ;;
*) LIBS="$LIB[]NAME $LIBS" ;;
esac
AC_TRY_LINK([$3], [$4],
[ac_cv_lib[]Name=yes],
[ac_cv_lib[]Name='m4_if([$5], [], [no], [[$5]])'])
@ -147,13 +157,13 @@ dnl package. This declaration must occur before an AC_LIB_LINKFLAGS or similar
dnl macro call that searches for libname.
AC_DEFUN([AC_LIB_FROMPACKAGE],
[
pushdef([NAME],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-],
[ABCDEFGHIJKLMNOPQRSTUVWXYZ___])])
pushdef([NAME],[m4_translit([$1],[abcdefghijklmnopqrstuvwxyz./+-],
[ABCDEFGHIJKLMNOPQRSTUVWXYZ____])])
define([acl_frompackage_]NAME, [$2])
popdef([NAME])
pushdef([PACK],[$2])
pushdef([PACKUP],[translit(PACK,[abcdefghijklmnopqrstuvwxyz./-],
[ABCDEFGHIJKLMNOPQRSTUVWXYZ___])])
pushdef([PACKUP],[m4_translit(PACK,[abcdefghijklmnopqrstuvwxyz./+-],
[ABCDEFGHIJKLMNOPQRSTUVWXYZ____])])
define([acl_libsinpackage_]PACKUP,
m4_ifdef([acl_libsinpackage_]PACKUP, [acl_libsinpackage_]PACKUP[[, ]],)[lib$1])
popdef([PACKUP])
@ -168,14 +178,14 @@ dnl in ${LIB${NAME}_PREFIX}/$acl_libdirstem.
AC_DEFUN([AC_LIB_LINKFLAGS_BODY],
[
AC_REQUIRE([AC_LIB_PREPARE_MULTILIB])
pushdef([NAME],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-],
[ABCDEFGHIJKLMNOPQRSTUVWXYZ___])])
pushdef([NAME],[m4_translit([$1],[abcdefghijklmnopqrstuvwxyz./+-],
[ABCDEFGHIJKLMNOPQRSTUVWXYZ____])])
pushdef([PACK],[m4_ifdef([acl_frompackage_]NAME, [acl_frompackage_]NAME, lib[$1])])
pushdef([PACKUP],[translit(PACK,[abcdefghijklmnopqrstuvwxyz./-],
[ABCDEFGHIJKLMNOPQRSTUVWXYZ___])])
pushdef([PACKUP],[m4_translit(PACK,[abcdefghijklmnopqrstuvwxyz./+-],
[ABCDEFGHIJKLMNOPQRSTUVWXYZ____])])
pushdef([PACKLIBS],[m4_ifdef([acl_frompackage_]NAME, [acl_libsinpackage_]PACKUP, lib[$1])])
dnl Autoconf >= 2.61 supports dots in --with options.
pushdef([P_A_C_K],[m4_if(m4_version_compare(m4_defn([m4_PACKAGE_VERSION]),[2.61]),[-1],[translit(PACK,[.],[_])],PACK)])
pushdef([P_A_C_K],[m4_if(m4_version_compare(m4_defn([m4_PACKAGE_VERSION]),[2.61]),[-1],[m4_translit(PACK,[.],[_])],PACK)])
dnl By default, look in $includedir and $libdir.
use_additional=yes
AC_LIB_WITH_FINAL_PREFIX([
@ -232,7 +242,7 @@ AC_DEFUN([AC_LIB_LINKFLAGS_BODY],
names_already_handled="$names_already_handled $name"
dnl See if it was already located by an earlier AC_LIB_LINKFLAGS
dnl or AC_LIB_HAVE_LINKFLAGS call.
uppername=`echo "$name" | sed -e 'y|abcdefghijklmnopqrstuvwxyz./-|ABCDEFGHIJKLMNOPQRSTUVWXYZ___|'`
uppername=`echo "$name" | sed -e 'y|abcdefghijklmnopqrstuvwxyz./+-|ABCDEFGHIJKLMNOPQRSTUVWXYZ____|'`
eval value=\"\$HAVE_LIB$uppername\"
if test -n "$value"; then
if test "$value" = yes; then

View file

@ -1,4 +1,4 @@
# netdb_h.m4 serial 7
# netdb_h.m4 serial 9
dnl Copyright (C) 2008, 2009, 2010 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
@ -10,21 +10,16 @@ AC_DEFUN([gl_HEADER_NETDB],
AC_CHECK_HEADERS_ONCE([netdb.h])
gl_CHECK_NEXT_HEADERS([netdb.h])
if test $ac_cv_header_netdb_h = yes; then
AC_COMPILE_IFELSE(
[AC_LANG_PROGRAM([[
#include <netdb.h>
struct addrinfo a;
int b = EAI_OVERFLOW;
int c = AI_NUMERICSERV;
]])],
[NETDB_H=''], [NETDB_H='netdb.h'])
HAVE_NETDB_H=1
else
NETDB_H='netdb.h'
HAVE_NETDB_H=0
fi
AC_SUBST([HAVE_NETDB_H])
AC_SUBST([NETDB_H])
dnl Check for declarations of anything we want to poison if the
dnl corresponding gnulib module is not in use.
gl_WARN_ON_USE_PREPARE([[#include <netdb.h>]],
[getaddrinfo freeaddrinfo gai_strerror getnameinfo])
])
AC_DEFUN([gl_NETDB_MODULE_INDICATOR],

View file

@ -1,4 +1,4 @@
# onceonly.m4 serial 6
# onceonly.m4 serial 7
dnl Copyright (C) 2002-2003, 2005-2006, 2008-2010 Free Software Foundation,
dnl Inc.
dnl This file is free software, distributed under the terms of the GNU
@ -39,16 +39,16 @@ AC_PREREQ([2.59])
AC_DEFUN([AC_CHECK_HEADERS_ONCE], [
:
m4_foreach_w([gl_HEADER_NAME], [$1], [
AC_DEFUN([gl_CHECK_HEADER_]m4_quote(translit(gl_HEADER_NAME,
[./-], [___])), [
AC_DEFUN([gl_CHECK_HEADER_]m4_quote(m4_translit(gl_HEADER_NAME,
[./-], [___])), [
m4_divert_text([INIT_PREPARE],
[gl_header_list="$gl_header_list gl_HEADER_NAME"])
gl_HEADERS_EXPANSION
AH_TEMPLATE(AS_TR_CPP([HAVE_]m4_defn([gl_HEADER_NAME])),
[Define to 1 if you have the <]m4_defn([gl_HEADER_NAME])[> header file.])
])
AC_REQUIRE([gl_CHECK_HEADER_]m4_quote(translit(gl_HEADER_NAME,
[./-], [___])))
AC_REQUIRE([gl_CHECK_HEADER_]m4_quote(m4_translit(gl_HEADER_NAME,
[./-], [___])))
])
])
m4_define([gl_HEADERS_EXPANSION], [

View file

@ -29,7 +29,7 @@ AC_DEFUN([AM_PO_SUBDIRS],
dnl Release version of the gettext macros. This is used to ensure that
dnl the gettext macros and po/Makefile.in.in are in sync.
AC_SUBST([GETTEXT_MACRO_VERSION], [0.17])
AC_SUBST([GETTEXT_MACRO_VERSION], [0.18])
dnl Perform the following tests also if --disable-nls has been given,
dnl because they are needed for "make dist" to work.

View file

@ -1,4 +1,4 @@
# printf.m4 serial 33
# printf.m4 serial 34
dnl Copyright (C) 2003, 2007-2010 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
@ -1101,7 +1101,7 @@ dnl }
dnl ---------------------------------------------------------------------
dnl Result is gl_cv_func_snprintf_retval_c99.
AC_DEFUN([gl_SNPRINTF_RETVAL_C99],
AC_DEFUN_ONCE([gl_SNPRINTF_RETVAL_C99],
[
AC_REQUIRE([AC_PROG_CC])
AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles

16
gl/m4/sha1.m4 Normal file
View file

@ -0,0 +1,16 @@
# sha1.m4 serial 9
dnl Copyright (C) 2002, 2003, 2004, 2005, 2006, 2008, 2009, 2010 Free Software
dnl Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
AC_DEFUN([gl_SHA1],
[
AC_LIBOBJ([sha1])
dnl Prerequisites of lib/sha1.c.
AC_REQUIRE([gl_BIGENDIAN])
AC_REQUIRE([AC_C_INLINE])
:
])

View file

@ -47,6 +47,9 @@ AC_DEFUN([gl_SOCKET_FAMILIES],
#endif
#ifdef HAVE_WINSOCK2_H
#include <winsock2.h>
#endif
#ifdef HAVE_WS2TCPIP_H
#include <ws2tcpip.h>
#endif]],
[[int x = AF_INET6; struct in6_addr y; struct sockaddr_in6 z;
if (&x && &y && &z) return 0;]])],

View file

@ -1,4 +1,4 @@
# stdint.m4 serial 34
# stdint.m4 serial 35
dnl Copyright (C) 2001-2010 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
@ -309,7 +309,7 @@ AC_DEFUN([gl_STDINT_BITSIZEOF],
dnl config.h.in,
dnl - extra AC_SUBST calls, so that the right substitutions are made.
m4_foreach_w([gltype], [$1],
[AH_TEMPLATE([BITSIZEOF_]translit(gltype,[abcdefghijklmnopqrstuvwxyz ],[ABCDEFGHIJKLMNOPQRSTUVWXYZ_]),
[AH_TEMPLATE([BITSIZEOF_]m4_translit(gltype,[abcdefghijklmnopqrstuvwxyz ],[ABCDEFGHIJKLMNOPQRSTUVWXYZ_]),
[Define to the number of bits in type ']gltype['.])])
for gltype in $1 ; do
AC_CACHE_CHECK([for bit size of $gltype], [gl_cv_bitsizeof_${gltype}],
@ -334,7 +334,7 @@ AC_DEFUN([gl_STDINT_BITSIZEOF],
eval BITSIZEOF_${GLTYPE}=\$result
done
m4_foreach_w([gltype], [$1],
[AC_SUBST([BITSIZEOF_]translit(gltype,[abcdefghijklmnopqrstuvwxyz ],[ABCDEFGHIJKLMNOPQRSTUVWXYZ_]))])
[AC_SUBST([BITSIZEOF_]m4_translit(gltype,[abcdefghijklmnopqrstuvwxyz ],[ABCDEFGHIJKLMNOPQRSTUVWXYZ_]))])
])
dnl gl_CHECK_TYPES_SIGNED(TYPES, INCLUDES)
@ -347,7 +347,7 @@ AC_DEFUN([gl_CHECK_TYPES_SIGNED],
dnl config.h.in,
dnl - extra AC_SUBST calls, so that the right substitutions are made.
m4_foreach_w([gltype], [$1],
[AH_TEMPLATE([HAVE_SIGNED_]translit(gltype,[abcdefghijklmnopqrstuvwxyz ],[ABCDEFGHIJKLMNOPQRSTUVWXYZ_]),
[AH_TEMPLATE([HAVE_SIGNED_]m4_translit(gltype,[abcdefghijklmnopqrstuvwxyz ],[ABCDEFGHIJKLMNOPQRSTUVWXYZ_]),
[Define to 1 if ']gltype[' is a signed integer type.])])
for gltype in $1 ; do
AC_CACHE_CHECK([whether $gltype is signed], [gl_cv_type_${gltype}_signed],
@ -367,7 +367,7 @@ AC_DEFUN([gl_CHECK_TYPES_SIGNED],
fi
done
m4_foreach_w([gltype], [$1],
[AC_SUBST([HAVE_SIGNED_]translit(gltype,[abcdefghijklmnopqrstuvwxyz ],[ABCDEFGHIJKLMNOPQRSTUVWXYZ_]))])
[AC_SUBST([HAVE_SIGNED_]m4_translit(gltype,[abcdefghijklmnopqrstuvwxyz ],[ABCDEFGHIJKLMNOPQRSTUVWXYZ_]))])
])
dnl gl_INTEGER_TYPE_SUFFIX(TYPES, INCLUDES)
@ -380,7 +380,7 @@ AC_DEFUN([gl_INTEGER_TYPE_SUFFIX],
dnl config.h.in,
dnl - extra AC_SUBST calls, so that the right substitutions are made.
m4_foreach_w([gltype], [$1],
[AH_TEMPLATE(translit(gltype,[abcdefghijklmnopqrstuvwxyz ],[ABCDEFGHIJKLMNOPQRSTUVWXYZ_])[_SUFFIX],
[AH_TEMPLATE(m4_translit(gltype,[abcdefghijklmnopqrstuvwxyz ],[ABCDEFGHIJKLMNOPQRSTUVWXYZ_])[_SUFFIX],
[Define to l, ll, u, ul, ull, etc., as suitable for
constants of type ']gltype['.])])
for gltype in $1 ; do
@ -419,7 +419,7 @@ AC_DEFUN([gl_INTEGER_TYPE_SUFFIX],
AC_DEFINE_UNQUOTED([${GLTYPE}_SUFFIX], [$result])
done
m4_foreach_w([gltype], [$1],
[AC_SUBST(translit(gltype,[abcdefghijklmnopqrstuvwxyz ],[ABCDEFGHIJKLMNOPQRSTUVWXYZ_])[_SUFFIX])])
[AC_SUBST(m4_translit(gltype,[abcdefghijklmnopqrstuvwxyz ],[ABCDEFGHIJKLMNOPQRSTUVWXYZ_])[_SUFFIX])])
])
dnl gl_STDINT_INCLUDES

View file

@ -1,4 +1,4 @@
# stdio_h.m4 serial 30
# stdio_h.m4 serial 31
dnl Copyright (C) 2007-2010 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
@ -8,6 +8,7 @@ AC_DEFUN([gl_STDIO_H],
[
AC_REQUIRE([gl_STDIO_H_DEFAULTS])
AC_REQUIRE([AC_C_INLINE])
AC_REQUIRE([gl_ASM_SYMBOL_PREFIX])
gl_CHECK_NEXT_HEADERS([stdio.h])
dnl No need to create extra modules for these functions. Everyone who uses
dnl <stdio.h> likely needs them.

View file

@ -5,7 +5,7 @@
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# serial 16
# serial 17
# Written by Paul Eggert.
@ -105,6 +105,7 @@ AC_DEFUN([gl_HEADER_STRING_H_DEFAULTS],
REPLACE_STRERROR=0; AC_SUBST([REPLACE_STRERROR])
REPLACE_STRNCAT=0; AC_SUBST([REPLACE_STRNCAT])
REPLACE_STRNDUP=0; AC_SUBST([REPLACE_STRNDUP])
REPLACE_STRNLEN=0; AC_SUBST([REPLACE_STRNLEN])
REPLACE_STRSIGNAL=0; AC_SUBST([REPLACE_STRSIGNAL])
REPLACE_STRTOK_R=0; AC_SUBST([REPLACE_STRTOK_R])
UNDEFINE_STRTOK_R=0; AC_SUBST([UNDEFINE_STRTOK_R])

View file

@ -1,4 +1,4 @@
# strnlen.m4 serial 10
# strnlen.m4 serial 12
dnl Copyright (C) 2002-2003, 2005-2007, 2009-2010 Free Software Foundation,
dnl Inc.
dnl This file is free software; the Free Software Foundation
@ -7,23 +7,23 @@ dnl with or without modifications, as long as this notice is preserved.
AC_DEFUN([gl_FUNC_STRNLEN],
[
AC_REQUIRE([gl_HEADER_STRING_H_DEFAULTS])
dnl Persuade glibc <string.h> to declare strnlen().
AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS])
AC_REQUIRE([gl_HEADER_STRING_H_DEFAULTS])
AC_CHECK_DECLS_ONCE([strnlen])
if test $ac_cv_have_decl_strnlen = no; then
HAVE_DECL_STRNLEN=0
else
AC_FUNC_STRNLEN
dnl Note: AC_FUNC_STRNLEN does AC_LIBOBJ([strnlen]).
if test $ac_cv_func_strnlen_working = no; then
REPLACE_STRNLEN=1
fi
fi
AC_FUNC_STRNLEN
if test $ac_cv_func_strnlen_working = no; then
# This is necessary because automake-1.6.1 doesn't understand
# that the above use of AC_FUNC_STRNLEN means we may have to use
# lib/strnlen.c.
#AC_LIBOBJ([strnlen])
AC_DEFINE([strnlen], [rpl_strnlen],
[Define to rpl_strnlen if the replacement function should be used.])
if test $HAVE_DECL_STRNLEN = 0 || test $REPLACE_STRNLEN = 1; then
AC_LIBOBJ([strnlen])
gl_PREREQ_STRNLEN
fi
])

View file

@ -2,6 +2,8 @@
# Copyright (C) 2000-2001, 2003-2007, 2009-2010 Free Software Foundation, Inc.
# serial 2
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
@ -24,7 +26,7 @@ AC_DEFUN([gl_HEADER_TIME_H_BODY],
])
dnl Define HAVE_STRUCT_TIMESPEC if `struct timespec' is declared
dnl in time.h or sys/time.h.
dnl in time.h, sys/time.h, or pthread.h.
AC_DEFUN([gl_CHECK_TYPE_STRUCT_TIMESPEC],
[
@ -41,6 +43,7 @@ AC_DEFUN([gl_CHECK_TYPE_STRUCT_TIMESPEC],
TIME_H_DEFINES_STRUCT_TIMESPEC=0
SYS_TIME_H_DEFINES_STRUCT_TIMESPEC=0
PTHREAD_H_DEFINES_STRUCT_TIMESPEC=0
if test $gl_cv_sys_struct_timespec_in_time_h = yes; then
TIME_H_DEFINES_STRUCT_TIMESPEC=1
else
@ -55,10 +58,24 @@ AC_DEFUN([gl_CHECK_TYPE_STRUCT_TIMESPEC],
[gl_cv_sys_struct_timespec_in_sys_time_h=no])])
if test $gl_cv_sys_struct_timespec_in_sys_time_h = yes; then
SYS_TIME_H_DEFINES_STRUCT_TIMESPEC=1
else
AC_CACHE_CHECK([for struct timespec in <pthread.h>],
[gl_cv_sys_struct_timespec_in_pthread_h],
[AC_COMPILE_IFELSE(
[AC_LANG_PROGRAM(
[[#include <pthread.h>
]],
[[static struct timespec x; x.tv_sec = x.tv_nsec;]])],
[gl_cv_sys_struct_timespec_in_pthread_h=yes],
[gl_cv_sys_struct_timespec_in_pthread_h=no])])
if test $gl_cv_sys_struct_timespec_in_pthread_h = yes; then
PTHREAD_H_DEFINES_STRUCT_TIMESPEC=1
fi
fi
fi
AC_SUBST([TIME_H_DEFINES_STRUCT_TIMESPEC])
AC_SUBST([SYS_TIME_H_DEFINES_STRUCT_TIMESPEC])
AC_SUBST([PTHREAD_H_DEFINES_STRUCT_TIMESPEC])
])
AC_DEFUN([gl_TIME_MODULE_INDICATOR],

View file

@ -1,4 +1,4 @@
# unistd_h.m4 serial 45
# unistd_h.m4 serial 46
dnl Copyright (C) 2006-2010 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
@ -38,8 +38,9 @@ AC_DEFUN([gl_UNISTD_H],
]], [chown dup2 dup3 environ euidaccess faccessat fchdir fchownat
fsync ftruncate getcwd getdomainname getdtablesize getgroups
gethostname getlogin getlogin_r getpagesize getusershell setusershell
endusershell lchown link linkat lseek pipe2 pread readlink readlinkat
rmdir sleep symlink symlinkat ttyname_r unlink unlinkat usleep])
endusershell lchown link linkat lseek pipe2 pread pwrite readlink
readlinkat rmdir sleep symlink symlinkat ttyname_r unlink unlinkat
usleep])
])
AC_DEFUN([gl_UNISTD_MODULE_INDICATOR],
@ -79,6 +80,7 @@ AC_DEFUN([gl_UNISTD_H_DEFAULTS],
GNULIB_LSEEK=0; AC_SUBST([GNULIB_LSEEK])
GNULIB_PIPE2=0; AC_SUBST([GNULIB_PIPE2])
GNULIB_PREAD=0; AC_SUBST([GNULIB_PREAD])
GNULIB_PWRITE=0; AC_SUBST([GNULIB_PWRITE])
GNULIB_READLINK=0; AC_SUBST([GNULIB_READLINK])
GNULIB_READLINKAT=0; AC_SUBST([GNULIB_READLINKAT])
GNULIB_RMDIR=0; AC_SUBST([GNULIB_RMDIR])
@ -113,6 +115,7 @@ AC_DEFUN([gl_UNISTD_H_DEFAULTS],
HAVE_LINKAT=1; AC_SUBST([HAVE_LINKAT])
HAVE_PIPE2=1; AC_SUBST([HAVE_PIPE2])
HAVE_PREAD=1; AC_SUBST([HAVE_PREAD])
HAVE_PWRITE=1; AC_SUBST([HAVE_PWRITE])
HAVE_READLINK=1; AC_SUBST([HAVE_READLINK])
HAVE_READLINKAT=1; AC_SUBST([HAVE_READLINKAT])
HAVE_SLEEP=1; AC_SUBST([HAVE_SLEEP])
@ -140,10 +143,12 @@ AC_DEFUN([gl_UNISTD_H_DEFAULTS],
REPLACE_LINKAT=0; AC_SUBST([REPLACE_LINKAT])
REPLACE_LSEEK=0; AC_SUBST([REPLACE_LSEEK])
REPLACE_PREAD=0; AC_SUBST([REPLACE_PREAD])
REPLACE_PWRITE=0; AC_SUBST([REPLACE_PWRITE])
REPLACE_READLINK=0; AC_SUBST([REPLACE_READLINK])
REPLACE_RMDIR=0; AC_SUBST([REPLACE_RMDIR])
REPLACE_SLEEP=0; AC_SUBST([REPLACE_SLEEP])
REPLACE_SYMLINK=0; AC_SUBST([REPLACE_SYMLINK])
REPLACE_TTYNAME_R=0; AC_SUBST([REPLACE_TTYNAME_R])
REPLACE_UNLINK=0; AC_SUBST([REPLACE_UNLINK])
REPLACE_UNLINKAT=0; AC_SUBST([REPLACE_UNLINKAT])
REPLACE_USLEEP=0; AC_SUBST([REPLACE_USLEEP])

View file

@ -1,4 +1,4 @@
# vasnprintf.m4 serial 29
# vasnprintf.m4 serial 31
dnl Copyright (C) 2002-2004, 2006-2010 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
@ -54,6 +54,7 @@ AC_DEFUN([gl_PREREQ_PRINTF_PARSE],
# Prerequisites of lib/vasnprintf.c.
AC_DEFUN_ONCE([gl_PREREQ_VASNPRINTF],
[
AC_REQUIRE([AC_C_INLINE])
AC_REQUIRE([AC_FUNC_ALLOCA])
AC_REQUIRE([AC_TYPE_LONG_LONG_INT])
AC_REQUIRE([gt_TYPE_WCHAR_T])
@ -62,6 +63,17 @@ AC_DEFUN_ONCE([gl_PREREQ_VASNPRINTF],
dnl Use the _snprintf function only if it is declared (because on NetBSD it
dnl is defined as a weak alias of snprintf; we prefer to use the latter).
AC_CHECK_DECLS([_snprintf], , , [#include <stdio.h>])
dnl We can avoid a lot of code by assuming that snprintf's return value
dnl conforms to ISO C99. So check that.
AC_REQUIRE([gl_SNPRINTF_RETVAL_C99])
case "$gl_cv_func_snprintf_retval_c99" in
*yes)
AC_DEFINE([HAVE_SNPRINTF_RETVAL_C99], [1],
[Define if the return value of the snprintf function is the number of
of bytes (excluding the terminating NUL) that would have been produced
if the buffer had been large enough.])
;;
esac
])
# Extra prerequisites of lib/vasnprintf.c for supporting 'long double'

View file

@ -1,4 +1,4 @@
# visibility.m4 serial 2 (gettext-0.18)
# visibility.m4 serial 3 (gettext-0.18)
dnl Copyright (C) 2005, 2008-2010 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
@ -26,15 +26,37 @@ AC_DEFUN([gl_VISIBILITY],
CFLAG_VISIBILITY=
HAVE_VISIBILITY=0
if test -n "$GCC"; then
dnl First, check whether -Werror can be added to the command line, or
dnl whether it leads to an error because of some other option that the
dnl user has put into $CC $CFLAGS $CPPFLAGS.
AC_MSG_CHECKING([whether the -Werror option is usable])
AC_CACHE_VAL([gl_cv_cc_vis_werror], [
gl_save_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS -Werror"
AC_TRY_COMPILE([], [],
[gl_cv_cc_vis_werror=yes],
[gl_cv_cc_vis_werror=no])
CFLAGS="$gl_save_CFLAGS"])
AC_MSG_RESULT([$gl_cv_cc_vis_werror])
dnl Now check whether visibility declarations are supported.
AC_MSG_CHECKING([for simple visibility declarations])
AC_CACHE_VAL([gl_cv_cc_visibility], [
gl_save_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS -fvisibility=hidden"
dnl We use the option -Werror and a function dummyfunc, because on some
dnl platforms (Cygwin 1.7) the use of -fvisibility triggers a warning
dnl "visibility attribute not supported in this configuration; ignored"
dnl at the first function definition in every compilation unit, and we
dnl don't want to use the option in this case.
if test $gl_cv_cc_vis_werror = yes; then
CFLAGS="$CFLAGS -Werror"
fi
AC_TRY_COMPILE(
[extern __attribute__((__visibility__("hidden"))) int hiddenvar;
extern __attribute__((__visibility__("default"))) int exportedvar;
extern __attribute__((__visibility__("hidden"))) int hiddenfunc (void);
extern __attribute__((__visibility__("default"))) int exportedfunc (void);],
extern __attribute__((__visibility__("default"))) int exportedfunc (void);
void dummyfunc (void) {}],
[],
[gl_cv_cc_visibility=yes],
[gl_cv_cc_visibility=no])

View file

@ -41,6 +41,8 @@
/* The definition of _GL_ARG_NONNULL is copied here. */
/* The definition of _GL_WARN_ON_USE is copied here. */
/* Declarations for a platform that lacks <netdb.h>, or where it is
incomplete. */
@ -186,7 +188,33 @@ extern int getnameinfo (const struct sockaddr *restrict sa, socklen_t salen,
# define NI_NUMERICSERV 2
# endif
#endif /* @GNULIB_GETADDRINFO@ */
#elif defined GNULIB_POSIXCHECK
# undef getaddrinfo
# if HAVE_RAW_DECL_GETADDRINFO
_GL_WARN_ON_USE (getaddrinfo, "getaddrinfo is unportable - "
"use gnulib module getaddrinfo for portability");
# endif
# undef freeaddrinfo
# if HAVE_RAW_DECL_FREEADDRINFO
_GL_WARN_ON_USE (freeaddrinfo, "freeaddrinfo is unportable - "
"use gnulib module getaddrinfo for portability");
# endif
# undef gai_strerror
# if HAVE_RAW_DECL_GAI_STRERROR
_GL_WARN_ON_USE (gai_strerror, "gai_strerror is unportable - "
"use gnulib module getaddrinfo for portability");
# endif
# undef getnameinfo
# if HAVE_RAW_DECL_GETNAMEINFO
_GL_WARN_ON_USE (getnameinfo, "getnameinfo is unportable - "
"use gnulib module getaddrinfo for portability");
# endif
#endif
#endif /* _GL_NETDB_H */
#endif /* _GL_NETDB_H */

View file

@ -733,15 +733,17 @@ re_string_reconstruct (re_string_t *pstr, Idx idx, int eflags)
mbstate_t cur_state;
wchar_t wc2;
Idx mlen = raw + pstr->len - p;
unsigned char buf[6];
size_t mbclen;
#if 0 /* dead code: buf is set but never used */
unsigned char buf[6];
if (BE (pstr->trans != NULL, 0))
{
int i = mlen < 6 ? mlen : 6;
while (--i >= 0)
buf[i] = pstr->trans[p[i]];
}
#endif
/* XXX Don't use mbrtowc, we know which conversion
to use (UTF-8 -> UCS4). */
memset (&cur_state, 0, sizeof (cur_state));

View file

@ -467,6 +467,8 @@ static unsigned int re_string_context_at (const re_string_t *input, Idx idx,
# else
/* alloca is implemented with malloc, so just use malloc. */
# define __libc_use_alloca(n) 0
# undef alloca
# define alloca(n) malloc (n)
# endif
#endif

428
gl/sha1.c Normal file
View file

@ -0,0 +1,428 @@
/* sha1.c - Functions to compute SHA1 message digest of files or
memory blocks according to the NIST specification FIPS-180-1.
Copyright (C) 2000, 2001, 2003, 2004, 2005, 2006, 2008, 2009, 2010 Free
Software Foundation, Inc.
This program 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, or (at your option) any
later version.
This program 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, write to the Free Software Foundation,
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
/* Written by Scott G. Miller
Credits:
Robert Klep <robert@ilse.nl> -- Expansion function fix
*/
#include <config.h>
#include "sha1.h"
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#if USE_UNLOCKED_IO
# include "unlocked-io.h"
#endif
#ifdef WORDS_BIGENDIAN
# define SWAP(n) (n)
#else
# define SWAP(n) \
(((n) << 24) | (((n) & 0xff00) << 8) | (((n) >> 8) & 0xff00) | ((n) >> 24))
#endif
#define BLOCKSIZE 32768
#if BLOCKSIZE % 64 != 0
# error "invalid BLOCKSIZE"
#endif
/* This array contains the bytes used to pad the buffer to the next
64-byte boundary. (RFC 1321, 3.1: Step 1) */
static const unsigned char fillbuf[64] = { 0x80, 0 /* , 0, 0, ... */ };
/* Take a pointer to a 160 bit block of data (five 32 bit ints) and
initialize it to the start constants of the SHA1 algorithm. This
must be called before using hash in the call to sha1_hash. */
void
sha1_init_ctx (struct sha1_ctx *ctx)
{
ctx->A = 0x67452301;
ctx->B = 0xefcdab89;
ctx->C = 0x98badcfe;
ctx->D = 0x10325476;
ctx->E = 0xc3d2e1f0;
ctx->total[0] = ctx->total[1] = 0;
ctx->buflen = 0;
}
/* Copy the 4 byte value from v into the memory location pointed to by *cp,
If your architecture allows unaligned access this is equivalent to
* (uint32_t *) cp = v */
static inline void
set_uint32 (char *cp, uint32_t v)
{
memcpy (cp, &v, sizeof v);
}
/* Put result from CTX in first 20 bytes following RESBUF. The result
must be in little endian byte order. */
void *
sha1_read_ctx (const struct sha1_ctx *ctx, void *resbuf)
{
char *r = resbuf;
set_uint32 (r + 0 * sizeof ctx->A, SWAP (ctx->A));
set_uint32 (r + 1 * sizeof ctx->B, SWAP (ctx->B));
set_uint32 (r + 2 * sizeof ctx->C, SWAP (ctx->C));
set_uint32 (r + 3 * sizeof ctx->D, SWAP (ctx->D));
set_uint32 (r + 4 * sizeof ctx->E, SWAP (ctx->E));
return resbuf;
}
/* Process the remaining bytes in the internal buffer and the usual
prolog according to the standard and write the result to RESBUF. */
void *
sha1_finish_ctx (struct sha1_ctx *ctx, void *resbuf)
{
/* Take yet unprocessed bytes into account. */
uint32_t bytes = ctx->buflen;
size_t size = (bytes < 56) ? 64 / 4 : 64 * 2 / 4;
/* Now count remaining bytes. */
ctx->total[0] += bytes;
if (ctx->total[0] < bytes)
++ctx->total[1];
/* Put the 64-bit file length in *bits* at the end of the buffer. */
ctx->buffer[size - 2] = SWAP ((ctx->total[1] << 3) | (ctx->total[0] >> 29));
ctx->buffer[size - 1] = SWAP (ctx->total[0] << 3);
memcpy (&((char *) ctx->buffer)[bytes], fillbuf, (size - 2) * 4 - bytes);
/* Process last bytes. */
sha1_process_block (ctx->buffer, size * 4, ctx);
return sha1_read_ctx (ctx, resbuf);
}
/* Compute SHA1 message digest for bytes read from STREAM. The
resulting message digest number will be written into the 16 bytes
beginning at RESBLOCK. */
int
sha1_stream (FILE *stream, void *resblock)
{
struct sha1_ctx ctx;
size_t sum;
char *buffer = malloc (BLOCKSIZE + 72);
if (!buffer)
return 1;
/* Initialize the computation context. */
sha1_init_ctx (&ctx);
/* Iterate over full file contents. */
while (1)
{
/* We read the file in blocks of BLOCKSIZE bytes. One call of the
computation function processes the whole buffer so that with the
next round of the loop another block can be read. */
size_t n;
sum = 0;
/* Read block. Take care for partial reads. */
while (1)
{
n = fread (buffer + sum, 1, BLOCKSIZE - sum, stream);
sum += n;
if (sum == BLOCKSIZE)
break;
if (n == 0)
{
/* Check for the error flag IFF N == 0, so that we don't
exit the loop after a partial read due to e.g., EAGAIN
or EWOULDBLOCK. */
if (ferror (stream))
{
free (buffer);
return 1;
}
goto process_partial_block;
}
/* We've read at least one byte, so ignore errors. But always
check for EOF, since feof may be true even though N > 0.
Otherwise, we could end up calling fread after EOF. */
if (feof (stream))
goto process_partial_block;
}
/* Process buffer with BLOCKSIZE bytes. Note that
BLOCKSIZE % 64 == 0
*/
sha1_process_block (buffer, BLOCKSIZE, &ctx);
}
process_partial_block:;
/* Process any remaining bytes. */
if (sum > 0)
sha1_process_bytes (buffer, sum, &ctx);
/* Construct result in desired memory. */
sha1_finish_ctx (&ctx, resblock);
free (buffer);
return 0;
}
/* Compute SHA1 message digest for LEN bytes beginning at BUFFER. The
result is always in little endian byte order, so that a byte-wise
output yields to the wanted ASCII representation of the message
digest. */
void *
sha1_buffer (const char *buffer, size_t len, void *resblock)
{
struct sha1_ctx ctx;
/* Initialize the computation context. */
sha1_init_ctx (&ctx);
/* Process whole buffer but last len % 64 bytes. */
sha1_process_bytes (buffer, len, &ctx);
/* Put result in desired memory area. */
return sha1_finish_ctx (&ctx, resblock);
}
void
sha1_process_bytes (const void *buffer, size_t len, struct sha1_ctx *ctx)
{
/* When we already have some bits in our internal buffer concatenate
both inputs first. */
if (ctx->buflen != 0)
{
size_t left_over = ctx->buflen;
size_t add = 128 - left_over > len ? len : 128 - left_over;
memcpy (&((char *) ctx->buffer)[left_over], buffer, add);
ctx->buflen += add;
if (ctx->buflen > 64)
{
sha1_process_block (ctx->buffer, ctx->buflen & ~63, ctx);
ctx->buflen &= 63;
/* The regions in the following copy operation cannot overlap. */
memcpy (ctx->buffer,
&((char *) ctx->buffer)[(left_over + add) & ~63],
ctx->buflen);
}
buffer = (const char *) buffer + add;
len -= add;
}
/* Process available complete blocks. */
if (len >= 64)
{
#if !_STRING_ARCH_unaligned
# define alignof(type) offsetof (struct { char c; type x; }, x)
# define UNALIGNED_P(p) (((size_t) p) % alignof (uint32_t) != 0)
if (UNALIGNED_P (buffer))
while (len > 64)
{
sha1_process_block (memcpy (ctx->buffer, buffer, 64), 64, ctx);
buffer = (const char *) buffer + 64;
len -= 64;
}
else
#endif
{
sha1_process_block (buffer, len & ~63, ctx);
buffer = (const char *) buffer + (len & ~63);
len &= 63;
}
}
/* Move remaining bytes in internal buffer. */
if (len > 0)
{
size_t left_over = ctx->buflen;
memcpy (&((char *) ctx->buffer)[left_over], buffer, len);
left_over += len;
if (left_over >= 64)
{
sha1_process_block (ctx->buffer, 64, ctx);
left_over -= 64;
memcpy (ctx->buffer, &ctx->buffer[16], left_over);
}
ctx->buflen = left_over;
}
}
/* --- Code below is the primary difference between md5.c and sha1.c --- */
/* SHA1 round constants */
#define K1 0x5a827999
#define K2 0x6ed9eba1
#define K3 0x8f1bbcdc
#define K4 0xca62c1d6
/* Round functions. Note that F2 is the same as F4. */
#define F1(B,C,D) ( D ^ ( B & ( C ^ D ) ) )
#define F2(B,C,D) (B ^ C ^ D)
#define F3(B,C,D) ( ( B & C ) | ( D & ( B | C ) ) )
#define F4(B,C,D) (B ^ C ^ D)
/* Process LEN bytes of BUFFER, accumulating context into CTX.
It is assumed that LEN % 64 == 0.
Most of this code comes from GnuPG's cipher/sha1.c. */
void
sha1_process_block (const void *buffer, size_t len, struct sha1_ctx *ctx)
{
const uint32_t *words = buffer;
size_t nwords = len / sizeof (uint32_t);
const uint32_t *endp = words + nwords;
uint32_t x[16];
uint32_t a = ctx->A;
uint32_t b = ctx->B;
uint32_t c = ctx->C;
uint32_t d = ctx->D;
uint32_t e = ctx->E;
/* First increment the byte count. RFC 1321 specifies the possible
length of the file up to 2^64 bits. Here we only compute the
number of bytes. Do a double word increment. */
ctx->total[0] += len;
if (ctx->total[0] < len)
++ctx->total[1];
#define rol(x, n) (((x) << (n)) | ((uint32_t) (x) >> (32 - (n))))
#define M(I) ( tm = x[I&0x0f] ^ x[(I-14)&0x0f] \
^ x[(I-8)&0x0f] ^ x[(I-3)&0x0f] \
, (x[I&0x0f] = rol(tm, 1)) )
#define R(A,B,C,D,E,F,K,M) do { E += rol( A, 5 ) \
+ F( B, C, D ) \
+ K \
+ M; \
B = rol( B, 30 ); \
} while(0)
while (words < endp)
{
uint32_t tm;
int t;
for (t = 0; t < 16; t++)
{
x[t] = SWAP (*words);
words++;
}
R( a, b, c, d, e, F1, K1, x[ 0] );
R( e, a, b, c, d, F1, K1, x[ 1] );
R( d, e, a, b, c, F1, K1, x[ 2] );
R( c, d, e, a, b, F1, K1, x[ 3] );
R( b, c, d, e, a, F1, K1, x[ 4] );
R( a, b, c, d, e, F1, K1, x[ 5] );
R( e, a, b, c, d, F1, K1, x[ 6] );
R( d, e, a, b, c, F1, K1, x[ 7] );
R( c, d, e, a, b, F1, K1, x[ 8] );
R( b, c, d, e, a, F1, K1, x[ 9] );
R( a, b, c, d, e, F1, K1, x[10] );
R( e, a, b, c, d, F1, K1, x[11] );
R( d, e, a, b, c, F1, K1, x[12] );
R( c, d, e, a, b, F1, K1, x[13] );
R( b, c, d, e, a, F1, K1, x[14] );
R( a, b, c, d, e, F1, K1, x[15] );
R( e, a, b, c, d, F1, K1, M(16) );
R( d, e, a, b, c, F1, K1, M(17) );
R( c, d, e, a, b, F1, K1, M(18) );
R( b, c, d, e, a, F1, K1, M(19) );
R( a, b, c, d, e, F2, K2, M(20) );
R( e, a, b, c, d, F2, K2, M(21) );
R( d, e, a, b, c, F2, K2, M(22) );
R( c, d, e, a, b, F2, K2, M(23) );
R( b, c, d, e, a, F2, K2, M(24) );
R( a, b, c, d, e, F2, K2, M(25) );
R( e, a, b, c, d, F2, K2, M(26) );
R( d, e, a, b, c, F2, K2, M(27) );
R( c, d, e, a, b, F2, K2, M(28) );
R( b, c, d, e, a, F2, K2, M(29) );
R( a, b, c, d, e, F2, K2, M(30) );
R( e, a, b, c, d, F2, K2, M(31) );
R( d, e, a, b, c, F2, K2, M(32) );
R( c, d, e, a, b, F2, K2, M(33) );
R( b, c, d, e, a, F2, K2, M(34) );
R( a, b, c, d, e, F2, K2, M(35) );
R( e, a, b, c, d, F2, K2, M(36) );
R( d, e, a, b, c, F2, K2, M(37) );
R( c, d, e, a, b, F2, K2, M(38) );
R( b, c, d, e, a, F2, K2, M(39) );
R( a, b, c, d, e, F3, K3, M(40) );
R( e, a, b, c, d, F3, K3, M(41) );
R( d, e, a, b, c, F3, K3, M(42) );
R( c, d, e, a, b, F3, K3, M(43) );
R( b, c, d, e, a, F3, K3, M(44) );
R( a, b, c, d, e, F3, K3, M(45) );
R( e, a, b, c, d, F3, K3, M(46) );
R( d, e, a, b, c, F3, K3, M(47) );
R( c, d, e, a, b, F3, K3, M(48) );
R( b, c, d, e, a, F3, K3, M(49) );
R( a, b, c, d, e, F3, K3, M(50) );
R( e, a, b, c, d, F3, K3, M(51) );
R( d, e, a, b, c, F3, K3, M(52) );
R( c, d, e, a, b, F3, K3, M(53) );
R( b, c, d, e, a, F3, K3, M(54) );
R( a, b, c, d, e, F3, K3, M(55) );
R( e, a, b, c, d, F3, K3, M(56) );
R( d, e, a, b, c, F3, K3, M(57) );
R( c, d, e, a, b, F3, K3, M(58) );
R( b, c, d, e, a, F3, K3, M(59) );
R( a, b, c, d, e, F4, K4, M(60) );
R( e, a, b, c, d, F4, K4, M(61) );
R( d, e, a, b, c, F4, K4, M(62) );
R( c, d, e, a, b, F4, K4, M(63) );
R( b, c, d, e, a, F4, K4, M(64) );
R( a, b, c, d, e, F4, K4, M(65) );
R( e, a, b, c, d, F4, K4, M(66) );
R( d, e, a, b, c, F4, K4, M(67) );
R( c, d, e, a, b, F4, K4, M(68) );
R( b, c, d, e, a, F4, K4, M(69) );
R( a, b, c, d, e, F4, K4, M(70) );
R( e, a, b, c, d, F4, K4, M(71) );
R( d, e, a, b, c, F4, K4, M(72) );
R( c, d, e, a, b, F4, K4, M(73) );
R( b, c, d, e, a, F4, K4, M(74) );
R( a, b, c, d, e, F4, K4, M(75) );
R( e, a, b, c, d, F4, K4, M(76) );
R( d, e, a, b, c, F4, K4, M(77) );
R( c, d, e, a, b, F4, K4, M(78) );
R( b, c, d, e, a, F4, K4, M(79) );
a = ctx->A += a;
b = ctx->B += b;
c = ctx->C += c;
d = ctx->D += d;
e = ctx->E += e;
}
}

92
gl/sha1.h Normal file
View file

@ -0,0 +1,92 @@
/* Declarations of functions and data types used for SHA1 sum
library functions.
Copyright (C) 2000, 2001, 2003, 2005, 2006, 2008, 2009, 2010 Free Software
Foundation, Inc.
This program 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, or (at your option) any
later version.
This program 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, write to the Free Software Foundation,
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
#ifndef SHA1_H
# define SHA1_H 1
# include <stdio.h>
# include <stdint.h>
# ifdef __cplusplus
extern "C" {
# endif
#define SHA1_DIGEST_SIZE 20
/* Structure to save state of computation between the single steps. */
struct sha1_ctx
{
uint32_t A;
uint32_t B;
uint32_t C;
uint32_t D;
uint32_t E;
uint32_t total[2];
uint32_t buflen;
uint32_t buffer[32];
};
/* Initialize structure containing state of computation. */
extern void sha1_init_ctx (struct sha1_ctx *ctx);
/* Starting with the result of former calls of this function (or the
initialization function update the context for the next LEN bytes
starting at BUFFER.
It is necessary that LEN is a multiple of 64!!! */
extern void sha1_process_block (const void *buffer, size_t len,
struct sha1_ctx *ctx);
/* Starting with the result of former calls of this function (or the
initialization function update the context for the next LEN bytes
starting at BUFFER.
It is NOT required that LEN is a multiple of 64. */
extern void sha1_process_bytes (const void *buffer, size_t len,
struct sha1_ctx *ctx);
/* Process the remaining bytes in the buffer and put result from CTX
in first 20 bytes following RESBUF. The result is always in little
endian byte order, so that a byte-wise output yields to the wanted
ASCII representation of the message digest. */
extern void *sha1_finish_ctx (struct sha1_ctx *ctx, void *resbuf);
/* Put result from CTX in first 20 bytes following RESBUF. The result is
always in little endian byte order, so that a byte-wise output yields
to the wanted ASCII representation of the message digest. */
extern void *sha1_read_ctx (const struct sha1_ctx *ctx, void *resbuf);
/* Compute SHA1 message digest for bytes read from STREAM. The
resulting message digest number will be written into the 20 bytes
beginning at RESBLOCK. */
extern int sha1_stream (FILE *stream, void *resblock);
/* Compute SHA1 message digest for LEN bytes beginning at BUFFER. The
result is always in little endian byte order, so that a byte-wise
output yields to the wanted ASCII representation of the message
digest. */
extern void *sha1_buffer (const char *buffer, size_t len, void *resblock);
# ifdef __cplusplus
}
# endif
#endif

View file

@ -50,6 +50,9 @@
with this substitute. With this substitute, only the values 0 and 1
give the expected result when converted to _Bool' or 'bool'.
- C99 allows the use of (_Bool)0.0 in constant expressions, but
this substitute cannot always provide this property.
Also, it is suggested that programs use 'bool' rather than '_Bool';
this isn't required, but 'bool' is more common. */

View file

@ -63,7 +63,6 @@
}
# if !REPLACE_PRINTF_POSIX /* avoid collision with printf.c */
# if !DEPENDS_ON_LIBINTL /* avoid collision with intl/printf.c */
int
printf (const char *format, ...)
{
@ -76,7 +75,6 @@ printf (const char *format, ...)
return retval;
}
# endif
# endif
# if !REPLACE_FPRINTF_POSIX /* avoid collision with fprintf.c */

View file

@ -63,6 +63,10 @@
/* The definition of _GL_WARN_ON_USE is copied here. */
/* Macros for stringification. */
#define _GL_STDIO_STRINGIZE(token) #token
#define _GL_STDIO_MACROEXPAND_AND_STRINGIZE(token) _GL_STDIO_STRINGIZE(token)
#if @GNULIB_DPRINTF@
# if @REPLACE_DPRINTF@
@ -640,16 +644,26 @@ _GL_WARN_ON_USE (popen, "popen is buggy on some platforms - "
#if @GNULIB_PRINTF_POSIX@ || @GNULIB_PRINTF@
# if (@GNULIB_PRINTF_POSIX@ && @REPLACE_PRINTF@) \
|| (@GNULIB_PRINTF@ && @REPLACE_STDIO_WRITE_FUNCS@ && @GNULIB_STDIO_H_SIGPIPE@)
# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
# if defined __GNUC__
# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
/* Don't break __attribute__((format(printf,M,N))). */
# define printf __printf__
# endif
# define GNULIB_overrides_printf 1
# define printf __printf__
# endif
_GL_FUNCDECL_RPL_1 (__printf__, int,
(const char *format, ...)
__asm__ (@ASM_SYMBOL_PREFIX@
_GL_STDIO_MACROEXPAND_AND_STRINGIZE(rpl_printf))
__attribute__ ((__format__ (__printf__, 1, 2)))
_GL_ARG_NONNULL ((1)));
_GL_CXXALIAS_RPL_1 (printf, __printf__, int, (const char *format, ...));
# else
_GL_FUNCDECL_RPL (printf, int,
(const char *format, ...)
__attribute__ ((__format__ (__printf__, 1, 2)))
_GL_ARG_NONNULL ((1)));
_GL_CXXALIAS_RPL (printf, int, (const char *format, ...));
# endif
# define GNULIB_overrides_printf 1
# else
_GL_CXXALIAS_SYS (printf, int, (const char *format, ...));
# endif

View file

@ -32,6 +32,9 @@
# include "intprops.h"
/* Use the system functions, not the gnulib overrides in this file. */
# undef sprintf
# undef strerror
# if ! HAVE_DECL_STRERROR
# define strerror(n) NULL

View file

@ -372,12 +372,23 @@ _GL_WARN_ON_USE (strndup, "strndup is unportable - "
MAXLEN bytes. If no '\0' terminator is found in that many bytes,
return MAXLEN. */
#if @GNULIB_STRNLEN@
# if ! @HAVE_DECL_STRNLEN@
# if @REPLACE_STRNLEN@
# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
# undef strnlen
# define strnlen rpl_strnlen
# endif
_GL_FUNCDECL_RPL (strnlen, size_t, (char const *__string, size_t __maxlen)
__attribute__ ((__pure__))
_GL_ARG_NONNULL ((1)));
_GL_CXXALIAS_RPL (strnlen, size_t, (char const *__string, size_t __maxlen));
# else
# if ! @HAVE_DECL_STRNLEN@
_GL_FUNCDECL_SYS (strnlen, size_t, (char const *__string, size_t __maxlen)
__attribute__ ((__pure__))
_GL_ARG_NONNULL ((1)));
# endif
# endif
_GL_CXXALIAS_SYS (strnlen, size_t, (char const *__string, size_t __maxlen));
# endif
_GL_CXXALIASWARN (strnlen);
#elif defined GNULIB_POSIXCHECK
# undef strnlen

View file

@ -56,7 +56,8 @@
/* Before doing "#define mkdir rpl_mkdir" below, we need to include all
headers that may declare mkdir(). */
#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
# include <io.h>
# include <io.h> /* mingw32, mingw64 */
# include <direct.h> /* mingw64 */
#endif
#ifndef S_IFMT
@ -455,7 +456,8 @@ _GL_CXXALIAS_RPL (mkdir, int, (char const *name, mode_t mode));
#else
/* mingw's _mkdir() function has 1 argument, but we pass 2 arguments.
Additionally, it declares _mkdir (and depending on compile flags, an
alias mkdir), only in the nonstandard <io.h>, which is included above. */
alias mkdir), only in the nonstandard includes <direct.h> and <io.h>,
which are included above. */
# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
static inline int

View file

@ -48,10 +48,20 @@
/* Some systems don't define struct timespec (e.g., AIX 4.1, Ultrix 4.3).
Or they define it with the wrong member names or define it in <sys/time.h>
(e.g., FreeBSD circa 1997). */
(e.g., FreeBSD circa 1997). Stock Mingw does not define it, but the
pthreads-win32 library defines it in <pthread.h>. */
# if ! @TIME_H_DEFINES_STRUCT_TIMESPEC@
# if @SYS_TIME_H_DEFINES_STRUCT_TIMESPEC@
# include <sys/time.h>
# elif @PTHREAD_H_DEFINES_STRUCT_TIMESPEC@
# include <pthread.h>
/* The pthreads-win32 <pthread.h> also defines a couple of broken macros. */
# undef asctime_r
# undef ctime_r
# undef gmtime_r
# undef localtime_r
# undef rand_r
# undef strtok_r
# else
# ifdef __cplusplus

View file

@ -86,7 +86,7 @@
#endif
#if (@GNULIB_WRITE@ || @GNULIB_READLINK@ || @GNULIB_READLINKAT@ \
|| @GNULIB_PREAD@ || defined GNULIB_POSIXCHECK)
|| @GNULIB_PREAD@ || @GNULIB_PWRITE@ || defined GNULIB_POSIXCHECK)
/* Get ssize_t. */
# include <sys/types.h>
#endif
@ -1016,6 +1016,40 @@ _GL_WARN_ON_USE (pread, "pread is unportable - "
#endif
#if @GNULIB_PWRITE@
/* Write at most BUFSIZE bytes from BUF into FD, starting at OFFSET.
Return the number of bytes written if successful, otherwise
set errno and return -1. 0 indicates nothing written. See the
POSIX:2001 specification
<http://www.opengroup.org/susv3xsh/pwrite.html>. */
# if @REPLACE_PWRITE@
# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
# define pwrite rpl_pwrite
# endif
_GL_FUNCDECL_RPL (pwrite, ssize_t,
(int fd, const void *buf, size_t bufsize, off_t offset)
_GL_ARG_NONNULL ((2)));
_GL_CXXALIAS_RPL (pwrite, ssize_t,
(int fd, const void *buf, size_t bufsize, off_t offset));
# else
# if !@HAVE_PWRITE@
_GL_FUNCDECL_SYS (pwrite, ssize_t,
(int fd, const void *buf, size_t bufsize, off_t offset)
_GL_ARG_NONNULL ((2)));
# endif
_GL_CXXALIAS_SYS (pwrite, ssize_t,
(int fd, const void *buf, size_t bufsize, off_t offset));
# endif
_GL_CXXALIASWARN (pwrite);
#elif defined GNULIB_POSIXCHECK
# undef pwrite
# if HAVE_RAW_DECL_PWRITE
_GL_WARN_ON_USE (pwrite, "pwrite is unportable - "
"use gnulib module pwrite for portability");
# endif
#endif
#if @GNULIB_READLINK@
/* Read the contents of the symbolic link FILE and place the first BUFSIZE
bytes of it into BUF. Return the number of bytes placed into BUF if
@ -1164,12 +1198,23 @@ _GL_WARN_ON_USE (symlinkat, "symlinkat is not portable - "
#if @GNULIB_TTYNAME_R@
/* Store at most BUFLEN characters of the pathname of the terminal FD is
open on in BUF. Return 0 on success, otherwise an error number. */
# if !@HAVE_TTYNAME_R@
# if @REPLACE_TTYNAME_R@
# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
# undef ttyname_r
# define ttyname_r rpl_ttyname_r
# endif
_GL_FUNCDECL_RPL (ttyname_r, int,
(int fd, char *buf, size_t buflen) _GL_ARG_NONNULL ((2)));
_GL_CXXALIAS_RPL (ttyname_r, int,
(int fd, char *buf, size_t buflen));
# else
# if !@HAVE_TTYNAME_R@
_GL_FUNCDECL_SYS (ttyname_r, int,
(int fd, char *buf, size_t buflen) _GL_ARG_NONNULL ((2)));
# endif
# endif
_GL_CXXALIAS_SYS (ttyname_r, int,
(int fd, char *buf, size_t buflen));
# endif
_GL_CXXALIASWARN (ttyname_r);
#elif defined GNULIB_POSIXCHECK
# undef ttyname_r
@ -1268,7 +1313,10 @@ _GL_FUNCDECL_RPL (write, ssize_t, (int fd, const void *buf, size_t count)
_GL_ARG_NONNULL ((2)));
_GL_CXXALIAS_RPL (write, ssize_t, (int fd, const void *buf, size_t count));
# else
_GL_CXXALIAS_SYS (write, ssize_t, (int fd, const void *buf, size_t count));
/* Need to cast, because on mingw, the third parameter is
unsigned int count
and the return type is 'int'. */
_GL_CXXALIAS_SYS_CAST (write, ssize_t, (int fd, const void *buf, size_t count));
# endif
_GL_CXXALIASWARN (write);
#endif

View file

@ -148,8 +148,14 @@
# define USE_SNPRINTF 1
# if HAVE_DECL__SNWPRINTF
/* On Windows, the function swprintf() has a different signature than
on Unix; we use the _snwprintf() function instead. */
# define SNPRINTF _snwprintf
on Unix; we use the function _snwprintf() or - on mingw - snwprintf()
instead. The mingw function snwprintf() has fewer bugs than the
MSVCRT function _snwprintf(), so prefer that. */
# if defined __MINGW32__
# define SNPRINTF snwprintf
# else
# define SNPRINTF _snwprintf
# endif
# else
/* Unix. */
# define SNPRINTF swprintf
@ -167,8 +173,15 @@
# define USE_SNPRINTF 0
# endif
# if HAVE_DECL__SNPRINTF
/* Windows. */
# define SNPRINTF _snprintf
/* Windows. The mingw function snprintf() has fewer bugs than the MSVCRT
function _snprintf(), so prefer that. */
# if defined __MINGW32__
# define SNPRINTF snprintf
/* Here we need to call the native snprintf, not rpl_snprintf. */
# undef snprintf
# else
# define SNPRINTF _snprintf
# endif
# else
/* Unix. */
# define SNPRINTF snprintf
@ -194,7 +207,7 @@
#undef remainder
#define remainder rem
#if !USE_SNPRINTF && !WIDE_CHAR_VERSION
#if (!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99) && !WIDE_CHAR_VERSION
# if (HAVE_STRNLEN && !defined _AIX)
# define local_strnlen strnlen
# else
@ -210,7 +223,7 @@ local_strnlen (const char *string, size_t maxlen)
# endif
#endif
#if (!USE_SNPRINTF || (NEED_PRINTF_DIRECTIVE_LS && !defined IN_LIBINTL)) && HAVE_WCHAR_T && (WIDE_CHAR_VERSION || DCHAR_IS_TCHAR)
#if (((!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99) && WIDE_CHAR_VERSION) || ((!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || (NEED_PRINTF_DIRECTIVE_LS && !defined IN_LIBINTL)) && !WIDE_CHAR_VERSION && DCHAR_IS_TCHAR)) && HAVE_WCHAR_T
# if HAVE_WCSLEN
# define local_wcslen wcslen
# else
@ -233,7 +246,7 @@ local_wcslen (const wchar_t *s)
# endif
#endif
#if !USE_SNPRINTF && HAVE_WCHAR_T && WIDE_CHAR_VERSION
#if (!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99) && HAVE_WCHAR_T && WIDE_CHAR_VERSION
# if HAVE_WCSNLEN
# define local_wcsnlen wcsnlen
# else
@ -1474,6 +1487,258 @@ is_borderline (const char *digits, size_t precision)
#endif
#if !USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99
/* Use a different function name, to make it possible that the 'wchar_t'
parametrization and the 'char' parametrization get compiled in the same
translation unit. */
# if WIDE_CHAR_VERSION
# define MAX_ROOM_NEEDED wmax_room_needed
# else
# define MAX_ROOM_NEEDED max_room_needed
# endif
/* Returns the number of TCHAR_T units needed as temporary space for the result
of sprintf or SNPRINTF of a single conversion directive. */
static inline size_t
MAX_ROOM_NEEDED (const arguments *ap, size_t arg_index, FCHAR_T conversion,
arg_type type, int flags, size_t width, int has_precision,
size_t precision, int pad_ourselves)
{
size_t tmp_length;
switch (conversion)
{
case 'd': case 'i': case 'u':
# if HAVE_LONG_LONG_INT
if (type == TYPE_LONGLONGINT || type == TYPE_ULONGLONGINT)
tmp_length =
(unsigned int) (sizeof (unsigned long long) * CHAR_BIT
* 0.30103 /* binary -> decimal */
)
+ 1; /* turn floor into ceil */
else
# endif
if (type == TYPE_LONGINT || type == TYPE_ULONGINT)
tmp_length =
(unsigned int) (sizeof (unsigned long) * CHAR_BIT
* 0.30103 /* binary -> decimal */
)
+ 1; /* turn floor into ceil */
else
tmp_length =
(unsigned int) (sizeof (unsigned int) * CHAR_BIT
* 0.30103 /* binary -> decimal */
)
+ 1; /* turn floor into ceil */
if (tmp_length < precision)
tmp_length = precision;
/* Multiply by 2, as an estimate for FLAG_GROUP. */
tmp_length = xsum (tmp_length, tmp_length);
/* Add 1, to account for a leading sign. */
tmp_length = xsum (tmp_length, 1);
break;
case 'o':
# if HAVE_LONG_LONG_INT
if (type == TYPE_LONGLONGINT || type == TYPE_ULONGLONGINT)
tmp_length =
(unsigned int) (sizeof (unsigned long long) * CHAR_BIT
* 0.333334 /* binary -> octal */
)
+ 1; /* turn floor into ceil */
else
# endif
if (type == TYPE_LONGINT || type == TYPE_ULONGINT)
tmp_length =
(unsigned int) (sizeof (unsigned long) * CHAR_BIT
* 0.333334 /* binary -> octal */
)
+ 1; /* turn floor into ceil */
else
tmp_length =
(unsigned int) (sizeof (unsigned int) * CHAR_BIT
* 0.333334 /* binary -> octal */
)
+ 1; /* turn floor into ceil */
if (tmp_length < precision)
tmp_length = precision;
/* Add 1, to account for a leading sign. */
tmp_length = xsum (tmp_length, 1);
break;
case 'x': case 'X':
# if HAVE_LONG_LONG_INT
if (type == TYPE_LONGLONGINT || type == TYPE_ULONGLONGINT)
tmp_length =
(unsigned int) (sizeof (unsigned long long) * CHAR_BIT
* 0.25 /* binary -> hexadecimal */
)
+ 1; /* turn floor into ceil */
else
# endif
if (type == TYPE_LONGINT || type == TYPE_ULONGINT)
tmp_length =
(unsigned int) (sizeof (unsigned long) * CHAR_BIT
* 0.25 /* binary -> hexadecimal */
)
+ 1; /* turn floor into ceil */
else
tmp_length =
(unsigned int) (sizeof (unsigned int) * CHAR_BIT
* 0.25 /* binary -> hexadecimal */
)
+ 1; /* turn floor into ceil */
if (tmp_length < precision)
tmp_length = precision;
/* Add 2, to account for a leading sign or alternate form. */
tmp_length = xsum (tmp_length, 2);
break;
case 'f': case 'F':
if (type == TYPE_LONGDOUBLE)
tmp_length =
(unsigned int) (LDBL_MAX_EXP
* 0.30103 /* binary -> decimal */
* 2 /* estimate for FLAG_GROUP */
)
+ 1 /* turn floor into ceil */
+ 10; /* sign, decimal point etc. */
else
tmp_length =
(unsigned int) (DBL_MAX_EXP
* 0.30103 /* binary -> decimal */
* 2 /* estimate for FLAG_GROUP */
)
+ 1 /* turn floor into ceil */
+ 10; /* sign, decimal point etc. */
tmp_length = xsum (tmp_length, precision);
break;
case 'e': case 'E': case 'g': case 'G':
tmp_length =
12; /* sign, decimal point, exponent etc. */
tmp_length = xsum (tmp_length, precision);
break;
case 'a': case 'A':
if (type == TYPE_LONGDOUBLE)
tmp_length =
(unsigned int) (LDBL_DIG
* 0.831 /* decimal -> hexadecimal */
)
+ 1; /* turn floor into ceil */
else
tmp_length =
(unsigned int) (DBL_DIG
* 0.831 /* decimal -> hexadecimal */
)
+ 1; /* turn floor into ceil */
if (tmp_length < precision)
tmp_length = precision;
/* Account for sign, decimal point etc. */
tmp_length = xsum (tmp_length, 12);
break;
case 'c':
# if HAVE_WINT_T && !WIDE_CHAR_VERSION
if (type == TYPE_WIDE_CHAR)
tmp_length = MB_CUR_MAX;
else
# endif
tmp_length = 1;
break;
case 's':
# if HAVE_WCHAR_T
if (type == TYPE_WIDE_STRING)
{
# if WIDE_CHAR_VERSION
/* ISO C says about %ls in fwprintf:
"If the precision is not specified or is greater than the size
of the array, the array shall contain a null wide character."
So if there is a precision, we must not use wcslen. */
const wchar_t *arg = ap->arg[arg_index].a.a_wide_string;
if (has_precision)
tmp_length = local_wcsnlen (arg, precision);
else
tmp_length = local_wcslen (arg);
# else
/* ISO C says about %ls in fprintf:
"If a precision is specified, no more than that many bytes are
written (including shift sequences, if any), and the array
shall contain a null wide character if, to equal the multibyte
character sequence length given by the precision, the function
would need to access a wide character one past the end of the
array."
So if there is a precision, we must not use wcslen. */
/* This case has already been handled separately in VASNPRINTF. */
abort ();
# endif
}
else
# endif
{
# if WIDE_CHAR_VERSION
/* ISO C says about %s in fwprintf:
"If the precision is not specified or is greater than the size
of the converted array, the converted array shall contain a
null wide character."
So if there is a precision, we must not use strlen. */
/* This case has already been handled separately in VASNPRINTF. */
abort ();
# else
/* ISO C says about %s in fprintf:
"If the precision is not specified or greater than the size of
the array, the array shall contain a null character."
So if there is a precision, we must not use strlen. */
const char *arg = ap->arg[arg_index].a.a_string;
if (has_precision)
tmp_length = local_strnlen (arg, precision);
else
tmp_length = strlen (arg);
# endif
}
break;
case 'p':
tmp_length =
(unsigned int) (sizeof (void *) * CHAR_BIT
* 0.25 /* binary -> hexadecimal */
)
+ 1 /* turn floor into ceil */
+ 2; /* account for leading 0x */
break;
default:
abort ();
}
if (!pad_ourselves)
{
# if ENABLE_UNISTDIO
/* Padding considers the number of characters, therefore the number of
elements after padding may be
> max (tmp_length, width)
but is certainly
<= tmp_length + width. */
tmp_length = xsum (tmp_length, width);
# else
/* Padding considers the number of elements, says POSIX. */
if (tmp_length < width)
tmp_length = width;
# endif
}
tmp_length = xsum (tmp_length, 1); /* account for trailing NUL */
return tmp_length;
}
#endif
DCHAR_T *
VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
const FCHAR_T *format, va_list args)
@ -2103,7 +2368,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
}
}
#endif
#if (!USE_SNPRINTF || (NEED_PRINTF_DIRECTIVE_LS && !defined IN_LIBINTL)) && HAVE_WCHAR_T
#if (!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || (NEED_PRINTF_DIRECTIVE_LS && !defined IN_LIBINTL)) && HAVE_WCHAR_T
else if (dp->conversion == 's'
# if WIDE_CHAR_VERSION
&& a.arg[dp->arg_index].type != TYPE_WIDE_STRING
@ -2592,8 +2857,16 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
count = wctomb (cbuf, *arg);
# endif
if (count <= 0)
/* Inconsistency. */
abort ();
{
/* Cannot convert. */
if (!(result == resultbuf || result == NULL))
free (result);
if (buf_malloced != NULL)
free (buf_malloced);
CLEANUP ();
errno = EILSEQ;
return NULL;
}
ENSURE_ALLOCATION (xsum (length, count));
memcpy (result + length, cbuf, count);
length += count;
@ -2616,8 +2889,8 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
length += n;
}
}
}
# endif
}
#endif
#if (NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_DOUBLE) && !defined IN_LIBINTL
else if ((dp->conversion == 'a' || dp->conversion == 'A')
@ -4301,11 +4574,11 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
{
arg_type type = a.arg[dp->arg_index].type;
int flags = dp->flags;
#if !USE_SNPRINTF || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
#if !USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
int has_width;
size_t width;
#endif
#if !USE_SNPRINTF || NEED_PRINTF_UNBOUNDED_PRECISION
#if !USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || NEED_PRINTF_UNBOUNDED_PRECISION
int has_precision;
size_t precision;
#endif
@ -4330,7 +4603,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
TCHAR_T *tmp;
#endif
#if !USE_SNPRINTF || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
#if !USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
has_width = 0;
width = 0;
if (dp->width_start != dp->width_end)
@ -4364,7 +4637,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
}
#endif
#if !USE_SNPRINTF || NEED_PRINTF_UNBOUNDED_PRECISION
#if !USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || NEED_PRINTF_UNBOUNDED_PRECISION
has_precision = 0;
precision = 6;
if (dp->precision_start != dp->precision_end)
@ -4437,246 +4710,10 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
#if !USE_SNPRINTF
/* Allocate a temporary buffer of sufficient size for calling
sprintf. */
{
switch (dp->conversion)
{
case 'd': case 'i': case 'u':
# if HAVE_LONG_LONG_INT
if (type == TYPE_LONGLONGINT || type == TYPE_ULONGLONGINT)
tmp_length =
(unsigned int) (sizeof (unsigned long long) * CHAR_BIT
* 0.30103 /* binary -> decimal */
)
+ 1; /* turn floor into ceil */
else
# endif
if (type == TYPE_LONGINT || type == TYPE_ULONGINT)
tmp_length =
(unsigned int) (sizeof (unsigned long) * CHAR_BIT
* 0.30103 /* binary -> decimal */
)
+ 1; /* turn floor into ceil */
else
tmp_length =
(unsigned int) (sizeof (unsigned int) * CHAR_BIT
* 0.30103 /* binary -> decimal */
)
+ 1; /* turn floor into ceil */
if (tmp_length < precision)
tmp_length = precision;
/* Multiply by 2, as an estimate for FLAG_GROUP. */
tmp_length = xsum (tmp_length, tmp_length);
/* Add 1, to account for a leading sign. */
tmp_length = xsum (tmp_length, 1);
break;
case 'o':
# if HAVE_LONG_LONG_INT
if (type == TYPE_LONGLONGINT || type == TYPE_ULONGLONGINT)
tmp_length =
(unsigned int) (sizeof (unsigned long long) * CHAR_BIT
* 0.333334 /* binary -> octal */
)
+ 1; /* turn floor into ceil */
else
# endif
if (type == TYPE_LONGINT || type == TYPE_ULONGINT)
tmp_length =
(unsigned int) (sizeof (unsigned long) * CHAR_BIT
* 0.333334 /* binary -> octal */
)
+ 1; /* turn floor into ceil */
else
tmp_length =
(unsigned int) (sizeof (unsigned int) * CHAR_BIT
* 0.333334 /* binary -> octal */
)
+ 1; /* turn floor into ceil */
if (tmp_length < precision)
tmp_length = precision;
/* Add 1, to account for a leading sign. */
tmp_length = xsum (tmp_length, 1);
break;
case 'x': case 'X':
# if HAVE_LONG_LONG_INT
if (type == TYPE_LONGLONGINT || type == TYPE_ULONGLONGINT)
tmp_length =
(unsigned int) (sizeof (unsigned long long) * CHAR_BIT
* 0.25 /* binary -> hexadecimal */
)
+ 1; /* turn floor into ceil */
else
# endif
if (type == TYPE_LONGINT || type == TYPE_ULONGINT)
tmp_length =
(unsigned int) (sizeof (unsigned long) * CHAR_BIT
* 0.25 /* binary -> hexadecimal */
)
+ 1; /* turn floor into ceil */
else
tmp_length =
(unsigned int) (sizeof (unsigned int) * CHAR_BIT
* 0.25 /* binary -> hexadecimal */
)
+ 1; /* turn floor into ceil */
if (tmp_length < precision)
tmp_length = precision;
/* Add 2, to account for a leading sign or alternate form. */
tmp_length = xsum (tmp_length, 2);
break;
case 'f': case 'F':
if (type == TYPE_LONGDOUBLE)
tmp_length =
(unsigned int) (LDBL_MAX_EXP
* 0.30103 /* binary -> decimal */
* 2 /* estimate for FLAG_GROUP */
)
+ 1 /* turn floor into ceil */
+ 10; /* sign, decimal point etc. */
else
tmp_length =
(unsigned int) (DBL_MAX_EXP
* 0.30103 /* binary -> decimal */
* 2 /* estimate for FLAG_GROUP */
)
+ 1 /* turn floor into ceil */
+ 10; /* sign, decimal point etc. */
tmp_length = xsum (tmp_length, precision);
break;
case 'e': case 'E': case 'g': case 'G':
tmp_length =
12; /* sign, decimal point, exponent etc. */
tmp_length = xsum (tmp_length, precision);
break;
case 'a': case 'A':
if (type == TYPE_LONGDOUBLE)
tmp_length =
(unsigned int) (LDBL_DIG
* 0.831 /* decimal -> hexadecimal */
)
+ 1; /* turn floor into ceil */
else
tmp_length =
(unsigned int) (DBL_DIG
* 0.831 /* decimal -> hexadecimal */
)
+ 1; /* turn floor into ceil */
if (tmp_length < precision)
tmp_length = precision;
/* Account for sign, decimal point etc. */
tmp_length = xsum (tmp_length, 12);
break;
case 'c':
# if HAVE_WINT_T && !WIDE_CHAR_VERSION
if (type == TYPE_WIDE_CHAR)
tmp_length = MB_CUR_MAX;
else
# endif
tmp_length = 1;
break;
case 's':
# if HAVE_WCHAR_T
if (type == TYPE_WIDE_STRING)
{
# if WIDE_CHAR_VERSION
/* ISO C says about %ls in fwprintf:
"If the precision is not specified or is greater
than the size of the array, the array shall
contain a null wide character."
So if there is a precision, we must not use
wcslen. */
const wchar_t *arg =
a.arg[dp->arg_index].a.a_wide_string;
if (has_precision)
tmp_length = local_wcsnlen (arg, precision);
else
tmp_length = local_wcslen (arg);
# else
/* ISO C says about %ls in fprintf:
"If a precision is specified, no more than that
many bytes are written (including shift
sequences, if any), and the array shall contain
a null wide character if, to equal the
multibyte character sequence length given by
the precision, the function would need to
access a wide character one past the end of the
array."
So if there is a precision, we must not use
wcslen. */
/* This case has already been handled above. */
abort ();
# endif
}
else
# endif
{
# if WIDE_CHAR_VERSION
/* ISO C says about %s in fwprintf:
"If the precision is not specified or is greater
than the size of the converted array, the
converted array shall contain a null wide
character."
So if there is a precision, we must not use
strlen. */
/* This case has already been handled above. */
abort ();
# else
/* ISO C says about %s in fprintf:
"If the precision is not specified or greater
than the size of the array, the array shall
contain a null character."
So if there is a precision, we must not use
strlen. */
const char *arg = a.arg[dp->arg_index].a.a_string;
if (has_precision)
tmp_length = local_strnlen (arg, precision);
else
tmp_length = strlen (arg);
# endif
}
break;
case 'p':
tmp_length =
(unsigned int) (sizeof (void *) * CHAR_BIT
* 0.25 /* binary -> hexadecimal */
)
+ 1 /* turn floor into ceil */
+ 2; /* account for leading 0x */
break;
default:
abort ();
}
if (!pad_ourselves)
{
# if ENABLE_UNISTDIO
/* Padding considers the number of characters, therefore
the number of elements after padding may be
> max (tmp_length, width)
but is certainly
<= tmp_length + width. */
tmp_length = xsum (tmp_length, width);
# else
/* Padding considers the number of elements,
says POSIX. */
if (tmp_length < width)
tmp_length = width;
# endif
}
tmp_length = xsum (tmp_length, 1); /* account for trailing NUL */
}
tmp_length =
MAX_ROOM_NEEDED (&a, dp->arg_index, dp->conversion, type,
flags, width, has_precision, precision,
pad_ourselves);
if (tmp_length <= sizeof (tmpbuf) / sizeof (TCHAR_T))
tmp = tmpbuf;
@ -4916,6 +4953,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
}
#endif
errno = 0;
switch (type)
{
case TYPE_SCHAR:
@ -5062,15 +5100,44 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
/* Look at the snprintf() return value. */
if (retcount < 0)
{
# if !HAVE_SNPRINTF_RETVAL_C99
/* HP-UX 10.20 snprintf() is doubly deficient:
It doesn't understand the '%n' directive,
*and* it returns -1 (rather than the length
that would have been required) when the
buffer is too small. */
size_t bigger_need =
xsum (xtimes (allocated, 2), 12);
ENSURE_ALLOCATION (bigger_need);
continue;
buffer is too small.
But a failure at this point can also come
from other reasons than a too small buffer,
such as an invalid wide string argument to
the %ls directive, or possibly an invalid
floating-point argument. */
size_t tmp_length =
MAX_ROOM_NEEDED (&a, dp->arg_index,
dp->conversion, type, flags,
width, has_precision,
precision, pad_ourselves);
if (maxlen < tmp_length)
{
/* Make more room. But try to do through
this reallocation only once. */
size_t bigger_need =
xsum (length,
xsum (tmp_length,
TCHARS_PER_DCHAR - 1)
/ TCHARS_PER_DCHAR);
/* And always grow proportionally.
(There may be several arguments, each
needing a little more room than the
previous one.) */
size_t bigger_need2 =
xsum (xtimes (allocated, 2), 12);
if (bigger_need < bigger_need2)
bigger_need = bigger_need2;
ENSURE_ALLOCATION (bigger_need);
continue;
}
# endif
}
else
count = retcount;
@ -5081,12 +5148,21 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
/* Attempt to handle failure. */
if (count < 0)
{
/* SNPRINTF or sprintf failed. Save and use the errno
that it has set, if any. */
int saved_errno = errno;
if (!(result == resultbuf || result == NULL))
free (result);
if (buf_malloced != NULL)
free (buf_malloced);
CLEANUP ();
errno = EINVAL;
errno =
(saved_errno != 0
? saved_errno
: (dp->conversion == 'c' || dp->conversion == 's'
? EILSEQ
: EINVAL));
return NULL;
}
@ -5422,6 +5498,8 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
length += count;
break;
}
#undef pad_ourselves
#undef prec_ourselves
}
}
}
@ -5473,6 +5551,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
}
}
#undef MAX_ROOM_NEEDED
#undef TCHARS_PER_DCHAR
#undef SNPRINTF
#undef USE_SNPRINTF

View file

@ -69,13 +69,14 @@
if the entity names are not disambiguated. A workaround is to
attach the current line number to the entity name:
#define GL_CONCAT0(x, y) x##y
#define GL_CONCAT(x, y) GL_CONCAT0 (x, y)
extern struct {...} * GL_CONCAT(dummy,__LINE__);
#define _GL_CONCAT0(x, y) x##y
#define _GL_CONCAT(x, y) _GL_CONCAT0 (x, y)
extern struct {...} * _GL_CONCAT (dummy, __LINE__);
But this has the problem that two invocations of verify from
within the same macro would collide, since the __LINE__ value
would be the same for both invocations.
would be the same for both invocations. (The GCC __COUNTER__
macro solves this problem, but is not portable.)
A solution is to use the sizeof operator. It yields a number,
getting rid of the identity of the type. Declarations like
@ -103,20 +104,41 @@
extern int (*dummy (void)) [sizeof (struct {...})];
* GCC warns about duplicate declarations of the dummy function if
-Wredundant_decls is used. GCC 4.3 and later have a builtin
__COUNTER__ macro that can let us generate unique identifiers for
each dummy function, to suppress this warning.
* This implementation exploits the fact that GCC does not warn about
the last declaration mentioned above. If a future version of GCC
introduces a warning for this, the problem could be worked around
by using code specialized to GCC, e.g.,:
by using code specialized to GCC, just as __COUNTER__ is already
being used if available.
#if 4 <= __GNUC__
# define verify(R) \
extern int (* verify_function__ (void)) \
[__builtin_constant_p (R) && (R) ? 1 : -1]
# define verify(R) [another version to keep GCC happy]
#endif
* In C++, any struct definition inside sizeof is invalid.
Use a template type to work around the problem. */
/* Concatenate two preprocessor tokens. */
# define _GL_CONCAT(x, y) _GL_CONCAT0 (x, y)
# define _GL_CONCAT0(x, y) x##y
/* _GL_COUNTER is an integer, preferably one that changes each time we
use it. Use __COUNTER__ if it works, falling back on __LINE__
otherwise. __LINE__ isn't perfect, but it's better than a
constant. */
# if defined __COUNTER__ && __COUNTER__ != __COUNTER__
# define _GL_COUNTER __COUNTER__
# else
# define _GL_COUNTER __LINE__
# endif
/* Generate a symbol with the given prefix, making it unique if
possible. */
# define _GL_GENSYM(prefix) _GL_CONCAT (prefix, _GL_COUNTER)
/* Verify requirement R at compile-time, as an integer constant expression.
Return 1. */
@ -135,6 +157,7 @@ template <int w>
/* Verify requirement R at compile-time, as a declaration without a
trailing ';'. */
# define verify(R) extern int (* verify_function__ (void)) [verify_true (R)]
# define verify(R) \
extern int (* _GL_GENSYM (verify_function) (void)) [verify_true (R)]
#endif

View file

@ -407,7 +407,7 @@ _GL_WARN_ON_USE (wcsnrtombs, "wcsnrtombs is unportable - "
_GL_FUNCDECL_RPL (wcwidth, int, (wchar_t));
_GL_CXXALIAS_RPL (wcwidth, int, (wchar_t));
# else
# if !defined wcwidth && !@HAVE_DECL_WCWIDTH@
# if !@HAVE_DECL_WCWIDTH@
/* wcwidth exists but is not declared. */
_GL_FUNCDECL_SYS (wcwidth, int, (wchar_t));
# endif

View file

@ -4,6 +4,7 @@ SUBDIRS = . tests
noinst_LIBRARIES = libnagiosplug.a
AM_CPPFLAGS = -DNP_STATE_DIR_PREFIX=\"$(localstatedir)\"
libnagiosplug_a_SOURCES = utils_base.c utils_disk.c utils_tcp.c utils_cmd.c
EXTRA_DIST = utils_base.h utils_disk.h utils_tcp.h utils_cmd.h parse_ini.h extra_opts.h

View file

@ -5,6 +5,8 @@ noinst_PROGRAMS = @EXTRA_TEST@
TESTS = @EXTRA_TEST@
check_PROGRAMS = @EXTRA_TEST@
AM_CPPFLAGS = -DNP_STATE_DIR_PREFIX=\"$(localstatedir)\"
INCLUDES = -I$(top_srcdir)/lib -I$(top_srcdir)/gl -I$(top_srcdir)/intl -I$(top_srcdir)/plugins
EXTRA_PROGRAMS = test_utils test_disk test_tcp test_cmd test_base64 test_ini1 test_ini3 test_opts1 test_opts2 test_opts3

View file

@ -21,6 +21,11 @@
#include "tap.h"
#include <sys/types.h>
#include <sys/stat.h>
#include "utils_base.c"
int
main (int argc, char **argv)
{
@ -28,8 +33,31 @@ main (int argc, char **argv)
double temp;
thresholds *thresholds = NULL;
int rc;
char *temp_string;
state_key *temp_state_key = NULL;
state_data *temp_state_data;
time_t current_time;
char *temp_filename;
FILE *temp_fp;
plan_tests(81+23);
plan_tests(141);
ok( this_nagios_plugin==NULL, "nagios_plugin not initialised");
np_init( "check_test", argc, argv );
ok( this_nagios_plugin!=NULL, "nagios_plugin now initialised");
ok( !strcmp(this_nagios_plugin->plugin_name, "check_test"), "plugin name initialised" );
ok( this_nagios_plugin->argc==argc, "Argc set" );
ok( this_nagios_plugin->argv==argv, "Argv set" );
np_set_args(0,0);
ok( this_nagios_plugin->argc==0, "argc changed" );
ok( this_nagios_plugin->argv==0, "argv changed" );
np_set_args(argc, argv);
range = parse_range_string("6");
ok( range != NULL, "'6' is valid range");
@ -251,5 +279,157 @@ main (int argc, char **argv)
test=np_extract_ntpvar("", "foo");
ok(!test, "Empty string return NULL");
/* This is the result of running ./test_utils */
temp_string = (char *) _np_state_generate_key();
ok(!strcmp(temp_string, "83d877b6cdfefb5d6f06101fd6fe76762f21792c"), "Got hash with exe and no parameters" ) ||
diag( "You are probably running in wrong directory. Must run as ./test_utils" );
this_nagios_plugin->argc=4;
this_nagios_plugin->argv[0] = "./test_utils";
this_nagios_plugin->argv[1] = "here";
this_nagios_plugin->argv[2] = "--and";
this_nagios_plugin->argv[3] = "now";
temp_string = (char *) _np_state_generate_key();
ok(!strcmp(temp_string, "94b5e17bf5abf51cb15aff5f69b96f2f8dac5ecd"), "Got based on expected argv" );
unsetenv("NAGIOS_PLUGIN_STATE_DIRECTORY");
temp_string = (char *) _np_state_calculate_location_prefix();
ok(!strcmp(temp_string, NP_STATE_DIR_PREFIX), "Got default directory" );
setenv("NAGIOS_PLUGIN_STATE_DIRECTORY", "", 1);
temp_string = (char *) _np_state_calculate_location_prefix();
ok(!strcmp(temp_string, NP_STATE_DIR_PREFIX), "Got default directory even with empty string" );
setenv("NAGIOS_PLUGIN_STATE_DIRECTORY", "/usr/local/nagios/var", 1);
temp_string = (char *) _np_state_calculate_location_prefix();
ok(!strcmp(temp_string, "/usr/local/nagios/var"), "Got default directory" );
ok(temp_state_key==NULL, "temp_state_key initially empty");
this_nagios_plugin->argc=1;
this_nagios_plugin->argv[0] = "./test_utils";
np_enable_state(NULL, 51);
temp_state_key = this_nagios_plugin->state;
ok( !strcmp(temp_state_key->plugin_name, "check_test"), "Got plugin name" );
ok( !strcmp(temp_state_key->name, "83d877b6cdfefb5d6f06101fd6fe76762f21792c"), "Got generated filename" );
np_enable_state("allowedchars_in_keyname", 77);
temp_state_key = this_nagios_plugin->state;
ok( !strcmp(temp_state_key->plugin_name, "check_test"), "Got plugin name" );
ok( !strcmp(temp_state_key->name, "allowedchars_in_keyname"), "Got key name with valid chars" );
ok( !strcmp(temp_state_key->_filename, "/usr/local/nagios/var/check_test/allowedchars_in_keyname"), "Got internal filename" );
/* Don't do this test just yet. Will die */
/*
np_enable_state("bad^chars$in@here", 77);
temp_state_key = this_nagios_plugin->state;
ok( !strcmp(temp_state_key->name, "bad_chars_in_here"), "Got key name with bad chars replaced" );
*/
np_enable_state("funnykeyname", 54);
temp_state_key = this_nagios_plugin->state;
ok( !strcmp(temp_state_key->plugin_name, "check_test"), "Got plugin name" );
ok( !strcmp(temp_state_key->name, "funnykeyname"), "Got key name" );
ok( !strcmp(temp_state_key->_filename, "/usr/local/nagios/var/check_test/funnykeyname"), "Got internal filename" );
ok( temp_state_key->data_version==54, "Version set" );
temp_state_data = np_state_read(temp_state_key);
ok( temp_state_data==NULL, "Got no state data as file does not exist" );
/*
temp_fp = fopen("var/statefile", "r");
if (temp_fp==NULL)
printf("Error opening. errno=%d\n", errno);
printf("temp_fp=%s\n", temp_fp);
ok( _np_state_read_file(temp_fp) == TRUE, "Can read state file" );
fclose(temp_fp);
*/
temp_state_key->_filename="var/statefile";
temp_state_data = np_state_read(temp_state_key);
ok( this_nagios_plugin->state->state_data!=NULL, "Got state data now" ) || diag("Are you running in right directory? Will get coredump next if not");
ok( this_nagios_plugin->state->state_data->time==1234567890, "Got time" );
ok( !strcmp((char *)this_nagios_plugin->state->state_data->data, "String to read"), "Data as expected" );
temp_state_key->data_version=53;
temp_state_data = np_state_read(temp_state_key);
ok( temp_state_data==NULL, "Older data version gives NULL" );
temp_state_key->data_version=54;
temp_state_key->_filename="var/nonexistant";
temp_state_data = np_state_read(temp_state_key);
ok( temp_state_data==NULL, "Missing file gives NULL" );
ok( this_nagios_plugin->state->state_data==NULL, "No state information" );
temp_state_key->_filename="var/oldformat";
temp_state_data = np_state_read(temp_state_key);
ok( temp_state_data==NULL, "Old file format gives NULL" );
temp_state_key->_filename="var/baddate";
temp_state_data = np_state_read(temp_state_key);
ok( temp_state_data==NULL, "Bad date gives NULL" );
temp_state_key->_filename="var/missingdataline";
temp_state_data = np_state_read(temp_state_key);
ok( temp_state_data==NULL, "Missing data line gives NULL" );
unlink("var/generated");
temp_state_key->_filename="var/generated";
current_time=1234567890;
np_state_write_string(current_time, "String to read");
ok(system("cmp var/generated var/statefile")==0, "Generated file same as expected");
unlink("var/generated_directory/statefile");
unlink("var/generated_directory");
temp_state_key->_filename="var/generated_directory/statefile";
current_time=1234567890;
np_state_write_string(current_time, "String to read");
ok(system("cmp var/generated_directory/statefile var/statefile")==0, "Have created directory");
/* This test to check cannot write to dir - can't automate yet */
/*
unlink("var/generated_bad_dir");
mkdir("var/generated_bad_dir", S_IRUSR);
np_state_write_string(current_time, "String to read");
*/
temp_state_key->_filename="var/generated";
time(&current_time);
np_state_write_string(0, "String to read");
temp_state_data = np_state_read(temp_state_key);
/* Check time is set to current_time */
ok(system("cmp var/generated var/statefile > /dev/null")!=0, "Generated file should be different this time");
ok(this_nagios_plugin->state->state_data->time-current_time<=1, "Has time generated from current time");
/* Don't know how to automatically test this. Need to be able to redefine die and catch the error */
/*
temp_state_key->_filename="/dev/do/not/expect/to/be/able/to/write";
np_state_write_string(0, "Bad file");
*/
np_cleanup();
ok( this_nagios_plugin==NULL, "Free'd this_nagios_plugin" );
return exit_status();
}

2
lib/tests/var/.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
generated
generated_directory/

5
lib/tests/var/baddate Normal file
View file

@ -0,0 +1,5 @@
# NP State file
1
54
2147483647
Date in future!!!!

View file

@ -0,0 +1,4 @@
# NP State file
1
54
1234567890

5
lib/tests/var/oldformat Normal file
View file

@ -0,0 +1,5 @@
# NP State file
0
54
1234567890
String to read

5
lib/tests/var/statefile Normal file
View file

@ -0,0 +1,5 @@
# NP State file
1
54
1234567890
String to read

View file

@ -27,6 +27,56 @@
#include "common.h"
#include <stdarg.h>
#include "utils_base.h"
#include <fcntl.h>
#define np_free(ptr) { if(ptr) { free(ptr); ptr = NULL; } }
nagios_plugin *this_nagios_plugin=NULL;
void np_init( char *plugin_name, int argc, char **argv ) {
if (this_nagios_plugin==NULL) {
this_nagios_plugin = malloc(sizeof(nagios_plugin));
if (this_nagios_plugin==NULL) {
die(STATE_UNKNOWN, _("Cannot allocate memory: %s"),
strerror(errno));
}
this_nagios_plugin->plugin_name = strdup(plugin_name);
if (this_nagios_plugin->plugin_name==NULL)
die(STATE_UNKNOWN, _("Cannot execute strdup: %s"), strerror(errno));
this_nagios_plugin->argc = argc;
this_nagios_plugin->argv = argv;
}
}
void np_set_args( int argc, char **argv ) {
if (this_nagios_plugin==NULL)
die(STATE_UNKNOWN, _("This requires np_init to be called"));
this_nagios_plugin->argc = argc;
this_nagios_plugin->argv = argv;
}
void np_cleanup() {
if (this_nagios_plugin!=NULL) {
if(this_nagios_plugin->state!=NULL) {
if(this_nagios_plugin->state->state_data) {
np_free(this_nagios_plugin->state->state_data->data);
np_free(this_nagios_plugin->state->state_data);
}
np_free(this_nagios_plugin->state->name);
np_free(this_nagios_plugin->state);
}
np_free(this_nagios_plugin->plugin_name);
np_free(this_nagios_plugin);
}
this_nagios_plugin=NULL;
}
/* Hidden function to get a pointer to this_nagios_plugin for testing */
void _get_nagios_plugin( nagios_plugin **pointer ){
*pointer = this_nagios_plugin;
}
void
die (int result, const char *fmt, ...)
@ -35,6 +85,9 @@ die (int result, const char *fmt, ...)
va_start (ap, fmt);
vprintf (fmt, ap);
va_end (ap);
if(this_nagios_plugin!=NULL) {
np_cleanup();
}
exit (result);
}
@ -102,7 +155,7 @@ _set_thresholds(thresholds **my_thresholds, char *warn_string, char *critical_st
thresholds *temp_thresholds = NULL;
if ((temp_thresholds = malloc(sizeof(thresholds))) == NULL)
die(STATE_UNKNOWN, _("Cannot allocate memory: %s\n"),
die(STATE_UNKNOWN, _("Cannot allocate memory: %s"),
strerror(errno));
temp_thresholds->warning = NULL;
@ -310,3 +363,302 @@ char *np_extract_value(const char *varlist, const char *name, char sep) {
return value;
}
/*
* Returns a string to use as a keyname, based on an md5 hash of argv, thus
* hopefully a unique key per service/plugin invocation. Use the extra-opts
* parse of argv, so that uniqueness in parameters are reflected there.
*/
char *_np_state_generate_key() {
struct sha1_ctx ctx;
int i;
char **argv = this_nagios_plugin->argv;
unsigned char result[20];
char keyname[41];
char *p=NULL;
sha1_init_ctx(&ctx);
for(i=0; i<this_nagios_plugin->argc; i++) {
sha1_process_bytes(argv[i], strlen(argv[i]), &ctx);
}
sha1_finish_ctx(&ctx, &result);
for (i=0; i<20; ++i) {
sprintf(&keyname[2*i], "%02x", result[i]);
}
keyname[40]='\0';
p = strdup(keyname);
if(p==NULL) {
die(STATE_UNKNOWN, _("Cannot execute strdup: %s"), strerror(errno));
}
return p;
}
void _cleanup_state_data() {
if (this_nagios_plugin->state->state_data!=NULL) {
np_free(this_nagios_plugin->state->state_data->data);
np_free(this_nagios_plugin->state->state_data);
}
}
/*
* Internal function. Returns either:
* envvar NAGIOS_PLUGIN_STATE_DIRECTORY
* statically compiled shared state directory
*/
char* _np_state_calculate_location_prefix(){
char *env_dir;
env_dir = getenv("NAGIOS_PLUGIN_STATE_DIRECTORY");
if(env_dir && env_dir[0] != '\0')
return env_dir;
return NP_STATE_DIR_PREFIX;
}
/*
* Initiatializer for state routines.
* Sets variables. Generates filename. Returns np_state_key. die with
* UNKNOWN if exception
*/
void np_enable_state(char *keyname, int expected_data_version) {
state_key *this_state = NULL;
char *temp_filename = NULL;
char *temp_keyname = NULL;
char *p=NULL;
if(this_nagios_plugin==NULL)
die(STATE_UNKNOWN, _("This requires np_init to be called"));
this_state = (state_key *) malloc(sizeof(state_key));
if(this_state==NULL)
die(STATE_UNKNOWN, _("Cannot allocate memory: %s"),
strerror(errno));
if(keyname==NULL) {
temp_keyname = _np_state_generate_key();
} else {
temp_keyname = strdup(keyname);
if(temp_keyname==NULL)
die(STATE_UNKNOWN, _("Cannot execute strdup: %s"), strerror(errno));
}
/* Die if invalid characters used for keyname */
p = temp_keyname;
while(*p!='\0') {
if(! (isalnum(*p) || *p == '_')) {
die(STATE_UNKNOWN, _("Invalid character for keyname - only alphanumerics or '_'"));
}
p++;
}
this_state->name=temp_keyname;
this_state->plugin_name=this_nagios_plugin->plugin_name;
this_state->data_version=expected_data_version;
this_state->state_data=NULL;
/* Calculate filename */
asprintf(&temp_filename, "%s/%s/%s", _np_state_calculate_location_prefix(), this_nagios_plugin->plugin_name, this_state->name);
this_state->_filename=temp_filename;
this_nagios_plugin->state = this_state;
}
/*
* Will return NULL if no data is available (first run). If key currently
* exists, read data. If state file format version is not expected, return
* as if no data. Get state data version number and compares to expected.
* If numerically lower, then return as no previous state. die with UNKNOWN
* if exceptional error.
*/
state_data *np_state_read() {
state_key *my_state_key;
state_data *this_state_data=NULL;
FILE *statefile;
int c;
int rc = FALSE;
if(this_nagios_plugin==NULL)
die(STATE_UNKNOWN, _("This requires np_init to be called"));
/* Open file. If this fails, no previous state found */
statefile = fopen( this_nagios_plugin->state->_filename, "r" );
if(statefile!=NULL) {
this_state_data = (state_data *) malloc(sizeof(state_data));
if(this_state_data==NULL)
die(STATE_UNKNOWN, _("Cannot allocate memory: %s"),
strerror(errno));
this_state_data->data=NULL;
this_nagios_plugin->state->state_data = this_state_data;
rc = _np_state_read_file(statefile);
fclose(statefile);
}
if(rc==FALSE) {
_cleanup_state_data();
}
return this_nagios_plugin->state->state_data;
}
/*
* Read the state file
*/
int _np_state_read_file(FILE *f) {
int c, status=FALSE;
size_t pos;
char *line;
int i;
int failure=0;
time_t current_time, data_time;
enum { STATE_FILE_VERSION, STATE_DATA_VERSION, STATE_DATA_TIME, STATE_DATA_TEXT, STATE_DATA_END } expected=STATE_FILE_VERSION;
time(&current_time);
/* Note: This introduces a limit of 1024 bytes in the string data */
line = (char *) malloc(1024);
if(line==NULL)
die(STATE_UNKNOWN, _("Cannot allocate memory: %s"),
strerror(errno));
while(!failure && (fgets(line,1024,f))!=NULL){
pos=strlen(line);
if(line[pos-1]=='\n') {
line[pos-1]='\0';
}
if(line[0] == '#') continue;
switch(expected) {
case STATE_FILE_VERSION:
i=atoi(line);
if(i!=NP_STATE_FORMAT_VERSION)
failure++;
else
expected=STATE_DATA_VERSION;
break;
case STATE_DATA_VERSION:
i=atoi(line);
if(i != this_nagios_plugin->state->data_version)
failure++;
else
expected=STATE_DATA_TIME;
break;
case STATE_DATA_TIME:
/* If time > now, error */
data_time=strtoul(line,NULL,10);
if(data_time > current_time)
failure++;
else {
this_nagios_plugin->state->state_data->time = data_time;
expected=STATE_DATA_TEXT;
}
break;
case STATE_DATA_TEXT:
this_nagios_plugin->state->state_data->data = strdup(line);
if(this_nagios_plugin->state->state_data->data==NULL)
die(STATE_UNKNOWN, _("Cannot execute strdup: %s"), strerror(errno));
expected=STATE_DATA_END;
status=TRUE;
break;
case STATE_DATA_END:
;
}
}
np_free(line);
return status;
}
/*
* If time=NULL, use current time. Create state file, with state format
* version, default text. Writes version, time, and data. Avoid locking
* problems - use mv to write and then swap. Possible loss of state data if
* two things writing to same key at same time.
* Will die with UNKNOWN if errors
*/
void np_state_write_string(time_t data_time, char *data_string) {
FILE *fp;
char *temp_file=NULL;
int fd=0, result=0;
time_t current_time;
size_t len;
char *directories=NULL;
char *p=NULL;
if(data_time==0)
time(&current_time);
else
current_time=data_time;
/* If file doesn't currently exist, create directories */
if(access(this_nagios_plugin->state->_filename,F_OK)!=0) {
asprintf(&directories, "%s", this_nagios_plugin->state->_filename);
if(directories==NULL)
die(STATE_UNKNOWN, _("Cannot allocate memory: %s"),
strerror(errno));
for(p=directories+1; *p; p++) {
if(*p=='/') {
*p='\0';
if((access(directories,F_OK)!=0) && (mkdir(directories, S_IRWXU)!=0)) {
/* Can't free this! Otherwise error message is wrong! */
/* np_free(directories); */
die(STATE_UNKNOWN, _("Cannot create directory: %s"), directories);
}
*p='/';
}
}
np_free(directories);
}
asprintf(&temp_file,"%s.XXXXXX",this_nagios_plugin->state->_filename);
if(temp_file==NULL)
die(STATE_UNKNOWN, _("Cannot allocate memory: %s"),
strerror(errno));
if((fd=mkstemp(temp_file))==-1) {
np_free(temp_file);
die(STATE_UNKNOWN, _("Cannot create temporary filename"));
}
fp=(FILE *)fdopen(fd,"w");
if(fp==NULL) {
close(fd);
unlink(temp_file);
np_free(temp_file);
die(STATE_UNKNOWN, _("Unable to open temporary state file"));
}
fprintf(fp,"# NP State file\n");
fprintf(fp,"%d\n",NP_STATE_FORMAT_VERSION);
fprintf(fp,"%d\n",this_nagios_plugin->state->data_version);
fprintf(fp,"%lu\n",current_time);
fprintf(fp,"%s\n",data_string);
fchmod(fd, S_IRUSR | S_IWUSR | S_IRGRP);
fflush(fp);
result=fclose(fp);
fsync(fd);
if(result!=0) {
unlink(temp_file);
np_free(temp_file);
die(STATE_UNKNOWN, _("Error writing temp file"));
}
if(rename(temp_file, this_nagios_plugin->state->_filename)!=0) {
unlink(temp_file);
np_free(temp_file);
die(STATE_UNKNOWN, _("Cannot rename state temp file"));
}
np_free(temp_file);
}

View file

@ -2,6 +2,8 @@
#define _UTILS_BASE_
/* Header file for nagios plugins utils_base.c */
#include "sha1.h"
/* This file holds header information for thresholds - use this in preference to
individual plugin logic */
@ -28,6 +30,30 @@ typedef struct thresholds_struct {
range *critical;
} thresholds;
#define NP_STATE_FORMAT_VERSION 1
typedef struct state_data_struct {
time_t time;
void *data;
int length; /* Of binary data */
} state_data;
typedef struct state_key_struct {
char *name;
char *plugin_name;
int data_version;
char *_filename;
state_data *state_data;
} state_key;
typedef struct np_struct {
char *plugin_name;
state_key *state;
int argc;
char **argv;
} nagios_plugin;
range *parse_range_string (char *);
int _set_thresholds(thresholds **, char *, char *);
void set_thresholds(thresholds **, char *, char *);
@ -67,4 +93,13 @@ char *np_extract_value(const char*, const char*, char);
*/
#define np_extract_ntpvar(l, n) np_extract_value(l, n, ',')
void np_enable_state(char *, int);
state_data *np_state_read();
void np_state_write_string(time_t, char *);
void np_init(char *, int argc, char **argv);
void np_set_args(int argc, char **argv);
void np_cleanup();
#endif /* _UTILS_BASE_ */

View file

@ -39,7 +39,7 @@ EXTRA_PROGRAMS = check_mysql check_radius check_pgsql check_snmp check_hpjd \
check_nagios check_by_ssh check_dns check_nt check_ide_smart \
check_procs check_mysql_query check_apt
EXTRA_DIST = t utils.c netutils.c sslutils.c popen.c utils.h netutils.h \
EXTRA_DIST = t tests utils.c netutils.c sslutils.c popen.c utils.h netutils.h \
popen.h common.h runcmd.c runcmd.h
PLUGINHDRS = common.h

View file

@ -59,6 +59,10 @@ const char *email = "nagiosplug-devel@lists.sourceforge.net";
#define MAX_OIDS 8
/* Longopts only arguments */
#define L_CALCULATE_RATE CHAR_MAX+1
#define L_RATE_MULTIPLIER CHAR_MAX+2
/* Gobble to string - stop incrementing c when c[0] match one of the
* characters in s */
#define GOBBLE_TOS(c, s) while(c[0]!='\0' && strchr(s, c[0])==NULL) { c++; }
@ -131,12 +135,16 @@ char *delimiter;
char *output_delim;
char *miblist = NULL;
int needmibs = FALSE;
int calculate_rate = 0;
int rate_multiplier = 1;
state_data *previous_state;
double previous_value[MAX_OIDS];
int
main (int argc, char **argv)
{
int i, len, line;
int i, len, line, total_oids;
unsigned int bk_count = 0, dq_count = 0;
int iresult = STATE_UNKNOWN;
int result = STATE_UNKNOWN;
@ -154,6 +162,17 @@ main (int argc, char **argv)
char *th_crit=NULL;
char type[8] = "";
output chld_out, chld_err;
char *previous_string=NULL;
char *ap=NULL;
char *state_string=NULL;
size_t response_length, current_length, string_length;
char *temp_string=NULL;
int is_numeric=0;
time_t current_time;
double temp_double;
time_t duration;
char *conv = "12345678";
int is_counter=0;
setlocale (LC_ALL, "");
bindtextdomain (PACKAGE, LOCALEDIR);
@ -173,12 +192,33 @@ main (int argc, char **argv)
timeout_interval = DEFAULT_TIMEOUT;
retries = DEFAULT_RETRIES;
np_init( (char *) progname, argc, argv );
/* Parse extra opts if any */
argv=np_extra_opts (&argc, argv, progname);
np_set_args(argc, argv);
if (process_arguments (argc, argv) == ERROR)
usage4 (_("Could not parse arguments"));
if(calculate_rate) {
if (!strcmp(label, "SNMP"))
label = strdup("SNMP RATE");
time(&current_time);
i=0;
previous_state = np_state_read();
if(previous_state!=NULL) {
/* Split colon separated values */
previous_string = strdup((char *) previous_state->data);
while((ap = strsep(&previous_string, ":")) != NULL) {
if(verbose>2)
printf("State for %d=%s\n", i, ap);
previous_value[i++]=strtod(ap,NULL);
}
}
}
/* Populate the thresholds */
th_warn=warning_thresholds;
th_crit=critical_thresholds;
@ -271,7 +311,10 @@ main (int argc, char **argv)
}
for (line=0, i=0; line < chld_out.lines; line++, i++) {
const char *conv = "%.0f";
if(calculate_rate)
conv = "%.10g";
else
conv = "%.0f";
ptr = chld_out.line[line];
oidname = strpcpy (oidname, ptr, delimiter);
@ -286,21 +329,34 @@ main (int argc, char **argv)
/* Clean up type array - Sol10 does not necessarily zero it out */
bzero(type, sizeof(type));
is_counter=0;
/* We strip out the datatype indicator for PHBs */
if (strstr (response, "Gauge: "))
if (strstr (response, "Gauge: ")) {
show = strstr (response, "Gauge: ") + 7;
else if (strstr (response, "Gauge32: "))
is_numeric++;
}
else if (strstr (response, "Gauge32: ")) {
show = strstr (response, "Gauge32: ") + 9;
is_numeric++;
}
else if (strstr (response, "Counter32: ")) {
show = strstr (response, "Counter32: ") + 11;
strcpy(type, "c");
is_numeric++;
is_counter=1;
if(!calculate_rate)
strcpy(type, "c");
}
else if (strstr (response, "Counter64: ")) {
show = strstr (response, "Counter64: ") + 11;
strcpy(type, "c");
is_numeric++;
is_counter=1;
if(!calculate_rate)
strcpy(type, "c");
}
else if (strstr (response, "INTEGER: "))
else if (strstr (response, "INTEGER: ")) {
show = strstr (response, "INTEGER: ") + 9;
is_numeric++;
}
else if (strstr (response, "STRING: ")) {
show = strstr (response, "STRING: ") + 8;
conv = "%.10g";
@ -345,14 +401,33 @@ main (int argc, char **argv)
iresult = STATE_DEPENDENT;
/* Process this block for integer comparisons */
if (thlds[i]->warning || thlds[i]->critical) {
/* Process this block for numeric comparisons */
if (is_numeric) {
ptr = strpbrk (show, "0123456789");
if (ptr == NULL)
die (STATE_UNKNOWN,_("No valid data returned"));
response_value[i] = strtod (ptr, NULL);
iresult = get_status(response_value[i], thlds[i]);
asprintf (&show, conv, response_value[i]);
if(calculate_rate) {
if (previous_state!=NULL) {
duration = current_time-previous_state->time;
if(duration<=0)
die(STATE_UNKNOWN,_("Time duration between plugin calls is invalid"));
temp_double = (response_value[i]-previous_value[i])/duration;
/* Simple overflow catcher (same as in rrdtool, rrd_update.c) */
if(is_counter) {
if(temp_double<(double)0.0)
temp_double+=(double)4294967296.0; /* 2^32 */
if(temp_double<(double)0.0)
temp_double+=(double)18446744069414584320.0; /* 2^64-2^32 */;
}
iresult = get_status(temp_double, thlds[i]);
asprintf (&show, conv, temp_double);
}
} else {
iresult = get_status(response_value[i], thlds[i]);
asprintf (&show, conv, response_value[i]);
}
}
/* Process this block for string matching */
@ -380,6 +455,7 @@ main (int argc, char **argv)
}
/* Process this block for existence-nonexistence checks */
/* TV: Should this be outside of this else block? */
else {
if (eval_method[i] & CRIT_PRESENT)
iresult = STATE_CRITICAL;
@ -393,7 +469,7 @@ main (int argc, char **argv)
result = max_state (result, iresult);
/* Prepend a label for this OID if there is one */
if (nlabels > (size_t)1 && (size_t)i < nlabels && labels[i] != NULL)
if (nlabels >= (size_t)1 && (size_t)i < nlabels && labels[i] != NULL)
asprintf (&outbuff, "%s%s%s %s%s%s", outbuff,
(i == 0) ? " " : output_delim,
labels[i], mark (iresult), show, mark (iresult));
@ -409,7 +485,13 @@ main (int argc, char **argv)
ptr = NULL;
strtod(show, &ptr);
if (ptr > show) {
strncat(perfstr, oidname, sizeof(perfstr)-strlen(perfstr)-1);
if (nlabels >= (size_t)1 && (size_t)i < nlabels && labels[i] != NULL)
temp_string=labels[i];
else
temp_string=oidname;
if(calculate_rate)
asprintf(&temp_string,"%s-rate",temp_string);
strncat(perfstr, temp_string, sizeof(perfstr)-strlen(perfstr)-1);
strncat(perfstr, "=", sizeof(perfstr)-strlen(perfstr)-1);
len = sizeof(perfstr)-strlen(perfstr)-1;
strncat(perfstr, show, len>ptr-show ? ptr-show : len);
@ -419,6 +501,44 @@ main (int argc, char **argv)
strncat(perfstr, " ", sizeof(perfstr)-strlen(perfstr)-1);
}
}
total_oids=i;
/* Save state data, as all data collected now */
if(calculate_rate) {
string_length=1024;
state_string=malloc(string_length);
if(state_string==NULL)
die(STATE_UNKNOWN, _("Cannot malloc"));
current_length=0;
for(i=0; i<total_oids; i++) {
asprintf(&temp_string,"%.0f",response_value[i]);
if(temp_string==NULL)
die(STATE_UNKNOWN,_("Cannot asprintf()"));
response_length = strlen(temp_string);
if(current_length+response_length>string_length) {
string_length=current_length+1024;
state_string=realloc(state_string,string_length);
if(state_string==NULL)
die(STATE_UNKNOWN, _("Cannot realloc()"));
}
strcpy(&state_string[current_length],temp_string);
current_length=current_length+response_length;
state_string[current_length]=':';
current_length++;
free(temp_string);
}
state_string[--current_length]='\0';
if (verbose > 2)
printf("State string=%s\n",state_string);
/* This is not strictly the same as time now, but any subtle variations will cancel out */
np_state_write_string(current_time, state_string );
if(previous_state==NULL) {
/* Or should this be highest state? */
die( STATE_OK, _("No previous data to calculate rate - assume okay" ) );
}
}
printf ("%s %s -%s %s\n", label, state_text (result), outbuff, perfstr);
if (mult_resp) printf ("%s", mult_resp);
@ -462,6 +582,8 @@ process_arguments (int argc, char **argv)
{"authpasswd", required_argument, 0, 'A'},
{"privpasswd", required_argument, 0, 'X'},
{"next", no_argument, 0, 'n'},
{"rate", no_argument, 0, L_CALCULATE_RATE},
{"rate-multiplier", required_argument, 0, L_RATE_MULTIPLIER},
{0, 0, 0, 0}
};
@ -609,7 +731,6 @@ process_arguments (int argc, char **argv)
output_delim = strscpy (output_delim, optarg);
break;
case 'l': /* label */
label = optarg;
nlabels++;
if (nlabels >= labels_size) {
labels_size += 8;
@ -666,7 +787,15 @@ process_arguments (int argc, char **argv)
unitv[nunits - 1] = ptr;
}
break;
case L_CALCULATE_RATE:
if(calculate_rate==0)
np_enable_state(NULL, 1);
calculate_rate = 1;
break;
case L_RATE_MULTIPLIER:
if(!is_integer(optarg)||(rate_multiplier=atoi(optarg)<=0))
usage2(_("Rate multiplier must be a positive integer"),optarg);
break;
}
}
@ -905,6 +1034,8 @@ print_help (void)
printf (" %s\n", _("Warning threshold range(s)"));
printf (" %s\n", "-c, --critical=THRESHOLD(s)");
printf (" %s\n", _("Critical threshold range(s)"));
printf (" %s\n", "--rate");
printf (" %s\n", _("Enable rate calculation. See 'Rate Calculation' below"));
/* Tests Against Strings */
printf (" %s\n", "-s, --string=STRING");
@ -914,7 +1045,7 @@ print_help (void)
printf (" %s\n", "-R, --eregi=REGEX");
printf (" %s\n", _("Return OK state (for that OID) if case-insensitive extended REGEX matches"));
printf (" %s\n", "-l, --label=STRING");
printf (" %s\n", _("Prefix label for output from plugin (default -s 'SNMP')"));
printf (" %s\n", _("Prefix label for output from plugin (default -l 'SNMP')"));
/* Output Formatting */
printf (" %s\n", "-u, --units=STRING");
@ -945,6 +1076,16 @@ print_help (void)
printf (" %s\n", _("- All evaluation methods other than PR, STR, and SUBSTR expect that the value"));
printf (" %s\n", _("returned from the SNMP query is an unsigned integer."));
printf("\n");
printf("%s\n", _("Rate Calculation:"));
printf(" %s\n", _("In many places, SNMP returns counters that are only meaningful when"));
printf(" %s\n", _("calculating the counter difference since the last check. check_snmp"));
printf(" %s\n", _("saves the last state information in a file so that the rate can be"));
printf(" %s\n", _("calculated. Use the --rate option to save state information. On the"));
printf(" %s\n", _("first run, there will be no prior state - this will return with OK."));
printf(" %s\n", _("The state is uniquely determined by the arguments to the plugin, so"));
printf(" %s\n", _("changing the arguments will create a new state file."));
printf (UT_SUPPORT);
}

View file

@ -51,7 +51,7 @@ if ($ARGV[0] && $ARGV[0] eq "-d") {
}
}
my $tests = 9;
my $tests = 21;
if (-x "./check_snmp") {
plan tests => $tests;
} else {
@ -106,3 +106,40 @@ like($res->output, '/'.quotemeta('SNMP OK - And now have fun with with this: \"C
"And now have fun with with this: \"C:\\\\\"
because we\'re not done yet!"').'/m', "Attempt to confuse parser No.3");
system("rm /usr/local/nagios/var/check_snmp/*");
$res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.10 --rate -w 600" );
is($res->return_code, 0, "Returns OK");
is($res->output, "No previous data to calculate rate - assume okay");
# Need to sleep, otherwise duration=0
sleep 1;
$res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.10 --rate -w 600" );
is($res->return_code, 1, "WARNING - due to going above rate calculation" );
is($res->output, "SNMP RATE WARNING - *666* | iso.3.6.1.4.1.8072.3.2.67.10-rate=666 ");
$res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.10 --rate -w 600" );
is($res->return_code, 3, "UNKNOWN - basically the divide by zero error" );
is($res->output, "Time duration between plugin calls is invalid");
$res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.10 --rate -l inoctets" );
is($res->return_code, 0, "OK for first call" );
is($res->output, "No previous data to calculate rate - assume okay" );
# Need to sleep, otherwise duration=0
sleep 1;
$res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.10 --rate -l inoctets" );
is($res->return_code, 0, "OK as no thresholds" );
is($res->output, "SNMP RATE OK - inoctets 666 | inoctets-rate=666 ", "Check label");
sleep 2;
$res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.10 --rate -l inoctets" );
is($res->return_code, 0, "OK as no thresholds" );
is($res->output, "SNMP RATE OK - inoctets 333 | inoctets-rate=333 ", "Check rate decreases due to longer interval");

View file

@ -33,9 +33,9 @@ ends with with this: C:\\';
my $multilin5 = 'And now have fun with with this: "C:\\"
because we\'re not done yet!';
my @fields = (ASN_OCTET_STR, ASN_OCTET_STR, ASN_OCTET_STR, ASN_OCTET_STR, ASN_OCTET_STR, ASN_UNSIGNED, ASN_UNSIGNED, ASN_COUNTER, ASN_COUNTER64, ASN_UNSIGNED);
my @values = ($multiline, $multilin2, $multilin3, $multilin4, $multilin5, 4294965296, 1000, 4294965296, uint64("18446744073709351616"), int(rand(2**32)));
my @incrts = (undef, undef, undef, undef, undef, 1000, -500, 1000, 100000, undef);
my @fields = (ASN_OCTET_STR, ASN_OCTET_STR, ASN_OCTET_STR, ASN_OCTET_STR, ASN_OCTET_STR, ASN_UNSIGNED, ASN_UNSIGNED, ASN_COUNTER, ASN_COUNTER64, ASN_UNSIGNED, ASN_COUNTER);
my @values = ($multiline, $multilin2, $multilin3, $multilin4, $multilin5, 4294965296, 1000, 4294965296, uint64("18446744073709351616"), int(rand(2**32)), 64000);
my @incrts = (undef, undef, undef, undef, undef, 1000, -500, 1000, 100000, undef, 666);
# Number of elements in our OID
my $oidelts;