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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
/* * 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); } }
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); }
/* * 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); }
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); } }
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); }