26
26
#include <cmcidt.h>
28
28
#include "cimXmlParser.h"
29
#include "cimXmlResp.h"
32
32
#include "dmalloc.h"
36
int yylex(YYSTYPE * lvalp, ParserControl * parm);
35
#ifdef LARGE_VOL_SUPPORT
38
#include <curl/curl.h> // new
39
#include <pthread.h> // new
40
#include <time.h> // new
41
#include <sys/time.h> // new
42
#include <setjmp.h> // new
44
struct _CMCIConnectionFT; // new
45
typedef struct _CMCIConnectionFT CMCIConnectionFT; // new
47
char * getNextSection(struct _CMCIConnection * ) ;
48
int checkTag(char * , int ) ;
51
#include "utilStringBuffer.h" // new
52
#include "cimXmlParser.h" // new
53
#include "native.h" // new
54
#include "esinfo.h" // new
55
#include "conn.h" // new
60
* response data helper functions.
62
inline char * CURPTR (enumScanInfo * esi ){
63
return(((char*)(esi->base)) + (esi->curoff)) ;
65
inline char * SSECPTR (enumScanInfo * esi ){
66
return(((char*)(esi->base)) + (esi->ssecoff)) ;
68
inline char * LASTPTR (enumScanInfo * esi ){
69
return(((char*)(esi->base)) + (esi->eodoff)) ;
71
inline void INCOFF (enumScanInfo * esi ){
75
int sfccFreeSection(ParserControl * );
76
void * enumScanThrd(struct native_enum *);
77
int sfccLex(parseUnion * , ParserControl * );
78
char * getNextSection(struct _CMCIConnection * );
79
int checkTag(char * , int );
81
#endif /* endif LARGE_VOL_SUPPORT */
39
83
static int attrsOk(XmlBuffer * xb, const XmlElement * e, XmlAttr * r,
40
84
const char *tag, int etag);
41
85
static char *getValue(XmlBuffer * xb, const char *v);
42
extern int yyparse(void *);
44
87
typedef struct tags {
47
int (*process) (YYSTYPE *, ParserControl * parm);
90
int (*process) (parseUnion *, ParserControl * parm);
1099
1170
memset(attr, 0, sizeof(attr));
1100
1171
if (tagEquals(parm->xmb, "PARAMETER.REFARRAY")) {
1101
1172
attr[1].attr = NULL;
1102
if (attrsOk(parm->xmb, elm, attr, "PARAMETER.REFARRAY", ZTOK_PARAM)) {
1173
if (attrsOk(parm->xmb, elm, attr, "PARAMETER.REFARRAY", ZTOK_PARAMREFARRAY)) {
1103
1174
memset(&lvalp->xtokParam, 0, sizeof(XtokParam));
1104
1175
lvalp->xtokParam.pType = ZTOK_PARAMREFARRAY;
1105
1176
lvalp->xtokParam.name = attr[0].attr;
1106
1177
lvalp->xtokParam.refClass = attr[1].attr;
1107
1178
lvalp->xtokParam.arraySize = attr[2].attr;
1108
1179
lvalp->xtokParam.type = CMPI_refA;
1180
return XTOK_PARAMREFARRAY;
1187
static int procSimpleExpReq(parseUnion * lvalp, ParserControl * parm)
1189
static XmlElement elm[] = {
1194
if (tagEquals(parm->xmb, "SIMPLEEXPREQ")) {
1195
if (attrsOk(parm->xmb, elm, attr, "SIMPLEEXPREQ", ZTOK_SIMPLEEXPREQ))
1197
return XTOK_SIMPLEEXPREQ;
1203
static int procExportMethodCall(parseUnion * lvalp, ParserControl * parm)
1205
static XmlElement elm[] = {
1211
memset(attr, 0, sizeof(attr));
1212
if (tagEquals(parm->xmb, "EXPMETHODCALL")) {
1213
if (attrsOk(parm->xmb, elm, attr, "EXPMETHODCALL", ZTOK_EXPMETHODCALL)) {
1214
if (strcasecmp(attr[0].attr, "ExportIndication") == 0) {
1215
return XTOK_EXPORTINDICATION;
1222
static int procExParamValue(parseUnion * lvalp, ParserControl * parm)
1224
static XmlElement elm[] = {
1230
memset(attr, 0, sizeof(attr));
1231
if (tagEquals(parm->xmb, "EXPPARAMVALUE")) {
1232
if (attrsOk(parm->xmb, elm, attr, "EXPPARAMVALUE", ZTOK_EXPPARAMVALUE)) {
1233
if (strcasecmp(attr[0].attr, "NewIndication") == 0) {
1234
return XTOK_EP_INSTANCE;
1241
static int procCdata(parseUnion * lvalp, ParserControl * parm)
1243
static XmlElement elm[] = {
1248
if (tagEquals(parm->xmb, "![CDATA[")) {
1250
parm->xmb->cur[0] = '>';
1252
if (attrsOk(parm->xmb, elm, attr, "![CDATA[", ZTOK_CDATA)) {
1254
v=strstr(parm->xmb->cur, "]]>");
1116
1267
static Tags tags[] = {
1117
1268
{TAG("?xml"), procXml, ZTOK_XML},
1152
1303
{TAG("OBJECTPATH"), procObjectPath, ZTOK_OBJECTPATH},
1153
1304
{TAG("METHODRESPONSE"), procMethodResp, ZTOK_METHODRESP},
1154
1305
{TAG("RETURNVALUE"), procRetValue, ZTOK_RETVALUE},
1155
{TAG("CLASSPATH"), procClassPath, ZTOK_CLASSPATH}
1306
{TAG("CLASSPATH"), procClassPath, ZTOK_CLASSPATH},
1307
{TAG("SIMPLEEXPREQ"), procSimpleExpReq, ZTOK_SIMPLEEXPREQ},
1308
{TAG("EXPMETHODCALL"), procExportMethodCall, ZTOK_EXPMETHODCALL},
1309
{TAG("EXPPARAMVALUE"), procExParamValue, ZTOK_EXPPARAMVALUE},
1310
{TAG("![CDATA["), procCdata, ZTOK_CDATA},
1311
{TAG(""), procCdata, ZTOK_CDATA},
1312
/* The last two lines are a hack for embedded instances. The CDATA
1313
* construct does not have a <x> ... </x> form but rather something like
1314
* <bla ....>, which is not a real tag. so the second line is necessary
1315
* for our lexer to find the closing "tag" for that case, which is just
1316
* an empty string */
1157
1318
#define TAGS_NITEMS (int)(sizeof(tags)/sizeof(Tags))
1159
int yylex(YYSTYPE * lvalp, ParserControl * parm)
1320
#ifndef LARGE_VOL_SUPPORT
1322
int sfccLex(parseUnion * lvalp, ParserControl * parm)
1483
#if LARGE_VOL_SUPPORT
1485
/* **************************************************************************/
1486
/* **************************************************************************/
1487
/* **************************************************************************/
1488
/* **************************************************************************/
1489
/* **************************************************************************/
1490
/* **************************************************************************/
1491
/* **************************************************************************/
1492
int sfccFreeSection(ParserControl * parm)
1494
if(parm->econ->asynRCntl.escanInfo.section){
1495
free(parm->econ->asynRCntl.escanInfo.section) ;
1496
parm->econ->asynRCntl.escanInfo.section = NULL ;
1499
#define TIMEDELAY 10
1500
void * enumScanThrd(struct native_enum *NatEnum)
1502
CMCIConnection * con = NatEnum->econ ; /* enumeration */
1503
CMPIObjectPath * cop = NatEnum->ecop ; /* enumeration */
1505
struct timespec tp ;
1508
ParserControl control;
1509
struct native_enum *local_enmp ;
1511
memset(&control,0,sizeof(control));
1514
* get the data array and save a copy of address in enumeration
1517
XmlBuffer *xmb = newXmlBuffer(NULL);
1519
control.respHdr.xmlBuffer = xmb;
1521
control.respHdr.rvArray=newCMPIArray(0,0,NULL);
1523
local_enmp = con->asynRCntl.enmp ;
1525
local_enmp->data = control.respHdr.rvArray ;
1528
control.da_nameSpace=(char*)getNameSpaceChars(cop);
1531
control.heap = parser_heap_init();
1533
control.econ = con ;
1535
if(rc = setjmp(save_env)) {
1536
printf(" we had a timeout , we are going to exit from here \n") ;
1537
con->asynRCntl.escanInfo.parsestate = PARSTATE_SERVER_TIMEOUT ;
1538
con->asynRCntl.xfer_state = XFER_ERROR ;
1543
* wait for first data block received or xfer complete
1544
* we need to have some data before starting
1546
while((con->asynRCntl.xfer_state != XFER_DATA_RECVD )&&
1547
(con->asynRCntl.xfer_state != XFER_COMPLETE)){
1551
control.respHdr.rc = startParsing(&control);
1554
* releaseXmlBuffer free's that last con->asynRCntl.escanInfo.section
1555
* we clear out that pointer just to be safe
1557
releaseXmlBuffer(xmb);
1559
con->asynRCntl.escanInfo.section = 0 ;
1561
parser_heap_term(control.heap);
1563
con->asynRCntl.escanInfo.parsestate = PARSTATE_COMPLETE ;
1567
int sfccLex(parseUnion * lvalp, ParserControl * parm)
1577
if(parm->econ->asynRCntl.escanInfo.getnew == 1 ){
1579
nextSection = getNextSection(parm->econ) ;
1580
if(nextSection != NULL) {
1581
parm->xmb->base = nextSection ;
1582
parm->xmb->cur = nextSection ;
1583
parm->xmb->last = nextSection + (parm->econ->asynRCntl.escanInfo.sectlen) ;
1586
printf(" sfccLex --- section is NULL !!!!!!!!!!!!!!!!! \n") ;
1592
next = nextTag(parm->xmb);
1596
// fprintf(stderr,"--- token: %.32s\n",next); //usefull for debugging
1597
if (parm->xmb->eTagFound) {
1598
parm->xmb->eTagFound = 0;
1599
return parm->xmb->etag;
1603
for (i = 0; i < TAGS_NITEMS; i++) {
1604
if (nextEquals(next + 1, tags[i].tag, tags[i].tagLen) == 1) {
1606
return tags[i].etag;
1612
if (strncmp(parm->xmb->cur, "<!--", 4) == 0) {
1613
parm->xmb->cur = strstr(parm->xmb->cur, "-->") + 3;
1616
if (strncmp(parm->xmb->cur, "<EC>", 4) == 0) {
1617
parm->econ->asynRCntl.escanInfo.getnew = 1 ;
1618
parm->econ->asynRCntl.escanInfo.parsestate = PARSTATE_STARTED ;
1621
for (i = 0; i < TAGS_NITEMS; i++) {
1622
if (nextEquals(next, tags[i].tag, tags[i].tagLen) == 1) {
1623
// printf("+++ %d\n",i);
1624
rc=tags[i].process(lvalp, parm);
1634
char * getNextSection(struct _CMCIConnection * con)
1637
char * workptr = NULL;
1638
char * curptr = NULL;
1645
* free that old buffer
1648
if(con->asynRCntl.escanInfo.section != NULL) {
1649
free(con->asynRCntl.escanInfo.section);
1650
con->asynRCntl.escanInfo.section = NULL ;
1653
if((retcode = pthread_mutex_lock(&(con->asynRCntl.escanlock))) != 0){
1654
printf(" getNextSection pthread lock return code %d\n",retcode) ;
1658
* If we have no more new data from the server , we
1659
* unlock and sleep then check till we see that we have
1663
while(con->asynRCntl.escanInfo.prevtotl == con->asynRCntl.escanInfo.recdtotl){
1664
if((retcode = pthread_mutex_unlock(&(con->asynRCntl.escanlock))) != 0){
1665
printf(" getNextSection pthread lock return code %d\n",retcode) ;
1667
/* *******************************************
1668
* *******************************************
1669
* timeout toval keeps us from hanging forever
1670
* *******************************************
1671
* *******************************************
1677
longjmp (save_env, 1);
1679
if(con->asynRCntl.escanInfo.prevtotl != con->asynRCntl.escanInfo.recdtotl){
1681
* we got more data , exit this loop
1683
if((retcode = pthread_mutex_lock(&(con->asynRCntl.escanlock))) != 0){
1684
printf(" getNextSection pthread lock return code %d\n",retcode) ;
1690
if((con->asynRCntl.xfer_state == XFER_DATA_RECVD) ||
1691
(con->asynRCntl.xfer_state == XFER_COMPLETE) ) {
1693
workptr = LASTPTR(&(con->asynRCntl.escanInfo)) ;
1694
curptr = CURPTR(&(con->asynRCntl.escanInfo));
1696
con->asynRCntl.escanInfo.ssecoff = con->asynRCntl.escanInfo.curoff ;
1699
while(workptr > curptr) {
1700
if(*workptr == '>'){
1701
tagval = checkTag(workptr , con->asynRCntl.eMethodType) ;
1703
con->asynRCntl.escanInfo.curoff = con->asynRCntl.escanInfo.curoff + (workptr - curptr) + 1 ;
1704
xmlblen = ((workptr - curptr) + 5) ;
1706
xmlb = malloc(xmlblen + 64) ;
1707
con->asynRCntl.escanInfo.section = xmlb ;
1709
con->asynRCntl.escanInfo.sectlen = xmlblen + 5 ;
1710
memset(xmlb , 0x0cc , xmlblen + 5) ;
1713
memcpy(xmlb , SSECPTR(&con->asynRCntl.escanInfo) , xmlblen) ;
1714
strcpy((xmlb+(xmlblen - 4)) , "<EC>") ;
1715
con->asynRCntl.escanInfo.getnew = 0 ;
1718
/* getNextSection xmlb is NULL !!! This is bad */
1721
con->asynRCntl.escanInfo.prevtotl = con->asynRCntl.escanInfo.recdtotl ;
1723
if((retcode = pthread_mutex_unlock(&(con->asynRCntl.escanlock))) != 0){
1724
printf(" getNextSection pthread lock return code %d\n",retcode) ;
1729
* backup before this tag
1731
workptr = workptr - tagval ;
1732
if(workptr <= curptr){
1733
if (con->asynRCntl.escanInfo.prevtotl != con->asynRCntl.escanInfo.recdtotl){
1734
pthread_mutex_unlock(&(con->asynRCntl.escanlock));
1738
longjmp (save_env, 2);
1739
pthread_mutex_lock(&(con->asynRCntl.escanlock));
1740
workptr = LASTPTR(&(con->asynRCntl.escanInfo)) ;
1741
curptr = CURPTR(&(con->asynRCntl.escanInfo));
1748
if(workptr <= curptr){
1749
if (con->asynRCntl.escanInfo.prevtotl != con->asynRCntl.escanInfo.recdtotl){
1750
workptr = LASTPTR(&(con->asynRCntl.escanInfo)) ;
1751
curptr = CURPTR(&(con->asynRCntl.escanInfo));
1758
if((retcode = pthread_mutex_unlock(&(con->asynRCntl.escanlock))) != 0){
1759
printf(" getNextSection pthread unlock return code %d\n",retcode) ;
1764
* check to see if the ending tag is at a
1765
* place in the data that we can use to
1766
* start parsing. The parsing needs to be
1767
* given certain chunks of the data based on
1768
* the request we are processing.
1769
* If we see </CIM> thats good , we are
1770
* at the end of the data.
1771
* return 0 if ending tag is OK
1772
* return >0 if ending tag is not OK
1774
* VALUE.NAMEDINSTANCE
1779
int checkTag(char * wrkptr , int methodtype ) {
1780
char * workptr = wrkptr ;
1784
memset(&temptag[0] , 00 , 119) ;
1788
while(*workptr != '<'){
1794
if (strncmp(workptr , "</CIM>", 6) == 0) {
1798
switch(methodtype) {
1799
case ENUMERATEINSTANCES:
1800
if (strncmp(workptr , "</VALUE.NAMEDINSTANCE>", 22) == 0) {
1804
case ENUMERATEINSTANCENAMES:
1805
if (strncmp(workptr , "</INSTANCENAME>", 15) == 0) {
1809
case ENUMERATECLASSES:
1810
if (strncmp(workptr , "</CLASS>", 8) == 0) {
1814
case ENUMERATECLASSNAMES:
1815
if (strncmp(workptr , "<CLASSNAME ", 11) == 0) {
1822
* return the length of this tag
1824
strncpy(&temptag[0] , workptr , taglength) ;