original files of m241
This commit is contained in:
@@ -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 */
|
||||
Reference in New Issue
Block a user