original files of m241

This commit is contained in:
neelimap
2026-07-30 11:19:44 +05:30
parent 170c2b3f3a
commit afc7070c1f
12254 changed files with 7655111 additions and 0 deletions
@@ -0,0 +1,820 @@
/* memPoolLib.c - memory pool management */
/*
* Copyright (c) 1997-2008, 2010 Wind River Systems, Inc.
*
* The right to copy, distribute, modify or otherwise make use
* of this software may be licensed only pursuant to the terms
* of an applicable Wind River license agreement.
*/
/*
modification history
--------------------
02i,28apr10,m_z eliminate compile warning
02h,29jan10,m_z VxWorks 64-bit support
(WIND00193649)
02g,10jan08,ps add semaphore protection to memPoolCheck()
02f,24feb07,msa Correct the apigen comments so they match the actual routines
and correct any apigen errors that may occur.
02e,28aug02,jc fixed semTake 0 timeout bug
02d,12apr02,pns added support for managing shared memory
02c,15mar02,pns added support for tracking memory used (leak detection)
02b,16jan02,pns ported to windmanage
02a,16may01,jc renamed to memPool and ported to wmos
01f,09jun99,km merge of Wind Web Server 2.0 code drop from 3Soft.
01e,17feb99,ck fixed wrong assertion statement.
01d,04dec98,mb bugfix: httpMemPartAlloc() caused memory corruption, reworked.
01c,13may97,mb osal introduced.
01b,12may97,ics logical simplifications.
01a,03mar97,ck initial creation.
*/
/*
DESCRIPTION
This module provides memory pool management.
NOMANUAL
*/
#include <stdio.h>
#define DEFINED_MEM_POOL_DESC
#define __DEBUG_MESSAGES_OFF__ /* undefine to allow debugging messages */
#include "wrn/wm/common/wm.h"
/* if in shared memory then pointers are stored as offset from pool id */
#ifdef __ENABLE_SHARED_MEMORY__
#define memPtrGet(pool, data) (void *) (pool->shared ? wmPtrGet(pool, data) : data)
#define memPtrSet(pool, data) (void *) (pool->shared ? wmPtrSet(pool, data) : data)
#else
#define memPtrGet(pool, data) data
#define memPtrSet(pool, data) data
#endif
/*******************************************************************************
*
* memPoolNew - create a memory pool (used by macro memPoolCreate)
*
* This routine creates a new memory pool, inside a memory block supplied by
* the caller. It returns a pool ID, which can be passed to other routines to
* manage the pool (that is, to allocate and free memory blocks in the
* partition). Partitions can be created to manage any number of
* separate memory pools.
*
* NOTE: Most of the memory required for administrative data is taken
* from the specified memory block. Therefore, the actual available
* memory will be slightly smaller than <ulPoolSize>.
* There is some additional dynamic memory allocation for some types
* of administrative data (such as semaphores or control blocks) that
* does not come from the block.
*
* RETURNS: The pool ID, or NULL if there is insufficient memory in
* the system memory pool for a new pool descriptor.
*
* NOMANUAL
*/
MEM_POOL_ID memPoolNew
(
char * pPool, /* memory area to create the pool in */
unsigned long ulPoolSize /* size in bytes of pPool */
#ifdef __ENABLE_SHARED_MEMORY__
,
BOOL shared
#endif
)
{
MEM_POOL_ID memDesc = NULL;
if (NULL == pPool)
{
wmError (ERROR_GENERAL, "Input parameter is NULL!");
return (NULL);
}
if (ulPoolSize < sizeof (MEM_POOL_MCB) +
sizeof (MEM_POOL_DESC) +
sizeof (unsigned long) +
MCB_ALIGN )
{
wmError (ERROR_GENERAL, "Partition too small for admin data!");
return (NULL);
}
memset (pPool, 0, ulPoolSize);
memDesc = (MEM_POOL_ID) pPool;
memDesc->ulPoolSize = ulPoolSize - sizeof (MEM_POOL_DESC)
- sizeof(unsigned long);
memDesc->ulWatermarkFree = memDesc->ulPoolSize;
#ifdef __ENABLE_SHARED_MEMORY__
memDesc->shared = shared;
#endif
if (OK != wmosSemCreate (&memDesc->semLockPool, 1, SEM_TYPICAL_K))
{
/* !! log this error !! */
return (NULL);
}
memPoolCleanup (memDesc);
DEBUG_MSG_2 ("memPoolCreate: id: 0x%x size: %d\n", pPool, ulPoolSize);
return (memDesc);
}
/*******************************************************************************
*
* memPoolCleanup - clear a memory pool
*
* This routine clears an existing pool containing a
* specified memory pool. It reinitializes the pool to its
* initial state, from which no memory is allocated. If
* there is a pointer to memory allocated from this pool, that
* memory will be corrupted and subsequently re-allocated.
*
* RETURNS: OK if the pool was cleaned up properly,
* or ERROR if the administrative data was found to be corrupted.
*
* NOMANUAL
*/
STATUS memPoolCleanup
(
MEM_POOL_ID poolId /* Memory pool ID */
)
{
MEM_POOL_MCB * pStart;
MEM_POOL_MCB * pPoolStart;
unsigned long ulSize;
unsigned long * pulDelimit;
#ifdef __ENABLE_SHARED_MEMORY__
DEBUG_MSG_2("memPoolCleanup: pool 0x%x is%s shared\n",
poolId, poolId->shared ? "" : " NOT");
#endif
if (poolId == NULL)
return wmError (ERROR_GENERAL, "memPoolCleanup: NULL poolID");
/*
* Calculate the start address of the allocatable memory. If this
* is our first time through, we'll need to initialize
* poolId->pPoolStart.
*/
pStart = (MEM_POOL_MCB *) ((((unsigned long) poolId + sizeof(MEM_POOL_DESC)
+ MCB_ALIGN - 1) / MCB_ALIGN) * MCB_ALIGN);
if (NULL == poolId->pPoolStart)
{
DEBUG_MSG_2 ("memPoolCleanup: pool: 0x%x start using : 0x%x\n",
poolId, pStart);
poolId->pPoolStart = memPtrSet(poolId, pStart);
pPoolStart = pStart;
DEBUG_MSG_2 ("memPoolCleanup: pool: 0x%x start NATIVE: 0x%x\n",
poolId, poolId->pPoolStart);
}
else
{
if (OK != memPoolCheck (poolId))
return wmError (ERROR_GENERAL, "memPoolCleanup: pool corrupted!");
pPoolStart = memPtrGet(poolId, poolId->pPoolStart);
}
DEBUG_MSG_2 ("memPoolCleanup: pool: 0x%x start: 0x%x\n", poolId, pPoolStart);
ulSize = poolId->ulPoolSize;
/* XXX walk through list to free semaphores, once they are introduced... */
if (OK != wmosSemTake (poolId->semLockPool, WAIT_FOREVER_K))
return ERROR;
memset (pStart, 0, ulSize);
pPoolStart->ulUsage = MCB_FREE;
pPoolStart->pPoolNext = NULL;
pPoolStart->ulBlockSize = poolId->ulPoolSize
- sizeof (MEM_POOL_MCB)
- ((unsigned long) pPoolStart + sizeof(MEM_POOL_DESC)) %
sizeof(MCB_ALIGN);
/* XXX SEM CREATE */
pulDelimit = (unsigned long *) ((char *)pStart + poolId->ulPoolSize );
*pulDelimit= MCB_DELIMITER;
wmosSemGive (poolId->semLockPool);
return OK;
}
#ifdef xx__ENABLE_MEMMGR_DEBUG__
/*******************************************************************************
*
* memPoolExists - see if a memory pool already created for address
*
* This routine checks if the administrative data of the given
* memory pool is still valid. This routine has a good chance of
* detecting corruption (caused, for example, by exceeding the bounds
* of allocated memory), but it cannot be guaranteed that it will
* do so.
*
* RETURNS: OK if the pool is valid, or ERROR if the
* administrative data has been corrupted.
*
* NOMANUAL
*/
BOOL memPoolExists
(
MEM_POOL_ID poolId /* memory pool to check */
)
{
MEM_POOL_MCB * pNextMCB;
if (poolId == NULL)
return wmError (ERROR_GENERAL,"memPoolExists: null id");
pNextMCB = pPoolAnchor;
while (pNextMCB != NULL)
{
if (poolId == pNextMCB)
return TRUE;
pNextMCB = memPtrGet(poolId, pNextMCB->pPoolNext);
}
return (OK);
}
#endif
/*******************************************************************************
*
* memPoolCheck - check the itegrity of a memory pool
*
* This routine checks if the administrative data of the given
* memory pool is still valid. This routine has a good chance of
* detecting corruption (caused, for example, by exceeding the bounds
* of allocated memory), but it cannot be guaranteed that it will
* do so.
*
* RETURNS: OK if the pool is valid, or ERROR if the
* administrative data has been corrupted.
*
* NOMANUAL
*/
STATUS memPoolCheck
(
MEM_POOL_ID poolId /* memory pool to check */
)
{
MEM_POOL_MCB * pStart;
MEM_POOL_MCB * pNextMCB;
#ifdef DEBUG_INFO
MEM_POOL_MCB * pLastMCB = NULL;
unsigned long ulAvailBytes = 0;
#endif
unsigned long * pulDelimit;
if (poolId == NULL)
return wmError (ERROR_GENERAL,"memPoolCheck: null poolID");
wmosSemTake (poolId->semLockPool, WAIT_FOREVER_K);
pStart = (MEM_POOL_MCB *) ((((unsigned long) poolId +
sizeof (MEM_POOL_DESC) + MCB_ALIGN - 1) / MCB_ALIGN) * MCB_ALIGN);
/* do all comparisons in pointer space, since we'll be using pointers */
pNextMCB = memPtrGet(poolId, poolId->pPoolStart);
if ((NULL != poolId->pPoolStart) && (pStart != pNextMCB))
{
DEBUG_MSG_2 ("memPoolCheck: invalid id: 0x%x expected start = 0x%x native = 0x%x\n",
poolId, pStart);
DEBUG_MSG_3 ("memPoolCheck: invalid id: 0x%x adjusted start = 0x%x native = 0x%x\n",
poolId, memPtrGet(poolId, poolId->pPoolStart), poolId->pPoolStart);
wmosSemGive (poolId->semLockPool);
return wmError (ERROR_GENERAL,"memPoolCheck: descriptor table invalid!");
}
/* check for pool overrun */
pulDelimit = (unsigned long *) ((char *) pStart + poolId->ulPoolSize);
if (*pulDelimit != MCB_DELIMITER)
{
wmosSemGive (poolId->semLockPool);
return wmError (ERROR_GENERAL, "memPoolCheck: end-of-pool overrun!");
}
/* walk through all pools */
while (NULL != pNextMCB)
{
MEM_POOL_MCB * pNextPossibleMCB;
pNextPossibleMCB = wmAdjust (pNextMCB, sizeof(MEM_POOL_MCB) + pNextMCB->ulBlockSize);
if (pNextMCB->ulUsage != MCB_FREE && pNextMCB->ulUsage != MCB_OCCUPIED)
{
DEBUG_MSG_3 ("memPoolCheck: 0x%x NextMCB: 0x%x NEXT_Possible: 0x%x\n",
poolId, pNextMCB, pNextPossibleMCB);
DEBUG_MSG_2 ("memPoolCheck: 0x%x type: 0x%x\n", poolId, pNextMCB->ulUsage);
wmosSemGive (poolId->semLockPool);
return wmError (ERROR, "memPoolCheck: bad block type");
}
/* if shared memory we need to make offsets back into pointers */
if ((NULL != pNextMCB->pPoolNext) &&
(memPtrGet(poolId, pNextMCB->pPoolNext) != pNextPossibleMCB))
{
#ifdef DEBUG_INFO
fprintf (stderr, "memPoolCheck: MCB corrupted between block %#x and %#x! "
"(signature set to %#lx, next is %x, should be %x)\n",
(int) pNextMCB, (int) pLastMCB, pNextMCB->ulUsage,
(int) pNextMCB->pPoolNext, (int) pNextPossibleMCB);
#endif
wmosSemGive (poolId->semLockPool);
return (ERROR);
}
#ifdef DEBUG_INFO
pLastMCB = pNextMCB;
ulAvailBytes += pNextMCB->ulBlockSize + sizeof (MEM_POOL_MCB);
#endif
#ifdef __ENABLE_SHARED_MEMORY__
if (poolId->shared)
DEBUG_MSG_3 ("memPoolCheck: id: 0x%x next: 0x%x adjusted 0x%x\n",
poolId, pNextMCB->pPoolNext,
memPtrGet(poolId, pNextMCB->pPoolNext));
#endif
pNextMCB = memPtrGet(poolId, pNextMCB->pPoolNext);
}
#ifdef DEBUG_INFO
ulAvailBytes += ((unsigned long)(poolId->pPoolStart)+sizeof(MEM_POOL_DESC))
% sizeof (MCB_ALIGN);
if (poolId->ulPoolSize != ulAvailBytes)
fprintf (stderr,"memPoolCheck: Memory leak detected! "
"%ld bytes from %ld bytes are missing!\n",
poolId->ulPoolSize - ulAvailBytes, poolId->ulPoolSize);
#endif
wmosSemGive (poolId->semLockPool);
return (OK);
}
/*******************************************************************************
*
* memPoolDelete - destroy a memory pool
*
* This routine destroys an existing memory pool. If there is
* pointer to memory allocated from this pool, that memory will be
* corrupted and subsequently returned to its original owner.
*
* RETURNS: A pointer to the memory block originally used to create this
* pool (as given to memPoolCreate()), or NULL if there is an error.
*
* NOMANUAL
*/
char * memPoolDelete
(
MEM_POOL_ID poolId /* Memory pool ID */
)
{
if (OK != memPoolCleanup (poolId))
{
wmError (ERROR_GENERAL,"memPoolCleanup: error during cleanup");
return (NULL);
}
wmosSemDestroy (poolId->semLockPool);
return ((char *) poolId);
}
/*******************************************************************************
*
* memPoolAvail - get the size of memory available in a pool
*
* This routine returns the total amount of unused memory in a pool if
* <sMode> is 0. It returns the size of the largest contiguous block of
* memory if <sMode> is 1. In the debugging library, 128 gives the minimum
* number of bytes that have up to now been available (the high
* water-mark).
*
* RETURNS: The number of bytes in the largest available block
*
* NOMANUAL
*/
unsigned long memPoolAvail
(
MEM_POOL_ID poolId, /* memory pool to check */
short sMode
)
{
MEM_POOL_MCB * mcbTmp;
unsigned long ulFree;
ulFree = 0;
if (memPoolCheck (poolId) != OK)
{
wmError (ERROR_GENERAL,"memPoolAvail: no valid pool");
return (0);
}
if (OK != wmosSemTake (poolId->semLockPool, WAIT_FOREVER_K))
return (0);
if (sMode == 128)
ulFree = poolId->ulPoolSize - poolId->ulWatermarkFree;
else
{
mcbTmp = memPtrGet(poolId, poolId->pPoolStart);
while (mcbTmp != NULL)
{
if (mcbTmp->ulUsage == MCB_FREE)
{
if ((sMode == 1) && (ulFree <(mcbTmp->ulBlockSize)))
ulFree = (mcbTmp->ulBlockSize);
if (sMode == 0)
ulFree += mcbTmp->ulBlockSize;
}
mcbTmp = memPtrGet(poolId, mcbTmp->pPoolNext);
}
}
wmosSemGive (poolId->semLockPool);
return (ulFree);
}
/*******************************************************************************
*
* memPoolUsed - get the amount of memory used in a pool
*
* RETURNS: The number of bytes in the largest available block
*
* NOMANUAL
*/
long memPoolUsed
(
MEM_POOL_ID poolId /* memory pool to check */
)
{
if (OK != memPoolCheck (poolId))
{
wmError (ERROR_GENERAL,"memPoolAvail: no valid pool");
return -1;
}
return (long)poolId->memUsed;
}
/*******************************************************************************
*
* memPoolAlloc - allocate a memory block from a memory pool
*
* This routine allocates a block of memory from a specified
* pool. The size of the block will be equal to or greater than
* <ulBytes> (the best-fit strategy is employed to choose the
* block of memory). The pool must already have been initialized with
* memPoolCreate().
*
* RETURNS: A pointer to the memory pool as given to memPoolCreate(),
* or NULL if there is an error.
*
* NOMANUAL
*/
void * memPoolAlloc
(
MEM_POOL_ID poolId, /* Memory pool ID */
unsigned long ulBytes /* Number of bytes to allocate */
)
{
MEM_POOL_MCB * mcbBestFit;
MEM_POOL_MCB * mcbTmp;
unsigned long ulFree;
unsigned long ulRoundedBlockSize;
if (memPoolCheck (poolId) != OK)
{
wmError (ERROR_GENERAL,"memPoolAlloc: no valid pool");
return (NULL);
}
if (OK != wmosSemTake (poolId->semLockPool, WAIT_FOREVER_K))
{
wmError (ERROR_GENERAL,"memPoolAlloc: wmosSemTake failed");
return (NULL);
}
mcbTmp = memPtrGet(poolId, poolId->pPoolStart);
/* Try to find a perfect match, (mcbBestFit->ulBlockSize == ulBytes)
or the closest one! */
mcbBestFit = NULL;
while ((mcbBestFit == NULL) || (mcbBestFit->ulBlockSize != ulBytes))
{
if ((mcbTmp->ulUsage == MCB_FREE) &&
(mcbTmp->ulBlockSize >= ulBytes) &&
( (mcbBestFit == NULL) || (mcbBestFit->ulBlockSize > mcbTmp->ulBlockSize)) )
{
mcbBestFit = mcbTmp;
}
if (NULL == (mcbTmp = memPtrGet(poolId, mcbTmp->pPoolNext)))
break;;
}
/* Nothing with at least ulBytes found... give up! */
if (mcbBestFit == NULL)
{
wmosSemGive (poolId->semLockPool);
DEBUG_MSG_2 ("memPoolAlloc: size requested: %d available: %d\n",
ulBytes, poolId->ulPoolSize - poolId->memUsed);
wmError (ERROR_GENERAL, "memPoolAlloc: insufficient memory");
return (NULL);
}
/* ulRoundedBlockSize: size of requested memory including fraction
of aligment boundaries */
ulRoundedBlockSize = ( ( ulBytes + MCB_ALIGN - 1 ) / MCB_ALIGN ) * MCB_ALIGN;
/* take a bigger block and try to split it! */
/* there must be enough memory for at least 1 more MCB, */
/* the current memory block and the new memory block */
/* to be able to split memory blocks ! */
if (mcbBestFit->ulBlockSize > ( ulRoundedBlockSize + sizeof (MEM_POOL_MCB ) ) )
{
/* SPLIT found memory block into two halves, aligned to sizeof (mem_pool_mcb) */
mcbTmp = (MEM_POOL_MCB *) (((char *)mcbBestFit) + ulRoundedBlockSize +
sizeof (MEM_POOL_MCB) );
/* fprintf ( stdout,"memPoolAlloc: splitting block, new block at %lx,
parent at %lx.\n", &mcbTmp[1],&mcbBestFit[1]); */
/* generate new MCB */
mcbTmp->ulUsage = MCB_FREE;
mcbTmp->pPoolNext = memPtrSet(poolId, mcbBestFit->pPoolNext);
mcbTmp->ulBlockSize = mcbBestFit->ulBlockSize - sizeof (MEM_POOL_MCB) - ulRoundedBlockSize;
#if 0 /* figure out how to replace this later */
assert ( mcbTmp->ulBlockSize > 0 );
#endif
/* ALLOCATE semaphore semLockBlock .... XXX */
/* modify existing MCB, ulBlockSize never counts sizeof(MEM_POOL_MCB) */
mcbBestFit->pPoolNext = memPtrSet(poolId, mcbTmp);
mcbBestFit->ulBlockSize = ulRoundedBlockSize;
}
/* Now, we should have found *anything* satisfying out needs */
#if 0
assert (mcbBestFit->ulBlockSize >= ulBytes);
#endif
mcbBestFit->ulUsage = MCB_OCCUPIED;
wmosSemGive (poolId->semLockPool);
ulFree = memPoolAvail (poolId, 0);
if (poolId->ulWatermarkFree > ulFree)
poolId->ulWatermarkFree = ulFree;
#ifdef DEBUG_INFO
printf("Block %p allocated!\n", &(mcbBestFit[1]));
#endif
poolId->memUsed += mcbBestFit->ulBlockSize;
mcbBestFit++;
DEBUG_MSG_2("memPoolAlloc: pool: 0x%x addr: 0x%x\n", poolId, mcbBestFit);
return ((void *) mcbBestFit);
}
/*******************************************************************************
*
* memPoolFree - free a memory block in a memory pool
*
* This routine returns a block of memory to the specified pool.
*
* RETURNS:
* OK, or ERROR if the pool is corrupt or invalid, or if
* the memory pointer is not to a valid block of memory
* previously allocated from this pool.
*
*
* NOMANUAL
*/
STATUS memPoolFree
(
MEM_POOL_ID poolId, /* Memory pool ID */
void * pBlock /* pointer to block of memory to free */
)
{
MEM_POOL_MCB * mcbLast = NULL;
MEM_POOL_MCB * mcbTmp;
MEM_POOL_MCB * mcbCurrent;
MEM_POOL_MCB * mcbNext;
char * pPoolStart;
if (NULL == poolId)
{
wmosFree(pBlock);
return OK;
}
if (memPoolCheck (poolId) != OK)
return wmError (ERROR_GENERAL,"memPoolFree: no valid pool");
/* check if pointer given to free, SEEMS to be correct... */
DEBUG_MSG_2 ("memPoolFree: pool: 0x%x addr: 0x%x\n", poolId, pBlock);
pPoolStart = (char *) memPtrGet(poolId, poolId->pPoolStart);
if ((char *)pBlock < pPoolStart ||
(char *)pBlock > pPoolStart + poolId->ulPoolSize + sizeof (MEM_POOL_DESC))
{
#ifdef __ENABLE_SHARED_MEMORY__
DEBUG_MSG_2 ("memPoolCheck: pool: 0x%x %s\n", poolId,
poolId->shared ? "SHARED" : "NOT SHARED");
#endif
DEBUG_MSG_2 ("memPoolCheck: pool: 0x%x native: 0x%x\n",
poolId, poolId->pPoolStart);
DEBUG_MSG_3 ("memPoolCheck: block: 0x%x start: 0x%x end: 0x%x\n",
pBlock, pPoolStart, pPoolStart + poolId->ulPoolSize);
return wmError (ERROR_GENERAL, "memPoolFree: can't find memory");
}
mcbCurrent = (MEM_POOL_MCB *) ((char *)pBlock - sizeof (MEM_POOL_MCB));
if (mcbCurrent->ulUsage == MCB_FREE || mcbCurrent->ulUsage != MCB_OCCUPIED)
{
DEBUG_MSG_2 ("memPoolCheck: pool: 0x%x block: 0x%x\n", poolId, pBlock);
return wmError (ERROR_GENERAL, "memPoolFree: invalid or already freed!");
}
#ifdef __WM_DIRTY__
/* "dirty" data to force error if used after free */
memset(pBlock, MY_BAD_K, mcbCurrent->ulBlockSize);
#endif
if (OK != wmosSemTake (poolId->semLockPool, WAIT_FOREVER_K))
return ERROR;
mcbTmp = memPtrGet(poolId, poolId->pPoolStart);
while (mcbTmp != NULL && mcbTmp != mcbCurrent)
{
mcbLast = mcbTmp;
mcbTmp = memPtrGet(poolId, mcbTmp->pPoolNext);
}
if (mcbTmp != mcbCurrent)
{
wmosSemGive (poolId->semLockPool);
return wmError (ERROR_GENERAL, "memPoolFree: block not found!");;
}
/* mark current block as free... */
mcbCurrent->ulUsage = MCB_FREE;
poolId->memUsed -= mcbCurrent->ulBlockSize;
/* when next block is free also, concatenate them ... */
mcbNext = memPtrGet(poolId, mcbCurrent->pPoolNext);
if (NULL != mcbNext && mcbNext->ulUsage == MCB_FREE)
{
mcbCurrent->ulBlockSize += mcbNext->ulBlockSize + sizeof (MEM_POOL_MCB);
/* FREE semaphore of now obsolete mcb.... once it is introduced! */
/* semDelete... */
mcbCurrent->pPoolNext = mcbNext->pPoolNext;
}
/* when preceding block is free also, concatenate them ... */
if (mcbLast != NULL && mcbLast->ulUsage == MCB_FREE)
{
mcbLast->ulBlockSize += mcbCurrent->ulBlockSize
+ sizeof (MEM_POOL_MCB);
/* FREE semaphore of now obsolete mcb.... once it is introduced! */
/* semDelete... */
mcbLast->pPoolNext = mcbCurrent->pPoolNext;
}
wmosSemGive (poolId->semLockPool);
#ifdef DEBUG_INFO
printf("Block %p freed!\n", pBlock);
#endif
return (OK);
}
#ifdef __ENABLE_MEMMGR_DEBUG__
/*******************************************************************************
*
* memPoolBlockSize - return size of memory block for debugging
*
* This routine returns the size of a block of memory in the specified pool.
*
* RETURNS:
* OK, or ERROR if the pool is corrupt or invalid, or if
* the memory pointer is not to a valid block of memory
* previously allocated from this pool.
*
* NOMANUAL
*/
sbyte4 memPoolBlockSize
(
MEM_POOL_ID poolId, /* Memory pool ID */
void * pBlock
)
{
MEM_POOL_MCB * mcbCurrent;
char * pPoolStart;
if (memPoolCheck (poolId) != OK)
return -1;
/* check if pointer given to free, SEEMS to be correct... */
pPoolStart = (char *) memPtrGet(poolId, poolId->pPoolStart);
/* should range check be a macro -- used elsewhere? */
if ((char *)pBlock < pPoolStart ||
(char *)pBlock > pPoolStart + poolId->ulPoolSize + sizeof (MEM_POOL_DESC))
return -1;
mcbCurrent = (MEM_POOL_MCB *) ((char *)pBlock - sizeof (MEM_POOL_MCB));
if (mcbCurrent->ulUsage == MCB_FREE || mcbCurrent->ulUsage != MCB_OCCUPIED)
return -1;
return mcbCurrent->ulBlockSize;
} /* memPoolSize */
#endif /* __ENABLE_MEMMGR_DEBUG__ */
#ifdef __ENABLE_SHARED_MEMORY__
BOOL memPoolShared
(
MEM_POOL_ID pool
)
{
return pool->shared;
}
#endif /* __ENABLE_SHARED_MEMORY__ */
/* eof memPoolLib.c */
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,89 @@
/* mudUtils.c - Utilities for Multithreaded Universal Daemon (MUD)*/
/* Copyright 1984-2007, 2010 Wind River Systems, Inc. */
/*
modification history
--------------------
01g,28apr10,m_z eliminate compile warning
01f,29jan10,m_z VxWorks 64-bit support
(WIND00193649)
01e,24feb07,msa Correct the apigen comments so they match the actual routines
and correct any apigen errors that may occur.
01d,02jan04,jws add mudlib.h include
01c,18dec03,adb included private/mudLibP.h
01b,02may03,jws remove assert()'s
01a,06sep01,jc written.
*/
/*
DESCRIPTION
Put a Multithreaded Universal Daemon in your life!
*/
/* include C standard library */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
/* include OSAL */
#include "wm.h"
/* include public interface to mud */
#include "memPoolLib.h"
#include "private/mudLibP.h"
#include "mudLib.h" /* this is needed !! */
#include "mudUtils.h" /* this is needed !! */
/**************************************************************************
*
* readLineFromSocket - Read a line from a socket.
*
* Read a single LF (\n) terminated line from a socket and terminate
* it with a NULL
*
* RETURNS: OK, or ERROR.
*
* NOMANUAL
*/
STATUS readLineFromSocket
(
MUD_SOCKET sock,
char * buffer,
#ifndef _WRS_CONFIG_LP64
ubyte4 sizebuf
#else
ubyte8 sizebuf
#endif
)
{
char oneChar;
#ifndef _WRS_CONFIG_LP64
sbyte4 bytesRead;
ubyte4 bytesMsg;
#else
sbyte8 bytesRead;
ubyte8 bytesMsg;
#endif
STATUS status;
bytesMsg = 0;
/* read as much as we can from the socket, and send an acknowledgement */
wmnetSocketBlocking (sock, TRUE);
do
{
if (OK != (status = wmnetTcpRead (sock, &oneChar, 1, &bytesRead)))
return status;
buffer[bytesMsg] = oneChar;
bytesMsg++;
} while (('\n' != oneChar) && (bytesMsg <= sizebuf));
buffer[bytesMsg] = 0; /* terminate string */
return OK;
}
/* eof mudUtils.c */
@@ -0,0 +1,731 @@
/* wmnetBSD.c - Implementation in BSD of the Rapid Control net AL */
/* Copyright 2004 Wind River Systems, Inc. */
/*
modification history
--------------------
01a,19feb04,jws Add modification history and copyright, SPR 92723
*/
/*
DESCRIPTION
This module implements all the functions defined in wmnet.h for BSD
*
*/
#include "wm.h"
#ifdef __BSD_OS__
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdarg.h>
#include <arpa/inet.h>
#include <errno.h>
/* constants used ONLY in this module */
#define kTCP_LISTEN_BACKLOG 20
#define kMinimalSocketTimeout 10
LOCAL OS_SOCKET_T tcpSocketCreate
(
void
)
{
OS_SOCKET_T sock;
sock = socket(PF_INET, SOCK_STREAM, 0);
DEBUG_MSG_1("socket 0x%x created\n", sock);
return sock;
}
LOCAL STATUS bindSocketToAddr
(
OS_SOCKET_T sock,
ubyte2 port
)
{
struct sockaddr_in LocalAddr;
/* ask the system to allocate a port and bind to INADDR_ANY */
memset(&LocalAddr, 0x00, sizeof(LocalAddr));
/* get system to allocate a port number by binding a host address */
LocalAddr.sin_family = PF_INET;
LocalAddr.sin_addr.s_addr = htonl(INADDR_ANY);
LocalAddr.sin_port = htons(port);
/* bind socket to local address */
if (ERROR == bind(sock, (struct sockaddr *) &LocalAddr, sizeof(LocalAddr)))
{
wmosError(ERROR_GENERAL_ACCESS_DENIED, "bindSocketToAddr: failed");
close(sock);
return ERROR;
}
return OK;
}
STATUS wmnetInitialize
(
void
)
{
return OK;
}
STATUS wmnetUdpBind
(
OS_SOCKET_T * pSock,
ubyte2 port
)
{
/* Create a datagram stream socket */
if (OK != wmnetUdpSocketCreate(pSock))
return ERROR;
if (OK != bindSocketToAddr(*pSock, port))
return ERROR;
return OK;
}
STATUS wmnetTcpServerOpen
(
OS_SOCKET_T * pSock,
ubyte2 port
)
{
STATUS status;
/* Create a stream socket */
if (-1 == (*pSock = tcpSocketCreate()))
return ERROR_GENERAL_ACCESS_DENIED;
if (OK != (status = bindSocketToAddr(*pSock, port)))
return status;
/* Create a incoming Client connect request queue */
if (0 != listen(*pSock, kTCP_LISTEN_BACKLOG))
{
wmosError(ERROR_GENERAL_ACCESS_DENIED, "wmnetTcpServerOpen: failed");
close(*pSock);
return ERROR;
}
return OK;
}
STATUS wmnetUdpSendTo
(
OS_SOCKET_T sock,
ubyte4 addr,
ubyte2 port,
sbyte * pBuffer,
ubyte4 bufSize
)
{
struct sockaddr_in *pAddrTo;
if (NULL == (pAddrTo = (struct sockaddr_in *) wmNew(pAddrTo)))
return ERROR_MEMMGR_NO_MEMORY;
pAddrTo->sin_family = PF_INET;
pAddrTo->sin_addr.s_addr = addr;
pAddrTo->sin_port = HTON2(port);
if (ERROR == sendto(sock, (sbyte *) pBuffer, bufSize, 0,
(struct sockaddr *)pAddrTo, sizeof(struct sockaddr)) )
{
wmFree(pAddrTo);
return wmosError(SYS_ERROR_SOCKET_GENERAL, "send failed");
}
wmFree(pAddrTo);
return OK;
}
STATUS wmnetUdpRcvFrom
(
OS_SOCKET_T sock,
ubyte4 * pAddrSender,
ubyte2 port,
sbyte * pBuffer,
ubyte4 bufSize,
sbyte4 * pBytesRead
)
{
struct sockaddr_in * pAddr;
ubyte4 iAddrLen;
int RecvResult;
iAddrLen = sizeof(*pAddr);
if ( NULL == (pAddr = (struct sockaddr_in *) wmMalloc(iAddrLen)) )
return ERROR_MEMMGR_NO_MEMORY;
RecvResult = recvfrom(sock, pBuffer, kMaxUdpPacketSize,
0, (struct sockaddr *) pAddr, &iAddrLen);
if (-1 == RecvResult)
{
wmFree(pAddr);
return wmosError(ERROR_GENERAL, "recv failed");
}
(*pAddrSender) = (ubyte4) pAddr->sin_addr.s_addr;
(*pBytesRead) = (ubyte4)RecvResult;
wmFree(pAddr);
return OK;
}
STATUS wmnetTcpAccept
(
OS_SOCKET_T * soc,
OS_SOCKET_T * accSoc,
ubyte2 port
)
{
struct sockaddr_in ClientAddr;
ubyte4 iAddrLen;
iAddrLen = sizeof(ClientAddr);
memset(&ClientAddr, 0x00, iAddrLen);
*accSoc = accept(*soc, (struct sockaddr *)&ClientAddr, &iAddrLen);
DEBUG_MSG_1("socket %d accepted++++++++++\n",*accSoc);
if (ERROR == *accSoc)
{
wmosError(ERROR_GENERAL, "wmnetTcpAccept: failed");
close(*accSoc);
close(*soc);
wmnetTcpServerOpen(soc, port);
return SYS_ERROR_SOCKET_ACCEPT;
}
return OK;
}
STATUS wmnetClientAddrGet
(
OS_SOCKET_T ClientSock,
ubyte4 * pAddr
)
{
struct sockaddr_in ClientAddr;
ubyte4 iAddrLen;
*pAddr = 0;
iAddrLen = sizeof(ClientAddr);
memset(&ClientAddr, 0x00, iAddrLen);
if (OK != getpeername(ClientSock, (struct sockaddr *)&ClientAddr, &iAddrLen))
return wmosError(ERROR_GENERAL, "unable to get address from socket");
*pAddr = ntohl(ClientAddr.sin_addr.s_addr);
return OK;
}
STATUS wmnetSocketClose
(
OS_SOCKET_T sock
)
{
DEBUG_MSG_1("wmnetSocketClose: socket = 0x%x\n", sock);
if (-1 == close(sock))
return wmosError (ERROR_GENERAL_ACCESS_DENIED,
"wmnetSocketClose: failed");
return OK;
}
LOCAL STATUS connectToServer
(
OS_SOCKET_T sock,
sbyte * pName,
ubyte2 port
)
{
struct sockaddr_in RemAddr;
ubyte4 ulHostAddress;
struct hostent * pHost;
char * pAddr;
memset(&RemAddr, 0x00, sizeof(RemAddr));
if (NULL == (pHost = gethostbyname(pName)))
return wmosError(ERROR_GENERAL,"remote host unknown");
pAddr = *(pHost->h_addr_list);
ulHostAddress = (ubyte4) ((ubyte4 *) pAddr);
RemAddr.sin_family = PF_INET;
RemAddr.sin_addr.s_addr = ulHostAddress;
RemAddr.sin_port = htons(port);
/* Create a Client connection */
if (-1 == connect( sock, (struct sockaddr *) &RemAddr, sizeof(RemAddr)))
return wmosError(ERROR_GENERAL_ACCESS_DENIED, "connectToServer: failed");
return OK;
}
STATUS wmnetTcpConnect
(
OS_SOCKET_T * pSoc,
sbyte * pName,
ubyte2 port
)
{
STATUS status;
/* Create a stream socket */
*pSoc = tcpSocketCreate();
if (ERROR == *pSoc)
return wmosError(ERROR_GENERAL, "failed socket creation");
if (OK != (status = bindSocketToAddr(*pSoc, ANY_PORT_K)))
return status;
/* Create a Client connection */
return connectToServer( *pSoc, pName, port );
}
STATUS wmnetTcpWrite
(
OS_SOCKET_T sock,
sbyte * pBuf,
ubyte4 BufLen
)
{
if (-1 == send(sock, pBuf, BufLen, 0))
return ERROR_GENERAL_ACCESS_DENIED;
return OK;
}
STATUS wmnetTcpRead
(
OS_SOCKET_T sock,
sbyte * pBuf,
ubyte4 BufSize,
ubyte4 * pBytesRead
)
{
ubyte4 bytes;
DEBUG_MSG_2 ("tcp read start sock: %x size: %d\n", sock, BufSize);
if (-1 == (bytes = recv(sock, pBuf, BufSize, 0)))
return wmosError(ERROR_GENERAL_ACCESS_DENIED, "wmnetTcpRead: failed");
if (NULL != pBytesRead)
*pBytesRead = bytes;
return OK;
}
/*******************************************************************************
*
* wmnetSocketBlocking - enable or disable socket blocking
*
* This function modifies the behavior of other socket functions. If socket
* blocking is enabled, calling wmosSocketRead or wmosSocketPeek will block until
* data is available. If socket blocking is disabled, these functions will return
* immediately.
*
* RETURNS: N/A
*
*/
STATUS wmnetSocketBlocking
(
OS_SOCKET_T sock, /* the socket */
BOOL block /* TRUE to enable socket blocking */
)
{
BOOL iOpt = (TRUE == block) ? FALSE : TRUE;
DEBUG_MSG_1("wmnetSocketBlocking: block = %d\n", block);
if (0 == ioctl (sock, FIONBIO, (int)&iOpt))
{
DEBUG_MSG_0("blocking set\n");
return OK;
}
switch(errno)
{
case EBADF:
DEBUG_MSG_0("d is not a valid descriptor.\n");
break;
case ENOTTY:
DEBUG_MSG_0("d is not associated with a character special device.\n");
break;
case EINVAL:
DEBUG_MSG_0("Request or argp is not valid.\n");
break;
default:
DEBUG_MSG_0("unknown ioctl error\n");
}
return wmosError(SYS_ERROR_SOCKET_GENERAL, "block set failed");
}
/*******************************************************************************
*
* wmnetSocketPeek - peek into a socket
*
* This routine peeks into a socket without modifying the data waiting on it. As
* many as (*pBufSize) characters are read and copied onto pBuf. When no data is
* pending, the routine will block or return immediately depending on wether
* socket blocking is enable or not (see wmnetSocketBlocking()).
*
* RETURNS: The number of characters that have been copied to pBuf or one of
* these errors:
* SYS_ERROR_SOCKET_TIMEOUT
* SYS_ERROR_SOCKET_GENERAL
*
*/
STATUS wmnetTcpPeek
(
OS_SOCKET_T sock, /* the socket */
sbyte * pBuf, /* the buffer where data will be copied */
ubyte4 BufSize, /* buffer size */
ubyte4 * pBytesRead /* return: number of bytes read */
)
{
ubyte4 bytes;
if (-1 == (bytes = recv(sock, pBuf, BufSize, MSG_PEEK)))
return wmosError(ERROR_GENERAL_ACCESS_DENIED, "wmnetTcpPeek: failed");
*pBytesRead = bytes;
return OK;
}
/*******************************************************************************
*
* wmnetSocketGroupWait - wait on a set of sockets and/or pipes
*
* This routine blocks until there is some activity (data available for
* reading or socket/pipe is closed) on the set of monitored sockets.
*
* setOfSockets is the list of sockets/pipes to wait on and it can be modified
* using the functions wmnetSocketGroupAddTo, wmnetSocketGroupAddPipe and
* wmnetSocketGroupClear.
*
* When the function returns, wmnet[Socket/Pipe]WantsAction could be used to
* determine which of the monitored sockets.pipes was active.
*
* timeoutInSecs can be set to 0 to indicate no timeout (i.e. infinite wait)
*
* RETURNS: The number of characters that have been copied to pBuf or one of
* these errors:
* SYS_ERROR_SOCKET_TIMEOUT
* SYS_ERROR_SOCKET_GENERAL
*
*/
STATUS wmnetSocketGroupWait
(
OS_FDSET_T * setOfSockets,
ubyte4 timeoutInSecs
)
{
int r;
struct timeval tv;
DEBUG_MSG_1("wmnetSocketGroupWait: timeout = %d\n", timeoutInSecs);
tv.tv_sec = timeoutInSecs;
tv.tv_usec = 0;
DEBUG_MSG_1("wmnetSocketGroupWait: max sockets = %d\n", setOfSockets->fdMax + 1);
r = select (setOfSockets->fdMax + 1, &setOfSockets->fdSet, NULL, NULL, &tv);
if (-1 == r)
{
switch (errno)
{
case EBADF:
DEBUG_MSG_0("One of the descriptor sets specified an invalid descriptor.\n");
break;
case EINTR:
DEBUG_MSG_0("A signal was delivered before the time limit expired "
"and before any of the selected events occurred.\n");
break;
case EINVAL:
DEBUG_MSG_0("The specified time limit is invalid. One of its "
"components is negative or too large. Or nfds was invalid.\n");
break;
default:
DEBUG_MSG_0("unknown select error\n");
}
return SYS_ERROR_SOCKET_GENERAL;
}
if (0 == r)
return ERROR_GENERAL_TIMEOUT;
return OK;
}
STATUS wmnetSocketGroupAddTo
(
OS_SOCKET_T sock,
OS_FDSET_T * setOfSockets
)
{
if (sock > FD_SETSIZE)
{
DEBUG_MSG_2("wmnetSocketGroupAddTo: ERROR - socket 0x%x greater than 0x%x\n",
sock, FD_SETSIZE);
return ERROR_GENERAL;
}
DEBUG_MSG_1("wmnetSocketGroupAddTo: socket = 0x%x\n", sock);
FD_SET(sock, &setOfSockets->fdSet);
if (sock > setOfSockets->fdMax)
setOfSockets->fdMax = sock;
return OK;
}
STATUS wmnetSocketGroupAddPipe
(
OS_PIPE_T pipe,
OS_FDSET_T * setOfSockets
)
{
DEBUG_MSG_1("wmnetSocketGroupAddPipe: pipe = 0x%x\n", (int) pipe);
return wmnetSocketGroupAddTo ((OS_SOCKET_T) pipe, setOfSockets);
}
STATUS wmnetSocketGroupClear
(
OS_FDSET_T * setOfSockets
)
{
DEBUG_MSG_0("wmnetSocketGroupClear: called\n");
FD_ZERO(setOfSockets);
setOfSockets->fdMax = 0;
return OK;
}
BOOL wmnetSocketWantsAction
(
OS_SOCKET_T sock,
OS_FDSET_T * setOfSockets
)
{
DEBUG_MSG_1("wmnetSocketGroupAddTo: socket = %d\n", sock);
return FD_ISSET(sock, (&setOfSockets->fdSet));
}
BOOL wmnetPipeWantsAction
(
OS_PIPE_T pipe,
OS_FDSET_T * setOfSockets
)
{
DEBUG_MSG_0("wmnetPipeWantsAction: called\n");
return wmnetSocketWantsAction((OS_SOCKET_T) pipe, setOfSockets);
}
/*******************************************************************************
*
* wmnetSocketPrintf - output a formatted string to a socket
*
* This sends a formatted string to the connection socket.
* It is identical to printf() in terms of the
* usage of parameters and format strings.
*
* RETURNS: size of sent string
*/
sbyte4 wmnetSocketPrintf
(
OS_SOCKET_T sock,
sbyte * szFormat,
...
)
{
enum {PRINTF_BUFFER = 1000 };
va_list vaList;
sbyte tmpBuffer[PRINTF_BUFFER];
ubyte4 bytesPrinted = 0;
va_start (vaList, szFormat);
bytesPrinted = vsprintf (tmpBuffer, szFormat, vaList);
wmnetTcpWrite(sock, tmpBuffer, bytesPrinted);
va_end (vaList);
return bytesPrinted;
}
/*******************************************************************************
*
* wmnetSockPrintf - print a formatted string on a socket
*
* All parameters identical to vfprintf, except for the first which identifies
* a socket instead of a file. ANSI requires that call to vfprintf should be
* preceded by a call to va_start, and followed by a call to va_end. The same
* applies to this function.
*
* SPECIFIC TO THIS PORT:
* Formatted output cannot be sent to a socket under Windows (fprintf does
* not work on sockets) and a temporary buffer needs to be allocated. If the
* size of the message is larger than PRINTF_BUFFER some data will be lost.
*
* RETURNS: OK or an error
* The number of characters sent to the socket (by reference)
*
*/
STATUS wmnetSocketVprintf
(
OS_SOCKET_T sock,
sbyte * szFormat,
va_list args,
ubyte4 * pBytesPrinted
)
{
enum {PRINTF_BUFFER = 1000 };
sbyte tmpBuffer[PRINTF_BUFFER];
* pBytesPrinted = 0;
(* pBytesPrinted) = vsprintf (tmpBuffer, szFormat, args);
wmnetTcpWrite(sock, tmpBuffer, strlen(tmpBuffer));
return OK;
}
STATUS wmnetAddressResolve
(
sbyte * pName,
ubyte4 * pAddress
)
{
sbyte * pTmp;
struct hostent * pHostAddr;
struct in_addr * pInAddr;
/* only resolve once */
*pAddress = inet_addr(pName);
if (-1 != *pAddress)
return OK;
pHostAddr = gethostbyname (pName);
if (pHostAddr == NULL)
{
*pAddress = 0;
return wmosError(SYS_ERROR_SOCKET_GENERAL, "wmnetAddressResolve: invalid name");
}
pInAddr = (struct in_addr *) pHostAddr->h_addr_list[0];
pTmp = inet_ntoa(*pInAddr);
*pAddress = inet_addr(pTmp);
return (-1 != *pAddress) ? OK : SYS_ERROR_SOCKET_GENERAL;
}
STATUS wmnetUdpSocketCreate
(
OS_SOCKET_T * pSock
)
{
*pSock = socket(PF_INET, SOCK_DGRAM, 0);
if (-1 == *pSock)
return wmosError(SYS_ERROR_SOCKET_GENERAL,
"wmnetUdpSocketCreate: socket creation failed");
return OK;
}
/*******************************************************************************
*
* wmnetStdoutToSocket - redirect STDIO to a socket
*
* This routine redirects current STDIO to the socket. An OS specific value
* needed to restore the Stdout is returned by reference in the second parameter.
*
*
* RETURNS: 'OK' or an error
*/
STATUS wmnetStdoutToSocket
(
OS_SOCKET_T sock,
sbyte4 * pOldStdout
)
{
return OK;
}
#endif /*__BSD_OS__*/
@@ -0,0 +1,704 @@
/* wmnetPosix.c - Implementation in Posix of the WindManage net AL */
/* Copyright 2004 Wind River Systems, Inc. */
/*
modification history
--------------------
01a,19feb04,jws Add modification history and copyright, SPR 92723
*/
/*
DESCRIPTION
This module implements all the functions defined in wmnet.h for most
Posix IP stacks
*/
#include "wm.h"
#ifdef __POSIX_OS__
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/termios.h>
#include <netdb.h>
#include <sys/filio.h>
#include <errno.h>
/* constants used ONLY in this module */
#define kTCP_LISTEN_BACKLOG 20
#define kMinimalSocketTimeout 10
LOCAL STATUS wmnetTcpSocketCreate
(
OS_SOCKET_T * pSock
)
{
if (NULL == pSock)
return wmosError(ERROR, "wmnetTcpSocketCreate: null pointer");
*pSock = socket(PF_INET, SOCK_STREAM, 0);
if (-1 == *pSock)
return wmosError(ERROR, "wmnetTcpSocketCreate: creation failed");
return OK;
}
STATUS wmnetUdpSocketCreate
(
OS_SOCKET_T * pSock
)
{
*pSock = socket(PF_INET, SOCK_DGRAM, 0);
if (-1 == *pSock)
return wmosError(ERROR_GENERAL, "wmnetUdpSocketCreate: failed");
return OK;
}
STATUS wmnetAddressResolve
(
sbyte * pName,
ubyte4 * pAddress
)
{
sbyte * pTmp;
struct hostent * pHostAddr;
struct in_addr * pInAddr;
/* only resolve once */
*pAddress = inet_addr(pName);
if (-1 != *pAddress)
return OK;
pHostAddr = gethostbyname (pName);
if (pHostAddr == NULL)
{
*pAddress = 0;
return wmosError(SYS_ERROR_SOCKET_GENERAL, "wmnetAddressResolve: invalid name");
}
pInAddr = (struct in_addr *) pHostAddr->h_addr_list[0];
pTmp = inet_ntoa(*pInAddr);
*pAddress = inet_addr(pTmp);
if (-1 == *pAddress)
return wmosError(SYS_ERROR_SOCKET_GENERAL, "wmnetAddressResolve: bad address");
return OK;
}
/*-----------------------------------------------------------------------*/
LOCAL STATUS wmnetBindSockToAddr
(
OS_SOCKET_T soc,
ubyte2 port
)
{
struct sockaddr_in LocalAddr;
/* ask the system to allocate a port and bind to INADDR_ANY */
memset(&LocalAddr, 0x00, sizeof(LocalAddr));
/* get system to allocate a port number by binding a host address */
LocalAddr.sin_family = PF_INET;
LocalAddr.sin_addr.s_addr = htonl(INADDR_ANY);
LocalAddr.sin_port = htons((ubyte2)port);
/* bind socket to local address */
if (ERROR == bind(soc, (struct sockaddr *) &LocalAddr, sizeof(LocalAddr)))
{
close(soc);
return wmosError(ERROR_GENERAL_ACCESS_DENIED, "");
}
return OK;
}
STATUS wmnetInitialize
(
void
)
{
return OK;
}
STATUS wmnetUdpBind
(
OS_SOCKET_T * pSoc,
ubyte2 port
)
{
/* Create a stream socket */
if (OK != wmnetUdpSocketCreate(pSoc))
return ERROR;
if (OK != wmnetBindSockToAddr(*pSoc, port))
return ERROR;
return OK;
}
STATUS wmnetTcpServerOpen
(
OS_SOCKET_T * pSoc,
ubyte2 port
)
{
/* Create a stream socket */
if (OK != wmnetTcpSocketCreate(pSoc))
return ERROR;
if (OK != wmnetBindSockToAddr(*pSoc, port))
return ERROR;
/* Create a incoming Client connect request queue */
if (0 != listen(*pSoc, kTCP_LISTEN_BACKLOG))
{
close(*pSoc);
return wmosError(ERROR_GENERAL, "wmnetTcpServerOpen: listen failed");
}
return OK;
}
STATUS wmnetUdpSendTo
(
OS_SOCKET_T sock,
ubyte4 addr,
ubyte2 port,
sbyte * pBuffer,
ubyte4 bufSize
)
{
struct sockaddr_in *pAddrTo;
if ( NULL == (pAddrTo = (struct sockaddr_in *) wmMalloc(sizeof(struct sockaddr_in))) )
return wmosError(ERROR_MEMMGR_NO_MEMORY, "wmnetUdpSendTo: no memory");
pAddrTo->sin_family = PF_INET;
pAddrTo->sin_addr.s_addr = addr;
pAddrTo->sin_port = HTON2(port);
if (ERROR == sendto(sock, (sbyte *) pBuffer,
bufSize, 0,
(struct sockaddr *)pAddrTo,
sizeof(struct sockaddr)) )
{
wmFree(pAddrTo);
return wmosError(SYS_ERROR_SOCKET_GENERAL, "wmnetUdpSendTo: sendto failed");
}
wmFree(pAddrTo);
return OK;
}
STATUS wmnetUdpRcvFrom
(
OS_SOCKET_T sock,
ubyte4 * pAddrSender,
ubyte2 port,
sbyte * pBuffer,
ubyte4 bufSize,
sbyte4 * pBytesRead
)
{
struct sockaddr_in *pAddr;
int iAddrLen;
int RecvResult;
iAddrLen = sizeof(struct sockaddr_in);
if ( NULL == (pAddr = (struct sockaddr_in *) wmMalloc(iAddrLen)) )
return wmosError(ERROR_MEMMGR_NO_MEMORY, "no memory");
RecvResult = recvfrom(sock, pBuffer, kMaxUdpPacketSize,
0, (struct sockaddr *)pAddr, &iAddrLen );
if (ERROR == RecvResult)
{
wmFree(pAddr);
return wmosError(ERROR_GENERAL, "");
}
*pAddrSender = (ubyte4) pAddr->sin_addr.s_addr;
*pBytesRead = (ubyte4) RecvResult;
wmFree(pAddr);
return OK;
}
/*-----------------------------------------------------------------------*/
STATUS wmnetTcpAccept
(
OS_SOCKET_T * soc,
OS_SOCKET_T * accSoc,
ubyte2 port
)
{
struct sockaddr_in ClientAddr;
int iAddrLen;
iAddrLen = sizeof(ClientAddr);
memset(&ClientAddr, 0x00, iAddrLen);
*accSoc = accept(*soc, (struct sockaddr *)&ClientAddr, &iAddrLen);
#ifdef DEBUG_VERBOSE
posixLog("socket %d accepted++++++++++\n",*accSoc);
#endif
if (ERROR == *accSoc)
{
close(*accSoc);
close(*soc);
wmnetTcpServerOpen(soc, port);
return wmosError(SYS_ERROR_SOCKET_ACCEPT, "wmnetTcpAccept: no server");
}
return OK;
}
/*-----------------------------------------------------------------------*/
STATUS wmnetClientAddrGet
(
OS_SOCKET_T ClientSock,
ubyte4 * pAddr
)
{
struct sockaddr_in ClientAddr;
int iAddrLen;
*pAddr = 0;
iAddrLen = sizeof(ClientAddr);
memset(&ClientAddr, 0x00, iAddrLen);
if (OK != getpeername(ClientSock, (struct sockaddr *)&ClientAddr, &iAddrLen))
return wmosError(ERROR_GENERAL, "unable to get address from socket");
*pAddr = ntohl(ClientAddr.sin_addr.s_addr);
return OK;
}
STATUS wmnetSocketClose
(
OS_SOCKET_T sock
)
{
#ifdef DEBUG_VERBOSE
posixLog("socket %d closed----------\n",sock,0,0,0,0,0);
#endif
if (ERROR == close(sock))
return wmosError(ERROR_GENERAL_ACCESS_DENIED, "wmnetSocketClose");
return OK;
}
LOCAL STATUS connectToServer
(
OS_SOCKET_T sock,
sbyte * pName,
ubyte4 port
)
{
struct sockaddr_in RemAddr;
int err;
struct hostent * pHost;
memset(&RemAddr, 0x00, sizeof(RemAddr));
if (NULL == (pHost = gethostbyname(pName)))
return wmosError(ERROR_GENERAL,"remote host unknown");
RemAddr.sin_family = PF_INET;
RemAddr.sin_addr.s_addr = (unsigned int) pHost->h_addr;
RemAddr.sin_port = htons((ubyte2)port);
/* Create a Client connection */
err = connect( sock, (struct sockaddr *)&RemAddr, sizeof(RemAddr));
if ( ERROR == err )
return wmosError(ERROR_GENERAL_ACCESS_DENIED, NULL);
return OK;
}
STATUS wmnetTcpConnect
(
OS_SOCKET_T * pSoc,
sbyte * pName,
ubyte2 port
)
{
/* Create a stream socket */
if (OK != wmnetTcpSocketCreate(pSoc))
return ERROR;
if (OK != wmnetBindSockToAddr(*pSoc, ANY_PORT_K))
return ERROR;
/* Create a Client connection */
return connectToServer( *pSoc, pName, port );
}
STATUS wmnetTcpWrite
(
OS_SOCKET_T sock,
sbyte * pBuf,
ubyte4 bufLen
)
{
sbyte * pMsg;
if (ERROR != send(sock, pBuf, bufLen, 0))
return OK;
switch (errno)
{
case EBADF:
pMsg = "invalid file descriptor";
break;
case EINTR:
pMsg = "operation was interrupted by signal";
break;
case EINVAL:
pMsg = "tolen not valid size for specified address family";
break;
case EMSGSIZE:
pMsg = "socket requires message be sent atomically, "
"and the message was too long";
break;
case ENOMEM:
pMsg = "insufficient memory available";
break;
case ENOSR:
pMsg = "insufficient STREAMS resources";
break;
case ENOTSOCK:
pMsg = "not a socket";
break;
case EWOULDBLOCK:
pMsg = "socket is marked non-blocking and the "
"requested operation would block";
break;
default:
pMsg = "unknown send error";
break;
}
return wmosError(ERROR_GENERAL_ACCESS_DENIED, pMsg);
}
STATUS wmnetTcpRead
(
OS_SOCKET_T sock,
sbyte * pBuf,
ubyte4 BufSize,
ubyte4 * pBytesRead
)
{
ubyte4 bytes;
if (NULL != pBytesRead)
*pBytesRead = 0;
bytes = recv(sock, pBuf, BufSize, 0);
if (ERROR == bytes)
return wmosError(ERROR_GENERAL_ACCESS_DENIED, "wmnetTcpRead: denied");
if (NULL != pBytesRead)
*pBytesRead = bytes;
return OK;
}
/*******************************************************************************
*
* wmnetSocketBlocking - enable or disable socket blocking
*
* This function modifies the behavior of other socket functions. If socket
* blocking is enabled, calling wmosSocketRead or wmosSocketPeek will block until
* data is available. If socket blocking is disabled, these functions will return
* immediately.
*
* RETURNS: N/A
*
*/
STATUS wmnetSocketBlocking
(
OS_SOCKET_T sock, /* the socket */
BOOL block /* TRUE to enable socket blocking */
)
{
int iOpt;
iOpt = ! block;
if (ERROR == ioctl (sock, FIONBIO, (int) &iOpt))
return wmosError (SYS_ERROR_SOCKET_GENERAL,
"wmnetSocketBlocking: ioctl failed");
return OK;
}
/*******************************************************************************
*
* wmnetSocketPeek - peek into a socket
*
* This routine peeks into a socket without modifying the data waiting on it. As
* many as (*pBufSize) characters are read and copied onto pBuf. When no data is
* pending, the routine will block or return immediately depending on wether
* socket blocking is enable or not (see wmnetSocketBlocking()).
*
* RETURNS: The number of characters that have been copied to pBuf or one of
* these errors:
* SYS_ERROR_SOCKET_TIMEOUT
* SYS_ERROR_SOCKET_GENERAL
*
*/
STATUS wmnetTcpPeek
(
OS_SOCKET_T sock, /* the socket */
sbyte * pBuf, /* the buffer where data will be copied */
ubyte4 BufSize, /* buffer size */
ubyte4 * bytesRead /* return: number of bytes read */
)
{
ubyte4 bytes;
bytes = recv(sock, pBuf, BufSize, MSG_PEEK);
if (ERROR == bytes)
return wmosError(ERROR_GENERAL_ACCESS_DENIED, "wmnetTcpPeek: denied");
if (NULL != bytesRead)
*bytesRead = bytes;
return OK;
}
/*******************************************************************************
*
* wmnetSocketGroupWait - wait on a set of sockets and/or pipes
*
* This routine blocks until there is some activity (data available for
* reading or socket/pipe is closed) on the set of monitored sockets.
*
* setOfSockets is the list of sockets/pipes to wait on and it can be modified
* using the functions wmnetSocketGroupAddTo, wmnetSocketGroupAddPipe and
* wmnetSocketGroupClear.
*
* When the function returns, wmnet[Socket/Pipe]WantsAction could be used to
* determine which of the monitored sockets.pipes was active.
*
* timeoutInSecs can be set to 0 to indicate no timeout (i.e. infinite wait)
*
* RETURNS: The number of characters that have been copied to pBuf or one of
* these errors:
* SYS_ERROR_SOCKET_TIMEOUT
* SYS_ERROR_SOCKET_GENERAL
*
*/
STATUS wmnetSocketGroupWait
(
OS_FDSET_T * setOfSockets,
ubyte4 timeoutInSecs
)
{
int r;
struct timeval tv;
tv.tv_sec = timeoutInSecs;
tv.tv_usec = 0;
assert ((0 < setOfSockets->fdMax) && (64 > setOfSockets->fdMax));
r = select (setOfSockets->fdMax + 1, &setOfSockets->fdSet, NULL, NULL, &tv);
if (0 > r)
return wmosError(SYS_ERROR_SOCKET_GENERAL, "wmnetSocketGroupWait: error");
if (0 == r)
return wmosError(ERROR_GENERAL_TIMEOUT, "wmnetSocketGroupWait: timeout");
return OK;
}
STATUS wmnetSocketGroupAddTo
(
OS_SOCKET_T sock,
OS_FDSET_T * setOfSockets
)
{
FD_SET(sock, &setOfSockets->fdSet);
if (sock > setOfSockets->fdMax)
setOfSockets->fdMax = sock;
return OK;
}
STATUS wmnetSocketGroupAddPipe
(
OS_PIPE_T pipe,
OS_FDSET_T * setOfSockets
)
{
return wmnetSocketGroupAddTo ((OS_SOCKET_T) pipe,setOfSockets);
}
STATUS wmnetSocketGroupClear
(
OS_FDSET_T * setOfSockets
)
{
FD_ZERO(&setOfSockets->fdSet);
setOfSockets->fdMax = 0;
return OK;
}
BOOL wmnetSocketWantsAction
(
OS_SOCKET_T sock,
OS_FDSET_T * setOfSockets
)
{
return FD_ISSET(sock, &setOfSockets->fdSet);
}
BOOL wmnetPipeWantsAction
(
OS_PIPE_T pipe,
OS_FDSET_T * setOfSockets
)
{
return wmnetSocketWantsAction((OS_SOCKET_T) pipe, setOfSockets);
}
/*******************************************************************************
*
* wmnetSocketPrintf - output a formatted string to a socket
*
* This sends a formatted string to the connection socket.
* It is identical to printf() in terms of the
* usage of parameters and format strings.
*
* INTERNAL: Note that vfdprintf is not ANSI, and that the function is not
* portable because it assumes that a socket is a file descriptor, which is not
* true in some OSes.
*
* RETURNS: OK or ERROR.
*/
STATUS wmnetSocketPrintf
(
OS_SOCKET_T sock,
sbyte * szFormat,
...
)
{
#if 0
va_list vaList;
va_start (vaList, szFormat);
if (vfprintf (sock, szFormat, vaList) > 0)
{
#ifdef DEBUG_VERBOSE
/* produce verbose output */
printf ("SOCKET PRINTF: ");
vprintf (szFormat, vaList);
printf ("\n");
#endif
va_end (vaList);
return OK;
}
else
{
va_end (vaList);
return wmosError(ERROR_GENERAL, "wmnetSocketPrintf failed");
}
#endif
return 0;
}
/*******************************************************************************
*
* wmnetStdoutToSocket - redirect STDIO to a socket
*
* This routine redirects current STDIO to the socket. An OS specific value
* needed to restore the Stdout is returned by reference in the second parameter.
*
*
* RETURNS: 'OK' or an error
*/
STATUS wmnetStdoutToSocket
(
OS_SOCKET_T sock,
sbyte4 * pOldStdout
)
{
return OK;
}
#endif /*__POSIX_OS__*/
@@ -0,0 +1,758 @@
/* wmnetPosix.c - Implementation in Posix of the WindManage net AL */
/* Copyright 2004 Wind River Systems, Inc. */
/*
modification history
--------------------
01a,19feb04,jws Add modification history and copyright, SPR 92723
*/
/*
DESCRIPTION
This module implements all the functions defined in wmnet.h for most
Posix IP stacks
*/
#include "wm.h"
#ifdef __SOLARIS_OS__
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/termios.h>
#include <netdb.h>
#include <sys/filio.h>
#include <errno.h>
/* constants used ONLY in this module */
#define kTCP_LISTEN_BACKLOG 20
#define kMinimalSocketTimeout 10
LOCAL STATUS wmnetTcpSocketCreate
(
OS_SOCKET_T * pSock
)
{
if (NULL == pSock)
return wmosError(ERROR, "wmnetTcpSocketCreate: null pointer");
*pSock = socket(PF_INET, SOCK_STREAM, 0);
if (-1 == *pSock)
return wmosError(ERROR, "wmnetTcpSocketCreate: creation failed");
return OK;
}
STATUS wmnetUdpSocketCreate
(
OS_SOCKET_T * pSock
)
{
*pSock = socket(PF_INET, SOCK_DGRAM, 0);
if (-1 == *pSock)
return wmosError(ERROR_GENERAL, "wmnetUdpSocketCreate: failed");
return OK;
}
STATUS wmnetAddressResolve
(
sbyte * pName,
ubyte4 * pAddress
)
{
sbyte * pTmp;
struct hostent * pHostAddr;
struct in_addr * pInAddr;
/* only resolve once */
*pAddress = inet_addr(pName);
if (-1 != *pAddress)
return OK;
pHostAddr = gethostbyname (pName);
if (pHostAddr == NULL)
{
*pAddress = 0;
return wmosError(SYS_ERROR_SOCKET_GENERAL, "wmnetAddressResolve: invalid name");
}
pInAddr = (struct in_addr *) pHostAddr->h_addr_list[0];
pTmp = inet_ntoa(*pInAddr);
*pAddress = inet_addr(pTmp);
if (-1 == *pAddress)
return wmosError(SYS_ERROR_SOCKET_GENERAL, "wmnetAddressResolve: bad address");
return OK;
}
/*-----------------------------------------------------------------------*/
LOCAL STATUS wmnetBindSockToAddr
(
OS_SOCKET_T soc,
ubyte2 port
)
{
struct sockaddr_in LocalAddr;
/* ask the system to allocate a port and bind to INADDR_ANY */
memset(&LocalAddr, 0x00, sizeof(LocalAddr));
/* get system to allocate a port number by binding a host address */
LocalAddr.sin_family = PF_INET;
LocalAddr.sin_addr.s_addr = htonl(INADDR_ANY);
LocalAddr.sin_port = htons((ubyte2)port);
/* bind socket to local address */
if (ERROR == bind(soc, (struct sockaddr *) &LocalAddr, sizeof(LocalAddr)))
{
close(soc);
return wmosError(ERROR_GENERAL_ACCESS_DENIED, "");
}
return OK;
}
STATUS wmnetInitialize
(
void
)
{
return OK;
}
STATUS wmnetUdpBind
(
OS_SOCKET_T * pSoc,
ubyte2 port
)
{
/* Create a stream socket */
if (OK != wmnetUdpSocketCreate(pSoc))
return ERROR;
if (OK != wmnetBindSockToAddr(*pSoc, port))
return ERROR;
return OK;
}
STATUS wmnetTcpServerOpen
(
OS_SOCKET_T * pSoc,
ubyte2 port
)
{
/* Create a stream socket */
if (OK != wmnetTcpSocketCreate(pSoc))
return ERROR;
if (OK != wmnetBindSockToAddr(*pSoc, port))
return ERROR;
/* Create a incoming Client connect request queue */
if (0 != listen(*pSoc, kTCP_LISTEN_BACKLOG))
{
close(*pSoc);
return wmosError(ERROR_GENERAL, "wmnetTcpServerOpen: listen failed");
}
return OK;
}
STATUS wmnetUdpSendTo
(
OS_SOCKET_T sock,
ubyte4 addr,
ubyte2 port,
sbyte * pBuffer,
ubyte4 bufSize
)
{
struct sockaddr_in *pAddrTo;
if ( NULL == (pAddrTo = (struct sockaddr_in *) wmMalloc(sizeof(struct sockaddr_in))) )
return wmosError(ERROR_MEMMGR_NO_MEMORY, "wmnetUdpSendTo: no memory");
pAddrTo->sin_family = PF_INET;
pAddrTo->sin_addr.s_addr = addr;
pAddrTo->sin_port = HTON2(port);
if (ERROR == sendto(sock, (sbyte *) pBuffer,
bufSize, 0,
(struct sockaddr *)pAddrTo,
sizeof(struct sockaddr)) )
{
wmFree(pAddrTo);
return wmosError(SYS_ERROR_SOCKET_GENERAL, "wmnetUdpSendTo: sendto failed");
}
wmFree(pAddrTo);
return OK;
}
STATUS wmnetUdpRcvFrom
(
OS_SOCKET_T sock,
ubyte4 * pAddrSender,
ubyte2 port,
sbyte * pBuffer,
ubyte4 bufSize,
sbyte4 * pBytesRead
)
{
struct sockaddr_in *pAddr;
int iAddrLen;
int RecvResult;
iAddrLen = sizeof(struct sockaddr_in);
if ( NULL == (pAddr = (struct sockaddr_in *) wmMalloc(iAddrLen)) )
return wmosError(ERROR_MEMMGR_NO_MEMORY, "no memory");
RecvResult = recvfrom(sock, pBuffer, kMaxUdpPacketSize,
0, (struct sockaddr *)pAddr, &iAddrLen );
if (ERROR == RecvResult)
{
wmFree(pAddr);
return wmosError(ERROR_GENERAL, "");
}
*pAddrSender = (ubyte4) pAddr->sin_addr.s_addr;
*pBytesRead = (ubyte4) RecvResult;
wmFree(pAddr);
return OK;
}
/*-----------------------------------------------------------------------*/
STATUS wmnetTcpAccept
(
OS_SOCKET_T * soc,
OS_SOCKET_T * accSoc,
ubyte2 port
)
{
struct sockaddr_in ClientAddr;
int iAddrLen;
iAddrLen = sizeof(ClientAddr);
memset(&ClientAddr, 0x00, iAddrLen);
*accSoc = accept(*soc, (struct sockaddr *)&ClientAddr, &iAddrLen);
#ifdef DEBUG_VERBOSE
posixLog("socket %d accepted++++++++++\n",*accSoc);
#endif
if (ERROR == *accSoc)
{
close(*accSoc);
close(*soc);
wmnetTcpServerOpen(soc, port);
return wmosError(SYS_ERROR_SOCKET_ACCEPT, "wmnetTcpAccept: no server");
}
return OK;
}
/*-----------------------------------------------------------------------*/
STATUS wmnetClientAddrGet
(
OS_SOCKET_T ClientSock,
ubyte4 * pAddr
)
{
struct sockaddr_in ClientAddr;
int iAddrLen;
*pAddr = 0;
iAddrLen = sizeof(ClientAddr);
memset(&ClientAddr, 0x00, iAddrLen);
if (OK != getpeername(ClientSock, (struct sockaddr *)&ClientAddr, &iAddrLen))
return wmosError(ERROR_GENERAL, "unable to get address from socket");
*pAddr = ntohl(ClientAddr.sin_addr.s_addr);
return OK;
}
STATUS wmnetSocketClose
(
OS_SOCKET_T sock
)
{
#ifdef DEBUG_VERBOSE
posixLog("socket %d closed----------\n",sock,0,0,0,0,0);
#endif
if (ERROR == close(sock))
return wmosError(ERROR_GENERAL_ACCESS_DENIED, "wmnetSocketClose");
return OK;
}
LOCAL STATUS connectToServer
(
OS_SOCKET_T sock,
sbyte * pName,
ubyte4 port
)
{
struct sockaddr_in RemAddr;
int err;
struct hostent * pHost;
memset(&RemAddr, 0x00, sizeof(RemAddr));
if (NULL == (pHost = gethostbyname(pName)))
return wmosError(ERROR_GENERAL,"remote host unknown");
RemAddr.sin_family = PF_INET;
RemAddr.sin_addr.s_addr = (unsigned int) pHost->h_addr;
RemAddr.sin_port = htons((ubyte2)port);
/* Create a Client connection */
err = connect( sock, (struct sockaddr *)&RemAddr, sizeof(RemAddr));
if ( ERROR == err )
return wmosError(ERROR_GENERAL_ACCESS_DENIED, NULL);
return OK;
}
STATUS wmnetTcpConnect
(
OS_SOCKET_T * pSoc,
sbyte * pName,
ubyte2 port
)
{
/* Create a stream socket */
if (OK != wmnetTcpSocketCreate(pSoc))
return ERROR;
if (OK != wmnetBindSockToAddr(*pSoc, ANY_PORT_K))
return ERROR;
/* Create a Client connection */
return connectToServer( *pSoc, pName, port );
}
STATUS wmnetTcpWrite
(
OS_SOCKET_T sock,
sbyte * pBuf,
ubyte4 bufLen
)
{
sbyte * pMsg;
if (ERROR != send(sock, pBuf, bufLen, 0))
return OK;
switch (errno)
{
case EBADF:
pMsg = "invalid file descriptor";
break;
case EINTR:
pMsg = "operation was interrupted by signal";
break;
case EINVAL:
pMsg = "tolen not valid size for specified address family";
break;
case EMSGSIZE:
pMsg = "socket requires message be sent atomically, "
"and the message was too long";
break;
case ENOMEM:
pMsg = "insufficient memory available";
break;
case ENOSR:
pMsg = "insufficient STREAMS resources";
break;
case ENOTSOCK:
pMsg = "not a socket";
break;
case EWOULDBLOCK:
pMsg = "socket is marked non-blocking and the "
"requested operation would block";
break;
default:
pMsg = "unknown send error";
break;
}
return wmosError(ERROR_GENERAL_ACCESS_DENIED, pMsg);
}
STATUS wmnetTcpRead
(
OS_SOCKET_T sock,
sbyte * pBuf,
ubyte4 BufSize,
ubyte4 * pBytesRead
)
{
ubyte4 bytes;
if (NULL != pBytesRead)
*pBytesRead = 0;
bytes = recv(sock, pBuf, BufSize, 0);
if (ERROR == bytes)
return wmosError(ERROR_GENERAL_ACCESS_DENIED, "wmnetTcpRead: denied");
if (NULL != pBytesRead)
*pBytesRead = bytes;
return OK;
}
/*******************************************************************************
*
* wmnetSocketBlocking - enable or disable socket blocking
*
* This function modifies the behavior of other socket functions. If socket
* blocking is enabled, calling wmosSocketRead or wmosSocketPeek will block until
* data is available. If socket blocking is disabled, these functions will return
* immediately.
*
* RETURNS: N/A
*
*/
STATUS wmnetSocketBlocking
(
OS_SOCKET_T sock, /* the socket */
BOOL block /* TRUE to enable socket blocking */
)
{
int iOpt;
iOpt = ! block;
if (ERROR == ioctl (sock, FIONBIO, (int) &iOpt))
return wmosError (SYS_ERROR_SOCKET_GENERAL,
"wmnetSocketBlocking: ioctl failed");
return OK;
}
/*******************************************************************************
*
* wmnetSocketPeek - peek into a socket
*
* This routine peeks into a socket without modifying the data waiting on it. As
* many as (*pBufSize) characters are read and copied onto pBuf. When no data is
* pending, the routine will block or return immediately depending on wether
* socket blocking is enable or not (see wmnetSocketBlocking()).
*
* RETURNS: The number of characters that have been copied to pBuf or one of
* these errors:
* SYS_ERROR_SOCKET_TIMEOUT
* SYS_ERROR_SOCKET_GENERAL
*
*/
STATUS wmnetTcpPeek
(
OS_SOCKET_T sock, /* the socket */
sbyte * pBuf, /* the buffer where data will be copied */
ubyte4 BufSize, /* buffer size */
ubyte4 * bytesRead /* return: number of bytes read */
)
{
ubyte4 bytes;
bytes = recv(sock, pBuf, BufSize, MSG_PEEK);
if (ERROR == bytes)
return wmosError(ERROR_GENERAL_ACCESS_DENIED, "wmnetTcpPeek: denied");
if (NULL != bytesRead)
*bytesRead = bytes;
return OK;
}
/*******************************************************************************
*
* wmnetSocketGroupWait - wait on a set of sockets and/or pipes
*
* This routine blocks until there is some activity (data available for
* reading or socket/pipe is closed) on the set of monitored sockets.
*
* setOfSockets is the list of sockets/pipes to wait on and it can be modified
* using the functions wmnetSocketGroupAddTo, wmnetSocketGroupAddPipe and
* wmnetSocketGroupClear.
*
* When the function returns, wmnet[Socket/Pipe]WantsAction could be used to
* determine which of the monitored sockets.pipes was active.
*
* timeoutInSecs can be set to 0 to indicate no timeout (i.e. infinite wait)
*
* RETURNS: The number of characters that have been copied to pBuf or one of
* these errors:
* SYS_ERROR_SOCKET_TIMEOUT
* SYS_ERROR_SOCKET_GENERAL
*
*/
STATUS wmnetSocketGroupWait
(
OS_FDSET_T * setOfSockets,
ubyte4 timeoutInSecs
)
{
int r;
struct timeval tv;
tv.tv_sec = timeoutInSecs;
tv.tv_usec = 0;
assert ((0 < setOfSockets->fdMax) && (64 > setOfSockets->fdMax));
r = select (setOfSockets->fdMax + 1, &setOfSockets->fdSet, NULL, NULL, &tv);
if (0 > r)
return wmosError(SYS_ERROR_SOCKET_GENERAL, "wmnetSocketGroupWait: error");
if (0 == r)
return wmosError(ERROR_GENERAL_TIMEOUT, "wmnetSocketGroupWait: timeout");
return OK;
}
STATUS wmnetSocketGroupAddTo
(
OS_SOCKET_T sock,
OS_FDSET_T * setOfSockets
)
{
FD_SET(sock, &setOfSockets->fdSet);
if (sock > setOfSockets->fdMax)
setOfSockets->fdMax = sock;
return OK;
}
STATUS wmnetSocketGroupAddPipe
(
OS_PIPE_T pipe,
OS_FDSET_T * setOfSockets
)
{
return wmnetSocketGroupAddTo ((OS_SOCKET_T) pipe,setOfSockets);
}
STATUS wmnetSocketGroupClear
(
OS_FDSET_T * setOfSockets
)
{
FD_ZERO(&setOfSockets->fdSet);
setOfSockets->fdMax = 0;
return OK;
}
BOOL wmnetSocketWantsAction
(
OS_SOCKET_T sock,
OS_FDSET_T * setOfSockets
)
{
return FD_ISSET(sock, &setOfSockets->fdSet);
}
BOOL wmnetPipeWantsAction
(
OS_PIPE_T pipe,
OS_FDSET_T * setOfSockets
)
{
return wmnetSocketWantsAction((OS_SOCKET_T) pipe, setOfSockets);
}
/*******************************************************************************
*
* wmnetSocketPrintf - output a formatted string to a socket
*
* This sends a formatted string to the connection socket.
* It is identical to printf() in terms of the
* usage of parameters and format strings.
*
* INTERNAL: Note that vfdprintf is not ANSI, and that the function is not
* portable because it assumes that a socket is a file descriptor, which is not
* true in some OSes.
*
* RETURNS: OK or ERROR.
*/
STATUS wmnetSocketPrintf
(
OS_SOCKET_T sock,
sbyte * szFormat,
...
)
{
#if 0
int size;
int copy;
FILE * file;
if (0 > (copy = dup(sock)))
return wmError(ERROR_GENERAL, "wmnetSocketPrintf: can't dupe socket");
if (NULL == (file = fdopen(copy, "w")))
return wmError(ERROR_GENERAL, "wmnetSocketPrintf: can't open socket file");
size = 0;
va_list vaList;
va_start (vaList, szFormat);
if (0 > (size += vfprintf (file, szFormat, vaList)))
{
#ifdef DEBUG_VERBOSE
/* produce verbose output */
printf ("SOCKET PRINTF: ");
vprintf (szFormat, vaList);
printf ("\n");
#endif
va_end (vaList);
}
else
{
va_end (vaList);
wmosError(ERROR_GENERAL, "wmnetSocketPrintf failed");
size = -1;
}
fclose(file);
return size;
#endif
return 0;
}
/*******************************************************************************
*
* wmnetSockPrintf - print a formatted string on a socket
*
* All parameters identical to vfprintf, except for the first which identifies
* a socket instead of a file. ANSI requires that call to vfprintf should be
* preceded by a call to va_start, and followed by a call to va_end. The same
* applies to this function.
*
* SPECIFIC TO THIS PORT:
* Formatted output cannot be sent to a socket under Windows (fprintf does
* not work on sockets) and a temporary buffer needs to be allocated. If the
* size of the message is larger than PRINTF_BUFFER some data will be lost.
*
* RETURNS: OK or an error
* The number of characters sent to the socket (by reference)
*
*/
STATUS wmnetSocketVprintf
(
OS_SOCKET_T sock,
sbyte * szFormat,
va_list args,
ubyte4 * pBytesPrinted
)
{
enum {PRINTF_BUFFER = 1000 };
sbyte tmpBuffer[PRINTF_BUFFER];
* pBytesPrinted = 0;
(* pBytesPrinted) = vsprintf (tmpBuffer, szFormat, args);
wmnetTcpWrite(sock, tmpBuffer, strlen(tmpBuffer));
return OK;
}
/*******************************************************************************
*
* wmnetStdoutToSocket - redirect STDIO to a socket
*
* This routine redirects current STDIO to the socket. An OS specific value
* needed to restore the Stdout is returned by reference in the second parameter.
*
*
* RETURNS: 'OK' or an error
*/
STATUS wmnetStdoutToSocket
(
OS_SOCKET_T sock,
sbyte4 * pOldStdout
)
{
return OK;
}
#endif /*__SOLARIS_OS__*/
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,438 @@
/* wmos.c - os isolation functions */
/*
* Copyright (c) 2003-2008, 2010-2012 Wind River Systems, Inc.
*
* The right to copy, distribute, modify or otherwise make use
* of this software may be licensed only pursuant to the terms
* of an applicable Wind River license agreement.
*/
/*
modification history
--------------------
01h,17sep12,r_w correct for thread priority.
Defect: WIND00375444
01g,07jan11,m_z correct compiling error on linux
CQID: Fix WIND00249657
01f,31mar10,m_z correct 32bit error
01e,29jan10,m_z VxWorks 64-bit support
(WIND00193649)
01d,28aug08,q_z fix for mud tasks spawned with option (WIND00130158)
01c,15jan04,gsr added mutex semaphore support
01b,02jan04,jws start componentization (COMMON_IS_COMPONENT)
01a,24sep03,jws modification history added
fix compiler warnings, SPR 90843
*/
/*
DESCRIPTION
This module contains interface routines for the Wind Manage Backplane.
*/
/* includes */
#ifndef COMMON_IS_COMPONENT
#include "wm_options.h"
#else
#define kHwTicksPerSecond sysClkRateGet()
#endif
#include "wrn/wm/common/wm.h"
#ifdef __VXWORKS_OS__
#include "sysLib.h"
#endif
#ifdef __SOLARIS_OS__
#include "semLib.h"
#include "taskLib.h"
#endif
/* defines */
#define DREF(x) (NULL == x) ? 0 : *((int *) x)
#undef __DEBUG_THREADS__
#ifdef __DEBUG_THREADS__
#define DEBUG_THREAD_M(fn, msg, data) \
printf("%20s: tid = 0x%x %-8s ptr = 0x%lx data = 0x%lx\n", \
fn, taskIdSelf(), msg, data, DREF(data));
#else
#define DEBUG_THREAD_M(fn, msg, data)
#endif
/* globals */
/* locals */
/**************************************************************************
*
* wmosInit - constructor of the OSAL layer
*
* RETURNS: none
*/
void wmosInit(void)
{
#if 0
#ifdef __BSD_OS__
osalInit();
#endif
#endif
}
/**************************************************************************
*
* wmosFini - destructor of the OSAL layer
*
* RETURNS: none
*/
void wmosFini(void)
{
#if 0
#ifdef __BSD_OS__
osalFini();
#endif
#endif
}
/**************************************************************************
*
* wmosSemBinaryCreate - create binary semaphore
*
* RETURNS: 'OK', or ERROR
*/
STATUS wmosSemBinaryCreate
(
OS_SEM_T *pSem,
OS_SEM_OPTIONS_T opt
)
{
if (NULL == pSem)
return wmError(ERROR_GENERAL_NULL_POINTER, "null pointer");
*pSem = semBCreate(opt, SEM_EMPTY);
return OK;
}
/**************************************************************************
*
* wmosSemMCreate - create mutex semaphore
*
* RETURNS: 'OK', or ERROR
*/
STATUS wmosSemMCreate
(
OS_SEM_T *pSem,
OS_SEM_OPTIONS_T opt
)
{
if (NULL == pSem)
return wmError(ERROR_GENERAL_NULL_POINTER, "null pointer");
*pSem = semMCreate(opt);
return OK;
}
/**************************************************************************
*
* wmosSemBinaryTake - why does this dupe wmosSemTake
*
* RETURNS: 'OK', or ERROR
*/
STATUS wmosSemBinaryTake
(
OS_SEM_T sem,
ubyte4 timeout
)
{
return semTake (sem, timeout);
}
/**************************************************************************
*
* wmosSemCreate - create a counting semaphore
*
* RETURNS: 'OK', or ERROR_GENERAL if creation failed failed
*/
STATUS wmosSemCreate
(
OS_SEM_T * pSem,
sbyte4 count,
OS_SEM_OPTIONS_T opt
)
{
switch (opt)
{
case SEM_TYPICAL_K:
*pSem = semCCreate (SEM_Q_FIFO, count);
if (NULL == *pSem)
return wmosError (ERROR_GENERAL,"Failed to create semaphr");
break;
case SEM_SHARED_MEM_K:
#ifdef WMOS_INCLUDE_SHARED_MEM_OBJS
*pSem = semCSmCreate (SEM_Q_FIFO, count);
if (NULL == *pSem)
return wmosError(ERROR_GENERAL,"Failed to create semaphore");
#else
return wmosError (ERROR_GENERAL,"Shared mem objs not included");
#endif
break;
default:
return wmosError (ERROR_GENERAL_ILLEGAL_VALUE,"unknown shared mem error");
}
return OK;
}
/**************************************************************************
*
* wmosSemDestroy - destroy an existing semaphore
*
* RETURNS: 'OK', or ERROR_GENERAL_ILLEGAL_VALUE the parameter was not an
* valid semaphore
*/
STATUS wmosSemDestroy
(
OS_SEM_T sem
)
{
if (ERROR == semDelete (sem))
return wmosError(ERROR_GENERAL_ILLEGAL_VALUE,"");
return OK;
}
/**************************************************************************
*
* wmosSemTake - take a semaphore
*
* This function decrements the count of an existing semaphore. When the
* count reaches zero, the function blocks until another thread gives
* the semaphore or it is destroyed.
*
* RETURNS: 'OK'
*/
STATUS wmosSemTake
(
OS_SEM_T sem,
ubyte4 timeout
)
{
return semTake(sem, timeout);
}
/**************************************************************************
*
* wmosSemGive - give a semaphore
*
* This function increments the count of an existing semaphore and unblocks
* any thread that may be waiting on it.
*
* RETURNS: 'OK'
*/
STATUS wmosSemGive
(
OS_SEM_T sem
)
{
return semGive(sem);
}
/**************************************************************************
*
* wmosSemFlush - unblock all tasks waiting for this semaphore
*
* This function unblocks all the tasks that may be waiting on semaphore
* 'sem', but the state (count) of the semaphore remains unmodified.
*
* RETURNS: 'OK'
*/
STATUS wmosSemFlush
(
OS_SEM_T sem
)
{
return semFlush(sem);
}
/**************************************************************************
*
* wmosYield - yield processor time
*
* This function will block only if other threads <with the same priority>
* are ready to run.
*
* RETURNS: N/A
*/
void wmosYield
(
void
)
{
taskDelay(NO_WAIT_K); /* yield the processor */
}
/**************************************************************************
*
* wmosTimeSleep - sleep for x milliseconds
*
* This function will block for 'mSecs' milliseconds.
*
* RETURNS: N/A
*/
void wmosTimeSleep
(
ubyte4 mSecs
)
{
int ticks = (int)((int)mSecs * kHwTicksPerSecond ) / 1000;
taskDelay(ticks);
}
/**************************************************************************
*
* wmosThreadCreate - spawn a new thread
*
* This function spawns a new thread from function 'pHandlerFcn'. A name
* 'pTaskName' may be given to the thread, otherwise this parameter may be NULL.
* 'priority' should be between 0 and 255, with the lower number signifying
* higher priority. The thread 'stackSize' should be given in bytes.
*
*
* RETURNS: 'OK', or ERROR_GENERAL_CREATE_TASK if thread creation failed
* 'pTid', the value of the thread identifier is returned by reference
*/
STATUS wmosThreadCreate
(
VOIDFUNCPTR pHandlerFcn,
sbyte * pTaskName,
void * pArg,
sbyte4 priority,
#ifndef _WRS_CONFIG_LP64
ubyte4 stackSize,
#else
ubyte8 stackSize,
#endif
OS_THREAD_T * pTid
)
{
OS_THREAD_T tid;
if (0 == stackSize)
stackSize = DEFAULT_THREAD_STACK_SIZE_K;
DEBUG_MSG_2("!!!! wmosThreadCreate: %s stacksize: %d\n",
NULL == pTaskName ? "(none)" : pTaskName, stackSize);
if ((0 >= priority) || (255 < priority))
priority = DEFAULT_THREAD_PRIORITY_K;
DEBUG_MSG_2("wmosThreadCreate: priority: %d arg ptr: 0x%x\n", priority, (int) pArg);
tid = taskSpawn (pTaskName, priority, kWmosThreadCreateOptions, stackSize, (FUNCPTR) pHandlerFcn,
(OS_ARG_T) pArg,0,0,0,0,0,0,0,0,0 );
#ifndef _WRS_CONFIG_LP64
if (ERROR == (STATUS) tid)
#else
if (TASK_ID_ERROR == tid)
#endif
{
wmosThreadCreateError();
return wmosError(ERROR_GENERAL_CREATE_TASK,"wmosThreadCreate: creation failed");
}
if (NULL != pTid)
*pTid = tid;
return OK;
}
/**************************************************************************
*
* wmosThreadKill - kill a thread
*
* This function kills an existing thread. The parameter 'tid' should be
* the one returned by wmosThreadCreate when the thread was created.
*
* RETURNS: 'OK', or ERROR_GENERAL if thread creation failed
*/
STATUS wmosThreadKill
(
OS_THREAD_T tid
)
{
if (ERROR == taskDelete(tid))
return wmosError(ERROR_GENERAL,"");
return OK;
}
/**************************************************************************
*
* wmosThreadSuspend - suspend a thread
*
* This function suspends an existing thread. The parameter 'tid' should be
* the one returned by wmosThreadCreate when the thread was created.
*
* RETURNS: 'OK', or ERROR if failed
*/
STATUS wmosThreadSuspend
(
OS_THREAD_T tid
)
{
if (ERROR == taskSuspend(tid))
return wmosError(ERROR_GENERAL,"");
return OK;
}
/**************************************************************************
*
* wmosThreadResume - resume a thread
*
* This function resumes an existing thread. The parameter 'tid' should be
* the one returned by wmosThreadCreate when the thread was created.
*
* RETURNS: 'OK', or ERROR if failed
*/
STATUS wmosThreadResume
(
OS_THREAD_T tid
)
{
if (ERROR == taskResume(tid))
return wmosError(ERROR_GENERAL,"");
return OK;
}
@@ -0,0 +1,783 @@
/* wmosVxWorks.c - Implementation in VxWorks of the Rapid Control OS AL */
/* Copyright 2004-2008, 2010 Wind River Systems, Inc. */
/*
modification history
--------------------
03c,07jan11,m_z correct compiling error on linux
CQID: Fix WIND00249657
03b,28jul10,m_z eliminate compile warning
03a,19jul10,h_y modified for WIND00223629
02l,09jul10,m_z remove compile warning
02k,07may10,m_z eliminate compile warning
02j,31mar10,m_z correct 32bit error
02i,29jan10,m_z VxWorks 64-bit support
(WIND00193649)
02k,28oct08,m_z change value cast to eliminate build warning
(WIND00139452)
01e,11oct07,ten For SMP use thread local storage (fomr tlsLib) rather than
task variables
01d,07mar07,ps fixes for RTP builds. defect WIND00044864
01c,17may06,ps add some vxWorks include files. CQ WIND000044862
01b,13jan04,gsr added pipeDelete routine for SPR 93009
01a,02jan04,jws add modification history
start componentization (COMMON_IS_COMPONENT)
*/
/*
DESCRIPTION
This module implements all the functions defined in wmos.h for the VxWorks OS
*/
#ifndef COMMON_IS_COMPONENT
#include "wm_options.h"
#else
#define kHwTicksPerSecond sysClkRateGet()
#undef RCB_SYSLOG_HOST_K /* appears only in this file !! */
/*
* There is an inclusion order problem with wm.h that forces us
* to define __VXWORKS_OS__ here. This must be looked at.
*/
#define __VXWORKS_OS__
#endif
#if defined(__VXWORKS_OS__) || defined(__VXWORKS_AE_OS__)
#include <vxWorks.h>
#include <tickLib.h>
#include <sysLib.h>
#include <pipeDrv.h>
#include <ioLib.h>
#include <errnoLib.h>
#include <stdlib.h>
#ifdef _WRS_KERNEL
#include <usrConfig.h>
#include <smObjLib.h>
#ifdef _WRS_VX_SMP
#include <tlsLib.h>
#endif
#else
#include <sys/fcntlcom.h>
#endif
#include "wm.h"
#define LONGEST_PIPE_NAME_K 128
#ifdef _WRS_VX_SMP
__thread long taskData;
#else
long taskData;
#endif
#ifdef _WRS_KERNEL
extern int errnoGet (void);
#endif
/**************************************************************************
*
* wmosMalloc - allocate memory
*
* uses native os management to allocate a block of memory.
*
* RETURNS: Pointer to memory allocated, or NULL if it failed.
*/
void * wmosMalloc
(
#ifndef _WRS_CONFIG_LP64
ubyte4 memSize
#else
ubyte8 memSize
#endif
)
{
char * pMem = NULL;
if ( memSize )
pMem = malloc( memSize );
#ifdef __ENABLE_MEMMGR_DEBUG__
printf("Malloc(%ld) %08lx\n", (ulong_t)memSize, (ulong_t)pMem);
#endif
return (void *)pMem;
}
/**************************************************************************
*
* wmosCalloc - allocate memory
*
* uses native os management to allocate a block of memory.
*
* RETURNS: Pointer to memory allocated, or NULL if it failed.
*/
void * wmosCalloc
(
#ifndef _WRS_CONFIG_LP64
ubyte4 elemCount,
ubyte4 elemSize
#else
ubyte8 elemCount,
ubyte8 elemSize
#endif
)
{
char * pMem = NULL;
/* Verify the allocation sizes are not zero */
if ( elemCount && elemSize )
pMem = calloc(elemCount, elemSize);
#ifdef __ENABLE_MEMMGR_DEBUG__
printf("Calloc(%ld) %08lx\n", (ulong_t)(elemCount * elemSize), (ulong_t)pMem);
#endif
return (void *)pMem;
}
/**************************************************************************
*
* wmosFree - free allocated memory
*
* frees memory allocated using native os management.
*
* RETURNS: N/A
*/
void wmosFree
(
void * pBuffer
)
{
if ( pBuffer )
free(pBuffer);
#ifdef __ENABLE_MEMMGR_DEBUG__
printf("Free(%08lx)\n", (ulong_t)pBuffer);
#endif
}
/**************************************************************************
*
* wmosTimeGet - get system time since 12:00 a.m. 1/1/1970
*
* RETURNS: time
*/
#ifndef _WRS_CONFIG_LP64
ubyte4 wmosTimeGet (void)
{
return (ubyte4)(tickGet() / kHwTicksPerSecond);
}
#else
ubyte8 wmosTimeGet (void)
{
return (ubyte8)(tickGet() / kHwTicksPerSecond);
}
#endif
/**************************************************************************
*
* wmosClock - get microseconds since starting
*
* RETURNS: microseconds
*/
OS_CLOCK_T wmosClock
(
void
)
{
return (clock()/CLOCKS_PER_SEC)*1000000;
}
/**************************************************************************
*
* wmosError - report an error
*
* This function should be called everytime an error is to be returned to a
* calling function. Instead of:
* \cs
* return ERROR_GENERAL
* \ce
* the following call should be used:
* \cs
* return wmosError(ERROR_GENERAL, "oops, did you forget to bring the money?");
* \ce
*
* Doing this provides a common execution path to all the errors,
* which allows trapping errors before they propagate up the call tree.
*
* RETURNS: 'OK', or ERROR_GENERAL if initialization failed
*/
STATUS wmosError
(
sbyte4 error,
sbyte * pMsg
)
{
#ifdef RCB_SYSLOG_HOST_K
char buffer[128];
#endif
#ifdef _WRS_KERNEL
logMsg ("Error =%d\t[%s] errno:%d\n", error, (long) pMsg, errnoGet(),0,0,0);
#endif
#ifdef RCB_SYSLOG_HOST_K
sprintf(buffer, "WM Error %d: %s\n", error, pMsg);
rcbLogSyslog(buffer);
#endif
return error;
}
/**************************************************************************
*
* wmosThreadCreateError - handle error returned by create thread
*
*
* RETURNS: none
*/
void wmosThreadCreateError(void)
{
switch (errno)
{
#ifdef _WRS_KERNEL
case S_intLib_NOT_ISR_CALLABLE:
DEBUG_MSG_0("wmosThreadCreateError: not callable\n");
break;
#endif
case S_objLib_OBJ_ID_ERROR:
DEBUG_MSG_0("wmosThreadCreateError: invalid obj id\n");
break;
#ifdef _WRS_KERNEL
case S_smObjLib_NOT_INITIALIZED:
DEBUG_MSG_0("wmosThreadCreateError: not initialized\n");
break;
case S_memLib_NOT_ENOUGH_MEMORY:
DEBUG_MSG_0("wmosThreadCreateError: not enough memory\n");
break;
case S_memLib_BLOCK_ERROR:
DEBUG_MSG_0("wmosThreadCreateError: blocking error\n");
break;
#endif
#ifdef SOMEONE_KNOWS_WHERE_S_pdLib_PRIORITY_NOT_WITHIN_PD_RANGE_IS_DEFINED
case S_pdLib_PRIORITY_NOT_WITHIN_PD_RANGE:
break;
#endif /* !! someone deal with this !! */
}
}
/**************************************************************************
*
* wmosNamedPipeCreate - create a named pipe
*
* 'pName' should be an alphanumeric string, without any special
* characters such as \/ or . (each port will build a valid pipe name based
* on the given 'pName'. The parameters 'maxMsgs' and 'msgSize' will determine
* the memory requirements for the pipe. The latter is expressed in bytes.
*
* RETURNS: 'OK', or ERROR_GENERAL if creation failed
*/
STATUS wmosNamedPipeCreate
(
sbyte * pName,
ubyte4 maxMsgs,
#ifndef _WRS_CONFIG_LP64
ubyte4 msgSize
#else
ubyte8 msgSize
#endif
)
{
sbyte pipeName[LONGEST_PIPE_NAME_K];
ubyte2 bufSize = LONGEST_PIPE_NAME_K;
STATUS errVal;
#ifdef OS_PIPE_PREFIX_K
strncpy(pipeName, OS_PIPE_PREFIX_K, bufSize);
bufSize = (ubyte2)(bufSize - (ubyte2)strlen(pipeName));
#else
#error OS_PIPE_PREFIX_K is not defined !!
#endif
strncat(pipeName, pName, bufSize);
errVal = pipeDevCreate (pipeName, maxMsgs, msgSize);
if (OK != errVal)
return wmosError(ERROR_GENERAL, "Invalid pipe");
return OK;
}
/**************************************************************************
*
* wmosNamedPipeDelete - delete a named pipe
*
* 'pName' should be an alphanumeric string, without any special
* characters such as \/ or . (each port will build a valid pipe name based
* on the given 'pName'.
*
* RETURNS: 'OK', or ERROR_GENERAL if deletion failed
*/
STATUS wmosNamedPipeDelete
(
sbyte * pName
)
{
sbyte pipeName[LONGEST_PIPE_NAME_K];
ubyte2 bufSize = LONGEST_PIPE_NAME_K;
STATUS errVal;
#ifdef OS_PIPE_PREFIX_K
strncpy(pipeName, OS_PIPE_PREFIX_K, bufSize);
bufSize = (ubyte2)(bufSize - (ubyte2)strlen(pipeName));
#else
#error OS_PIPE_PREFIX_K is not defined !!
#endif
strncat(pipeName, pName, bufSize);
errVal = pipeDevDelete (pipeName, FALSE);
if (OK != errVal)
return wmosError(ERROR_GENERAL, "pipe delete failed");
return OK;
}
/**************************************************************************
*
* wmosNamedPipeOpen - connect to an existing named pipe
*
* After a pipe has been created with wmosNamedPipeCreate, it can be opened
* with this command. The supported 'mode's are 'OS_PIPE_IN' (reading),
* 'OS_PIPE_OUT' (writing) and 'OS_PIPE_BOTH' (read/write).
*
* RETURNS: 'OK', ERROR_GENERAL_ILLEGAL_VALUE if an unrecognized 'mode' is
* passed or ERROR_GENERAL for any other error.
* 'pPipe' points to the pipe identifier (by reference)
*
*/
STATUS wmosNamedPipeOpen
(
sbyte * pName,
OS_PIPE_MODE_T mode,
BOOL noBlock,
OS_PIPE_T * pPipe
)
{
sbyte4 flags;
sbyte pipeName[LONGEST_PIPE_NAME_K];
ubyte2 bufSize = LONGEST_PIPE_NAME_K;
#ifdef OS_PIPE_PREFIX_K
strncpy(pipeName, OS_PIPE_PREFIX_K, bufSize);
bufSize = (ubyte2)(bufSize - (ubyte2)strlen(pipeName));
#endif
strncat(pipeName, pName, bufSize);
switch (mode)
{
case OS_PIPE_IN:
flags = O_RDONLY;
break;
case OS_PIPE_OUT:
flags = O_WRONLY;
break;
case OS_PIPE_BOTH:
flags = O_RDWR;
break;
default:
return wmosError(ERROR_GENERAL_ILLEGAL_VALUE, "invalid pipe mode");
}
(*pPipe) = open(pipeName, flags, 0);
if ( -1 == (*pPipe))
return wmosError(ERROR_GENERAL, "failed to open pipe");
return OK;
}
/**************************************************************************
*
* wmosNamedPipeWrite - write to an open pipe
*
*
* RETURNS: 'OK', ERROR_GENERAL if the writing is unsuccesful
*
*/
STATUS wmosNamedPipeWrite
(
OS_PIPE_T pipe,
sbyte * buffer,
#ifndef _WRS_CONFIG_LP64
ubyte4 bufSize,
ubyte4 * bytesWritten
#else
ubyte8 bufSize,
ubyte8* bytesWritten
#endif
)
{
#ifndef _WRS_CONFIG_LP64
sbyte4 errVal;
#else
sbyte8 errVal;
#endif
errVal = write(pipe, buffer, bufSize);
#ifndef _WRS_CONFIG_LP64
if (errVal != bufSize)
#else
if ((ubyte8)errVal != bufSize)
#endif
return wmosError(ERROR_GENERAL, "pipe write failed");
return OK;
}
/**************************************************************************
*
* wmosNamedPipeRead - read from a named pipe
*
*
* RETURNS: 'OK', or ERROR_GENERAL if initialization failed
*/
STATUS wmosNamedPipeRead
(
OS_PIPE_T pipe,
sbyte * pBuffer,
#ifndef _WRS_CONFIG_LP64
ubyte4 bufSize,
ubyte4 * pBytesRead
#else
ubyte8 bufSize,
ubyte8* pBytesRead
#endif
)
{
#ifndef _WRS_CONFIG_LP64
sbyte4 bytesRead;
#else
sbyte8 bytesRead;
#endif
bytesRead = read(pipe, pBuffer, bufSize);
if (ERROR == bytesRead)
return wmosError(ERROR_GENERAL, "pipe read failed");
if (NULL != pBytesRead)
#ifndef _WRS_CONFIG_LP64
*pBytesRead = (ubyte4) bytesRead;
#else
*pBytesRead = (ubyte8) bytesRead;
#endif
return OK;
}
/**************************************************************************
*
* wmosNamedPipeClose - close a named pipe
*
* RETURNS: 'OK', or ERROR_GENERAL if initialization failed
*/
STATUS wmosNamedPipeClose
(
OS_PIPE_T pipe
)
{
sbyte4 errVal;
errVal = close(pipe);
if (-1 == errVal)
return wmosError(ERROR_GENERAL, "pipe close failed");
return OK;
}
#ifdef _WRS_KERNEL /* functions not available in RTP */
/**************************************************************************
*
* wmosThreadDataInit - prepare to save pointers with thread local storage
*
* Each thread must be call for init
*
* RETURNS: 'OK', or ERROR_GENERAL if initialization failed
*
* NOMANUAL
*/
STATUS wmosThreadDataInit
(
void
)
{
#ifndef _WRS_VX_SMP
/* UP version uses task variables */
#ifndef _WRS_CONFIG_LP64
taskVarAdd(taskIdSelf(), (int *)&taskData);
#endif
#else
/* SMP version uses thread local storage */
/*
* Init: Any reference to the variable will cause per-task
* storage to be allocated
*/
taskData = (long)NULL;
#endif
return OK;
}
/**************************************************************************
*
* wmosThreadDataGet - get pointer saved with thread local storage
*
* RETURNS: 'OK', or ERROR_GENERAL if no pointer or not initialized
*
* NOMANUAL
*/
STATUS wmosThreadDataGet
(
void ** ppData
)
{
/* Retrieve a data pointer for the current thread */
*ppData = (void *) taskData;
return OK;
}
/**************************************************************************
*
* wmosThreadDataSet - save pointer with thread local storage
*
* RETURNS: 'OK'
*
* NOMANUAL
*/
STATUS wmosThreadDataSet
(
void ** ppData
)
{
taskData = (long) *ppData;
return OK;
}
/**************************************************************************
*
* wmosThreadDataExit - frees resources used for thread local storage
*
* RETURNS: 'OK'
*
* NOMANUAL
*/
STATUS wmosThreadDataExit
(
void
)
{
return OK;
}
#endif /* #ifdef _WRS_KERNEL */
/**************************************************************************
*
* wmosQueueCreate - create a message queue
*
* RETURNS: 'OK'
*/
STATUS wmosQueueCreate
(
#ifndef _WRS_CONFIG_LP64
ubyte4 maxMsgs,
ubyte4 msgSize,
#else
ubyte8 maxMsgs,
ubyte8 msgSize,
#endif
sbyte4 flags,
OS_MSGQ_T * pQID
)
{
*pQID = msgQCreate (maxMsgs, msgSize, flags);
if (0 == *pQID)
return wmosError (ERROR, "wmosQueueCreate: queue creation failed");
return OK;
}
/**************************************************************************
*
* wmosQueueDelete - delete a message queue
*
* RETURNS: 'OK'
*/
STATUS wmosQueueDelete
(
OS_MSGQ_T qID
)
{
return msgQDelete (qID);
}
/**************************************************************************
*
* wmosQueueReceive - receive data from a message queue
*
* RETURNS: 'OK'
*/
STATUS wmosQueueReceive
(
OS_MSGQ_T qID,
sbyte * pBuffer,
#ifndef _WRS_CONFIG_LP64
ubyte4 buffSize,
ubyte4 timeout,
sbyte4 * pBytesReceived
#else
ubyte8 buffSize,
ubyte4 timeout,
sbyte8 * pBytesReceived
#endif
)
{
*pBytesReceived = msgQReceive (qID, pBuffer, buffSize, timeout);
#ifndef _WRS_CONFIG_LP64
return (ERROR == *pBytesReceived) ? (STATUS)ERROR : OK;
#else
return ((sbyte8)ERROR == *pBytesReceived) ? (STATUS)ERROR : OK;
#endif
}
/**************************************************************************
*
* wmosQueueSend - send data to a message queue
*
* RETURNS: 'OK'
*/
STATUS wmosQueueSend
(
OS_MSGQ_T qID,
sbyte * pMsg,
#ifndef _WRS_CONFIG_LP64
ubyte4 msgSize,
#else
ubyte8 msgSize,
#endif
ubyte4 timeout,
sbyte4 priority
)
{
return msgQSend (qID, pMsg, msgSize, timeout, priority);
}
#ifdef __ENABLE_SHARED_MEMORY__
/**************************************************************************
*
* wmosSharedMemAttach - attach to previously created shared memory
*
* RETURNS: N/A
*/
STATUS wmosSharedMemoryAttach
(
OS_MEM_SHARE_T * pMemory
)
{
sbyte * pMsg;
if (NULL == pMemory)
return wmError(ERROR, "wmosSharedMemConnect: null ID ptr");
pMemory->pData = sdAttach(pdSelf(), pMemory->id, 0);
pMemory->pool = pMemory->pData;
DEBUG_MSG_0("wmosSharedMemoryAttach: done\n");
return OK;
}
/**************************************************************************
*
* wmosSharedMemCreate - allocated shared memory
*
* frees memory allocated using native os management.
*
* RETURNS: N/A
*/
STATUS wmosSharedMemoryCreate
(
sbyte * pName,
#ifndef _WRS_CONFIG_LP64
sbyte4 size,
#else
sbyte8 size,
#endif
OS_MEM_SHARE_T * pMemory
)
{
pMemory->id = sdCreate(pName, size, 0, NULL, NULL, NULL);
pMemory->size = size;
return OK;
}
STATUS wmosSharedMemoryDestroy
(
OS_MEM_SHARE_T * pMemory
)
{
return sdDetach(pdSelf(), pMemory->id, 0);
}
#endif /* __ENABLE_SHARED_MEMORY__ */
#endif /* __VXWORKS_OS__ */
@@ -0,0 +1,42 @@
common/port/wmnet/wmnetVxWorks.c
common/port/wmos/wmos.c
common/port/wmos/wmosVxWorks.c
common/memPoolLib.c
common/mudLib.c
common/mudUtils.c
common/wmAccessLib.c
common/wmAuth.c
common/wmBufferLib.c
common/wmCompareLib.c
common/wmConvertLib.c
common/wmFileLib.c
common/wmHashLib.c
common/wmLib.c
common/wmLinkListLib.c
common/wmLogLib.c
common/wmMD5.c
common/wmMemBlockLib.c
common/wmNonce.c
common/wmOidLib.c
common/wmInstanceLib.c
common/wmStdLib.c
common/wmUserLib.c
common/wmXmlParser.c
backplane/wmbBackplaneLib.c
backplane/wmbComponentLib.c
backplane/wmbDBLib.c
backplane/wmbEventLib.c
backplane/wmbLib.c
backplane/wmbObjectLib.c
backplane/wmbSessionLib.c
backplane/wmbSystem.c
backplane/wmbTableLib.c
backplane/wmbTransactionCore.c
backplane/wmbTransactionLib.c
backplane/wmbLockMgrCore.c
backplane/wmbLockMgrLib.c
backplane/wmbPortfolioLib.c
backplane/wmbPortfolioRemote.c
backplane/wmbSNMPLib.c
backplane/wmbDataLib.c
backplane/wmbCommonHandlers.c
@@ -0,0 +1,536 @@
/* wmAccessLib.c - user access control library */
/*
* Copyright (c) 2001-2010, 2012 Wind River Systems, Inc.
*
* The right to copy, distribute, modify or otherwise make use
* of this software may be licensed only pursuant to the terms
* of an applicable Wind River license agreement.
*/
/*
modification history
--------------------
01k,17may12,h_l replace NO_STRING with NULL_STRING (WIND00032212)
01j,18nov10,m_z add option filter for access level convertion
CQID: Fix WIND00242096
01i,28apr10,m_z eliminate compile warning
01h,19jan10,m_z VxWorks 64-bit support
(WIND00193649)
01g,24feb07,msa Correct the apigen comments so they match the actual routines
and correct any apigen errors that may occur.
01f,13sep04,dkg added new API's to set & get user access level to support
JavaScript Authentication feature
01e,12jul04,gsr access level does not print in user show SPR 84874
01d,02jan04,jws start componentization (COMMON_IS_COMPONENT)
01c,24sep03,jws fix compile warnings, SPR 90843
01a,01aug01,pns written
01b,09oct01,rws modified comments
*/
/*
DESCRIPTION
This module implements access control support for WindManage
INCLUDE FILES: wm.h 'wmb.h'
*/
/* includes */
#include "wrn/wm/common/wm.h"
#include <string.h>
#ifdef COMMON_IS_COMPONENT
#define __RLI_ACCESS_LEVEL_SHIFT__ 0
#endif
#undef __RLI_DEBUG_ACCESS__ /* local macro */
LOCAL ubyte4 systemAccessLevel = ACCESS_LEVEL_MASK_K;
LOCAL ubyte4 systemAccessGroups = ACCESS_GROUP_MASK_K;
LOCAL DTTypeInfo * pAccessInfo = NULL;
#ifdef __ENABLE_LAN_IP_FILTER__
/*-----------------------------------------------------------------------*/
extern BOOL RLI_CUSTOM_DYNAMIC_IP_FILTER_ENABLED();
extern BOOL RLI_CUSTOM_DYNAMIC_IP_CHECK(ubyte4 ClientIpAddr, ubyte4 FutureParam1, ubyte4 FutureParam2);
/**************************************************************************
*
* accessIpValid - IP address validation function.
*
* This routine checks the IP address <ClientIPAddr> against the filtering
* scheme defined in 'RLI_CUSTOM_DYNAMIC_IP_CHECK'. If IP filtering is <not>
* enabled, then all IP addresses are allowed (valid).
*
*
* RETURNS:
*\is
*\i TRUE
* If <ClientIPAddr> is a valid IP address, or if filtering is not enabled.
*\i FALSE
* If <ClientIPAddr> is an invalid IP address (one that should be blocked).
*\ie
*
* NOMANUAL
*/
BOOL accessIpValid
(
ubyte4 ClientIpAddr /* client IP address !rws hex? */
)
{
#ifdef __RLI_DEBUG_ACCESS__
BOOL retBool;
printf("ACCESS_ValidIpAddress: Checking client request (address=%d.%d.%d.%d).\n", (int)((ClientIpAddr >> 24) & 0xff), (int)((ClientIpAddr >> 16) & 0xff), (int)((ClientIpAddr >> 8) & 0xff), (int)(ClientIpAddr & 0xff));
#endif
/* is ip filtering enabled? */
if (RLI_CUSTOM_DYNAMIC_IP_FILTER_ENABLED())
{
#ifndef __RLI_DEBUG_ACCESS__
/* check if the ip address is valid */
return RLI_CUSTOM_DYNAMIC_IP_CHECK(ClientIpAddr, 0, 0);
#else
retBool = RLI_CUSTOM_DYNAMIC_IP_CHECK(ClientIpAddr, 0, 0);
if (retBool)
printf("accessIpValid: Valid IP address.\n");
else
printf("accessIpValid: Invalid IP address --- block!\n");
return retBool;
#endif
}
DEBUG_MSG_0("accessIpValid: filtering not enabled.\n");
return TRUE;
}
#endif /* __ENABLE_LAN_IP_FILTER__ */
DTTypeInfo * wmAccessInfoGet
(
void
)
{
return pAccessInfo;
}
void wmAccessInfoSet
(
DTTypeInfo * pInfo
)
{
pAccessInfo = pInfo;
}
ubyte4 wmAccessLevelGet
(
void * what
)
{
return systemAccessLevel;
}
ubyte4 wmAccessGroupsGet
(
void * what
)
{
return systemAccessGroups;
}
#ifndef __WMB_VIEW_ACCESS_MODEL__
/**************************************************************************
*
* wmAccessReadAllowed - Determines if a user has read access for a resource.
*
* This routine checks a user's access level--defined in the session
* environment structure--against the resources' required access level.
*
*
* RETURNS:
*\is
*\i TRUE
* If the user has the required read access level.
*\i FALSE
* If the user does not have the required read access level.
*\ie
*/
BOOL wmAccessReadAllowed
(
Access userAccess, /* user privileges*/
Access resourceAccess /* access level required by resource */
)
{
/* See if user's access level is high enough */
if (wmAccessInvalidLevel (resourceAccess, userAccess))
return FALSE;
/* If user is in resource's group */
#if (ACCESS_GROUP_MASK_K != 0)
if (wmAccessInvalidGroup (resourceAccess, userAccess))
return FALSE;
#endif
return TRUE;
}
/**************************************************************************
*
* wmAccessWriteAllowed - Determines if a user has write access for a resource.
*
* This routine determines if a user has the appripriate accesss level to
* write to a resource.
*
*
* RETURNS:
*\is
*\i TRUE
* If the user has the required write access level.
*\i FALSE
* If the user does not have the required write access level.
*\ie
*/
BOOL wmAccessWriteAllowed
(
Access userAccess, /* user environment struct pointer */
Access resourceAccess /* access level required by resource */
)
{
/* See if user's access level is high enough */
if (wmAccessInvalidLevel (resourceAccess, userAccess))
return FALSE;
/* See if user's options overlap with the resource's (if resource options is not empty) */
#if (ACCESS_GROUP_MASK_K != 0)
if (wmAccessInvalidGroup (resourceAccess, userAccess))
return FALSE;
#endif
return TRUE;
}
/**************************************************************************
*
* wmAccessReadOkay - Determines if a user has read access for a resource.
*
* This routine checks a user's access level--defined in the session
* environment structure--against the resources' required access level.
*
*
* RETURNS:
*\is
*\i TRUE
* If the user has the required read access level.
*\i FALSE
* If the user does not have the required read access level.
*\ie
*
* NOMANUAL
*/
BOOL wmAccessReadOkay
(
Access userAccess, /* user privileges*/
Access resourceAccess /* access level required by resource */
)
{
/* See if user's access level is high enough */
if (wmAccessInvalidLevel (resourceAccess, userAccess))
return FALSE;
/* If user is in resource's group */
#if (ACCESS_GROUP_MASK_K != 0)
if (wmAccessInvalidGroup (resourceAccess, userAccess))
return FALSE;
#endif
return TRUE;
}
#endif
/**************************************************************************
*
* wmAccessToStr - convert value of access to string
*
*
* RETURNS:\is
*\i ERROR_GENERAL_NOT_FOUND
*\i OK
*\ie
*/
STATUS wmAccessToStr
(
Access nAccess,
sbyte * pString
)
{
DTTypeInfo * pTypeInfo;
sbyte * tptr;
sbyte delim[2];
sbyte numstr[20];
int i;
int hits;
int count;
Access mask;
unsigned int tmp_access;
if (NULL == (pTypeInfo = wmAccessInfoGet()))
return wmError(ERROR_GENERAL_UNINITIALIZED, "no system access info");
if (NULL == pString)
return wmError(ERROR_GENERAL_NO_DATA, "no access data");
pString[0] = '\0';
#ifndef __RLI_ACCESS_LEVEL_MASK__
return wmConvertToStr (&nAccess,pString,4,DATATYPE_INTEGER_K);
#endif
/* get separater */
tptr = strstr(pTypeInfo->pValidateStr,"D=");
if (NULL==tptr)
return ERROR_GENERAL_NOT_FOUND;
delim[0] = tptr[2];
delim[1] = '\0';
count = wmConvertGetEnumCount(pTypeInfo);
mask = 0x01 << __RLI_ACCESS_LEVEL_SHIFT__;
hits = 0;
/* Convert Option Bits */
while (mask & __RLI_ACCESS_OPTION_MASK__)
{
if (nAccess & mask)
{
/* find it in the list */
for (i = 0; i < count; i++)
{
if (mask == (Access) pTypeInfo->pEnumTable[i].EnumValue)
{
if (hits)
strcat(pString, delim);
strcat(pString,pTypeInfo->pEnumTable[i].EnumString);
nAccess &= (Access)~mask;
hits++;
break;
}
}
/* Do not allow undefined option bits */
if (i == count) {
nAccess &= (Access)~mask;
/* return ERROR_GENERAL_NOT_FOUND; */
}
}
mask = (Access)(mask << 1);
}
/* Convert and append access level */
tmp_access = wmAccessLevelGet(NULL);
if (tmp_access > 0)
tmp_access &= nAccess;
wmConvertToStr(&tmp_access, numstr, sizeof(numstr), DATATYPE_UINTEGER_K);
if (strlen(pString))
strcat(pString,delim);
strcat(pString,numstr);
return OK;
}
/**************************************************************************
*
* wmAccessFromString - convert string representation to numeric access
*
*
* RETURNS:\is
*\i ERROR_GENERAL_NOT_FOUND
*\i ERROR_GENERAL_OUT_OF_RANGE
*\i OK
*\ie
*/
STATUS wmAccessFromString
(
sbyte * pString,
Access * pAccess
)
{
DTTypeInfo * pTypeInfo;
STATUS status;
sbyte * pTemp;
sbyte * pNext;
sbyte delimiter;
int i;
unsigned int enumLen;
unsigned int enumValue;
int count;
char numstr[20];
sbyte4 tmpAccess;
Access tmpAccess1;
BOOL match;
DTEnumInfo * pEnumTable;
*pAccess = 0;
if (NULL == (pTypeInfo = wmAccessInfoGet()))
return wmError(ERROR_GENERAL_UNINITIALIZED, "no system access info");
if (NULL_STRING(pString))
return wmError(ERROR_GENERAL_NO_DATA, "no access data");
#ifndef __RLI_ACCESS_LEVEL_MASK__
return wmConvertStrTo(pString, pAccess, sizeof(Access), DATATYPE_INTEGER_K);
#endif
/* get separater */
if (NULL == (pTemp = strstr(pTypeInfo->pValidateStr,"D=")))
return ERROR_GENERAL_NOT_FOUND;
delimiter = pTemp[2];
count = wmConvertGetEnumCount(pTypeInfo);
pTemp = pString;
while (0 != *pTemp)
{
enumLen = (unsigned int)STRLEN(pTemp);
if (NULL != (pNext = STRCHR(pTemp, delimiter)))
enumLen = (unsigned int) (pNext - pTemp);
if (ISDIGIT((int)*pTemp))
{
strncpy(numstr, pTemp, enumLen);
numstr[enumLen] = '\0';
if (OK != (status = wmConvertStrTo(numstr, &tmpAccess, sizeof(tmpAccess), DATATYPE_INTEGER_K)))
return status;
if ((0 > tmpAccess) || (tmpAccess > ACCESS_LEVEL_MASK_K))
return ERROR_GENERAL_OUT_OF_RANGE;
tmpAccess1 = (Access)tmpAccess;
*pAccess |= tmpAccess1;
}
else
{
/* find it in the list */
pEnumTable = pTypeInfo->pEnumTable;
match = FALSE;
enumValue = 0;
for (i = 0; i < count; i++, pEnumTable++)
{
if (0 != STRNCMP(pTemp, pEnumTable->EnumString, enumLen))
continue;
enumValue = pEnumTable->EnumValue;
if (enumLen == (unsigned int) STRLEN(pEnumTable->EnumString))
{
match = TRUE;
break;
}
if (match)
return ERROR_GENERAL_DATA_AMBIG;
match = TRUE;
}
/* Do not allow undefined option bits */
if (! match)
return ERROR_GENERAL_ILLEGAL_VALUE;
*pAccess |=(Access)enumValue;
}
/* get next entry */
pTemp += enumLen;
if (NULL != pNext)
pTemp++;
}
return OK;
} /* wmAccessFromString */
/*New APIs */
Access wmAccessReadGet ( WM_ACCESS_T pAccess )
{
return pAccess.read;
}
Access wmAccessWriteGet ( WM_ACCESS_T pAccess )
{
return pAccess.write;
}
STATUS wmAccessReadSet ( WM_ACCESS_T *pAccess, Access readAccess )
{
if (NULL == pAccess)
return ERROR;
else
{
pAccess->read = readAccess ;
return OK;
}
}
STATUS wmAccessWriteSet ( WM_ACCESS_T *pAccess, Access writeAccess )
{
if (NULL == pAccess)
return ERROR;
else
{
pAccess->write = writeAccess ;
return OK;
}
}
/* eof wmAccessLib.c */
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,208 @@
/* wmCompareLib.c - comparison tests library */
/* Copyright 2001, 2010 Wind River Systems, Inc. */
/*
modification history
--------------------
01c,29jan10,m_z VxWorks 64-bit support
(WIND00193649)
01a,01aug01,pns written
01b,09oct01,rws modified comments
*/
/*
DESCRIPTION
This module implements data comparisons for RCB data
INCLUDE FILES: wm.h wmb.h
*/
/* includes */
#include "wm.h"
#include "wmb.h"
/*-----------------------------------------------------------------------*/
BOOL compareUchars
(
void * pUchar,
void * pUchar1
)
{
if ( (NULL == pUchar) || (NULL == pUchar1) )
return FALSE;
else
return (*((unsigned char *)pUchar) == *((unsigned char *)pUchar1));
}
/*-----------------------------------------------------------------------*/
BOOL compareIP
(
void * pIPaddr,
void * pIPaddr1
)
{
if ( (NULL == pIPaddr) || (NULL == pIPaddr1) )
return FALSE;
else
return (*((ubyte4 *)pIPaddr) == *((ubyte4 *)pIPaddr1));
}
/*-----------------------------------------------------------------------*/
BOOL compareInts
(
void * pInt,
void * pInt1
)
{
if ( (NULL == pInt) || (NULL == pInt1) )
return FALSE;
else
return (*((int *)pInt) == *((int *)pInt1)) ? TRUE : FALSE;
}
/*-----------------------------------------------------------------------*/
BOOL compareUnsignedInts
(
void * pUnsigned,
void * pUnsigned1
)
{
if ( (NULL == pUnsigned) || (NULL == pUnsigned1) )
return FALSE;
else
return (*((unsigned int *)pUnsigned) == *((unsigned int *)pUnsigned1));
}
/*-----------------------------------------------------------------------*/
BOOL compareShorts
(
void * pShort,
void * pShort1
)
{
if ( (NULL == pShort) || (NULL == pShort1) )
return FALSE;
else
return (*((short *)pShort) == *((short *)pShort1));
}
/*-----------------------------------------------------------------------*/
BOOL compareUshorts
(
void * pUshort,
void * pUshort1
)
{
if ( (NULL == pUshort) || (NULL == pUshort1) )
return FALSE;
else
return (*((unsigned short *)pUshort) == *((unsigned short *)pUshort1));
}
/*-----------------------------------------------------------------------*/
BOOL compareLongs
(
void * pLong,
void * pLong1
)
{
if ( (NULL == pLong) || (NULL == pLong1) )
return FALSE;
else
return (*((long *)pLong) == *((long *)pLong1));
}
/*-----------------------------------------------------------------------*/
BOOL compareUlongs
(
void * pUlong,
void * pUlong1
)
{
if ( (NULL == pUlong) || (NULL == pUlong1) )
return FALSE;
else
return (*((unsigned long *)pUlong) == *((unsigned long *)pUlong1));
}
/*-----------------------------------------------------------------------*/
BOOL compareStrings
(
void * pStr,
void * pStr1
)
{
if ((NULL == pStr) || (NULL == pStr1))
return FALSE;
return (0 == STRCMP(pStr, pStr1));
}
/**************************************************************************
*
* compareValues - Compare objects of same datatype.
*
* This routine is a wrapper for comparison functions for each of the
* following datatypes: 'int', 'uint','short', 'ushort', 'long', 'ulong',
* 'IpAddr', and 'string'.
*
* RETURNS:
*\is
*\i TRUE
*
*\i FALSE
*
*\ie
*/
BOOL compareValues
(
void * pDataObject,
void * pDataObject1,
DATATYPE_T DType
)
{
switch (DType)
{
case DATATYPE_INTEGER_K:
return compareInts(pDataObject, pDataObject1);
case DATATYPE_UINTEGER_K:
return compareUnsignedInts(pDataObject, pDataObject1);
case DATATYPE_SHORT_K:
return compareShorts(pDataObject, pDataObject1);
case DATATYPE_USHORT_K:
return compareUshorts(pDataObject, pDataObject1);
case DATATYPE_LONG_K:
return compareLongs(pDataObject, pDataObject1);
case DATATYPE_ULONG_K:
return compareUlongs(pDataObject, pDataObject1);
case DATATYPE_IPV4_K:
return compareIP(pDataObject, pDataObject1);
case DATATYPE_STRING_K:
return compareStrings(pDataObject, pDataObject1);
default:
break;
}
return FALSE;
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,871 @@
/* wmFileLib.c - ansi file support */
/* adapted from rc_ansifs.c */
/*
* Copyright (c) 2002-2010, 2012 Wind River Systems, Inc.
*
* The right to copy, distribute, modify or otherwise make use
* of this software may be licensed only pursuant to the terms
* of an applicable Wind River license agreement.
*/
/*
modification history
--------------------
01h,12nov12,f_f don't attach fileDir if it's invalid (WIND00387021)
01g,02aug12,f_f correct the wrong file dir from the full path (WIND00367073)
01f,17may12,h_l replace NO_STRING with NULL_STRING (WIND00032212)
01e,07may10,m_z eliminate compile warning
01d,29jan10,m_z VxWorks 64-bit support
(WIND00193649)
01c,24feb07,msa Correct the apigen comments so they match the actual routines
and correct any apigen errors that may occur.
01b,10aug06,ps fix missing arguments to wmosSemTake
01a,17may02,rs updated refgen comments
01 , ,ps imported from rc 3.3 vob
*/
/*
DESCRIPTION:
WindManage ANSI file support library.
INCLUDE FILES:
wm.h
*/
#include "wm.h"
#ifdef __ANSI_FILE_MANAGER_ENABLED__
#ifndef kDIRECTORY_BUFFER_SIZE
#define kDIRECTORY_BUFFER_SIZE 256
#endif
static sbyte * mDefaultPath = NULL;
static OS_SEM_T mFileMutex;
/*-----------------------------------------------------------------------*/
#ifdef __DECOMPRESSION_ENABLED__
LOCAL void wmFileLock
(
void
)
{
wmosSemTake( mFileMutex, WAIT_FOREVER_K );
}
/*-----------------------------------------------------------------------*/
LOCAL void wmFileUnlock
(
void
)
{
wmosSemGive( mFileMutex );
}
#endif /* __DECOMPRESSION_ENABLED__ */
/*-----------------------------------------------------------------------*/
LOCAL void wmFileDetermineFileLength
(
FILE * pFile,
Length * pLength
)
{
long start, end;
/* Is there an easier way of doing this? */
fseek(pFile, 0, SEEK_SET);
start = ftell(pFile);
fseek(pFile, 0, SEEK_END);
end = ftell(pFile);
fseek(pFile, 0, SEEK_SET);
*pLength = (Length)end - (Length)start;
}
/**************************************************************************
*
* wmFileCreateDirDOS - WMB file open.
*
* This routine will.
*
* RETURNS: OK, or ERROR if the file is not found or if there is insufficient
* memory to open the file.
*
*
* NOMANUAL
*/
#if 0
LOCAL WM_DIR_T * wmFileCreateDirDOS
(
sbyte * pFileName
)
{
WM_DIR_T * pDir;
if (! wmNew(pDir))
{
wmError(ERROR_MEMMGR_NO_MEMORY, "wmFileCreateDirDOS: no memory");
return NULL;
}
if (NULL == (pDir->pDirHandle = (DIR_HANDLE *) wmMalloc(sizeof(DIR_HANDLE))))
{
wmFree(pDir)
wmError(ERROR_MEMMGR_NO_MEMORY, "wmFileCreateDirDOS: no memory");
return NULL;
}
return pDir;
}
#endif
/*-----------------------------------------------------------------------*/
LOCAL void * wmFileOpenFile
(
sbyte * pFileName,
sbyte * pPathName,
#ifndef _WRS_CONFIG_LP64
sbyte4 * pLength,
#else
sbyte8 * pLength,
#endif
BOOL compression
)
{
sbyte *pFullPath = NULL;
sbyte *pData = NULL;
sbyte *pReturn = NULL;
FILE *pFile = NULL;
Length pathLen = 0;
Length fullPathLen = 0;
Length bytesRead = 0;
Length fileLen = 0;
#ifdef __DECOMPRESSION_ENABLED__
BOOL isCompressed = FALSE;
sbyte *pDecompressedData;
sbyte4 decompressedLen;
#endif /* __DECOMPRESSION_ENABLED__ */
*pLength = -1; /* to differentiate a null for empty file */
pathLen = STRLEN(pPathName);
fullPathLen = pathLen + STRLEN(pFileName) + 3;
pFullPath = (sbyte*) wmosMalloc(fullPathLen);
if (NULL == pFullPath)
{
DEBUG_MSG_2("error malloc -- %d bytes, for %s\n", fullPathLen, pFileName);
return NULL;
}
STRCPY(pFullPath, pPathName);
/* does the base path have proper path separator? */
if (0 < pathLen)
{
--pathLen;
#ifdef __WIN32_OS__
if ('\\' != pPathName[pathLen])
STRCAT(pFullPath, "\\");
#else
if ('/' != pPathName[pathLen])
STRCAT(pFullPath, "/");
#endif
}
STRCAT(pFullPath, pFileName);
pFile = fopen(pFullPath, "rb");
if (NULL == pFile)
{
DEBUG_MSG_1("error fopen -- %s", pFullPath);
wmosFree(pFullPath);
return NULL;
}
wmFileDetermineFileLength( pFile, &fileLen );
if (0 >= fileLen)
{
*pLength = 0;
wmosFree(pFullPath);
return NULL;
}
pData = (sbyte*) wmosMalloc(fileLen + 1); /* +1 for EOL */
if (NULL == pData)
{
DEBUG_MSG_1("error malloc -- %d bytes, for buffer\n", fileLen);
wmosFree(pFullPath);
return NULL;
}
bytesRead = fread(pData, sizeof(sbyte), fileLen, pFile);
*pLength = fileLen;
pReturn = pData;
pData[fileLen] = 0; /* null terminate string */
#ifdef __DECOMPRESSION_ENABLED__
if (compression)
{
/* If the file is compressed, then use the decompression code.
Otherwise, just return the data as is. */
DECOMP_IsCompressed(pData, &isCompressed);
if ( isCompressed )
{
wmFileLock();
DECOMP_DecompressData(pData, bytesRead,
&pDecompressedData, &decompressedLen);
wmFileUnlock();
wmosFree(pData);
*pLength = decompressedLen;
pReturn = pDecompressedData;
}
}
#endif /* __DECOMPRESSION_ENABLED__ */
wmosFree(pFullPath);
fclose(pFile);
return pReturn;
}
/**************************************************************************
*
* wmFileReadFile - .
*
* This routine will .
*
* RETURNS: N/A.
*
*
* NOMANUAL
*/
void * wmFileReadFile
(
WM_DIR_T * pDir,
#ifndef _WRS_CONFIG_LP64
sbyte4 * pLen,
#else
sbyte8 * pLen,
#endif
sbyte * pId
)
{
sbyte * pBasePath;
if (NULL == pDir)
pBasePath = mDefaultPath;
else
pBasePath = pDir->cwd;
return wmFileOpenFile(pId, pBasePath, pLen, TRUE);
}
/**************************************************************************
*
* wmFileRetrieveFile - File retrieve.
*
* This routine will .
*
* RETURNS: Pointer to .
*
*
* NOMANUAL
*/
void * wmFileRetrieveFile
(
#ifndef _WRS_CONFIG_LP64
sbyte4 * pLen,
#else
sbyte8 * pLen,
#endif
sbyte * pId
)
{
return wmFileOpenFile(pId, mDefaultPath, pLen, TRUE);
}
/**************************************************************************
*
* wmFileReleaseFile - WMB file release.
*
* This routine will .
*
* RETURNS: N/A.
*
*
* NOMANUAL
*/
void wmFileReleaseFile
(
void *pObject
)
{
if (NULL != pObject)
wmosFree(pObject);
}
/**************************************************************************
*
* wmFileRetreiveResource - WMB resource retreive.
*
* This routine will .
*
* RETURNS: N/A.
*
*
* NOMANUAL
*/
void* wmFileRetrieveResource
(
#ifndef _WRS_CONFIG_LP64
sbyte4 * pLen,
#else
sbyte8 * pLen,
#endif
sbyte *pId
)
{
return wmFileOpenFile(pId, mDefaultPath, pLen, FALSE);
}
/**************************************************************************
*
* wmFileReleaseResource - WMB resource release.
*
* This routine will .
*
* RETURNS: N/A.
*
*
* NOMANUAL
*/
void wmFileReleaseResource
(
void *pObject
)
{
wmosFree(pObject);
}
/**************************************************************************
*
* wmFileInit - WMB file Lib init.
*
* This routine will .
*
* RETURNS: N/A.
*
*
* NOMANUAL
*/
STATUS wmFileInit
(
sbyte *pPath
)
{
/* already initialized? */
if (NULL != mDefaultPath)
return ERROR_GENERAL;
mDefaultPath = wmosMalloc (STRLEN(pPath) + 1 );
if ( NULL == mDefaultPath )
return ERROR_MEMMGR_NO_MEMORY;
STRCPY( mDefaultPath, pPath );
return wmosSemCreate(&mFileMutex, 1, 0);
}
#ifdef __ENABLE_SESSION_DIRECTORIES__
LOCAL BOOL wmFileChangePath
(
sbyte * pOldPath,
sbyte * pNewPath
)
{
sbyte *pParent;
/* relative change */
while (('.' == *pNewPath) && ('.' == *(pNewPath + 1)))
{
/* move up old path */
pParent = STRRCHR(pOldPath, PATH_CHAR_K);
pNewPath = STRCHR(pNewPath, PATH_CHAR_K);
/*
if (NULL == pNewPath)
return FALSE;
*/
if (NULL == pParent)
break;
*(++pParent) = 0;
if (NULL == pNewPath)
break;
}
return TRUE;
}
/**************************************************************************
*
* wmFileChdir - WMB chdir.
*
* This routine will .
*
* RETURNS: OK, or ERROR if <pPath> is invlaid. <pPath> can be relative or
* absolute.
*
*
* NOMANUAL
*/
STATUS wmFileChdir
(
WM_DIR_T * pDir,
sbyte * pPath
)
{
STATUS status = OK;
sbyte tempPath[kDIRECTORY_BUFFER_SIZE];
#ifndef _WRS_CONFIG_LP64
ubyte4 length;
#else
ubyte8 length;
#endif
#ifdef __WIN32_OS__
DWORD attributes;
#else
DIR *handle;
#endif
if (NULL == pDir)
return wmError(ERROR_GENERAL_NULL_POINTER, "no dir info");
if (NULL_STRING(pPath))
return wmError(ERROR_GENERAL_INVALID_PATH, "invalid path");
if (kDIRECTORY_BUFFER_SIZE < STRLEN(pPath))
return wmError(ERROR_GENERAL_BUFFER_OVERRUN, "buffer overflow");
STRNCPY(tempPath, pDir->cwd, kDIRECTORY_BUFFER_SIZE);
switch (*pPath)
{
case '.':
/* relative path */
wmFileChangePath(tempPath, pPath);
break;
case PATH_CHAR_K:
/* absolute path */
STRNCPY(tempPath, pPath, kDIRECTORY_BUFFER_SIZE);
break;
default:
#ifdef __WIN32_OS__
/* grrrr... stupid DOS */
if (':' == *(pPath + 1))
STRNCPY(tempPath, pPath, kDIRECTORY_BUFFER_SIZE);
else
#endif
{
length = STRLEN(tempPath);
if (PATH_CHAR_K != tempPath[length - 1])
{
tempPath[length++] = PATH_CHAR_K;
tempPath[length ] = 0;
}
STRNCAT(tempPath, pPath, kDIRECTORY_BUFFER_SIZE - length);
}
break;
}
/* make sure path is valid and have access */
#ifdef __WIN32_OS__
if ( -1 == (attributes = GetFileAttributes(tempPath)))
return ERROR_GENERAL_INVALID_PATH;
if ( 0 == (FILE_ATTRIBUTE_DIRECTORY & attributes))
return ERROR_GENERAL_INVALID_PATH;
#else
if (NULL == (handle = opendir(tempPath)))
return ERROR_GENERAL_INVALID_PATH;
closedir(handle);
#endif
STRNCPY(pDir->cwd, tempPath, kDIRECTORY_BUFFER_SIZE);
return status;
}
/**************************************************************************
*
* wmFileOpenDir - WMB file open. Win32 specific!
*
* This routine will.
*
* RETURNS: OK, or ERROR if the file is not found or if there is insufficient
* memory to open the file.
*
*
* NOMANUAL
*/
#ifdef __WIN32_OS__
STATUS wmFileOpenDir
(
WM_DIR_T * pDir,
sbyte * pFileName
)
{
sbyte * pFullPath;
sbyte4 length;
if (wmDirBad(pDir))
return wmError(ERROR_GENERAL_NULL_POINTER, "wmFileOpenDir: invalid dir struct");
if (NULL == pFileName)
pFileName = "*";
if (NULL == (pFullPath = wmMalloc(kDIRECTORY_BUFFER_SIZE)))
return wmError(ERROR_MEMMGR_NO_MEMORY, "wmFileOpenDir: no memory");
length = STRLEN(pDir->cwd);
STRCPY(pFullPath, pDir->cwd);
if (PATH_CHAR_K != pFullPath[length - 1])
{
pFullPath[length++] = PATH_CHAR_K;
pFullPath[length] = 0;
}
STRNCAT(pFullPath, pFileName, kDIRECTORY_BUFFER_SIZE - length);
/* Find first file in current directory */
if (-1L == (pDir->handle = _findfirst(pFullPath, &pDir->fileInfo)))
{
pDir->found = FALSE;
wmFree(pFullPath);
return wmError(ERROR_GENERAL_FILE_NOT_FOUND, "file not found");
}
wmFree(pFullPath);
return OK;
}
#else /* ! __WIN32_OS__ */
/**************************************************************************
*
* wmFileOpenDir - WMB file open.
*
* This routine will.
*
* RETURNS: OK, or ERROR if the file is not found or if there is insufficient
* memory to open the file.
*
*
* NOMANUAL
*/
STATUS wmFileOpenDir
(
WM_DIR_T * pDir,
sbyte * pFileName
)
{
#ifndef _WRS_CONFIG_LP64
ubyte4 length;
#else
ubyte8 length;
#endif
sbyte * pFullPath = NULL;
sbyte * pTruncate = NULL;
if (wmDirBad(pDir))
return wmError(ERROR_MEMMGR_NO_MEMORY, "wmFileOpenDir: invalid dir struct");
DEBUG_MSG_1("Open directory for filename: %s\n", pFileName);
if (NULL == (pFullPath = wmMalloc(kDIRECTORY_BUFFER_SIZE)))
return wmError(ERROR_MEMMGR_NO_MEMORY, "wmFileOpenDir: no memory");
length = STRLEN(pDir->cwd);
STRCPY(pFullPath, pDir->cwd);
if (PATH_CHAR_K != pFullPath[length - 1])
{
pFullPath[length++] = PATH_CHAR_K;
pFullPath[length] = 0;
}
DEBUG_MSG_1("Current working directory: %s\n", pFullPath);
if (! NULL_STRING(pFileName))
{
DEBUG_MSG_1("Appending filename: %s\n", pFileName);
STRNCAT(pFullPath, pFileName, kDIRECTORY_BUFFER_SIZE - length);
pTruncate = STRRCHR(pFullPath, PATH_CHAR_K);
if (NULL == pTruncate)
pTruncate = STRRCHR(pFullPath, '.');
}
DEBUG_MSG_0("Appended filename\n");
if (NULL != pTruncate)
{
pTruncate++;
DEBUG_MSG_1("Filemask: %s\n", pTruncate);
STRNCPY(pDir->fileMask, pTruncate, sizeof(pDir->fileMask));
*pTruncate = 0;
STRNCPY(pDir->fileDir, pFileName, sizeof(pDir->fileDir));
}
else
{
DEBUG_MSG_0("No filename given\n");
if (NULL_STRING(pFileName))
pDir->fileMask[0] = 0;
else
STRNCPY(pDir->fileMask, pFileName, sizeof(pDir->fileMask));
pDir->fileDir[0] = 0;
}
pDir->nameLen = (sbyte4)STRLEN(pDir->fileMask);
DEBUG_MSG_1("Adjusted directory: %s\n", pFullPath);
DEBUG_MSG_1("Filemask: %s\n", pDir->fileMask);
if (NULL == (pDir->handle = opendir (pFullPath)))
{
wmFree(pFullPath);
return wmError(ERROR_GENERAL_FILE_NOT_FOUND, "file not found");
}
wmFree(pFullPath);
return OK;
}
#endif /* ! __WIN32_OS__ */
/**************************************************************************
*
* wmFileNextDir - Get next file in dir. Win32 specific!
*
* This routine will .
*
* RETURNS: Poitner to next filename, or NULL if ?
*
*
* NOMANUAL
*/
#ifdef __WIN32_OS__
sbyte * wmFileNextDir
(
WM_DIR_T * pDir,
sbyte4 * size,
ubyte4 * flags
)
{
*size = 0;
*flags = 0;
if (NULL == pDir)
return NULL;
/* First file in current directory? */
if (FALSE == pDir->found)
pDir->found = TRUE;
else
{
if (0 > _findnext(pDir->handle, &pDir->fileInfo))
return NULL;
}
if (pDir->fileInfo.attrib & _A_SUBDIR)
*flags |= FS_DIRECTORY_K;
if (pDir->fileInfo.attrib & _A_RDONLY)
*flags |= FS_READ_ONLY_K;
*size = pDir->fileInfo.size;
return pDir->fileInfo.name;
}
#else /* ! __WIN32_OS__ */
/**************************************************************************
*
* wmFileNextDir - Get next file in dir.
*
* This routine will .
*
* RETURNS: Poitner to next filename, or NULL if .
*
*
* NOMANUAL
*/
sbyte * wmFileNextDir
(
WM_DIR_T * pDir,
#ifndef _WRS_CONFIG_LP64
sbyte4 *size,
#else
sbyte8 *size,
#endif
ubyte4 *flags
)
{
sbyte fileSeparator = PATH_CHAR_K;
sbyte * pFullName;
struct dirent * pDirInfo;
sbyte * pName;
struct stat fileStats;
ubyte4 dirlen;
*size = 0;
*flags = 0;
if (wmDirBad(pDir))
return NULL;
if (NULL == (pFullName = wmMalloc(kDIRECTORY_BUFFER_SIZE)))
return NULL;
*pFullName = 0;
if (NULL == (pDirInfo = readdir(pDir->handle)))
{
DEBUG_MSG_0("Readdir failed\n");
wmFree(pFullName);
return NULL;
}
pName = pDirInfo->d_name;
if (0 == STRCMP(pName, ".") || (0 == STRCMP(pName, "..")))
return pName;
/*
if ( (!NULL_STRING(pName)) && (0 != STRNCMP(pName, pDir->fileMask, pDir->nameLen)))
return NULL;
*/
if (!NULL_STRING(pDir->cwd))
STRCPY(pFullName, pDir->cwd);
dirlen = STRLEN(pDir->fileDir);
if (dirlen > 1 && PATH_CHAR_K == pDir->fileDir[dirlen-1])
{
if (!NULL_STRING(pFullName))
STRNCAT(pFullName, &fileSeparator, 1);
if (!NULL_STRING(pDir->fileDir))
STRCAT(pFullName, pDir->fileDir);
}
if (!NULL_STRING(pFullName))
STRNCAT(pFullName, &fileSeparator, 1);
if (!NULL_STRING(pDirInfo->d_name))
STRCAT(pFullName, pDirInfo->d_name);
DEBUG_MSG_1("Stat for: %s\n", pFullName);
/* expand error handling -- get err info */
if (0 != stat(pFullName, &fileStats))
{
DEBUG_MSG_0("Stat failed\n");
wmFree(pFullName);
return NULL;
}
*size = fileStats.st_size;
DEBUG_MSG_1("File size: %d\n", *size);
if (S_ISDIR(fileStats.st_mode))
*flags |= FS_DIRECTORY_K;
wmFree(pFullName);
return pDirInfo->d_name;
}
#endif /* __WIN32_OS__ */
/**************************************************************************
*
* wmFileCloseDir - WMB file close.
*
* This routine will .
*
* RETURNS: N/A.
*
*
* NOMANUAL
*/
void wmFileCloseDir
(
WM_DIR_T * pDir
)
{
CLOSEDIR(pDir->handle);
}
#else /* __ENABLE_SESSION_DIRECTORIES__ */
STATUS wmFileChdir(WM_DIR_T * pDir, sbyte *pPath) {return OK;}
void wmFileCloseDir(WM_DIR_T * pDir){}
STATUS wmFileOpenDir(WM_DIR_T * pDir, sbyte *pFileName) {return OK;}
sbyte* wmFileNextDir(
WM_DIR_T * pDir,
#ifndef _WRS_CONFIG_LP64
sbyte4 *size,
#else
sbyte8 *size,
#endif
ubyte4 *flags
)
{
*size = 0;
*flags = 0;
return NULL;
}
#endif /* __ENABLE_SESSION_DIRECTORIES__ */
#endif /* __ANSI_FILE_MANAGER_ENABLED__ */
@@ -0,0 +1,473 @@
/* wmHashLib.c - hash function library */
/* Copyright 2001-2007,2010 Wind River Systems, Inc. */
/*
modification history
--------------------
01d.28apr10,m_z eliminate compile warning
01c,29jan10,m_z VxWorks 64-bit support
(WIND00193649)
01b,24feb07,msa Correct the apigen comments so they match the actual routines
and correct any apigen errors that may occur.
01a,01aug01,pns written
*/
/*
DESCRIPTION
This module implements hash functions for the internal database
INCLUDE FILES: wm.h
*/
/* includes */
#include "wm.h"
/* average number of hash collisions per bucket */
#ifndef AVERAGE_COLLISIONS_K
#define AVERAGE_COLLISIONS_K 3
#endif
sbyte4 wmHashPrime ( sbyte4 start);
LOCAL sbyte4 prime_numbers[] = /* array of prime numbers */
{
7, 13, 23, 31, 47, 53, 71, 89, 101, 199, 223, 293, 311, 397, 409, 499,
509, 599, 607, 691, 709, 797, 811, 887, 907, 997, 1013, 1097, 1109,
1193, 1201, 1297, 1301
};
sbyte4 wmHashPrime
(
sbyte4 start /* number of objects to find prime number */
)
{
unsigned int i;
/* Find the Prime number just larger than start */
for (i = 0; i < ARRAY_SIZE(prime_numbers); i++)
{
/* scan the list of primes looking for the entry larger */
if ( prime_numbers[i] >= start)
return prime_numbers[i];
}
/* The largest prime used for object counts over 5000 */
return prime_numbers[ARRAY_SIZE(prime_numbers) - 1];
}
/**************************************************************************
*
* wmHashKeyGenerate - generate hash value from string
*
* RETURNS: N/A
*
*
* NOMANUAL
*/
ubyte4 wmHashKeyGenerate
(
sbyte * pStr
)
{
sbyte4 count = 0;
sbyte4 hash = 0;
while (NAME_OK(pStr))
{
count++;
hash *= 32;
hash += *(pStr++);
}
return (ubyte4)hash;
}
/**************************************************************************
*
* wmHashEntryGet - get hash node to table entry offset
*
* Entry is first found -- may be wrong item because of hash collision
* This is ok, the caller must verify
*
* RETURNS: Found hash or NULL
*
*
* NOMANUAL
*/
LOCAL STATUS wmHashEntryGet
(
WMB_HASH_TABLE_T * pTable,
sbyte * pName,
ubyte4 * pKey,
HASH_T * * ppHash
)
{
ubyte4 key;
ubyte4 index;
HASH_T * pNode;
if (NULL == pTable || NULL == pName || NULL == pKey || NULL == ppHash)
return wmError(ERROR_GENERAL_NULL_POINTER, "null pointers");
pNode = pTable->pNodes;
key = wmHashKeyGenerate (pName);
/* key has to be trimmed to within table range */
index = key % pTable->tableSize;
pNode += index;
*ppHash = pNode;
*pKey = key;
return OK;
}
/**************************************************************************
*
* wmHashConstruct - make a new hash table
*
* RETURNS: ERROR or OK
*
*
* NOMANUAL
*/
STATUS wmHashConstruct
(
MEM_POOL_ID memID,
sbyte4 rows,
fnHashKeyExtract pFuncExtractKey,
fnHashCompare pFuncCompare,
fnHashNodeName pFuncName,
WMB_HASH_TABLE_T ** ppTable
)
{
WMB_HASH_TABLE_T * pTable;
sbyte4 size;
HASH_T * pNodes;
if (1 > rows)
return wmError (ERROR, "wmHashConstruct: invalid row count");
rows = wmHashPrime (rows / AVERAGE_COLLISIONS_K);
size = (sbyte4)sizeof(HASH_T) * rows;
if (NULL == memID)
{
pTable = (WMB_HASH_TABLE_T *) wmMalloc (sizeof(WMB_HASH_TABLE_T));
pNodes = (HASH_T *) wmMalloc ((ubyte4)size);
}
else
{
pTable = (WMB_HASH_TABLE_T *) wmPoolAlloc (memID, sizeof(WMB_HASH_TABLE_T));
pNodes = (HASH_T *) wmPoolAlloc (memID, (ubyte4)size);
}
if (NULL == pTable || NULL == pNodes)
{
if (NULL == memID)
{
if (NULL != pTable)
wmFree (pTable);
if (NULL != pNodes)
wmFree (pNodes);
}
else
{
if (NULL != pTable)
wmPoolFree (memID, pTable);
if (NULL != pNodes)
wmPoolFree (memID, pNodes);
}
return wmError (ERROR, "no memory");
}
memset(pNodes, 0, (ubyte4)size);
pTable->tableSize = rows;
pTable->pFuncCompare = pFuncCompare;
pTable->pFuncExtractKey = pFuncExtractKey;
pTable->pNodes = pNodes;
pTable->mem = memID;
pTable->pBlock = NULL;
*ppTable = pTable;
return OK;
}
/**************************************************************************
*
* wmHashDestruct - free a hash table
*
* RETURNS: N/A
*
*
* NOMANUAL
*/
void wmHashDestruct
(
WMB_HASH_TABLE_T * pTable /* pointer to hash table */
)
{
MEM_POOL_ID pool;
if (NULL != pTable->pBlock)
wmMemBlockDestroy (pTable->pBlock);
if (NULL != (pool = pTable->mem))
{
wmPoolFree (pool, pTable->pNodes);
wmPoolFree (pool, pTable);
}
else
{
wmFree (pTable->pNodes);
wmFree (pTable);
}
}
/**************************************************************************
*
* wmHashNodeNew - create a new hash node
*
* RETURNS: N/A
*
*
* NOMANUAL
*/
LOCAL HASH_T * wmHashNodeNew
(
WMB_HASH_TABLE_T * pTable /* hash table */
)
{
WM_BLOCK_T * pBlock;
HASH_T * pHash;
if (NULL == (pBlock = pTable->pBlock))
{
pBlock = wmMemBlockCreate(pTable->mem, NULL, pTable->tableSize, sizeof(HASH_T));
if (NULL == pBlock)
return NULL;
pTable->pBlock = pBlock;
}
if (NULL != (pHash = wmMemBlockEntryCreate(pBlock)))
wmZero(pHash);
return pHash;
}
/**************************************************************************
*
* wmHashEntryAdd - add a new element to hash table
*
* RETURNS: N/A
*
*
* NOMANUAL
*/
STATUS wmHashEntryAdd
(
WMB_HASH_TABLE_T * pHashTable, /* hash table */
sbyte * pName, /* name to register */
void * pId, /* identifier (component or session) */
void * pEntry /* database entry */
)
{
HASH_T * pNode;
HASH_T * pPrevNode;
fnHashCompare compare;
ubyte4 key;
if ((NULL == pHashTable) || (NULL == pEntry))
return wmError (ERROR_GENERAL_NOT_FOUND,
"wmHashEntryAdd: invalid table or entry");
/* Find the relevant bucket entry */
if (OK != wmHashEntryGet(pHashTable, pName, &key, &pNode))
return ERROR;
/* if we got a hit it's either a duplication or hash collision */
compare = pHashTable->pFuncCompare;
if (NULL != pNode->pEntry)
{
pPrevNode = pNode;
/* Check to make sure there aren't any duplicates */
while (NULL != pNode)
{
if (NULL == pNode->pEntry)
break;
/* don't bother w/ strings unless keys are same */
if ((key == pNode->key) &&
(NULL != pId && pId == pNode->owner) &&
compare (pName, pNode->pEntry))
{
DEBUG_MSG_1("Duplicate entry: %s\n", pName);
return wmError(ERROR_GENERAL_ACCESS_DENIED, "duplicate entry");
}
pPrevNode = pNode;
pNode = pNode->pNext;
}
if (NULL == pNode)
{
if (NULL == (pNode = wmHashNodeNew(pHashTable)))
return wmError(ERROR_GENERAL, "no memory");
}
/* don't link to ourselves */
if (pNode != pPrevNode)
pPrevNode->pNext = pNode;
}
pNode->pEntry = pEntry;
pNode->key = key;
pNode->owner = pId;
pHashTable->count++;
#ifdef __WM_DEBUG__
pNode->rid = pHashTable->count;
#endif
return OK;
} /* wmHashEntryAdd */
/**************************************************************************
*
* wmHashEntryFind - find a name in hash table
*
* RETURNS: N/A
*
*
* NOMANUAL
*/
void * wmHashEntryFind
(
WMB_HASH_TABLE_T * pTable,
sbyte * pName,
void * pID
)
{
ubyte4 key;
HASH_T * pNode;
if ((NULL == pTable) || (NULL == pName))
return NULL;
if (OK != wmHashEntryGet(pTable, pName, &key, &pNode))
return NULL;
if (NULL == pNode->pEntry)
return NULL;
/*
if (wmbEntryFlagGet(pEntry, DB_FLAG_ALIASED))
{
pName = wmbEntryNameGet(pEntry);
while (NAME_OK(pName))
pName++;
if (OK != wmHashEntryGet(pTable, ++pName, &key, &pNode))
return NULL;
}
*/
for ( ; NULL != pNode; pNode = pNode->pNext)
{
if (NULL == pNode->pEntry)
return NULL;
if (NULL != pID && pID != pNode->owner)
continue;
if (key != pNode->key)
continue;
if (pTable->pFuncCompare (pName, pNode->pEntry))
return pNode->pEntry;
}
return NULL;
} /* wmHashEntryFind */
#ifdef __WM_DEBUG__
/**************************************************************************
*
* wmHashDump - dump hash table
*
* RETURNS: N/A
*
*
* NOMANUAL
*/
void wmHashDump
(
WMB_HASH_TABLE_T * pTable
)
{
sbyte4 index;
HASH_T * pNode;
HASH_T * pTemp;
fnHashNodeName pFuncName;
pFuncName = pTable->pFuncName;
pNode = pTable->pNodes;
for (index = 0; index < pTable->tableSize; index++, pNode++)
{
for (pTemp = pNode; NULL != pTemp; pTemp = pTemp->pNext)
{
if (NULL == pTemp->pEntry)
continue;
printf("%3d 0x%x %s\n", index, pTemp->key, pFuncName(pTemp->pEntry));
}
}
}
#endif
/* eof wmHashLib.c */
@@ -0,0 +1,749 @@
/* wmInstanceLib.c - WindManage Instance library */
/*
* Copyright (c) 2004-2007, 2010-2013 Wind River Systems, Inc.
*
* The right to copy, distribute, modify or otherwise make use
* of this software may be licensed only pursuant to the terms
* of an applicable Wind River license agreement.
*/
/*
modification history
--------------------
01g,08apr13,r_w fix coverity issues for defect WIND00411995
01f,17may12,h_l replace NO_STRING with NULL_STRING (WIND00032212)
01e,03mar11,r_w prevent from accessing illegal address.defect WIND00255070
01d,29apr10,m_z eliminate compile warning
01c,29jan10,m_z VxWorks 64-bit support
(WIND00193649)
01b,24feb07,msa Correct the apigen comments so they match the actual routines
and correct any apigen errors that may occur.
01a,04may04,dlr derived from wmOidLib.c, adapted to string Instances
*/
/*
DESCRIPTION
This module contains support routines string-based instance manipulation.
All string instance sizes include the termination character.
This library does support base instances for the tables. They
are not yet used, but are reserved for heirarchical WindMarks
in the future. NOTE that termination character of the base
Instance must be accounted for when merging or comparing
Instances.
INCLUDE FILES: wm.h
*/
/* includes */
#include "wm.h"
#ifndef _WRS_CONFIG_LP64
int wmInstanceMax
#else
long wmInstanceMax
#endif
(
WM_INSTANCE_T inst
);
#ifdef __WM_DEBUG__
LOCAL BOOL debugEnabled = FALSE;
void wmInstanceDebug
(
WM_INSTANCE_T inst,
sbyte * pMsg
)
{
if (! debugEnabled)
return;
wmInstancePrint(inst, pMsg);
}
void wmInstanceDebugEnable
(
BOOL enable
)
{
debugEnabled = enable;
}
#endif /* __WM_DEBUG__ */
/**************************************************************************
*
* wmInstanceMax - max possible of Instance in bytes
*
*
* RETURNS:\is
*\i ERROR_GENERAL_NOT_FOUND
*\i OK
*\ie
*
* NOMANUAL
*/
#ifndef _WRS_CONFIG_LP64
int wmInstanceMax
#else
long wmInstanceMax
#endif
(
WM_INSTANCE_T inst
)
{
return (long)wmBufferMaxGet(inst);
}
/**************************************************************************
*
* wmInstanceLen - length of Instance in bytes (the terminator is counted)
*
*
* RETURNS:\is
*\i ERROR_GENERAL_NOT_FOUND
*\i OK
*\ie
*
* NOMANUAL
*/
#ifndef _WRS_CONFIG_LP64
int wmInstanceLen
#else
long wmInstanceLen
#endif
(
WM_INSTANCE_T inst
)
{
return (long)wmBufferUsedGet(inst);
}
/**************************************************************************
*
* wmInstancePrint - print ascii Instance w/ message
*
*
* RETURNS:\is
*\i ERROR_GENERAL_NOT_FOUND
*\i OK
*\ie
*
* NOMANUAL
*/
void wmInstancePrint
(
WM_INSTANCE_T pInstance,
sbyte * pMsg
)
{
sbyte temp[256];
if (OK != wmInstanceStringGet(pInstance, temp, sizeof(temp)))
strcpy(temp, "(empty)");
if (NULL == pMsg)
printf("%s\n", temp);
else
printf("%s %s\n", pMsg, temp);
}
/**************************************************************************
*
* wmInstanceFromString - create inst from an ascii string
*
* This routine copys the string-based instance into the provided buffer,
*
* If <msize> is greater than the storage required, the buffer size is
* increased to <msize>.
*
*
* RETURNS:\is
*\i inst buffer pointer
*\i NULL
*\ie
*
* NOMANUAL
*/
WM_BUFFER_T * wmInstanceFromString
(
sbyte * pString, /* ascii version of inst */
#ifndef _WRS_CONFIG_LP64
int msize /* optional max buffer size in bytes */
#else
long msize /* optional max buffer size in bytes */
#endif
)
{
WM_BUFFER_T * pInst;
#ifndef _WRS_CONFIG_LP64
int len = 1;
#else
long len = 1;
#endif
if (NULL_STRING(pString)) return NULL;
#ifndef _WRS_CONFIG_LP64
len = (int)strlen(pString) + 1; /* Count the terminator */
#else
len = (long)strlen(pString) + 1; /* Count the terminator */
#endif
if (msize < len) msize = len; /* set size of buffer to ask for */
/* create an Instance buffer */
#ifndef _WRS_CONFIG_LP64
pInst = wmBufferCreate (NULL, (unsigned int)msize, pString, DATATYPE_STRING_K, TRUE);
#else
pInst = wmBufferCreate (NULL, (unsigned long)msize, pString, DATATYPE_STRING_K, TRUE);
#endif
if (NULL == pInst) return NULL;
#ifndef _WRS_CONFIG_LP64
pInst->Used = (ubyte4)len;
#else
pInst->Used = (ubyte8)len;
#endif
return (pInst);
}
/**************************************************************************
*
* wmInstanceStringSet - update inst with an ascii string inst
*
* This routine simply copies/appends a string-based instance
*
* RETURNS:\is
*\i OK or ERROR
*\ie
*
* NOMANUAL
*/
STATUS wmInstanceStringSet
(
WM_INSTANCE_T pInstance,
sbyte * pString,
BOOL append
)
{
char * pInst;
#ifndef _WRS_CONFIG_LP64
int max;
int used;
unsigned int len;
#else
long max;
long used;
unsigned long len;
#endif
if ((NULL == pString) || (NULL == pInstance))
return wmError(ERROR_GENERAL_NO_DATA, "no data");
#ifndef _WRS_CONFIG_LP64
max = (int)wmBufferMaxGet(pInstance);
used = (int)wmBufferUsedGet(pInstance);
#else
max = (long)wmBufferMaxGet(pInstance);
used = (long)wmBufferUsedGet(pInstance);
#endif
pInst = wmBufferDataGet(pInstance);
if (NULL == pInst)
{
wmBufferUpdate(pInstance, NULL, 256, 0, FALSE);
#ifndef _WRS_CONFIG_LP64
max = (int)wmBufferMaxGet(pInstance);
#else
max = (long)wmBufferMaxGet(pInstance);
#endif
pInst = wmBufferDataGet(pInstance);
}
else
{
if (append)
pInst += used;
else
used = 0;
}
strcpy(pInst, pString); /* max !!! */
len = strlen(pString) + 1; /* count the terminator */
#ifndef _WRS_CONFIG_LP64
wmBufferUsedSet(pInstance, ((ubyte4)used + len));
#else
wmBufferUsedSet(pInstance, ((ubyte8)used + len));
#endif
return OK;
}
/**************************************************************************
*
* wmInstanceAppend - append one buffer onto another
*
*
* RETURNS: ERROR or OK
*
* NOMANUAL
*/
STATUS wmInstanceAppend
(
WM_INSTANCE_T pDestInst,
WM_INSTANCE_T pAddInst
)
{
#ifndef _WRS_CONFIG_LP64
/* ubyte4 destLen;*/
ubyte4 addLen;
/* ubyte4 total;*/
#else
/* ubyte8 destLen;*/
ubyte8 addLen;
/* ubyte8 total;*/
#endif
/*sbyte * pDest;*/
sbyte * pAdd;
if (NULL == pDestInst || NULL == pAddInst)
return wmError(ERROR_GENERAL_NO_DATA, "wmInstanceAppend: null arg(s)");
/*pDest = wmBufferDataGet(pDestInst);*/
pAdd = wmBufferDataGet(pAddInst);
/* total = wmBufferMaxGet(pDestInst);
destLen = wmBufferUsedGet(pDestInst);*/
addLen = wmBufferUsedGet(pAddInst);
/* wmBufferAppend will skip terminator in the Dest string instance buffer */
return wmBufferAppend(pDestInst, pAdd, addLen);
}
/**************************************************************************
*
* wmInstanceEqual - compare 2 insts
*
* RETURNS: TRUE if same
*
* NOMANUAL
*/
BOOL wmInstanceEqual
(
WM_INSTANCE_T orig,
WM_INSTANCE_T test
)
{
#ifndef _WRS_CONFIG_LP64
ubyte4 destLen;
ubyte4 addLen;
#else
ubyte8 destLen;
ubyte8 addLen;
#endif
sbyte * pDest;
sbyte * pAdd;
pDest = wmBufferDataGet(orig);
pAdd = wmBufferDataGet(test);
if (NULL == pDest || NULL == pAdd)
return FALSE;
destLen = wmBufferUsedGet(orig);
addLen = wmBufferUsedGet(test);
/* make sure there's enough space (fix later: just resize) */
if (addLen != destLen)
return FALSE;
return (0 == memcmp(pDest, pAdd, addLen));
}
/**************************************************************************
*
* wmInstanceCmp - compare 2 insts
*
* RETURNS:
*
* NOMANUAL
*/
int wmInstanceCmp
(
WM_INSTANCE_T orig,
WM_INSTANCE_T test
)
{
#ifndef _WRS_CONFIG_LP64
ubyte4 i;
ubyte4 origLen;
ubyte4 testLen;
#else
ubyte8 i;
ubyte8 origLen;
ubyte8 testLen;
#endif
ubyte * pOrig;
ubyte * pTest;
pOrig = wmBufferDataGet(orig);
pTest = wmBufferDataGet(test);
if (NULL == pTest || NULL == pOrig)
return 0;
origLen = wmBufferUsedGet(orig) - 1; /* skip terminators */
testLen = wmBufferUsedGet(test) - 1;
for (i = 0; (i < origLen) && (i < testLen); i++, pOrig++, pTest++)
{
if (*pOrig < *pTest)
return -1;
if (*pOrig > *pTest)
return 1;
}
/* so far they are the same */
if (origLen < testLen)
return -1;
if (origLen > testLen)
return 1;
return 0;
}
/**************************************************************************
*
* wmInstanceTruncate - truncate inst
*
*
* RETURNS: ERROR or OK
*
* NOMANUAL
*/
STATUS wmInstanceTruncate
(
WM_INSTANCE_T inst,
#ifndef _WRS_CONFIG_LP64
sbyte4 length /* in bytes */
#else
sbyte8 length /* in bytes */
#endif
)
{
sbyte * pData;
#ifndef _WRS_CONFIG_LP64
ubyte4 used;
ubyte4 max;
#else
ubyte8 used;
ubyte8 max;
#endif
pData = wmBufferDataGet (inst);
max = wmBufferMaxGet (inst);
used = wmBufferUsedGet (inst);
pData += length;
#ifndef _WRS_CONFIG_LP64
if (length > (sbyte4)used)
#else
if (length > (sbyte8)used)
#endif
return wmError(ERROR_GENERAL_ILLEGAL_VALUE, "wmInstanceTruncate: length too long");
/* nothing to do */
#ifndef _WRS_CONFIG_LP64
if (length == (sbyte4)used)
#else
if (length == (sbyte8)used)
#endif
return OK;
#ifndef _WRS_CONFIG_LP64
memset(pData, 0, (max - (ubyte4)length)); /* the zero's double as the string terminator */
wmBufferUsedSet(inst, (ubyte4)length);
#else
memset(pData, 0, (max - (ubyte8)length)); /* the zero's double as the string terminator */
wmBufferUsedSet(inst, (ubyte8)length);
#endif
return OK;
}
/**************************************************************************
*
* wmInstanceSuffix - create new buffer containing unique instance suffix
*
*
* RETURNS: buffer with suffix only
*
* NOMANUAL
*/
WM_INSTANCE_T wmInstanceSuffix
(
WM_INSTANCE_T pBaseInst,
WM_INSTANCE_T pFullInst
)
{
WM_INSTANCE_T pSuffix;
#ifndef _WRS_CONFIG_LP64
ubyte4 baseLen;
ubyte4 fullLen;
ubyte4 index;
#else
ubyte8 baseLen;
ubyte8 fullLen;
ubyte8 index;
#endif
sbyte * pBase;
sbyte * pFull;
if (NULL == pBaseInst || NULL == pFullInst)
return NULL;
pBase = wmBufferDataGet (pBaseInst);
pFull = wmBufferDataGet (pFullInst);
baseLen = wmBufferUsedGet (pBaseInst);
fullLen = wmBufferUsedGet (pFullInst);
if (baseLen >= fullLen)
return NULL;
/* Skip the zero terminator */
if (0 < baseLen)
baseLen--;
/* base should match beginning of full */
if (0 != baseLen) for (index = baseLen; index > 0; index --, pBase++, pFull++)
{
if (*pBase != *pFull)
return NULL;
}
/* only create suffix if it doesn't already exist */
fullLen -= baseLen;
pSuffix = wmBufferCreate(NULL, fullLen, pFull, wmBufferTypeGet(pFullInst), TRUE);
return pSuffix;
}
/**************************************************************************
*
* wmInstanceScalerSet - there is currently no definition for non-OID scalars
*
* RETURNS: OK
*
*
* NOMANUAL
*/
#if 0
void wmInstanceScalerSet
(
WM_INSTANCE_T inst
)
{
int zero = 0;
wmBufferAppend(inst, &zero, sizeof(zero));
}
/* return if scaler */
BOOL wmInstanceScaler
(
WM_INSTANCE_T inst
)
{
int * pData;
int size;
if (0 >= (size = wmBufferUsedGet(inst)))
return FALSE;
pData = wmBufferDataGet(inst);
pData += size;
return (*pData == 0);
}
#endif /* 0 */
/**************************************************************************
*
* wmInstanceStringGet - create ascii version of inst
*
*
* RETURNS:\is
*\i ERROR_GENERAL_NOT_FOUND
*\i OK
*\ie
*
* NOMANUAL
*/
STATUS wmInstanceStringGet
(
WM_INSTANCE_T inst,
sbyte * pString,
#ifndef _WRS_CONFIG_LP64
sbyte4 strLen
#else
sbyte8 strLen
#endif
)
{
int * pData;
#ifndef _WRS_CONFIG_LP64
sbyte4 instLen;
#else
sbyte8 instLen;
#endif
if (wmInstanceBad(inst))
return wmError(ERROR_GENERAL_INVALID, "wmInstanceStringGet: bad inst");
pData = wmBufferDataGet (inst);
#ifndef _WRS_CONFIG_LP64
instLen = (sbyte4)wmBufferUsedGet (inst);
#else
instLen = (sbyte8)wmBufferUsedGet (inst);
#endif
if (NULL == pData || 1 > instLen)
return wmError(ERROR_GENERAL_NO_DATA, "wmInstanceStringGet: no data");
if (strLen < instLen) /* string terminators are already included in these sizes */
return wmError(ERROR_GENERAL_NO_DATA, "wmInstanceStringGet: dest buffer too small");
strcpy(pString, (char *) pData);
return OK;
}
/**************************************************************************
*
* wmInstanceValid - does Instance contain valid data
*
*
* RETURNS:\is
*\i ERROR
*\i OK
*\ie
*
* NOMANUAL
*/
STATUS wmInstanceValid
(
WM_INSTANCE_T inst
)
{
if (wmInvalid(inst))
return wmError(ERROR_GENERAL_INVALID, "wmInstanceInvalid: bad Instance");
if (wmInvalid(wmBufferDataGet(inst)))
return wmError(ERROR_GENERAL_INVALID, "wmInstanceInvalid: bad data");
return OK;
}
/**************************************************************************
*
* wmBufferSuffix - copy unique portion of buffer
*
* RETURNS: N/A
*
*
* NOMANUAL
*/
STATUS wmBufferInstSuffix
(
WM_BUFFER_T * pRoot, /* [in] root buffer */
WM_BUFFER_T * pFull, /* [in] complete buffer */
WM_BUFFER_T * pSuffix /* [in/out] portion complete root lacks */
)
{
sbyte * pRootData = NULL;
sbyte * pFullData = NULL;
#ifndef _WRS_CONFIG_LP64
ubyte4 rootLen;
ubyte4 fullLen;
#else
ubyte8 rootLen;
ubyte8 fullLen;
#endif
pRootData = wmBufferDataGet(pRoot);
pFullData = wmBufferDataGet(pFull);
if((NULL == pRootData)||(NULL == pFullData))
{
wmInstancePrint(pRoot, "root");
wmInstancePrint(pFull, "full");
return ERROR;
}
rootLen = wmBufferUsedGet(pRoot) - 1; /* don't count the zero terminator here */
fullLen = wmBufferUsedGet(pFull);
if (memcmp(pRootData, pFullData, rootLen) != 0)
{
wmInstancePrint(pRoot, "root");
wmInstancePrint(pFull, "full");
return ERROR;
}
return wmBufferUpdate (pSuffix, &pFullData[rootLen], fullLen - rootLen,
wmBufferTypeGet(pFull), TRUE);
}
/* eof wmInstanceLib.c */
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,523 @@
/* wmLinkListLib.c - RCB linklist library */
/* Copyright 2001-2007 Wind River Systems, Inc. */
/*
modification history
--------------------
01d,15mar10,m_z VxWorks 64bit support (WIND00193649)
01c,24feb07,msa Correct the apigen comments so they match the actual routines
and correct any apigen errors that may occur.
01b,11oct01,rws comments modified
01a,01aug01,pns written
*/
/*
DESCRIPTION
LinkListLib.c
INCLUDE FILES: rc2.h
*/
/* includes */
#include "wm.h"
/**************************************************************************
*
* wmLinkListMoveToEnd - move to end of linklist.
*
* RETURNS: Pointer to end of linklist.
*
*
* NOMANUAL
*/
static WM_LIST_T * wmLinkListMoveToEnd
(
WM_LIST_T * pFindEnd
)
{
if (NULL == pFindEnd)
return NULL;
while (NULL != pFindEnd->pNext)
pFindEnd = pFindEnd->pNext;
return pFindEnd;
}
/**************************************************************************
*
* wmLinkListAddObject - Add an object to a linklist.
*
* RETURNS:\is
*\i OK
*\i ERROR_GENERAL_NOT_FOUND
*\i SYS_ERROR_NO_MEMORY
*\ie
*
* NOMANUAL
*/
STATUS wmLinkListAddObject
(
WM_LIST_T * p_lstHead,
void * pData
)
{
WM_LIST_T *p_lstNewElement, *pFindEnd = p_lstHead;
if (NULL == p_lstHead)
return ERROR_GENERAL_NOT_FOUND;
if ((NULL == p_lstHead->pNext) && (NULL == p_lstHead->pObject))
{
p_lstHead->pObject = pData;
return OK;
}
p_lstNewElement = (WM_LIST_T *) wmMalloc (sizeof(WM_LIST_T));
if (NULL == p_lstNewElement)
return SYS_ERROR_NO_MEMORY;
p_lstNewElement->pObject = pData;
p_lstNewElement->pNext = NULL;
pFindEnd = wmLinkListMoveToEnd(pFindEnd);
pFindEnd->pNext = p_lstNewElement;
return OK;
} /* wmLinkListAddObject */
/**************************************************************************
*
* wmLinkListGetNextObject - Get the next object from a linklist.
*
* RETURNS: A pointer to the next object.
*
*
* NOMANUAL
*/
void * wmLinkListGetNextObject
(
WM_LIST_T ** p_lstSpot
)
{
void * pTemp;
if (NULL == p_lstSpot)
return NULL;
if (NULL == (*p_lstSpot))
return NULL;
pTemp = (*p_lstSpot)->pObject;
*p_lstSpot = (*p_lstSpot)->pNext;
return pTemp;
}
/**************************************************************************
*
* wmLinkListGetFirstObject - Get the first object from a linklist.
*
* RETURNS: A pointer to the first object.
*
*
* NOMANUAL
*/
void * wmLinkListGetFirstObject
(
WM_LIST_T * plstHead
)
{
if (NULL == plstHead)
return NULL;
return plstHead->pObject;
}
/**************************************************************************
*
* wmLinkListFindObject - Find an object with value <pValue> in a linklist.
*
* RETURNS: A pointer to the object.
*
*
* NOMANUAL
*/
void * wmLinkListFindObject
(
WM_LIST_T * p_lstHead,
void * pValue,
BOOL (*fComparisonHandler)(void *, void *)
)
{
void *pObject;
if ((NULL == p_lstHead) || (NULL == fComparisonHandler))
return NULL;
while (NULL != (pObject = wmLinkListGetNextObject(&p_lstHead)))
{
if (TRUE == fComparisonHandler(pValue, pObject))
return pObject;
}
return NULL;
}
/**************************************************************************
*
* wmLinkListSize - Get the length of a linklist.
*
* RETURNS: The length <ListLen> of the linklist.
*
*
* NOMANUAL
*/
Length wmLinkListSize
(
WM_LIST_T * p_lstHead
)
{
Length ListLen = 0;
if (NULL == p_lstHead)
return ListLen;
if (NULL != p_lstHead->pObject)
ListLen++;
while (NULL != p_lstHead->pNext)
{
p_lstHead = p_lstHead->pNext;
ListLen++;
}
return ListLen;
}
/**************************************************************************
*
* wmLinkListRemoveObject - Remove an object from a linklist.
*
* RETURNS:\is
*\i ERROR_GENERAL_NOT_FOUND
*\i OK
*\ie
*
* NOMANUAL
*/
STATUS wmLinkListRemoveObject
(
WM_LIST_T * p_lstHead,
BOOL (*funcComparisonHandler)(void *)
)
{
WM_LIST_T *p_lstPrevious, *p_lstCurrent;
if ((NULL == p_lstHead) || (NULL == p_lstHead->pObject) ||
(NULL == funcComparisonHandler))
{
return ERROR_GENERAL_NOT_FOUND;
}
if (funcComparisonHandler(p_lstHead->pObject))
{
WM_LIST_T *p_lstTemp;
wmFree(p_lstHead->pObject);
if (NULL == p_lstHead->pNext)
{
p_lstHead->pObject = NULL;
return OK;
}
p_lstHead->pObject = p_lstHead->pNext->pObject;
p_lstTemp = p_lstHead->pNext;
p_lstHead->pNext = p_lstHead->pNext->pNext;
wmFree(p_lstTemp);
return OK;
}
p_lstPrevious = p_lstHead;
p_lstCurrent = p_lstPrevious->pNext;
while (NULL != p_lstCurrent)
{
if (funcComparisonHandler(p_lstCurrent->pObject))
{
wmFree(p_lstCurrent->pObject);
p_lstPrevious->pNext = p_lstCurrent->pNext;
wmFree(p_lstCurrent);
return OK;
}
p_lstPrevious = p_lstCurrent;
p_lstCurrent = p_lstCurrent->pNext;
}
return ERROR_GENERAL_NOT_FOUND;
} /* wmLinkListRemoveObject */
/**************************************************************************
*
* wmLinkListSelectiveRemoveObject - Remove an object from a linklist.
*
* Remove an object with parameter <pRemoveParam> from a linklist.
*
* RETURNS:\is
*\i ERROR_GENERAL_NOT_FOUND
*\i OK
*\ie
*
* NOMANUAL
*/
STATUS wmLinkListSelectiveRemoveObject
(
WM_LIST_T * p_lstHead,
void * pRemoveParam,
BOOL (*funcComparisonHandler)(void *, void *))
{
WM_LIST_T * p_lstPrevious;
WM_LIST_T * p_lstCurrent;
if ((NULL == p_lstHead) || (NULL == p_lstHead->pObject) ||
(NULL == funcComparisonHandler))
{
return ERROR_GENERAL_NOT_FOUND;
}
if (funcComparisonHandler(pRemoveParam, p_lstHead->pObject))
{
WM_LIST_T *p_lstTemp;
wmFree(p_lstHead->pObject);
if (NULL == p_lstHead->pNext)
{
p_lstHead->pObject = NULL;
return OK;
}
p_lstHead->pObject = p_lstHead->pNext->pObject;
p_lstTemp = p_lstHead->pNext;
p_lstHead->pNext = p_lstHead->pNext->pNext;
wmFree(p_lstTemp);
return OK;
}
p_lstPrevious = p_lstHead;
p_lstCurrent = p_lstPrevious->pNext;
while (NULL != p_lstCurrent)
{
if (funcComparisonHandler(pRemoveParam, p_lstCurrent->pObject))
{
wmFree(p_lstCurrent->pObject);
p_lstPrevious->pNext = p_lstCurrent->pNext;
wmFree(p_lstCurrent);
return OK;
}
p_lstPrevious = p_lstCurrent;
p_lstCurrent = p_lstCurrent->pNext;
}
return ERROR_GENERAL_NOT_FOUND;
} /* wmLinkListSelectiveRemoveObject */
/**************************************************************************
*
* wmLinkListTraverse - Traverse a linklist.
*
*
* RETURNS:\is
*\i ERROR_GENERAL_NOT_FOUND
*\i OK
*\ie
*
* NOMANUAL
*/
STATUS wmLinkListTraverse
(
WM_LIST_T * p_lstHead,
void (*funcProcessObject)(void *)
)
{
WM_LIST_T * p_lstSpot = p_lstHead;
void * pObject;
if ((NULL == p_lstHead) || (NULL == funcProcessObject))
return ERROR_GENERAL_NOT_FOUND;
while (NULL != (pObject = wmLinkListGetNextObject(&p_lstSpot)))
funcProcessObject(pObject);
return OK;
}
/**************************************************************************
*
* wmLinkListConstruct - Create a linklist.
*
*
* RETURNS: A pointer to the new linklist.
*
*
* NOMANUAL
*/
WM_LIST_T * wmLinkListConstruct
(
void
)
{
WM_LIST_T * pList;
pList = (WM_LIST_T *) wmMalloc (sizeof(WM_LIST_T));
if (NULL == pList)
return NULL;
pList->pObject = NULL;
pList->pNext = NULL;
return pList;
}
/**************************************************************************
*
* wmLinkListParamDestruct - wmLinkListParamDestruct
*
*
* RETURNS: n/a
*
*
* NOMANUAL
*/
void wmLinkListParamDestruct
(
WM_LIST_T ** p_lstToDelete,
void (*funcObject_Destruct)(void *, void *),
void * second_param
)
{
WM_LIST_T * p_lstCurrent, *p_lstNext;
if ((NULL == p_lstToDelete) || (NULL == funcObject_Destruct))
return;
p_lstCurrent = *(p_lstToDelete);
while (NULL != p_lstCurrent)
{
if (NULL != p_lstCurrent->pObject)
funcObject_Destruct(p_lstCurrent->pObject, second_param);
p_lstNext = p_lstCurrent->pNext;
wmFree(p_lstCurrent);
p_lstCurrent = p_lstNext;
}
*p_lstToDelete = NULL;
}
/**************************************************************************
*
* wmLinkListDestruct - Destroy a linklist.
*
*
* RETURNS: n/a
*
*
* NOMANUAL
*/
void wmLinkListDestruct
(
WM_LIST_T ** p_lstToDelete,
void (*funcObject_Destruct)(void *)
)
{
WM_LIST_T *p_lstCurrent, *p_lstNext;
if ((NULL == p_lstToDelete) || (NULL == *p_lstToDelete) || (NULL == funcObject_Destruct))
return;
p_lstCurrent = *(p_lstToDelete);
while (NULL != p_lstCurrent)
{
if (NULL != p_lstCurrent->pObject)
funcObject_Destruct(p_lstCurrent->pObject);
p_lstNext = p_lstCurrent->pNext;
wmFree(p_lstCurrent);
p_lstCurrent = p_lstNext;
}
*p_lstToDelete = NULL;
}
@@ -0,0 +1,343 @@
/* wmLogLib.c - WindManage logging library */
/* Copyright (c) 2001-2007 2010 2012 Wind River Systems, Inc. */
/*
modification history
--------------------
01g,31jan12,r_w fix defect WIND00326056 to eliminate compile warning
01f,28jul10,m_z eliminate compile warning
01e,27jul10,m_z eliminate compile warning
01d,29apr10,m_z eliminate compile warining
01c,15mar10,m_z VxWorks 64bit support (WIND00193649)
01b,24feb07,msa Correct the apigen comments so they match the actual routines
and correct any apigen errors that may occur.
01a,01aug01,pns written
02a,07dec01,pns renamed, updated
*/
/*
DESCRIPTION
This module implements logging to file or syslog servers
INCLUDE FILES: wm2.h 'wmb.h'
*/
/* includes */
#include "wm.h"
#include <string.h>
typedef struct LOG_INFO_S
{
ubyte4 flags;
ubyte4 syslog_host;
OS_SOCKET_T sock;
FILE * pFile;
} LOG_INFO_T, * LOG_PTR_T;
LOCAL LOG_INFO_T systemLog;
LOCAL LOG_ID_T log = &systemLog;
#define wmLogBad(x) (NULL == x)
#define wmLogGet(x) x = &mLog
#define wmLogTypeGet(x) ((LOG_PTR_T) x)->type
#define wmLogFileGet(x) ((LOG_PTR_T) x)->pFile
#define wmLogSockGet(x) ((LOG_PTR_T) x)->sock
#define wmLogHostGet(x) ((LOG_PTR_T) x)->syslog_host
#define wmLogTypeSet(x,y) ((LOG_PTR_T) x)->type = y
#define wmLogFileSet(x,y) ((LOG_PTR_T) x)->pFile = y
#define wmLogSockSet(x,y) ((LOG_PTR_T) x)->sock = y
#define wmLogHostSet(x,y) ((LOG_PTR_T) x)->syslog_host = y
#define wmLogEnabled(x,y) FLAG_SET(((LOG_PTR_T) x), y)
#define wmLogEnable(x,y) SET_FLAG(((LOG_PTR_T) x), y)
#define wmLogDisable(x,y) CLEAR_FLAG(((LOG_PTR_T) x), y)
#define LOG_FLAG_THREAD 0x01
#define LOG_FLAG_STDERR 0x02
#define LOG_FLAG_SYSLOG 0x04
#define LOG_FLAG_FILE 0x08
void wmLogThreads
(
BOOL enabled
)
{
if (enabled)
wmLogEnable (log, LOG_FLAG_THREAD);
else
wmLogDisable (log, LOG_FLAG_THREAD);
}
BOOL wmLogThreadsGet
(
void
)
{
return wmLogEnabled(log, LOG_FLAG_THREAD);
}
void wmLogStderr
(
BOOL enabled
)
{
if (enabled)
wmLogEnable (log, LOG_FLAG_STDERR);
else
wmLogDisable (log, LOG_FLAG_STDERR);
}
BOOL wmLogStderrGet
(
void
)
{
return wmLogEnabled(log, LOG_FLAG_STDERR);
}
void wmLogReset
(
void
)
{
memset(log, 0, sizeof(LOG_INFO_T));
}
/**************************************************************************
*
* wmLogSyslogInit - initalize syslog to go to <pHost>
*
* RETURNS:
*
* NOMANUAL
*/
LOCAL STATUS wmLogSyslogInit
(
LOG_ID_T slog,
char * pHost
)
{
wmnetUdpSocketCreate(&wmLogSockGet(slog));
wmnetAddressResolve(pHost, (ubyte4 *)&wmLogHostGet(slog));
return OK;
}
/**************************************************************************
*
* wmLogInit - initalize logging to use file <pFileName>
*
* RETURNS:
* \is
*
* \i NULL
* file doesn't exist
* \ie
*
* NOMANUAL
*/
STATUS wmLogOpen
(
LOG_TYPE_T type,
char * pName
)
{
FILE * pFile;
wmLogReset();
switch(type)
{
case LOG_TYPE_FILE:
if (NULL == pName)
return wmError (ERROR, "wmLogInit: name is null");
if (NULL == (pFile = fopen(pName, "w")))
return wmError (ERROR, "wmLogInit: unable to open file");
wmLogEnable (log, LOG_FLAG_FILE);
wmLogFileSet (log, pFile);
break;
case LOG_TYPE_SYSLOG:
if (NULL == pName)
return wmError (ERROR, "wmLogInit: name is null");
wmLogEnable (log, LOG_FLAG_SYSLOG);
wmLogSyslogInit (log, pName);
break;
case LOG_TYPE_STDERR:
wmLogEnable (log, LOG_FLAG_STDERR);
break;
default:
return wmError (ERROR, "wmLogInit");
}
return OK;
}
/**************************************************************************
*
* wmLogSyslog - send <pMsg> to a remote syslog server
*
* RETURNS: N/A
*
* NOMANUAL
*/
void wmLogSyslog
(
char * pMsg
)
{
if (NULL == pMsg)
pMsg = "(no message)";
wmnetUdpSendTo(wmLogSockGet(log), wmLogHostGet(log), 514, pMsg, strlen(pMsg));
}
/**************************************************************************
*
* wmLogWrite - write <pText> to log
*
* RETURNS: N/A
*
*
* NOMANUAL
*/
void wmLogWrite
(
char * pText
)
{
if (NULL == pText)
return;
if (wmLogEnabled(log, LOG_FLAG_FILE))
{
fprintf (wmLogFileGet (log), "%s\r\n", pText);
fflush (wmLogFileGet (log));
}
if (wmLogEnabled(log, LOG_FLAG_SYSLOG))
wmLogSyslog (pText);
}
/**************************************************************************
*
* wmLogClose - release resouwmes used for logging
*
* RETURNS: N/A
*
*
* NOMANUAL
*/
void wmLogClose
(
void
)
{
if (wmLogEnabled(log, LOG_FLAG_FILE))
fclose (wmLogFileGet (log));
if (wmLogEnabled(log, LOG_FLAG_SYSLOG))
wmnetSocketClose (wmLogSockGet (log));
}
/**************************************************************************
*
* wmLogPrintf - send formatted string <pMsg> to log
*
* RETURNS: N/A
*
* NOMANUAL
*/
void wmLogPrintf
(
char * pMsg,
...
)
{
char buffer[256];
char * pBuf;
va_list vaList;
if (NULL == pMsg)
return;
if (wmLogEnabled(log, LOG_FLAG_STDERR) && wmLogEnabled(log, LOG_FLAG_THREAD))
#ifndef _WRS_CONFIG_LP64
fprintf(stderr, "Thread (0x%x) : ", (int)taskIdSelf());
#else
fprintf(stderr, "Thread (0x%p) : ", (void*)taskIdSelf());
#endif
va_start (vaList, pMsg);
if (wmLogEnabled(log, LOG_FLAG_SYSLOG))
{
pBuf = buffer;
if (wmLogEnabled(log, LOG_FLAG_THREAD))
{
#ifndef _WRS_CONFIG_LP64
sprintf(pBuf, "TID: %-5x ", (int)taskIdSelf());
#else
sprintf(pBuf, "TID: %-5p ", (void *) (taskIdSelf()));
#endif
wmLogSyslog(buffer);
pBuf += strlen(buffer);
}
vsprintf(pBuf, pMsg, vaList);
wmLogSyslog(pBuf);
}
if (wmLogEnabled(log, LOG_FLAG_STDERR))
vfprintf(stderr, pMsg, vaList);
if (wmLogEnabled(log, LOG_FLAG_FILE))
vfprintf (wmLogFileGet (log), pMsg, vaList);
va_end (vaList);
}
/**************************************************************************
*
* wmLogSyslogSend - send <pMsg> to a syslog server <pHost>
*
* RETURNS: N/A
*
* NOMANUAL
*/
void wmLogSyslogSend
(
char * pHost,
char * pMsg
)
{
wmLogReset();
wmLogOpen (LOG_TYPE_SYSLOG, pHost);
wmLogSyslog (pMsg);
wmLogClose ();
}
@@ -0,0 +1,416 @@
/* wmMD5.c - MD5 Interface Routines */
/* Copyright(c) 2005-2007, 2010, 2012 Wind River Systems, Inc.
*
* The right to copy, distribute, modify or otherwise make use
* of this software may be licensed only pursuant to the terms
* of an applicable Wind River license agreement.
*/
/*
modification history
--------------------
01e,18apr12,r_w remove dependence of retrofit.h
Requirement: WIND00299859
01d,15mar10,m_z VxWorks 64bit support (WIND00193649)
01c,24feb07,msa Correct the apigen comments so they match the actual routines
and correct any apigen errors that may occur.
01b,25apr05,??? Update JS Auth #define ordering
01a,17sep04,dkg ported from RC3.3 to WM4.4 for JavaScript Authentication
*/
/*-----------------------------------------------------------------------*/
/*
**********************************************************************
** Copyright (C) 1990, RSA Data Security, Inc. All rights reserved. **
** **
** License to copy and use this software is granted provided that **
** it is identified as the "RSA Data Security, Inc. MD5 Message **
** Digest Algorithm" in all material mentioning or referencing this **
** software or this function. **
** **
** License is also granted to make and use derivative works **
** provided that such works are identified as "derived from the RSA **
** Data Security, Inc. MD5 Message Digest Algorithm" in all **
** material mentioning or referencing the derived work. **
** **
** RSA Data Security, Inc. makes no representations concerning **
** either the merchantability of this software or the suitability **
** of this software for any particular purpose. It is provided "as **
** is" without express or implied warranty of any kind. **
** **
** These notices must be retained in any copies of any part of this **
** documentation and/or software. **
**********************************************************************
*/
/* See if Digest is enabled globally */
#include "wm_options.h"
#ifdef __JAVASCRIPT_DIGEST_ENABLED__
#include "httpLib.h"
#include "wmMD5.h"
/* forward references */
extern void wmMD5Init (MD5_CTX *mdContext);
extern void wmMD5Update(MD5_CTX *mdContext, ubyte *inBuf, ubyte4 inLen);
extern void wmMD5Final (MD5_CTX *mdContext);
static void wmTransform (ubyte4 *buf, ubyte4 *in);
static ubyte PADDING[64] =
{
0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
/*-----------------------------------------------------------------------*/
/* F, G and H are basic MD5 functions: selection, majority, parity */
#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
#define H(x, y, z) ((x) ^ (y) ^ (z))
#define I(x, y, z) ((y) ^ ((x) | (~z)))
/* ROTATE_LEFT rotates x left n bits */
#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4 */
/* Rotation is separate from addition to prevent recomputation */
#define FF(a, b, c, d, x, s, ac) \
{ (a) += F ((b), (c), (d)) + (x) + (ubyte4)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
#define GG(a, b, c, d, x, s, ac) \
{ (a) += G ((b), (c), (d)) + (x) + (ubyte4)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
#define HH(a, b, c, d, x, s, ac) \
{ (a) += H ((b), (c), (d)) + (x) + (ubyte4)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
#define II(a, b, c, d, x, s, ac) \
{ (a) += I ((b), (c), (d)) + (x) + (ubyte4)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
static OS_SEM_T MD5_MUTEX;
/*-----------------------------------------------------------------------*/
extern STATUS wmMD5INIT(void)
{
return wmosSemCreate(&MD5_MUTEX, 1, 0);
}
/*-----------------------------------------------------------------------*/
static STATUS wmMD5MutexWait()
{
return wmosSemTake(MD5_MUTEX, WAIT_FOREVER_K);
}
/*-----------------------------------------------------------------------*/
static STATUS wmMD5MutexRelease()
{
return wmosSemGive(MD5_MUTEX);
}
/*-----------------------------------------------------------------------*/
extern void wmMD5Init(MD5_CTX *mdContext)
{
mdContext->i[0] = mdContext->i[1] = (ubyte4)0;
/* Load magic initialization constants. */
mdContext->buf[0] = (ubyte4)0x67452301;
mdContext->buf[1] = (ubyte4)0xefcdab89;
mdContext->buf[2] = (ubyte4)0x98badcfe;
mdContext->buf[3] = (ubyte4)0x10325476;
}
/*-----------------------------------------------------------------------*/
extern void wmMD5Update(MD5_CTX *mdContext, ubyte *inBuf, ubyte4 inLen)
{
ubyte4 in[16];
sbyte4 mdi;
ubyte4 i, ii;
/* compute number of bytes mod 64 */
mdi = (sbyte4)((mdContext->i[0] >> 3) & 0x3F);
/* update number of bits */
if ((mdContext->i[0] + ((ubyte4)inLen << 3)) < mdContext->i[0])
mdContext->i[1]++;
mdContext->i[0] += ((ubyte4)inLen << 3);
mdContext->i[1] += ((ubyte4)inLen >> 29);
while (inLen--)
{
/* add new character to buffer, increment mdi */
mdContext->in[mdi++] = *inBuf++;
/* transform if necessary */
if (mdi == 0x40)
{
for (i = 0, ii = 0; i < 16; i++, ii += 4)
in[i] = (((ubyte4)mdContext->in[ii+3]) << 24) | (((ubyte4)mdContext->in[ii+2]) << 16) |
(((ubyte4)mdContext->in[ii+1]) << 8) | ((ubyte4)mdContext->in[ii]);
wmTransform (mdContext->buf, in);
mdi = 0;
}
}
} /* wmMD5Update */
/*-----------------------------------------------------------------------*/
extern void wmMD5Final(MD5_CTX *mdContext)
{
ubyte4 in[16];
sbyte4 mdi;
ubyte4 i, ii;
ubyte4 padLen;
/* save number of bits */
in[14] = mdContext->i[0];
in[15] = mdContext->i[1];
/* compute number of bytes mod 64 */
mdi = (sbyte4)((mdContext->i[0] >> 3) & 0x3F);
/* pad out to 56 mod 64 */
padLen = (mdi < 56) ? (56 - mdi) : (120 - mdi);
wmMD5Update(mdContext, PADDING, padLen);
/* append length in bits and transform */
for (i = 0, ii = 0; i < 14; i++, ii += 4)
in[i] = (((ubyte4)mdContext->in[ii+3]) << 24) | (((ubyte4)mdContext->in[ii+2]) << 16) |
(((ubyte4)mdContext->in[ii+1]) << 8) | ((ubyte4)mdContext->in[ii]);
wmTransform (mdContext->buf, in);
/* store buffer in digest */
for (i = 0, ii = 0; i < 4; i++, ii += 4)
{
mdContext->digest[ii] = (ubyte) (mdContext->buf[i] & 0xFF);
mdContext->digest[ii+1] = (ubyte)((mdContext->buf[i] >> 8) & 0xFF);
mdContext->digest[ii+2] = (ubyte)((mdContext->buf[i] >> 16) & 0xFF);
mdContext->digest[ii+3] = (ubyte)((mdContext->buf[i] >> 24) & 0xFF);
}
} /* wmMD5Final */
/*-----------------------------------------------------------------------*/
extern STATUS wmMD5MessageCompare(sbyte *pFirstMesg, sbyte *pSecondMesg)
{
if ((NULL == pFirstMesg) || (NULL == pSecondMesg))
return kMD5_NoMatch;
return (0 == MEMCMP(pFirstMesg, pSecondMesg, kDigestMesgBufSize)) ? kMD5_Match : kMD5_NoMatch;
}
/*-----------------------------------------------------------------------*/
extern STATUS wmMD5MessageDigest(sbyte *pInputMessage, Length MesgLen, sbyte *pRetDigestMesg)
{
MD5_CTX* pMdContext;
/* JavaScript digest style. JAB */
if (NULL == pRetDigestMesg)
return ERROR_GENERAL_NO_DATA;
MEMSET(pRetDigestMesg, 0x00, kDigestMesgBufSize);
if (NULL == pInputMessage)
return ERROR_GENERAL_NO_DATA;
if (OK != wmMD5MutexWait())
return SYS_ERROR_MUTEX_WAIT;
if (NULL != (pMdContext = wmMalloc(sizeof(MD5_CTX))))
{
Length k;
/* Computes the message digest for the input string pInputMessage. */
wmMD5Init(pMdContext);
for (k = 0; k < MesgLen; k++)
{
wmMD5Update(pMdContext, (ubyte *) pInputMessage, 1);
pInputMessage++;
}
wmMD5Final(pMdContext);
}
else
{
wmMD5MutexRelease();
return ERROR_MEMMGR_NO_MEMORY;
}
if (OK != wmMD5MutexRelease())
{
wmFree(pMdContext);
return SYS_ERROR_MUTEX_RELEASE;
}
MEMCPY(pRetDigestMesg, pMdContext->digest, kDigestMesgBufSize);
wmFree(pMdContext);
return OK;
} /* wmMD5MessageDigest */
/*-----------------------------------------------------------------------*/
static void wmTransform(ubyte4 *buf, ubyte4 *in)
{
ubyte4 a = buf[0], b = buf[1], c = buf[2], d = buf[3];
/* Basic MD5 step. Transform buf based on in. */
/* Round 1 */
#define S11 7
#define S12 12
#define S13 17
#define S14 22
FF ( a, b, c, d, in[ 0], S11, 3614090360U); /* 1 */
FF ( d, a, b, c, in[ 1], S12, 3905402710U); /* 2 */
FF ( c, d, a, b, in[ 2], S13, 606105819U); /* 3 */
FF ( b, c, d, a, in[ 3], S14, 3250441966U); /* 4 */
FF ( a, b, c, d, in[ 4], S11, 4118548399U); /* 5 */
FF ( d, a, b, c, in[ 5], S12, 1200080426U); /* 6 */
FF ( c, d, a, b, in[ 6], S13, 2821735955U); /* 7 */
FF ( b, c, d, a, in[ 7], S14, 4249261313U); /* 8 */
FF ( a, b, c, d, in[ 8], S11, 1770035416U); /* 9 */
FF ( d, a, b, c, in[ 9], S12, 2336552879U); /* 10 */
FF ( c, d, a, b, in[10], S13, 4294925233U); /* 11 */
FF ( b, c, d, a, in[11], S14, 2304563134U); /* 12 */
FF ( a, b, c, d, in[12], S11, 1804603682U); /* 13 */
FF ( d, a, b, c, in[13], S12, 4254626195U); /* 14 */
FF ( c, d, a, b, in[14], S13, 2792965006U); /* 15 */
FF ( b, c, d, a, in[15], S14, 1236535329U); /* 16 */
/* Round 2 */
#define S21 5
#define S22 9
#define S23 14
#define S24 20
GG ( a, b, c, d, in[ 1], S21, 4129170786U); /* 17 */
GG ( d, a, b, c, in[ 6], S22, 3225465664U); /* 18 */
GG ( c, d, a, b, in[11], S23, 643717713U); /* 19 */
GG ( b, c, d, a, in[ 0], S24, 3921069994U); /* 20 */
GG ( a, b, c, d, in[ 5], S21, 3593408605U); /* 21 */
GG ( d, a, b, c, in[10], S22, 38016083U); /* 22 */
GG ( c, d, a, b, in[15], S23, 3634488961U); /* 23 */
GG ( b, c, d, a, in[ 4], S24, 3889429448U); /* 24 */
GG ( a, b, c, d, in[ 9], S21, 568446438U); /* 25 */
GG ( d, a, b, c, in[14], S22, 3275163606U); /* 26 */
GG ( c, d, a, b, in[ 3], S23, 4107603335U); /* 27 */
GG ( b, c, d, a, in[ 8], S24, 1163531501U); /* 28 */
GG ( a, b, c, d, in[13], S21, 2850285829U); /* 29 */
GG ( d, a, b, c, in[ 2], S22, 4243563512U); /* 30 */
GG ( c, d, a, b, in[ 7], S23, 1735328473U); /* 31 */
GG ( b, c, d, a, in[12], S24, 2368359562U); /* 32 */
/* Round 3 */
#define S31 4
#define S32 11
#define S33 16
#define S34 23
HH ( a, b, c, d, in[ 5], S31, 4294588738U); /* 33 */
HH ( d, a, b, c, in[ 8], S32, 2272392833U); /* 34 */
HH ( c, d, a, b, in[11], S33, 1839030562U); /* 35 */
HH ( b, c, d, a, in[14], S34, 4259657740U); /* 36 */
HH ( a, b, c, d, in[ 1], S31, 2763975236U); /* 37 */
HH ( d, a, b, c, in[ 4], S32, 1272893353U); /* 38 */
HH ( c, d, a, b, in[ 7], S33, 4139469664U); /* 39 */
HH ( b, c, d, a, in[10], S34, 3200236656U); /* 40 */
HH ( a, b, c, d, in[13], S31, 681279174U); /* 41 */
HH ( d, a, b, c, in[ 0], S32, 3936430074U); /* 42 */
HH ( c, d, a, b, in[ 3], S33, 3572445317U); /* 43 */
HH ( b, c, d, a, in[ 6], S34, 76029189U); /* 44 */
HH ( a, b, c, d, in[ 9], S31, 3654602809U); /* 45 */
HH ( d, a, b, c, in[12], S32, 3873151461U); /* 46 */
HH ( c, d, a, b, in[15], S33, 530742520U); /* 47 */
HH ( b, c, d, a, in[ 2], S34, 3299628645U); /* 48 */
/* Round 4 */
#define S41 6
#define S42 10
#define S43 15
#define S44 21
II ( a, b, c, d, in[ 0], S41, 4096336452U); /* 49 */
II ( d, a, b, c, in[ 7], S42, 1126891415U); /* 50 */
II ( c, d, a, b, in[14], S43, 2878612391U); /* 51 */
II ( b, c, d, a, in[ 5], S44, 4237533241U); /* 52 */
II ( a, b, c, d, in[12], S41, 1700485571U); /* 53 */
II ( d, a, b, c, in[ 3], S42, 2399980690U); /* 54 */
II ( c, d, a, b, in[10], S43, 4293915773U); /* 55 */
II ( b, c, d, a, in[ 1], S44, 2240044497U); /* 56 */
II ( a, b, c, d, in[ 8], S41, 1873313359U); /* 57 */
II ( d, a, b, c, in[15], S42, 4264355552U); /* 58 */
II ( c, d, a, b, in[ 6], S43, 2734768916U); /* 59 */
II ( b, c, d, a, in[13], S44, 1309151649U); /* 60 */
II ( a, b, c, d, in[ 4], S41, 4149444226U); /* 61 */
II ( d, a, b, c, in[11], S42, 3174756917U); /* 62 */
II ( c, d, a, b, in[ 2], S43, 718787259U); /* 63 */
II ( b, c, d, a, in[ 9], S44, 3951481745U); /* 64 */
buf[0] += a;
buf[1] += b;
buf[2] += c;
buf[3] += d;
} /* wmTransform */
#endif /*__JAVASCRIPT_DIGEST_ENABLED__*/
@@ -0,0 +1,611 @@
/* wmMemBlockLib.c - WindManage backplane data pool management. */
/* Copyright 2001-2007 Wind River Systems, Inc. */
/*
modification history
--------------------
01g,28apr10,m-z eliminate compile warning
01f,15mar10,m_z VxWorks 64bit support (WIND00193649)
01d,24feb07,msa Correct the apigen comments so they match the actual routines
and correct any apigen errors that may occur.
01c,17sep03,jws Fix compiler warnings, SPR 90282
01a,01aug01,pns written
01b,11oct01,rws comments modified
*/
/*
DESCRIPTION
WindManage Backplane data pool management.
*/
/*
INCLUDE FILES: wm.h wmb.h
*/
#include "wrn/wm/common/wm.h"
#include "wrn/wm/backplane/wmb.h"
#undef MEM_ALLOC
#undef MEM_FREE
#define MEM_ALLOC(pool, size) (NULL == pool ? wmMalloc(size) : wmPoolAlloc(pool, size))
#define MEM_FREE(pool, data) if (NULL == pool) wmFree(data); else wmPoolFree(pool, data)
#ifndef __NO_MAGIC__
#define MEM_HEAD 0xbbbbbbbb
#define MEM_TAIL 0xcccccccc
#endif
BOOL wmMemBlockOkay
(
WM_BLOCK_T * pBlock,
void * pData
);
/**************************************************************************
*
* setBit - set state of bit in bitfield.
*
* RETURNS: NA
*
*/
LOCAL void setBit
(
ubyte4 * pBits, /* bit flags in words */
#ifndef _WRS_CONFIG_LP64
ubyte4 offset, /* offset into data */
#else
ubyte8 offset, /* offset into data */
#endif
BOOL on
)
{
#ifndef _WRS_CONFIG_LP64
ubyte4 major;
ubyte4 minor;
#else
ubyte8 major;
ubyte8 minor;
#endif
ubyte4 mask;
major = offset / WORD_BITS_K;
minor = offset % WORD_BITS_K;
mask = (ubyte4)(1 << minor);
if (on)
pBits[major] |= mask;
else
pBits[major] &= ~mask;
}
/**************************************************************************
*
* firstBit - find free bit in bitfield.
*
* Destructive get - sets bit found
*
* RETURNS: integer count of bits until encountering first enabled bit
*
*
* NOMANUAL
*/
#ifndef _WRS_CONFIG_LP64
LOCAL sbyte4 firstBit
#else
LOCAL sbyte8 firstBit
#endif
(
ubyte4 * pBits, /* bitfield */
#ifndef _WRS_CONFIG_LP64
ubyte4 max /* bitfield bit count */
#else
ubyte8 max /* bitfield bit count */
#endif
)
{
ubyte4 mask;
#ifndef _WRS_CONFIG_LP64
ubyte4 index;
ubyte4 loop;
#else
ubyte8 index;
ubyte8 loop;
#endif
/* counting by words */
max /= WORD_BITS_K;
for (index = 0; index < max; index++, pBits++)
{
if (0xffffffff == *pBits)
continue;
mask = 1;
for (loop = 0; loop < WORD_BITS_K; loop++ )
{
if (0 == (mask & *pBits))
{
/* set bit to indicate use */
*pBits |= mask;
#ifndef _WRS_CONFIG_LP64
return (sbyte4)((index * WORD_BITS_K) + loop);
#else
return (sbyte8)((index * WORD_BITS_K) + loop);
#endif
}
mask = mask << 1;
}
}
return -1;
}
/**************************************************************************
*
* wmMemBlockCreate - Create a new data pool.
*
* This routine creates a new data pool.
*
* RETURNS: A pointer to the new data pool <pBlock>.
*
*
* NOMANUAL
*/
WM_BLOCK_T * wmMemBlockCreate
(
void * memID,
WM_BLOCK_T * pPrior, /* link to prior block */
#ifndef _WRS_CONFIG_LP64
int elements, /* number of elements in block */
int size /* size of each element */
#else
long elements, /* number of elements in block */
long size /* size of each element */
#endif
)
{
WM_BLOCK_T * pBlock;
int * pBits;
void * pData;
unsigned long adjust;
unsigned long bytes;
unsigned long total;
pBlock = (WM_BLOCK_T *) MEM_ALLOC(memID, sizeof(WM_BLOCK_T));
if (NULL == pBlock)
return NULL;
/* adjust size to multiple of sizeof int */
adjust = elements % WORD_BITS_K;
if (0 < adjust)
elements += (long)(WORD_BITS_K - adjust);
/* how many bits to keep track of elements */
bytes = (unsigned long)(elements / 8);
/* now actual size of all data needed */
#ifndef __NO_MAGIC__
/*
* only head needs adjusting for head and tail,
* all other blocks will inherit adjusted size
*/
if (NULL == pPrior)
size += (long)(2 * sizeof(ubyte4));
#endif
total = (unsigned long)(elements * size);
if (NULL == (pData = MEM_ALLOC(memID, total)))
{
MEM_FREE(memID, pBlock);
return NULL;
}
if (NULL == (pBits = MEM_ALLOC(memID, bytes + 1)))
{
MEM_FREE(memID, pData);
MEM_FREE(memID, pBlock);
return NULL;
}
memset(pBits, 0, bytes);
while (NULL != pPrior)
{
if (NULL == pPrior->pNext)
break;
pPrior = pPrior->pNext;
}
if (NULL != pPrior)
pPrior->pNext = pBlock;
wmMemBlockBless(pBlock);
pBlock->memID = memID;
pBlock->pData = pData;
pBlock->free = pBits;
pBlock->max = elements;
pBlock->size = size;
pBlock->used = 0;
pBlock->pNext = NULL;
return pBlock;
}
/**************************************************************************
*
* wmMemBlockExtend - append a similar memory block.
*
* This routine creates a new data pool.
*
* RETURNS: A pointer to the new data pool <pBlock>.
*
*
* NOMANUAL
*/
LOCAL WM_BLOCK_T * wmMemBlockExtend
(
WM_BLOCK_T * pBlock /* prior block */
)
{
return wmMemBlockCreate(pBlock->memID, pBlock, pBlock->max, pBlock->size);
}
/**************************************************************************
*
* wmMemBlockDestroy - free a data pool.
*
* RETURNS: N/A.
*
*
* NOMANUAL
*/
void wmMemBlockDestroy
(
WM_BLOCK_T * pBlock /* block(s) to free */
)
{
WM_BLOCK_T * pNext;
while (NULL != pBlock)
{
pNext = pBlock->pNext;
MEM_FREE(pBlock->memID, pBlock->free);
MEM_FREE(pBlock->memID, pBlock->pData);
MEM_FREE(pBlock->memID, pBlock);
pBlock = pNext;
}
}
#if 0
struct WM_BLOCK_T * pNext;
void * memID; /* mem pool id */
int used; /* elements in use */
int top; /* highest used element */
int max; /* size of pool */
int size; /* element size */
void * free; /* bitflags if free */
void * pData; /* data */
#endif
/**************************************************************************
*
* wmMemBlockEntryCreate - Create an entry in data pool <pBlock>.
*
* Create an entry in data pool <pBlock>.
*
*
* RETURNS: A pointer to the new entry.
*
* NOMANUAL
*/
void * wmMemBlockEntryCreate
(
WM_BLOCK_T * pBlock /* data pool pointer */
)
{
WM_BLOCK_T * pPrior = NULL;
void * pData = NULL;
#ifndef _WRS_CONFIG_LP64
sbyte4 offset;
#else
sbyte8 offset;
#endif
#ifndef __NO_MAGIC__
ubyte4 * pMagic;
#ifndef _WRS_CONFIG_LP64
ubyte4 bytes;
#else
ubyte8 bytes;
#endif
#endif
for ( ; NULL != pBlock; pBlock = pBlock->pNext)
{
pPrior = pBlock;
/* all filled up? */
if (pBlock->used == pBlock->max)
continue;
/* find first free spot */
#ifndef _WRS_CONFIG_LP64
offset = firstBit(pBlock->free, (ubyte4)pBlock->max);
#else
offset = firstBit(pBlock->free, (ubyte8)pBlock->max);
#endif
if (0 > offset)
{
wmError(ERROR, "no high bit found!");
return NULL;
}
pData = wmMemBlockEntryGet(pBlock, offset);
break;
}
/* no hits means add another block and try again */
if (NULL == pBlock)
{
if (NULL == (pBlock = wmMemBlockExtend(pPrior)))
{
wmError(ERROR_MEMMGR_NO_MEMORY, "no memory");
return NULL;
}
#ifndef _WRS_CONFIG_LP64
offset = firstBit(pBlock->free, (ubyte4)pBlock->max);
#else
offset = firstBit(pBlock->free, (ubyte8)pBlock->max);
#endif
pData = wmMemBlockEntryGet(pBlock, offset);
}
/* if we have no data here then something is seriously wrong! */
if (NULL == pData)
{
wmError(ERROR, "why no data?");
return NULL;
}
pBlock->used++;
#ifndef __NO_MAGIC__
pMagic = (ubyte4 *) pData;
*pMagic = MEM_HEAD;
bytes = (pBlock->size / sizeof(ubyte4)) - 1;
pMagic[bytes] = MEM_TAIL;
/* we return data just past magic header */
pData = ++pMagic;
#endif
return pData;
}
/**************************************************************************
*
* wmMemBlockEntryGet - Gets an entry in data pool <pBlock>.
*
* Gets an entry in data pool <pBlock>.
*
*
* RETURNS: A pointer to the pool entry <pData> in pool <pBlock>.
*
* NOMANUAL
*/
void * wmMemBlockEntryGet
(
WM_BLOCK_T * pBlock, /* data pool pointer */
#ifndef _WRS_CONFIG_LP64
int index /* offset into pool */
#else
long index /* offset into pool */
#endif
)
{
char * pData;
if (wmMemBlockBad(pBlock))
return NULL;
while (index > pBlock->max)
{
pBlock = pBlock->pNext;
index -= pBlock->max;
if (wmMemBlockBad(pBlock))
return NULL;
}
pData = pBlock->pData;
pData += pBlock->size * index;
return pData;
}
/**************************************************************************
*
* wmMemBlockOkay - validate <pData> in block <pBlock>.
*
* RETURNS: OK or ERROR if <pData> or <pBlock> are invalid
*
* NOMANUAL
*/
BOOL wmMemBlockOkay
(
WM_BLOCK_T * pBlock,
void * pData
)
{
#ifndef __NO_MAGIC__
return TRUE;
#else
pMagic = (ubyte4 *) pData;
pMagic--;
if (MEM_HEAD != *pMagic)
return FALSE;
/* ensure we didn't overwrite end of block */
bytes = pBlock->size / sizeof(ubyte4) - 1;
return (MEM_TAIL == pMagic[bytes]))
#endif
}
/**************************************************************************
*
* wmMemBlockFree - Free the allocated entry <pData> in block <pBlock>.
*
* RETURNS: OK or ERROR if <pData> or <pBlock> are invalid
*
* NOMANUAL
*/
STATUS wmMemBlockFree
(
WM_BLOCK_T * pBlock,
void * pData
)
{
char * pStart = NULL;
char * pTest;
#ifndef _WRS_CONFIG_LP64
int blockSize;
int offset;
int bCount;
#else
long blockSize;
long offset;
long bCount;
#endif
#ifndef __NO_MAGIC__
ubyte4 * pMagic;
#ifndef _WRS_CONFIG_LP64
ubyte4 bytes;
#else
ubyte8 bytes;
#endif
#endif
if (wmMemBlockBad(pBlock))
return wmError(ERROR_GENERAL_INVALID, "wmMemBlockFree: bad block");
if (NULL == pData)
return wmError(ERROR_GENERAL_NULL_POINTER, "wmMemBlockFree: NULL pointer");
#ifndef __NO_MAGIC__
pMagic = (ubyte4 *) pData;
pMagic--;
if (MEM_HEAD != *pMagic)
return wmError(ERROR, "block header corrupted");
/* ensure we didn't overwrite end of block */
bytes = pBlock->size / sizeof(ubyte4) - 1;
if (MEM_TAIL != pMagic[bytes])
return wmError(ERROR, "corrupted tail");
/* adjust to actual assigned data */
pData = pMagic;
#endif
pTest = (char *) pData;
blockSize = (pBlock->max - 1) * pBlock->size;
/* is data in this block? */
for ( ; NULL != pBlock; pBlock = pBlock->pNext)
{
pStart = pBlock->pData;
if (pStart <= pTest && pTest <= pStart + blockSize)
break;
}
if (NULL == pBlock)
return wmError(ERROR_GENERAL_NULL_POINTER, "wmMemBlockFree: invalid data ptr");
/* which block is it? */
offset = (pTest - pStart) / pBlock->size;
/* mark as unused */
if (pBlock->used == pBlock->max)
bCount = 0;
#ifndef _WRS_CONFIG_LP64
setBit(pBlock->free, (unsigned int)offset, FALSE);
#else
setBit(pBlock->free, (unsigned long)offset, FALSE);
#endif
/* adjust count */
pBlock->used--;
#ifdef __WM_INVALIDATE__
memset(pData, MY_BAD_K, pBlock->size);
#endif
return OK;
}
/* eof wmMemBlockLib.c */
@@ -0,0 +1,51 @@
/* wmNonce.c - JS support routines */
/* Copyright(c) 2005-2007, 2010, 2012 Wind River Systems, Inc.
*
* The right to copy, distribute, modify or otherwise make use
* of this software may be licensed only pursuant to the terms
* of an applicable Wind River license agreement.
*/
/*
modification history
--------------------
01e,18apr12,r_w remove dependence of retrofit.h
Requirement: WIND00299859
01d,15mar10,m_z VxWorks 64bit support (WIND00193649)
01c,24feb07,msa Correct the apigen comments so they match the actual routines
and correct any apigen errors that may occur.
01b,25apr05,??? Update JS Auth #define ordering
01a,17sep04,dkg ported from RC3.3 to WM4.4 for JavaScript Authentication
*/
/* See if Digest is enabled globally */
#include "wm_options.h"
#ifdef __JAVASCRIPT_DIGEST_ENABLED__
#include "httpLib.h"
#include "wmAuth.h"
#include "wmNonce.h"
STATUS wmbGetNonceHandler
(
WMB_TID_T tid, /* transaction id */
WMB_OBJ_T obj, /* the WindMark object */
COMMAND_T cmd /* handler command */
)
{
sbyte *pHtmlOutputBuf;
STATUS status;
WMB_SESSION_T * pSession = wmbTransactionSessionGet(tid);
pHtmlOutputBuf = wmAUTHGetSentNonce(pSession->clientIndex);
status = wmbObjectImport(obj,pHtmlOutputBuf,32,DATATYPE_STRING_K);
return status;
}
#endif
@@ -0,0 +1,656 @@
/* wmOidLib.c - WindManage OID library */
/*
* Copyright (c) 2001-2007, 2010, 2012-2013 Wind River Systems, Inc.
*
* The right to copy, distribute, modify or otherwise make use
* of this software may be licensed only pursuant to the terms
* of an applicable Wind River license agreement.
*/
/*
modification history
--------------------
01h,08apr13,r_w fix coverity issues for defect WIND00411995
01g,17may12,h_l replace NO_STRING with NULL_STRING (WIND00032212)
01f,01apr10,m_z correct 32bit error
01e,15mar10,m_z VxWorks 64bit support (WIND00193649)
01d,24feb07,msa Correct the apigen comments so they match the actual routines
and correct any apigen errors that may occur.
01c,07apr03,jws fix SPR 87133 (wmOidFromString())
01b,07feb03,jws fix compiler warning SPR 84193
01a,13mar01,pns written
*/
/*
DESCRIPTION
This module contains support routines OID manipulation.
INCLUDE FILES: wm.h
*/
/* includes */
#include "wm.h"
#ifdef __WM_DEBUG__
LOCAL BOOL debugEnabled = FALSE;
void wmOidDebug
(
WM_OID_T oid,
sbyte * pMsg
)
{
if (! debugEnabled)
return;
wmOidPrint(oid, pMsg);
}
void wmOidDebugEnable
(
BOOL enable
)
{
debugEnabled = enable;
}
#endif /* __WM_DEBUG__ */
/**************************************************************************
*
* wmOidMax - max possible of OID in bytes
*
*
* RETURNS:\is
*\i ERROR_GENERAL_NOT_FOUND
*\i OK
*\ie
*
* NOMANUAL
*/
int wmOidMax
(
WM_OID_T oid
)
{
return (wmBufferMaxGet(oid) < 0x0fffffff)?((int)wmBufferMaxGet(oid)):0x0fffffff;
}
/**************************************************************************
*
* wmOidLen - length of OID in bytes
*
*
* RETURNS:\is
*\i ERROR_GENERAL_NOT_FOUND
*\i OK
*\ie
*
* NOMANUAL
*/
int wmOidLen
(
WM_OID_T oid
)
{
return (int)wmBufferUsedGet(oid);
}
#if 0
/**************************************************************************
*
* wmOidLenSet - set length of OID in 4 byte words
*
*
* RETURNS: NA
*
* NOMANUAL
*/
LOCAL void wmOidLenSet
(
WM_OID_T oid,
sbyte4 len
)
{
wmBufferUsedSet(oid, len);
}
#endif
/**************************************************************************
*
* wmOidPrint - print ascii OID w/ message
*
*
* RETURNS:\is
*\i ERROR_GENERAL_NOT_FOUND
*\i OK
*\ie
*
* NOMANUAL
*/
void wmOidPrint
(
WM_OID_T pInstance,
sbyte * pMsg
)
{
sbyte temp[256];
if (OK != wmOidStringGet(pInstance, temp, sizeof(temp)))
strcpy(temp, "(empty)");
if (NULL == pMsg)
printf("%s\n", temp);
else
printf("%s %s\n", pMsg, temp);
}
/**************************************************************************
*
* wmOidFromString - create oid from an ascii string
*
* This routine counts the number of elements in an ascii OID string,
* and creates a buffer holding an array of these elements as binary
* 32 bit integers.
*
* If <msize> is greater than the storage required, the buffer size is
* increased to <msize>.
*
*
* RETURNS:\is
*\i oid buffer pointer
*\i NULL
*\ie
*
* NOMANUAL
*/
WM_BUFFER_T * wmOidFromString
(
sbyte * pString, /* ascii version of oid, e.g. "1.1.2" */
int msize /* optional max buffer size in bytes */
)
{
WM_BUFFER_T * pOid;
sbyte * pAsciiOid;
int len = 1;
if (NULL_STRING(pString)) return NULL;
/* compute number of elements in oid string */
for (pAsciiOid = pString; '\0' != *pAsciiOid; pAsciiOid++)
{
if ('.' == *pAsciiOid) len++;
}
len *= 4; /* convert to number of bytes needed for binary oid */
if (msize < len) msize = len; /* set size of buffer to ask for */
/* create an OID buffer */
#ifndef _WRS_CONFIG_LP64
pOid = wmBufferCreate (NULL, msize, NULL, DATATYPE_OID_K, TRUE);
#else
pOid = wmBufferCreate (NULL, (ubyte8)msize, NULL, DATATYPE_OID_K, TRUE);
#endif
if (NULL == pOid) return NULL;
/* update data with binary version of oid */
if (wmConvertStrToOid(pString, wmBufferDataGet(pOid), msize, &len) != OK)
{
wmBufferDelete(pOid);
return NULL;
}
#ifndef _WRS_CONFIG_LP64
pOid->Used = len;
#else
pOid->Used = (ubyte8)len;
#endif
return (pOid);
}
/**************************************************************************
*
* wmOidStringSet - update oid with an ascii string oid
*
*
* RETURNS:\is
*\i OK or ERROR
*\ie
*
* NOMANUAL
*/
STATUS wmOidStringSet
(
WM_OID_T pInstance,
sbyte * pString,
BOOL append
)
{
int * pInt;
int max;
int used;
int len;
if ((NULL == pString) || (NULL == pInstance))
return wmError(ERROR_GENERAL_NO_DATA, "no data");
max = (int)wmBufferMaxGet(pInstance);
used = (int)wmBufferUsedGet(pInstance);
pInt = wmBufferDataGet(pInstance);
if (NULL == pInt)
{
wmBufferUpdate(pInstance, NULL, 256, 0, FALSE);
max = (int)wmBufferMaxGet(pInstance);
pInt = wmBufferDataGet(pInstance);
}
else
{
if (append)
pInt += used;
else
used = 0;
}
#ifndef _WRS_CONFIG_LP64
wmConvertStrToOid(pString, pInt, (max * (int)sizeof(int)), &len);
#else
wmConvertStrToOid(pString, pInt, (ubyte8)(max * (int)sizeof(int)), &len);
#endif
/*
len /= sizeof(int);
wmOidLenSet(pInstance, used + len);
*/
#ifndef _WRS_CONFIG_LP64
wmBufferUsedSet(pInstance, used + len);
#else
wmBufferUsedSet(pInstance, (ubyte8)(used + len));
#endif
return OK;
}
/**************************************************************************
*
* wmOidAppend - append one buffer onto another
*
*
* RETURNS: ERROR or OK
*
* NOMANUAL
*/
STATUS wmOidAppend
(
WM_OID_T pDestOid,
WM_OID_T pAddOid
)
{
/*sbyte4 destLen;*/
sbyte4 addLen;
/* sbyte * pDest;*/
sbyte * pAdd;
/* sbyte4 total;*/
if (NULL == pDestOid || NULL == pAddOid)
return wmError(ERROR_GENERAL_NO_DATA, "wmOidAppend: null arg(s)");
/* pDest = wmBufferDataGet(pDestOid);*/
pAdd = wmBufferDataGet(pAddOid);
/* total = (sbyte4)wmBufferMaxGet(pDestOid);*/
/* destLen = (sbyte4)wmBufferUsedGet(pDestOid);*/
addLen = (sbyte4)wmBufferUsedGet(pAddOid);
#ifndef _WRS_CONFIG_LP64
return wmBufferAppend(pDestOid, pAdd, addLen);
#else
return wmBufferAppend(pDestOid, pAdd, (ubyte8)addLen);
#endif
#if 0
/* make sure there's enough space (fix later: just resize) */
if (addLen > total - destLen)
return wmError(ERROR_GENERAL_BUFFER_OVERRUN, "wmOidAppend: not enough space");
/* add suffix! */
pDest += destLen;
destLen += addLen;
memcpy(pDest, pAdd, addLen);
wmBufferUsedSet(pDestOid, destLen);
return OK;
#endif
}
/**************************************************************************
*
* wmOidEqual - compare 2 oids
*
* RETURNS: TRUE if same
*
* NOMANUAL
*/
BOOL wmOidEqual
(
WM_OID_T orig,
WM_OID_T test
)
{
sbyte4 destLen;
sbyte4 addLen;
sbyte * pDest;
sbyte * pAdd;
pDest = wmBufferDataGet(orig);
pAdd = wmBufferDataGet(test);
if (NULL == pDest || NULL == pAdd)
return FALSE;
destLen = (sbyte4)wmBufferUsedGet(orig);
addLen = (sbyte4)wmBufferUsedGet(test);
/* make sure there's enough space (fix later: just resize) */
if (addLen != destLen)
return FALSE;
#ifndef _WRS_CONFIG_LP64
return (0 == memcmp(pDest, pAdd, addLen));
#else
return (0 == memcmp(pDest, pAdd, (ubyte8)addLen));
#endif
}
/**************************************************************************
*
* wmOidCmp - compare 2 oids
*
* RETURNS:
*
* NOMANUAL
*/
int wmOidCmp
(
WM_OID_T orig,
WM_OID_T test
)
{
sbyte4 i;
sbyte4 origLen;
sbyte4 testLen;
ubyte4 * pOrig;
ubyte4 * pTest;
pOrig = wmBufferDataGet(orig);
pTest = wmBufferDataGet(test);
if (NULL == pTest || NULL == pOrig)
return 0;
origLen = (sbyte4)wmBufferUsedGet(orig) / 4;
testLen = (sbyte4)wmBufferUsedGet(test) / 4;
for (i = 0; (i < origLen) && (i < testLen); i++, pOrig++, pTest++)
{
if (*pOrig < *pTest)
return -1;
if (*pOrig > *pTest)
return 1;
}
/* so far they are the same */
if (origLen < testLen)
return -1;
if (origLen > testLen)
return 1;
return 0;
}
/**************************************************************************
*
* wmOidTruncate - truncate oid
*
*
* RETURNS: ERROR or OK
*
* NOMANUAL
*/
STATUS wmOidTruncate
(
WM_OID_T oid,
sbyte4 length /* in bytes */
)
{
sbyte * pData;
sbyte4 used;
sbyte4 max;
pData = wmBufferDataGet (oid);
max = (sbyte4)wmBufferMaxGet (oid);
used = (sbyte4)wmBufferUsedGet (oid);
pData += length;
if (length > used)
return wmError(ERROR_GENERAL_ILLEGAL_VALUE, "wmOidTruncate: length too long");
/* nothing to do */
if (length == used)
return OK;
#ifndef _WRS_CONFIG_LP64
memset(pData, 0, max - length);
wmBufferUsedSet(oid, length);
#else
memset(pData, 0, (ubyte8)(max - length));
wmBufferUsedSet(oid, (ubyte8)length);
#endif
return OK;
}
/**************************************************************************
*
* wmOidSuffix - create new buffer containing unique instance suffix
*
*
* RETURNS: buffer with suffix only
*
* NOMANUAL
*/
WM_OID_T wmOidSuffix
(
WM_OID_T pBaseOid,
WM_OID_T pFullOid
)
{
WM_OID_T pSuffix;
sbyte4 baseLen;
sbyte4 fullLen;
sbyte4 * pBase;
sbyte4 * pFull;
sbyte4 index;
if (NULL == pBaseOid || NULL == pFullOid)
return NULL;
pBase = wmBufferDataGet (pBaseOid);
pFull = wmBufferDataGet (pFullOid);
baseLen = (sbyte4)wmBufferUsedGet (pBaseOid);
fullLen = (sbyte4)wmBufferUsedGet (pFullOid);
if (baseLen >= fullLen)
return NULL;
/* base should match beginning of full */
for (index = baseLen; index > 0; index -= 4, pBase++, pFull++)
{
if (*pBase != *pFull)
return NULL;
}
/* only create suffix if it doesn't already exist */
fullLen -= baseLen;
#ifndef _WRS_CONFIG_LP64
pSuffix = wmBufferCreate(NULL, fullLen, pFull, wmBufferTypeGet(pFullOid), TRUE);
#else
pSuffix = wmBufferCreate(NULL, (ubyte8)fullLen, pFull, wmBufferTypeGet(pFullOid), TRUE);
#endif
/*
wmBufferMakeOid(pSuffix, TRUE);
*/
return pSuffix;
}
/**************************************************************************
*
* wmOidScalerSet - set OID to be scalar object, i.e., .0 at end
*
* RETURNS: OK
*
*
* NOMANUAL
*/
void wmOidScalerSet
(
WM_OID_T oid
)
{
int zero = 0;
wmBufferAppend(oid, &zero, sizeof(zero));
}
/* return if scaler */
BOOL wmOidScaler
(
WM_OID_T oid
)
{
int * pData;
int size;
if (0 >= (size = (int)wmBufferUsedGet(oid)))
return FALSE;
pData = wmBufferDataGet(oid);
pData += size;
return (*pData == 0);
}
/**************************************************************************
*
* wmOidStringGet - create ascii version of oid
*
*
* RETURNS:\is
*\i ERROR_GENERAL_NOT_FOUND
*\i OK
*\ie
*
* NOMANUAL
*/
STATUS wmOidStringGet
(
WM_OID_T oid,
sbyte * pString,
sbyte4 strLen
)
{
int * pData;
sbyte4 oidLen;
if (wmOidBad(oid))
return wmError(ERROR_GENERAL_INVALID, "wmOidStringGet: bad oid");
pData = wmBufferDataGet (oid);
oidLen = (sbyte4)wmBufferUsedGet (oid);
if (NULL == pData || 4 > oidLen)
return wmError(ERROR_GENERAL_NO_DATA, "wmOidStringGet: no data");
wmConvertOidToString ((ubyte4 *)pData, oidLen, pString, strLen, NULL);
return OK;
}
/**************************************************************************
*
* wmOidValid - does OID contain valid data
*
*
* RETURNS:\is
*\i ERROR
*\i OK
*\ie
*
* NOMANUAL
*/
STATUS wmOidValid
(
WM_OID_T oid
)
{
if (wmInvalid(oid))
return wmError(ERROR_GENERAL_INVALID, "wmOidInvalid: bad OID");
if (wmInvalid(wmBufferDataGet(oid)))
return wmError(ERROR_GENERAL_INVALID, "wmOidInvalid: bad data");
return OK;
}
/* eof wmOidLib.c */
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,381 @@
/* wmUserLib.c - WindManage user access library */
/*
* Copyright (c) 2002, 2007, 2009, 2010, 2012 Wind River Systems, Inc.
*
* The right to copy, distribute, modify or otherwise make use
* of this software may be licensed only pursuant to the terms
* of an applicable Wind River license agreement.
*/
/*
modification history
--------------------
02e,22nov12,f_f move the userInfo defination to the header file
(REQ: WIND00364534)
01f,17may12,h_l replace NO_STRING with NULL_STRING (WIND00032212)
01e,07may10,m_z eliminate compile warning
01d,15mar10,m_z VxWorks 64bit support (WIND00193649)
01c,09mar09,m_z Eliminate compile warning
02b,09mar09,m_z Eliminate compile warning
(WIND00157339)
02,24feb07,msa Correct the apigen comments so they match the actual routines
and correct any apigen errors that may occur.
01,17may02,rs updated refgen comments
*/
/*
DESCRIPTION:
This module implements multi user access routines.
INCLUDE FILES:
wm.h
wmb.h
*/
#include "wm.h"
#include "wmb.h"
#ifdef __ENABLE_WMB_USERS__
/* passwords should be stored in encrypted form */
#ifndef RCC_ENCRYPT_FUNC
# define RCC_ENCRYPT_FUNC(password, salt) password
#endif
userInfo userBase[MAX_USERS_K] =
{
{DEFAULT_LOGIN_K, DEFAULT_PASSWORD_K, 10},
{"guest", "guest", 0}
};
LOCAL void USER_GetSalt
(
sbyte salt[2]
)
{
sbyte buffer[32];
#ifndef _WRS_CONFIG_LP64
ubyte4 timeNow;
#else
ubyte8 timeNow;
#endif
sbyte4 len;
sbyte4 offset;
sbyte4 seed = 0;
timeNow = wmosTimeGet();
ASCTIME((ubyte4)timeNow, buffer);
len = (sbyte4)STRLEN(buffer) - 1;
offset = (int)(timeNow % len);
while (1)
{
seed = buffer[offset];
if (ISALNUM(seed))
break;
++offset;
offset = offset % len;
}
salt[0] = (sbyte) seed;
offset = seed % len;
while (1)
{
seed = buffer[offset];
if (ISALNUM(seed))
break;
++offset;
offset = offset % len;
}
salt[1] = (sbyte) seed;
}
LOCAL userInfo * USER_GetUser
(
sbyte * pLogin
)
{
sbyte2 index;
userInfo *pUser = userBase;
for (index = 0; index < MAX_USERS_K; index++, pUser++)
{
if (0 == STRCMP(pUser->login, pLogin))
return pUser;
}
return NULL;
}
#if 0
LOCAL userInfo * USER_GetPasswordOwner
(
sbyte * pPassword
)
{
sbyte2 index;
sbyte salt[2];
sbyte * pEncrypted = NULL;
userInfo * pUser = userBase;
USER_GetSalt(salt);
pEncrypted = RCC_ENCRYPT_FUNC(pPassword, salt);
for (index = 0; index < MAX_USERS_K; index++, pUser++)
{
if (NULL_STRING(pUser->password))
continue;
if (0 == STRCMP(pUser->password, pEncrypted))
return pUser;
}
return NULL;
}
#endif
/*-----------------------------------------------------------------------*/
LOCAL userInfo * USER_NewUser
(
void
)
{
sbyte2 index;
userInfo *pUser = userBase;
for (index = 0; index < MAX_USERS_K; index++, pUser++)
{
if (NULL_STRING(pUser->login))
return pUser;
}
return NULL;
}
/**************************************************************************
*
* wmUserValidate - Validate (authenticate?) a WMB user.
*
* This routine validates a user <pLogin>:<pPassword> .
*
* RETURNS: TRUE is <pUser> is a valid WMB user. FALSE if not.
*
*/
BOOL wmUserValidate
(
OS_SOCKET_T sock,
sbyte * pLogin,
sbyte * pPassword,
Access * pAccess
)
{
sbyte * pEncrypted = NULL;
sbyte salt[2];
userInfo * pUser;
#ifdef __USE_PASSWORD_ONLY__
if (NULL != (pUser = USER_GetPasswordOwner(pPassword)))
{
*pAccess = pUser->accessLevel;
return TRUE;
}
else
{
*pAccess = 0;
return FALSE;
}
#endif
if (NULL == (pUser = USER_GetUser(pLogin)))
return FALSE;
*pAccess = pUser->accessLevel;
USER_GetSalt(salt);
pEncrypted = RCC_ENCRYPT_FUNC(pPassword, salt);
return (0 == STRCMP(pUser->password, pEncrypted));
}
/**************************************************************************
*
* wmUserAdd - Add a WMB user.
*
* This routine adds a user <pLogin>:<pPassword>, with <pAccess> level.
*
* RETURNS: OK, or ERROR if the username already exists, the specified
* access level is invalid, or if the user database is full.
*
*/
STATUS wmUserAdd
(
sbyte * pLogin,
sbyte * pAccess
)
{
Access accessLevel;
userInfo * pUser;
/* check for pre-existing account */
if (NULL != (pUser = USER_GetUser(pLogin)))
{
printf("User: %s already exists.", pLogin);
return wmError(ERROR_GENERAL, "User already exists");
}
if (NULL == pAccess)
pAccess = DEFAULT_ACCESS_K;
if (OK != wmConvertStrTypeTo(pAccess, &accessLevel, wmAccessInfoGet()))
return wmError(ERROR_GENERAL_ILLEGAL_VALUE, "invalid access");
if (NULL == (pUser = USER_NewUser()))
return wmError(ERROR_GENERAL_MAXED, "user database is full");
STRCPY(pUser->login, pLogin);
pUser->accessLevel = accessLevel;
return OK;
}
/**************************************************************************
*
* wmUserDelete - Delete a WMB user.
*
* This routine deletes user <pLogin> from the WMB user database.
*
* RETURNS: OK, or ERROR if the username does not exist.
*
*/
STATUS wmUserDelete
(
sbyte * pLogin
)
{
userInfo * pUser;
if (NULL == (pUser = USER_GetUser(pLogin)))
return wmError(ERROR_GENERAL, "invalid user");
MEMSET(pUser->login, 0, sizeof(pUser->login));
MEMSET(pUser->password, 0, sizeof(pUser->password));
pUser->accessLevel = 0;
return OK;
}
/**************************************************************************
*
* wmUserChangePassword - Change a WMB user's password.
*
* This routine changes the password for user <pLogin>.
*
* RETURNS: OK, or ERROR if the username does not exist.
*
*/
STATUS wmUserChangePassword
(
sbyte * pLogin,
sbyte * pPassword
)
{
sbyte seed[2];
userInfo * pUser;
if (NULL == (pUser = USER_GetUser(pLogin)))
return wmError(ERROR_GENERAL, "invalid user");
USER_GetSalt(seed);
STRCPY(pUser->password,RCC_ENCRYPT_FUNC(pPassword, seed));
return OK;
}
/**************************************************************************
*
* wmUserChangeAccess - Change a WMB user's access level.
*
* This routine changes the access level for user <pLogin> to <pAccess>.
*
* RETURNS: OK, or ERROR if the username does not exist.
*
*/
STATUS wmUserChangeAccess
(
sbyte * pLogin,
sbyte * pAccess
)
{
userInfo * pUser = USER_GetUser(pLogin);
Access accessLevel;
STATUS status;
if (NULL == pUser)
return wmError(ERROR_GENERAL_INVALID_USER, "invalid user");
status = wmConvertStrTypeTo(pAccess, &accessLevel, wmAccessInfoGet());
if (OK != status)
return status;
pUser->accessLevel = accessLevel;
return OK;
}
/*-----------------------------------------------------------------------*/
/**************************************************************************
*
* wmUserShowUsers - Shows all WMB users.
*
* This routine lists all WMB users and WMB access level. This is intended for
* use ONLY as a debugging feature.
*
* RETURNS: N/A.
*
*/
void wmUserShowUsers
(
void
)
{
sbyte4 index;
sbyte access[30];
userInfo * pUser;
pUser = userBase;
for (index = 0; index < MAX_USERS_K; index++, pUser++)
{
if (NULL_STRING(pUser->login))
continue;
wmAccessToStr(pUser->accessLevel, access);
printf ("User: %20s Access: %s", pUser->login, access);
printf ("\n");
}
}
#endif /* __ENABLE_WMB_USERS__ */
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,54 @@
# Makefile - makefile for src/wrn/wm/common/zlib
#
# Copyright (c) 2002-2003, 2013 Wind River Systems, Inc.
#
# The right to copy, distribute, modify or otherwise make use
# of this software may be licensed only pursuant to the terms
# of an applicable Wind River license agreement.
#
# modification history
# --------------------
# 01d,22apr13,r_w modified for coverity tool prevent.pl
# 01b,13mar03,jws merged from TMS branch
# 01a,01nov02,kw created
#
# DESCRIPTION
# This file contains the makefile rules for building part of
# the wm library
#
#
LIB_BASE_NAME = wmzlib
TGT_DIR = $(WIND_BASE)/target
# Using WM_BASE works whether or not we are under WIND_BASE.
WM_BASE = ../../../../..
DOC_FILES =
SRC_FILES= zlib_adler32.c zlib_compress.c zlib_crc32.c zlib_deflate.c \
zlib_gzio.c zlib_infblock.c zlib_infcodes.c zlib_inffast.c \
zlib_inflate.c zlib_inftrees.c zlib_infutil.c zlib_trees.c \
zlib_uncompr.c zlib_zutil.c
OBJS= $(SRC_FILES:%c=%o)
# PRE_INCLUDE= -I$(WM_BASE)/h -I$(WM_BASE)/h/wrn/wm \
# -I$(WM_BASE)/h/wrn/wm/common \
# -I$(WM_BASE)/h/wrn/wm/backplane \
# -I$(WM_BASE)/h/wrn/wm/wmm \
# -I$(WM_BASE)/h/wrn/wm/http \
# -I$(WM_BASE)/h/wrn/wm/cli \
# -I$(WM_BASE)/h/wrn/wm/common/zlib/vxWorks \
# -I$(WM_BASE)/h/wrn/em \
# -I$(WM_BASE)/h/wrn/wm/snmp/engine
PRE_INCLUDE= -I$(WM_BASE)/h/wrn/wm/common/zlib/vxWorks
# EXTRA_DEFINE = -DCOMMON_IS_COMPONENT
include $(TGT_DIR)/h/make/rules.library
@@ -0,0 +1,48 @@
/* adler32.c -- compute the Adler-32 checksum of a data stream
* Copyright (C) 1995-2002 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
/* @(#) $Id$ */
#include "zlib.h"
#define BASE 65521L /* largest prime smaller than 65536 */
#define NMAX 5552
/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
#define DO1(buf,i) {s1 += buf[i]; s2 += s1;}
#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1);
#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2);
#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4);
#define DO16(buf) DO8(buf,0); DO8(buf,8);
/* ========================================================================= */
uLong ZEXPORT adler32(adler, buf, len)
uLong adler;
const Bytef *buf;
uInt len;
{
unsigned long s1 = adler & 0xffff;
unsigned long s2 = (adler >> 16) & 0xffff;
int k;
if (buf == Z_NULL) return 1L;
while (len > 0) {
k = len < NMAX ? len : NMAX;
len -= k;
while (k >= 16) {
DO16(buf);
buf += 16;
k -= 16;
}
if (k != 0) do {
s1 += *buf++;
s2 += s1;
} while (--k);
s1 %= BASE;
s2 %= BASE;
}
return (s2 << 16) | s1;
}
@@ -0,0 +1,68 @@
/* compress.c -- compress a memory buffer
* Copyright (C) 1995-2002 Jean-loup Gailly.
* For conditions of distribution and use, see copyright notice in zlib.h
*/
/* @(#) $Id$ */
#include "zlib.h"
/* ===========================================================================
Compresses the source buffer into the destination buffer. The level
parameter has the same meaning as in deflateInit. sourceLen is the byte
length of the source buffer. Upon entry, destLen is the total size of the
destination buffer, which must be at least 0.1% larger than sourceLen plus
12 bytes. Upon exit, destLen is the actual size of the compressed buffer.
compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
memory, Z_BUF_ERROR if there was not enough room in the output buffer,
Z_STREAM_ERROR if the level parameter is invalid.
*/
int ZEXPORT compress2 (dest, destLen, source, sourceLen, level)
Bytef *dest;
uLongf *destLen;
const Bytef *source;
uLong sourceLen;
int level;
{
z_stream stream;
int err;
stream.next_in = (Bytef*)source;
stream.avail_in = (uInt)sourceLen;
#ifdef MAXSEG_64K
/* Check for source > 64K on 16-bit machine: */
if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR;
#endif
stream.next_out = dest;
stream.avail_out = (uInt)*destLen;
if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR;
stream.zalloc = (alloc_func)0;
stream.zfree = (free_func)0;
stream.opaque = (voidpf)0;
err = deflateInit(&stream, level);
if (err != Z_OK) return err;
err = deflate(&stream, Z_FINISH);
if (err != Z_STREAM_END) {
deflateEnd(&stream);
return err == Z_OK ? Z_BUF_ERROR : err;
}
*destLen = stream.total_out;
err = deflateEnd(&stream);
return err;
}
/* ===========================================================================
*/
int ZEXPORT compress (dest, destLen, source, sourceLen)
Bytef *dest;
uLongf *destLen;
const Bytef *source;
uLong sourceLen;
{
return compress2(dest, destLen, source, sourceLen, Z_DEFAULT_COMPRESSION);
}
@@ -0,0 +1,162 @@
/* crc32.c -- compute the CRC-32 of a data stream
* Copyright (C) 1995-2002 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
/* @(#) $Id$ */
#include "zlib.h"
#define local static
#ifdef DYNAMIC_CRC_TABLE
local int crc_table_empty = 1;
local uLongf crc_table[256];
local void make_crc_table OF((void));
/*
Generate a table for a byte-wise 32-bit CRC calculation on the polynomial:
x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1.
Polynomials over GF(2) are represented in binary, one bit per coefficient,
with the lowest powers in the most significant bit. Then adding polynomials
is just exclusive-or, and multiplying a polynomial by x is a right shift by
one. If we call the above polynomial p, and represent a byte as the
polynomial q, also with the lowest power in the most significant bit (so the
byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p,
where a mod b means the remainder after dividing a by b.
This calculation is done using the shift-register method of multiplying and
taking the remainder. The register is initialized to zero, and for each
incoming bit, x^32 is added mod p to the register if the bit is a one (where
x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by
x (which is shifting right by one and adding x^32 mod p if the bit shifted
out is a one). We start with the highest power (least significant bit) of
q and repeat for all eight bits of q.
The table is simply the CRC of all possible eight bit values. This is all
the information needed to generate CRC's on data a byte at a time for all
combinations of CRC register values and incoming bytes.
*/
local void make_crc_table()
{
uLong c;
int n, k;
uLong poly; /* polynomial exclusive-or pattern */
/* terms of polynomial defining this crc (except x^32): */
static const Byte p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26};
/* make exclusive-or pattern from polynomial (0xedb88320L) */
poly = 0L;
for (n = 0; n < sizeof(p)/sizeof(Byte); n++)
poly |= 1L << (31 - p[n]);
for (n = 0; n < 256; n++)
{
c = (uLong)n;
for (k = 0; k < 8; k++)
c = c & 1 ? poly ^ (c >> 1) : c >> 1;
crc_table[n] = c;
}
crc_table_empty = 0;
}
#else
/* ========================================================================
* Table of CRC-32's of all single-byte values (made by make_crc_table)
*/
local const uLongf crc_table[256] = {
0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L,
0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L,
0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L,
0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL,
0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L,
0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L,
0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L,
0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL,
0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L,
0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL,
0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L,
0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L,
0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L,
0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL,
0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL,
0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L,
0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL,
0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L,
0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L,
0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L,
0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL,
0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L,
0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L,
0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL,
0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L,
0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L,
0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L,
0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L,
0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L,
0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL,
0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL,
0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L,
0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L,
0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL,
0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL,
0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L,
0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL,
0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L,
0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL,
0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L,
0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL,
0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L,
0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L,
0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL,
0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L,
0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L,
0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L,
0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L,
0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L,
0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L,
0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL,
0x2d02ef8dL
};
#endif
/* =========================================================================
* This function can be used by asm versions of crc32()
*/
const uLongf * ZEXPORT get_crc_table()
{
#ifdef DYNAMIC_CRC_TABLE
if (crc_table_empty) make_crc_table();
#endif
return (const uLongf *)crc_table;
}
/* ========================================================================= */
#define DO1(buf) crc = crc_table[((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8);
#define DO2(buf) DO1(buf); DO1(buf);
#define DO4(buf) DO2(buf); DO2(buf);
#define DO8(buf) DO4(buf); DO4(buf);
/* ========================================================================= */
uLong ZEXPORT crc32(crc, buf, len)
uLong crc;
const Bytef *buf;
uInt len;
{
if (buf == Z_NULL) return 0L;
#ifdef DYNAMIC_CRC_TABLE
if (crc_table_empty)
make_crc_table();
#endif
crc = crc ^ 0xffffffffL;
while (len >= 8)
{
DO8(buf);
len -= 8;
}
if (len) do {
DO1(buf);
} while (--len);
return crc ^ 0xffffffffL;
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,874 @@
/* gzio.c -- IO on .gz files
* Copyright (C) 1995-2002 Jean-loup Gailly.
* For conditions of distribution and use, see copyright notice in zlib.h
*
* Compile this file with -DNO_DEFLATE to avoid the compression code.
*/
/* @(#) $Id$ */
#include <stdio.h>
#include "zutil.h"
struct internal_state {int dummy;}; /* for buggy compilers */
#ifndef Z_BUFSIZE
# ifdef MAXSEG_64K
# define Z_BUFSIZE 4096 /* minimize memory usage for 16-bit DOS */
# else
# define Z_BUFSIZE 16384
# endif
#endif
#ifndef Z_PRINTF_BUFSIZE
# define Z_PRINTF_BUFSIZE 4096
#endif
#define ALLOC(size) malloc(size)
#define TRYFREE(p) {if (p) free(p);}
int ZEXPORT gzeof (gzFile file);
static int gz_magic[2] = {0x1f, 0x8b}; /* gzip magic header */
/* gzip flag byte */
#define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */
#define HEAD_CRC 0x02 /* bit 1 set: header CRC present */
#define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */
#define ORIG_NAME 0x08 /* bit 3 set: original file name present */
#define COMMENT 0x10 /* bit 4 set: file comment present */
#define RESERVED 0xE0 /* bits 5..7: reserved */
typedef struct gz_stream {
z_stream stream;
int z_err; /* error code for last stream operation */
int z_eof; /* set if end of input file */
FILE *file; /* .gz file */
Byte *inbuf; /* input buffer */
Byte *outbuf; /* output buffer */
uLong crc; /* crc32 of uncompressed data */
char *msg; /* error message */
char *path; /* path name for debugging only */
int transparent; /* 1 if input file is not a .gz file */
char mode; /* 'w' or 'r' */
long startpos; /* start of compressed data in file (header skipped) */
} gz_stream;
local gzFile gz_open OF((const char *path, const char *mode, int fd));
local int do_flush OF((gzFile file, int flush));
local int get_byte OF((gz_stream *s));
local void check_header OF((gz_stream *s));
local int destroy OF((gz_stream *s));
local void putLong OF((FILE *file, uLong x));
local uLong getLong OF((gz_stream *s));
/* ===========================================================================
Opens a gzip (.gz) file for reading or writing. The mode parameter
is as in fopen ("rb" or "wb"). The file is given either by file descriptor
or path name (if fd == -1).
gz_open return NULL if the file could not be opened or if there was
insufficient memory to allocate the (de)compression state; errno
can be checked to distinguish the two cases (if errno is zero, the
zlib error is Z_MEM_ERROR).
*/
local gzFile gz_open (path, mode, fd)
const char *path;
const char *mode;
int fd;
{
int err;
int level = Z_DEFAULT_COMPRESSION; /* compression level */
int strategy = Z_DEFAULT_STRATEGY; /* compression strategy */
char *p = (char*)mode;
gz_stream *s;
char fmode[80]; /* copy of mode, without the compression level */
char *m = fmode;
if (!path || !mode) return Z_NULL;
s = (gz_stream *)ALLOC(sizeof(gz_stream));
if (!s) return Z_NULL;
s->stream.zalloc = (alloc_func)0;
s->stream.zfree = (free_func)0;
s->stream.opaque = (voidpf)0;
s->stream.next_in = s->inbuf = Z_NULL;
s->stream.next_out = s->outbuf = Z_NULL;
s->stream.avail_in = s->stream.avail_out = 0;
s->file = NULL;
s->z_err = Z_OK;
s->z_eof = 0;
s->crc = crc32(0L, Z_NULL, 0);
s->msg = NULL;
s->transparent = 0;
s->path = (char*)ALLOC(strlen(path)+1);
if (s->path == NULL) {
return destroy(s), (gzFile)Z_NULL;
}
strcpy(s->path, path); /* do this early for debugging */
s->mode = '\0';
do {
if (*p == 'r') s->mode = 'r';
if (*p == 'w' || *p == 'a') s->mode = 'w';
if (*p >= '0' && *p <= '9') {
level = *p - '0';
} else if (*p == 'f') {
strategy = Z_FILTERED;
} else if (*p == 'h') {
strategy = Z_HUFFMAN_ONLY;
} else {
*m++ = *p; /* copy the mode */
}
} while (*p++ && m != fmode + sizeof(fmode));
if (s->mode == '\0') return destroy(s), (gzFile)Z_NULL;
if (s->mode == 'w') {
#ifdef NO_DEFLATE
err = Z_STREAM_ERROR;
#else
err = deflateInit2(&(s->stream), level,
Z_DEFLATED, -MAX_WBITS, DEF_MEM_LEVEL, strategy);
/* windowBits is passed < 0 to suppress zlib header */
s->stream.next_out = s->outbuf = (Byte*)ALLOC(Z_BUFSIZE);
#endif
if (err != Z_OK || s->outbuf == Z_NULL) {
return destroy(s), (gzFile)Z_NULL;
}
} else {
s->stream.next_in = s->inbuf = (Byte*)ALLOC(Z_BUFSIZE);
err = inflateInit2(&(s->stream), -MAX_WBITS);
/* windowBits is passed < 0 to tell that there is no zlib header.
* Note that in this case inflate *requires* an extra "dummy" byte
* after the compressed stream in order to complete decompression and
* return Z_STREAM_END. Here the gzip CRC32 ensures that 4 bytes are
* present after the compressed stream.
*/
if (err != Z_OK || s->inbuf == Z_NULL) {
return destroy(s), (gzFile)Z_NULL;
}
}
s->stream.avail_out = Z_BUFSIZE;
errno = 0;
s->file = fd < 0 ? F_OPEN(path, fmode) : (FILE*)fdopen(fd, fmode);
if (s->file == NULL) {
return destroy(s), (gzFile)Z_NULL;
}
if (s->mode == 'w') {
/* Write a very simple .gz header:
*/
fprintf(s->file, "%c%c%c%c%c%c%c%c%c%c", gz_magic[0], gz_magic[1],
Z_DEFLATED, 0 /*flags*/, 0,0,0,0 /*time*/, 0 /*xflags*/, OS_CODE);
s->startpos = 10L;
/* We use 10L instead of ftell(s->file) to because ftell causes an
* fflush on some systems. This version of the library doesn't use
* startpos anyway in write mode, so this initialization is not
* necessary.
*/
} else {
check_header(s); /* skip the .gz header */
s->startpos = (ftell(s->file) - s->stream.avail_in);
}
return (gzFile)s;
}
/* ===========================================================================
Opens a gzip (.gz) file for reading or writing.
*/
gzFile ZEXPORT gzopen (path, mode)
const char *path;
const char *mode;
{
return gz_open (path, mode, -1);
}
/* ===========================================================================
Associate a gzFile with the file descriptor fd. fd is not dup'ed here
to mimic the behavio(u)r of fdopen.
*/
gzFile ZEXPORT gzdopen (fd, mode)
int fd;
const char *mode;
{
char name[20];
if (fd < 0) return (gzFile)Z_NULL;
sprintf(name, "<fd:%d>", fd); /* for debugging */
return gz_open (name, mode, fd);
}
/* ===========================================================================
* Update the compression level and strategy
*/
int ZEXPORT gzsetparams (file, level, strategy)
gzFile file;
int level;
int strategy;
{
gz_stream *s = (gz_stream*)file;
if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR;
/* Make room to allow flushing */
if (s->stream.avail_out == 0) {
s->stream.next_out = s->outbuf;
if (fwrite(s->outbuf, 1, Z_BUFSIZE, s->file) != Z_BUFSIZE) {
s->z_err = Z_ERRNO;
}
s->stream.avail_out = Z_BUFSIZE;
}
return deflateParams (&(s->stream), level, strategy);
}
/* ===========================================================================
Read a byte from a gz_stream; update next_in and avail_in. Return EOF
for end of file.
IN assertion: the stream s has been sucessfully opened for reading.
*/
local int get_byte(s)
gz_stream *s;
{
if (s->z_eof) return EOF;
if (s->stream.avail_in == 0) {
errno = 0;
s->stream.avail_in = (unsigned)fread(s->inbuf, 1, Z_BUFSIZE, s->file);
if (s->stream.avail_in == 0) {
s->z_eof = 1;
if (ferror(s->file)) s->z_err = Z_ERRNO;
return EOF;
}
s->stream.next_in = s->inbuf;
}
s->stream.avail_in--;
return *(s->stream.next_in)++;
}
/* ===========================================================================
Check the gzip header of a gz_stream opened for reading. Set the stream
mode to transparent if the gzip magic header is not present; set s->err
to Z_DATA_ERROR if the magic header is present but the rest of the header
is incorrect.
IN assertion: the stream s has already been created sucessfully;
s->stream.avail_in is zero for the first time, but may be non-zero
for concatenated .gz files.
*/
local void check_header(s)
gz_stream *s;
{
int method; /* method byte */
int flags; /* flags byte */
uInt len;
int c;
/* Check the gzip magic header */
for (len = 0; len < 2; len++) {
c = get_byte(s);
if (c != gz_magic[len]) {
if (len != 0) s->stream.avail_in++, s->stream.next_in--;
if (c != EOF) {
s->stream.avail_in++, s->stream.next_in--;
s->transparent = 1;
}
s->z_err = s->stream.avail_in != 0 ? Z_OK : Z_STREAM_END;
return;
}
}
method = get_byte(s);
flags = get_byte(s);
if (method != Z_DEFLATED || (flags & RESERVED) != 0) {
s->z_err = Z_DATA_ERROR;
return;
}
/* Discard time, xflags and OS code: */
for (len = 0; len < 6; len++) (void)get_byte(s);
if ((flags & EXTRA_FIELD) != 0) { /* skip the extra field */
len = (uInt)get_byte(s);
len += ((uInt)get_byte(s))<<8;
/* len is garbage if EOF but the loop below will quit anyway */
while (len-- != 0 && get_byte(s) != EOF) ;
}
if ((flags & ORIG_NAME) != 0) { /* skip the original file name */
while ((c = get_byte(s)) != 0 && c != EOF) ;
}
if ((flags & COMMENT) != 0) { /* skip the .gz file comment */
while ((c = get_byte(s)) != 0 && c != EOF) ;
}
if ((flags & HEAD_CRC) != 0) { /* skip the header crc */
for (len = 0; len < 2; len++) (void)get_byte(s);
}
s->z_err = s->z_eof ? Z_DATA_ERROR : Z_OK;
}
/* ===========================================================================
* Cleanup then free the given gz_stream. Return a zlib error code.
Try freeing in the reverse order of allocations.
*/
local int destroy (s)
gz_stream *s;
{
int err = Z_OK;
if (!s) return Z_STREAM_ERROR;
TRYFREE(s->msg);
if (s->stream.state != NULL) {
if (s->mode == 'w') {
#ifdef NO_DEFLATE
err = Z_STREAM_ERROR;
#else
err = deflateEnd(&(s->stream));
#endif
} else if (s->mode == 'r') {
err = inflateEnd(&(s->stream));
}
}
if (s->file != NULL && fclose(s->file)) {
#ifdef ESPIPE
if (errno != ESPIPE) /* fclose is broken for pipes in HP/UX */
#endif
err = Z_ERRNO;
}
if (s->z_err < 0) err = s->z_err;
TRYFREE(s->inbuf);
TRYFREE(s->outbuf);
TRYFREE(s->path);
TRYFREE(s);
return err;
}
/* ===========================================================================
Reads the given number of uncompressed bytes from the compressed file.
gzread returns the number of bytes actually read (0 for end of file).
*/
int ZEXPORT gzread (file, buf, len)
gzFile file;
voidp buf;
unsigned len;
{
gz_stream *s = (gz_stream*)file;
Bytef *start = (Bytef*)buf; /* starting point for crc computation */
Byte *next_out; /* == stream.next_out but not forced far (for MSDOS) */
if (s == NULL || s->mode != 'r') return Z_STREAM_ERROR;
if (s->z_err == Z_DATA_ERROR || s->z_err == Z_ERRNO) return -1;
if (s->z_err == Z_STREAM_END) return 0; /* EOF */
next_out = (Byte*)buf;
s->stream.next_out = (Bytef*)buf;
s->stream.avail_out = len;
while (s->stream.avail_out != 0) {
if (s->transparent) {
/* Copy first the lookahead bytes: */
uInt n = s->stream.avail_in;
if (n > s->stream.avail_out) n = s->stream.avail_out;
if (n > 0) {
zmemcpy(s->stream.next_out, s->stream.next_in, n);
next_out += n;
s->stream.next_out = next_out;
s->stream.next_in += n;
s->stream.avail_out -= n;
s->stream.avail_in -= n;
}
if (s->stream.avail_out > 0) {
s->stream.avail_out -= (unsigned)fread(next_out, 1, s->stream.avail_out,
s->file);
}
len -= s->stream.avail_out;
s->stream.total_in += (uLong)len;
s->stream.total_out += (uLong)len;
if (len == 0) s->z_eof = 1;
return (int)len;
}
if (s->stream.avail_in == 0 && !s->z_eof) {
errno = 0;
s->stream.avail_in = (unsigned)fread(s->inbuf, 1, Z_BUFSIZE, s->file);
if (s->stream.avail_in == 0) {
s->z_eof = 1;
if (ferror(s->file)) {
s->z_err = Z_ERRNO;
break;
}
}
s->stream.next_in = s->inbuf;
}
s->z_err = inflate(&(s->stream), Z_NO_FLUSH);
if (s->z_err == Z_STREAM_END) {
/* Check CRC and original size */
s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start));
start = s->stream.next_out;
if (getLong(s) != s->crc) {
s->z_err = Z_DATA_ERROR;
} else {
(void)getLong(s);
/* The uncompressed length returned by above getlong() may
* be different from s->stream.total_out) in case of
* concatenated .gz files. Check for such files:
*/
check_header(s);
if (s->z_err == Z_OK) {
uLong total_in = s->stream.total_in;
uLong total_out = s->stream.total_out;
inflateReset(&(s->stream));
s->stream.total_in = total_in;
s->stream.total_out = total_out;
s->crc = crc32(0L, Z_NULL, 0);
}
}
}
if (s->z_err != Z_OK || s->z_eof) break;
}
s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start));
return (int)(len - s->stream.avail_out);
}
/* ===========================================================================
Reads one byte from the compressed file. gzgetc returns this byte
or -1 in case of end of file or error.
*/
int ZEXPORT gzgetc(file)
gzFile file;
{
unsigned char c;
return gzread(file, &c, 1) == 1 ? c : -1;
}
/* ===========================================================================
Reads bytes from the compressed file until len-1 characters are
read, or a newline character is read and transferred to buf, or an
end-of-file condition is encountered. The string is then terminated
with a null character.
gzgets returns buf, or Z_NULL in case of error.
The current implementation is not optimized at all.
*/
char * ZEXPORT gzgets(file, buf, len)
gzFile file;
char *buf;
int len;
{
char *b = buf;
if (buf == Z_NULL || len <= 0) return Z_NULL;
while (--len > 0 && gzread(file, buf, 1) == 1 && *buf++ != '\n') ;
*buf = '\0';
return b == buf && len > 0 ? Z_NULL : b;
}
#ifndef NO_DEFLATE
/* ===========================================================================
Writes the given number of uncompressed bytes into the compressed file.
gzwrite returns the number of bytes actually written (0 in case of error).
*/
int ZEXPORT gzwrite (file, buf, len)
gzFile file;
const voidp buf;
unsigned len;
{
gz_stream *s = (gz_stream*)file;
if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR;
s->stream.next_in = (Bytef*)buf;
s->stream.avail_in = len;
while (s->stream.avail_in != 0) {
if (s->stream.avail_out == 0) {
s->stream.next_out = s->outbuf;
if (fwrite(s->outbuf, 1, Z_BUFSIZE, s->file) != Z_BUFSIZE) {
s->z_err = Z_ERRNO;
break;
}
s->stream.avail_out = Z_BUFSIZE;
}
s->z_err = deflate(&(s->stream), Z_NO_FLUSH);
if (s->z_err != Z_OK) break;
}
s->crc = crc32(s->crc, (const Bytef *)buf, len);
return (int)(len - s->stream.avail_in);
}
/* ===========================================================================
Converts, formats, and writes the args to the compressed file under
control of the format string, as in fprintf. gzprintf returns the number of
uncompressed bytes actually written (0 in case of error).
*/
#ifdef STDC
#include <stdarg.h>
int ZEXPORTVA gzprintf (gzFile file, const char *format, /* args */ ...)
{
char buf[Z_PRINTF_BUFSIZE];
va_list va;
int len;
va_start(va, format);
#ifdef HAS_vsnprintf
len = vsnprintf(buf, sizeof(buf), format, va);
#else
len = vsprintf(buf, format, va);
#endif
va_end(va);
if ((len <= 0) || (len >= Z_PRINTF_BUFSIZE))
return 0;
return gzwrite(file, buf, (unsigned)len);
}
#else /* not ANSI C */
int ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
gzFile file;
const char *format;
int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
a11, a12, a13, a14, a15, a16, a17, a18, a19, a20;
{
char buf[Z_PRINTF_BUFSIZE];
int len;
#ifdef HAS_snprintf
len = snprintf(buf, sizeof(buf), format, a1, a2, a3, a4, a5, a6, a7, a8,
a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
#else
len = sprintf(buf, format, a1, a2, a3, a4, a5, a6, a7, a8,
a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
#endif
if ((len <= 0) || (len >= Z_PRINTF_BUFSIZE)) return 0;
return gzwrite(file, buf, len);
}
#endif
/* ===========================================================================
Writes c, converted to an unsigned char, into the compressed file.
gzputc returns the value that was written, or -1 in case of error.
*/
int ZEXPORT gzputc(file, c)
gzFile file;
int c;
{
unsigned char cc = (unsigned char) c; /* required for big endian systems */
return gzwrite(file, &cc, 1) == 1 ? (int)cc : -1;
}
/* ===========================================================================
Writes the given null-terminated string to the compressed file, excluding
the terminating null character.
gzputs returns the number of characters written, or -1 in case of error.
*/
int ZEXPORT gzputs(file, s)
gzFile file;
const char *s;
{
return gzwrite(file, (char*)s, (unsigned)strlen(s));
}
/* ===========================================================================
Flushes all pending output into the compressed file. The parameter
flush is as in the deflate() function.
*/
local int do_flush (file, flush)
gzFile file;
int flush;
{
uInt len;
int done = 0;
gz_stream *s = (gz_stream*)file;
if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR;
s->stream.avail_in = 0; /* should be zero already anyway */
for (;;) {
len = Z_BUFSIZE - s->stream.avail_out;
if (len != 0) {
if ((uInt)fwrite(s->outbuf, 1, len, s->file) != len) {
s->z_err = Z_ERRNO;
return Z_ERRNO;
}
s->stream.next_out = s->outbuf;
s->stream.avail_out = Z_BUFSIZE;
}
if (done) break;
s->z_err = deflate(&(s->stream), flush);
/* Ignore the second of two consecutive flushes: */
if (len == 0 && s->z_err == Z_BUF_ERROR) s->z_err = Z_OK;
/* deflate has finished flushing only when it hasn't used up
* all the available space in the output buffer:
*/
done = (s->stream.avail_out != 0 || s->z_err == Z_STREAM_END);
if (s->z_err != Z_OK && s->z_err != Z_STREAM_END) break;
}
return s->z_err == Z_STREAM_END ? Z_OK : s->z_err;
}
int ZEXPORT gzflush (file, flush)
gzFile file;
int flush;
{
gz_stream *s = (gz_stream*)file;
int err = do_flush (file, flush);
if (err) return err;
fflush(s->file);
return s->z_err == Z_STREAM_END ? Z_OK : s->z_err;
}
#endif /* NO_DEFLATE */
/* ===========================================================================
Sets the starting position for the next gzread or gzwrite on the given
compressed file. The offset represents a number of bytes in the
gzseek returns the resulting offset location as measured in bytes from
the beginning of the uncompressed stream, or -1 in case of error.
SEEK_END is not implemented, returns error.
In this version of the library, gzseek can be extremely slow.
*/
z_off_t ZEXPORT gzseek (file, offset, whence)
gzFile file;
z_off_t offset;
int whence;
{
gz_stream *s = (gz_stream*)file;
if (s == NULL || whence == SEEK_END ||
s->z_err == Z_ERRNO || s->z_err == Z_DATA_ERROR) {
return -1L;
}
if (s->mode == 'w') {
#ifdef NO_DEFLATE
return -1L;
#else
if (whence == SEEK_SET) {
offset -= (unsigned)s->stream.total_in;
}
if (offset < 0) return -1L;
/* At this point, offset is the number of zero bytes to write. */
if (s->inbuf == Z_NULL) {
s->inbuf = (Byte*)ALLOC(Z_BUFSIZE); /* for seeking */
zmemzero(s->inbuf, Z_BUFSIZE);
}
while (offset > 0) {
uInt size = Z_BUFSIZE;
if (offset < Z_BUFSIZE) size = (uInt)offset;
size = (uInt)gzwrite(file, s->inbuf, size);
if (size == 0) return -1L;
offset -= size;
}
return (z_off_t)s->stream.total_in;
#endif
}
/* Rest of function is for reading only */
/* compute absolute position */
if (whence == SEEK_CUR) {
offset += (unsigned)s->stream.total_out;
}
if (offset < 0) return -1L;
if (s->transparent) {
/* map to fseek */
s->stream.avail_in = 0;
s->stream.next_in = s->inbuf;
if (fseek(s->file, offset, SEEK_SET) < 0) return -1L;
s->stream.total_in = s->stream.total_out = (uLong)offset;
return offset;
}
/* For a negative seek, rewind and use positive seek */
if ((uLong)offset >= s->stream.total_out) {
offset -= (unsigned)s->stream.total_out;
} else if (gzrewind(file) < 0) {
return -1L;
}
/* offset is now the number of bytes to skip. */
if (offset != 0 && s->outbuf == Z_NULL) {
s->outbuf = (Byte*)ALLOC(Z_BUFSIZE);
}
while (offset > 0) {
int size = Z_BUFSIZE;
if (offset < Z_BUFSIZE) size = (int)offset;
size = gzread(file, s->outbuf, (uInt)size);
if (size <= 0) return -1L;
offset -= size;
}
return (z_off_t)s->stream.total_out;
}
/* ===========================================================================
Rewinds input file.
*/
int ZEXPORT gzrewind (file)
gzFile file;
{
gz_stream *s = (gz_stream*)file;
if (s == NULL || s->mode != 'r') return -1;
s->z_err = Z_OK;
s->z_eof = 0;
s->stream.avail_in = 0;
s->stream.next_in = s->inbuf;
s->crc = crc32(0L, Z_NULL, 0);
if (s->startpos == 0) { /* not a compressed file */
rewind(s->file);
return 0;
}
(void) inflateReset(&s->stream);
return fseek(s->file, s->startpos, SEEK_SET);
}
/* ===========================================================================
Returns the starting position for the next gzread or gzwrite on the
given compressed file. This position represents a number of bytes in the
uncompressed data stream.
*/
z_off_t ZEXPORT gztell (file)
gzFile file;
{
return gzseek(file, 0L, SEEK_CUR);
}
/* ===========================================================================
Returns 1 when EOF has previously been detected reading the given
input stream, otherwise zero.
*/
int ZEXPORT gzeof (file)
gzFile file;
{
gz_stream *s = (gz_stream*)file;
return (s == NULL || s->mode != 'r') ? 0 : s->z_eof;
}
/* ===========================================================================
Outputs a long in LSB order to the given file
*/
local void putLong (file, x)
FILE *file;
uLong x;
{
int n;
for (n = 0; n < 4; n++) {
fputc((int)(x & 0xff), file);
x >>= 8;
}
}
/* ===========================================================================
Reads a long in LSB order from the given gz_stream. Sets z_err in case
of error.
*/
local uLong getLong (s)
gz_stream *s;
{
uLong x = (uLong)get_byte(s);
int c;
x += ((uLong)get_byte(s))<<8;
x += ((uLong)get_byte(s))<<16;
c = get_byte(s);
if (c == EOF) s->z_err = Z_DATA_ERROR;
x += ((uLong)c)<<24;
return x;
}
/* ===========================================================================
Flushes all pending output if necessary, closes the compressed file
and deallocates all the (de)compression state.
*/
int ZEXPORT gzclose (file)
gzFile file;
{
int err;
gz_stream *s = (gz_stream*)file;
if (s == NULL) return Z_STREAM_ERROR;
if (s->mode == 'w') {
#ifdef NO_DEFLATE
return Z_STREAM_ERROR;
#else
err = do_flush (file, Z_FINISH);
if (err != Z_OK) return destroy((gz_stream*)file);
putLong (s->file, s->crc);
putLong (s->file, s->stream.total_in);
#endif
}
return destroy((gz_stream*)file);
}
/* ===========================================================================
Returns the error message for the last error which occured on the
given compressed file. errnum is set to zlib error number. If an
error occured in the file system and not in the compression library,
errnum is set to Z_ERRNO and the application may consult errno
to get the exact error code.
*/
const char* ZEXPORT gzerror (file, errnum)
gzFile file;
int *errnum;
{
char *m;
gz_stream *s = (gz_stream*)file;
if (s == NULL) {
*errnum = Z_STREAM_ERROR;
return (const char*)ERR_MSG(Z_STREAM_ERROR);
}
*errnum = s->z_err;
if (*errnum == Z_OK) return (const char*)"";
m = (char*)(*errnum == Z_ERRNO ? zstrerror(errno) : s->stream.msg);
if (m == NULL || *m == '\0') m = (char*)ERR_MSG(s->z_err);
TRYFREE(s->msg);
s->msg = (char*)ALLOC(strlen(s->path) + strlen(m) + 3);
strcpy(s->msg, s->path);
strcat(s->msg, ": ");
strcat(s->msg, m);
return (const char*)s->msg;
}
@@ -0,0 +1,403 @@
/* infblock.c -- interpret and process block types to last block
* Copyright (C) 1995-2002 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
#include "zutil.h"
#include "infblock.h"
#include "inftrees.h"
#include "infcodes.h"
#include "infutil.h"
struct inflate_codes_state {int dummy;}; /* for buggy compilers */
/* simplify the use of the inflate_huft type with some defines */
#define exop word.what.Exop
#define bits word.what.Bits
/* Table for deflate from PKZIP's appnote.txt. */
local const uInt border[] = { /* Order of the bit length code lengths */
16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
/*
Notes beyond the 1.93a appnote.txt:
1. Distance pointers never point before the beginning of the output
stream.
2. Distance pointers can point back across blocks, up to 32k away.
3. There is an implied maximum of 7 bits for the bit length table and
15 bits for the actual data.
4. If only one code exists, then it is encoded using one bit. (Zero
would be more efficient, but perhaps a little confusing.) If two
codes exist, they are coded using one bit each (0 and 1).
5. There is no way of sending zero distance codes--a dummy must be
sent if there are none. (History: a pre 2.0 version of PKZIP would
store blocks with no distance codes, but this was discovered to be
too harsh a criterion.) Valid only for 1.93a. 2.04c does allow
zero distance codes, which is sent as one code of zero bits in
length.
6. There are up to 286 literal/length codes. Code 256 represents the
end-of-block. Note however that the static length tree defines
288 codes just to fill out the Huffman codes. Codes 286 and 287
cannot be used though, since there is no length base or extra bits
defined for them. Similarily, there are up to 30 distance codes.
However, static trees define 32 codes (all 5 bits) to fill out the
Huffman codes, but the last two had better not show up in the data.
7. Unzip can check dynamic Huffman blocks for complete code sets.
The exception is that a single code would not be complete (see #4).
8. The five bits following the block type is really the number of
literal codes sent minus 257.
9. Length codes 8,16,16 are interpreted as 13 length codes of 8 bits
(1+6+6). Therefore, to output three times the length, you output
three codes (1+1+1), whereas to output four times the same length,
you only need two codes (1+3). Hmm.
10. In the tree reconstruction algorithm, Code = Code + Increment
only if BitLength(i) is not zero. (Pretty obvious.)
11. Correction: 4 Bits: # of Bit Length codes - 4 (4 - 19)
12. Note: length code 284 can represent 227-258, but length code 285
really is 258. The last length deserves its own, short code
since it gets used a lot in very redundant files. The length
258 is special since 258 - 3 (the min match length) is 255.
13. The literal/length and distance code bit lengths are read as a
single stream of lengths. It is possible (and advantageous) for
a repeat code (16, 17, or 18) to go across the boundary between
the two sets of lengths.
*/
void inflate_blocks_reset(s, z, c)
inflate_blocks_statef *s;
z_streamp z;
uLongf *c;
{
if (c != Z_NULL)
*c = s->check;
if (s->mode == BTREE || s->mode == DTREE)
ZFREE(z, s->sub.trees.blens);
if (s->mode == CODES)
inflate_codes_free(s->sub.decode.codes, z);
s->mode = TYPE;
s->bitk = 0;
s->bitb = 0;
s->read = s->write = s->window;
if (s->checkfn != Z_NULL)
z->adler = s->check = (*s->checkfn)(0L, (const Bytef *)Z_NULL, 0);
Tracev((stderr, "inflate: blocks reset\n"));
}
inflate_blocks_statef *inflate_blocks_new(z, c, w)
z_streamp z;
check_func c;
uInt w;
{
inflate_blocks_statef *s;
if ((s = (inflate_blocks_statef *)ZALLOC
(z,1,sizeof(struct inflate_blocks_state))) == Z_NULL)
return s;
if ((s->hufts =
(inflate_huft *)ZALLOC(z, sizeof(inflate_huft), MANY)) == Z_NULL)
{
ZFREE(z, s);
return Z_NULL;
}
if ((s->window = (Bytef *)ZALLOC(z, 1, w)) == Z_NULL)
{
ZFREE(z, s->hufts);
ZFREE(z, s);
return Z_NULL;
}
s->end = s->window + w;
s->checkfn = c;
s->mode = TYPE;
Tracev((stderr, "inflate: blocks allocated\n"));
inflate_blocks_reset(s, z, Z_NULL);
return s;
}
int inflate_blocks(s, z, r)
inflate_blocks_statef *s;
z_streamp z;
int r;
{
uInt t; /* temporary storage */
uLong b; /* bit buffer */
uInt k; /* bits in bit buffer */
Bytef *p; /* input data pointer */
uInt n; /* bytes available there */
Bytef *q; /* output window write pointer */
uInt m; /* bytes to end of window or read pointer */
/* copy input/output information to locals (UPDATE macro restores) */
LOAD
/* process input based on current state */
while (1) switch (s->mode)
{
case TYPE:
NEEDBITS(3)
t = (uInt)b & 7;
s->last = t & 1;
switch (t >> 1)
{
case 0: /* stored */
Tracev((stderr, "inflate: stored block%s\n",
s->last ? " (last)" : ""));
DUMPBITS(3)
t = k & 7; /* go to byte boundary */
DUMPBITS(t)
s->mode = LENS; /* get length of stored block */
break;
case 1: /* fixed */
Tracev((stderr, "inflate: fixed codes block%s\n",
s->last ? " (last)" : ""));
{
uInt bl, bd;
inflate_huft *tl, *td;
inflate_trees_fixed(&bl, &bd, &tl, &td, z);
s->sub.decode.codes = inflate_codes_new(bl, bd, tl, td, z);
if (s->sub.decode.codes == Z_NULL)
{
r = Z_MEM_ERROR;
LEAVE
}
}
DUMPBITS(3)
s->mode = CODES;
break;
case 2: /* dynamic */
Tracev((stderr, "inflate: dynamic codes block%s\n",
s->last ? " (last)" : ""));
DUMPBITS(3)
s->mode = TABLE;
break;
case 3: /* illegal */
DUMPBITS(3)
s->mode = BAD;
z->msg = (char*)"invalid block type";
r = Z_DATA_ERROR;
LEAVE
}
break;
case LENS:
NEEDBITS(32)
if ((((~b) >> 16) & 0xffff) != (b & 0xffff))
{
s->mode = BAD;
z->msg = (char*)"invalid stored block lengths";
r = Z_DATA_ERROR;
LEAVE
}
s->sub.left = (uInt)b & 0xffff;
b = k = 0; /* dump bits */
Tracev((stderr, "inflate: stored length %u\n", s->sub.left));
s->mode = s->sub.left ? STORED : (s->last ? DRY : TYPE);
break;
case STORED:
if (n == 0)
LEAVE
NEEDOUT
t = s->sub.left;
if (t > n) t = n;
if (t > m) t = m;
zmemcpy(q, p, t);
p += t; n -= t;
q += t; m -= t;
if ((s->sub.left -= t) != 0)
break;
Tracev((stderr, "inflate: stored end, %lu total out\n",
z->total_out + (q >= s->read ? q - s->read :
(s->end - s->read) + (q - s->window))));
s->mode = s->last ? DRY : TYPE;
break;
case TABLE:
NEEDBITS(14)
s->sub.trees.table = t = (uInt)b & 0x3fff;
#ifndef PKZIP_BUG_WORKAROUND
if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29)
{
s->mode = BAD;
z->msg = (char*)"too many length or distance symbols";
r = Z_DATA_ERROR;
LEAVE
}
#endif
t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f);
if ((s->sub.trees.blens = (uIntf*)ZALLOC(z, t, sizeof(uInt))) == Z_NULL)
{
r = Z_MEM_ERROR;
LEAVE
}
DUMPBITS(14)
s->sub.trees.index = 0;
Tracev((stderr, "inflate: table sizes ok\n"));
s->mode = BTREE;
case BTREE:
while (s->sub.trees.index < 4 + (s->sub.trees.table >> 10))
{
NEEDBITS(3)
s->sub.trees.blens[border[s->sub.trees.index++]] = (uInt)b & 7;
DUMPBITS(3)
}
while (s->sub.trees.index < 19)
s->sub.trees.blens[border[s->sub.trees.index++]] = 0;
s->sub.trees.bb = 7;
t = inflate_trees_bits(s->sub.trees.blens, &s->sub.trees.bb,
&s->sub.trees.tb, s->hufts, z);
if (t != Z_OK)
{
r = t;
if (r == Z_DATA_ERROR)
{
ZFREE(z, s->sub.trees.blens);
s->mode = BAD;
}
LEAVE
}
s->sub.trees.index = 0;
Tracev((stderr, "inflate: bits tree ok\n"));
s->mode = DTREE;
case DTREE:
while (t = s->sub.trees.table,
s->sub.trees.index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f))
{
inflate_huft *h;
uInt i, j, c;
t = s->sub.trees.bb;
NEEDBITS(t)
h = s->sub.trees.tb + ((uInt)b & inflate_mask[t]);
t = h->bits;
c = h->base;
if (c < 16)
{
DUMPBITS(t)
s->sub.trees.blens[s->sub.trees.index++] = c;
}
else /* c == 16..18 */
{
i = c == 18 ? 7 : c - 14;
j = c == 18 ? 11 : 3;
NEEDBITS(t + i)
DUMPBITS(t)
j += (uInt)b & inflate_mask[i];
DUMPBITS(i)
i = s->sub.trees.index;
t = s->sub.trees.table;
if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) ||
(c == 16 && i < 1))
{
ZFREE(z, s->sub.trees.blens);
s->mode = BAD;
z->msg = (char*)"invalid bit length repeat";
r = Z_DATA_ERROR;
LEAVE
}
c = c == 16 ? s->sub.trees.blens[i - 1] : 0;
do {
s->sub.trees.blens[i++] = c;
} while (--j);
s->sub.trees.index = i;
}
}
s->sub.trees.tb = Z_NULL;
{
uInt bl, bd;
inflate_huft *tl, *td;
inflate_codes_statef *c;
bl = 9; /* must be <= 9 for lookahead assumptions */
bd = 6; /* must be <= 9 for lookahead assumptions */
t = s->sub.trees.table;
t = inflate_trees_dynamic(257 + (t & 0x1f), 1 + ((t >> 5) & 0x1f),
s->sub.trees.blens, &bl, &bd, &tl, &td,
s->hufts, z);
if (t != Z_OK)
{
if (t == (uInt)Z_DATA_ERROR)
{
ZFREE(z, s->sub.trees.blens);
s->mode = BAD;
}
r = t;
LEAVE
}
Tracev((stderr, "inflate: trees ok\n"));
if ((c = inflate_codes_new(bl, bd, tl, td, z)) == Z_NULL)
{
r = Z_MEM_ERROR;
LEAVE
}
s->sub.decode.codes = c;
}
ZFREE(z, s->sub.trees.blens);
s->mode = CODES;
case CODES:
UPDATE
if ((r = inflate_codes(s, z, r)) != Z_STREAM_END)
return inflate_flush(s, z, r);
r = Z_OK;
inflate_codes_free(s->sub.decode.codes, z);
LOAD
Tracev((stderr, "inflate: codes end, %lu total out\n",
z->total_out + (q >= s->read ? q - s->read :
(s->end - s->read) + (q - s->window))));
if (!s->last)
{
s->mode = TYPE;
break;
}
s->mode = DRY;
case DRY:
FLUSH
if (s->read != s->write)
LEAVE
s->mode = DONE;
case DONE:
r = Z_STREAM_END;
LEAVE
case BAD:
r = Z_DATA_ERROR;
LEAVE
default:
r = Z_STREAM_ERROR;
LEAVE
}
}
int inflate_blocks_free(s, z)
inflate_blocks_statef *s;
z_streamp z;
{
inflate_blocks_reset(s, z, Z_NULL);
ZFREE(z, s->window);
ZFREE(z, s->hufts);
ZFREE(z, s);
Tracev((stderr, "inflate: blocks freed\n"));
return Z_OK;
}
void inflate_set_dictionary(s, d, n)
inflate_blocks_statef *s;
const Bytef *d;
uInt n;
{
zmemcpy(s->window, d, n);
s->read = s->write = s->window + n;
}
/* Returns true if inflate is currently at the end of a block generated
* by Z_SYNC_FLUSH or Z_FULL_FLUSH.
* IN assertion: s != Z_NULL
*/
int inflate_blocks_sync_point(s)
inflate_blocks_statef *s;
{
return s->mode == LENS;
}
@@ -0,0 +1,251 @@
/* infcodes.c -- process literals and length/distance pairs
* Copyright (C) 1995-2002 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
#include "zutil.h"
#include "inftrees.h"
#include "infblock.h"
#include "infcodes.h"
#include "infutil.h"
#include "inffast.h"
/* simplify the use of the inflate_huft type with some defines */
#define exop word.what.Exop
#define bits word.what.Bits
typedef enum { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */
START, /* x: set up for LEN */
LEN, /* i: get length/literal/eob next */
LENEXT, /* i: getting length extra (have base) */
DIST, /* i: get distance next */
DISTEXT, /* i: getting distance extra */
COPY, /* o: copying bytes in window, waiting for space */
LIT, /* o: got literal, waiting for output space */
WASH, /* o: got eob, possibly still output waiting */
END, /* x: got eob and all data flushed */
BADCODE} /* x: got error */
inflate_codes_mode;
/* inflate codes private state */
struct inflate_codes_state {
/* mode */
inflate_codes_mode mode; /* current inflate_codes mode */
/* mode dependent information */
uInt len;
union {
struct {
inflate_huft *tree; /* pointer into tree */
uInt need; /* bits needed */
} code; /* if LEN or DIST, where in tree */
uInt lit; /* if LIT, literal */
struct {
uInt get; /* bits to get for extra */
uInt dist; /* distance back to copy from */
} copy; /* if EXT or COPY, where and how much */
} sub; /* submode */
/* mode independent information */
Byte lbits; /* ltree bits decoded per branch */
Byte dbits; /* dtree bits decoder per branch */
inflate_huft *ltree; /* literal/length/eob tree */
inflate_huft *dtree; /* distance tree */
};
inflate_codes_statef *inflate_codes_new(bl, bd, tl, td, z)
uInt bl, bd;
inflate_huft *tl;
inflate_huft *td; /* need separate declaration for Borland C++ */
z_streamp z;
{
inflate_codes_statef *c;
if ((c = (inflate_codes_statef *)
ZALLOC(z,1,sizeof(struct inflate_codes_state))) != Z_NULL)
{
c->mode = START;
c->lbits = (Byte)bl;
c->dbits = (Byte)bd;
c->ltree = tl;
c->dtree = td;
Tracev((stderr, "inflate: codes new\n"));
}
return c;
}
int inflate_codes(s, z, r)
inflate_blocks_statef *s;
z_streamp z;
int r;
{
uInt j; /* temporary storage */
inflate_huft *t; /* temporary pointer */
uInt e; /* extra bits or operation */
uLong b; /* bit buffer */
uInt k; /* bits in bit buffer */
Bytef *p; /* input data pointer */
uInt n; /* bytes available there */
Bytef *q; /* output window write pointer */
uInt m; /* bytes to end of window or read pointer */
Bytef *f; /* pointer to copy strings from */
inflate_codes_statef *c = s->sub.decode.codes; /* codes state */
/* copy input/output information to locals (UPDATE macro restores) */
LOAD
/* process input and output based on current state */
while (1) switch (c->mode)
{ /* waiting for "i:"=input, "o:"=output, "x:"=nothing */
case START: /* x: set up for LEN */
#ifndef SLOW
if (m >= 258 && n >= 10)
{
UPDATE
r = inflate_fast(c->lbits, c->dbits, c->ltree, c->dtree, s, z);
LOAD
if (r != Z_OK)
{
c->mode = r == Z_STREAM_END ? WASH : BADCODE;
break;
}
}
#endif /* !SLOW */
c->sub.code.need = c->lbits;
c->sub.code.tree = c->ltree;
c->mode = LEN;
case LEN: /* i: get length/literal/eob next */
j = c->sub.code.need;
NEEDBITS(j)
t = c->sub.code.tree + ((uInt)b & inflate_mask[j]);
DUMPBITS(t->bits)
e = (uInt)(t->exop);
if (e == 0) /* literal */
{
c->sub.lit = t->base;
Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
"inflate: literal '%c'\n" :
"inflate: literal 0x%02x\n", t->base));
c->mode = LIT;
break;
}
if (e & 16) /* length */
{
c->sub.copy.get = e & 15;
c->len = t->base;
c->mode = LENEXT;
break;
}
if ((e & 64) == 0) /* next table */
{
c->sub.code.need = e;
c->sub.code.tree = t + t->base;
break;
}
if (e & 32) /* end of block */
{
Tracevv((stderr, "inflate: end of block\n"));
c->mode = WASH;
break;
}
c->mode = BADCODE; /* invalid code */
z->msg = (char*)"invalid literal/length code";
r = Z_DATA_ERROR;
LEAVE
case LENEXT: /* i: getting length extra (have base) */
j = c->sub.copy.get;
NEEDBITS(j)
c->len += (uInt)b & inflate_mask[j];
DUMPBITS(j)
c->sub.code.need = c->dbits;
c->sub.code.tree = c->dtree;
Tracevv((stderr, "inflate: length %u\n", c->len));
c->mode = DIST;
case DIST: /* i: get distance next */
j = c->sub.code.need;
NEEDBITS(j)
t = c->sub.code.tree + ((uInt)b & inflate_mask[j]);
DUMPBITS(t->bits)
e = (uInt)(t->exop);
if (e & 16) /* distance */
{
c->sub.copy.get = e & 15;
c->sub.copy.dist = t->base;
c->mode = DISTEXT;
break;
}
if ((e & 64) == 0) /* next table */
{
c->sub.code.need = e;
c->sub.code.tree = t + t->base;
break;
}
c->mode = BADCODE; /* invalid code */
z->msg = (char*)"invalid distance code";
r = Z_DATA_ERROR;
LEAVE
case DISTEXT: /* i: getting distance extra */
j = c->sub.copy.get;
NEEDBITS(j)
c->sub.copy.dist += (uInt)b & inflate_mask[j];
DUMPBITS(j)
Tracevv((stderr, "inflate: distance %u\n", c->sub.copy.dist));
c->mode = COPY;
case COPY: /* o: copying bytes in window, waiting for space */
f = q - c->sub.copy.dist;
while (f < s->window) /* modulo window size-"while" instead */
f += s->end - s->window; /* of "if" handles invalid distances */
while (c->len)
{
NEEDOUT
OUTBYTE(*f++)
if (f == s->end)
f = s->window;
c->len--;
}
c->mode = START;
break;
case LIT: /* o: got literal, waiting for output space */
NEEDOUT
OUTBYTE(c->sub.lit)
c->mode = START;
break;
case WASH: /* o: got eob, possibly more output */
if (k > 7) /* return unused byte, if any */
{
Assert(k < 16, "inflate_codes grabbed too many bytes")
k -= 8;
n++;
p--; /* can always return one */
}
FLUSH
if (s->read != s->write)
LEAVE
c->mode = END;
case END:
r = Z_STREAM_END;
LEAVE
case BADCODE: /* x: got error */
r = Z_DATA_ERROR;
LEAVE
default:
r = Z_STREAM_ERROR;
LEAVE
}
#ifdef NEED_DUMMY_RETURN
return Z_STREAM_ERROR; /* Some dumb compilers complain without this */
#endif
}
void inflate_codes_free(c, z)
inflate_codes_statef *c;
z_streamp z;
{
ZFREE(z, c);
Tracev((stderr, "inflate: codes free\n"));
}
@@ -0,0 +1,183 @@
/* inffast.c -- process literals and length/distance pairs fast
* Copyright (C) 1995-2002 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
#include "zutil.h"
#include "inftrees.h"
#include "infblock.h"
#include "infcodes.h"
#include "infutil.h"
#include "inffast.h"
struct inflate_codes_state {int dummy;}; /* for buggy compilers */
/* simplify the use of the inflate_huft type with some defines */
#define exop word.what.Exop
#define bits word.what.Bits
/* macros for bit input with no checking and for returning unused bytes */
#define GRABBITS(j) {while(k<(j)){b|=((uLong)NEXTBYTE)<<k;k+=8;}}
#define UNGRAB {c=z->avail_in-n;c=(k>>3)<c?k>>3:c;n+=c;p-=c;k-=c<<3;}
/* Called with number of bytes left to write in window at least 258
(the maximum string length) and number of input bytes available
at least ten. The ten bytes are six bytes for the longest length/
distance pair plus four bytes for overloading the bit buffer. */
int inflate_fast(bl, bd, tl, td, s, z)
uInt bl, bd;
inflate_huft *tl;
inflate_huft *td; /* need separate declaration for Borland C++ */
inflate_blocks_statef *s;
z_streamp z;
{
inflate_huft *t; /* temporary pointer */
uInt e; /* extra bits or operation */
uLong b; /* bit buffer */
uInt k; /* bits in bit buffer */
Bytef *p; /* input data pointer */
uInt n; /* bytes available there */
Bytef *q; /* output window write pointer */
uInt m; /* bytes to end of window or read pointer */
uInt ml; /* mask for literal/length tree */
uInt md; /* mask for distance tree */
uInt c; /* bytes to copy */
uInt d; /* distance back to copy from */
Bytef *r; /* copy source pointer */
/* load input, output, bit values */
LOAD
/* initialize masks */
ml = inflate_mask[bl];
md = inflate_mask[bd];
/* do until not enough input or output space for fast loop */
do { /* assume called with m >= 258 && n >= 10 */
/* get literal/length code */
GRABBITS(20) /* max bits for literal/length code */
if ((e = (t = tl + ((uInt)b & ml))->exop) == 0)
{
DUMPBITS(t->bits)
Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
"inflate: * literal '%c'\n" :
"inflate: * literal 0x%02x\n", t->base));
*q++ = (Byte)t->base;
m--;
continue;
}
do {
DUMPBITS(t->bits)
if (e & 16)
{
/* get extra bits for length */
e &= 15;
c = t->base + ((uInt)b & inflate_mask[e]);
DUMPBITS(e)
Tracevv((stderr, "inflate: * length %u\n", c));
/* decode distance base of block to copy */
GRABBITS(15); /* max bits for distance code */
e = (t = td + ((uInt)b & md))->exop;
do {
DUMPBITS(t->bits)
if (e & 16)
{
/* get extra bits to add to distance base */
e &= 15;
GRABBITS(e) /* get extra bits (up to 13) */
d = t->base + ((uInt)b & inflate_mask[e]);
DUMPBITS(e)
Tracevv((stderr, "inflate: * distance %u\n", d));
/* do the copy */
m -= c;
r = q - d;
if (r < s->window) /* wrap if needed */
{
do {
r += s->end - s->window; /* force pointer in window */
} while (r < s->window); /* covers invalid distances */
e = (uInt)(s->end - r);
if (c > e)
{
c -= e; /* wrapped copy */
do {
*q++ = *r++;
} while (--e);
r = s->window;
do {
*q++ = *r++;
} while (--c);
}
else /* normal copy */
{
*q++ = *r++; c--;
*q++ = *r++; c--;
do {
*q++ = *r++;
} while (--c);
}
}
else /* normal copy */
{
*q++ = *r++; c--;
*q++ = *r++; c--;
do {
*q++ = *r++;
} while (--c);
}
break;
}
else if ((e & 64) == 0)
{
t += t->base;
e = (t += ((uInt)b & inflate_mask[e]))->exop;
}
else
{
z->msg = (char*)"invalid distance code";
UNGRAB
UPDATE
return Z_DATA_ERROR;
}
} while (1);
break;
}
if ((e & 64) == 0)
{
t += t->base;
if ((e = (t += ((uInt)b & inflate_mask[e]))->exop) == 0)
{
DUMPBITS(t->bits)
Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
"inflate: * literal '%c'\n" :
"inflate: * literal 0x%02x\n", t->base));
*q++ = (Byte)t->base;
m--;
break;
}
}
else if (e & 32)
{
Tracevv((stderr, "inflate: * end of block\n"));
UNGRAB
UPDATE
return Z_STREAM_END;
}
else
{
z->msg = (char*)"invalid literal/length code";
UNGRAB
UPDATE
return Z_DATA_ERROR;
}
} while (1);
} while (m >= 258 && n >= 10);
/* not enough input or output--restore pointers and return */
UNGRAB
UPDATE
return Z_OK;
}
@@ -0,0 +1,366 @@
/* inflate.c -- zlib interface to inflate modules
* Copyright (C) 1995-2002 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
#include "zutil.h"
#include "infblock.h"
struct inflate_blocks_state {int dummy;}; /* for buggy compilers */
typedef enum {
METHOD, /* waiting for method byte */
FLAG, /* waiting for flag byte */
DICT4, /* four dictionary check bytes to go */
DICT3, /* three dictionary check bytes to go */
DICT2, /* two dictionary check bytes to go */
DICT1, /* one dictionary check byte to go */
DICT0, /* waiting for inflateSetDictionary */
BLOCKS, /* decompressing blocks */
CHECK4, /* four check bytes to go */
CHECK3, /* three check bytes to go */
CHECK2, /* two check bytes to go */
CHECK1, /* one check byte to go */
DONE, /* finished check, done */
BAD} /* got an error--stay here */
inflate_mode;
/* inflate private state */
struct internal_state {
/* mode */
inflate_mode mode; /* current inflate mode */
/* mode dependent information */
union {
uInt method; /* if FLAGS, method byte */
struct {
uLong was; /* computed check value */
uLong need; /* stream check value */
} check; /* if CHECK, check values to compare */
uInt marker; /* if BAD, inflateSync's marker bytes count */
} sub; /* submode */
/* mode independent information */
int nowrap; /* flag for no wrapper */
uInt wbits; /* log2(window size) (8..15, defaults to 15) */
inflate_blocks_statef
*blocks; /* current inflate_blocks state */
};
int ZEXPORT inflateReset(z)
z_streamp z;
{
if (z == Z_NULL || z->state == Z_NULL)
return Z_STREAM_ERROR;
z->total_in = z->total_out = 0;
z->msg = Z_NULL;
z->state->mode = z->state->nowrap ? BLOCKS : METHOD;
inflate_blocks_reset(z->state->blocks, z, Z_NULL);
Tracev((stderr, "inflate: reset\n"));
return Z_OK;
}
int ZEXPORT inflateEnd(z)
z_streamp z;
{
if (z == Z_NULL || z->state == Z_NULL || z->zfree == Z_NULL)
return Z_STREAM_ERROR;
if (z->state->blocks != Z_NULL)
inflate_blocks_free(z->state->blocks, z);
ZFREE(z, z->state);
z->state = Z_NULL;
Tracev((stderr, "inflate: end\n"));
return Z_OK;
}
int ZEXPORT inflateInit2_(z, w, version, stream_size)
z_streamp z;
int w;
const char *version;
int stream_size;
{
if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
stream_size != sizeof(z_stream))
return Z_VERSION_ERROR;
/* initialize state */
if (z == Z_NULL)
return Z_STREAM_ERROR;
z->msg = Z_NULL;
if (z->zalloc == Z_NULL)
{
z->zalloc = zcalloc;
z->opaque = (voidpf)0;
}
if (z->zfree == Z_NULL) z->zfree = zcfree;
if ((z->state = (struct internal_state FAR *)
ZALLOC(z,1,sizeof(struct internal_state))) == Z_NULL)
return Z_MEM_ERROR;
z->state->blocks = Z_NULL;
/* handle undocumented nowrap option (no zlib header or check) */
z->state->nowrap = 0;
if (w < 0)
{
w = - w;
z->state->nowrap = 1;
}
/* set window size */
if (w < 8 || w > 15)
{
inflateEnd(z);
return Z_STREAM_ERROR;
}
z->state->wbits = (uInt)w;
/* create inflate_blocks state */
if ((z->state->blocks =
inflate_blocks_new(z, z->state->nowrap ? Z_NULL : adler32, (uInt)1 << w))
== Z_NULL)
{
inflateEnd(z);
return Z_MEM_ERROR;
}
Tracev((stderr, "inflate: allocated\n"));
/* reset state */
inflateReset(z);
return Z_OK;
}
int ZEXPORT inflateInit_(z, version, stream_size)
z_streamp z;
const char *version;
int stream_size;
{
return inflateInit2_(z, DEF_WBITS, version, stream_size);
}
#define NEEDBYTE {if(z->avail_in==0)return r;r=f;}
#define NEXTBYTE (z->avail_in--,z->total_in++,*z->next_in++)
int ZEXPORT inflate(z, f)
z_streamp z;
int f;
{
int r;
uInt b;
if (z == Z_NULL || z->state == Z_NULL || z->next_in == Z_NULL)
return Z_STREAM_ERROR;
f = f == Z_FINISH ? Z_BUF_ERROR : Z_OK;
r = Z_BUF_ERROR;
while (1) switch (z->state->mode)
{
case METHOD:
NEEDBYTE
if (((z->state->sub.method = NEXTBYTE) & 0xf) != Z_DEFLATED)
{
z->state->mode = BAD;
z->msg = (char*)"unknown compression method";
z->state->sub.marker = 5; /* can't try inflateSync */
break;
}
if ((z->state->sub.method >> 4) + 8 > z->state->wbits)
{
z->state->mode = BAD;
z->msg = (char*)"invalid window size";
z->state->sub.marker = 5; /* can't try inflateSync */
break;
}
z->state->mode = FLAG;
case FLAG:
NEEDBYTE
b = NEXTBYTE;
if (((z->state->sub.method << 8) + b) % 31)
{
z->state->mode = BAD;
z->msg = (char*)"incorrect header check";
z->state->sub.marker = 5; /* can't try inflateSync */
break;
}
Tracev((stderr, "inflate: zlib header ok\n"));
if (!(b & PRESET_DICT))
{
z->state->mode = BLOCKS;
break;
}
z->state->mode = DICT4;
case DICT4:
NEEDBYTE
z->state->sub.check.need = (uLong)NEXTBYTE << 24;
z->state->mode = DICT3;
case DICT3:
NEEDBYTE
z->state->sub.check.need += (uLong)NEXTBYTE << 16;
z->state->mode = DICT2;
case DICT2:
NEEDBYTE
z->state->sub.check.need += (uLong)NEXTBYTE << 8;
z->state->mode = DICT1;
case DICT1:
NEEDBYTE
z->state->sub.check.need += (uLong)NEXTBYTE;
z->adler = z->state->sub.check.need;
z->state->mode = DICT0;
return Z_NEED_DICT;
case DICT0:
z->state->mode = BAD;
z->msg = (char*)"need dictionary";
z->state->sub.marker = 0; /* can try inflateSync */
return Z_STREAM_ERROR;
case BLOCKS:
r = inflate_blocks(z->state->blocks, z, r);
if (r == Z_DATA_ERROR)
{
z->state->mode = BAD;
z->state->sub.marker = 0; /* can try inflateSync */
break;
}
if (r == Z_OK)
r = f;
if (r != Z_STREAM_END)
return r;
r = f;
inflate_blocks_reset(z->state->blocks, z, &z->state->sub.check.was);
if (z->state->nowrap)
{
z->state->mode = DONE;
break;
}
z->state->mode = CHECK4;
case CHECK4:
NEEDBYTE
z->state->sub.check.need = (uLong)NEXTBYTE << 24;
z->state->mode = CHECK3;
case CHECK3:
NEEDBYTE
z->state->sub.check.need += (uLong)NEXTBYTE << 16;
z->state->mode = CHECK2;
case CHECK2:
NEEDBYTE
z->state->sub.check.need += (uLong)NEXTBYTE << 8;
z->state->mode = CHECK1;
case CHECK1:
NEEDBYTE
z->state->sub.check.need += (uLong)NEXTBYTE;
if (z->state->sub.check.was != z->state->sub.check.need)
{
z->state->mode = BAD;
z->msg = (char*)"incorrect data check";
z->state->sub.marker = 5; /* can't try inflateSync */
break;
}
Tracev((stderr, "inflate: zlib check ok\n"));
z->state->mode = DONE;
case DONE:
return Z_STREAM_END;
case BAD:
return Z_DATA_ERROR;
default:
return Z_STREAM_ERROR;
}
#ifdef NEED_DUMMY_RETURN
return Z_STREAM_ERROR; /* Some dumb compilers complain without this */
#endif
}
int ZEXPORT inflateSetDictionary(z, dictionary, dictLength)
z_streamp z;
const Bytef *dictionary;
uInt dictLength;
{
uInt length = dictLength;
if (z == Z_NULL || z->state == Z_NULL || z->state->mode != DICT0)
return Z_STREAM_ERROR;
if (adler32(1L, dictionary, dictLength) != z->adler) return Z_DATA_ERROR;
z->adler = 1L;
if (length >= ((uInt)1<<z->state->wbits))
{
length = (1<<z->state->wbits)-1;
dictionary += dictLength - length;
}
inflate_set_dictionary(z->state->blocks, dictionary, length);
z->state->mode = BLOCKS;
return Z_OK;
}
int ZEXPORT inflateSync(z)
z_streamp z;
{
uInt n; /* number of bytes to look at */
Bytef *p; /* pointer to bytes */
uInt m; /* number of marker bytes found in a row */
uLong r, w; /* temporaries to save total_in and total_out */
/* set up */
if (z == Z_NULL || z->state == Z_NULL)
return Z_STREAM_ERROR;
if (z->state->mode != BAD)
{
z->state->mode = BAD;
z->state->sub.marker = 0;
}
if ((n = z->avail_in) == 0)
return Z_BUF_ERROR;
p = z->next_in;
m = z->state->sub.marker;
/* search */
while (n && m < 4)
{
static const Byte mark[4] = {0, 0, 0xff, 0xff};
if (*p == mark[m])
m++;
else if (*p)
m = 0;
else
m = 4 - m;
p++, n--;
}
/* restore */
z->total_in += p - z->next_in;
z->next_in = p;
z->avail_in = n;
z->state->sub.marker = m;
/* return no joy or set up to restart on a new block */
if (m != 4)
return Z_DATA_ERROR;
r = z->total_in; w = z->total_out;
inflateReset(z);
z->total_in = r; z->total_out = w;
z->state->mode = BLOCKS;
return Z_OK;
}
/* Returns true if inflate is currently at the end of a block generated
* by Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP
* implementation to provide an additional safety check. PPP uses Z_SYNC_FLUSH
* but removes the length bytes of the resulting empty stored block. When
* decompressing, PPP checks that at the end of input packet, inflate is
* waiting for these length bytes.
*/
int ZEXPORT inflateSyncPoint(z)
z_streamp z;
{
if (z == Z_NULL || z->state == Z_NULL || z->state->blocks == Z_NULL)
return Z_STREAM_ERROR;
return inflate_blocks_sync_point(z->state->blocks);
}
@@ -0,0 +1,454 @@
/* inftrees.c -- generate Huffman trees for efficient decoding
* Copyright (C) 1995-2002 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
#include "zutil.h"
#include "inftrees.h"
#if !defined(BUILDFIXED) && !defined(STDC)
# define BUILDFIXED /* non ANSI compilers may not accept inffixed.h */
#endif
const char inflate_copyright[] =
" inflate 1.1.4 Copyright 1995-2002 Mark Adler ";
/*
If you use the zlib library in a product, an acknowledgment is welcome
in the documentation of your product. If for some reason you cannot
include such an acknowledgment, I would appreciate that you keep this
copyright string in the executable of your product.
*/
struct internal_state {int dummy;}; /* for buggy compilers */
/* simplify the use of the inflate_huft type with some defines */
#define exop word.what.Exop
#define bits word.what.Bits
local int huft_build OF((
uIntf *, /* code lengths in bits */
uInt, /* number of codes */
uInt, /* number of "simple" codes */
const uIntf *, /* list of base values for non-simple codes */
const uIntf *, /* list of extra bits for non-simple codes */
inflate_huft * FAR*,/* result: starting table */
uIntf *, /* maximum lookup bits (returns actual) */
inflate_huft *, /* space for trees */
uInt *, /* hufts used in space */
uIntf * )); /* space for values */
/* Tables for deflate from PKZIP's appnote.txt. */
local const uInt cplens[31] = { /* Copy lengths for literal codes 257..285 */
3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
/* see note #13 above about 258 */
local const uInt cplext[31] = { /* Extra bits for literal codes 257..285 */
0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2,
3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 112, 112}; /* 112==invalid */
local const uInt cpdist[30] = { /* Copy offsets for distance codes 0..29 */
1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
8193, 12289, 16385, 24577};
local const uInt cpdext[30] = { /* Extra bits for distance codes */
0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
7, 7, 8, 8, 9, 9, 10, 10, 11, 11,
12, 12, 13, 13};
/*
Huffman code decoding is performed using a multi-level table lookup.
The fastest way to decode is to simply build a lookup table whose
size is determined by the longest code. However, the time it takes
to build this table can also be a factor if the data being decoded
is not very long. The most common codes are necessarily the
shortest codes, so those codes dominate the decoding time, and hence
the speed. The idea is you can have a shorter table that decodes the
shorter, more probable codes, and then point to subsidiary tables for
the longer codes. The time it costs to decode the longer codes is
then traded against the time it takes to make longer tables.
This results of this trade are in the variables lbits and dbits
below. lbits is the number of bits the first level table for literal/
length codes can decode in one step, and dbits is the same thing for
the distance codes. Subsequent tables are also less than or equal to
those sizes. These values may be adjusted either when all of the
codes are shorter than that, in which case the longest code length in
bits is used, or when the shortest code is *longer* than the requested
table size, in which case the length of the shortest code in bits is
used.
There are two different values for the two tables, since they code a
different number of possibilities each. The literal/length table
codes 286 possible values, or in a flat code, a little over eight
bits. The distance table codes 30 possible values, or a little less
than five bits, flat. The optimum values for speed end up being
about one bit more than those, so lbits is 8+1 and dbits is 5+1.
The optimum values may differ though from machine to machine, and
possibly even between compilers. Your mileage may vary.
*/
/* If BMAX needs to be larger than 16, then h and x[] should be uLong. */
#define BMAX 15 /* maximum bit length of any code */
local int huft_build(b, n, s, d, e, t, m, hp, hn, v)
uIntf *b; /* code lengths in bits (all assumed <= BMAX) */
uInt n; /* number of codes (assumed <= 288) */
uInt s; /* number of simple-valued codes (0..s-1) */
const uIntf *d; /* list of base values for non-simple codes */
const uIntf *e; /* list of extra bits for non-simple codes */
inflate_huft * FAR *t; /* result: starting table */
uIntf *m; /* maximum lookup bits, returns actual */
inflate_huft *hp; /* space for trees */
uInt *hn; /* hufts used in space */
uIntf *v; /* working area: values in order of bit length */
/* Given a list of code lengths and a maximum table size, make a set of
tables to decode that set of codes. Return Z_OK on success, Z_BUF_ERROR
if the given code set is incomplete (the tables are still built in this
case), or Z_DATA_ERROR if the input is invalid. */
{
uInt a; /* counter for codes of length k */
uInt c[BMAX+1]; /* bit length count table */
uInt f; /* i repeats in table every f entries */
int g; /* maximum code length */
int h; /* table level */
register uInt i; /* counter, current code */
register uInt j; /* counter */
register int k; /* number of bits in current code */
int l; /* bits per table (returned in m) */
uInt mask; /* (1 << w) - 1, to avoid cc -O bug on HP */
register uIntf *p; /* pointer into c[], b[], or v[] */
inflate_huft *q; /* points to current table */
struct inflate_huft_s r; /* table entry for structure assignment */
inflate_huft *u[BMAX]; /* table stack */
register int w; /* bits before this table == (l * h) */
uInt x[BMAX+1]; /* bit offsets, then code stack */
uIntf *xp; /* pointer into x */
int y; /* number of dummy codes added */
uInt z; /* number of entries in current table */
/* Generate counts for each bit length */
p = c;
#define C0 *p++ = 0;
#define C2 C0 C0 C0 C0
#define C4 C2 C2 C2 C2
C4 /* clear c[]--assume BMAX+1 is 16 */
p = b; i = n;
do {
c[*p++]++; /* assume all entries <= BMAX */
} while (--i);
if (c[0] == n) /* null input--all zero length codes */
{
*t = (inflate_huft *)Z_NULL;
*m = 0;
return Z_OK;
}
/* Find minimum and maximum length, bound *m by those */
l = (int)*m;
for (j = 1; j <= BMAX; j++)
if (c[j])
break;
k = (int)j; /* minimum code length */
if ((uInt)l < j)
l = (int)j;
for (i = BMAX; i; i--)
if (c[i])
break;
g = (int)i; /* maximum code length */
if ((uInt)l > i)
l = (int)i;
*m = (uInt)l;
/* Adjust last length count to fill out codes, if needed */
for (y = 1 << j; j < i; j++, y <<= 1)
if ((y -= (int)c[j]) < 0)
return Z_DATA_ERROR;
if ((y -= (int)c[i]) < 0)
return Z_DATA_ERROR;
c[i] += (uInt)y;
/* Generate starting offsets into the value table for each length */
x[1] = j = 0;
p = c + 1; xp = x + 2;
while (--i) { /* note that i == g from above */
*xp++ = (j += *p++);
}
/* Make a table of values in order of bit lengths */
p = b; i = 0;
do {
if ((j = *p++) != 0)
v[x[j]++] = i;
} while (++i < n);
n = x[g]; /* set n to length of v */
/* Generate the Huffman codes and for each, make the table entries */
x[0] = i = 0; /* first Huffman code is zero */
p = v; /* grab values in bit order */
h = -1; /* no tables yet--level -1 */
w = -l; /* bits decoded == (l * h) */
u[0] = (inflate_huft *)Z_NULL; /* just to keep compilers happy */
q = (inflate_huft *)Z_NULL; /* ditto */
z = 0; /* ditto */
/* go through the bit lengths (k already is bits in shortest code) */
for (; k <= g; k++)
{
a = c[k];
while (a--)
{
/* here i is the Huffman code of length k bits for value *p */
/* make tables up to required level */
while (k > w + l)
{
h++;
w += l; /* previous table always l bits */
/* compute minimum size table less than or equal to l bits */
z = (uInt)(g - w);
z = z > (uInt)l ? (uInt)l : z; /* table size upper limit */
if ((f = (uInt)(1 << (j = (uInt)(k - w)))) > a + 1) /* try a k-w bit table */
{ /* too few codes for k-w bit table */
f -= a + 1; /* deduct codes from patterns left */
xp = c + k;
if (j < z)
while (++j < z) /* try smaller tables up to z bits */
{
if ((f <<= 1) <= *++xp)
break; /* enough codes to use up j bits */
f -= *xp; /* else deduct codes from patterns */
}
}
z = (uInt)(1 << j); /* table entries for j-bit table */
/* allocate new table */
if (*hn + z > MANY) /* (note: doesn't matter for fixed) */
return Z_DATA_ERROR; /* overflow of MANY */
u[h] = q = hp + *hn;
*hn += z;
/* connect to last table, if there is one */
if (h)
{
x[h] = i; /* save pattern for backing up */
r.bits = (Byte)l; /* bits to dump before this table */
r.exop = (Byte)j; /* bits in this table */
j = i >> (w - l);
r.base = (uInt)(q - u[h-1] - j); /* offset to this table */
u[h-1][j] = r; /* connect to last table */
}
else
*t = q; /* first table is returned result */
}
/* set up table entry in r */
r.bits = (Byte)(k - w);
if (p >= v + n)
r.exop = 128 + 64; /* out of values--invalid code */
else if (*p < s)
{
r.exop = (Byte)(*p < 256 ? 0 : 32 + 64); /* 256 is end-of-block */
r.base = *p++; /* simple code is just the value */
}
else
{
r.exop = (Byte)(e[*p - s] + 16 + 64);/* non-simple--look up in lists */
r.base = d[*p++ - s];
}
/* fill code-like entries with r */
f = (uInt)(1 << (k - w));
for (j = (uInt)(i >> w); j < z; j += f)
q[j] = r;
/* backwards increment the k-bit code i */
for (j = (uInt)(1 << (k - 1)); i & j; j >>= 1)
i ^= j;
i ^= j;
/* backup over finished tables */
mask = (uInt)((1 << w) - 1); /* needed on HP, cc -O bug */
while ((i & mask) != x[h])
{
h--; /* don't need to update q */
w -= l;
mask = (uInt)((1 << w) - 1);
}
}
}
/* Return Z_BUF_ERROR if we were given an incomplete table */
return y != 0 && g != 1 ? Z_BUF_ERROR : Z_OK;
}
int inflate_trees_bits(c, bb, tb, hp, z)
uIntf *c; /* 19 code lengths */
uIntf *bb; /* bits tree desired/actual depth */
inflate_huft * FAR *tb; /* bits tree result */
inflate_huft *hp; /* space for trees */
z_streamp z; /* for messages */
{
int r;
uInt hn = 0; /* hufts used in space */
uIntf *v; /* work area for huft_build */
if ((v = (uIntf*)ZALLOC(z, 19, sizeof(uInt))) == Z_NULL)
return Z_MEM_ERROR;
r = huft_build(c, 19, 19, (uIntf*)Z_NULL, (uIntf*)Z_NULL,
tb, bb, hp, &hn, v);
if (r == Z_DATA_ERROR)
z->msg = (char*)"oversubscribed dynamic bit lengths tree";
else if (r == Z_BUF_ERROR || *bb == 0)
{
z->msg = (char*)"incomplete dynamic bit lengths tree";
r = Z_DATA_ERROR;
}
ZFREE(z, v);
return r;
}
int inflate_trees_dynamic(nl, nd, c, bl, bd, tl, td, hp, z)
uInt nl; /* number of literal/length codes */
uInt nd; /* number of distance codes */
uIntf *c; /* that many (total) code lengths */
uIntf *bl; /* literal desired/actual bit depth */
uIntf *bd; /* distance desired/actual bit depth */
inflate_huft * FAR *tl; /* literal/length tree result */
inflate_huft * FAR *td; /* distance tree result */
inflate_huft *hp; /* space for trees */
z_streamp z; /* for messages */
{
int r;
uInt hn = 0; /* hufts used in space */
uIntf *v; /* work area for huft_build */
/* allocate work area */
if ((v = (uIntf*)ZALLOC(z, 288, sizeof(uInt))) == Z_NULL)
return Z_MEM_ERROR;
/* build literal/length tree */
r = huft_build(c, nl, 257, cplens, cplext, tl, bl, hp, &hn, v);
if (r != Z_OK || *bl == 0)
{
if (r == Z_DATA_ERROR)
z->msg = (char*)"oversubscribed literal/length tree";
else if (r != Z_MEM_ERROR)
{
z->msg = (char*)"incomplete literal/length tree";
r = Z_DATA_ERROR;
}
ZFREE(z, v);
return r;
}
/* build distance tree */
r = huft_build(c + nl, nd, 0, cpdist, cpdext, td, bd, hp, &hn, v);
if (r != Z_OK || (*bd == 0 && nl > 257))
{
if (r == Z_DATA_ERROR)
z->msg = (char*)"oversubscribed distance tree";
else if (r == Z_BUF_ERROR) {
#ifdef PKZIP_BUG_WORKAROUND
r = Z_OK;
}
#else
z->msg = (char*)"incomplete distance tree";
r = Z_DATA_ERROR;
}
else if (r != Z_MEM_ERROR)
{
z->msg = (char*)"empty distance tree with lengths";
r = Z_DATA_ERROR;
}
ZFREE(z, v);
return r;
#endif
}
/* done */
ZFREE(z, v);
return Z_OK;
}
/* build fixed tables only once--keep them here */
#ifdef BUILDFIXED
local int fixed_built = 0;
#define FIXEDH 544 /* number of hufts used by fixed tables */
local inflate_huft fixed_mem[FIXEDH];
local uInt fixed_bl;
local uInt fixed_bd;
local inflate_huft *fixed_tl;
local inflate_huft *fixed_td;
#else
#include "inffixed.h"
#endif
int inflate_trees_fixed(bl, bd, tl, td, z)
uIntf *bl; /* literal desired/actual bit depth */
uIntf *bd; /* distance desired/actual bit depth */
inflate_huft * FAR *tl; /* literal/length tree result */
inflate_huft * FAR *td; /* distance tree result */
z_streamp z; /* for memory allocation */
{
#ifdef BUILDFIXED
/* build fixed tables if not already */
if (!fixed_built)
{
int k; /* temporary variable */
uInt f = 0; /* number of hufts used in fixed_mem */
uIntf *c; /* length list for huft_build */
uIntf *v; /* work area for huft_build */
/* allocate memory */
if ((c = (uIntf*)ZALLOC(z, 288, sizeof(uInt))) == Z_NULL)
return Z_MEM_ERROR;
if ((v = (uIntf*)ZALLOC(z, 288, sizeof(uInt))) == Z_NULL)
{
ZFREE(z, c);
return Z_MEM_ERROR;
}
/* literal table */
for (k = 0; k < 144; k++)
c[k] = 8;
for (; k < 256; k++)
c[k] = 9;
for (; k < 280; k++)
c[k] = 7;
for (; k < 288; k++)
c[k] = 8;
fixed_bl = 9;
huft_build(c, 288, 257, cplens, cplext, &fixed_tl, &fixed_bl,
fixed_mem, &f, v);
/* distance table */
for (k = 0; k < 30; k++)
c[k] = 5;
fixed_bd = 5;
huft_build(c, 30, 0, cpdist, cpdext, &fixed_td, &fixed_bd,
fixed_mem, &f, v);
/* done */
ZFREE(z, v);
ZFREE(z, c);
fixed_built = 1;
}
#endif
*bl = fixed_bl;
*bd = fixed_bd;
*tl = fixed_tl;
*td = fixed_td;
return Z_OK;
}
@@ -0,0 +1,87 @@
/* inflate_util.c -- data and routines common to blocks and codes
* Copyright (C) 1995-2002 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
#include "zutil.h"
#include "infblock.h"
#include "inftrees.h"
#include "infcodes.h"
#include "infutil.h"
struct inflate_codes_state {int dummy;}; /* for buggy compilers */
/* And'ing with mask[n] masks the lower n bits */
uInt inflate_mask[17] = {
0x0000,
0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff,
0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff
};
/* copy as much as possible from the sliding window to the output area */
int inflate_flush(s, z, r)
inflate_blocks_statef *s;
z_streamp z;
int r;
{
uInt n;
Bytef *p;
Bytef *q;
/* local copies of source and destination pointers */
p = z->next_out;
q = s->read;
/* compute number of bytes to copy as far as end of window */
n = (uInt)((q <= s->write ? s->write : s->end) - q);
if (n > z->avail_out) n = z->avail_out;
if (n && r == Z_BUF_ERROR) r = Z_OK;
/* update counters */
z->avail_out -= n;
z->total_out += n;
/* update check information */
if (s->checkfn != Z_NULL)
z->adler = s->check = (*s->checkfn)(s->check, q, n);
/* copy as far as end of window */
zmemcpy(p, q, n);
p += n;
q += n;
/* see if more to copy at beginning of window */
if (q == s->end)
{
/* wrap pointers */
q = s->window;
if (s->write == s->end)
s->write = s->window;
/* compute bytes to copy */
n = (uInt)(s->write - q);
if (n > z->avail_out) n = z->avail_out;
if (n && r == Z_BUF_ERROR) r = Z_OK;
/* update counters */
z->avail_out -= n;
z->total_out += n;
/* update check information */
if (s->checkfn != Z_NULL)
z->adler = s->check = (*s->checkfn)(s->check, q, n);
/* copy */
zmemcpy(p, q, n);
p += n;
q += n;
}
/* update pointers */
z->next_out = p;
s->read = q;
/* done */
return r;
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,58 @@
/* uncompr.c -- decompress a memory buffer
* Copyright (C) 1995-2002 Jean-loup Gailly.
* For conditions of distribution and use, see copyright notice in zlib.h
*/
/* @(#) $Id$ */
#include "zlib.h"
/* ===========================================================================
Decompresses the source buffer into the destination buffer. sourceLen is
the byte length of the source buffer. Upon entry, destLen is the total
size of the destination buffer, which must be large enough to hold the
entire uncompressed data. (The size of the uncompressed data must have
been saved previously by the compressor and transmitted to the decompressor
by some mechanism outside the scope of this compression library.)
Upon exit, destLen is the actual size of the compressed buffer.
This function can be used to decompress a whole file at once if the
input file is mmap'ed.
uncompress returns Z_OK if success, Z_MEM_ERROR if there was not
enough memory, Z_BUF_ERROR if there was not enough room in the output
buffer, or Z_DATA_ERROR if the input data was corrupted.
*/
int ZEXPORT uncompress (dest, destLen, source, sourceLen)
Bytef *dest;
uLongf *destLen;
const Bytef *source;
uLong sourceLen;
{
z_stream stream;
int err;
stream.next_in = (Bytef*)source;
stream.avail_in = (uInt)sourceLen;
/* Check for source > 64K on 16-bit machine: */
if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR;
stream.next_out = dest;
stream.avail_out = (uInt)*destLen;
if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR;
stream.zalloc = (alloc_func)0;
stream.zfree = (free_func)0;
err = inflateInit(&stream);
if (err != Z_OK) return err;
err = inflate(&stream, Z_FINISH);
if (err != Z_STREAM_END) {
inflateEnd(&stream);
return err == Z_OK ? Z_BUF_ERROR : err;
}
*destLen = stream.total_out;
err = inflateEnd(&stream);
return err;
}
@@ -0,0 +1,225 @@
/* zutil.c -- target dependent utility functions for the compression library
* Copyright (C) 1995-2002 Jean-loup Gailly.
* For conditions of distribution and use, see copyright notice in zlib.h
*/
/* @(#) $Id$ */
#include "zutil.h"
struct internal_state {int dummy;}; /* for buggy compilers */
#ifndef STDC
extern void exit OF((int));
#endif
const char *z_errmsg[10] = {
"need dictionary", /* Z_NEED_DICT 2 */
"stream end", /* Z_STREAM_END 1 */
"", /* Z_OK 0 */
"file error", /* Z_ERRNO (-1) */
"stream error", /* Z_STREAM_ERROR (-2) */
"data error", /* Z_DATA_ERROR (-3) */
"insufficient memory", /* Z_MEM_ERROR (-4) */
"buffer error", /* Z_BUF_ERROR (-5) */
"incompatible version",/* Z_VERSION_ERROR (-6) */
""};
const char * ZEXPORT zlibVersion()
{
return ZLIB_VERSION;
}
#ifdef DEBUG
# ifndef verbose
# define verbose 0
# endif
int z_verbose = verbose;
void z_error (m)
char *m;
{
fprintf(stderr, "%s\n", m);
exit(1);
}
#endif
/* exported to allow conversion of error code to string for compress() and
* uncompress()
*/
const char * ZEXPORT zError(err)
int err;
{
return ERR_MSG(err);
}
#ifndef HAVE_MEMCPY
void zmemcpy(dest, source, len)
Bytef* dest;
const Bytef* source;
uInt len;
{
if (len == 0) return;
do {
*dest++ = *source++; /* ??? to be unrolled */
} while (--len != 0);
}
int zmemcmp(s1, s2, len)
const Bytef* s1;
const Bytef* s2;
uInt len;
{
uInt j;
for (j = 0; j < len; j++) {
if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1;
}
return 0;
}
void zmemzero(dest, len)
Bytef* dest;
uInt len;
{
if (len == 0) return;
do {
*dest++ = 0; /* ??? to be unrolled */
} while (--len != 0);
}
#endif
#ifdef __TURBOC__
#if (defined( __BORLANDC__) || !defined(SMALL_MEDIUM)) && !defined(__32BIT__)
/* Small and medium model in Turbo C are for now limited to near allocation
* with reduced MAX_WBITS and MAX_MEM_LEVEL
*/
# define MY_ZCALLOC
/* Turbo C malloc() does not allow dynamic allocation of 64K bytes
* and farmalloc(64K) returns a pointer with an offset of 8, so we
* must fix the pointer. Warning: the pointer must be put back to its
* original form in order to free it, use zcfree().
*/
#define MAX_PTR 10
/* 10*64K = 640K */
local int next_ptr = 0;
typedef struct ptr_table_s {
voidpf org_ptr;
voidpf new_ptr;
} ptr_table;
local ptr_table table[MAX_PTR];
/* This table is used to remember the original form of pointers
* to large buffers (64K). Such pointers are normalized with a zero offset.
* Since MSDOS is not a preemptive multitasking OS, this table is not
* protected from concurrent access. This hack doesn't work anyway on
* a protected system like OS/2. Use Microsoft C instead.
*/
voidpf zcalloc (voidpf opaque, unsigned items, unsigned size)
{
voidpf buf = opaque; /* just to make some compilers happy */
ulg bsize = (ulg)items*size;
/* If we allocate less than 65520 bytes, we assume that farmalloc
* will return a usable pointer which doesn't have to be normalized.
*/
if (bsize < 65520L) {
buf = farmalloc(bsize);
if (*(ush*)&buf != 0) return buf;
} else {
buf = farmalloc(bsize + 16L);
}
if (buf == NULL || next_ptr >= MAX_PTR) return NULL;
table[next_ptr].org_ptr = buf;
/* Normalize the pointer to seg:0 */
*((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4;
*(ush*)&buf = 0;
table[next_ptr++].new_ptr = buf;
return buf;
}
void zcfree (voidpf opaque, voidpf ptr)
{
int n;
if (*(ush*)&ptr != 0) { /* object < 64K */
farfree(ptr);
return;
}
/* Find the original pointer */
for (n = 0; n < next_ptr; n++) {
if (ptr != table[n].new_ptr) continue;
farfree(table[n].org_ptr);
while (++n < next_ptr) {
table[n-1] = table[n];
}
next_ptr--;
return;
}
ptr = opaque; /* just to make some compilers happy */
Assert(0, "zcfree: ptr not found");
}
#endif
#endif /* __TURBOC__ */
#if defined(M_I86) && !defined(__32BIT__)
/* Microsoft C in 16-bit mode */
# define MY_ZCALLOC
#if (!defined(_MSC_VER) || (_MSC_VER <= 600))
# define _halloc halloc
# define _hfree hfree
#endif
voidpf zcalloc (voidpf opaque, unsigned items, unsigned size)
{
if (opaque) opaque = 0; /* to make compiler happy */
return _halloc((long)items, size);
}
void zcfree (voidpf opaque, voidpf ptr)
{
if (opaque) opaque = 0; /* to make compiler happy */
_hfree(ptr);
}
#endif /* MSC */
#ifndef MY_ZCALLOC /* Any system without a special alloc function */
#ifndef STDC
extern voidp calloc OF((uInt items, uInt size));
extern void free OF((voidpf ptr));
#endif
voidpf zcalloc (opaque, items, size)
voidpf opaque;
unsigned items;
unsigned size;
{
if (opaque) items += size - size; /* make compiler happy */
return (voidpf)calloc(items, size);
}
void zcfree (opaque, ptr)
voidpf opaque;
voidpf ptr;
{
free(ptr);
if (opaque) return; /* make compiler happy */
}
#endif /* MY_ZCALLOC */