~ubuntu-branches/ubuntu/utopic/sblim-sfcc/utopic-proposed

« back to all changes in this revision

Viewing changes to backend/cimxml/cimXmlParser.c

  • Committer: Package Import Robot
  • Author(s): Kent Baxley
  • Date: 2013-12-16 15:29:54 UTC
  • mfrom: (1.1.5)
  • Revision ID: package-import@ubuntu.com-20131216152954-a56rjd1wzcq1yz4j
Tags: 2.2.6-0ubuntu1
New upstream release

Show diffs side-by-side

added added

removed removed

Lines of Context:
34
34
 
35
35
#include <pthread.h>
36
36
 
37
 
#ifdef LARGE_VOL_SUPPORT
38
 
 
39
 
// New begin
40
 
#include <curl/curl.h>         // new
41
 
#include <time.h>              // new
42
 
#include <sys/time.h>          // new
43
 
#include <setjmp.h>            // new
44
 
 
45
 
struct _CMCIConnectionFT;                           // new 
46
 
typedef struct _CMCIConnectionFT CMCIConnectionFT;  // new
47
 
 
48
 
char * getNextSection(struct _CMCIConnection * ) ;
49
 
int checkTag(char * , int ) ;
50
 
 
51
 
#include "cmci.h"
52
 
#include "utilStringBuffer.h"  // new
53
 
#include "cimXmlParser.h"      // new
54
 
#include "native.h"            // new
55
 
#include "esinfo.h"            // new
56
 
#include "conn.h"              // new
57
 
 
58
 
jmp_buf save_env ;
59
 
 
60
 
/*
61
 
 * response data helper functions.
62
 
 */
63
 
inline char * CURPTR (enumScanInfo * esi ){
64
 
 return(((char*)(esi->base)) + (esi->curoff)) ;
65
 
}
66
 
inline char * SSECPTR (enumScanInfo * esi ){
67
 
 return(((char*)(esi->base)) + (esi->ssecoff)) ;
68
 
}
69
 
inline char * LASTPTR (enumScanInfo * esi ){
70
 
 return(((char*)(esi->base)) + (esi->eodoff)) ;
71
 
}
72
 
inline void INCOFF (enumScanInfo * esi ){
73
 
 (esi->curoff)++ ;      
74
 
}
75
 
 
76
 
int sfccFreeSection(ParserControl * );
77
 
void * enumScanThrd(struct native_enum *);
78
 
int sfccLex(parseUnion * , ParserControl * );
79
 
char * getNextSection(struct _CMCIConnection * );
80
 
int checkTag(char * , int );
81
 
 
82
 
#endif /* endif LARGE_VOL_SUPPORT */
83
 
 
84
37
static int attrsOk(XmlBuffer * xb, const XmlElement * e, XmlAttr * r,
85
38
                   const char *tag, int etag);
86
39
static char *getValue(XmlBuffer * xb, const char *v);
1319
1272
};
1320
1273
#define TAGS_NITEMS     (int)(sizeof(tags)/sizeof(Tags))
1321
1274
 
1322
 
#ifndef LARGE_VOL_SUPPORT
1323
 
 
1324
1275
int sfccLex(parseUnion * lvalp, ParserControl * parm)
1325
1276
{
1326
1277
   int i, rc;
1363
1314
   }
1364
1315
   return 0;
1365
1316
}
1366
 
#endif
1367
1317
 
1368
1318
static pthread_mutex_t scan_mutex = PTHREAD_MUTEX_INITIALIZER;
1369
1319
 
1486
1436
  }
1487
1437
}
1488
1438
 
1489
 
#if LARGE_VOL_SUPPORT
1490
 
 
1491
 
/* **************************************************************************/
1492
 
/* **************************************************************************/
1493
 
/* **************************************************************************/
1494
 
/* **************************************************************************/
1495
 
/* **************************************************************************/
1496
 
/* **************************************************************************/
1497
 
/* **************************************************************************/
1498
 
int sfccFreeSection(ParserControl * parm)
1499
 
{
1500
 
   if(parm->econ->asynRCntl.escanInfo.section){                       
1501
 
            free(parm->econ->asynRCntl.escanInfo.section) ;
1502
 
                  parm->econ->asynRCntl.escanInfo.section = NULL ;
1503
 
   }    
1504
 
}
1505
 
#define TIMEDELAY 10 
1506
 
void * enumScanThrd(struct native_enum *NatEnum)
1507
 
{
1508
 
   CMCIConnection * con = NatEnum->econ ; /* enumeration */
1509
 
   CMPIObjectPath * cop = NatEnum->ecop ; /* enumeration */ 
1510
 
   
1511
 
   struct          timespec tp ;
1512
 
         int             rc = 0 ;
1513
 
   
1514
 
   ParserControl control;
1515
 
   struct native_enum  *local_enmp ;
1516
 
   
1517
 
   memset(&control,0,sizeof(control));
1518
 
  
1519
 
   /* 
1520
 
    * get the data array and save a copy of address in enumeration 
1521
 
    */
1522
 
    
1523
 
   XmlBuffer *xmb = newXmlBuffer(NULL);
1524
 
   control.xmb = xmb;
1525
 
   control.respHdr.xmlBuffer = xmb;
1526
 
    
1527
 
   control.respHdr.rvArray=newCMPIArray(0,0,NULL);
1528
 
 
1529
 
   local_enmp = con->asynRCntl.enmp ;
1530
 
   
1531
 
   local_enmp->data = control.respHdr.rvArray ;
1532
 
   
1533
 
   control.requestObjectPath = cop;
1534
 
 
1535
 
   control.heap = parser_heap_init();
1536
 
 
1537
 
   control.econ = con ;
1538
 
     
1539
 
   if(rc = setjmp(save_env)) {
1540
 
      printf(" we had a timeout , we are going to exit from here \n") ;
1541
 
      con->asynRCntl.escanInfo.parsestate = PARSTATE_SERVER_TIMEOUT ;
1542
 
      con->asynRCntl.xfer_state = XFER_ERROR ;
1543
 
      return ;
1544
 
   }
1545
 
   
1546
 
   /*
1547
 
    * wait for first data block received or xfer complete
1548
 
    * we need to have some data before starting
1549
 
    */
1550
 
   while((con->asynRCntl.xfer_state != XFER_DATA_RECVD )&&
1551
 
         (con->asynRCntl.xfer_state != XFER_COMPLETE)){
1552
 
        usleep(100000) ;
1553
 
   }
1554
 
       
1555
 
   control.respHdr.rc = startParsing(&control);
1556
 
     
1557
 
   /*
1558
 
    * releaseXmlBuffer free's that last con->asynRCntl.escanInfo.section 
1559
 
    * we clear out that pointer just to be safe
1560
 
    */
1561
 
   releaseXmlBuffer(xmb);
1562
 
   
1563
 
   con->asynRCntl.escanInfo.section = 0 ;
1564
 
   
1565
 
   parser_heap_term(control.heap);
1566
 
   
1567
 
   con->asynRCntl.escanInfo.parsestate = PARSTATE_COMPLETE ;
1568
 
    
1569
 
}
1570
 
 
1571
 
int sfccLex(parseUnion * lvalp, ParserControl * parm)
1572
 
{
1573
 
   int i, rc;
1574
 
   char *next;
1575
 
   char *nextSection ;
1576
 
 
1577
 
   for (;;) {
1578
 
        
1579
 
          if(parm->econ) {
1580
 
             
1581
 
             if(parm->econ->asynRCntl.escanInfo.getnew == 1 ){
1582
 
            
1583
 
            nextSection = getNextSection(parm->econ) ;
1584
 
            if(nextSection != NULL) {
1585
 
               parm->xmb->base = nextSection ;
1586
 
               parm->xmb->cur  = nextSection ;
1587
 
               parm->xmb->last = nextSection + (parm->econ->asynRCntl.escanInfo.sectlen) ;
1588
 
 
1589
 
         } else {
1590
 
              printf(" sfccLex --- section is NULL !!!!!!!!!!!!!!!!! \n") ;
1591
 
         }
1592
 
         }
1593
 
      }
1594
 
      
1595
 
      
1596
 
      next = nextTag(parm->xmb);
1597
 
      if (next == NULL) {
1598
 
         return 0;
1599
 
      }
1600
 
//      fprintf(stderr,"--- token: %.32s\n",next); //usefull for debugging
1601
 
      if (parm->xmb->eTagFound) {
1602
 
         parm->xmb->eTagFound = 0;
1603
 
         return parm->xmb->etag;
1604
 
      }
1605
 
 
1606
 
      if (*next == '/') {
1607
 
         for (i = 0; i < TAGS_NITEMS; i++) {
1608
 
            if (nextEquals(next + 1, tags[i].tag, tags[i].tagLen) == 1) {
1609
 
               skipTag(parm->xmb);
1610
 
               return tags[i].etag;
1611
 
            }
1612
 
         }
1613
 
      }
1614
 
 
1615
 
      else {
1616
 
         if (strncmp(parm->xmb->cur, "<!--", 4) == 0) {
1617
 
            parm->xmb->cur = strstr(parm->xmb->cur, "-->") + 3;
1618
 
            continue;
1619
 
         } else
1620
 
         if (strncmp(parm->xmb->cur, "<EC>", 4) == 0) {
1621
 
            parm->econ->asynRCntl.escanInfo.getnew = 1 ;
1622
 
            parm->econ->asynRCntl.escanInfo.parsestate = PARSTATE_STARTED ; 
1623
 
            continue;
1624
 
         } 
1625
 
         for (i = 0; i < TAGS_NITEMS; i++) {
1626
 
            if (nextEquals(next, tags[i].tag, tags[i].tagLen) == 1) {
1627
 
//             printf("+++ %d\n",i);
1628
 
               rc=tags[i].process(lvalp, parm);
1629
 
               return rc;
1630
 
            }
1631
 
         }
1632
 
      }
1633
 
      break;
1634
 
   }
1635
 
   return 0;
1636
 
}
1637
 
 
1638
 
char * getNextSection(struct _CMCIConnection * con)
1639
 
{
1640
 
        char * xmlb    = NULL;
1641
 
  char * workptr = NULL;
1642
 
  char * curptr  = NULL;
1643
 
  int    xmlblen = 0;
1644
 
  int    tagval  = 0;
1645
 
  int    retcode = 0; 
1646
 
  int    toval   = 0;
1647
 
  
1648
 
   /*
1649
 
    * free that old buffer 
1650
 
    */
1651
 
  
1652
 
  if(con->asynRCntl.escanInfo.section != NULL) {
1653
 
     free(con->asynRCntl.escanInfo.section);
1654
 
     con->asynRCntl.escanInfo.section = NULL ;
1655
 
  }
1656
 
  
1657
 
  if((retcode = pthread_mutex_lock(&(con->asynRCntl.escanlock))) != 0){
1658
 
     printf(" getNextSection pthread lock return code %d\n",retcode) ;  
1659
 
  }
1660
 
  
1661
 
  /*
1662
 
   * If we have no more new data from the server , we 
1663
 
   * unlock and sleep then check till we see that we have 
1664
 
   * received new data 
1665
 
   */
1666
 
  
1667
 
  while(con->asynRCntl.escanInfo.prevtotl == con->asynRCntl.escanInfo.recdtotl){
1668
 
     if((retcode = pthread_mutex_unlock(&(con->asynRCntl.escanlock))) != 0){
1669
 
        printf(" getNextSection pthread lock return code %d\n",retcode) ;       
1670
 
     }
1671
 
     /* *******************************************
1672
 
      * ******************************************* 
1673
 
      * timeout toval keeps us from hanging forever
1674
 
      * *******************************************
1675
 
      * *******************************************
1676
 
      */
1677
 
     usleep(1000) ;
1678
 
     toval++ ;
1679
 
 
1680
 
     if(toval>5000) 
1681
 
         longjmp (save_env, 1);
1682
 
     
1683
 
     if(con->asynRCntl.escanInfo.prevtotl != con->asynRCntl.escanInfo.recdtotl){
1684
 
          /* 
1685
 
           * we got more data , exit this loop
1686
 
           */
1687
 
        if((retcode = pthread_mutex_lock(&(con->asynRCntl.escanlock))) != 0){
1688
 
             printf(" getNextSection pthread lock return code %d\n",retcode) ;  
1689
 
        }
1690
 
        break;
1691
 
     }   
1692
 
  }
1693
 
 
1694
 
  if((con->asynRCntl.xfer_state == XFER_DATA_RECVD) ||
1695
 
     (con->asynRCntl.xfer_state == XFER_COMPLETE)       )    {
1696
 
 
1697
 
     workptr = LASTPTR(&(con->asynRCntl.escanInfo)) ;
1698
 
     curptr  = CURPTR(&(con->asynRCntl.escanInfo));
1699
 
  
1700
 
     con->asynRCntl.escanInfo.ssecoff = con->asynRCntl.escanInfo.curoff ;
1701
 
     
1702
 
     toval = 0;
1703
 
     while(workptr > curptr) {   
1704
 
        if(*workptr == '>'){
1705
 
                 tagval = checkTag(workptr , con->asynRCntl.eMethodType) ;
1706
 
                 if(tagval == 0){
1707
 
              con->asynRCntl.escanInfo.curoff = con->asynRCntl.escanInfo.curoff + (workptr - curptr) + 1 ;
1708
 
              xmlblen = ((workptr - curptr) + 5) ;
1709
 
           
1710
 
              xmlb = malloc(xmlblen + 64) ;
1711
 
              con->asynRCntl.escanInfo.section = xmlb ;
1712
 
 
1713
 
              con->asynRCntl.escanInfo.sectlen = xmlblen + 5 ;
1714
 
              memset(xmlb , 0x0cc , xmlblen + 5) ;
1715
 
                                   
1716
 
              if(xmlb != NULL){
1717
 
                 memcpy(xmlb , SSECPTR(&con->asynRCntl.escanInfo) , xmlblen) ;
1718
 
                 strcpy((xmlb+(xmlblen - 4)) , "<EC>") ;
1719
 
                 con->asynRCntl.escanInfo.getnew = 0 ;
1720
 
 
1721
 
              } else {
1722
 
                     /* getNextSection xmlb is NULL !!! This is bad */
1723
 
              }
1724
 
                           
1725
 
              con->asynRCntl.escanInfo.prevtotl = con->asynRCntl.escanInfo.recdtotl ;
1726
 
 
1727
 
              if((retcode =  pthread_mutex_unlock(&(con->asynRCntl.escanlock))) != 0){
1728
 
                 printf(" getNextSection pthread lock return code %d\n",retcode) ;      
1729
 
              }
1730
 
              return(xmlb) ;
1731
 
          } else {
1732
 
                  /* 
1733
 
                   * backup before this tag 
1734
 
                   */
1735
 
              workptr = workptr - tagval ;
1736
 
              if(workptr <= curptr){
1737
 
                 if (con->asynRCntl.escanInfo.prevtotl != con->asynRCntl.escanInfo.recdtotl){
1738
 
                          pthread_mutex_unlock(&(con->asynRCntl.escanlock));
1739
 
                          usleep(1000) ;
1740
 
                          toval++ ;
1741
 
                          if(toval > 5000)
1742
 
                             longjmp (save_env, 2);
1743
 
                          pthread_mutex_lock(&(con->asynRCntl.escanlock));
1744
 
                    workptr = LASTPTR(&(con->asynRCntl.escanInfo)) ;
1745
 
                    curptr  = CURPTR(&(con->asynRCntl.escanInfo));                      
1746
 
                 }
1747
 
              }
1748
 
              continue;
1749
 
          }
1750
 
        } else {
1751
 
           workptr-- ;
1752
 
           if(workptr <= curptr){
1753
 
              if (con->asynRCntl.escanInfo.prevtotl != con->asynRCntl.escanInfo.recdtotl){
1754
 
                 workptr = LASTPTR(&(con->asynRCntl.escanInfo)) ;
1755
 
                 curptr  = CURPTR(&(con->asynRCntl.escanInfo));
1756
 
              }
1757
 
           }
1758
 
        }
1759
 
     }
1760
 
  }
1761
 
  
1762
 
  if((retcode =  pthread_mutex_unlock(&(con->asynRCntl.escanlock))) != 0){
1763
 
     printf(" getNextSection pthread unlock return code %d\n",retcode) ;        
1764
 
  }
1765
 
  return(NULL) ;
1766
 
}
1767
 
/*
1768
 
 * check to see if the ending tag is at a 
1769
 
 * place in the data that we can use to 
1770
 
 * start parsing. The parsing needs to be
1771
 
 * given certain chunks of the data based on 
1772
 
 * the request we are processing. 
1773
 
 * If we see </CIM> thats good , we are 
1774
 
 * at the end of the data.
1775
 
 * return 0 if ending tag is OK
1776
 
 * return >0 if ending tag is not OK   
1777
 
 * CIM 
1778
 
 * VALUE.NAMEDINSTANCE
1779
 
 * CLASSNAME
1780
 
 *
1781
 
 */
1782
 
 
1783
 
int checkTag(char * wrkptr , int methodtype ) {
1784
 
char * workptr = wrkptr ;
1785
 
char temptag[120] ;
1786
 
int  taglength = 1 ;
1787
 
 
1788
 
   memset(&temptag[0] , 00 , 119) ;
1789
 
   /*
1790
 
    * find start of tag 
1791
 
    */
1792
 
   while(*workptr != '<'){ 
1793
 
      workptr-- ;
1794
 
      taglength++ ;
1795
 
   }
1796
 
                 
1797
 
         
1798
 
         if (strncmp(workptr , "</CIM>", 6) == 0) {
1799
 
                  return(0) ;
1800
 
         }
1801
 
         
1802
 
  switch(methodtype) {
1803
 
     case ENUMERATEINSTANCES:
1804
 
        if (strncmp(workptr , "</VALUE.NAMEDINSTANCE>", 22) == 0) {
1805
 
           return(0) ;
1806
 
        }
1807
 
        break ;
1808
 
     case ENUMERATEINSTANCENAMES:       
1809
 
          if (strncmp(workptr , "</INSTANCENAME>", 15) == 0) {
1810
 
           return(0) ;
1811
 
        }
1812
 
        break;
1813
 
     case ENUMERATECLASSES:
1814
 
          if (strncmp(workptr , "</CLASS>", 8) == 0) {
1815
 
           return(0) ;
1816
 
        }
1817
 
        break;
1818
 
     case ENUMERATECLASSNAMES:
1819
 
          if (strncmp(workptr , "<CLASSNAME ", 11) == 0) {
1820
 
           return(0) ;
1821
 
        }
1822
 
        break;  
1823
 
         }
1824
 
            
1825
 
         /*
1826
 
          * return the length of this tag 
1827
 
          */
1828
 
         strncpy(&temptag[0] , workptr , taglength) ;
1829
 
         return(taglength) ;
1830
 
                
1831
 
}
1832
 
 
1833
 
#endif
 
1439
 
1834
1440