9a0042c61e
git-svn-id: svn://opensvn.adaptivecomputing.com/maui/trunk@2 3f5042e3-fb1d-0410-be18-d6ca2573e517
1966 lines
32 KiB
C
1966 lines
32 KiB
C
/* HEADER */
|
|
|
|
/* *
|
|
* Contains: *
|
|
* *
|
|
* */
|
|
|
|
|
|
#include "mcom.h"
|
|
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <ctype.h>
|
|
|
|
/* prototypes */
|
|
|
|
int MXMLGetChild(mxml_t *,char *,int *,mxml_t **);
|
|
int MXMLAddE(mxml_t *,mxml_t *);
|
|
int MXMLGetAttrF(mxml_t *,char *,int *,void *,enum MDataFormatEnum,int);
|
|
int MXMLGetAttr(mxml_t *,char *,int *,char *,int);
|
|
int MXMLToString(mxml_t *,char *,int,char **,mbool_t);
|
|
int MXMLAppendAttr(mxml_t *,char *,char *,char);
|
|
|
|
/* END prototypes */
|
|
|
|
|
|
extern int MSecCompress(unsigned char *,unsigned int,unsigned char *,char *);
|
|
extern int MSecDecompress(unsigned char *,unsigned int,unsigned char *,unsigned int,unsigned char **,char *);
|
|
|
|
|
|
int MXMLExtractE(
|
|
|
|
mxml_t *E, /* I */
|
|
mxml_t *C, /* I */
|
|
mxml_t **CP) /* O (optional) */
|
|
|
|
{
|
|
int cindex;
|
|
|
|
if ((E == NULL) || (C == NULL))
|
|
{
|
|
return(FAILURE);
|
|
}
|
|
|
|
for (cindex = 0;cindex < E->CCount;cindex++)
|
|
{
|
|
if (C != E->C[cindex])
|
|
{
|
|
if (MXMLExtractE(E->C[cindex],C,CP) == SUCCESS)
|
|
{
|
|
return(SUCCESS);
|
|
}
|
|
|
|
continue;
|
|
}
|
|
|
|
if (CP != NULL)
|
|
*CP = E->C[cindex];
|
|
|
|
E->C[cindex] = NULL;
|
|
|
|
return(SUCCESS);
|
|
} /* END for (cindex) */
|
|
|
|
return(FAILURE);
|
|
} /* MXMLExtractE() */
|
|
|
|
|
|
|
|
|
|
int MXMLMergeE(
|
|
|
|
mxml_t *Dst, /* I */
|
|
mxml_t *Src, /* I */
|
|
char Delim) /* I */
|
|
|
|
{
|
|
int cindex;
|
|
int aindex;
|
|
|
|
/* parent and child must have identical element structure */
|
|
|
|
if ((Dst == NULL) || (Src == NULL))
|
|
{
|
|
return(FAILURE);
|
|
}
|
|
|
|
for (cindex = 0;cindex < Dst->CCount;cindex++)
|
|
{
|
|
/* recursively call all children */
|
|
|
|
if (MXMLMergeE(Dst->C[cindex],Src->C[cindex],Delim) == FAILURE)
|
|
{
|
|
return(FAILURE);
|
|
}
|
|
|
|
/* merge all attributes */
|
|
|
|
for (aindex = 0;aindex < Src->ACount;aindex++)
|
|
{
|
|
MXMLAppendAttr(
|
|
Dst,
|
|
Src->AName[aindex],
|
|
(char *)Src->AVal[aindex],
|
|
Delim);
|
|
}
|
|
} /* END for (cindex) */
|
|
|
|
return(SUCCESS);
|
|
} /* MXMLMergeE() */
|
|
|
|
|
|
|
|
|
|
|
|
int MXMLSetChild(
|
|
|
|
mxml_t *E, /* I */
|
|
char *CName, /* I */
|
|
mxml_t **CE) /* O */
|
|
|
|
{
|
|
if (CE != NULL)
|
|
*CE = NULL;
|
|
|
|
if ((E == NULL) || (CName == NULL))
|
|
{
|
|
return(FAILURE);
|
|
}
|
|
|
|
if (MXMLGetChild(E,CName,NULL,CE) == SUCCESS)
|
|
{
|
|
/* located existing child */
|
|
|
|
return(SUCCESS);
|
|
}
|
|
|
|
/* create new child */
|
|
|
|
if ((*CE = (mxml_t *)calloc(1,sizeof(mxml_t))) == NULL)
|
|
{
|
|
return(FAILURE);
|
|
}
|
|
|
|
MXMLAddE(E,*CE);
|
|
|
|
if (CName != NULL)
|
|
(*CE)->Name = strdup(CName);
|
|
|
|
return(SUCCESS);
|
|
} /* END MXMLSetChild() */
|
|
|
|
|
|
|
|
|
|
|
|
int MXMLCreateE(
|
|
|
|
mxml_t **E, /* O */
|
|
char *Name) /* I (optional) */
|
|
|
|
{
|
|
/* NOTE: should 'Name' be mandatory? */
|
|
|
|
if (E == NULL)
|
|
{
|
|
return(FAILURE);
|
|
}
|
|
|
|
if ((*E = (mxml_t *)calloc(1,sizeof(mxml_t))) == NULL)
|
|
{
|
|
return(FAILURE);
|
|
}
|
|
|
|
if ((Name != NULL) && (Name[0] != '\0'))
|
|
(*E)->Name = strdup(Name);
|
|
|
|
return(SUCCESS);
|
|
} /* END MXMLCreateE() */
|
|
|
|
|
|
|
|
|
|
int MXMLDestroyE(
|
|
|
|
mxml_t **EP) /* I (modified) */
|
|
|
|
{
|
|
int index;
|
|
|
|
mxml_t *E;
|
|
|
|
if (EP == NULL)
|
|
{
|
|
return(FAILURE);
|
|
}
|
|
|
|
E = *EP;
|
|
|
|
if (E == NULL)
|
|
{
|
|
return(SUCCESS);
|
|
}
|
|
|
|
if (E->C != NULL)
|
|
{
|
|
/* destroy children */
|
|
|
|
for (index = 0;index < E->CCount;index++)
|
|
{
|
|
if (E->C[index] == NULL)
|
|
continue;
|
|
|
|
MXMLDestroyE(&E->C[index]);
|
|
} /* END for (index) */
|
|
|
|
free(E->C);
|
|
} /* END if (E->C != NULL) */
|
|
|
|
/* free attributes */
|
|
|
|
if (E->AName != NULL)
|
|
{
|
|
for (index = 0;index < E->ACount;index++)
|
|
{
|
|
if (E->AName[index] == NULL)
|
|
break;
|
|
|
|
free(E->AName[index]);
|
|
|
|
if ((E->AVal != NULL) && (E->AVal[index] != NULL))
|
|
free(E->AVal[index]);
|
|
} /* END for (index) */
|
|
|
|
if (E->AVal != NULL)
|
|
{
|
|
free(E->AVal);
|
|
}
|
|
|
|
if (E->AName != NULL)
|
|
{
|
|
free(E->AName);
|
|
}
|
|
} /* END if (E->AName != NULL) */
|
|
|
|
/* free name */
|
|
|
|
if (E->Name != NULL)
|
|
free(E->Name);
|
|
|
|
if (E->Val != NULL)
|
|
free(E->Val);
|
|
|
|
free(E);
|
|
|
|
*EP = NULL;
|
|
|
|
return(SUCCESS);
|
|
} /* END MXMLDestroyE() */
|
|
|
|
|
|
|
|
|
|
|
|
int MXMLSetAttr(
|
|
|
|
mxml_t *E, /* I (modified) */
|
|
char *A, /* I */
|
|
void *V, /* I */
|
|
enum MDataFormatEnum Format) /* I */
|
|
|
|
{
|
|
int aindex;
|
|
int iindex;
|
|
|
|
int rc;
|
|
|
|
char tmpLine[MMAX_LINE];
|
|
|
|
char *ptr;
|
|
|
|
/* NOTE: overwrite existing attr if found */
|
|
|
|
if ((E == NULL) || (A == NULL))
|
|
{
|
|
return(FAILURE);
|
|
}
|
|
|
|
if (V != NULL)
|
|
{
|
|
switch (Format)
|
|
{
|
|
case mdfString:
|
|
default:
|
|
|
|
ptr = (char *)V;
|
|
|
|
break;
|
|
|
|
case mdfInt:
|
|
|
|
sprintf(tmpLine,"%d",
|
|
*(int *)V);
|
|
|
|
ptr = tmpLine;
|
|
|
|
break;
|
|
|
|
case mdfLong:
|
|
|
|
sprintf(tmpLine,"%ld",
|
|
*(long *)V);
|
|
|
|
ptr = tmpLine;
|
|
|
|
break;
|
|
|
|
case mdfDouble:
|
|
|
|
sprintf(tmpLine,"%f",
|
|
*(double *)V);
|
|
|
|
ptr = tmpLine;
|
|
|
|
break;
|
|
} /* END switch(Format) */
|
|
}
|
|
else
|
|
{
|
|
tmpLine[0] = '\0';
|
|
|
|
ptr = tmpLine;
|
|
}
|
|
|
|
/* initialize attribute table */
|
|
|
|
if (E->AName == NULL)
|
|
{
|
|
E->AName = (char **)calloc(1,sizeof(char *) * MMAX_XMLATTR);
|
|
E->AVal = (char **)calloc(1,sizeof(char *) * MMAX_XMLATTR);
|
|
|
|
if ((E->AName == NULL) || (E->AVal == NULL))
|
|
{
|
|
return(FAILURE);
|
|
}
|
|
|
|
E->ASize = MMAX_XMLATTR;
|
|
E->ACount = 0;
|
|
}
|
|
|
|
/* insert in alphabetical order */
|
|
|
|
/* overwrite existing attribute if found */
|
|
|
|
iindex = 0;
|
|
rc = 0;
|
|
|
|
for (aindex = 0;aindex < E->ACount;aindex++)
|
|
{
|
|
rc = strcmp(E->AName[aindex],A);
|
|
|
|
if (rc > 0)
|
|
break;
|
|
|
|
if (rc == 0)
|
|
{
|
|
iindex = aindex;
|
|
|
|
break;
|
|
}
|
|
|
|
iindex = aindex + 1;
|
|
} /* END for (aindex) */
|
|
|
|
if (aindex >= E->ACount)
|
|
{
|
|
iindex = aindex;
|
|
|
|
if (aindex >= E->ASize)
|
|
{
|
|
/* allocate memory */
|
|
|
|
E->AName = (char **)realloc(E->AName,sizeof(char *) * MAX(16,E->ASize << 1));
|
|
E->AVal = (char **)realloc(E->AVal,sizeof(char *) * MAX(16,E->ASize << 1));
|
|
|
|
if ((E->AVal == NULL) || (E->AName == NULL))
|
|
{
|
|
E->ASize = 0;
|
|
|
|
return(FAILURE);
|
|
}
|
|
|
|
E->ASize <<= 1;
|
|
}
|
|
} /* END if (aindex >= E->ACount) */
|
|
|
|
if ((ptr == NULL) && (aindex >= E->ACount))
|
|
{
|
|
/* no action required for empty attribute */
|
|
|
|
return(SUCCESS);
|
|
}
|
|
|
|
/* prepare insertion point */
|
|
|
|
if (rc != 0)
|
|
{
|
|
for (aindex = E->ACount - 1;aindex >= iindex;aindex--)
|
|
{
|
|
E->AVal[aindex + 1] = E->AVal[aindex];
|
|
E->AName[aindex + 1] = E->AName[aindex];
|
|
} /* END for (aindex) */
|
|
|
|
E->AVal[aindex + 1] = NULL;
|
|
E->AName[aindex + 1] = NULL;
|
|
} /* END if (rc != 0) */
|
|
|
|
if ((iindex < E->ACount) && (E->AVal[iindex] != NULL))
|
|
free(E->AVal[iindex]);
|
|
|
|
E->AVal[iindex] = strdup((ptr != NULL) ? ptr : "");
|
|
|
|
if ((rc != 0) || (E->AName[iindex] == NULL))
|
|
{
|
|
E->AName[iindex] = strdup(A);
|
|
|
|
E->ACount++;
|
|
}
|
|
|
|
return(SUCCESS);
|
|
} /* END MXMLSetAttr() */
|
|
|
|
|
|
|
|
|
|
int MXMLAppendAttr(
|
|
|
|
mxml_t *E, /* I root element */
|
|
char *AName, /* I */
|
|
char *AVal, /* I */
|
|
char Delim) /* I */
|
|
|
|
{
|
|
int ATok;
|
|
int len;
|
|
|
|
char VBuf[MMAX_LINE];
|
|
|
|
if ((E == NULL) || (AName == NULL) || (AVal == NULL))
|
|
{
|
|
return(FAILURE);
|
|
}
|
|
|
|
ATok = -1;
|
|
|
|
if (MXMLGetAttr(E,AName,&ATok,VBuf,sizeof(VBuf)) == SUCCESS)
|
|
{
|
|
char DString[2];
|
|
|
|
len = strlen(E->AVal[ATok]) + strlen(AVal) + 2;
|
|
|
|
E->AVal[ATok] = (char *)realloc(
|
|
E->AVal[ATok],
|
|
len);
|
|
|
|
if (E->AVal[ATok] == NULL)
|
|
{
|
|
return(FAILURE);
|
|
}
|
|
|
|
DString[0] = Delim;
|
|
DString[1] = '\0';
|
|
|
|
/* just allocated adequate space, should not be able to overflow */
|
|
|
|
strcat(E->AVal[ATok],DString);
|
|
|
|
strcat(E->AVal[ATok],AVal);
|
|
}
|
|
else if (MXMLSetAttr(E,AName,AVal,mdfString) == FAILURE)
|
|
{
|
|
return(FAILURE);
|
|
}
|
|
|
|
return(SUCCESS);
|
|
} /* END MXMLAppendAttr() */
|
|
|
|
|
|
|
|
|
|
|
|
int MXMLSetVal(
|
|
|
|
mxml_t *E, /* I (modified) */
|
|
void *V, /* I */
|
|
enum MDataFormatEnum Format) /* I */
|
|
|
|
{
|
|
char tmpLine[MMAX_LINE];
|
|
char *ptr;
|
|
|
|
if ((E == NULL) || (V == NULL))
|
|
{
|
|
return(FAILURE);
|
|
}
|
|
|
|
if (E->Val != NULL)
|
|
{
|
|
free(E->Val);
|
|
|
|
E->Val = NULL;
|
|
}
|
|
|
|
switch(Format)
|
|
{
|
|
case mdfString:
|
|
default:
|
|
|
|
ptr = (char *)V;
|
|
|
|
break;
|
|
|
|
case mdfInt:
|
|
|
|
sprintf(tmpLine,"%d",
|
|
*(int *)V);
|
|
|
|
ptr = tmpLine;
|
|
|
|
break;
|
|
|
|
case mdfLong:
|
|
|
|
sprintf(tmpLine,"%ld",
|
|
*(long *)V);
|
|
|
|
ptr = tmpLine;
|
|
|
|
break;
|
|
|
|
case mdfDouble:
|
|
|
|
sprintf(tmpLine,"%f",
|
|
*(double *)V);
|
|
|
|
ptr = tmpLine;
|
|
|
|
break;
|
|
} /* END switch(Format) */
|
|
|
|
E->Val = strdup(ptr);
|
|
|
|
/* strip '<' symbols NOTE: ignore '<' symbol in attrs */
|
|
|
|
/* NOTE: must replace temp hack 14 w/ < */
|
|
|
|
for (ptr = strchr(E->Val,'<');ptr != NULL;ptr = strchr(ptr,'<'))
|
|
*ptr = (char)14;
|
|
|
|
return(SUCCESS);
|
|
} /* END MXMLSetVal() */
|
|
|
|
|
|
|
|
|
|
int MXMLAddE(
|
|
|
|
mxml_t *E, /* I (modified) */
|
|
mxml_t *C) /* I (required) */
|
|
|
|
{
|
|
if ((E == NULL) || (C == NULL))
|
|
{
|
|
return(FAILURE);
|
|
}
|
|
|
|
if (E->CCount >= E->CSize)
|
|
{
|
|
if (E->C == NULL)
|
|
{
|
|
E->C = (mxml_t **)calloc(1,sizeof(mxml_t *) * MDEF_XMLICCOUNT);
|
|
|
|
E->CSize = MDEF_XMLICCOUNT;
|
|
}
|
|
else
|
|
{
|
|
E->C = (mxml_t **)realloc(E->C,sizeof(mxml_t *) * MAX(16,E->CSize << 1));
|
|
|
|
E->CSize <<= 1;
|
|
}
|
|
|
|
if (E->C == NULL)
|
|
{
|
|
/* cannot alloc memory */
|
|
|
|
return(FAILURE);
|
|
} /* END if (E->C == NULL) */
|
|
} /* END if (E->CCount >= E->CSize) */
|
|
|
|
E->C[E->CCount] = C;
|
|
|
|
E->CCount++;
|
|
|
|
return(SUCCESS);
|
|
} /* END MXMLAddE() */
|
|
|
|
|
|
|
|
|
|
int MXMLToXString(
|
|
|
|
mxml_t *E, /* I */
|
|
char **Buf, /* O (populated/modified) */
|
|
int *BufSize, /* I/O */
|
|
int MaxBufSize, /* I */
|
|
char **Tail, /* O */
|
|
mbool_t NoCompress) /* I */
|
|
|
|
{
|
|
int NewSize;
|
|
|
|
/* NOTE: MXMLToString() only fails due to lack of space */
|
|
|
|
if ((E == NULL) || (Buf == NULL))
|
|
{
|
|
return(FAILURE);
|
|
}
|
|
|
|
/* allocate initial memory if required */
|
|
|
|
if (*Buf == NULL)
|
|
{
|
|
NewSize = MMAX_BUFFER;
|
|
|
|
if ((*Buf = (char *)malloc(NewSize)) == NULL)
|
|
{
|
|
/* cannot allocate buffer */
|
|
|
|
return(FAILURE);
|
|
}
|
|
|
|
if (BufSize != NULL)
|
|
*BufSize = MMAX_BUFFER;
|
|
}
|
|
else
|
|
{
|
|
if (BufSize != NULL)
|
|
{
|
|
NewSize = *BufSize;
|
|
}
|
|
else
|
|
{
|
|
return(FAILURE);
|
|
}
|
|
}
|
|
|
|
while (MXMLToString(
|
|
E,
|
|
*Buf,
|
|
NewSize,
|
|
Tail,
|
|
NoCompress) == FAILURE)
|
|
{
|
|
if (NewSize >= MaxBufSize)
|
|
{
|
|
return(FAILURE);
|
|
}
|
|
|
|
NewSize = MIN(NewSize << 1,MaxBufSize);
|
|
|
|
if ((*Buf = (char *)realloc(*Buf,NewSize)) == NULL)
|
|
{
|
|
/* cannot allocate buffer */
|
|
|
|
return(FAILURE);
|
|
}
|
|
|
|
if (BufSize != NULL)
|
|
*BufSize = NewSize;
|
|
} /* END while (MXMLToString() == FAILURE) */
|
|
|
|
return(SUCCESS);
|
|
} /* END MXMLToXString() */
|
|
|
|
|
|
|
|
|
|
int MXMLToString(
|
|
|
|
mxml_t *E, /* I */
|
|
char *Buf, /* O */
|
|
int BufSize, /* I */
|
|
char **Tail, /* O */
|
|
mbool_t NoCompress) /* I (compress Data element) */
|
|
|
|
{
|
|
char NewLine[MMAX_BUFFER];
|
|
|
|
int index;
|
|
|
|
int BSpace;
|
|
|
|
char *BPtr;
|
|
|
|
char *tail;
|
|
|
|
int len;
|
|
|
|
if (Buf != NULL)
|
|
{
|
|
Buf[0] = '\0';
|
|
}
|
|
|
|
if ((E == NULL) || (Buf == NULL))
|
|
{
|
|
return(FAILURE);
|
|
}
|
|
|
|
if (BufSize < MMAX_NAME)
|
|
{
|
|
return(FAILURE);
|
|
}
|
|
|
|
BPtr = Buf;
|
|
BSpace = BufSize;
|
|
|
|
/* display header */
|
|
|
|
BPtr[0] = '<';
|
|
|
|
BPtr++;
|
|
BSpace--;
|
|
|
|
if (E->Name != NULL)
|
|
{
|
|
len = strlen(E->Name);
|
|
|
|
if (len >= BSpace)
|
|
{
|
|
/* insufficient space */
|
|
|
|
BPtr[0] = '\0';
|
|
|
|
return(FAILURE);
|
|
}
|
|
|
|
strcpy(BPtr,E->Name);
|
|
|
|
BSpace -= len;
|
|
BPtr += len;
|
|
}
|
|
else
|
|
{
|
|
strcpy(BPtr,"NA");
|
|
|
|
len = strlen("NA");
|
|
|
|
BPtr += len;
|
|
BSpace -= len;
|
|
}
|
|
|
|
/* display attributes */
|
|
|
|
for (index = 0;index < E->ACount;index++)
|
|
{
|
|
/* FORMAT: <NAME>="<VAL>" */
|
|
|
|
BPtr[0] = ' ';
|
|
|
|
BPtr++;
|
|
BSpace--;
|
|
|
|
len = strlen(E->AName[index]);
|
|
|
|
if (len >= BSpace)
|
|
{
|
|
/* insufficient space */
|
|
|
|
BPtr[0] = '\0';
|
|
|
|
return(FAILURE);
|
|
}
|
|
|
|
strcpy(BPtr,E->AName[index]);
|
|
|
|
BSpace -= len;
|
|
BPtr += len;
|
|
|
|
BPtr[0] = '=';
|
|
|
|
BPtr++;
|
|
BSpace--;
|
|
|
|
BPtr[0] = '"';
|
|
|
|
BPtr++;
|
|
BSpace--;
|
|
|
|
if ((strchr(E->AVal[index],'<') != NULL) ||
|
|
(strchr(E->AVal[index],'>') != NULL))
|
|
{
|
|
/* must replace '<' with '<' and '>' with '>' */
|
|
|
|
int index1;
|
|
int index2 = 0;
|
|
|
|
len = strlen(E->AVal[index]);
|
|
|
|
for (index1 = 0;index1 < len;index1++)
|
|
{
|
|
if (E->AVal[index][index1] == '<')
|
|
{
|
|
NewLine[index2++] = '&';
|
|
NewLine[index2++] = 'l';
|
|
NewLine[index2++] = 't';
|
|
NewLine[index2++] = ';';
|
|
}
|
|
else if (E->AVal[index][index1] == '>')
|
|
{
|
|
NewLine[index2++] = '&';
|
|
NewLine[index2++] = 'g';
|
|
NewLine[index2++] = 't';
|
|
NewLine[index2++] = ';';
|
|
}
|
|
else
|
|
{
|
|
NewLine[index2++] = E->AVal[index][index1];
|
|
}
|
|
} /* END for (index1) */
|
|
|
|
NewLine[index2] = '\0';
|
|
|
|
len = strlen(NewLine);
|
|
|
|
if (len >= BSpace)
|
|
{
|
|
/* insufficient space */
|
|
|
|
BPtr[0] = '\0';
|
|
|
|
return(FAILURE);
|
|
}
|
|
|
|
strcpy(BPtr,NewLine);
|
|
} /* END if (strchr(E->AVal,'<')...) */
|
|
else
|
|
{
|
|
len = strlen(E->AVal[index]);
|
|
|
|
if (len >= BSpace)
|
|
{
|
|
/* insufficient space */
|
|
|
|
BPtr[0] = '\0';
|
|
|
|
return(FAILURE);
|
|
}
|
|
|
|
strcpy(BPtr,E->AVal[index]);
|
|
} /* END else */
|
|
|
|
BSpace -= len;
|
|
BPtr += len;
|
|
|
|
BPtr[0] = '"';
|
|
|
|
BPtr++;
|
|
BSpace--;
|
|
} /* END for (index) */
|
|
|
|
BPtr[0] = '>';
|
|
|
|
BPtr++;
|
|
BSpace--;
|
|
|
|
if (E->Val != NULL)
|
|
{
|
|
len = strlen(E->Val);
|
|
|
|
if (len >= BSpace)
|
|
{
|
|
/* insufficient space */
|
|
|
|
BPtr[0] = '\0';
|
|
|
|
return(FAILURE);
|
|
}
|
|
|
|
strcpy(BPtr,E->Val);
|
|
|
|
BSpace -= len;
|
|
BPtr += len;
|
|
}
|
|
|
|
/* display children */
|
|
|
|
for (index = 0;index < E->CCount;index++)
|
|
{
|
|
if (E->C[index] == NULL)
|
|
continue;
|
|
|
|
if (MXMLToString(E->C[index],BPtr,BSpace,&tail,NoCompress) == FAILURE)
|
|
{
|
|
return(FAILURE);
|
|
}
|
|
|
|
len = strlen(BPtr);
|
|
|
|
BSpace -= len;
|
|
BPtr += len;
|
|
} /* END for (index) */
|
|
|
|
/* display footer */
|
|
|
|
if (E->Name != NULL)
|
|
{
|
|
len = strlen(E->Name);
|
|
}
|
|
else
|
|
{
|
|
len = strlen("NA");
|
|
}
|
|
|
|
if (BSpace < len + 4)
|
|
{
|
|
BPtr[0] = '\0';
|
|
|
|
return(FAILURE);
|
|
}
|
|
|
|
BPtr[0] = '<';
|
|
|
|
BPtr++;
|
|
BSpace--;
|
|
|
|
BPtr[0] = '/';
|
|
|
|
BPtr++;
|
|
BSpace--;
|
|
|
|
if (E->Name != NULL)
|
|
{
|
|
strcpy(BPtr,E->Name);
|
|
}
|
|
else
|
|
{
|
|
strcpy(BPtr,"NA");
|
|
}
|
|
|
|
BSpace -= len;
|
|
BPtr += len;
|
|
|
|
BPtr[0] = '>';
|
|
|
|
BPtr++;
|
|
BSpace--;
|
|
|
|
/* terminate string */
|
|
|
|
BPtr[0] = '\0';
|
|
|
|
if (Tail != NULL)
|
|
*Tail = BPtr;
|
|
|
|
if ((NoCompress == FALSE) && (strlen(Buf) > (MMAX_BUFFER >> 1)))
|
|
{
|
|
if ((E->Name != NULL) && !strcmp(E->Name,"Data"))
|
|
{
|
|
/* attempt to compress in place */
|
|
|
|
if (MSecCompress((unsigned char *)Buf,strlen(Buf),NULL,MCONST_CKEY) == FAILURE)
|
|
{
|
|
return(FAILURE);
|
|
}
|
|
}
|
|
}
|
|
|
|
return(SUCCESS);
|
|
} /* END MXMLToString() */
|
|
|
|
|
|
|
|
|
|
int MXMLGetAttrF(
|
|
|
|
mxml_t *E, /* I */
|
|
char *AName, /* I/O */
|
|
int *ATok, /* I (optional) */
|
|
void *AVal, /* O (optional) */
|
|
enum MDataFormatEnum DFormat, /* I */
|
|
int VSize) /* I */
|
|
|
|
{
|
|
char tmpLine[MMAX_LINE];
|
|
int rc;
|
|
|
|
if (AVal == NULL)
|
|
{
|
|
return(FAILURE);
|
|
}
|
|
|
|
switch (DFormat)
|
|
{
|
|
case mdfString:
|
|
|
|
rc = MXMLGetAttr(
|
|
E,
|
|
AName,
|
|
ATok,
|
|
(char *)AVal,
|
|
VSize);
|
|
|
|
return(rc);
|
|
|
|
/* NOTREACHED*/
|
|
|
|
break;
|
|
|
|
case mdfInt:
|
|
case mdfLong:
|
|
case mdfDouble:
|
|
|
|
if (MXMLGetAttr(
|
|
E,
|
|
AName,
|
|
ATok,
|
|
tmpLine,
|
|
sizeof(tmpLine)) == FAILURE)
|
|
{
|
|
/* clear response */
|
|
|
|
switch(DFormat)
|
|
{
|
|
case mdfInt: *(int *)AVal = 0; break;
|
|
case mdfLong: *(long *)AVal = 0; break;
|
|
case mdfDouble: *(double *)AVal = 0.0; break;
|
|
default: break;
|
|
} /* END switch(DFormat) */
|
|
|
|
return(FAILURE);
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
return(FAILURE);
|
|
|
|
/*NOTREACHED*/
|
|
|
|
break;
|
|
} /* END switch(DFormat) */
|
|
|
|
switch (DFormat)
|
|
{
|
|
case mdfInt:
|
|
|
|
*(int *)AVal = (int)strtol(tmpLine,NULL,10);
|
|
|
|
break;
|
|
|
|
case mdfLong:
|
|
|
|
*(long *)AVal = strtol(tmpLine,NULL,10);
|
|
|
|
break;
|
|
|
|
case mdfDouble:
|
|
|
|
*(double *)AVal = strtod(tmpLine,NULL);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
*(char **)AVal = NULL;
|
|
|
|
return(FAILURE);
|
|
|
|
/*NOTREACHED*/
|
|
|
|
break;
|
|
} /* END switch (DFormat) */
|
|
|
|
return(SUCCESS);
|
|
} /* END MXMLGetAttrF() */
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int MXMLGetAttr(
|
|
|
|
mxml_t *E, /* I */
|
|
char *AName, /* I/O */
|
|
int *ATok, /* I (optional) */
|
|
char *AVal, /* O (optional) */
|
|
int VSize) /* I */
|
|
|
|
{
|
|
/* NOTE: set AName to empty string to get Name */
|
|
|
|
int aindex;
|
|
int astart;
|
|
|
|
int EVSize;
|
|
|
|
if (AVal != NULL)
|
|
AVal[0] = '\0';
|
|
|
|
if (E == NULL)
|
|
{
|
|
return(FAILURE);
|
|
}
|
|
|
|
EVSize = (VSize > 0) ? VSize : MMAX_LINE;
|
|
|
|
if (ATok != NULL)
|
|
astart = *ATok;
|
|
else
|
|
astart = -1;
|
|
|
|
for (aindex = astart + 1;aindex < E->ACount;aindex++)
|
|
{
|
|
if ((AName == NULL) ||
|
|
(AName[0] == '\0') ||
|
|
!strcmp(AName,E->AName[aindex]))
|
|
{
|
|
if ((AName != NULL) && (AName[0] == '\0'))
|
|
{
|
|
strncpy(AName,E->AName[aindex],MMAX_NAME);
|
|
AName[MMAX_NAME - 1] = '\0';
|
|
}
|
|
|
|
if (AVal != NULL)
|
|
{
|
|
strncpy(AVal,E->AVal[aindex],EVSize);
|
|
AVal[EVSize - 1] = '\0';
|
|
}
|
|
|
|
if (ATok != NULL)
|
|
*ATok = aindex;
|
|
|
|
return(SUCCESS);
|
|
}
|
|
} /* END for (aindex) */
|
|
|
|
return(FAILURE);
|
|
} /* END MXMLGetAttr() */
|
|
|
|
|
|
|
|
|
|
int MXMLGetChild(
|
|
|
|
mxml_t *E, /* I */
|
|
char *CName, /* I (optional) */
|
|
int *CTok, /* I (optional) */
|
|
mxml_t **C) /* O */
|
|
|
|
{
|
|
int cindex;
|
|
int cstart;
|
|
|
|
if (C != NULL)
|
|
*C = NULL;
|
|
|
|
if ((E == NULL) || (C == NULL))
|
|
{
|
|
return(FAILURE);
|
|
}
|
|
|
|
if (CTok != NULL)
|
|
cstart = *CTok;
|
|
else
|
|
cstart = -1;
|
|
|
|
for (cindex = cstart + 1;cindex < E->CCount;cindex++)
|
|
{
|
|
if (E->C[cindex] == NULL)
|
|
continue;
|
|
|
|
if ((CName == NULL) || !strcmp(CName,E->C[cindex]->Name))
|
|
{
|
|
*C = E->C[cindex];
|
|
|
|
if (CTok != NULL)
|
|
*CTok = cindex;
|
|
|
|
return(SUCCESS);
|
|
}
|
|
} /* END for (cindex) */
|
|
|
|
return(FAILURE);
|
|
} /* END MXMLGetChild() */
|
|
|
|
|
|
|
|
|
|
int MXMLGetChildCI(
|
|
|
|
mxml_t *E, /* I */
|
|
char *CName, /* I (optional) */
|
|
int *CTok, /* I (optional) */
|
|
mxml_t **CP) /* O (optional) */
|
|
|
|
{
|
|
int cindex;
|
|
int cstart;
|
|
|
|
int SLen;
|
|
|
|
if (CP != NULL)
|
|
*CP = NULL;
|
|
|
|
#ifndef __MOPT
|
|
if (E == NULL)
|
|
{
|
|
return(FAILURE);
|
|
}
|
|
#endif /* __MOPT */
|
|
|
|
if (CTok != NULL)
|
|
cstart = *CTok;
|
|
else
|
|
cstart = -1;
|
|
|
|
if (CName != NULL)
|
|
SLen = strlen(CName) + 1;
|
|
else
|
|
SLen = 0;
|
|
|
|
for (cindex = cstart + 1;cindex < E->CCount;cindex++)
|
|
{
|
|
if (E->C[cindex] == NULL)
|
|
continue;
|
|
|
|
if ((CName == NULL) || !strncasecmp(CName,E->C[cindex]->Name,SLen))
|
|
{
|
|
if (CP != NULL)
|
|
*CP = E->C[cindex];
|
|
|
|
if (CTok != NULL)
|
|
*CTok = cindex;
|
|
|
|
return(SUCCESS);
|
|
}
|
|
} /* END for (cindex) */
|
|
|
|
return(FAILURE);
|
|
} /* END MXMLGetChildCI() */
|
|
|
|
|
|
|
|
|
|
|
|
#define MMAX_XBUFFER 131072
|
|
|
|
int MXMLFromString(
|
|
|
|
mxml_t **EP, /* O (populate or create - will be freed on failure) */
|
|
char *XMLString, /* I */
|
|
char **Tail, /* O (optional) */
|
|
char *EMsg) /* O (optional) */
|
|
|
|
{
|
|
mxml_t *E;
|
|
char *ptr;
|
|
|
|
char *tail;
|
|
|
|
int index;
|
|
|
|
mbool_t ElementIsClosed = FALSE;
|
|
|
|
mbool_t DoAppend = FALSE;
|
|
|
|
char tmpNLine[MMAX_LINE + 1];
|
|
char tmpVLine[MMAX_XBUFFER + 1];
|
|
|
|
if (EP != NULL)
|
|
*EP = NULL;
|
|
|
|
if (EMsg != NULL)
|
|
EMsg[0] = '\0';
|
|
|
|
if ((XMLString == NULL) || (EP == NULL))
|
|
{
|
|
if (EMsg != NULL)
|
|
strcpy(EMsg,"invalid arguments");
|
|
|
|
return(FAILURE);
|
|
}
|
|
|
|
if ((ptr = strchr(XMLString,'<')) == NULL)
|
|
{
|
|
if (EMsg != NULL)
|
|
strcpy(EMsg,"no XML in string");
|
|
|
|
return(FAILURE);
|
|
}
|
|
|
|
if (ptr[1] == '/')
|
|
{
|
|
/* located tail marker */
|
|
|
|
if (EMsg != NULL)
|
|
strcpy(EMsg,"premature termination marker");
|
|
|
|
return(FAILURE);
|
|
}
|
|
|
|
/* NOTE: should support append/overlay parameter (NYI) */
|
|
|
|
/* ignore 'meta' elements */
|
|
|
|
while ((ptr[1] == '?') || (ptr[1] == '!'))
|
|
{
|
|
ptr++;
|
|
|
|
/* ignore 'meta' elements */
|
|
|
|
if (*ptr == '?')
|
|
{
|
|
ptr++;
|
|
|
|
if ((ptr = strstr(ptr,"?>")) == NULL)
|
|
{
|
|
/* cannot locate end of meta element */
|
|
|
|
return(FAILURE);
|
|
}
|
|
|
|
if ((ptr = strchr(ptr,'<')) == NULL)
|
|
{
|
|
/* cannot locate next element */
|
|
|
|
if (EMsg != NULL)
|
|
strcpy(EMsg,"cannot locate post-meta XML");
|
|
|
|
return(FAILURE);
|
|
}
|
|
} /* END if (*ptr == '?') */
|
|
|
|
/* ignore 'comment' element */
|
|
|
|
if (!strncmp(ptr,"!--",3))
|
|
{
|
|
ptr += 3;
|
|
|
|
if ((ptr = strstr(ptr,"-->")) == NULL)
|
|
{
|
|
/* cannot locate end of comment element */
|
|
|
|
if (EMsg != NULL)
|
|
strcpy(EMsg,"cannot locate comment termination marker");
|
|
|
|
return(FAILURE);
|
|
}
|
|
|
|
if ((ptr = strchr(ptr,'<')) == NULL)
|
|
{
|
|
/* cannot locate next element */
|
|
|
|
if (EMsg != NULL)
|
|
strcpy(EMsg,"cannot locate post-comment XML");
|
|
|
|
return(FAILURE);
|
|
}
|
|
} /* END if (!strncmp(ptr,"!--",3)) */
|
|
else if (ptr[1] == '!')
|
|
{
|
|
char* ptr2;
|
|
|
|
ptr++;
|
|
ptr++;
|
|
|
|
while (*ptr != '\0')
|
|
{
|
|
if (strchr("<[>",*ptr) != NULL)
|
|
{
|
|
break;
|
|
}
|
|
|
|
ptr++;
|
|
}
|
|
|
|
if ((ptr2 = strchr("<[>",*ptr)) == NULL)
|
|
{
|
|
/* cannot locate end element */
|
|
|
|
if (EMsg != NULL)
|
|
strcpy(EMsg,"cannot locate post-comment XML");
|
|
|
|
return(FAILURE);
|
|
}
|
|
|
|
switch (*ptr2)
|
|
{
|
|
case '[':
|
|
|
|
ptr = strstr(ptr,"]>");
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
/* NYI */
|
|
|
|
return(FAILURE);
|
|
|
|
/* NOTREACHED */
|
|
|
|
break;
|
|
}
|
|
|
|
if ((ptr = strchr(ptr,'<')) == NULL)
|
|
{
|
|
/* cannot locate next element */
|
|
|
|
if (EMsg != NULL)
|
|
strcpy(EMsg,"cannot locate post-comment XML");
|
|
|
|
return(FAILURE);
|
|
}
|
|
} /* END if (*ptr == '!') */
|
|
} /* END while ((ptr[1] == '?') || (ptr[1] == '!')) */
|
|
|
|
/* remove whitespace */
|
|
|
|
while (isspace(*ptr))
|
|
ptr++;
|
|
|
|
/* extract root element */
|
|
|
|
if (*ptr != '<')
|
|
{
|
|
/* cannot located start of element */
|
|
|
|
if (EMsg != NULL)
|
|
strcpy(EMsg,"cannot locate start of root element");
|
|
|
|
return(FAILURE);
|
|
}
|
|
|
|
ptr++; /* ignore '<' */
|
|
|
|
index = 0;
|
|
|
|
while ((*ptr != ' ') && (*ptr != '>'))
|
|
{
|
|
if ((ptr[0] == '/') && (ptr[1] == '>'))
|
|
{
|
|
ElementIsClosed = TRUE;
|
|
|
|
break;
|
|
}
|
|
|
|
tmpNLine[index++] = *(ptr++);
|
|
|
|
if ((index >= MMAX_LINE) || (ptr[0] == '\0'))
|
|
{
|
|
if (EMsg != NULL)
|
|
sprintf(EMsg,"element name is too long - %.10s",
|
|
tmpNLine);
|
|
|
|
return(FAILURE);
|
|
}
|
|
}
|
|
|
|
tmpNLine[index] = '\0';
|
|
|
|
if ((*EP == NULL) && (MXMLCreateE(EP,tmpNLine) == FAILURE))
|
|
{
|
|
if (EMsg != NULL)
|
|
sprintf(EMsg,"cannot create XML element '%s'",
|
|
tmpNLine);
|
|
|
|
return(FAILURE);
|
|
}
|
|
|
|
E = *EP;
|
|
|
|
if ((E->ACount > 0) || (E->CCount > 0))
|
|
{
|
|
DoAppend = TRUE;
|
|
}
|
|
|
|
if (ElementIsClosed == TRUE)
|
|
{
|
|
ptr += 2; /* skip '/>' */
|
|
|
|
if (Tail != NULL)
|
|
*Tail = ptr;
|
|
|
|
return(SUCCESS);
|
|
}
|
|
|
|
while (*ptr == ' ')
|
|
ptr++;
|
|
|
|
while (*ptr != '>')
|
|
{
|
|
/* extract attributes */
|
|
|
|
/* FORMAT: <ATTR>="<VAL>" */
|
|
|
|
index = 0;
|
|
|
|
while ((*ptr != '=') && (*ptr != '\0'))
|
|
{
|
|
tmpNLine[index++] = *(ptr++);
|
|
|
|
if (index >= MMAX_LINE)
|
|
break;
|
|
}
|
|
|
|
tmpNLine[index] = '\0';
|
|
|
|
if (*ptr != '\0')
|
|
ptr++; /* skip '=' */
|
|
|
|
if (*ptr != '\0')
|
|
ptr++; /* skip '"' */
|
|
|
|
if (*ptr == '\0')
|
|
{
|
|
if (EMsg != NULL)
|
|
sprintf(EMsg,"string is corrupt - early termination");
|
|
|
|
MXMLDestroyE(EP);
|
|
|
|
return(FAILURE);
|
|
}
|
|
|
|
index = 0;
|
|
|
|
while ((*ptr != '"') ||
|
|
((ptr > XMLString) && (*(ptr - 1) == '\\')))
|
|
{
|
|
if (((*ptr == '&') && (*(ptr+1) == 'l') && (*(ptr+2) == 't') && (*(ptr+3) == ';')))
|
|
{
|
|
tmpVLine[index++] = '<';
|
|
|
|
ptr += 4;
|
|
}
|
|
else if (((*ptr == '&') && (*(ptr+1) == 'g') && (*(ptr+2) == 't') && (*(ptr+3) == ';')))
|
|
{
|
|
tmpVLine[index++] = '>';
|
|
|
|
ptr += 4;
|
|
}
|
|
else
|
|
{
|
|
tmpVLine[index++] = *(ptr++);
|
|
}
|
|
|
|
if ((index >= MMAX_XBUFFER) || (*ptr == '\0'))
|
|
{
|
|
MXMLDestroyE(EP);
|
|
|
|
/* locate tail */
|
|
|
|
if (Tail != NULL)
|
|
*Tail = ptr + strlen(ptr);
|
|
|
|
if (EMsg != NULL)
|
|
sprintf(EMsg,"attribute name is too long - %.10s",
|
|
tmpVLine);
|
|
|
|
return(FAILURE);
|
|
}
|
|
}
|
|
|
|
tmpVLine[index] = '\0';
|
|
|
|
MXMLSetAttr(E,tmpNLine,(void *)tmpVLine,mdfString);
|
|
|
|
ptr++; /* ignore '"' */
|
|
|
|
while (*ptr == ' ')
|
|
ptr++;
|
|
|
|
if ((ptr[0] == '/') && (ptr[1] == '>'))
|
|
{
|
|
/* element terminator reached */
|
|
|
|
ptr += 2; /* skip '/>' */
|
|
|
|
if (Tail != NULL)
|
|
*Tail = ptr;
|
|
|
|
return(SUCCESS);
|
|
}
|
|
} /* END while (*ptr != '>') */
|
|
|
|
ptr++; /* ignore '>' */
|
|
|
|
/* skip whitespace */
|
|
|
|
while (isspace(*ptr))
|
|
ptr++;
|
|
|
|
/* NOTE: value can occur before, after, or spread amongst children */
|
|
|
|
/* extract value */
|
|
|
|
if (*ptr != '<')
|
|
{
|
|
char *ptr2;
|
|
|
|
index = 0;
|
|
|
|
if (!strncmp(ptr,CRYPTHEAD,strlen(CRYPTHEAD)))
|
|
{
|
|
char *tail;
|
|
int len;
|
|
|
|
mxml_t *C;
|
|
|
|
char *tmpBuf;
|
|
|
|
/* compressed data detected, '<' symbol guaranteed to not be part of string */
|
|
|
|
tail = strchr(ptr,'<');
|
|
|
|
/* determine size of value */
|
|
|
|
len = tail - ptr;
|
|
|
|
/* uncompress data */
|
|
|
|
tmpBuf = NULL;
|
|
|
|
/* NOTE: CRYPTHEAD header indicates encryption/compression */
|
|
|
|
MSecDecompress((unsigned char *)ptr,(unsigned int)len,NULL,(unsigned int)0,(unsigned char **)&tmpBuf,NULL);
|
|
|
|
/* process expanded buffer (guaranteed to be a single element */
|
|
|
|
if ((MXMLFromString(&C,tmpBuf,NULL,EMsg) == FAILURE) ||
|
|
(MXMLAddE(E,C) == FAILURE))
|
|
{
|
|
MXMLDestroyE(EP);
|
|
|
|
if ((EMsg != NULL) &&
|
|
(EMsg[0] == '\0'))
|
|
{
|
|
strcpy(EMsg,"cannot add child element");
|
|
}
|
|
|
|
return(FAILURE);
|
|
}
|
|
|
|
tmpBuf = NULL;
|
|
|
|
/* move pointer to end of compressed data */
|
|
|
|
ptr = tail;
|
|
} /* END if (!strncmp(ptr,CRYPTHEAD,strlen(CRYPTHEAD))) */
|
|
|
|
while (*ptr != '<')
|
|
{
|
|
tmpVLine[index++] = *(ptr++);
|
|
|
|
if (index >= MMAX_XBUFFER)
|
|
break;
|
|
}
|
|
|
|
tmpVLine[index] = '\0';
|
|
|
|
E->Val = strdup(tmpVLine);
|
|
|
|
/* restore '<' symbols */
|
|
|
|
for (ptr2 = strchr(E->Val,(char)14);ptr2 != NULL;ptr2 = strchr(ptr2,(char)14))
|
|
*ptr2 = '<';
|
|
} /* END if (*ptr != '<') */
|
|
|
|
/* extract children */
|
|
|
|
while (ptr[1] != '/')
|
|
{
|
|
mxml_t *C;
|
|
|
|
C = NULL;
|
|
|
|
if (DoAppend == TRUE)
|
|
{
|
|
char *ptr2;
|
|
char tmpCName[MMAX_NAME];
|
|
|
|
int index;
|
|
|
|
/* FORMAT: <NAME>... */
|
|
|
|
/* locate name */
|
|
|
|
ptr2 = ptr + 1; /* ignore '<' */
|
|
|
|
index = 0;
|
|
|
|
while ((*ptr2 != ' ') && (*ptr2 != '>'))
|
|
{
|
|
if ((ptr2[0] == '/') && (ptr2[1] == '>'))
|
|
{
|
|
break;
|
|
}
|
|
|
|
tmpCName[index++] = *(ptr2++);
|
|
|
|
if ((index >= MMAX_LINE) || (ptr2[0] == '\0'))
|
|
{
|
|
if (EMsg != NULL)
|
|
sprintf(EMsg,"element name is too long - %.10s",
|
|
tmpCName);
|
|
|
|
MXMLDestroyE(EP);
|
|
|
|
return(FAILURE);
|
|
}
|
|
}
|
|
|
|
tmpCName[index] = '\0';
|
|
|
|
MXMLGetChild(E,tmpCName,NULL,&C);
|
|
}
|
|
|
|
if ((MXMLFromString(&C,ptr,&tail,EMsg) == FAILURE) ||
|
|
(MXMLAddE(E,C) == FAILURE))
|
|
{
|
|
break;
|
|
}
|
|
|
|
ptr = tail;
|
|
|
|
if ((ptr == NULL) || (ptr[0] == '\0'))
|
|
{
|
|
/* XML is corrupt */
|
|
|
|
if (Tail != NULL)
|
|
*Tail = ptr;
|
|
|
|
if ((EMsg != NULL) && (EMsg[0] == '\0'))
|
|
strcpy(EMsg,"cannot extract child");
|
|
|
|
MXMLDestroyE(EP);
|
|
|
|
return(FAILURE);
|
|
}
|
|
} /* END while (ptr[1] != '/') */
|
|
|
|
/* ignore whitespace */
|
|
|
|
while (isspace(*ptr))
|
|
ptr++;
|
|
|
|
/* value may follow children */
|
|
|
|
if (E->Val == NULL)
|
|
{
|
|
if (!strncmp(ptr,CRYPTHEAD,strlen(CRYPTHEAD)))
|
|
{
|
|
char *tail;
|
|
int len;
|
|
|
|
mxml_t *C;
|
|
|
|
char *tmpBuf;
|
|
|
|
/* compressed data detected, '<' symbol guaranteed to not be part of string */
|
|
|
|
tail = strchr(ptr,'<');
|
|
|
|
/* determine size of value */
|
|
|
|
len = tail - ptr;
|
|
|
|
/* uncompress data */
|
|
|
|
tmpBuf = NULL;
|
|
|
|
/* NOTE: CRYPTHEAD header indicates encryption/compression */
|
|
|
|
MSecDecompress((unsigned char *)ptr,(unsigned int)len,NULL,(unsigned int)0,(unsigned char **)&tmpBuf,NULL);
|
|
|
|
/* process expanded buffer (guaranteed to be a single element */
|
|
|
|
if ((MXMLFromString(&C,tmpBuf,NULL,EMsg) == FAILURE) ||
|
|
(MXMLAddE(E,C) == FAILURE))
|
|
{
|
|
MXMLDestroyE(EP);
|
|
|
|
if ((EMsg != NULL) &&
|
|
(EMsg[0] == '\0'))
|
|
{
|
|
strcpy(EMsg,"cannot add child element");
|
|
}
|
|
|
|
return(FAILURE);
|
|
}
|
|
|
|
tmpBuf = NULL;
|
|
|
|
/* move pointer to end of compressed data */
|
|
|
|
ptr = tail;
|
|
} /* END if (!strncmp(ptr,CRYPTHEAD,strlen(CRYPTHEAD))) */
|
|
|
|
index = 0;
|
|
|
|
while (*ptr != '<')
|
|
{
|
|
tmpVLine[index++] = *(ptr++);
|
|
|
|
if ((index >= MMAX_XBUFFER) || (*ptr == '\0'))
|
|
{
|
|
if (EMsg != NULL)
|
|
sprintf(EMsg,"cannot load value line - %.10s (%s)",
|
|
tmpVLine,
|
|
(index >= MMAX_XBUFFER) ? "too long" : "corrupt");
|
|
|
|
MXMLDestroyE(EP);
|
|
|
|
return(FAILURE);
|
|
}
|
|
|
|
if ((*ptr == '/') && (ptr[1] == '>'))
|
|
break;
|
|
}
|
|
|
|
tmpVLine[index] = '\0';
|
|
|
|
if (index > 0)
|
|
E->Val = strdup(tmpVLine);
|
|
} /* END if (tmpVLine[0] == '\0') */
|
|
|
|
/* process tail */
|
|
|
|
if (*ptr == '/')
|
|
{
|
|
/* process '/>' */
|
|
|
|
ptr++; /* ignore '/' */
|
|
}
|
|
else if (*ptr != '\0')
|
|
{
|
|
/* NOTE: corrupt XML string may move ptr beyond string terminator */
|
|
|
|
ptr++; /* ignore '<' */
|
|
|
|
ptr++; /* ignore '/' */
|
|
|
|
ptr += strlen(E->Name);
|
|
}
|
|
|
|
if (*ptr == '\0')
|
|
{
|
|
if (EMsg != NULL)
|
|
sprintf(EMsg,"xml tail is corrupt");
|
|
|
|
MXMLDestroyE(EP);
|
|
|
|
return(FAILURE);
|
|
}
|
|
|
|
ptr++; /* ignore '>' */
|
|
|
|
if (Tail != NULL)
|
|
*Tail = ptr;
|
|
|
|
return(SUCCESS);
|
|
} /* END MXMLFromString() */
|
|
|
|
|
|
|
|
|
|
mbool_t MXMLStringIsValid(
|
|
|
|
char *Buf) /* I */
|
|
|
|
{
|
|
char *ptr;
|
|
|
|
/* NOTE: only limited checks performed */
|
|
|
|
/* check if line starts with '<' */
|
|
|
|
if ((Buf == NULL) || (Buf[0] == '\0'))
|
|
{
|
|
return(FALSE);
|
|
}
|
|
|
|
ptr = strchr(Buf,'<');
|
|
|
|
if (ptr == NULL)
|
|
{
|
|
return(FALSE);
|
|
}
|
|
|
|
ptr--;
|
|
|
|
while (ptr > Buf)
|
|
{
|
|
if (!isspace(*ptr))
|
|
{
|
|
return(FALSE);
|
|
}
|
|
|
|
ptr--;
|
|
} /* END while (ptr > Buf) */
|
|
|
|
/* check if line contains '<' */
|
|
|
|
ptr = strchr(Buf,'>');
|
|
|
|
if (ptr == NULL)
|
|
{
|
|
return(FALSE);
|
|
}
|
|
|
|
return(TRUE);
|
|
} /* END MXMLStringIsValid() */
|
|
|
|
|
|
|
|
|
|
int MXMLDupE(
|
|
|
|
mxml_t *SrcE, /* I */
|
|
mxml_t **DstEP) /* O */
|
|
|
|
{
|
|
char Buffer[MMAX_BUFFER];
|
|
|
|
if (DstEP == NULL)
|
|
{
|
|
return(FAILURE);
|
|
}
|
|
|
|
*DstEP = NULL;
|
|
|
|
if (SrcE == NULL)
|
|
{
|
|
return(FAILURE);
|
|
}
|
|
|
|
if (MXMLToString(SrcE,Buffer,sizeof(Buffer),NULL,TRUE) == FAILURE)
|
|
{
|
|
return(FAILURE);
|
|
}
|
|
|
|
if (MXMLFromString(DstEP,Buffer,NULL,NULL) == FAILURE)
|
|
{
|
|
return(FAILURE);
|
|
}
|
|
|
|
return(SUCCESS);
|
|
} /* END MXMLDupE() */
|
|
|
|
/* END MXML.c */
|
|
|
|
|