📄 cifile.c
字号:
return nodeId;
}
static void buildFromFile(FILE *inf, char *fileBuffer, HRPOOL pool,
HRTREE tree, int nodeID, int level)
{
static int lastReadLevel;
int readLevel, newNodeID, nameCounter = 1;
RvUint32 length;
cfgValue cfgVal;
char *p, *p2, *value=NULL, *name=NULL;
long int pos=0;
char assistBuff[2*FILE_BUF_SIZE];
int assistLen;
/* We clear the value so that purify won't shout about Unitiaialized Memory Copy (UMC),
since we're going to copy the contents of this node into RTREE somewhere along the
way. We don't care about all the files, so we can just clean them here... */
memset(&cfgVal, 0, sizeof(cfgVal));
if (level == 0)
{
lastReadLevel = 0;
}
for (;;)
{
readLevel = -2;
memset(fileBuffer, 0, FILE_BUF_SIZE);
while ((readLevel < 0))
{
pos = ftell(inf);
if (fgets(fileBuffer, FILE_BUF_SIZE, inf)==NULL)
return;
readLevel = parseLine(lastReadLevel, fileBuffer, &name, &value);
}
if (readLevel < level)
{
/* a higher level, we must exit */
fseek(inf, pos, SEEK_SET);
return;
}
lastReadLevel = readLevel;
/* will resolve '*' names here */
if (!strcmp(name, "*"))
{
if (readLevel != level)
RvSprintf(name, "%d", 1);
else
RvSprintf(name, "%d", ++nameCounter);
}
else
if (atoi(name))
nameCounter = atoi(name);
cfgVal.name = rpoolAllocCopyExternal(pool, name, (int)strlen(name));
cfgVal.isString = RV_TRUE; /* assume string */
cfgVal.value = 0;
cfgVal.str = NULL;
/* parse the value */
p = value;
switch (*p)
{
case '\'': /* string */
MATCH_QUOTE('\'');
cfgVal.str = rpoolAllocCopyExternal(pool, (void*)p, assistLen);
cfgVal.value = assistLen;
break;
case '[': /* hex string */
{
RvBool bIsHighByte;
char c;
RvUint8 i;
MATCH_QUOTE(']');
p2 = assistBuff;
cfgVal.value = (assistLen + 1) >> 1;
memset(assistBuff, 0, (RvSize_t)cfgVal.value);
bIsHighByte = !(length & 1);
for (; length; length--, p++)
{
c = (char)toupper((char)*p);
i = (char)((c > '9')? (c - 'A' + (char)10) : (c - '0'));
if (bIsHighByte)
{
*p2 = (char)(i << (char)4);
}
else
{
*p2 = (char)(*p2 + i);
p2++;
}
bIsHighByte = !bIsHighByte;
}
cfgVal.str = rpoolAllocCopyExternal(pool, (void*)assistBuff, cfgVal.value);
break;
}
case '"': /* BMP string */
p2 = findMatchingQuote(p + 1, '"');
if (!p2 || ((p2 - p) < 1))
break;
p++;
*p2 = '\0';
length = (p2 - p);
cfgVal.value = length * 2;
{
chrn2bmp(p, (RvSize_t)length, (RvUint8*)assistBuff);
cfgVal.str = rpoolAllocCopyExternal(pool, (void *)assistBuff, cfgVal.value);
}
break;
case '%': /* bit string */
{
char buf[1024];
char bitBuf[1152];
int i, val;
p2 = findMatchingQuote(p + 1, '%');
if (!p2 || ((p2 - p) < 1))
break;
p++;
*p2 = '\0';
/* str -> bits */
p2 = buf;
val = 0;
i = length = 0;
while (*p)
{
if (*p != '1' && *p != '0')
goto bitstr_out;
val += (((unsigned)(*p - '0')) << (7 - i));
if (++i > 7)
{
*p2 = (char)val;
i = val = 0;
p2++;
}
p++;
length++; /* count bits */
}
if (i)
*p2 = (char)val;
cfgVal.value = ciBuildBitString(buf, (int)length, bitBuf);
cfgVal.str = rpoolAllocCopyExternal(pool, (void *)bitBuf, cfgVal.value);
bitstr_out:
break;
}
case '{': /* object ID */
MATCH_QUOTE('}');
/* the target string should be big enough */
cfgVal.value = oidEncodeOID((int)length, assistBuff, p);
cfgVal.str = rpoolAllocCopyExternal(pool, (void *)assistBuff, cfgVal.value);
break;
case '<': /* IP */
{
RvAddress addr;
const RvAddressIpv4* ipv4Addr;
RvUint32 ipV4 = RV_UINT32_MAX;
MATCH_QUOTE('>');
RvAddressConstruct(&addr, RV_ADDRESS_TYPE_IPV4);
if (RvAddressSetString(&addr, (RvChar *)p) != NULL)
{
ipv4Addr = RvAddressGetIpv4(&addr);
if (ipv4Addr != NULL)
ipV4 = RvAddressIpv4GetIp(ipv4Addr);
RvAddressDestruct(&addr);
}
cfgVal.value = 4;
cfgVal.str = rpoolAllocCopyExternal(pool, (void*)&ipV4, cfgVal.value);
break;
}
default:
cfgVal.isString = RV_FALSE;
cfgVal.value = atoi(p);
}
if (level == readLevel)
{
newNodeID = getSameNode(tree, rtParent(tree, nodeID), pool, cfgVal.name);
if (newNodeID <= 0)
{
/* Such a node doesn't exist - add it in */
newNodeID = rtAddBrother(tree, nodeID, &cfgVal);
nodeID = newNodeID;
}
else
{
/* Already have such a node - ignore this new one */
if (cfgVal.name != NULL)
rpoolFree(pool, cfgVal.name);
if (cfgVal.str != NULL)
rpoolFree(pool, cfgVal.str);
}
}
else
newNodeID = rtAddTail(tree, nodeID, &cfgVal);
if (nodeID != newNodeID) /* nest to next level */
buildFromFile(inf, fileBuffer, pool, tree, newNodeID, level + 1);
}
}
#define IS_PRINTABLE(c) ((c) >= ' ' && (c) < 127)
static void outputToFile(FILE *outf, HRTREE tree, int nodeID, int level, HRPOOL pool)
{
pcfgValue cfgVal;
int child, i, printable, isBMP;
static int lastOutputLevel;
char buff[MAX_CONFIG_TEMP_BUFFER_SIZE];
if (level == 0)
lastOutputLevel = 0;
for (;;)
{
if (level != 0)
{
cfgVal = (pcfgValue)rtGetByPath(tree, nodeID);
/* make the file legable by adding some extra blank lines */
if (level == 1)
fprintf(outf, "\n\n");
else
if (lastOutputLevel > level + 2)
putc('\n', outf);
/* output the level */
if (level == 1) /* always print number on first level */
fputc('1', outf);
else
if (level == lastOutputLevel)
fputc(' ', outf);
else
if (level == lastOutputLevel + 1)
fputc('+', outf);
else
if (level == lastOutputLevel - 1)
fputc('-', outf);
else
fprintf(outf, "%d", level);
/* output the name, padded with spaces on the left */
rpoolCopyToExternal(pool, (void*)buff, cfgVal->name, 0, MAX_CONFIG_TEMP_BUFFER_SIZE);
buff[rpoolChunkSize(pool, cfgVal->name)] = 0;
fprintf(outf, "%*c%s = ", level, ' ',
atoi(buff) ? "*" : buff);
if (cfgVal->isString)
{
char buff[MAX_CONFIG_TEMP_BUFFER_SIZE];
rpoolCopyToExternal(pool, (void*)buff, cfgVal->str, 0, MAX_CONFIG_TEMP_BUFFER_SIZE);
/* see if we can print it as a BMP string */
isBMP = 1; /* assume so */
if (cfgVal->value % 2 == 0) /* even length */
{
for (i = 0; i < cfgVal->value; i += 2)
{
if (buff[i] != '\0' ||
!IS_PRINTABLE(buff[i + 1]))
{
isBMP = 0;
break;
}
}
}
else
isBMP = 0;
if (isBMP)
{
fputc('"', outf);
for (i = 0; i < cfgVal->value; i += 2)
{
int iChar = buff[i + 1];
fputc(iChar, outf);
}
fprintf(outf, "\"\n");
}
else /* non BMP strings */
{
/* see if string is printable */
printable = 1;
for (i = 0; i < cfgVal->value; i++)
{
if (!IS_PRINTABLE(buff[i]))
{
printable = 0;
}
}
if (printable)
{
fputc('\'', outf);
fwrite(buff, (RvSize_t)cfgVal->value, 1, outf);
fputc('\'', outf);
fputc('\n', outf);
}
else
{
/* output octet string */
fputc('[', outf);
for (i = 0; i < cfgVal->value; i++)
fprintf(outf, "%02x",
(unsigned char)buff[i]);
fprintf(outf, "]\n");
}
}
}
else /* an int */
fprintf(outf, "%d\n", cfgVal->value);
}
lastOutputLevel = level;
/* process children */
child = rtHead(tree, nodeID);
if (child >= 0)
outputToFile(outf, tree, child, level + 1, pool);
/* move to brother */
nodeID = rtBrother(tree, nodeID);
if (nodeID < 0)
return;
}
}
#ifdef __cplusplus
}
#endif
#endif /* NOFILESYSTEM */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -