📄 dbfunct.c
字号:
/*
* Copyright (C) Ericsson Mobile Communications AB, 2000, 2001.
* Licensed to AU-System AB.
* All rights reserved.
*
* This software is covered by the license agreement between
* the end user and AU-System AB, and may be used and copied
* only in accordance with the terms of the said agreement.
*
* Neither Ericsson Mobile Communications AB nor AU-System AB
* assumes any responsibility or liability for any errors or inaccuracies in
* this software, or any consequential, incidental or indirect damage arising
* out of the use of the Generic WAP Client software.
*/
/*
* dbFunct.c
*
* Data channel handling.
* Store and find authentication information in database.
* Store and find cookies.
*
* This file contains various functions with two things in common:
* they both use wipdb database and they access internal
* structures in the database.
*
*
* Created by Niclas Kellgren 000904.
*
* Revision history:
* 000914, NKE: data channel code moved from wipdb.c
* 001004, NKE: host authentication added
* 001010, NKE: proxy authentication api added
* 001019, NKE: host and proxy api changed
* 001106, NKE: proxy authentication functionality added
* 001116, NKE: updates and corrections
* 001117, NKE: documentation
* 001207, NKE: corrected addDataChannel
* 001211, NKE: removed persistent proxy handling
* 010122, NKE: replaced configuration variable names with constants
* 010130, NKE: changed the declaration of addHost and deleteHost
* 010130, NKE: added getFirstConfiguredObject
* 010208, RMZ: added functions for cookies
* 010315, NKE: added COOKIES_ENABLED default value
* 010320, NKE: bugfix and some optimizations of data channels
* 010402, RMZ: modified host handling/matching for data channels
* 010511, IPN: added ALLOW_WTLS_CLASS_1 and MASTER_GW default values.
* 010514, NKE: added setPersistentAuthStatus
* 010514, NKE: fixed bug in setPersistentAuthStatus
*/
#include "dbfunct.h"
/*************************************************************/
/************************ external *************************/
/*************************************************************/
/*************
* Constants *
*************/
/* These constants are copies from wipdb.c */
enum {
DB_keyLen = 6,
DB_flag_rec = 0,
DB_flag_str = 3,
DB_flag_dataExternal = 0x0080,
DB_flag_lastElement = 0x0100
};
/*********
* Types *
*********/
/* These types are copies from wipdb.c */
typedef union {
UINT32 i;
void* p;
BYTE* s;
struct RecordStruct* r;
struct FieldStruct* f;
struct ElementStruct* e;
} DataUnion;
typedef struct ElementStruct* ElementPtr;
typedef struct ElementStruct {
ElementPtr next;
DataUnion data;
UINT16 flags;
} Element;
typedef struct FieldStruct {
ElementPtr next;
DataUnion data;
UINT16 flags;
BYTE key[DB_keyLen];
} Field, *FieldPtr;
typedef struct RecordStruct* RecordPtr;
typedef struct RecordStruct {
ElementPtr next;
DataUnion data;
UINT16 flags;
BYTE key[DB_keyLen];
UINT16 ref;
RecordPtr nextRec;
} Record;
/* Common types used */
/*
Typedef to store substrings of an url
*/
typedef struct UrlParts {
BYTE* host;
BYTE* hEnd; /* one byte past host end */
BYTE* path;
BYTE* pEnd; /* one byte past path end */
} UrlParts;
/*************************
* External declarations *
*************************/
/* Found in wipdb.c */
RecordPtr db_findRecord(DB_ref record);
FieldPtr db_findField(const BYTE* key);
UINT8 db_deleteItem_ptr(RecordPtr rec, ElementPtr currentElem);
void db_moveToFront(RecordPtr rec, ElementPtr elem);
ElementPtr db_createNewElement (RecordPtr rec, const BYTE* key, UINT16 flags, DataUnion data,
ElementPtr prev, ElementPtr element, UINT8 *errorCode);
/* Found in CmmnRsrc.c */
extern const BYTE latin1_lc[256];
/***************************************
* Common static function declarations *
***************************************/
static BOOL parseUrl(BYTE* url, UrlParts* urlParts);
static BOOL domainMatch(UrlParts* urlParts, BYTE* domain, BYTE* dEnd,
BOOL reqDotRule, BOOL emptyRule, INT32 maxPreLabels,
INT32* preLabels);
static BOOL pathMatch(UrlParts* urlParts, BYTE* path, BOOL fullSegRule,
UINT32* pLen);
static BYTE* dupSubStr(const BYTE* str, const BYTE* strEnd);
/*************************************************************/
/****************** data channel handling ******************/
/*************************************************************/
/*
For information on data channels, objects and what you can
configure, see Users Manual. You can find all all abbreviations
for element names in capiclnt.c functions: CLNTc_setIntConfig,
CLNTc_setStrConfig, CLNTc_setDCHIntConfig, CLNTc_setDCHStrConfig.
There are three types of configure: global, template and local:
* The global configurations are saved under root/globl. They are
valid for all objects and channels.
* The template is object 0, saved as root/glob/obj00. When
creating a new object, the template is copied. The new object
includes copies of all parameters and data channels. In fact,
the object 0 is a complete channel and can be used for searching
if one would like to.
If changing the template, only when a new object is created, the
changes take place.
* The local objects are saved under the root and named objxx,
where xx is the hexadecimal representation of the object number.
STRUCTURE
The structure used is a combination of a database hierachy and
external lists containing data and pointers to database elements
This combination is not desirable. If the database is manipulated
through ordinary database operations, such as db_deleteItem, then
the external structure will contains dangling pointers and the
system may crash. An alternative could be to put all information
outside or inside the database. None of these alternatives are
appealing. A pure database solution is far to slow, since the
data channel handling are very frequent operations. If not using
the database at all, then all of its advantages are lost and
the program will be significantly larger. The database handles
deallocation and persistent memory among other things.
The database tree looks like this if two channels have been added
to the default system.
root
|
obj01 --- globl ---
| |
| obj00 --- ua --- cMode --- cAge
| |
| updtI --- dsplI --- hstSz
|
|
dch00 ------------------------ dch01 ------------- updtI --- dsplI --- hstSz
| |
hosts --- onln --- tmout hosts --- onln --- tmout
| |
<> --- <> --- <> --- <> --- <> --- <> ---
| | | | | |
string string string string string string
At top level there are 'globl' and 'obj'. 'globl' contains the
global constants. It hosts 'obj00', the object template. When
creating a new object, the template is copied and renamed.
In this code, elements are created and inserted into the database
without calling the approptiate database operations (setItem).
This is done to speed up handling, but at the same time care must
be taken to introduce new flags etc. into this code as well.
*/
/*************
* Constants *
*************/
/*********
* Types *
*********/
typedef struct ChannelListStruct {
RecordPtr hostPtr;
DB_ref channelRef;
UINT8 channelNbr;
} ChannelList[DB_maxNbrOfDataChannels], *ChannelListPtr;
typedef struct ObjectListStruct {
ChannelListPtr channelList;
INT16 defaultChannel;
DB_ref objectRef;
UINT8 channelListSize;
UINT8 objectNbr;
} ObjectList[DB_maxNbrOfObjects], *ObjectListPtr;
/*************
* Variables *
*************/
static ObjectListPtr objectList; /* List of all objects created by createObjects.\*/
static int objectListSize = 0; /* Both used for data channel handling. */
static DB_ref obj00Ref = DB_null; /* Reference to the object template = /globl/obj00 */
DB_ref globalRef = DB_null; /* Reference to the global object = /glob */
/* variables to collect id:s (Nbr:s) of expired channels */
static UINT8 expChNbrList[DB_maxNbrOfDataChannels];
static int expChNbrListSize = 0;
static int nextExpChNbrListInd = 0;
/*************
* Functions *
*************/
/*
* Return pointer the struct associatied with 'channel' in the
* channel list of 'object'. NULL is returned if 'object' or
*'channel' does not exist.
*/
static ChannelListPtr getChannel(UINT8 object, UINT8 channel)
{
ChannelListPtr channelList;
int i, j;
/* Find channel list for object */
for (i=0; ; i++) {
if (i == objectListSize)
return NULL;
if (objectList[i].objectNbr == object) {
channelList = objectList[i].channelList;
break;
}
}
/* Find channel */
for (j=0; j < objectList[i].channelListSize; j++) {
if (channelList[j].channelNbr == channel)
return &channelList[j];
}
return NULL;
}
/*
* Return a reference to the record associated with object
* 'object'.
*/
DB_ref getObjectRef(UINT8 object)
{
int i;
/* Find object */
for (i=0; i < objectListSize; i++) {
if (objectList[i].objectNbr == object)
return objectList[i].objectRef;
}
return DB_null;
}
/*
* Return a reference to the record associatied with channel
* 'channel' in object 'object'.
*/
DB_ref getChannelRef(UINT8 object, UINT8 channel)
{
ChannelListPtr channelStruct;
channelStruct = getChannel(object, channel);
if (channelStruct == NULL)
return DB_null;
else
return channelStruct->channelRef;
}
/*
* Create an record containing all mandatory fields. The record
* is named "objxx", where xx is the hexidecimal representation
* of 'object' in lower-case. This is done by copying the template
* globl/obj00. If obj00 contains any predefined data channels,
* the are copied too.
*
* Return a pointer to the new channel list.
*/
ObjectListPtr addObjectInternal(INT8 object) {
BYTE key[] = "obj??";
ChannelListPtr channelList;
ChannelListPtr sourceList;
ObjectListPtr objectRecord;
FieldPtr field;
DB_ref refO;
DB_ref ref;
UINT8 error;
UINT8 nbrOfChannels = 0;
int i;
if (objectListSize == DB_maxNbrOfObjects || object == 0)
return NULL;
/* Create a new object by copying the template */
ByteToHex(object, key+3);
refO = db_copyRecord(obj00Ref, DB_root, key, DB_noPersistentSave, &error);
if (error)
return NULL;
/* Create a channel list for the new object */
channelList = (ChannelListPtr) OSConnectorAlloc(sizeof(ChannelList));
#ifndef HAS_SETJMP
if (channelList == NULL)
return NULL;
#endif
/* Init object list struct */
objectRecord = &objectList[objectListSize++];
objectRecord->objectRef = refO;
objectRecord->objectNbr = object;
objectRecord->channelList = channelList;
objectRecord->defaultChannel = objectList[0].defaultChannel;
/* Search for channels inherited from the template */
*(key + 0) = 'd';
*(key + 1) = 'c';
*(key + 2) = 'h';
sourceList = objectList[0].channelList; /* List of numbers of template channels */
for (i=0; i < objectList[0].channelListSize; i++) {
ByteToHex(sourceList->channelNbr, key+3);
ref = db_getRef(refO, key, &error);
if (db_findRecord(ref) == NULL)
goto Could_not_find_channel;
field = db_findField((BYTE*) "hosts");
if (field != NULL) {
channelList->channelNbr = sourceList->channelNbr;
channelList->channelRef = ref;
channelList->hostPtr = (RecordPtr) field;
channelList++;
nbrOfChannels++;
} else
Could_not_find_channel:
if (sourceList->channelNbr == objectList[0].defaultChannel)
objectRecord->defaultChannel = -1;
sourceList++;
}
objectRecord->channelListSize = nbrOfChannels;
return objectRecord;
}
/*
* Interface to addObjectInternal for external calls.
*
* Create an record containing all mandatory fields. The record
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -