Beispiel #1
0
int
enqRetry(RTElement * element, const CMPIContext * ctx, int repo)
{

  _SFCB_ENTER(TRACE_INDPROVIDER, "enqRetry");
  // Put this one on the retry queue
  if (pthread_mutex_lock(&RQlock) != 0) {
    // lock failed
    return 1;
  }
  if (RQhead == NULL) {
    // Queue is empty
    _SFCB_TRACE(1,("--- Adding indication to new retry queue."));
    RQhead = element;
    RQtail = element;
    RQtail->next = element;
    RQtail->prev = element;
  } else {
    _SFCB_TRACE(1,("--- Adding indication to retry queue."));
    element->next = RQtail->next;
    element->next->prev = element;
    RQtail->next = element;
    element->prev = RQtail;
    RQtail = element;
  }
  if (pthread_mutex_unlock(&RQlock) != 0) {
    // lock failed
    return 1;
  }
  _SFCB_RETURN(0);
}
CMPIInstance   *
internalProviderGetInstance(const CMPIObjectPath * cop, CMPIStatus *rc)
{
  int             len;
  CMPIString     *cn = CMGetClassName(cop, NULL);
  CMPIString     *ns = CMGetNameSpace(cop, NULL);
  char           *key = normalizeObjectPathCharsDup(cop);
  CMPIInstance   *ci = NULL;
  const char     *nss = ns->ft->getCharPtr(ns, NULL);
  const char     *cns = cn->ft->getCharPtr(cn, NULL);
  const char     *bnss = repositoryNs(nss);
  CMPIStatus      st = { CMPI_RC_OK, NULL };

  _SFCB_ENTER(TRACE_INTERNALPROVIDER, "internalProviderGetInstance");
  _SFCB_TRACE(1, ("--- Get instance for %s %s %s", nss, cns, key));

  if (testNameSpace(bnss, rc) == 0) {
    _SFCB_TRACE(1, ("--- Invalid namespace %s", nss));
    free(key);
    _SFCB_RETURN(NULL);
  }

  ci = ipGetBlob(bnss, cns, key, &len);

  if (ci == NULL) {
    _SFCB_TRACE(1, ("--- Instance not found"));
    st.rc = CMPI_RC_ERR_NOT_FOUND;
  }

  *rc = st;
  free(key);
  _SFCB_RETURN(ci);
}
int
enqRetry(RTElement * element, const CMPIContext * ctx, int repo)
{

  _SFCB_ENTER(TRACE_INDPROVIDER, "enqRetry");
  // Put this one on the retry queue
  if (pthread_mutex_lock(&RQlock) != 0) {
    // lock failed
    return 1;
  }
  if (RQhead == NULL) {
    // Queue is empty
    _SFCB_TRACE(1,("--- Adding indication to new retry queue."));
    RQhead = element;
    RQtail = element;
    RQtail->next = element;
    RQtail->prev = element;
  } else {
    _SFCB_TRACE(1,("--- Adding indication to retry queue."));
    element->next = RQtail->next;
    element->next->prev = element;
    RQtail->next = element;
    element->prev = RQtail;
    RQtail = element;
  }
  if (repo==1) {
    // If this needs to be persisted in the repo 
    // (not the initial fill from refillRetryQ)
    _SFCB_TRACE(1,("--- Creating SFCB_IndicationElement instance."));
    CMPIObjectPath * op=CMNewObjectPath(_broker,"root/interop","SFCB_IndicationElement",NULL);
    // Add the indID as the only key
    CMAddKey(op,"IndicationID",&element->instanceID,CMPI_uint32);
    // Create the instance
    //element->SFCBIndEle=op;
    element->SFCBIndEle=op->ft->clone(op,NULL);
    CMPIInstance * ci=CMNewInstance(_broker,op,NULL);
    // Set all the properties
    CMSetProperty(ci,"IndicationID",&element->instanceID,CMPI_uint32);
    CMSetProperty(ci,"RetryCount",&(RQtail->count),CMPI_uint32);
    CMSetProperty(ci,"LastDelivery",&(RQtail->lasttry),CMPI_sint32);
    CMSetProperty(ci,"ld",&(element->ref),CMPI_ref);
    CMSetProperty(ci,"ind",&element->ind,CMPI_ref);
    CMSetProperty(ci,"sub",&element->sub,CMPI_ref);
    CBCreateInstance(_broker, ctx, op, ci, NULL);
    CMRelease(op);
    CMRelease(ci);
  }

  if (pthread_mutex_unlock(&RQlock) != 0) {
    // lock failed
    return 1;
  }
  _SFCB_RETURN(0);
}
CMPIStatus
IndCIMXMLHandlerMethodCleanup(CMPIMethodMI * mi,
                              const CMPIContext *ctx,
                              CMPIBoolean terminating)
{
  CMPIStatus      st = { CMPI_RC_OK, NULL };
  _SFCB_ENTER(TRACE_INDPROVIDER, "IndCIMXMLHandlerMethodCleanup");
  if (retryRunning == 1) {
    _SFCB_TRACE(1, ("--- Stopping indication retry thread"));
    pthread_kill(t, SIGUSR2);
    // Wait for thread to complete
    pthread_join(t, NULL);
    _SFCB_TRACE(1, ("--- Indication retry thread stopped"));
  }
  _SFCB_RETURN(st);
}
Beispiel #5
0
static CMPIStatus
ClassProviderGetClass(CMPIClassMI * mi,
                      const CMPIContext *ctx,
                      const CMPIResult *rslt,
                      const CMPIObjectPath * ref, const char **properties)
{
  CMPIStatus      st = { CMPI_RC_OK, NULL };
  CMPIString     *cn = CMGetClassName(ref, NULL);
  CMPIConstClass *cl,
                 *clLocal;
  ClassRegister  *cReg;
  int             rc;
  ReadCtl         ctl;

  _SFCB_ENTER(TRACE_PROVIDERS, "ClassProviderGetClass");
  _SFCB_TRACE(1, ("--- ClassName=\"%s\"", (char *) cn->hdl));

  cReg = getNsReg(ref, &rc);
  if (cReg == NULL) {
    CMPIStatus      st = { CMPI_RC_ERR_INVALID_NAMESPACE, NULL };
    _SFCB_RETURN(st);
  }

  cReg->ft->wLock(cReg);

  ctl = stdRead;
  clLocal = getResolvedClass(cReg, (char *) cn->hdl, NULL, &ctl);
  if (clLocal) {
    /*
     * Make a cloned copy of the cached results to prevent thread
     * interference. 
     */
    _SFCB_TRACE(1, ("--- Class found"));
    cl = clLocal->ft->clone(clLocal, NULL);
    memLinkInstance((CMPIInstance *) cl);
    CMReturnInstance(rslt, (CMPIInstance *) cl);
    if (ctl != cached)
      CMRelease(cl);
  } else {
    _SFCB_TRACE(1, ("--- Class not found"));
    st.rc = CMPI_RC_ERR_NOT_FOUND;
  }

  cReg->ft->wUnLock(cReg);

  _SFCB_RETURN(st);
}
int refillRetryQ (const CMPIContext * ctx)
{
  _SFCB_ENTER(TRACE_INDPROVIDER, "refillRetryQ");  
  int qfill=0;
  if (RQhead==NULL) {
    // The queue is empty, check if there are instances to be restored
    CMPIObjectPath * op=CMNewObjectPath(_broker,"root/interop","SFCB_IndicationElement",NULL);
    CMPIEnumeration * enm = _broker->bft->enumerateInstances(_broker, ctx, op, NULL, NULL);
    while(enm && enm->ft->hasNext(enm, NULL)) {
    // get the properties from the repo instance
      CMPIData inst=CMGetNext(enm,NULL);
      CMPIData indID=CMGetProperty(inst.value.inst,"indicationID",NULL);
      CMPIData rcount=CMGetProperty(inst.value.inst,"retryCount",NULL);
      CMPIData last=CMGetProperty(inst.value.inst,"lastDelivery",NULL);
      CMPIData ind=CMGetProperty(inst.value.inst,"ind",NULL);
      CMPIData sub=CMGetProperty(inst.value.inst,"sub",NULL);
      CMPIData ld=CMGetProperty(inst.value.inst,"ld",NULL);
      _SFCB_TRACE(1,("--- Requeueing indication id:%d",indID.value.Int));
      // Rebuild the queue element
      RTElement *element;
      element = (RTElement *) malloc(sizeof(*element));
      element->instanceID=indID.value.Int;
      element->lasttry=last.value.Int;
      element->count=rcount.value.Int;
      element->ind=ind.value.ref->ft->clone(ind.value.ref,NULL);
      element->ref=ld.value.ref->ft->clone(ld.value.ref,NULL);
      element->sub=sub.value.ref->ft->clone(sub.value.ref,NULL);
      CMPIObjectPath * indele=CMGetObjectPath(inst.value.inst,NULL);
      element->SFCBIndEle=indele->ft->clone(indele,NULL);
      // call enq
      enqRetry(element,ctx,0);
      qfill=1;
    }
    // spawn thread if we queued anything
    if ((qfill == 1 ) && (retryRunning == 0)) {
      retryRunning=1;
      _SFCB_TRACE(1,("--- Starting retryExport thread"));
      pthread_attr_init(&tattr);
      pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED);
      CMPIContext * pctx = native_clone_CMPIContext(ctx);
      pthread_create(&t, &tattr,&retryExport,(void *) pctx);
    }
  }

  _SFCB_RETURN(0); 
}
Beispiel #7
0
static CMPIConstClass *
getResolvedClass(ClassRegister * cr, const char *clsName,
                 ClassRecord * crec, ReadCtl * rctl)
{
  _SFCB_ENTER(TRACE_PROVIDERS, "getResolvedClass");
  _SFCB_TRACE(1, ("--- classname %s cReg %p", clsName, cr));
  CMPIConstClass *cc = NULL,
      *cls;
  ReadCtl         ctl = *rctl;
  ClassBase      *cb = (ClassBase *) cr->hdl;

  if (crec == NULL) {
    crec = cb->ht->ft->get(cb->ht, clsName);
    if (crec == NULL)
      _SFCB_RETURN(NULL);
  }

  if (crec->cachedRCls == NULL) {
    cls = getClass(cr, clsName, &ctl);
    ClClass        *ccl = (ClClass *) cls->hdl;
    if (ccl->hdr.type == HDR_Class)
      return cls;

    char           *pn = (char *) cls->ft->getCharSuperClassName(cls);
    if (pn == NULL) {
      *rctl = ctl;
      return cls;
    }

    ClClass        *mc = ClClassNew(clsName, pn);
    cc = NEW(CMPIConstClass);
    cc->ft = CMPIConstClassFT;
    cc->hdl = mc;
    // printf("#-# merging %s %s\n",clsName,pn);
    mergeParents(cr, mc, pn, cls, rctl);

    if (*rctl == tempRead)
      _SFCB_RETURN(cc);

    crec->cachedRCls = cc;
    cb->cachedRCount++;
    if (cb->cachedRCount >= cSize)
      pruneRCache(cr);          /* should this be checking rSize? */
    ENQ_TOP_LIST(crec, cb->firstRCached, cb->lastRCached, nextRCached,
                 prevRCached);
  } else {
    // printf("-#- class %s in resolved cache
    // %p\n",clsName,crec->cachedRCls);
    if (crec != cb->firstRCached) {
      DEQ_FROM_LIST(crec, cb->firstRCached, cb->lastRCached, nextRCached,
                    prevRCached);
      ENQ_TOP_LIST(crec, cb->firstRCached, cb->lastRCached, nextRCached,
                   prevRCached);
    }
  }
  *rctl = cached;
  _SFCB_RETURN(crec->cachedRCls);
}
Beispiel #8
0
static CMPIConstClass *
getClass(ClassRegister * cr, const char *clsName)
{
  _SFCB_ENTER(TRACE_PROVIDERS, "getClass");
  _SFCB_TRACE(1, ("--- classname %s cReg %p", clsName, cr));
  ClassBase      *cb = (ClassBase *) cr->hdl;
  CMPIConstClass *cls = cb->ht->ft->get(cb->ht, clsName);
  _SFCB_RETURN(cls);
}
Beispiel #9
0
static CMPIConstClass *
getClass(ClassRegister * cr, const char *clsName, enum readCtl *ctl)
{
  ClassRecord    *crec;
  int             r;
  CMPIConstClass *cc;
  char           *buf;

  _SFCB_ENTER(TRACE_PROVIDERS, "getClass");
  _SFCB_TRACE(1, ("--- classname %s cReg %p", clsName, cr));
  ClassBase      *cb = (ClassBase *) cr->hdl;

  crec = cb->ht->ft->get(cb->ht, clsName);
  if (crec == NULL) {
    _SFCB_RETURN(NULL);
  }

  if (crec->cachedCCls == NULL) {
    r = gzseek(cr->f, crec->position, SEEK_SET);
    buf = (char *) malloc(crec->length);
    r = gzread(cr->f, buf, crec->length);

    cc = NEW(CMPIConstClass);
    cc->hdl = buf;
    cc->ft = CMPIConstClassFT;
    cc->ft->relocate(cc);

    if (*ctl == tempRead)
      _SFCB_RETURN(cc);
    // printf("-#- class %s Added %p\n",clsName,cc);

    crec->cachedCCls = cc;
    cb->cachedCCount++;
    if (cb->cachedCCount >= cSize)
      pruneCCache(cr);
    ENQ_TOP_LIST(crec, cb->firstCCached, cb->lastCCached, nextCCached,
                 prevCCached);
    *ctl = cached;
  } else {
    // printf("-#- class %s in cache %p\n",clsName,crec->cachedCCls);
    if (crec != cb->firstCCached) {
      DEQ_FROM_LIST(crec, cb->firstCCached, cb->lastCCached, nextCCached,
                    prevCCached);
      ENQ_TOP_LIST(crec, cb->firstCCached, cb->lastCCached, nextCCached,
                   prevCCached);
    }
  }
  *ctl = cached;
  _SFCB_RETURN(crec->cachedCCls);
}
Beispiel #10
0
static CMPIStatus
ClassProviderGetClass(CMPIClassMI * mi,
                      const CMPIContext *ctx,
                      const CMPIResult *rslt,
                      const CMPIObjectPath * ref, const char **properties)
{
  CMPIStatus      st = { CMPI_RC_OK, NULL };
  CMPIString     *cn = CMGetClassName(ref, NULL);
  CMPIConstClass *cl;
  ClassRegister  *cReg;
  int             rc;

  _SFCB_ENTER(TRACE_PROVIDERS, "ClassProviderGetClass");
  _SFCB_TRACE(1, ("--- ClassName=\"%s\"", (char *) cn->hdl));

  cReg = getNsReg(ref, &rc);
  if (cReg == NULL) {
    CMPIStatus      st = { CMPI_RC_ERR_INVALID_NAMESPACE, NULL };
    _SFCB_RETURN(st);
  }

  cReg->ft->rLock(cReg);

  cl = getClass(cReg, (char *) cn->hdl);
  if (cl) {
    _SFCB_TRACE(1, ("--- Class found"));
    CMReturnInstance(rslt, (CMPIInstance *) cl);
  } else {
    _SFCB_TRACE(1, ("--- Class not found"));
    st.rc = CMPI_RC_ERR_NOT_FOUND;
  }

  cReg->ft->rUnLock(cReg);

  _SFCB_RETURN(st);
}
Beispiel #11
0
static void loopOnChildChars(ClassRegister *cReg, char *cn, CMPIArray *ar, int *i, int ignprov)
{
   UtilList *ul = getChildren(cReg,cn);
   char *child;

   _SFCB_ENTER(TRACE_PROVIDERS, "loopOnChildChars");
   _SFCB_TRACE(1,("--- class %s",cn));

   if (ul) for (child = (char *) ul->ft->getFirst(ul); child;  
         child=(char*)ul->ft->getNext(ul)) {
      if (ignprov || repCandidate(cReg, child)) {
         CMSetArrayElementAt(ar, *i, child, CMPI_chars);
         *i=(*i)+1;
      }
      loopOnChildChars(cReg, child,ar,i,ignprov);
   }
   _SFCB_EXIT();
}
static CMPIConstClass *
assocForName(const char *nameSpace, const char *assocClass,
             const char *role, const char *resultRole)
{
  CMPIConstClass *cc = getConstClass(nameSpace, assocClass);

  _SFCB_ENTER(TRACE_INTERNALPROVIDER, "assocForName");
  _SFCB_TRACE(1,
              ("--- nameSpace: %s assocClass: %s cc: %p", nameSpace,
               assocClass, cc));

  if (cc != NULL && cc->ft->isAssociation(cc) != 0 &&
      (role == NULL
       || (cc->ft->getProperty(cc, role, NULL).state & CMPI_notFound) == 0)
      && (resultRole == NULL
          || (cc->ft->getProperty(cc, resultRole,
                                  NULL).state & CMPI_notFound) == 0)) {
    _SFCB_RETURN(cc);
  } else
    _SFCB_RETURN(NULL);
}
CMPIStatus
deliverInd(const CMPIObjectPath * ref, const CMPIArgs * in, CMPIInstance * ind)
{
  _SFCB_ENTER(TRACE_INDPROVIDER, "deliverInd");
  CMPIInstance   *hci,
                 *sub;
  CMPIStatus      st = { CMPI_RC_OK, NULL };
  CMPIString     *dest;
  char            strId[64];
  ExpSegments     xs;
  UtilStringBuffer *sb;
  static int      id = 1;
  char           *resp;
  char           *msg;

  if ((hci = internalProviderGetInstance(ref, &st)) == NULL) {
    setStatus(&st, CMPI_RC_ERR_NOT_FOUND, NULL);
    _SFCB_RETURN(st);
  }
  dest = CMGetProperty(hci, "destination", NULL).value.string;
  _SFCB_TRACE(1, ("--- destination: %s\n", (char *) dest->hdl));
  sub = CMGetArg(in, "subscription", NULL).value.inst;

  sprintf(strId, "%d", id++);
  xs = exportIndicationReq(ind, strId);
  sb = segments2stringBuffer(xs.segments);
  if (exportIndication
      ((char *) dest->hdl, (char *) sb->ft->getCharPtr(sb), &resp, &msg)) {
    setStatus(&st, CMPI_RC_ERR_FAILED, NULL);
  }
  RespSegment     rs = xs.segments[5];
  UtilStringBuffer *usb = (UtilStringBuffer *) rs.txt;
  CMRelease(usb);
  CMRelease(sb);
  if (resp)
    free(resp);
  if (msg)
    free(msg);
  _SFCB_RETURN(st);
}
Beispiel #14
0
static CMPIConstClass *getClass(ClassRegister * cr, const char *clsName, void **id)
{
   ClassRecord *crec;
   int r;
   CMPIConstClass *cc;
   char *buf;
   
   _SFCB_ENTER(TRACE_PROVIDERS, "getClass");
   _SFCB_TRACE(1,("--- classname %s cReg %p",clsName,cr));
   ClassBase *cb = (ClassBase *) cr->hdl;
   
   crec = cb->ht->ft->get(cb->ht, clsName);
   if (crec==NULL) {
      _SFCB_RETURN(NULL);
   }
   
   if (crec->cachedCls==NULL) {
//   fprintf(stderr,"--- reading class %s\n",clsName);
      r=gzseek(cr->f, crec->position, SEEK_SET);
      buf = (char *) malloc(crec->length);
      r=gzread(cr->f, buf, crec->length);  
   
      cc = NEW(CMPIConstClass);
      cc->hdl = buf;
      cc->ft = CMPIConstClassFT;
      cc->ft->relocate(cc);
      crec->cachedCls=cc;
      cb->cachedCount++;
      if (cb->cachedCount>=cacheLimit) pruneCache(cr);
      ENQ_TOP_LIST(crec,cb->firstCached,cb->lastCached,nextCached,prevCached);
   }
   else {
      if (crec!=cb->firstCached) {
         DEQ_FROM_LIST(crec,cb->firstCached,cb->lastCached,nextCached,prevCached);
         ENQ_TOP_LIST(crec,cb->firstCached,cb->lastCached,nextCached,prevCached);
      }
//      fprintf(stderr,"--- in cache class %s\n",clsName);
   }   
   _SFCB_RETURN(crec->cachedCls);   
}
Beispiel #15
0
/*
 * S E M A P H O R E
 */
static void handleDbpSession(int connFd) {
	
	CommHndl conn_fd;
   	struct sembuf procReleaseUnDo = {0,1,SEM_UNDO};

   	int r,b2,c, by=0, h;
 
   	char buffer[1024],bc[1];
   	char buffer2[500];
   	char *response=NULL; 	//Fehlermeldung reinschreiben und an Client zurückschicken.
   					//Vermutlich später nicht mehr notwendig!!
   	char *header=NULL;char *payload;
   	int nbytes;
      
   
   _SFCB_ENTER(TRACE_DBPDAEMON, "handledbpRequest");
   _SFCB_TRACE(1, ("--- Forking sql handler"));
   		
   // printf("dbpProcSem %p dbpProcId: %d hMax: %d doFork: %d\n",dbpProcSem,dbpProcId,hMax,doFork);
   // printf("dbpProcId: %d hMax: %d doFork: %d\n",dbpProcId,hMax,doFork);
    if (doFork) {
      	semAcquire(dbpWorkSem,0);
      	semAcquire(dbpProcSem,0);
      	for (dbpProcId=0; dbpProcId<hMax; dbpProcId++)
        	if (semGetValue(dbpProcSem,dbpProcId+1)==0) break;
        printf("dbpProcId: %d hMax: %d\n",dbpProcId,hMax);
      	procReleaseUnDo.sem_num=dbpProcId+1; 
         
      	r = fork();

      	if (r==0) {
         	currentProc=getpid();
         	processName="CIMSQL-Processor";
         	semRelease(dbpProcSem,0);
         	semAcquireUnDo(dbpProcSem,0);
         	semReleaseUnDo(dbpProcSem,dbpProcId+1);
         	semRelease(dbpWorkSem,0);

         	if (sfcbSSLMode) {
#if defined USE_SSL
            	conn_fd.socket=-2;
            	conn_fd.bio=BIO_new(BIO_s_socket());
            	BIO_set_fd(conn_fd.bio,connFd,BIO_CLOSE);
            	if (!(conn_fd.ssl = SSL_new(ctx)))
               		intSSLerror("Error creating SSL context");
            	SSL_set_bio(conn_fd.ssl, conn_fd.bio, conn_fd.bio);
            	if (SSL_accept(conn_fd.ssl) <= 0)
               		intSSLerror("Error accepting SSL connection");
#endif
         	}
         	else {
            	conn_fd.socket=connFd;
#if defined USE_SSL
            	conn_fd.bio=NULL;
            	conn_fd.ssl=NULL;
#endif
         	}
      	}
      	else if (r>0) {
         	running++;
         	_SFCB_EXIT();
      	}
   	}
   	else r = 0;

  	if (r < 0) {
      	char *emsg=strerror(errno);
      	mlogf(M_ERROR,M_SHOW,"--- fork handler: %s\n",emsg);
      	exit(1);
   	}

   	if (r == 0) {
      	if (doFork) {
         	_SFCB_TRACE(1,("--- Forked sql handler %d", currentProc))
         	resultSockets=sPairs[hBase+dbpProcId];
      	}

      	_SFCB_TRACE(1,("--- Started sql handler %d %d", currentProc,
                   resultSockets.receive));

      	if (getenv("SFCB_PAUSE_HTTP")) for (;;) {
        	fprintf(stderr,"-#- Pausing - pid: %d\n",currentProc);
         	sleep(5);
      	}   
       
      	conn_fd.socket=connFd;
#if defined USE_SSL
      	conn_fd.bio=NULL;
      	conn_fd.ssl=NULL;
#endif
    	for(;;){ 
     	//c onn_fd.socket=connFd;

     	// doHttpRequest(conn_fd);
			nbytes = read (connFd, buffer, HEADER);
			header = (char *) malloc(nbytes);//sowas wie \n Steuerzeichen
			strncpy(header,buffer,nbytes);
   			header[nbytes]=0;
			h = atoi(header);
				printd("Ein Client h: %d header: %s nbytes: %d\n",h,header,nbytes);
			//Sonderfall, noch nicht eingeloggt
			if(by&h){
				//login
				nbytes = read(connFd, buffer, 2);
				c = atoi((char*)&buffer);
				if(c==CONNECT){ 
					printd("Ein Client hat sich korrekt angemeldet\n");
					response = "1 1 1\n";//"Sie sind angemeldet. Warte auf Anfragen:\n";
					write(connFd, response , strlen(response));
					by=0;
					h=CONTINUE;//dummy, um switch sofort zu verlassen
				}
				else{
					printd("Ein Client hat sich NICHT korrekt angemeldet %d\n",c);
					response = "1 1 0\n";//"Sie sind nicht angemeldet. Auf wiedersehen.\n";
					write(connFd, response , strlen(response));
					break;
				} 
				while((nbytes = read(connFd, bc, 1))>0)//
	  				if(bc[0]=='\n')
	  					break;
			}
			if(by){
				printd("Ein Client hat sich NICHT korrekt angemeldet %d\n",h);
				response = "1 1 0\n";//"Sie sind nicht angemeldet. Auf wiedersehen.\n";
				write(connFd, response , strlen(response));
				break;	
			}
			switch(h){
				case CONTINUE: break;
				case PROTOCOL: {
					nbytes = read(connFd, buffer, 2);
					c = atoi((char*)&buffer);
					
					//Pipe leersaugen
					while((nbytes = read(connFd, bc, 1))>0)//
	      				if(bc[0]=='\n')
	      					break;
						
						
						if(c==CONNECT){ 
						   	response = "1 1 0\n"; //"Sie sind bereits angemeldet, Operation wird ignoriert:\n";
							write(connFd, response , strlen(response));
						}
						else if(c==LOGOUT){
							printd("Der Client hat die Verbindung beendet\n");
					   		response = "1 2 1\n";//"By\n";
				    		write(connFd, response ,strlen(response));
				    		by=1; 
						}
						else{
							b2 = sprintf(buffer2,"%d %d %d",1,c,0);//sprintf(buffer2, "Syntxfehler: Operation %d ist keine Protokolloperation\n",c);
							printd("%s",buffer2);
	   						write(connFd, buffer2 , b2);
						}
					break;	
				}
				case SQL:
					while((nbytes = read(connFd, buffer, 1024))>0){
						if(buffer[nbytes-1]=='\n')
							break;
						//falls Anweisung laenerg als 1024, muss buffer mit vorgaengerbuffer konkadiniert werden. vgl. adrian		
					}
					// abschließendes $ finden:
					
					//printd("SQL: %d\n",nbytes);
					nbytes--;
					while((nbytes>0) && (buffer[nbytes]!='$'))
						nbytes--;
					//printf("malloc %d bytes",nbytes);
					payload = (char *) malloc(nbytes+1+1);
					
					//ein \n voranstellen, yyerror()s wegen
					//*payload = '\n';
					strcpy(payload,"\n");
					strncat(payload,buffer,nbytes);
					
					response = processSQLQuery(payload,conn_fd); //--> Datenstruktur, in die das Statement reinkommt
					
					free(payload);payload=NULL;	
					//ResultMetaData
					
					
					write(connFd, response , strlen(response)); 
					free(response);response=NULL;
					
					break;
				case META:  
					nbytes = read(connFd, buffer, 2);
					c = atoi((char*)&buffer);
					if(c==METADB){
						response = (char *) malloc(strlen(metaDB)+7);
						response = strcpy(response,"3 1 1\n");
						response = strcat(response,metaDB);
						write(connFd, response , strlen(response));
						free(response);
						break;
					}
					
					if(c==TABLES||c==STABLES||c==KEYS||c==COLS){
					  //printf("UND los\n");
						
						while((nbytes = read(connFd, buffer, 1024))>0){
							if(buffer[nbytes-1]=='\n')
								break;
							//falls Anweisung laenerg als 1024, muss buffer mit vorgaengerbuffer konkadiniert werden. vgl. adrian		
						}
						// abschließendes $ finden:
					
						printd("SQL: %d\n",nbytes);
						nbytes--;
						while((nbytes>0) && (buffer[nbytes]!='$'))
							nbytes--;
						//printf("malloc %d bytes",nbytes);
						
						buffer[nbytes] = 0;
						if(nbytes==0)
							payload = NULL;
						else{
							payload = (char *) malloc(nbytes+1);
							strcpy(payload,buffer);
							//printd(">%s< %d\n",payload,c);
						}
						if(c==TABLES)
							response = processMetaTables(payload,"root/cimv2");
						else if(c==STABLES)
							response = processSuperTables(payload,"root/cimv2");
						else if(c==KEYS)
							response = processKeyTable(payload,"root/cimv2");
						else if(c==COLS){
							char *arg2 = strstr(payload,"::");
							
							char *arg1 = strtok(payload,"::");
							//printf("lllllll\n");
							//printf(">%s< >%s< >%s< >%s<\n",payload,arg2,arg1,arg2+2);
							response = processMetaColumns(arg1,arg2+2,"root/cimv2");
							//printf("zurück\n");
						}
						//printf(">>%s<<",response);
						free(payload);payload=NULL;
						write(connFd, response , strlen(response));
						//free(response);
						//dieses free tut nicht, weil irgendwo anders was nicht stimmt!!!
						break;	
					}
					break;
				case SPOOLIN: break;
				case SPOOLOUT: break;
				default: 
					printd("Unbekannter Befehl: \"%s\"\n",header);
					b2 = sprintf(buffer2,"Fehler: unbekannter Befehl:  %s \n", header);
					//strncpy(response,buffer2,b2);
				
	    			//response = "Fehler: Unbekannter Befehl\n";
	    			write(connFd, buffer2 , b2);
	    			break;
				
				
			}
	     	free(header);
	      	if(by)
	      		break;
      	}
      
      
     	if (!doFork) return;

      	_SFCB_TRACE(1, ("--- SQL handler exiting %d", currentProc));
      	printf("--- SQL handler exiting %d\n", currentProc);
      	dumpTiming(currentProc);
      	exit(0);
   }
        
    
}
Beispiel #16
0
static CMPIStatus
ClassProviderInvokeMethod(CMPIMethodMI * mi,
                          const CMPIContext *ctx,
                          const CMPIResult *rslt,
                          const CMPIObjectPath * ref,
                          const char *methodName,
                          const CMPIArgs * in, CMPIArgs * out)
{
  CMPIStatus      st = { CMPI_RC_OK, NULL };
  CMPIArray      *ar;
  int             rc;
  ClassRegister  *cReg;

  _SFCB_ENTER(TRACE_PROVIDERS, "ClassProviderInvokeMethod");

  cReg = getNsReg(ref, &rc);
  if (cReg == NULL) {
    CMPIStatus      st = { CMPI_RC_ERR_INVALID_NAMESPACE, NULL };
    _SFCB_RETURN(st);
  }

  if (strcasecmp(methodName, "getchildren") == 0) {
    CMPIData        cn = CMGetArg(in, "class", NULL);
    _SFCB_TRACE(1, ("--- getchildren %s", (char *) cn.value.string->hdl));

    cReg->ft->wLock(cReg);

    if (cn.type == CMPI_string && cn.value.string && cn.value.string->hdl) {
      char           *child;
      int             l = 0,
          i = 0;
      UtilList       *ul =
          getChildren(cReg, (char *) cn.value.string->hdl);
      if (ul)
        l = ul->ft->size(ul);
      ar = CMNewArray(_broker, l, CMPI_string, NULL);
      if (ul)
        for (child = (char *) ul->ft->getFirst(ul); child; child = (char *)
             ul->ft->getNext(ul)) {
          CMSetArrayElementAt(ar, i++, child, CMPI_chars);
        }
      st = CMAddArg(out, "children", &ar, CMPI_stringA);
    } else {
    }

    cReg->ft->wUnLock(cReg);

  }

  else if (strcasecmp(methodName, "getallchildren") == 0) {
    int             ignprov = 0;
    CMPIStatus      st;
    CMPIData        cn = CMGetArg(in, "class", &st);

    cReg->ft->wLock(cReg);

    if (st.rc != CMPI_RC_OK) {
      cn = CMGetArg(in, "classignoreprov", NULL);
      ignprov = 1;
    }
    _SFCB_TRACE(1,
                ("--- getallchildren %s", (char *) cn.value.string->hdl));
    if (cn.type == CMPI_string && cn.value.string && cn.value.string->hdl) {
      int             n = 0,
          i = 0;
      loopOnChildCount(cReg, (char *) cn.value.string->hdl, &n, ignprov);
      _SFCB_TRACE(1, ("--- count %d", n));
      ar = CMNewArray(_broker, n, CMPI_string, NULL);
      if (n) {
        _SFCB_TRACE(1, ("--- loop %s", (char *) cn.value.string->hdl));
        loopOnChildChars(cReg, (char *) cn.value.string->hdl, ar, &i,
                         ignprov);
      }
      st = CMAddArg(out, "children", &ar, CMPI_stringA);
    } else {
    }

    cReg->ft->wUnLock(cReg);
  }

  else if (strcasecmp(methodName, "getassocs") == 0) {
    ar = CMNewArray(_broker, cReg->topAssocs, CMPI_string, NULL);
    ClassBase      *cb = (ClassBase *) (cReg + 1);
    UtilHashTable  *ct = cb->ht;
    HashTableIterator *i;
    char           *cn;
    ClassRecord    *crec;
    int             n;

    cReg->ft->wLock(cReg);

    for (n = 0, i = ct->ft->getFirst(ct, (void **) &cn, (void **) &crec);
         i; i = ct->ft->getNext(ct, i, (void **) &cn, (void **) &crec)) {
      if (crec->flags & CREC_isAssociation && crec->parent == NULL) {
        /*
         * add top-level association class 
         */
        CMSetArrayElementAt(ar, n++, cn, CMPI_chars);
      }
    }
    CMAddArg(out, "assocs", &ar, CMPI_stringA);

    cReg->ft->wUnLock(cReg);
  }

  else if (strcasecmp(methodName, "ischild") == 0) {
    char           *parent = (char *) CMGetClassName(ref, NULL)->hdl;
    char           *chldn =
        (char *) CMGetArg(in, "child", NULL).value.string->hdl;
    st.rc = traverseChildren(cReg, parent, chldn);
  }

  else if (strcasecmp(methodName, "_startup") == 0) {

    /* let providerMgr know that we're odne init'ing  */
    semRelease(sfcbSem,INIT_CLASS_PROV_ID);

    st.rc = CMPI_RC_OK;
  }

  else {
    mlogf(M_ERROR, M_SHOW,
          "--- ClassProvider: Invalid invokeMethod request %s\n",
          methodName);
    st.rc = CMPI_RC_ERR_METHOD_NOT_FOUND;
  }
  _SFCB_RETURN(st);
}
Beispiel #17
0
/*
 * Von httpDaemon aus httpAdapter abgeschrieben.
 *
 */
int dbpDaemon(int argc, char *argv[], int sslMode, int sfcbPid) {//int argc, char *argv[], int sslMode) {
	struct sockaddr_in sin;
   int sin_len,ru;
   socklen_t sz;
   char *cp;
   long procs, port;
   int listenFd, connFd;

   name = argv[0];
   debug = 1;
   doFork = 1;

   _SFCB_ENTER(TRACE_DBPDAEMON, "dbpDaemon");

   setupControl(configfile);
   sfcbSSLMode=sslMode;
   if (sslMode) processName="DBPS-Daemon";
   else processName="DBP-Daemon";

   if (sslMode) {
      if (getControlNum("dbpsPort", &port))
         port = 5981;
      hBase=stBase;
      hMax=stMax;
   }
   else {
      if (getControlNum("dbpPort", &port))
         port = 5980;
      hBase=htBase;
      hMax=htMax;
   }

   if (getControlNum("dbpProcs", &procs))
      procs = 10;
   initDbpProcCtl(procs);

//   if (getControlBool("doBasicAuth", &doBa))
//      doBa=0;
//
//   i = 1;
//   while (i < argc && argv[i][0] == '-') {
//      if (strcmp(argv[i], "-D") == 0)
//         debug = 1;
//      else if (strcmp(argv[i], "-nD") == 0)
//         debug = 0;
//      else if (strcmp(argv[i], "-p") == 0 && i + 1 < argc) {
//         ++i;
//         port = (unsigned short) atoi(argv[i]);
//      }
//      else if (strcmp(argv[i], "-tm") == 0) {
//         if (isdigit(*argv[i + 1])) {
//            ++i;
//         }
//      }
//      else if (strcmp(argv[i], "-F") == 0)
//         doFork = 1;
//      else if (strcmp(argv[i], "-nF") == 0)
//         doFork = 0;
//      else if (strcmp(argv[i], "-H") == 0);
//      ++i;
//   }
//
//   if (getControlBool("useChunking", &noChunking))
//      noChunking=0;
//   noChunking=noChunking==0;

   cp = strrchr(name, '/');
   if (cp != NULL)
      ++cp;
   else  cp = name;
   name = cp;

   if (sslMode) mlogf(M_INFO,M_SHOW,"--- %s DBPS Daemon V" sfcdbpDaemonVersion " started - %d - port %ld\n", 
         name, currentProc,port);
   else mlogf(M_INFO,M_SHOW,"--- %s DBP  Daemon V" sfcdbpDaemonVersion " started - %d - port %ld\n", 
         name, currentProc,port);


   if (doBa) mlogf(M_INFO,M_SHOW,"--- Using Basic Authentication\n");

   listenFd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
   sin_len = sizeof(sin);

   ru = 1;
   setsockopt(listenFd, SOL_SOCKET, SO_REUSEADDR, (char *) &ru, sizeof(ru));

   memset(&sin,0,sin_len);

   sin.sin_family = AF_INET;
   sin.sin_addr.s_addr = INADDR_ANY;
   sin.sin_port = htons(port);

   if (bind(listenFd, (struct sockaddr *) &sin, sin_len) ||
       listen(listenFd, 0)) {
      mlogf(M_ERROR,M_SHOW,"--- Cannot listen on port %ld\n", port);
      kill(sfcbPid,3);
   }

  if (!debug) {
      int rc = fork();
      if (rc == -1) {
         char *emsg=strerror(errno);
         mlogf(M_ERROR,M_SHOW,"--- fork daemon: %s",emsg);
         exit(1);
      }
      else if (rc)
         exit(0);
   }
//   memInit();
    currentProc=getpid();
    setSignal(SIGCHLD, handleSigChld,0);
    setSignal(SIGUSR1, handleSigUsr1,0);
    setSignal(SIGINT, SIG_IGN,0);
    setSignal(SIGTERM, SIG_IGN,0);
    setSignal(SIGHUP, SIG_IGN,0);

 //   commInit();

#if defined USE_SSL
    if (sfcbSSLMode) {
       char *fnc,*fnk;
       ctx = SSL_CTX_new(SSLv23_method());
       getControlChars("sslCertificateFilePath", &fnc);
       if (SSL_CTX_use_certificate_chain_file(ctx, fnc) != 1)
           intSSLerror("Error loading certificate from file");
       getControlChars("sslKeyFilePath", &fnk);
       if (SSL_CTX_use_PrivateKey_file(ctx, fnk, SSL_FILETYPE_PEM) != 1)
           intSSLerror("Error loading private key from file");
    }
#endif

   for (;;) {
   char *emsg;
      listen(listenFd, 1);
      sz = sizeof(sin);
      if ((connFd = accept(listenFd, (__SOCKADDR_ARG) & sin, &sz))<0) {
         if (errno == EINTR || errno == EAGAIN) {
            if (stopAccepting) break;
            continue;
         }   
         emsg=strerror(errno);
         mlogf(M_ERROR,M_SHOW,"--- accept error %s\n",emsg);
         _SFCB_ABORT();
      }
      _SFCB_TRACE(1, ("--- Processing dbp request"));

      handleDbpSession(connFd); 
      close(connFd);
   }
   
   printf("--- %s draining %d\n",processName,running);
   for (;;) {
      if (running==0) {
         mlogf(M_INFO,M_SHOW,"--- %s terminating %d\n",processName,getpid());
         exit(0);
      }   
      sleep(1);
   }   
	



/*   struct sockaddr_in sin;
   int sz,i,sin_len,ru;
   char *cp;//??
   long procs, port;
   int listenFd, connFd;


   name = "sfcBroker";
   //debug = 1;
   //doFork = 1;

   _SFCB_ENTER(TRACE_DBPDAEMON, "dbpDaemon");

   //setupControl(NULL);
   processName="DBP Daemon"; //Variable aus sfcBroker, dieser neue Prozess hat noch keinen zugewiesen bekommen

	//if (getControlNum("httpPort", &port))
        port = 5980;
    //hBase=htBase;
    //hMax=htMax;
   
//initndpProcCtl(procs);
   

   cp = strrchr(name, '/');
   if (cp != NULL)
      ++cp;
   else  cp = name;
   name = cp;

   
   printf("--- %s  DBP  Daemon V" sfcdbpDaemonVersion " started - %d - port %ld\n", name, getpid(),port);



   listenFd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
   sin_len = sizeof(sin);

   ru = 1;
   setsockopt(listenFd, SOL_SOCKET, SO_REUSEADDR, (char *) &ru, sizeof(ru));

   memset(&sin,0,sin_len);

   sin.sin_family = AF_INET;
   sin.sin_addr.s_addr = INADDR_ANY;
   sin.sin_port = htons(port);

   if (bind(listenFd, (struct sockaddr *) &sin, sin_len) ||
       listen(listenFd, 0)) {//Test, ob Port frei ist
      printf("cannot listen on port %ld", port);
      exit(3);
   }

  //if (!debug) {
      int rc = fork();
      if (rc == -1) {
         perror("fork daemon");
         exit(1);
      }
      else if (rc)
         exit(0);
   //}
//   memInit();
//printf("jetzt kann sich jemand verbinden\n");
 //   setSignal(SIGCHLD, handleSigChld,0);
	
    for (;;) {
     	
        listen(listenFd, 1);
        sz = sizeof(sin);
        if ((connFd = accept(listenFd, (__SOCKADDR_ARG) & sin, &sz))<0) {
            if (errno == EINTR || errno == EAGAIN)
            	continue;
        	perror("accept error");
        //  _SFCB_ABORT();
        }
         _SFCB_TRACE(1, ("--- Processing  dbp request"));

	   	printd("es hat sich glaub ich jemand verbunden\n");
	   
	    handleDbpSession(connFd); 
       	close(connFd);
    }
*/
}
CMPIStatus
IndCIMXMLHandlerInvokeMethod(CMPIMethodMI * mi,
                             const CMPIContext *ctx,
                             const CMPIResult *rslt,
                             const CMPIObjectPath * ref,
                             const char *methodName,
                             const CMPIArgs * in, CMPIArgs * out)
{
  _SFCB_ENTER(TRACE_INDPROVIDER, "IndCIMXMLHandlerInvokeMethod");

  CMPIStatus      st = { CMPI_RC_OK, NULL };
  CMPIStatus      circ = { CMPI_RC_OK, NULL };
  struct timeval tv;
  struct timezone tz;
  static unsigned int indID=1;


  if (interOpNameSpace(ref, &st) == 0)
    _SFCB_RETURN(st);

  if (strcasecmp(methodName, "_deliver") == 0) {

    // On the first indication, check if reliable indications are enabled.
    if (RIEnabled == -1) {
      CMPIObjectPath *op=CMNewObjectPath(_broker,"root/interop","CIM_IndicationService",NULL);
      CMPIEnumeration *isenm = _broker->bft->enumerateInstances(_broker, ctx, op, NULL, NULL);
      CMPIData isinst=CMGetNext(isenm,NULL);
      CMPIData mc=CMGetProperty(isinst.value.inst,"DeliveryRetryAttempts",NULL);
      RIEnabled=mc.value.uint16;
    }

    CMPIInstance *indo=CMGetArg(in,"indication",NULL).value.inst;
    CMPIInstance *ind=CMClone(indo,NULL);
    CMPIContext    *ctxLocal=NULL;
    CMPIObjectPath *iop=NULL,*subop=NULL;
    CMPIInstance *sub=NULL;

    if (RIEnabled) {
      ctxLocal = prepareUpcall((CMPIContext *) ctx);
      // Set the indication sequence values
      iop=CMGetObjectPath(ind,NULL);
      CMAddKey(iop,"SFCB_IndicationID",&indID,CMPI_uint32);
      CMSetProperty(ind,"SFCB_IndicationID",&indID,CMPI_uint32);
      // Prevent this property from showing up in the indication
      filterFlagProperty(ind, "SFCB_IndicationID");
      sub=CMGetArg(in,"subscription",NULL).value.inst;
      CMPIData handler=CMGetProperty(sub, "Handler", &st);
      CMPIObjectPath *hop=handler.value.ref;
      CMPIInstance *hdlr=CBGetInstance(_broker, ctxLocal, hop, NULL, &st);

      // Build the complete sequence context
      // Get the stub from the handler
      CMPIString *context = CMGetProperty(hdlr, "SequenceContext", &st).value.string;
      // and add the sfcb start time
      char *cstr=malloc( (strlen(context->ft->getCharPtr(context,NULL)) + strlen(sfcBrokerStart) + 1) * sizeof(char));
      sprintf(cstr,"%s%s",context->ft->getCharPtr(context,NULL),sfcBrokerStart);
      context = sfcb_native_new_CMPIString(cstr, NULL, 0); 
      // and put it in the indication
      CMSetProperty(ind, "SequenceContext", &context, CMPI_string);
      free(cstr);
      CMRelease(context);

      // Get the proper sequence number
      CMPIValue lastseq = CMGetProperty(hdlr, "LastSequenceNumber", &st).value;
      lastseq.sint64++;
      // Handle wrapping of the signed int
      if (lastseq.sint64 < 0) lastseq.sint64=0;
      // Update the last used number in the handler
      CMSetProperty(hdlr, "LastSequenceNumber", &lastseq.sint64, CMPI_sint64);
      CBModifyInstance(_broker, ctxLocal, hop, hdlr, NULL);
      // And the indication
      CMSetProperty(ind, "SequenceNumber", &lastseq, CMPI_sint64);
    }

    // Now send the indication
    st = deliverInd(ref, in, ind);
    if (st.rc != 0) {
      if (RIEnabled){
        _SFCB_TRACE(1,("--- Indication delivery failed, adding to retry queue"));
        // Indication delivery failed, send to retry queue
        // build an element
        RTElement      *element;
        element = (RTElement *) malloc(sizeof(*element));
        element->ref=ref->ft->clone(ref,NULL);
        // Get the OP of the subscription and indication
        subop=CMGetObjectPath(sub,NULL);
        element->sub=subop->ft->clone(subop,NULL);
        element->ind=iop->ft->clone(iop,NULL);
        // Store other attrs
        element->instanceID=indID;
        element->count=0;
        gettimeofday(&tv, &tz);
        element->lasttry=tv.tv_sec;
        // Push the indication to the repo
        CBCreateInstance(_broker, ctxLocal, iop, ind, &circ);
        if (circ.rc != 0) {
            mlogf(M_ERROR,M_SHOW,"Pushing indication instance to repository failed, rc:%d\n",circ.rc);
        }
        indID++;
        // Add it to the retry queue
        enqRetry(element,ctx,1);
        // And launch the thread if it isn't already running
        pthread_attr_init(&tattr);
        pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED);
        if (retryRunning == 0) {
          retryRunning = 1;
          _SFCB_TRACE(1,("--- Starting retryExport thread"));
          CMPIContext    *pctx = native_clone_CMPIContext(ctx);
          pthread_create(&t, &tattr, &retryExport, (void *) pctx);
        }
        CMRelease(ctxLocal);
      }
    }
    CMRelease(ind);
  }
  else {
    printf("--- ClassProvider: Invalid request %s\n", methodName);
    st.rc = CMPI_RC_ERR_METHOD_NOT_FOUND;
  }

  _SFCB_RETURN(st);
}
Beispiel #19
0
static CMPIStatus __rft_returnInstance(const CMPIResult * result,
                                       const CMPIInstance * instance)
{
   int size,isInst=isInstance(instance);
   void *ptr;
   NativeResult *r = (NativeResult*) result;
   int releaseInstance=0;
   CMPIStatus st={CMPI_RC_OK,NULL};
   
   _SFCB_ENTER(TRACE_PROVIDERDRV, "__rft_returnInstance");
   
   if (r->qs) {
      int irc;

      if (r->qs->where) {
         r->qs->propSrc.data=(CMPIInstance *)instance;
         irc=r->qs->where->ft->evaluate(r->qs->where,&r->qs->propSrc);
         if (irc==1) {
            if (r->qs->allProps==0) {
               instance=
		       r->qs->ft->cloneAndFilter(r->qs,(CMPIInstance *)instance,CMGetObjectPath(instance, NULL),r->qs->keys);
               releaseInstance=1;
            }     
         }   
         else CMReturn(CMPI_RC_OK);
      }
      else {
         if (r->qs->allProps==0) {
		 instance=r->qs->ft->cloneAndFilter(r->qs,(CMPIInstance *)instance,CMGetObjectPath(instance,NULL), r->qs->keys);
            releaseInstance=1;
         }
      }        
   }

   if (r->legacy) {
      CMPIValue v;
      CMPIStatus rc;
      _SFCB_TRACE(1,("--- Legacy Mode"));
      if(isInst) {
        v.inst = CMClone(instance,NULL);
        memLinkInstance(v.inst);
      }
      else v.inst = (CMPIInstance *) instance;
      rc=returnData(result, &v, CMPI_instance);
      if (releaseInstance) instance->ft->release((CMPIInstance*)instance);
      _SFCB_RETURN(rc);
   }

   if (isInst) {
      size=getInstanceSerializedSize(instance);
      ptr=nextResultBufferPos(r, MSG_SEG_INSTANCE, (unsigned long)size);
      _SFCB_TRACE(1,("--- Moving instance %d",size));
      getSerializedInstance(instance,ptr); /* memcpy inst to ptr */
   }
   else {
      size=getConstClassSerializedSize((CMPIConstClass*)instance);
      ptr=nextResultBufferPos(r, MSG_SEG_CONSTCLASS, (unsigned long)size);
      _SFCB_TRACE(1,("--- Moving class %d",size));
      getSerializedConstClass((CMPIConstClass*)instance,ptr);
   }

   if (releaseInstance) instance->ft->release((CMPIInstance*)instance);
   _SFCB_RETURN(st);
}
void           *
retryExport(void *lctx)
{
  _SFCB_ENTER(TRACE_INDPROVIDER, "retryExport");

  CMPIObjectPath *ref;
  CMPIArgs       *in;
  CMPIInstance   *sub;
  CMPIContext    *ctx = (CMPIContext *) lctx;
  CMPIContext    *ctxLocal;
  RTElement      *cur,
                 *purge;
  struct timeval  tv;
  struct timezone tz;
  int             rint,
                  maxcount,
                  ract,
                  rtint;
  CMPIUint64      sfc = 0;
  CMPIObjectPath *op;
  CMPIEnumeration *isenm = NULL;

  //Setup signal handlers
  struct sigaction sa;
  sa.sa_handler = handle_sig_retry;
  sa.sa_flags = 0;
  sigemptyset(&sa.sa_mask);
  sigaction(SIGUSR2, &sa, NULL);

  CMPIStatus      st = { CMPI_RC_OK, NULL };

  ctxLocal = prepareUpcall(ctx);

  // Get the retry params from IndService
  op = CMNewObjectPath(_broker, "root/interop", "CIM_IndicationService",
                       NULL);
  isenm = _broker->bft->enumerateInstances(_broker, ctx, op, NULL, NULL);
  CMPIData        isinst = CMGetNext(isenm, NULL);
  CMPIData        mc =
      CMGetProperty(isinst.value.inst, "DeliveryRetryAttempts", NULL);
  CMPIData        ri =
      CMGetProperty(isinst.value.inst, "DeliveryRetryInterval", NULL);
  CMPIData        ra =
      CMGetProperty(isinst.value.inst, "SubscriptionRemovalAction", NULL);
  CMPIData        rti =
      CMGetProperty(isinst.value.inst, "SubscriptionRemovalTimeInterval",
                    NULL);
  maxcount = mc.value.uint16;   // Number of times to retry delivery
  rint = ri.value.uint32;       // Interval between retries
  rtint = rti.value.uint32;     // Time to allow sub to keep failing until 
  ract = ra.value.uint16;       // ... this action is taken

  // Now, run the queue
  sleep(5); //Prevent deadlock on startup when localmode is used.
  pthread_mutex_lock(&RQlock);
  cur = RQhead;
  while (RQhead != NULL) {
    if(retryShutdown) break; // Provider shutdown
    ref = cur->ref;
    // Build the CMPIArgs that deliverInd needs
    CMPIInstance *iinst=internalProviderGetInstance(cur->ind,&st);
    if (st.rc != 0 ) {
      mlogf(M_ERROR,M_SHOW,"Failed to retrieve indication instance from repository, rc:%d\n",st.rc);
      purge=cur;
      cur=cur->next;
      dqRetry(ctx,purge);
      continue;
    }
    in=CMNewArgs(_broker,NULL);
    CMAddArg(in,"indication",&iinst,CMPI_instance);
    sub=internalProviderGetInstance(cur->sub,&st);
    if (st.rc == CMPI_RC_ERR_NOT_FOUND) {
      // sub got deleted, purge this indication and move on
      _SFCB_TRACE(1,("--- Subscription for indication gone, deleting indication."));
      purge = cur;
      cur = cur->next;
      dqRetry(ctx,purge);
    } else {
      // Still valid, retry
      gettimeofday(&tv, &tz);
      if ((cur->lasttry + rint) > tv.tv_sec) {
        _SFCB_TRACE(1,("--- sleeping."));
        // no retries are ready, release the lock
        // and sleep for an interval, then relock
        pthread_mutex_unlock(&RQlock);
        sleep(rint);
        if(retryShutdown) break; // Provider shutdown
        pthread_mutex_lock(&RQlock);
      }
      st = deliverInd(ref, in, iinst);
      if ((st.rc == 0) || (cur->count >= maxcount - 1)) {
        // either it worked, or we maxed out on retries
        // If it succeeded, clear the failtime
        if (st.rc == 0) {
          _SFCB_TRACE(1,("--- Indication succeeded."));
          sfc = 0;
          CMSetProperty(sub, "DeliveryFailureTime", &sfc, CMPI_uint64);
          CBModifyInstance(_broker, ctxLocal, cur->sub, sub, NULL);
        }
        // remove from queue in either case
        _SFCB_TRACE(1,("--- Indication removed."));
        purge = cur;
        cur = cur->next;
        dqRetry(ctx,purge);
      } else {
        // still failing, leave on queue 
        _SFCB_TRACE(1,("--- Indication still failing."));
        cur->count++;
        gettimeofday(&tv, &tz);
        cur->lasttry = tv.tv_sec;

        CMPIInstance * indele=internalProviderGetInstance(cur->SFCBIndEle,&st);
        CMSetProperty(indele,"LastDelivery",&cur->lasttry,CMPI_sint32);
        CMSetProperty(indele,"RetryCount",&cur->count,CMPI_uint32);
        CBModifyInstance(_broker, ctxLocal, cur->SFCBIndEle, indele, NULL);

        CMPIData        sfcp =
            CMGetProperty(sub, "DeliveryFailureTime", NULL);
        sfc = sfcp.value.uint64;
        if (sfc == 0) {
          // if the time isn't set, this is the first failure
          sfc = tv.tv_sec;
          CMSetProperty(sub, "DeliveryFailureTime", &sfc, CMPI_uint64);
          CBModifyInstance(_broker, ctxLocal, cur->sub, sub, NULL);
          cur = cur->next;
        } else if (sfc + rtint < tv.tv_sec) {
          // Exceeded subscription removal threshold, if action is:
          // 2, delete the sub; 3, disable the sub; otherwise, nothing
          if (ract == 2) {
            _SFCB_TRACE(1,("--- Subscription threshold reached, deleting."));
            CBDeleteInstance(_broker, ctx, cur->sub);
            purge = cur;
            cur = cur->next;
            dqRetry(ctx,purge);
          } else if (ract == 3) {
            // Set sub state to disable(4)
            _SFCB_TRACE(1,("--- Subscription threshold reached, disable."));
            CMPIUint16      sst = 4;
            CMSetProperty(sub, "SubscriptionState", &sst, CMPI_uint16);
            CBModifyInstance(_broker, ctx, cur->sub, sub, NULL);
            purge = cur;
            cur = cur->next;
            dqRetry(ctx,purge);
          }
        } else {
          cur = cur->next;
        }
      }
    }
  }
  // Queue went dry, cleanup and exit
  _SFCB_TRACE(1,("--- Indication retry queue empty, thread exitting."));
  pthread_mutex_unlock(&RQlock);
  retryRunning = 0;
  CMRelease(ctxLocal);
  CMRelease(ctx);
  _SFCB_RETURN(NULL);
}
CMPIStatus
InternalProviderEnumInstanceNames(CMPIInstanceMI * mi,
                                  const CMPIContext *ctx,
                                  const CMPIResult *rslt,
                                  const CMPIObjectPath * ref)
{
  CMPIStatus      st = { CMPI_RC_OK, NULL };
  CMPIStatus      sti = { CMPI_RC_OK, NULL };
  BlobIndex      *bi;
  CMPIString     *cn = CMGetClassName(ref, NULL);
  CMPIString     *ns = CMGetNameSpace(ref, NULL);
  CMPIObjectPath *cop;
  const char     *nss = ns->ft->getCharPtr(ns, NULL);
  const char     *cns = cn->ft->getCharPtr(cn, NULL);
  const char     *bnss = repositoryNs(nss);
  size_t          ekl;
  int             i,
                  ac = 0;
  char            copKey[8192] = "";
  char           *kp;
  CMPIArgs       *in,
                 *out;
  CMPIObjectPath *op;
  CMPIArray      *ar;
  CMPIData        rv;

  _SFCB_ENTER(TRACE_INTERNALPROVIDER, "InternalProviderEnumInstanceNames");
  _SFCB_TRACE(1, ("%s %s", nss, cns));

  in = CMNewArgs(Broker, NULL);
  out = CMNewArgs(Broker, NULL);
  CMAddArg(in, "class", cns, CMPI_chars);
  op = CMNewObjectPath(Broker, bnss, "$ClassProvider$", &sti);
  rv = CBInvokeMethod(Broker, ctx, op, "getallchildren", in, out, &sti);
  ar = CMGetArg(out, "children", NULL).value.array;
  if (ar)
    ac = CMGetArrayCount(ar, NULL);

  for (i = 0; cns; i++) {
    if ((bi = _getIndex(bnss, cns)) != NULL) {
      if (ipGetFirst(bi, NULL, &kp, &ekl)) {
        while (1) {
          strcpy(copKey, nss);
          strcat(copKey, ":");
          strcat(copKey, cns);
          strcat(copKey, ".");
          strncat(copKey, kp, ekl);

          cop = getObjectPath(copKey, NULL);
          if (cop)
            CMReturnObjectPath(rslt, cop);
          else {
            CMPIStatus      st = { CMPI_RC_ERR_FAILED, NULL };
            return st;
          }
          if (bi->next < bi->dSize && ipGetNext(bi, NULL, &kp, &ekl)) {
            continue;
          }
          break;
        }
      }
      freeBlobIndex(&bi, 1);
    }
    if (i < ac)
      cns = (char *) CMGetArrayElementAt(ar, i, NULL).value.string->hdl;
    else
      cns = NULL;
  }
  _SFCB_RETURN(st);
}
static CMPIStatus
enumInstances(CMPIInstanceMI * mi,
              const CMPIContext *ctx, void *rslt,
              const CMPIObjectPath * ref,
              const char **properties,
              void (*retFnc) (void *, CMPIInstance *), int ignprov)
{
  CMPIStatus      st = { CMPI_RC_OK, NULL };
  CMPIStatus      sti = { CMPI_RC_OK, NULL };
  BlobIndex      *bi;
  CMPIString     *cn = CMGetClassName(ref, NULL);
  CMPIString     *ns = CMGetNameSpace(ref, NULL);
  const char     *nss = ns->ft->getCharPtr(ns, NULL);
  const char     *cns = cn->ft->getCharPtr(cn, NULL);
  const char     *bnss = repositoryNs(nss);
  int             len,
                  i,
                  ac = 0;
  CMPIInstance   *ci;
  CMPIArgs       *in,
                 *out;
  CMPIObjectPath *op;
  CMPIArray      *ar;
  CMPIData        rv;
  const char    **keyList;

  _SFCB_ENTER(TRACE_INTERNALPROVIDER, "enumInstances");
  _SFCB_TRACE(1, ("--- %s %s", nss, cns));

  in = CMNewArgs(Broker, NULL);
  out = CMNewArgs(Broker, NULL);
  if (ignprov)
    CMAddArg(in, "classignoreprov", cns, CMPI_chars);
  else
    CMAddArg(in, "class", cns, CMPI_chars);

  op = CMNewObjectPath(Broker, bnss, "$ClassProvider$", &sti);
  _SFCB_TRACE(1, ("--- getallchildren"));
  rv = CBInvokeMethod(Broker, ctx, op, "getallchildren", in, out, &sti);
  _SFCB_TRACE(1, ("--- getallchildren rc: %d", sti.rc));

  ar = CMGetArg(out, "children", NULL).value.array;
  if (ar)
    ac = CMGetArrayCount(ar, NULL);
  _SFCB_TRACE(1, ("--- getallchildren ar: %p count: %d", ar, ac));

  for (i = 0; cns; i++) {
    _SFCB_TRACE(1, ("--- looking for %s", cns));
    if ((bi = _getIndex(bnss, cns)) != NULL) {
      for (ci = ipGetFirst(bi, &len, NULL, 0); ci;
           ci = ipGetNext(bi, &len, NULL, 0)) {
        if (properties) {
          keyList = getKeyList(ci->ft->getObjectPath(ci, NULL));
          ci->ft->setPropertyFilter(ci, properties, keyList);
          if (keyList) {
            free(keyList);
          }
        }
        _SFCB_TRACE(1, ("--- returning instance %p", ci));
        retFnc(rslt, ci);
      }
    }
    freeBlobIndex(&bi, 1);
    if (i < ac)
      cns = (char *) CMGetArrayElementAt(ar, i, NULL).value.string->hdl;
    else
      cns = NULL;
  }

  _SFCB_RETURN(st);
}
CMPIStatus
IndCIMXMLHandlerCreateInstance(CMPIInstanceMI * mi,
                               const CMPIContext *ctx,
                               const CMPIResult *rslt,
                               const CMPIObjectPath * cop,
                               const CMPIInstance *ci)
{
  CMPIStatus      st = { CMPI_RC_OK, NULL };
  CMPIArgs       *in,
                 *out = NULL;
  CMPIObjectPath *op;
  CMPIData        rv;
  unsigned short  persistenceType;

  _SFCB_ENTER(TRACE_INDPROVIDER, "IndCIMXMLHandlerCreateInstance");

  if (interOpNameSpace(cop, &st) == 0)
    _SFCB_RETURN(st);

  internalProviderGetInstance(cop, &st);
  if (st.rc == CMPI_RC_ERR_FAILED)
    _SFCB_RETURN(st);
  if (st.rc == CMPI_RC_OK) {
    setStatus(&st, CMPI_RC_ERR_ALREADY_EXISTS, NULL);
    _SFCB_RETURN(st);
  }

  CMPIInstance   *ciLocal = CMClone(ci, NULL);
  memLinkInstance(ciLocal);
  CMPIObjectPath* copLocal = CMClone(cop, NULL);
  memLinkObjectPath(copLocal);

  setCCN(copLocal,ciLocal,"CIM_ComputerSystem");

  CMPIString *sysname=ciLocal->ft->getProperty(ciLocal,"SystemName",&st).value.string;
  if (sysname == NULL || sysname->hdl == NULL) {
    char hostName[512];
    hostName[0]=0;
    gethostname(hostName,511); /* should be the same as SystemName of IndicationService */
    CMAddKey(copLocal, "SystemName", hostName, CMPI_chars);
    CMSetProperty(ciLocal,"SystemName",hostName,CMPI_chars);
  }


  CMPIString     *dest =
      CMGetProperty(ciLocal, "destination", &st).value.string;
  if (dest == NULL || CMGetCharPtr(dest) == NULL) {
    setStatus(&st, CMPI_RC_ERR_FAILED,
              "Destination property not found; is required");
    CMRelease(ciLocal);
    _SFCB_RETURN(st);
  } else {                      /* if no scheme is given, assume http (as
                                 * req. for param by mof) */
    char           *ds = CMGetCharPtr(dest);
    if (strstr(ds, "://") == NULL) {
      char           *prefix = "http://";
      int             n = strlen(ds) + strlen(prefix) + 1;
      char           *newdest = (char *) malloc(n * sizeof(char));
      strcpy(newdest, prefix);
      strcat(newdest, ds);
      CMSetProperty(ciLocal, "destination", newdest, CMPI_chars);
      free(newdest);
    }
  }

  CMPIData        persistence =
      CMGetProperty(ciLocal, "persistencetype", &st);
  if (persistence.state == CMPI_nullValue
      || persistence.state == CMPI_notFound) {
    persistenceType = 2;        /* default is 2 = permanent */
  } else if (persistence.value.uint16 < 1 || persistence.value.uint16 > 3) {
    setStatus(&st, CMPI_RC_ERR_FAILED,
              "PersistenceType property must be 1, 2, or 3");
    CMRelease(ciLocal);
    _SFCB_RETURN(st);
  } else {
    persistenceType = persistence.value.uint16;
  }
  CMSetProperty(ciLocal, "persistencetype", &persistenceType, CMPI_uint16);

  if (CMClassPathIsA(_broker, copLocal, "cim_listenerdestination", NULL)) {
    //get the creation timestamp
    struct timeval  tv;
    struct timezone tz;
    char   context[100];
    gettimeofday(&tv, &tz);
    struct tm cttm;
    char * gtime = (char *) malloc(15 * sizeof(char));
    memset(gtime, 0, 15 * sizeof(char));
    if (gmtime_r(&tv.tv_sec, &cttm) != NULL) {
      strftime(gtime, 15, "%Y%m%d%H%M%S", &cttm);
    }

    // Even though reliable indications may be disabled, we need to do this 
    // in case it ever gets enabled.
    // Get the IndicationService name
    CMPIObjectPath * isop = CMNewObjectPath(_broker, "root/interop", "CIM_IndicationService", NULL);
    CMPIEnumeration * isenm = _broker->bft->enumerateInstances(_broker, ctx, isop, NULL, NULL);
    CMPIData isinst = CMGetNext(isenm, NULL);
    CMPIData mc = CMGetProperty(isinst.value.inst, "Name", NULL);

    // build the context string
    sprintf (context,"%s#%s#",mc.value.string->ft->getCharPtr(mc.value.string,NULL),gtime);
    CMPIValue scontext;
    scontext.string = sfcb_native_new_CMPIString(context, NULL, 0);
    free(gtime);

    // set the properties
    CMSetProperty(ciLocal, "SequenceContext", &scontext, CMPI_string);
    CMPIValue zarro = {.sint64 = -1 };
    CMSetProperty(ciLocal, "LastSequenceNumber", &zarro, CMPI_sint64);
  }

  CMPIString     *str = CDToString(_broker, copLocal, NULL);
  CMPIString     *ns = CMGetNameSpace(copLocal, NULL);
  _SFCB_TRACE(1,
              ("--- handler %s %s", (char *) ns->hdl, (char *) str->hdl));

  in = CMNewArgs(_broker, NULL);
  CMAddArg(in, "handler", &ciLocal, CMPI_instance);
  CMAddArg(in, "key", &copLocal, CMPI_ref);
  op = CMNewObjectPath(_broker, "root/interop",
                       "cim_indicationsubscription", &st);
  rv = CBInvokeMethod(_broker, ctx, op, "_addHandler", in, out, &st);

  if (st.rc == CMPI_RC_OK) {
    st = InternalProviderCreateInstance(NULL, ctx, rslt, copLocal, ciLocal);
  }
  else {
    rv=CBInvokeMethod(_broker,ctx,op,"_removeHandler",in,out,NULL);
  }

  _SFCB_RETURN(st);
}

CMPIStatus
IndCIMXMLHandlerModifyInstance(CMPIInstanceMI * mi,
                               const CMPIContext *ctx,
                               const CMPIResult *rslt,
                               const CMPIObjectPath * cop,
                               const CMPIInstance *ci,
                               const char **properties)
{
  CMPIStatus      st = { CMPI_RC_ERR_NOT_SUPPORTED, NULL };
  _SFCB_ENTER(TRACE_INDPROVIDER, "IndCIMXMLHandlerSetInstance");
  _SFCB_RETURN(st);
}
CMPIStatus
getRefs(const CMPIContext *ctx, const CMPIResult *rslt,
        const CMPIObjectPath * cop,
        const char *assocClass,
        const char *resultClass,
        const char *role,
        const char *resultRole,
        const char **propertyList, int associatorFunction)
{
  UtilList       *refs = UtilFactory->newList(memAddUtilList, memUnlinkEncObj);
  char           *ns = (char *) CMGetNameSpace(cop, NULL)->hdl;
  CMPIStatus      st = { CMPI_RC_OK, NULL };

  _SFCB_ENTER(TRACE_INTERNALPROVIDER, "getRefs");

  if (assocClass != NULL) {
    CMPIObjectPath *path;
    if (assocForName(ns, assocClass, role, resultRole) == NULL) {
      /*
       * for an unknown class we just return nothing 
       */
      _SFCB_RETURN(st);
    }
    path = CMNewObjectPath(_broker, ns, assocClass, NULL);
    SafeInternalProviderAddEnumInstances(refs, NULL, ctx, path,
                                         propertyList, &st, 1);
  }

  else {
    CMPIData        rv;
    CMPIObjectPath *op =
        CMNewObjectPath(Broker, ns, "$ClassProvider$", &st);
    CMPIArgs       *in = CMNewArgs(Broker, NULL);
    CMPIArgs       *out = CMNewArgs(Broker, NULL);
    rv = CBInvokeMethod(Broker, ctx, op, "getassocs", in, out, &st);
    if (out) {
      int             i,
                      m;
      CMPIArray      *ar = CMGetArg(out, "assocs", &st).value.array;
      for (i = 0, m = CMGetArrayCount(ar, NULL); i < m; i++) {
        char           *name =
            CMGetArrayElementAt(ar, i, NULL).value.string->hdl;
        if (name) {
          CMPIObjectPath *cop = CMNewObjectPath(Broker, ns, name, NULL);
          if (cop) {
            SafeInternalProviderAddEnumInstances(refs, NULL, ctx, cop,
                                                 propertyList, &st, 1);
          }
        }
        _SFCB_TRACE(1, ("--- assoc %s", name));
      }
    }
  }

  if (role) {
    // filter out the associations not matching the role property
    CMPIInstance   *ci;
    UtilStringBuffer *pn = normalizeObjectPathStrBuf(cop);
    for (ci = refs->ft->getFirst(refs); ci; ci = refs->ft->getNext(refs)) {
      CMPIData        data = CMGetProperty(ci, role, NULL);
      if ((data.state & CMPI_notFound) ||
          data.type != CMPI_ref ||
          objectPathEquals(pn, data.value.ref, NULL, 0) == 0) {
        refs->ft->removeCurrent(refs);
      }
    }
    pn->ft->release(pn);
  }

  else {
    // filter out associations not referencing pathName
    CMPIInstance   *ci;
    int             matched,
                    i,
                    m;
    UtilStringBuffer *pn = normalizeObjectPathStrBuf(cop);
    for (ci = refs->ft->getFirst(refs); ci; ci = refs->ft->getNext(refs)) {
      for (matched = 0, i = 0, m = CMGetPropertyCount(ci, NULL); i < m;
           i++) {
        CMPIData        data = CMGetPropertyAt(ci, i, NULL, NULL);
        if (data.type == CMPI_ref
            && objectPathEquals(pn, data.value.ref, NULL, 0)) {
          matched = 1;
          break;
        }
      }
      if (matched == 0)
        refs->ft->removeCurrent(refs);
    }
    pn->ft->release(pn);
  }

  if (associatorFunction == REF) {
    CMPIInstance   *ci;
    for (ci = refs->ft->getFirst(refs); ci; ci = refs->ft->getNext(refs)) {
      CMReturnInstance(rslt, ci);
    }
    refs->ft->release(refs);
    _SFCB_RETURN(st);
  }

  else if (associatorFunction == REF_NAME) {
    CMPIInstance   *ci;
    for (ci = refs->ft->getFirst(refs); ci; ci = refs->ft->getNext(refs)) {
      CMPIObjectPath *ref = CMGetObjectPath(ci, NULL);
      CMReturnObjectPath(rslt, ref);
    }
    refs->ft->release(refs);
    _SFCB_RETURN(st);
  }

  else {
    // Use hashtable to avoid dup'd associators
    CMPIInstance   *ci;
    UtilHashTable  *assocs =
        UtilFactory->newHashTable(61, UtilHashTable_charKey);
    UtilStringBuffer *pn = normalizeObjectPathStrBuf(cop);
    for (ci = refs->ft->getFirst(refs); ci; ci = refs->ft->getNext(refs)) {
      // Q: for ASSOC_NAME we should not require the
      // object exist if we go by the book, should we?
      // The current approach retrieves the instances
      // via the CIMOM handle
      if (resultRole) {
        CMPIData        data = CMGetProperty(ci, resultRole, NULL);
        UtilStringBuffer *an = NULL;
        if ((data.state & CMPI_notFound) == 0 && data.type == CMPI_ref &&
            objectPathEquals(pn, data.value.ref, &an, 0) == 0) {
          if (resultClass == NULL
              || CMClassPathIsA(Broker, data.value.ref, resultClass,
                                NULL)) {
            CMPIInstance   *aci =
                CBGetInstance(Broker, ctx, data.value.ref, propertyList,
                              &st);
            assocs->ft->put(assocs, an->ft->getCharPtr(an), aci);
          }
        }
      }

      else {
        // must loop over the properties to find ref instances
        int             i,
                        m;
        for (i = 0, m = CMGetPropertyCount(ci, NULL); i < m; i++) {
          CMPIData        data = CMGetPropertyAt(ci, i, NULL, NULL);
          if (data.type == CMPI_ref) {
            CMPIObjectPath *ref = data.value.ref;
            CMPIString     *tns = CMGetNameSpace(ref, NULL);
            if (tns == NULL || tns->hdl == NULL)
              CMSetNameSpace(ref, ns);
            UtilStringBuffer *an = NULL;
            if (objectPathEquals(pn, ref, &an, 0) == 0) {

              if (resultClass == NULL
                  || CMClassPathIsA(Broker, ref, resultClass, NULL)) {
                CMPIInstance   *aci =
                    CBGetInstance(Broker, ctx, ref, propertyList, &st);
                if (aci)
                  assocs->ft->put(assocs, an->ft->getCharPtr(an), aci);
              }
            }
          }
        }
      }
    }

    {
      HashTableIterator *it;
      char           *an;
      CMPIInstance   *aci;
      for (it =
           assocs->ft->getFirst(assocs, (void **) &an, (void **) &aci); it;
           it =
           assocs->ft->getNext(assocs, it, (void **) &an,
                               (void **) &aci)) {
        if (associatorFunction == ASSOC)
          CMReturnInstance(rslt, aci);
        else {
          CMPIObjectPath *op = CMGetObjectPath(aci, NULL);
          CMReturnObjectPath(rslt, op);
        }
      }
    }

    refs->ft->release(refs);
    assocs->ft->release(assocs);
    pn->ft->release(pn);
    _SFCB_RETURN(st);

  }
}
Beispiel #25
0
static CMPIStatus ClassProviderInvokeMethod(CMPIMethodMI * mi,
                                     const CMPIContext * ctx,
                                     const CMPIResult * rslt,
                                     const CMPIObjectPath * ref,
                                     const char *methodName,
                                     const CMPIArgs * in, CMPIArgs * out)
{
   CMPIStatus st = { CMPI_RC_OK, NULL };
   CMPIArray *ar;
   int rc;
   ClassRegister *cReg;
   
   _SFCB_ENTER(TRACE_PROVIDERS, "ClassProviderInvokeMethod");

   cReg=getNsReg(ref, &rc);
   if (cReg==NULL) {
      CMPIStatus st = { CMPI_RC_ERR_INVALID_NAMESPACE, NULL };
      _SFCB_RETURN(st);
   }

   if (strcasecmp(methodName, "getchildren") == 0) {
      CMPIData cn = CMGetArg(in, "class", NULL);
      _SFCB_TRACE(1,("--- getchildren %s",(char*)cn.value.string->hdl));
      
      cReg->ft->wLock(cReg);
   
      if (cn.type == CMPI_string && cn.value.string && cn.value.string->hdl) {
         char *child;
         int l=0, i=0;
         UtilList *ul = getChildren(cReg, (char *) cn.value.string->hdl);
         if (ul) l = ul->ft->size(ul);
         ar = CMNewArray(_broker, l, CMPI_string, NULL);
         if (ul) for (child = (char *) ul->ft->getFirst(ul); child;  child = (char *)
               ul->ft->getNext(ul)) {
            CMSetArrayElementAt(ar, i++, child, CMPI_chars);
         }
         st = CMAddArg(out, "children", &ar, CMPI_stringA);
      }
      else {
      }
      
      cReg->ft->wUnLock(cReg);
   
   }
   
   else if (strcasecmp(methodName, "getallchildren") == 0) {
      int ignprov=0;
      CMPIStatus st;
      CMPIData cn = CMGetArg(in, "class", &st);
      
      cReg->ft->wLock(cReg);
   
      if (st.rc!=CMPI_RC_OK) {
         cn = CMGetArg(in, "classignoreprov", NULL);
         ignprov=1;
      }
      _SFCB_TRACE(1,("--- getallchildren %s",(char*)cn.value.string->hdl));
      if (cn.type == CMPI_string && cn.value.string && cn.value.string->hdl) {
         int n=0,i=0;
         loopOnChildCount(cReg,(char *)cn.value.string->hdl,&n,ignprov);
         _SFCB_TRACE(1,("--- count %d",n));
         ar = CMNewArray(_broker, n, CMPI_string, NULL);
         if (n) {
            _SFCB_TRACE(1,("--- loop %s",(char*)cn.value.string->hdl));
            loopOnChildChars(cReg, (char *)cn.value.string->hdl,ar,&i,ignprov);         
         }   
         st = CMAddArg(out, "children", &ar, CMPI_stringA);
      }
      else {
      }
      
      cReg->ft->wUnLock(cReg);   
   }

   else if (strcasecmp(methodName, "getassocs") == 0) {
      ar = CMNewArray(_broker, cReg->topAssocs, CMPI_string, NULL);
      ClassBase *cb = (ClassBase *) (cReg + 1);
      UtilHashTable *ct = cb->ht;
      HashTableIterator *i;
      char *cn;
      ClassRecord *crec;
      int n;

      cReg->ft->wLock(cReg);
   
       for (n = 0, i = ct->ft->getFirst(ct, (void **) &cn, (void **) &crec); i;
           i = ct->ft->getNext(ct, i, (void **) &cn, (void **) &crec)) {
         if(crec->flags & CREC_isAssociation && crec->parent == NULL) {
	   /* add top-level association class */
	   CMSetArrayElementAt(ar, n++, cn, CMPI_chars);
         }
      }
      CMAddArg(out, "assocs", &ar, CMPI_stringA);
      
      cReg->ft->wUnLock(cReg);
   }

   else if (strcasecmp(methodName, "ischild") == 0) {
      char *parent=(char*)CMGetClassName(ref,NULL)->hdl;
      char *chldn=(char*)CMGetArg(in, "child", NULL).value.string->hdl;
      st.rc = traverseChildren(cReg, parent, chldn);
   }
   
   else if (strcasecmp(methodName, "_startup") == 0) {

     /* check to see if cacheLimit was specified in providerRegister */
     CMPIStatus parm_st = { CMPI_RC_OK, NULL };
     CMPIData parmdata = CMGetContextEntry(ctx, "sfcbProviderParameters", &parm_st);

     if (parm_st.rc == CMPI_RC_OK ) {
       const char* parms = CMGetCharPtr(parmdata.value.string);

       /* cacheLimit is currently the only param, so just take whatever is after the '=' */
       const char* val = strchr(parms,'=');
       /* conversion to uint may cause wrapping; won't catch negatives */
       cacheLimit = ((val != NULL) && (cacheLimit = atoi(val+sizeof(char)))>0) ? cacheLimit : 10;
     }

      st.rc=CMPI_RC_OK;
  }
   
   else {
      mlogf(M_ERROR,M_SHOW,"--- ClassProvider: Invalid invokeMethod request %s\n", methodName);
      st.rc = CMPI_RC_ERR_METHOD_NOT_FOUND;
   }
   _SFCB_RETURN(st);
}