예제 #1
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);
}
예제 #2
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);
   }
        
    
}