/*
*
* ProLinga-Repository
*
* Copyright (C) 2002-2008 Xobas Software.
* All rights reserved.
*
* This file is part of ProLinga-Repository.
*
* ProLinga-Repository is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* ProLinga-Repository is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with ProLinga-Repository. If not, see .
*
* More information is available at the following addresses:
*
* Website : http://www.prolinga.org
*
* Email : prolinga-list@prolinga.org
*
*
*/
#include "RepCommon.h"
#include
#include
#include "RCRepositoryCommand.hpp"
#include "DocumentList.hpp"
#include "DocumentGet.hpp"
#include "DocumentPut.hpp"
#include "DocumentDelete.hpp"
#include
#include "RepMain.hpp"
#include "RepError.hpp"
#include "RepConfig.hpp"
using namespace DbXml;
/* Global Config Pointer */
//class ConfigSetting configSetting;
//ConfigSettingPtr confRepPtr = &configSetting;
//XmlContainer container(0, "abc");
//XmlContainer *contPtr = &container;
extern ConfigRepPtr confRepPtr;
bool RCisOnlySpace(const char *str)
{
int i,j;
j = strlen(str);
for(i=0;ixmlChildrenNode != NULL)
{
RCremoveWhiteSpace(cur->xmlChildrenNode);
}
if ((!strncmp((char *)cur->name, "text",4)) && (RCisOnlySpace((char *)cur->content)))
{
curRemove = cur;
cur = cur->next;
xmlUnlinkNode(curRemove);
xmlFreeNode(curRemove);
}
else
{
cur = cur->next;
}
}
return 0;
}
void RCCreateResponse(xmlDocPtr *docResponse, xmlNodePtr *curResponse)
{
/* Set up Response file */
*docResponse = xmlNewDoc((const xmlChar *)XML_VERSION);
(*docResponse)->children = xmlNewDocNode(*docResponse, NULL, (const xmlChar *)ROOT_ELEM, NULL);
*curResponse = xmlDocGetRootElement(*docResponse);
xmlNewTextChild (*curResponse, NULL, (const xmlChar *)"Repository", (const xmlChar *)"");
*curResponse = (*curResponse)->xmlChildrenNode;
xmlNewProp (*curResponse, (const xmlChar *)"Version", (const xmlChar *)REP_DOC_VERSION);
}
int RCWriteResponse(const xmlDocPtr docResponse, const char *rcOut)
{
return xmlSaveFile(rcOut, docResponse);
}
void RCCreateRepositoryObject(const char *objApplication, const char *objType, const char *objName,
const xmlDocPtr docObj, const xmlNodePtr curObj, xmlBufferPtr *buf)
{
xmlDocPtr doc;
xmlNodePtr cur, curTmp;
/* Create Repository XML Document */
doc = xmlNewDoc((const xmlChar *)XML_VERSION);
doc->children = xmlNewDocNode(doc, NULL, (const xmlChar *)ROOT_ELEM, NULL);
cur = xmlDocGetRootElement(doc);
cur = xmlNewTextChild (cur, NULL, (const xmlChar *)"RepositoryObject", (const xmlChar *)"");
cur = xmlNewTextChild (cur, NULL, (const xmlChar *)"Object", (const xmlChar *)"");
xmlNewProp (cur, (const xmlChar *)"Application", (const xmlChar *)objApplication);
xmlNewProp (cur, (const xmlChar *)"Type", (const xmlChar *)objType);
xmlNewProp (cur, (const xmlChar *)"Name", (const xmlChar *)objName);
/* Copy object sub set */
curTmp = curObj->xmlChildrenNode;
if (!xmlStrcmp(curTmp->name, (const xmlChar *)"text"))
curTmp = curTmp->next;
if (cur != NULL)
xmlAddChildList(cur, xmlCopyNodeList(curTmp));
/* Remove Whitespace in xml document */
cur = xmlDocGetRootElement(doc);
RCremoveWhiteSpace(cur);
/* Dump XML to string */
xmlIndentTreeOutput = 1;
xmlKeepBlanksDefault(0);
cur = xmlDocGetRootElement(doc);
xmlNodeDump(*buf, doc, cur, 0, 1);
/* Release */
xmlFreeDoc(doc);
}
void RCCreateCommandDoc(xmlNodePtr cur, xmlDocPtr *docCmd)
{
xmlNodePtr curCmd;
/* Set node pointer to object in repository command */
cur = cur->xmlChildrenNode;
while (cur != NULL)
{
if (!xmlStrcmp(cur->name, (const xmlChar *) "Object"))
break;
cur = cur->next;
}
/* Create new Command Doc */
*docCmd = xmlNewDoc((const xmlChar *)XML_VERSION);
(**docCmd).children = xmlNewDocNode(*docCmd, NULL, (const xmlChar *)ROOT_ELEM, NULL);
curCmd = xmlDocGetRootElement(*docCmd);
curCmd->xmlChildrenNode = xmlCopyNodeList(cur);
}
void RCCreateResponseCommand(const char *cmdName, xmlDocPtr **docCmd)
{
xmlNodePtr curCmd;
/* Create Command Response */
**docCmd = xmlNewDoc((const xmlChar *)XML_VERSION);
(***docCmd).children = xmlNewDocNode(**docCmd, NULL, (const xmlChar *)ROOT_ELEM, NULL);
curCmd = xmlDocGetRootElement(**docCmd);
xmlNewTextChild (curCmd, NULL, (const xmlChar *)"Command", (const xmlChar *)"");
curCmd = curCmd->xmlChildrenNode;
xmlNewProp (curCmd, (const xmlChar *)"Name", (const xmlChar *)cmdName);
xmlNewProp (curCmd, (const xmlChar *)"Mode", (const xmlChar *)"Response");
}
void RCCreateResponseObject(const char *objApplication, const char *objType, const char *objName, xmlDocPtr *docCmd)
{
xmlNodePtr curCmd;
*docCmd = xmlNewDoc((const xmlChar *)XML_VERSION);
(**docCmd).children = xmlNewDocNode(*docCmd, NULL, (const xmlChar *)ROOT_ELEM, NULL);
curCmd = xmlDocGetRootElement(*docCmd);
curCmd = xmlNewTextChild (curCmd, NULL, (const xmlChar *)"Object", (const xmlChar *)"");
xmlNewProp (curCmd, (const xmlChar *)"Application", (const xmlChar *)objApplication);
xmlNewProp (curCmd, (const xmlChar *)"Type", (const xmlChar *)objType);
xmlNewProp (curCmd, (const xmlChar *)"Name", (const xmlChar *)"objName");
}
void RCInsertResponseObject(const char *objApplication, const char *objType, const char *objName, xmlDocPtr **docCmd)
{
xmlNodePtr curCmd;
/* Insert appn, type and name in Command Response */
curCmd = xmlDocGetRootElement(**docCmd);
if (!xmlStrcmp(curCmd->name, (const xmlChar *) "text"))
curCmd = curCmd->next;
curCmd = curCmd->xmlChildrenNode;
if (!xmlStrcmp(curCmd->name, (const xmlChar *) "text"))
curCmd = curCmd->next;
curCmd = xmlNewTextChild (curCmd, NULL, (const xmlChar *)"Object", (const xmlChar *)"");
xmlNewProp (curCmd, (const xmlChar *)"Application", (const xmlChar *)objApplication);
xmlNewProp (curCmd, (const xmlChar *)"Type", (const xmlChar *)objType);
//curCmd = xmlNewTextChild (curCmd, NULL, (const xmlChar *)"Name", (const xmlChar *)objName);
xmlNewProp (curCmd, (const xmlChar *)"Name", (const xmlChar *)objName);
}
void RCInsertResponseObjectError(const int id, const char *severity, const char *description, const char *externalDesc, xmlDocPtr **docCmd)
{
xmlNodePtr curCmd;
char dummyId[10]="";
/* Set Pointer */
curCmd = xmlDocGetRootElement(**docCmd);
curCmd = curCmd->xmlChildrenNode;
curCmd = xmlGetLastChild(curCmd);
/* Insert Error */
curCmd = xmlNewTextChild (curCmd, NULL, (const xmlChar *)"Error", (const xmlChar *)"");
sprintf(dummyId, "%d", id);
xmlNewProp (curCmd, (const xmlChar *)"Id", (const xmlChar *)dummyId);
xmlNewTextChild (curCmd, NULL, (const xmlChar *)"Severity", (const xmlChar *)severity);
xmlNewTextChild (curCmd, NULL, (const xmlChar *)"Description", (const xmlChar *)description);
xmlNewTextChild (curCmd, NULL, (const xmlChar *)"ExternalDescription", (const xmlChar *)externalDesc);
}
void RCInsertResponseObjectDoc(const xmlDocPtr docObj, xmlDocPtr **docCmd)
{
xmlNodePtr curObj, curCmd ;
//xmlAttrPtr attrCmd;
/* Set Pointer Command Response */
curCmd = xmlDocGetRootElement(**docCmd);
curCmd = curCmd->xmlChildrenNode;
while (curCmd != NULL)
{
if (!xmlStrcmp(curCmd->name, (const xmlChar *) "Command"))
break;
curCmd = curCmd->next;
}
//attrCmd = xmlNewProp (curCmd, (const xmlChar *)"Id", (const xmlChar *)"1");
/* Set Pointer Object */
curObj = xmlDocGetRootElement(docObj);
curObj = curObj->xmlChildrenNode;
while (curObj != NULL)
{
if (!xmlStrcmp(curObj->name, (const xmlChar *) "Object"))
break;
curObj = curObj->next;
}
/* Merge */
xmlAddChildList(curCmd, xmlCopyNodeList(curObj));
}
void RCSetResponseCommandStatus(const int cmdStatus, xmlDocPtr **docCmd)
{
xmlNodePtr curCmd;
/* Write Status */
curCmd = xmlDocGetRootElement(**docCmd);
curCmd = curCmd->xmlChildrenNode;
while (curCmd != NULL)
{
if (!xmlStrcmp(curCmd->name, (const xmlChar *) "Command"))
break;
curCmd = curCmd->next;
}
if (cmdStatus == 0)
xmlNewProp (curCmd, (const xmlChar *)"Status", (const xmlChar *)"Ok");
else if (cmdStatus == 1)
xmlNewProp (curCmd, (const xmlChar *)"Status", (const xmlChar *)"Warning");
else if (cmdStatus == 2)
xmlNewProp (curCmd, (const xmlChar *)"Status", (const xmlChar *)"Error");
}
void RCMergeResponse(const xmlDocPtr docSrc, xmlDocPtr *docDest)
{
xmlNodePtr curSrc, curDest;
/* Set pointer in source document */
curDest = xmlDocGetRootElement(*docDest);
curDest = curDest->xmlChildrenNode;
while (curDest != NULL)
{
if (!xmlStrcmp(curDest->name, (const xmlChar *) "Repository"))
break;
curDest = curDest->next;
}
/* Set pointer in destination document */
curSrc = xmlDocGetRootElement(docSrc);
curSrc = curSrc->xmlChildrenNode;
while (curSrc != NULL)
{
if (!xmlStrcmp(curSrc->name, (const xmlChar *) "Command"))
break;
curSrc = curSrc->next;
}
/* Merge */
xmlAddChildList(curDest, xmlCopyNodeList(curSrc));
}
int RCCommandExec(const char *cmdName, const xmlDocPtr docCmd, xmlDocPtr *docRespCmd)
{
xmlDocPtr docList, docGet;
xmlNodePtr curCmd;
xmlBufferPtr bufCmd;
char *objApplication = NULL, *objType = NULL, *objName = NULL;
char *externalError;
int dbStatus, cmdStatus = 0;
/* Create Command Response */
RCCreateResponseCommand(cmdName, &docRespCmd);
/* Set pointer to command */
curCmd = xmlDocGetRootElement(docCmd);
/* Loop through all Objects */
for (curCmd = curCmd->xmlChildrenNode; curCmd != NULL; curCmd = curCmd->next)
{
if (xmlStrcmp(curCmd->name, (const xmlChar *) "Object")) continue;
/* Get Object Index Details */
objApplication = (char *)xmlGetProp(curCmd, (const xmlChar *)"Application");
objType = (char *)xmlGetProp(curCmd, (const xmlChar *)"Type");
objName = (char *)xmlGetProp(curCmd, (const xmlChar *)"Name");
/* Determine command and call appropriate function */
if (!strcmp(cmdName, "List"))
{
/* List Command */
dbStatus = DocumentList(objApplication, objType, objName, &externalError, &docList);
if (dbStatus == 0)
{
/* Merge result in response */
RCInsertResponseObjectDoc(docList, &docRespCmd);
xmlFreeDoc(docList);
}
else
{
/* Insert Object line in response */
RCInsertResponseObject(objApplication, objType, objName, &docRespCmd);
}
}
else if (!strcmp(cmdName, "Get"))
{
/* Get Command */
dbStatus = DocumentGet(objApplication, objType, objName, &externalError, &docGet);
if (dbStatus == 0)
{
/* Merge result in response */
RCInsertResponseObjectDoc(docGet, &docRespCmd);
xmlFreeDoc(docGet);
}
else
{
/* Insert Object line in response */
RCInsertResponseObject(objApplication, objType, objName, &docRespCmd);
//buf = xmlBufferCreate();
//curRespCmd = xmlDocGetRootElement(*docRespCmd);
//xmlNodeDump(buf, *docRespCmd, curRespCmd, 0, 1);
//printf("%s\n", (char *)xmlBufferContent(buf));
//xmlBufferFree(buf);
}
}
else if (!strcmp(cmdName, "Put"))
{
/* Create Repository Object */
bufCmd = xmlBufferCreate();
RCCreateRepositoryObject(objApplication, objType, objName, docCmd, curCmd, &bufCmd);
/* Put Command */
dbStatus = DocumentPut(objApplication, objType, objName, (char *)xmlBufferContent(bufCmd), &externalError);
/* Release */
xmlBufferFree(bufCmd);
/* Insert Object line in response */
RCInsertResponseObject(objApplication, objType, objName, &docRespCmd);
}
else if (!strcmp(cmdName, "Delete"))
{
/* Delete Command */
dbStatus = DocumentDelete(objApplication, objType, objName, &externalError);
/* Insert Object line in response */
RCInsertResponseObject(objApplication, objType, objName, &docRespCmd);
}
else if (!strcmp(cmdName, "Ping"))
{
/* Dummy to test if service is available */
dbStatus = 0;
}
else
{
/* Invalid Command */
dbStatus = 0;
continue;
}
/* Error handling */
if (dbStatus != 0)
{
/* If external / 3rd party error */
if (dbStatus == 90001)
{
RCInsertResponseObjectError(dbStatus, "Error", "External warning/error", externalError, &docRespCmd);
delete externalError;
cmdStatus = 2;
}
else
{
RCInsertResponseObjectError(dbStatus, errorRepSeverity[errorTable10000[(dbStatus-10000)].severity], errorTable10000[(dbStatus-10000)].description, "", &docRespCmd);
if (cmdStatus < errorTable10000[(dbStatus-10000)].severity)
cmdStatus = errorTable10000[(dbStatus-10000)].severity;
}
}
}
/* Write Status */
RCSetResponseCommandStatus(cmdStatus, &docRespCmd);
/* Return */
return 0;
}
int RCCommandSysInfo(const xmlDocPtr docCmd, xmlDocPtr *docRespCmd)
{
xmlNodePtr curRespCmd;
char server_port[5], num_threads[5], server_comp[5], log_level[5];
char *service_id, *server_host, *log_file, *system_path;
char hostname[40];
// char hostname[40], ip_address[16];
// struct hostent *he;
/* Create Command Response */
RCCreateResponseCommand("SysInfo", &docRespCmd);
/* Get Config Values */
service_id = confRepPtr->getStringValue("ServiceId", DEF_SERVER_HOST);
server_host = confRepPtr->getStringValue("ServerHost", DEF_SERVER_HOST);
sprintf(server_port,"%d",confRepPtr->getNumberValue("ServerPort", DEF_SERVER_PORT));
sprintf(num_threads,"%d",confRepPtr->getNumberValue("NumberOfThreads", DEF_THREADS));
system_path = confRepPtr->getStringValue("SystemPath", DEF_SYSTEM_PATH);
sprintf(server_comp,"%d",confRepPtr->getNumberValue("ServerCompressionLevel", DEF_SERVER_COMP_LEVEL));
log_file = confRepPtr->getStringValue("LogFile", DEF_LOG_FILE);
sprintf(log_level,"%d",confRepPtr->getNumberValue("LogLevel", DEF_LOG_LEVEL));
/* Get System Values */
gethostname(hostname,40);
// he = gethostbyname(hostname);
// strcpy(ip_address, he->h_addr);
/* Insert values in Command Response */
curRespCmd = xmlDocGetRootElement(*docRespCmd);
if (!xmlStrcmp(curRespCmd->name, (const xmlChar *) "text"))
curRespCmd = curRespCmd->next;
curRespCmd = curRespCmd->xmlChildrenNode;
if (!xmlStrcmp(curRespCmd->name, (const xmlChar *) "text"))
curRespCmd = curRespCmd->next;
xmlNewTextChild (curRespCmd, NULL, (const xmlChar *)"ServiceId", (const xmlChar *)service_id);
xmlNewTextChild (curRespCmd, NULL, (const xmlChar *)"ServerHost", (const xmlChar *)server_host);
xmlNewTextChild (curRespCmd, NULL, (const xmlChar *)"ServerPort", (const xmlChar *)server_port);
xmlNewTextChild (curRespCmd, NULL, (const xmlChar *)"SystemPath", (const xmlChar *)system_path);
xmlNewTextChild (curRespCmd, NULL, (const xmlChar *)"NumberOfThreads", (const xmlChar *)num_threads);
xmlNewTextChild (curRespCmd, NULL, (const xmlChar *)"LogFile", (const xmlChar *)log_file);
xmlNewTextChild (curRespCmd, NULL, (const xmlChar *)"LogLevel", (const xmlChar *)log_level);
xmlNewTextChild (curRespCmd, NULL, (const xmlChar *)"ServerCompressionLevel", (const xmlChar *)server_comp);
xmlNewTextChild (curRespCmd, NULL, (const xmlChar *)"SystemHostName", (const xmlChar *)hostname);
//xmlNewTextChild (curRespCmd, NULL, (const xmlChar *)"SystemIPNumber", (const xmlChar *)"");
//xmlNewTextChild (curRespCmd, NULL, (const xmlChar *)"SystemOperatingSystem", (const xmlChar *)"");
/* Write Status */
RCSetResponseCommandStatus(0, &docRespCmd);
/* Return */
return 0;
}
xmlDocPtr RCRepositoryCommand(const xmlDocPtr doc)
{
xmlDocPtr docCmd, docResponse, docRespCmd;
xmlNodePtr cur, curResponse;
char *cmdName;
int dbStatus;
/* Set up response document */
RCCreateResponse(&docResponse, &curResponse);
cur = xmlDocGetRootElement(doc);
/* Check if correct repository XML and version */
cur = cur->xmlChildrenNode;
if (!xmlStrcmp(cur->name, (const xmlChar *) "text"))
cur = cur->next;
/* Loop through all Repository Commands */
for (cur = cur->xmlChildrenNode; cur != NULL; cur = cur->next)
{
if (xmlStrcmp(cur->name, (const xmlChar *) "Command")) continue;
/* Get command name */
cmdName = (char *)xmlGetProp(cur, (const xmlChar *)"Name");
/* Create Command document */
RCCreateCommandDoc(cur, &docCmd);
/* Execute Command */
if (strcmp(cmdName, "SysInfo") == 0)
dbStatus = RCCommandSysInfo(docCmd, &docRespCmd);
else
dbStatus = RCCommandExec(cmdName, docCmd, &docRespCmd);
/* Merge response level2 in level 1 */
RCMergeResponse(docRespCmd, &docResponse);
/* Release Command Doc */
xmlFreeDoc(docCmd);
xmlFreeDoc(docRespCmd);
}
/* Debug */
/* Print document */
/*
xmlBufferPtr buf = xmlBufferCreate();
curResponse = xmlDocGetRootElement(docResponse);
xmlNodeDump(buf, docResponse, curResponse, 0, 1);
printf("QQQ\n%s\n", (char *)xmlBufferContent(buf));
xmlBufferFree(buf);
*/
/* Release + cleanup */
//xmlCleanupParser();
/* Return OK */
return docResponse;
}