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

« back to all changes in this revision

Viewing changes to backend/cimxml/client.c

  • Committer: Bazaar Package Importer
  • Author(s): Thierry Carrez
  • Date: 2009-08-19 14:41:55 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20090819144155-jb46y5kmluacii70
Tags: 2.2.0-0ubuntu1
* New upstream version.
* debian/libcimcclient0.install: Ship missing libcmpisfcc library
* debian/control:
  - Switch to libcurl4-openssl-dev to match the rest of the SBLIM stack
  - Bump debhelper depend to >=5 to match debian/compat
  - Fix section names, add missing ${misc:Depends}
* debian/copyright: Add missing copyright notice
* debian/rules: Removed spurious DH_MAKESHLIBS argument

Show diffs side-by-side

added added

removed removed

Lines of Context:
2
2
/*
3
3
 * client.c
4
4
 *
5
 
 * (C) Copyright IBM Corp. 2005
6
 
 * (C) Copyright Intel Corp. 2005
 
5
 * © Copyright IBM Corp. 2005, 2007
 
6
 * © Copyright Intel Corp. 2005
7
7
 *
8
8
 * THIS FILE IS PROVIDED UNDER THE TERMS OF THE ECLIPSE PUBLIC LICENSE
9
9
 * ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS FILE
20
20
 *
21
21
 */
22
22
 
 
23
#include <stdlib.h>
 
24
#include <string.h>
 
25
#include <pthread.h>
 
26
#include <curl/curl.h>
 
27
 
 
28
#include <time.h>              // new
 
29
#include <sys/time.h>          // new
 
30
 
23
31
#include "config.h"
24
32
 
25
33
#include "cmci.h"
27
35
#include "native.h"
28
36
 
29
37
#include "cimc.h"
30
 
 
31
 
#include <stdlib.h>
32
 
#include <string.h>
33
 
#include <curl/curl.h>
 
38
#include "nativeCimXml.h"
 
39
 
 
40
#ifndef LARGE_VOL_SUPPORT 
 
41
typedef const struct _CMCIConnectionFT {
 
42
    CMPIStatus (*release) (CMCIConnection *);
 
43
    char *(*genRequest)(ClientEnc *cle, const char *op, CMPIObjectPath *cop,
 
44
                                                  int classWithKeys);
 
45
    char *(*addPayload)(CMCIConnection *, UtilStringBuffer *pl);
 
46
    char *(*getResponse)(CMCIConnection *con, CMPIObjectPath *cop);   
 
47
    void (*initializeHeaders)(CMCIConnection *con);
 
48
    void (*reset)(CMCIConnection *);
 
49
} CMCIConnectionFT;
 
50
#else
 
51
 
 
52
#include "esinfo.h"
 
53
#define TIMEDELAY 10 
 
54
void * enumScanThrd(struct native_enum *) ;
 
55
 
 
56
static CMPIEnumeration * enumInstances(CMCIClient * ,
 
57
                                       CMPIObjectPath *,
 
58
                                       CMPIFlags ,
 
59
                                       char ** ,
 
60
                                       CMPIStatus * );
 
61
static CMPIEnumeration * enumInstanceNames(CMCIClient * ,
 
62
                                           CMPIObjectPath * ,
 
63
                                           CMPIStatus * ) ;
 
64
static CMPIEnumeration * enumClasses(CMCIClient * ,
 
65
                                     CMPIObjectPath * ,
 
66
                                     CMPIFlags ,
 
67
                                     CMPIStatus * ) ;
 
68
static CMPIEnumeration* enumClassNames(CMCIClient * ,
 
69
                                       CMPIObjectPath * ,
 
70
                                       CMPIFlags ,
 
71
                                       CMPIStatus *);
 
72
static char* genEnumRequest(ClientEnc * , const char * , CMPIObjectPath * , int ) ;
 
73
char *getEnumResponse(CMCIConnection * , CMPIObjectPath *) ;
 
74
static size_t enumWriteHeaders(void *, size_t , size_t , void *);                 
 
75
static size_t enumWriteCb(void *, size_t , size_t , void *) ;
 
76
void initEscanInfo(CMCIConnection * ) ;
 
77
static int enumCheckProgress(void * , double , double , double , double );
 
78
 
 
79
typedef const struct _CMCIConnectionFT {
 
80
    CMPIStatus (*release) (CMCIConnection *);
 
81
    char *(*genRequest)(ClientEnc *cle, const char *op, CMPIObjectPath *cop,
 
82
                                                  int classWithKeys);
 
83
    char *(*genEnumRequest)(ClientEnc *cle, const char *op, CMPIObjectPath *cop,
 
84
                                                  int classWithKeys);   
 
85
    char *(*addPayload)(CMCIConnection *, UtilStringBuffer *pl);
 
86
    char *(*getResponse)(CMCIConnection *con, CMPIObjectPath *cop);
 
87
    char *(*getEnumResponse)(CMCIConnection *con, CMPIObjectPath *cop);    
 
88
    void (*initializeHeaders)(CMCIConnection *con);
 
89
    void (*reset)(CMCIConnection *);
 
90
} CMCIConnectionFT;
 
91
                      
 
92
#endif /* endif LARGE_VOL_SUPPORT */
 
93
 
 
94
#include "conn.h"
 
95
 
34
96
#include "cimXmlParser.h"
35
97
 
36
98
#define CIMSERVER_TIMEOUT       (10 * 60) /* 10 minutes max per operation */
49
111
void list2StringBuffer(UtilStringBuffer *sb, UtilList *ul, char *sep);
50
112
char *getResponse(CMCIConnection *con, CMPIObjectPath *cop);
51
113
CMCIConnection *initConnection(CMCIClientData *cld);
 
114
static void addXmlReference(UtilStringBuffer *sb, CMPIObjectPath * cop);
52
115
 
53
116
extern UtilList *getNameSpaceComponents(CMPIObjectPath * cop);
54
117
extern void pathToXml(UtilStringBuffer *sb, CMPIObjectPath *cop);
75
138
#else
76
139
#define SET_DEBUG()
77
140
#endif
 
141
/*
 
142
 * for large volume data http transfer encoding chunked  
 
143
 */
 
144
 
 
145
pthread_mutex_t init_mutex = PTHREAD_MUTEX_INITIALIZER;
 
146
pthread_cond_t  init_cond  = PTHREAD_COND_INITIALIZER;
 
147
 
78
148
 
79
149
//#if TIMING
80
150
#if 0
115
185
static const char EnumerateClassNames[] = "EnumerateClassNames";
116
186
static const char EnumerateClasses[] = "EnumerateClasses";
117
187
 
118
 
typedef const struct _CMCIConnectionFT {
119
 
    CMPIStatus (*release) (CMCIConnection *);
120
 
    char *(*genRequest)(ClientEnc *cle, const char *op, CMPIObjectPath *cop,
121
 
                                                  int classWithKeys);
122
 
    char *(*addPayload)(CMCIConnection *, UtilStringBuffer *pl);
123
 
    char *(*getResponse)(CMCIConnection *con, CMPIObjectPath *cop);
124
 
    void (*initializeHeaders)(CMCIConnection *con);
125
 
    void (*reset)(CMCIConnection *);
126
 
} CMCIConnectionFT;
127
188
 
128
189
struct _ClientEnc {
129
190
   CMCIClient          enc;
135
196
#define MAX_PLAUSIBLE_PROGRESS 30
136
197
#define MAX_PROGRESS_FIXUPS    10
137
198
 
138
 
struct _TimeoutControl {
139
 
  time_t   mTimestampStart;
140
 
  time_t   mTimestampLast;
141
 
  unsigned mFixups;
142
 
};
143
199
 
144
 
struct _CMCIConnection {
145
 
    CMCIConnectionFT *ft;        
146
 
    CURL *mHandle;               // The handle to the curl object
147
 
    struct curl_slist *mHeaders; // The list of headers sent with each request
148
 
    UtilStringBuffer *mBody;     // The body of the request
149
 
    UtilStringBuffer *mUri;      // The uri of the request
150
 
    UtilStringBuffer *mUserPass; // The username/password used in authentication
151
 
    UtilStringBuffer *mResponse; // Used to store the HTTP response
152
 
    CMPIStatus        mStatus;   // returned request status (via HTTP trailers)               
153
 
    struct _TimeoutControl mTimeout; /* Used for timeout control */
154
 
};
155
200
 
156
201
/* --------------------------------------------------------------------------*/
157
202
 
212
257
    *colonidx=0;
213
258
    if (strcasecmp(str,"cimstatuscode") == 0) {
214
259
      /* set status code */
215
 
      status->rc = atoi(colonidx+1);
 
260
      status->rc = atoi(colonidx+1);       
 
261
    } else {
 
262
        if (strcasecmp(str, "cimstatuscodedescription") == 0) {
 
263
           status->msg=newCMPIString(colonidx+1,NULL);
216
264
      }
217
 
      else
218
 
      if (strcasecmp(str, "cimstatuscodedescription") == 0) {
219
 
      status->msg=newCMPIString(colonidx+1,NULL);
220
265
    }
221
266
  }
222
267
  free(str);
223
268
  return nmemb;
224
269
}
225
270
 
226
 
/* --------------------------------------------------------------------------*/
227
271
 
228
272
static size_t writeCb(void *ptr, size_t size,
229
273
                                        size_t nmemb, void *stream)
291
335
  free(con);
292
336
  return rc;
293
337
}
294
 
 
295
338
/* --------------------------------------------------------------------------*/
296
339
 
297
340
static char *addPayload(CMCIConnection *con, UtilStringBuffer *pl)
313
356
 
314
357
/* --------------------------------------------------------------------------*/
315
358
 
 
359
/* --------------------------------------------------------------------------*/
 
360
 
316
361
static char* genRequest(ClientEnc *cle, const char *op,
317
362
                        CMPIObjectPath *cop, int classWithKeys)
318
363
{
425
470
 
426
471
   return NULL;
427
472
}
428
 
 
429
473
/* --------------------------------------------------------------------------*/
430
474
 
431
475
char *getResponse(CMCIConnection *con, CMPIObjectPath *cop)
454
498
    return NULL;
455
499
}
456
500
 
 
501
 
 
502
/* --------------------------------------------------------------------------*/
 
503
 
 
504
 
457
505
/* --------------------------------------------------------------------------*/
458
506
 
459
507
static void initializeHeaders(CMCIConnection *con)
467
515
#ifdef HAVE_HTTP_CHUNKING
468
516
        "TE: trailers",
469
517
#endif
 
518
 
470
519
        NULL
471
520
    };
472
521
    unsigned int i;
478
527
    for (i = 0; headers[i]!= NULL; i++)
479
528
        con->mHeaders = curl_slist_append(con->mHeaders, headers[i]);
480
529
}
481
 
 
482
 
static CMCIConnectionFT conFt={
483
 
  releaseConnection,
484
 
  genRequest,
485
 
  addPayload,
486
 
  getResponse,
487
 
  initializeHeaders
488
 
};
 
530
#ifndef LARGE_VOL_SUPPORT
 
531
static CMCIConnectionFT conFt={
 
532
  releaseConnection,
 
533
  genRequest,
 
534
  addPayload,
 
535
  getResponse,
 
536
  initializeHeaders
 
537
};
 
538
#else 
 
539
static CMCIConnectionFT conFt={
 
540
  releaseConnection,
 
541
  genRequest,
 
542
  genEnumRequest,
 
543
  addPayload,
 
544
  getResponse,
 
545
  getEnumResponse,
 
546
  initializeHeaders
 
547
};
 
548
#endif
489
549
 
490
550
/* --------------------------------------------------------------------------*/
491
551
 
492
552
CMCIConnection *initConnection(CMCIClientData *cld)
493
553
{
494
554
   CMCIConnection *c=(CMCIConnection*)calloc(1,sizeof(CMCIConnection));
 
555
 
495
556
   c->ft=&conFt;
496
557
   c->mHandle = curl_easy_init();
497
558
   c->mHeaders = NULL;
518
579
     {0x3c, "&lt;",     4},     /* '<' */
519
580
     {0x3e, "&gt;",     4},     /* '>' */
520
581
};
521
 
 
 
582
#define LargestXmlEscapeSize 6 /* From above */
522
583
#define SizeofXmlEscapes (sizeof(XmlEscapes)/sizeof(XmlSpecialChar))
523
584
 
524
585
char XmlToAscii(char **XmlStr);
560
621
 
561
622
char * AsciiToXmlStr(char *AsciiStr)
562
623
{
563
 
    char *Ap;
564
 
    char *XmlStr; 
 
624
    char *Ap = NULL;
 
625
    char *XmlStr = NULL; 
565
626
    int  Xlen;
566
627
    int  i;
567
 
    size_t buflen;
 
628
    int buflen;
568
629
    if (AsciiStr) {
569
630
      buflen = strlen(AsciiStr) + 1;
570
631
      XmlStr = malloc(buflen);
571
632
    }
572
633
    if (XmlStr) {
573
 
      Xlen = 0;
574
 
      for (Ap = AsciiStr; *Ap != '\0'; Ap++)
575
 
        {
576
 
          for (i = 0; i < SizeofXmlEscapes; ++i)
577
 
            if (*Ap == XmlEscapes[i].XmlAscii)
578
 
              break;
579
 
          if (i < SizeofXmlEscapes)
580
 
            {
581
 
              if (buflen - Xlen <= XmlEscapes[i].XmlEscapeSize) {
582
 
                buflen = 2 * buflen;
583
 
                XmlStr = realloc(XmlStr,buflen);
584
 
                if (XmlStr == NULL) {
585
 
                  break;
586
 
                }
587
 
              }
588
 
              memcpy(XmlStr + Xlen, XmlEscapes[i].XmlEscape, XmlEscapes[i].XmlEscapeSize);
589
 
              Xlen += XmlEscapes[i].XmlEscapeSize;
590
 
            }
591
 
          else
592
 
            XmlStr[Xlen++] = *Ap;
593
 
        }
594
 
      XmlStr[Xlen] = '\0';
 
634
        Xlen = 0;
 
635
        for (Ap = AsciiStr; *Ap != '\0'; Ap++)
 
636
        {
 
637
            for (i = 0; i < SizeofXmlEscapes; ++i)
 
638
                if (*Ap == XmlEscapes[i].XmlAscii)
 
639
                    break;
 
640
 
 
641
            if (buflen <= Xlen + LargestXmlEscapeSize) {
 
642
                buflen = 2 * buflen;
 
643
                XmlStr = realloc(XmlStr,buflen);
 
644
                if (XmlStr == NULL) {
 
645
                    break;
 
646
                }
 
647
            }
 
648
 
 
649
            if (i < SizeofXmlEscapes)
 
650
            {
 
651
                memcpy(XmlStr + Xlen, XmlEscapes[i].XmlEscape, XmlEscapes[i].XmlEscapeSize);
 
652
                Xlen += XmlEscapes[i].XmlEscapeSize;
 
653
            }
 
654
            else
 
655
                XmlStr[Xlen++] = *Ap;
 
656
        }
 
657
        XmlStr[Xlen] = '\0';
595
658
    }
596
659
    return XmlStr;
597
660
}
660
723
        sb->ft->appendChars(sb, ContainerTag);
661
724
    }
662
725
    sb->ft->append3Chars(sb, " NAME=\"", ValueName, "\"");
663
 
    if (xmlTypeStr)
 
726
    if (ContainerType && xmlTypeStr)
664
727
        sb->ft->append5Chars(sb, " ", ContainerType, "=\"", xmlTypeStr, "\"");
665
728
    sb->ft->appendChars(sb, ">\n");
666
729
    if (isArray)
672
735
            CMPIData ele = CMGetArrayElementAt(arr, i, NULL);
673
736
            cv = value2Chars(valtyp, &ele.value);
674
737
            if (valtyp == CMPI_string || valtyp == CMPI_chars)
675
 
{
 
738
            {
676
739
                char *xmlValStr  = AsciiToXmlStr(cv);
677
740
                if (cv) free(cv);
678
741
                cv = xmlValStr;
682
745
        }
683
746
        sb->ft->appendChars(sb, "</VALUE.ARRAY>\n");
684
747
    }
685
 
    else
 
748
    else if (data.type == CMPI_ref)
 
749
    {
 
750
        addXmlReference(sb, data.value.ref);
 
751
    }
 
752
    else 
686
753
    {
687
754
        cv = value2Chars(valtyp, &(data.value));
688
755
        if (valtyp == CMPI_string || valtyp == CMPI_chars)
721
788
 
722
789
/* --------------------------------------------------------------------------*/
723
790
 
 
791
static void addXmlNamespacePath(UtilStringBuffer *sb, CMPIObjectPath *cop)
 
792
{
 
793
  CMPIString * hn;
 
794
  
 
795
  hn = cop->ft->getHostname(cop, NULL);
 
796
  
 
797
  sb->ft->appendChars(sb, "<NAMESPACEPATH>\n");
 
798
  sb->ft->append3Chars(sb, "<HOST>",
 
799
               (hn != NULL && hn->hdl != NULL) ? 
 
800
               (char *)hn->hdl : "localhost",
 
801
               "</HOST>\n");
 
802
  if (hn != NULL)
 
803
    CMRelease(hn);
 
804
  addXmlNamespace(sb, cop);
 
805
  sb->ft->appendChars(sb, "</NAMESPACEPATH>\n");
 
806
}
 
807
/* --------------------------------------------------------------------------*/
 
808
 
724
809
static void addXmlObjectName(UtilStringBuffer *sb, CMPIObjectPath *cop,
725
810
                                              const char *ValueTagName)
726
811
{
788
873
 
789
874
/* --------------------------------------------------------------------------*/
790
875
 
791
 
static void addXmlNamedInstance(UtilStringBuffer *sb,
 
876
static void addXmlReference(UtilStringBuffer *sb,
 
877
                            CMPIObjectPath * cop)
 
878
{
 
879
  CMPIString  *hn, *ns, *name;
 
880
 
 
881
  hn = cop->ft->getHostname(cop, NULL);
 
882
  ns = cop->ft->getNameSpace(cop, NULL);
 
883
 
 
884
  sb->ft->appendChars(sb, "<VALUE.REFERENCE>\n");
 
885
  
 
886
  if(hn && hn->hdl && ns && ns->hdl) {
 
887
    sb->ft->appendChars(sb, "<INSTANCEPATH>\n");
 
888
    addXmlNamespacePath(sb, cop);
 
889
  }
 
890
  else if(ns && ns->hdl) {
 
891
    sb->ft->appendChars(sb, "<LOCALINSTANCEPATH>\n");
 
892
    addXmlNamespace(sb, cop);
 
893
  }
 
894
  
 
895
  name = cop->ft->getClassName(cop, NULL);
 
896
  sb->ft->append3Chars(sb, "<INSTANCENAME CLASSNAME=\"", (char*)name->hdl, "\">\n");
 
897
  CMRelease(name);
 
898
  pathToXml(sb, cop);
 
899
  sb->ft->appendChars(sb,"</INSTANCENAME>\n");
 
900
  
 
901
  if(hn && hn->hdl && ns && ns->hdl) {
 
902
    sb->ft->appendChars(sb, "</INSTANCEPATH>\n");
 
903
  }
 
904
  else if(ns && ns->hdl) {
 
905
    sb->ft->appendChars(sb, "</LOCALINSTANCEPATH>\n");
 
906
  }
 
907
  
 
908
  sb->ft->appendChars(sb,"</VALUE.REFERENCE>\n");
 
909
  
 
910
  if(hn) {
 
911
    CMRelease(hn);
 
912
  }
 
913
  if(ns) {
 
914
    CMRelease(ns);
 
915
  }
 
916
}
 
917
 
 
918
/* --------------------------------------------------------------------------*/
 
919
 
 
920
static void addXmlInstance(UtilStringBuffer *sb,
792
921
                                CMPIObjectPath * cop, CMPIInstance * inst)
793
922
{
794
923
   CMPIString       * cn;
802
931
 
803
932
   cn  = cop->ft->getClassName(cop, NULL);
804
933
 
805
 
   sb->ft->appendChars(sb, "<VALUE.NAMEDINSTANCE>\n");
806
 
 
807
 
   /* Add the objectpath */
808
 
   sb->ft->append3Chars(sb, "<INSTANCENAME CLASSNAME=\"",
809
 
                            (char *)cn->hdl, "\">\n");
810
 
   pathToXml(sb, cop);
811
 
   sb->ft->appendChars(sb,"</INSTANCENAME>\n");
812
 
 
813
934
   /* Add the instance */
814
935
   sb->ft->append3Chars(sb,"<INSTANCE CLASSNAME=\"", (char*)cn->hdl, "\">\n");
815
936
   CMRelease(cn);
817
938
   for (i = 0; i < numproperties; i++)
818
939
   {
819
940
      propertydata = inst->ft->getPropertyAt(inst, i, &propertyname, NULL);
820
 
      addXmlValue(sb, "PROPERTY", "TYPE", propertyname->hdl,
821
 
                                              propertydata);
 
941
      if(propertydata.type == CMPI_ref) {
 
942
          addXmlValue(sb, "PROPERTY.REFERENCE", NULL, propertyname->hdl, propertydata);
 
943
      }
 
944
      else {
 
945
          addXmlValue(sb, "PROPERTY", "TYPE", propertyname->hdl, propertydata);
 
946
      }
 
947
 
822
948
      if(propertyname) CMRelease(propertyname);
823
949
   }
824
950
   sb->ft->appendChars(sb,"</INSTANCE>\n");
 
951
}
 
952
 
 
953
static void addXmlNamedInstance(UtilStringBuffer *sb,
 
954
                                CMPIObjectPath * cop, CMPIInstance * inst)
 
955
{
 
956
   CMPIString       * cn;
 
957
   int                i;
 
958
   int                numproperties = inst->ft->getPropertyCount(inst, NULL);
 
959
   CMPIData           propertydata;
 
960
   CMPIString       * propertyname;
 
961
 
 
962
   if (cop == NULL)
 
963
       cop = inst->ft->getObjectPath(inst, NULL);
 
964
 
 
965
   cn  = cop->ft->getClassName(cop, NULL);
 
966
 
 
967
   sb->ft->appendChars(sb, "<VALUE.NAMEDINSTANCE>\n");
 
968
 
 
969
   /* Add the objectpath */
 
970
   sb->ft->append3Chars(sb, "<INSTANCENAME CLASSNAME=\"",
 
971
                            (char *)cn->hdl, "\">\n");
 
972
   pathToXml(sb, cop);
 
973
   sb->ft->appendChars(sb,"</INSTANCENAME>\n");
 
974
 
 
975
   /* Add the instance */
 
976
   addXmlInstance(sb, cop, inst);
825
977
 
826
978
   sb->ft->appendChars(sb,"</VALUE.NAMEDINSTANCE>\n");
827
979
}
841
993
{
842
994
  CMPIStatus rc={CMPI_RC_OK,NULL};
843
995
  ClientEnc             * cl = (ClientEnc*)mb;
844
 
  
 
996
 
845
997
  if (cl->data.hostName) {
846
998
    free(cl->data.hostName);
847
999
  }
873
1025
  return rc;
874
1026
}
875
1027
 
 
1028
#ifndef LARGE_VOL_SUPPORT
 
1029
 
 
1030
/* --------------------------------------------------------------------------*/
876
1031
static CMPIEnumeration * enumInstanceNames(
877
1032
        CMCIClient * mb,
878
1033
        CMPIObjectPath * cop,
941
1096
   END_TIMING(_T_GOOD);
942
1097
   return retval;
943
1098
}
 
1099
#endif
944
1100
 
945
1101
/* --------------------------------------------------------------------------*/
946
1102
 
1090
1246
 
1091
1247
   addXmlNamespace(sb, cop);
1092
1248
 
1093
 
   classname = cop->ft->getClassName(cop, NULL);
1094
 
   sb->ft->append3Chars(sb, "<IPARAMVALUE NAME=\"NewInstance\">\n"
1095
 
                            "<INSTANCE CLASSNAME=\"",
1096
 
                            (char *)classname->hdl, "\">\n");
1097
 
   CMRelease(classname);
1098
 
 
1099
 
   /* Add all the instance properties */
1100
 
   for (i=0; i<numproperties; i++) {
1101
 
      propertydata = inst->ft->getPropertyAt(inst, i, &propertyname, NULL);
1102
 
      addXmlValue(sb, "PROPERTY", "TYPE", propertyname->hdl, propertydata);
1103
 
      if (propertyname) CMRelease(propertyname);
1104
 
   }
1105
 
 
1106
 
   sb->ft->appendChars(sb,"</INSTANCE>\n</IPARAMVALUE>\n");
 
1249
   sb->ft->appendChars(sb, "<IPARAMVALUE NAME=\"NewInstance\">\n");
 
1250
   addXmlInstance(sb, cop, inst);
 
1251
   sb->ft->appendChars(sb,"</IPARAMVALUE>\n");
1107
1252
   sb->ft->appendChars(sb,"</IMETHODCALL>\n");
1108
1253
   addXmlFooter(sb);
1109
1254
 
1472
1617
   return retval;
1473
1618
}
1474
1619
 
 
1620
#ifndef LARGE_VOL_SUPPORT
 
1621
 
1475
1622
/* --------------------------------------------------------------------------*/
1476
 
 
1477
1623
static CMPIEnumeration * enumInstances(
1478
1624
        CMCIClient * mb,
1479
1625
        CMPIObjectPath * cop,
1506
1652
    emitorigin(sb,flags & CMPI_FLAG_IncludeClassOrigin);
1507
1653
 
1508
1654
    if (properties != NULL)
1509
 
        addXmlPropertyListParam(sb, properties);
 
1655
       addXmlPropertyListParam(sb, properties);
1510
1656
 
1511
1657
    sb->ft->appendChars(sb,"</IMETHODCALL>\n");
1512
1658
    addXmlFooter(sb);
1515
1661
 
1516
1662
    if (error || (error = con->ft->getResponse(con, cop))) {
1517
1663
        CMSetStatusWithChars(rc,CMPI_RC_ERR_FAILED,error);
1518
 
        free(error);
 
1664
        free(error);
1519
1665
        END_TIMING(_T_FAILED);
1520
1666
        return NULL;
1521
1667
    }
1534
1680
 
1535
1681
    if (rh.errCode != 0) {
1536
1682
        CMSetStatusWithChars(rc, rh.errCode, rh.description);
1537
 
        free(rh.description);
1538
 
        CMRelease(rh.rvArray);
 
1683
        free(rh.description);
 
1684
        CMRelease(rh.rvArray);
1539
1685
        END_TIMING(_T_FAILED);
1540
1686
        return NULL;
1541
1687
    }
1551
1697
    END_TIMING(_T_GOOD);
1552
1698
    return retval;
1553
1699
}
 
1700
#endif
1554
1701
 
1555
1702
/* --------------------------------------------------------------------------*/
1556
 
 
1557
1703
static CMPIEnumeration * associators(
1558
1704
        CMCIClient      * mb,
1559
1705
        CMPIObjectPath  * cop,
2098
2244
                                          argname->hdl, argdata);
2099
2245
             break;
2100
2246
         case CMPI_instance:    /* TODO: UNTESTED */
2101
 
             if (argdata.type & CMPI_ARRAY)
2102
 
                 goto not_supported;
2103
2247
             sb->ft->append3Chars(sb, "<PARAMVALUE NAME=\"",
2104
2248
                                      argname->hdl,
2105
2249
                                      "\" PARAMTYPE=\"instance\">\n");
2106
 
             addXmlNamedInstance(sb, NULL, argdata.value.inst);
2107
 
      sb->ft->appendChars(sb,"</PARAMVALUE>\n");
 
2250
             if (argdata.type & CMPI_ARRAY) {
 
2251
               int i;
 
2252
               int n = CMGetArrayCount(argdata.value.array, NULL);
 
2253
               sb->ft->appendChars(sb, "<VALUE.ARRAY>\n");             
 
2254
               for (i=0; i < n; i++) {
 
2255
                 CMPIData instel = 
 
2256
                   CMGetArrayElementAt(argdata.value.array,i,NULL);
 
2257
                 addXmlNamedInstance(sb, NULL, instel.value.inst);
 
2258
               }
 
2259
               sb->ft->appendChars(sb, "</VALUE.ARRAY>\n");            
 
2260
             } else {
 
2261
               addXmlNamedInstance(sb, NULL, argdata.value.inst);
 
2262
             }
 
2263
             sb->ft->appendChars(sb,"</PARAMVALUE>\n");
2108
2264
             break;
2109
2265
         case CMPI_ref:
2110
 
             if (argdata.type & CMPI_ARRAY)
2111
 
                 goto not_supported;
2112
 
             argcop = argdata.value.ref;
2113
2266
             sb->ft->append3Chars(sb, "<PARAMVALUE NAME=\"",
2114
2267
                                      argname->hdl,
2115
2268
                                      "\" PARAMTYPE=\"reference\">\n");
2116
 
             sb->ft->appendChars(sb, "<VALUE.REFERENCE>\n");
2117
 
             sb->ft->appendChars(sb, "<INSTANCEPATH>\n");
2118
 
             sb->ft->appendChars(sb, "<NAMESPACEPATH>\n");
2119
 
             name = argcop->ft->getHostname(argcop, NULL);
2120
 
             sb->ft->append3Chars(sb, "<HOST>",
2121
 
                                  name != NULL ? 
2122
 
                                     (char *)name->hdl : "localhost",
2123
 
                                  "</HOST>\n");
2124
 
             if (name != NULL)
2125
 
                 CMRelease(name);
2126
 
             addXmlNamespace(sb, argcop);
2127
 
             sb->ft->appendChars(sb, "</NAMESPACEPATH>\n");
2128
 
 
2129
 
             name = argcop->ft->getClassName(argcop, NULL);
2130
 
             sb->ft->append3Chars(sb, "<INSTANCENAME CLASSNAME=\"",
2131
 
                            (char*)name->hdl, "\">\n");
2132
 
             CMRelease(name);
2133
 
             pathToXml(sb, argcop);
2134
 
             sb->ft->appendChars(sb,"</INSTANCENAME>\n");
2135
 
             sb->ft->appendChars(sb,"</INSTANCEPATH>\n");
2136
 
             sb->ft->appendChars(sb,"</VALUE.REFERENCE>\n");
 
2269
             if (argdata.type & CMPI_ARRAY) {
 
2270
               int i;
 
2271
               int n = CMGetArrayCount(argdata.value.array, NULL);
 
2272
               sb->ft->appendChars(sb, "<VALUE.ARRAY>\n");             
 
2273
               for (i=0; i < n; i++) {
 
2274
                 CMPIData refel = 
 
2275
                   CMGetArrayElementAt(argdata.value.array,i,NULL);
 
2276
                 addXmlReference(sb,refel.value.ref);
 
2277
               }
 
2278
               sb->ft->appendChars(sb, "</VALUE.ARRAY>\n");            
 
2279
             } else {
 
2280
               addXmlReference(sb,argdata.value.ref);
 
2281
             }
2137
2282
             sb->ft->appendChars(sb,"</PARAMVALUE>\n");
2138
2283
             break;
2139
2284
         default:
2537
2682
   return ccc;
2538
2683
}
2539
2684
 
 
2685
#ifndef LARGE_VOL_SUPPORT 
 
2686
 
2540
2687
/* --------------------------------------------------------------------------*/
2541
2688
 
2542
2689
/* finished & working */
2688
2835
   return retval;
2689
2836
}
2690
2837
 
2691
 
/* --------------------------------------------------------------------------*/
 
2838
#endif
2692
2839
 
2693
2840
static CMCIClientFT clientFt = {
2694
2841
   NATIVE_FT_VERSION,
2720
2867
 
2721
2868
/* --------------------------------------------------------------------------*/
2722
2869
 
2723
 
static CMCIClient *xmlConnect2(CIMCEnv *env, const char *hn, const char *scheme, const char *port,
 
2870
static CIMCClient *xmlConnect2(CIMCEnv *env, const char *hn, const char *scheme, const char *port,
2724
2871
                         const char *user, const char *pwd, 
2725
2872
                         int verifyMode, const char * trustStore,
2726
2873
                         const char * certFile, const char * keyFile,
2727
 
                         CMPIStatus *rc)
 
2874
                         CIMCStatus *rc)
2728
2875
{  
2729
2876
   ClientEnc *cc = (ClientEnc*)calloc(1, sizeof(ClientEnc));
2730
2877
 
2762
2909
     }
2763
2910
 
2764
2911
   CMSetStatus(rc, CMPI_RC_OK);
2765
 
   return (CMCIClient*)cc;
 
2912
   return (CIMCClient*)cc;
2766
2913
}
2767
2914
 
2768
 
static CMCIClient *xmlConnect(CIMCEnv *env, const char *hn, const char *scheme, const char *port,
2769
 
                        const char *user, const char *pwd, CMPIStatus *rc)
 
2915
static CIMCClient *xmlConnect(CIMCEnv *env, const char *hn, const char *scheme, const char *port,
 
2916
                        const char *user, const char *pwd, CIMCStatus *rc)
2770
2917
{
2771
 
  return xmlConnect2(env, hn, scheme, port, user, pwd, CMCI_VERIFY_PEER, NULL,
 
2918
  return (CIMCClient*)xmlConnect2(env, hn, scheme, port, user, pwd, CMCI_VERIFY_PEER, NULL,
2772
2919
                      NULL, NULL, rc);
2773
2920
}
2774
2921
 
2781
2928
  return NULL;
2782
2929
}
2783
2930
 
2784
 
static CMPIInstance* newInstance(CIMCEnv* ce, const CMPIObjectPath* op, CMPIStatus* rc)
2785
 
{
2786
 
   return newCMPIInstance((CMPIObjectPath*)op,rc);
2787
 
}
2788
 
 
2789
 
static CMPIString* newString(CIMCEnv* ce, const char *ptr, CMPIStatus * rc)
2790
 
{
2791
 
   return newCMPIString(ptr, rc);
2792
 
}
2793
 
 
2794
 
static CMPIObjectPath* newObjectPath(CIMCEnv* ce, const char *ns, const char *cn, CMPIStatus* rc)
2795
 
{
2796
 
   return newCMPIObjectPath(ns,cn,rc);
2797
 
}
2798
 
 
2799
 
static CMPIArgs* newArgs(CIMCEnv* ce, CMPIStatus* rc)
2800
 
{
2801
 
   return newCMPIArgs(rc);
2802
 
}
2803
 
 
2804
 
static CMPIArray* newArray(CIMCEnv* ce, CMPICount max, CMPIType type, CMPIStatus* rc)
2805
 
{
2806
 
   return newCMPIArray(max, type, rc);
2807
 
}
2808
 
 
2809
 
static CMPIDateTime *newDateTime(CIMCEnv* ce, CMPIStatus *rc) 
2810
 
{
2811
 
   return native_new_CMPIDateTime(rc); 
2812
 
}
2813
 
 
2814
 
static CMPIDateTime *newDateTimeFromBinary(CIMCEnv* ce, CMPIUint64 binTime, CMPIBoolean interval, 
2815
 
      CMPIStatus *rc) 
2816
 
{
2817
 
   return native_new_CMPIDateTime_fromBinary(binTime,interval,rc); 
2818
 
}
2819
 
 
2820
 
static CMPIDateTime *newDateTimeFromChars(CIMCEnv* ce, const char *utcTime, CMPIStatus *rc) 
2821
 
{
2822
 
   return native_new_CMPIDateTime_fromChars(utcTime,rc); 
 
2931
static CIMCInstance* newInstance(CIMCEnv* ce, const CIMCObjectPath* op, CIMCStatus* rc)
 
2932
{
 
2933
  return (CIMCInstance*)newCMPIInstance((CMPIObjectPath*)op,(CMPIStatus*)rc);
 
2934
}
 
2935
 
 
2936
static CIMCString* newString(CIMCEnv* ce, const char *ptr, CIMCStatus * rc)
 
2937
{
 
2938
  return (CIMCString*)newCMPIString(ptr, (CMPIStatus*)rc);
 
2939
}
 
2940
 
 
2941
static CIMCObjectPath* newObjectPath(CIMCEnv* ce, const char *ns, const char *cn, CIMCStatus* rc)
 
2942
{
 
2943
  return (CIMCObjectPath*)newCMPIObjectPath(ns,cn,(CMPIStatus*)rc);
 
2944
}
 
2945
 
 
2946
static CIMCArgs* newArgs(CIMCEnv* ce, CIMCStatus* rc)
 
2947
{
 
2948
  return (CIMCArgs*)newCMPIArgs((CMPIStatus*)rc);
 
2949
}
 
2950
 
 
2951
static CIMCArray* newArray(CIMCEnv* ce, CMPICount max, CMPIType type, CIMCStatus* rc)
 
2952
{
 
2953
  return (CIMCArray*)newCMPIArray(max, type, (CMPIStatus*)rc);
 
2954
}
 
2955
 
 
2956
static CIMCDateTime *newDateTime(CIMCEnv* ce, CIMCStatus *rc) 
 
2957
{
 
2958
  return (CIMCDateTime*)native_new_CMPIDateTime((CMPIStatus*)rc); 
 
2959
}
 
2960
 
 
2961
static CIMCDateTime *newDateTimeFromBinary(CIMCEnv* ce, CMPIUint64 binTime, CMPIBoolean interval, 
 
2962
      CIMCStatus *rc) 
 
2963
{
 
2964
  return (CIMCDateTime*)native_new_CMPIDateTime_fromBinary(binTime,interval,(CMPIStatus*)rc); 
 
2965
}
 
2966
 
 
2967
static CIMCDateTime *newDateTimeFromChars(CIMCEnv* ce, const char *utcTime, CIMCStatus *rc) 
 
2968
{
 
2969
  return (CIMCDateTime*)native_new_CMPIDateTime_fromChars(utcTime,(CMPIStatus*)rc); 
 
2970
}
 
2971
 
 
2972
static CIMCIndicationListener *newIndicationListener (CIMCEnv* ce,
 
2973
                                                      int sslMode,
 
2974
                                                      int *portNumber,
 
2975
                                                      char **socketName,
 
2976
                                                      void (*fp) (CIMCInstance *indInstance),
 
2977
                                                      CIMCStatus *rc)
 
2978
{
 
2979
   /* socket name not required, cimxml/tcpip mode */
 
2980
   return newCIMCIndicationListener(sslMode, portNumber, fp, rc);
2823
2981
}
2824
2982
 
2825
2983
static CIMCEnvFT localFT = {
2835
2993
  newDateTime,
2836
2994
  newDateTimeFromBinary,
2837
2995
  newDateTimeFromChars,
 
2996
  newIndicationListener,
2838
2997
};
2839
2998
 
2840
2999
/* Factory function for CIMXML Client */
2848
3007
    
2849
3008
    return env;
2850
3009
 }
 
3010
/* *********************************************************** */ 
 
3011
/* *********************************************************** */
 
3012
/*                                                             */
 
3013
/* *********************************************************** */
 
3014
/* *********************************************************** */
 
3015
 
 
3016
#ifdef LARGE_VOL_SUPPORT
 
3017
 
 
3018
 
 
3019
/* --------------------------------------------------------------------------*/
 
3020
 
 
3021
/* --------------------------------------------------------------------------*/
 
3022
static CMPIEnumeration * enumInstances(
 
3023
        CMCIClient * mb,
 
3024
        CMPIObjectPath * cop,
 
3025
        CMPIFlags flags,
 
3026
        char ** properties,
 
3027
        CMPIStatus * rc)
 
3028
{
 
3029
   ClientEnc         *cl  = (ClientEnc *)mb;
 
3030
   CMCIConnection   *con = cl->connection;
 
3031
   UtilStringBuffer *sb  = UtilFactory->newStringBuffer(2048);
 
3032
   char               *error;
 
3033
   CMPIEnumeration    *retEnum;
 
3034
   struct native_enum *retNatEnum;
 
3035
   pthread_t enum_scanthrd_id = 0 ;
 
3036
   int       pthrd_error      = 0 ;
 
3037
 
 
3038
   initEscanInfo(con) ;
 
3039
   
 
3040
   START_TIMING(EnumerateInstances);
 
3041
   SET_DEBUG();
 
3042
   
 
3043
   if(pthrd_error = pthread_mutex_init(&(con->asynRCntl.escanlock),NULL) != 0){
 
3044
      CMSetStatusWithChars(rc,CMPI_RC_ERR_FAILED," Failed pthread mutex init");
 
3045
      END_TIMING(_T_FAILED);
 
3046
      return NULL;
 
3047
   }
 
3048
    
 
3049
   con->ft->genEnumRequest(cl, EnumerateInstances, cop, 0);
 
3050
 
 
3051
   addXmlHeader(sb);
 
3052
 
 
3053
   sb->ft->append3Chars(sb, "<IMETHODCALL NAME=\"", EnumerateInstances, "\">");
 
3054
   addXmlNamespace(sb, cop);
 
3055
 
 
3056
   addXmlClassnameParam(sb, cop);
 
3057
 
 
3058
   emitdeep(sb,flags & CMPI_FLAG_DeepInheritance);
 
3059
   emitlocal(sb,flags & CMPI_FLAG_LocalOnly);
 
3060
   emitqual(sb,flags & CMPI_FLAG_IncludeQualifiers);
 
3061
   emitorigin(sb,flags & CMPI_FLAG_IncludeClassOrigin);
 
3062
 
 
3063
   if (properties != NULL)
 
3064
            addXmlPropertyListParam(sb, properties);
 
3065
 
 
3066
   sb->ft->appendChars(sb,"</IMETHODCALL>\n");
 
3067
   addXmlFooter(sb);
 
3068
 
 
3069
   error = con->ft->addPayload(con,sb);
 
3070
 
 
3071
   CMSetStatus (&con->mStatus, CMPI_RC_OK );
 
3072
 
 
3073
   if (error || (error = con->ft->getEnumResponse(con, cop))) {
 
3074
       CMSetStatusWithChars(rc,CMPI_RC_ERR_FAILED,error);
 
3075
             free(error);
 
3076
       END_TIMING(_T_FAILED);
 
3077
       return NULL;
 
3078
   }
 
3079
 
 
3080
   if (con->mStatus.rc != CMPI_RC_OK) {
 
3081
      if (rc)
 
3082
         *rc=cloneStatus(con->mStatus);
 
3083
      CMRelease(sb);
 
3084
      END_TIMING(_T_FAILED);
 
3085
      return NULL;
 
3086
   }
 
3087
 
 
3088
         /*
 
3089
          * allocate an empty enumeration , to be filled in 
 
3090
          * by the scan of the xml data in enumScanThrd .  
 
3091
    */
 
3092
    
 
3093
   retEnum = newCMPIEnumeration(NULL , NULL);
 
3094
   
 
3095
   /*
 
3096
    * copy addresses so parsing can find our connection and 
 
3097
    * the enumeration. 
 
3098
    */
 
3099
   
 
3100
   retNatEnum = (struct native_enum *) retEnum ;
 
3101
         retNatEnum->econ = con ;
 
3102
         retNatEnum->ecop = cop ;
 
3103
         con->asynRCntl.enmp = (struct native_enum  *) retEnum ;
 
3104
           
 
3105
   pthrd_error = pthread_create(&enum_scanthrd_id,
 
3106
                                 NULL,
 
3107
                                 (void*)&enumScanThrd,
 
3108
                                 (void*)retNatEnum);
 
3109
   /*
 
3110
    * if enumInstances Couldn't run thread pthrd_error , system error 
 
3111
    * otherwise we are OK , set status appropriately
 
3112
    */                                    
 
3113
   if(pthrd_error != 0){
 
3114
     CMSetStatus(rc,CMPI_RC_ERROR_SYSTEM);
 
3115
   } else {
 
3116
         CMSetStatus(rc,CMPI_RC_OK);
 
3117
   }
 
3118
        
 
3119
         CMRelease(sb);
 
3120
         
 
3121
   return retEnum;
 
3122
}
 
3123
 
 
3124
/* --------------------------------------------------------------------------*/
 
3125
static CMPIEnumeration * enumInstanceNames(
 
3126
        CMCIClient * mb,
 
3127
        CMPIObjectPath * cop,
 
3128
        CMPIStatus * rc)
 
3129
{
 
3130
   ClientEnc            * cl = (ClientEnc*)mb;
 
3131
   CMCIConnection       * con = cl->connection;
 
3132
   UtilStringBuffer     * sb = UtilFactory->newStringBuffer(2048);
 
3133
   char                 * error;
 
3134
   CMPIEnumeration    *retval;
 
3135
   CMPIEnumeration    *retEnum;
 
3136
   struct native_enum *retNatEnum;
 
3137
   pthread_t enum_scanthrd_id = 0 ;
 
3138
   int       pthrd_error      = 0 ;
 
3139
    
 
3140
   initEscanInfo(con) ;
 
3141
 
 
3142
   START_TIMING(EnumerateInstanceNames);
 
3143
   SET_DEBUG();
 
3144
   
 
3145
   if(pthrd_error = pthread_mutex_init(&(con->asynRCntl.escanlock),NULL) != 0){
 
3146
      CMSetStatusWithChars(rc,CMPI_RC_ERR_FAILED," Failed pthread mutex init");
 
3147
      END_TIMING(_T_FAILED);
 
3148
      return NULL;
 
3149
   }
 
3150
     
 
3151
   con->ft->genEnumRequest(cl, EnumerateInstanceNames, cop, 0);
 
3152
 
 
3153
   /* Construct the CIM-XML request */
 
3154
   addXmlHeader(sb);
 
3155
   sb->ft->append3Chars(sb, "<IMETHODCALL NAME=\"", EnumerateInstanceNames, "\">");
 
3156
 
 
3157
   addXmlNamespace(sb, cop);
 
3158
   addXmlClassnameParam(sb, cop);
 
3159
 
 
3160
   sb->ft->appendChars(sb,"</IMETHODCALL>\n");
 
3161
   addXmlFooter(sb);
 
3162
 
 
3163
   error = con->ft->addPayload(con, sb);
 
3164
 
 
3165
   CMSetStatus (&con->mStatus, CMPI_RC_OK );
 
3166
 
 
3167
   if (error || (error = con->ft->getEnumResponse(con, cop))) {
 
3168
      CMSetStatusWithChars(rc,CMPI_RC_ERR_FAILED,error);
 
3169
            free(error);
 
3170
      END_TIMING(_T_FAILED);
 
3171
      return NULL;
 
3172
   }
 
3173
 
 
3174
   if (con->mStatus.rc != CMPI_RC_OK) {
 
3175
      if (rc)
 
3176
         *rc=cloneStatus(con->mStatus);
 
3177
      CMRelease(sb);
 
3178
      END_TIMING(_T_FAILED);
 
3179
      return NULL;
 
3180
   }
 
3181
 
 
3182
         /*
 
3183
          * allocate an empty enumeration , to be filled in 
 
3184
          * by the scan of the xml data in enumScanThrd .  
 
3185
    */
 
3186
     
 
3187
   retEnum = newCMPIEnumeration(NULL , NULL);
 
3188
    
 
3189
   /*
 
3190
    * copy addresses so parsing can find our connection and 
 
3191
    * the enumeration. 
 
3192
    */
 
3193
    
 
3194
   retNatEnum = (struct native_enum *) retEnum ;
 
3195
         retNatEnum->econ = con ;
 
3196
         retNatEnum->ecop = cop ;
 
3197
         con->asynRCntl.enmp = (struct native_enum  *) retEnum ;
 
3198
            
 
3199
   pthrd_error = pthread_create(&enum_scanthrd_id,
 
3200
                                 NULL,
 
3201
                                 (void*)&enumScanThrd,
 
3202
                                 (void*)retNatEnum);
 
3203
   /*
 
3204
    * if enumInstanceNames Couldn't run thread pthrd_error , system error 
 
3205
    * otherwise we are OK , set status appropriately
 
3206
    */                                    
 
3207
   if(pthrd_error != 0){
 
3208
      CMSetStatus(rc,CMPI_RC_ERROR_SYSTEM);
 
3209
   } else {
 
3210
      CMSetStatus(rc,CMPI_RC_OK);
 
3211
   }
 
3212
                  
 
3213
         CMRelease(sb);
 
3214
          
 
3215
   return retEnum;
 
3216
 
 
3217
}
 
3218
/* --------------------------------------------------------------------------*/
 
3219
static CMPIEnumeration * enumClasses(
 
3220
        CMCIClient * mb,
 
3221
        CMPIObjectPath * cop,
 
3222
        CMPIFlags flags,
 
3223
        CMPIStatus * rc)
 
3224
{
 
3225
   ClientEnc         *cl  = (ClientEnc *)mb;
 
3226
   CMCIConnection   *con = cl->connection;
 
3227
   UtilStringBuffer *sb  = UtilFactory->newStringBuffer(2048);
 
3228
   char             *error;
 
3229
   CMPIEnumeration  *retval;
 
3230
   CMPIEnumeration    *retEnum;
 
3231
   struct native_enum *retNatEnum;
 
3232
   pthread_t enum_scanthrd_id = 0 ;
 
3233
   int       pthrd_error      = 0 ;
 
3234
    
 
3235
   START_TIMING(EnumerateClasses);
 
3236
   SET_DEBUG();
 
3237
    
 
3238
   initEscanInfo(con) ;
 
3239
   if(pthrd_error = pthread_mutex_init(&(con->asynRCntl.escanlock),NULL) != 0){
 
3240
       CMSetStatusWithChars(rc,CMPI_RC_ERR_FAILED," Failed pthread mutex init");
 
3241
       END_TIMING(_T_FAILED);
 
3242
       return NULL;
 
3243
   }
 
3244
   
 
3245
   con->ft->genEnumRequest(cl, EnumerateClasses, cop, 0);
 
3246
 
 
3247
   /* Construct the CIM-XML request */
 
3248
   addXmlHeader(sb);
 
3249
   sb->ft->append3Chars(sb, "<IMETHODCALL NAME=\"", EnumerateClasses, "\">");
 
3250
 
 
3251
   addXmlNamespace(sb, cop);
 
3252
   emitdeep(sb,flags & CMPI_FLAG_DeepInheritance);
 
3253
   emitlocal(sb,flags & CMPI_FLAG_LocalOnly);
 
3254
   emitqual(sb,flags & CMPI_FLAG_IncludeQualifiers);
 
3255
   emitorigin(sb,flags & CMPI_FLAG_IncludeClassOrigin);
 
3256
   addXmlClassnameParam(sb, cop);
 
3257
 
 
3258
   sb->ft->appendChars(sb,"</IMETHODCALL>\n");
 
3259
   addXmlFooter(sb);
 
3260
 
 
3261
   error = con->ft->addPayload(con,sb);
 
3262
   
 
3263
   CMSetStatus (&con->mStatus, CMPI_RC_OK );
 
3264
   
 
3265
   if (error || (error = con->ft->getEnumResponse(con, cop))) {
 
3266
      CMSetStatusWithChars(rc,CMPI_RC_ERR_FAILED,error);
 
3267
            free(error);
 
3268
      END_TIMING(_T_FAILED);
 
3269
      return NULL;
 
3270
   }
 
3271
 
 
3272
   if (con->mStatus.rc != CMPI_RC_OK) {
 
3273
      if (rc)
 
3274
         *rc=cloneStatus(con->mStatus);
 
3275
      CMRelease(sb);
 
3276
      END_TIMING(_T_FAILED);
 
3277
      return NULL;
 
3278
   }
 
3279
 
 
3280
         /*
 
3281
          * allocate an empty enumeration , to be filled in 
 
3282
          * by the scan of the xml data in enumScanThrd .  
 
3283
    */
 
3284
     
 
3285
   retEnum = newCMPIEnumeration(NULL , NULL);
 
3286
    
 
3287
   /*
 
3288
    * copy addresses so parsing can find our connection and 
 
3289
    * the enumeration. 
 
3290
    */
 
3291
    
 
3292
   retNatEnum = (struct native_enum *) retEnum ;
 
3293
         retNatEnum->econ = con ;
 
3294
         retNatEnum->ecop = cop ;
 
3295
         con->asynRCntl.enmp = (struct native_enum  *) retEnum ;
 
3296
 
 
3297
   pthrd_error = pthread_create(&enum_scanthrd_id,
 
3298
                                 NULL,
 
3299
                                 (void*)&enumScanThrd,
 
3300
                                 (void*)retNatEnum);
 
3301
  /*
 
3302
   * if enumClasses Couldn't run thread pthrd_error , system error 
 
3303
   * otherwise we are OK , set status appropriately
 
3304
   */                                     
 
3305
   if(pthrd_error != 0){
 
3306
      CMSetStatus(rc,CMPI_RC_ERROR_SYSTEM);
 
3307
   } else {
 
3308
      CMSetStatus(rc,CMPI_RC_OK);
 
3309
   }
 
3310
         
 
3311
   CMRelease(sb);
 
3312
 
 
3313
   return retEnum;
 
3314
 
 
3315
}
 
3316
/* --------------------------------------------------------------------------*/
 
3317
/* finished & working */
 
3318
static CMPIEnumeration* enumClassNames(
 
3319
        CMCIClient * mb,
 
3320
        CMPIObjectPath * cop,
 
3321
        CMPIFlags flags,
 
3322
        CMPIStatus * rc)
 
3323
{
 
3324
   ClientEnc *cl=(ClientEnc*)mb;
 
3325
   CMCIConnection *con=cl->connection;
 
3326
   UtilStringBuffer *sb=UtilFactory->newStringBuffer(2048);
 
3327
   char *error;
 
3328
   CMPIEnumeration    *retEnum;
 
3329
   struct native_enum *retNatEnum;
 
3330
   pthread_t enum_scanthrd_id = 0 ;
 
3331
   int       pthrd_error      = 0 ;
 
3332
    
 
3333
   START_TIMING(EnumerateClassNames);
 
3334
   SET_DEBUG();
 
3335
 
 
3336
    
 
3337
   // con->asynRCntl.enmp = (struct native_enum  *)retNatEnum ;
 
3338
    
 
3339
   initEscanInfo(con) ;
 
3340
   if(pthrd_error = pthread_mutex_init(&(con->asynRCntl.escanlock),NULL) != 0){
 
3341
       CMSetStatusWithChars(rc,CMPI_RC_ERR_FAILED," Failed pthread mutex init");
 
3342
       END_TIMING(_T_FAILED);
 
3343
       return NULL;
 
3344
   }
 
3345
    
 
3346
   con->ft->genEnumRequest(cl, EnumerateClassNames, cop, 0);
 
3347
 
 
3348
   /* Construct the CIM-XML request */
 
3349
   addXmlHeader(sb);
 
3350
   sb->ft->append3Chars(sb,"<IMETHODCALL NAME=\"", EnumerateClassNames, "\">");
 
3351
 
 
3352
   addXmlNamespace(sb, cop);
 
3353
   emitdeep(sb,flags & CMPI_FLAG_DeepInheritance);
 
3354
   addXmlClassnameParam(sb, cop);
 
3355
 
 
3356
   sb->ft->appendChars(sb,"</IMETHODCALL>\n");
 
3357
   addXmlFooter(sb);
 
3358
 
 
3359
   error = con->ft->addPayload(con,sb);
 
3360
   
 
3361
   CMSetStatus (&con->mStatus, CMPI_RC_OK ); 
 
3362
   
 
3363
   if (error || (error = con->ft->getEnumResponse(con, cop))) {
 
3364
      CMSetStatusWithChars(rc,CMPI_RC_ERR_FAILED,error);
 
3365
            free(error);
 
3366
      END_TIMING(_T_FAILED);
 
3367
      return NULL;
 
3368
   }
 
3369
 
 
3370
   if (con->mStatus.rc != CMPI_RC_OK) {
 
3371
      if (rc)
 
3372
         *rc=cloneStatus(con->mStatus);
 
3373
      CMRelease(sb);
 
3374
      END_TIMING(_T_FAILED);
 
3375
      return NULL;
 
3376
   }
 
3377
         /*
 
3378
          * allocate an empty enumeration , to be filled in 
 
3379
          * by the scan of the xml data in enumScanThrd .  
 
3380
    */
 
3381
     
 
3382
   retEnum = newCMPIEnumeration(NULL , NULL);
 
3383
    
 
3384
   /*
 
3385
    * copy addresses so parsing can find our connection and 
 
3386
    * the enumeration. 
 
3387
    */
 
3388
    
 
3389
   retNatEnum = (struct native_enum *) retEnum ;
 
3390
         retNatEnum->econ = con ;
 
3391
         retNatEnum->ecop = cop ;
 
3392
         con->asynRCntl.enmp = (struct native_enum  *) retEnum ;
 
3393
        
 
3394
   pthrd_error = pthread_create(&enum_scanthrd_id,
 
3395
                                 NULL,
 
3396
                                 (void*)&enumScanThrd,
 
3397
                                 (void*)retNatEnum);
 
3398
  /*
 
3399
   * if enumClassNames Couldn't run thread pthrd_error , system error 
 
3400
   * otherwise we are OK , set status appropriately
 
3401
   */                               
 
3402
   if(pthrd_error != 0){
 
3403
      CMSetStatus(rc,CMPI_RC_ERROR_SYSTEM);
 
3404
   } else {
 
3405
      CMSetStatus(rc,CMPI_RC_OK);
 
3406
   }
 
3407
                  
 
3408
   CMRelease(sb);
 
3409
 
 
3410
   return retEnum;
 
3411
 
 
3412
}
 
3413
 
 
3414
/* --------------------------------------------------------------------------*/
 
3415
static char* genEnumRequest(ClientEnc *cle, const char *op,
 
3416
                        CMPIObjectPath *cop, int classWithKeys)
 
3417
{
 
3418
   CMCIConnection   *con = cle->connection;
 
3419
   CMCIClientData   *cld = &cle->data;
 
3420
   UtilList         *nsc;
 
3421
   char             method[256]    = "CIMMethod: ";
 
3422
   char             CimObject[512] = "CIMObject: ";
 
3423
   char             *nsp;
 
3424
   int        isEnumOp = 0 ;
 
3425
   int        chunkedTransfer = 0 ; 
 
3426
   
 
3427
   if (!con->mHandle) return "Unable to initialize curl interface.";
 
3428
 
 
3429
//    if (!supportsSSL() && url.scheme == "https")
 
3430
//        throw HttpException("this curl library does not support https urls.");
 
3431
   
 
3432
   /* 
 
3433
    * check to see if this is an enumeration 
 
3434
    */
 
3435
   if((strcmp(op , EnumerateInstances )) == 0) {
 
3436
          chunkedTransfer = 1 ;
 
3437
          isEnumOp = 1 ; 
 
3438
      con->asynRCntl.eMethodType = ENUMERATEINSTANCES ;
 
3439
   } else 
 
3440
   if((strcmp(op , EnumerateInstanceNames )) == 0) {
 
3441
          chunkedTransfer = 1 ;
 
3442
          isEnumOp = 1 ;
 
3443
      con->asynRCntl.eMethodType = ENUMERATEINSTANCENAMES ;
 
3444
   } else
 
3445
   if((strcmp(op , EnumerateClasses )) == 0) {
 
3446
          chunkedTransfer = 1 ;
 
3447
          isEnumOp = 1 ;
 
3448
      con->asynRCntl.eMethodType = ENUMERATECLASSES ;
 
3449
   } else 
 
3450
   if((strcmp(op , EnumerateClassNames )) == 0) {
 
3451
          chunkedTransfer = 1 ;
 
3452
          isEnumOp = 1 ; 
 
3453
      con->asynRCntl.eMethodType = ENUMERATECLASSNAMES ;
 
3454
   }  else {
 
3455
         isEnumOp = 0 ; /* some other operation */
 
3456
   }
 
3457
      
 
3458
   con->mResponse->ft->reset(con->mResponse);
 
3459
 
 
3460
   con->mUri->ft->reset(con->mUri);
 
3461
   con->mUri->ft->append6Chars(con->mUri, cld->scheme, "://", cld->hostName,
 
3462
                                                  ":", cld->port, "/cimom");
 
3463
 
 
3464
   /* Initialize curl with the url */
 
3465
   curl_easy_setopt(con->mHandle, CURLOPT_URL,
 
3466
                                  con->mUri->ft->getCharPtr(con->mUri));
 
3467
 
 
3468
   /* Enable progress checking */
 
3469
   curl_easy_setopt(con->mHandle, CURLOPT_NOPROGRESS, 0);
 
3470
   
 
3471
   /* Reset timeout control */
 
3472
   con->mTimeout.mTimestampStart = 0;
 
3473
   con->mTimeout.mTimestampLast = 0;
 
3474
   con->mTimeout.mFixups = 0;
 
3475
 
 
3476
   /* This will be a HTTP post */
 
3477
   curl_easy_setopt(con->mHandle, CURLOPT_POST, 1);
 
3478
 
 
3479
   /* Disable SSL Host verification */
 
3480
   curl_easy_setopt(con->mHandle, CURLOPT_SSL_VERIFYHOST, 0);
 
3481
 
 
3482
   /* Setup authentication */
 
3483
   curl_easy_setopt(con->mHandle, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
 
3484
 
 
3485
   /* Set username and password */
 
3486
   if (cld->user != NULL) {
 
3487
      UtilStringBuffer *UserPass = con->mUserPass;
 
3488
 
 
3489
      UserPass->ft->reset(UserPass);
 
3490
      UserPass->ft->appendChars(UserPass, cld->user);
 
3491
      if (cld->pwd)
 
3492
         UserPass->ft->append3Chars(UserPass, ":", cld->pwd, NULL);
 
3493
      /* Setup "<userid>:<password>" */
 
3494
      curl_easy_setopt(con->mHandle, CURLOPT_USERPWD,
 
3495
                                     UserPass->ft->getCharPtr(UserPass));
 
3496
   }
 
3497
 
 
3498
   /* initialize status */
 
3499
   CMSetStatus(&con->mStatus,CMPI_RC_OK);
 
3500
 
 
3501
   /* Setup connect timeouts for cimserver operations */
 
3502
   curl_easy_setopt(con->mHandle, CURLOPT_NOSIGNAL, 1);
 
3503
   curl_easy_setopt(con->mHandle, CURLOPT_CONNECTTIMEOUT, CIMSERVER_TIMEOUT);
 
3504
 
 
3505
   /* setup callback for client timeout calculations */
 
3506
   curl_easy_setopt(con->mHandle, CURLOPT_PROGRESSFUNCTION, enumCheckProgress);
 
3507
   curl_easy_setopt(con->mHandle, CURLOPT_PROGRESSDATA, con);
 
3508
 
 
3509
   // Initialize default headers
 
3510
   con->ft->initializeHeaders(con);
 
3511
 
 
3512
   /* 
 
3513
    * check for chunk transfer or no chunk  
 
3514
    */
 
3515
       
 
3516
   if(chunkedTransfer == 1){
 
3517
         /* 
 
3518
          * only use http chunk if these enumeration requests come in
 
3519
          */ 
 
3520
         if(isEnumOp) {
 
3521
        con->mHeaders = curl_slist_append(con->mHeaders, "TE: trailers ");
 
3522
     } 
 
3523
   } 
 
3524
 
 
3525
   // Add CIMMethod header
 
3526
   strcat(method, op);
 
3527
   con->mHeaders = curl_slist_append(con->mHeaders, method);
 
3528
 
 
3529
   // Add CIMObject header with cop's namespace, class, keys
 
3530
   if (classWithKeys)
 
3531
       pathToChars(cop, NULL, &CimObject[11], 1);
 
3532
   else {
 
3533
       nsc = getNameSpaceComponents(cop);
 
3534
       nsp = nsc->ft->getFirst(nsc);
 
3535
       while (nsp != NULL) {
 
3536
           strcat(CimObject, nsp);
 
3537
           free(nsp); /* VM: freeing strdup'ed memory - should be part of release */
 
3538
           if ((nsp = nsc->ft->getNext(nsc)) != NULL)
 
3539
               strcat(CimObject, "%2F");
 
3540
       }
 
3541
       CMRelease(nsc);
 
3542
   }
 
3543
   con->mHeaders = curl_slist_append(con->mHeaders, CimObject);
 
3544
 
 
3545
   // Set all of the headers for the request
 
3546
   curl_easy_setopt(con->mHandle, CURLOPT_HTTPHEADER, con->mHeaders);
 
3547
 
 
3548
   // Set up the callbacks to store the response
 
3549
   if(isEnumOp){
 
3550
     curl_easy_setopt(con->mHandle, CURLOPT_WRITEFUNCTION, enumWriteCb);
 
3551
     //Use CURLOPT_FILE instead of CURLOPT_WRITEDATA - more portable
 
3552
     curl_easy_setopt(con->mHandle, CURLOPT_FILE, con);
 
3553
     // SAVE ME curl_easy_setopt(con->mHandle, CURLOPT_FILE, con->mResponse);
 
3554
        // Header processing: 
 
3555
     curl_easy_setopt(con->mHandle, CURLOPT_WRITEHEADER, con);
 
3556
     curl_easy_setopt(con->mHandle, CURLOPT_HEADERFUNCTION, enumWriteHeaders);
 
3557
   } else {
 
3558
   curl_easy_setopt(con->mHandle, CURLOPT_WRITEFUNCTION, writeCb);
 
3559
 
 
3560
   // Use CURLOPT_FILE instead of CURLOPT_WRITEDATA - more portable
 
3561
   curl_easy_setopt(con->mHandle, CURLOPT_FILE, con->mResponse);
 
3562
 
 
3563
   // Header processing: 
 
3564
   curl_easy_setopt(con->mHandle, CURLOPT_WRITEHEADER, &con->mStatus);
 
3565
   curl_easy_setopt(con->mHandle, CURLOPT_HEADERFUNCTION, writeHeaders);
 
3566
   }
 
3567
 
 
3568
   // Fail if we receive an error (HTTP response code >= 300)
 
3569
   curl_easy_setopt(con->mHandle, CURLOPT_FAILONERROR, 1);
 
3570
 
 
3571
   return NULL;
 
3572
}
 
3573
 
 
3574
/* --------------------------------------------------------------------------*/
2851
3575
 
 
3576
static size_t enumWriteHeaders(void *ptr, size_t size,
 
3577
                                  size_t nmemb, void *stream)
 
3578
{
 
3579
  CMCIConnection   *con = stream ;
 
3580
  CMPIStatus *status=(CMPIStatus*)&con->mStatus ;
 
3581
  char *str=ptr;
 
3582
  char *colonidx; 
 
3583
  int   length = 0 ;
 
3584
 
 
3585
  if (str[nmemb-1] != 0) {
 
3586
    /* make sure the string is zero-terminated */
 
3587
      str = malloc(nmemb + 1);
 
3588
      memcpy(str,ptr,nmemb);
 
3589
      str[nmemb] = 0;
 
3590
  } else {
 
3591
    str = strdup(ptr);
 
3592
  }
 
3593
  colonidx=strchr(str,':');
 
3594
  
 
3595
  if (colonidx) {
 
3596
    *colonidx=0;
 
3597
    if (strcasecmp(str,"cimstatuscode") == 0) {
 
3598
        /* set status code */
 
3599
        status->rc = atoi(colonidx+1);
 
3600
        con->asynRCntl.xfer_state = XFER_COMPLETE ;
 
3601
    }      
 
3602
    else if (strcasecmp(str, "cimstatuscodedescription") == 0) {
 
3603
        status->msg=newCMPIString(colonidx+1,NULL);
 
3604
    }  
 
3605
    else if (strcasecmp(str, "content-length") == 0) {
 
3606
        length = atoi(colonidx+1);
 
3607
        /*
 
3608
         * even though we sent for chunk response and expect a trailer
 
3609
         * we can get all the data back without getting a trailer !
 
3610
         * keep track of this for checkProgress function. 
 
3611
         * in both cases signal enumResponseThrd.                                        
 
3612
         */
 
3613
        con->asynRCntl.xfer_state = XFER_RESP_CL ;
 
3614
        pthread_mutex_lock( &con->asynRCntl.xfer_cond_mutex );
 
3615
        pthread_cond_signal( &con->asynRCntl.xfer_cond );
 
3616
        pthread_mutex_unlock( &con->asynRCntl.xfer_cond_mutex );                                              
 
3617
    }
 
3618
    else if (strncasecmp(str, "Transfer-encoding" , 17) == 0) {
 
3619
        if (strncasecmp(colonidx+2, "chunked" , 7) == 0){       
 
3620
           con->asynRCntl.xfer_state = XFER_RESP_TEC ;
 
3621
           pthread_mutex_lock( &con->asynRCntl.xfer_cond_mutex );
 
3622
           pthread_cond_signal( &con->asynRCntl.xfer_cond );
 
3623
           pthread_mutex_unlock( &con->asynRCntl.xfer_cond_mutex );     
 
3624
                
 
3625
        }
 
3626
    }
 
3627
  }
 
3628
  
 
3629
  if (strncasecmp(str, "Transfer-encoding" , 17) == 0) {
 
3630
        // printf(" enumWriteHeaders we see Transfer-encoding: 2nd one \n") ;
 
3631
  }
 
3632
  
 
3633
  free(str);
 
3634
  return nmemb;
 
3635
}
 
3636
 
 
3637
/* --------------------------------------------------------------------------*/
 
3638
 
 
3639
static size_t enumWriteCb(void *ptr, size_t size,
 
3640
                                        size_t nmemb, void *stream)
 
3641
{
 
3642
          CMCIConnection   *con = stream ;
 
3643
          int retcode    = 0;
 
3644
          
 
3645
    UtilStringBuffer *sb=(UtilStringBuffer*)con->mResponse ;
 
3646
    
 
3647
    /*
 
3648
     * lock connection structure here 
 
3649
     */
 
3650
    if((retcode = pthread_mutex_lock(&(con->asynRCntl.escanlock))) != 0){
 
3651
     // printf(" enumWriteCb pthread lock return code %d\n",retcode) ;  
 
3652
    }                   
 
3653
    
 
3654
    unsigned int length = size * nmemb;
 
3655
    sb->ft->appendBlock(sb, ptr, length);
 
3656
    
 
3657
    /*
 
3658
     * maintain escanInfo base pointer and end of data offset  
 
3659
     */
 
3660
    con->asynRCntl.escanInfo.base = sb->hdl ;
 
3661
    con->asynRCntl.escanInfo.eodoff = con->asynRCntl.escanInfo.eodoff + length  ;
 
3662
    con->asynRCntl.escanInfo.recdtotl = con->asynRCntl.escanInfo.recdtotl + length ;
 
3663
    
 
3664
    /*
 
3665
     * unlock connection structure here 
 
3666
     */
 
3667
    if((retcode = pthread_mutex_unlock(&(con->asynRCntl.escanlock))) != 0){
 
3668
     //printf(" enumWriteCb ptread lock return code %d\n",retcode) ;    
 
3669
    }  
 
3670
     
 
3671
    if(length > 0) 
 
3672
        con->asynRCntl.xfer_state = XFER_DATA_RECVD ; 
 
3673
 
 
3674
    return length;
 
3675
}
 
3676
 
 
3677
/* --------------------------------------------------------------------------*/
 
3678
 
 
3679
void *enumResponseThrd(CMCIConnection *con)
 
3680
{
 
3681
CURLcode rv ; /* CURL error code */ 
 
3682
    
 
3683
    if(con->asynRCntl.xfer_state == XFER_NOT_STARTED){
 
3684
      con->asynRCntl.xfer_state = XFER_GENRQST ;
 
3685
    } else {
 
3686
    //  printf(" enumResponseThrd xfer_state = %d is out of sequence !!!!!!!!!!! \n",
 
3687
    //       con->asynRCntl.xfer_state) ;    
 
3688
    }  
 
3689
    
 
3690
    rv  = curl_easy_perform(con->mHandle);   
 
3691
    
 
3692
    /* indicate timeout error for aborted by progess handler */
 
3693
    if (rv  == CURLE_ABORTED_BY_CALLBACK) {
 
3694
      rv = CURLE_OPERATION_TIMEOUTED;
 
3695
    }
 
3696
    
 
3697
    if (rv) {
 
3698
        CMSetStatus(&con->mStatus,CMPI_RC_ERROR_SYSTEM);
 
3699
    }
 
3700
                     
 
3701
}
 
3702
 
 
3703
/* --------------------------------------------------------------------------*/
 
3704
 
 
3705
char *getEnumResponse(CMCIConnection *con, CMPIObjectPath *cop)
 
3706
{
 
3707
    CURLcode rv;
 
3708
    pthread_t       enum_rthd_id  = 0 ;
 
3709
    int             pthrd_error   = 0 ;
 
3710
    struct          timespec tp ;
 
3711
          int             rc = 0 ;
 
3712
      
 
3713
 
 
3714
    pthrd_error = pthread_create(&enum_rthd_id,
 
3715
                                  NULL,
 
3716
                                  (void*)&enumResponseThrd,
 
3717
                                  (void*)con);
 
3718
    /*
 
3719
     * if we cannot create the thread return error
 
3720
     */                                   
 
3721
    if(pthrd_error != 0){
 
3722
      // fprintf(stderr, "getEnumResponse Couldn't run enumResponseThrd errno %d\n", pthrd_error);
 
3723
      return strdup("Error from pthread_create of enumResponseThrd"); 
 
3724
    }
 
3725
 
 
3726
    pthread_mutex_lock( &con->asynRCntl.xfer_cond_mutex );
 
3727
    clock_gettime(CLOCK_REALTIME, &tp);
 
3728
    tp.tv_sec += TIMEDELAY;    
 
3729
    rc = pthread_cond_timedwait(&con->asynRCntl.xfer_cond, &con->asynRCntl.xfer_cond_mutex , &tp);    
 
3730
    pthread_mutex_unlock( &con->asynRCntl.xfer_cond_mutex);    
 
3731
    /* 
 
3732
     * if we didn't get something back from server in TIMEDELAY seconds
 
3733
     * we are calling it an error and cancel the thread.
 
3734
     */   
 
3735
    if(rc != 0) {
 
3736
         // printf(" - DEBUG getEnumResponse pthread_cond_timedwait - TIMEDOUT !!!! rc = %d!!!\n",rc) ;         
 
3737
       pthread_cancel(enum_rthd_id);
 
3738
       return strdup("No data received from server");           
 
3739
    }
 
3740
    
 
3741
    if(con->mStatus.rc != CMPI_RC_OK)
 
3742
    {
 
3743
         pthread_cancel(enum_rthd_id);
 
3744
       return strdup("failed curl_easy_perform call");   
 
3745
    }   
 
3746
    
 
3747
    return NULL;
 
3748
}
 
3749
static int enumCheckProgress(void *data,
 
3750
                         double total,
 
3751
                         double actual,
 
3752
                         double ign1,
 
3753
                         double ign2)
 
3754
{
 
3755
        CMCIConnection   *con = (CMCIConnection   *) data ;
 
3756
  struct _TimeoutControl * timeout;
 
3757
 
 
3758
  timeout = &con->mTimeout ;
 
3759
  time_t timestampNow = time(NULL);
 
3760
    
 
3761
  if (total > 0 ){
 
3762
    if (total == actual){ 
 
3763
       con->asynRCntl.xfer_state = XFER_COMPLETE ;
 
3764
    }
 
3765
  }
 
3766
  /* we received everything and don't care about timeouts */
 
3767
  if (total == actual) {
 
3768
    return 0;
 
3769
  }
 
3770
  if (timeout->mFixups > MAX_PROGRESS_FIXUPS) {
 
3771
    /* to many fixups occured -> fail */
 
3772
    return 1;
 
3773
  }
 
3774
  if (timeout->mTimestampStart == 0 || 
 
3775
      timeout->mTimestampLast > timestampNow ||
 
3776
      timestampNow - timeout->mTimestampLast > MAX_PLAUSIBLE_PROGRESS ) {
 
3777
    /* need to fix up - either first call or system time changed */
 
3778
    timeout->mFixups += 1;
 
3779
    timeout->mTimestampStart = timestampNow;
 
3780
    timeout->mTimestampLast = timestampNow;
 
3781
    return 0;
 
3782
  }
 
3783
  if (timestampNow - timeout->mTimestampStart < CIMSERVER_TIMEOUT) {
 
3784
    timeout->mTimestampLast = timestampNow;
 
3785
    return 0; 
 
3786
  } else {
 
3787
    return 1;
 
3788
  }
 
3789
}
 
3790
 
 
3791
/* --------------------------------------------------------------------------*/
 
3792
void initEscanInfo(CMCIConnection * con) {   
 
3793
   con->asynRCntl.escanInfo.base    = 0;
 
3794
   con->asynRCntl.escanInfo.eodoff  = 1;
 
3795
   con->asynRCntl.escanInfo.ssecoff = 0;
 
3796
   con->asynRCntl.escanInfo.curoff  = 0;
 
3797
   con->asynRCntl.escanInfo.section = 0;
 
3798
   con->asynRCntl.escanInfo.sectlen = 0;
 
3799
   con->asynRCntl.escanInfo.prevtotl= 0;
 
3800
   con->asynRCntl.escanInfo.recdtotl= 0;
 
3801
   con->asynRCntl.escanInfo.getnew  = 1;  /* set so we getnext section right away */
 
3802
   con->asynRCntl.escanInfo.parsestate = PARSTATE_INIT;
 
3803
   con->asynRCntl.escanlock         = init_mutex;
 
3804
   con->asynRCntl.xfer_cond_mutex   = init_mutex;
 
3805
   con->asynRCntl.xfer_cond         = init_cond; 
 
3806
}
 
3807
/* --------------------------------------------------------------------------*/
 
3808
 
 
3809
#endif