"Fossies" - the Fresh Open Source Software Archive

Member "npadmin-0.14/structfill.C" (19 Apr 2001, 5655 Bytes) of package /linux/misc/old/npadmin-0.14.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file.

    1 /* Copyright (c) 2000 Ben Woodard
    2  * All rights reserved.
    3  *
    4  * This program is free software; you can redistribute it and/or
    5  * modify it under the terms of the GNU General Public Licence
    6  * as published by the Free Software Foundation; either version 2
    7  * of the Licence, or (at your option) any later version.
    8  *
    9  * This program is distributed in the hope that it will be useful,
   10  * but WITHOUT ANY WARRENTY; without even the implied warrenty of
   11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
   12  * GNU General Public Licence in the COPYING file for more
   13  * details.
   14  *
   15  * You should have received a copy of the GNU Library General 
   16  * Public License along with the GNU C Library; see the file 
   17  * COPYING.LIB.  If not, write to the Free Software Foundation, 
   18  * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 
   19  */
   20 
   21 #include <stdarg.h>
   22 #include <assert.h>
   23 #include <string.h>
   24 #include <stdlib.h>
   25 #include <stdio.h>
   26 
   27 #include "structfill.h"
   28 
   29 TableEntry::TableEntry(const char *ostr,Tags thetype,unsigned int off,
   30                TableEntry *nxt):oidstr(ostr),type(thetype),
   31   offset(off),next(nxt){
   32   assert(type==INT_TAG || type==TIME_TICK_TAG || type==OID_TAG || 
   33      type==STRING_TAG || type==IPADDR_TAG || type==COUNTER_TAG);
   34 }
   35 
   36 void SNMP_structFiller::append(const char *oidstr,Tags tag,
   37                    unsigned int offset){
   38   assert(oidstr);
   39   tabdef=new TableEntry(oidstr,tag,offset,tabdef);
   40   if(oidseq)
   41     oidseq->append(oidstr);
   42   else
   43     oidseq=new OidSeq(1,oidstr);
   44 }
   45 
   46 void SNMP_structFiller::remove(const char *oidstr){
   47   //delete the TableEntry
   48   assert(tabdef); /* if this fails you are trying to delete 
   49              something from an empty structfiller. */
   50   if(*tabdef==oidstr){
   51     TableEntry *nextone=tabdef->next;
   52     delete tabdef;
   53     tabdef=nextone;
   54   } else { // search for it amongst the rest of the entries
   55     char test=0;
   56     for(TableEntry *cur=tabdef;cur!=NULL;cur=cur->next){
   57       if(*cur->next==oidstr){
   58     TableEntry *doomed=cur->next;
   59     cur->next=doomed->next;
   60     delete doomed;
   61     test=1;
   62     break;
   63       }
   64     }
   65     assert(test); /* if this fails you are trying to delete 
   66              something from a structfiller that doesn't 
   67              exist there. */
   68   }
   69 
   70   //delete it off of the oidseq
   71   assert(oidseq); /* this should never fail. It means that there is 
   72              something seriously wrong. the oidseq is out 
   73              of sync with the table */
   74   oidseq->remove(oidstr);
   75 }
   76 
   77 SNMP_structFiller::~SNMP_structFiller(){
   78   if(oidseq) delete oidseq;
   79   if(retseq) delete retseq;
   80   while(tabdef){
   81     TableEntry *tmp=tabdef->next;
   82     delete tabdef;
   83     tabdef=tmp;
   84   }
   85 }
   86 
   87 int SNMP_structFiller::fillStruct(OidSeq *data,
   88                   unsigned char *curstruct){
   89   int retval=1;
   90   for(TableEntry *cur=tabdef;cur!=NULL;cur=cur->next){
   91     BerBase *curber;
   92     if(!(curber=data->child(cur->oidstr))){
   93       retval=0;
   94       continue;
   95     }
   96 
   97     if(curber->type()!=cur->type){
   98       if(curber->type()==INT_TAG && cur->type==COUNTER_TAG)
   99     fprintf(stderr,"Warning: Counter returned when Integer expected for "
  100         "%s.Buggy firmware?\n",cur->oidstr);
  101       else if(curber->type()==COUNTER_TAG && cur->type==INT_TAG)
  102     fprintf(stderr,"Warning: Integer returned when Counter expected for "
  103         "%s. Buggy firmware?\n",cur->oidstr);
  104       else{
  105     fprintf(stderr,"Warning: Printer returned a value of type 0x%x when a "
  106         "value of 0x%x was expected for %s. Buggy firmware?"
  107         "\n",curber->type(),cur->type,cur->oidstr);
  108     throw SNMP_error_oid(cur->oidstr);
  109       }
  110     }
  111     
  112     unsigned char *inside=curstruct+cur->offset;
  113     switch(cur->type){
  114     case INT_TAG:
  115     case COUNTER_TAG:
  116       *((long*)inside)=((BerInt*)curber)->value();
  117       break;
  118     case TIME_TICK_TAG:
  119       *((unsigned long*)inside)=((BerTimeTick*)curber)->value();
  120       break;
  121     case IPADDR_TAG:
  122       assert(((BerIPAddr*)curber)->Len()==4);
  123       (*((unsigned char**)inside)=new unsigned char[4]);
  124       memcpy(*((unsigned char**)inside),((BerIPAddr*)curber)->IPaddr(),4);
  125       break;
  126     default:
  127       assert(0); // this should never happen
  128     case OID_TAG:
  129     case STRING_TAG:
  130       (*((char**)inside)=new char[256]);
  131       int len=((BerString*)curber)->copy(*((char**)inside),256);
  132       (*(char**)inside)[len]=0;
  133       *(char**)inside=(char*)realloc(*(char**)inside,len+1);
  134       break;
  135     }
  136   }
  137   return retval;
  138 }
  139 
  140 void *SNMP_structFiller::get(void *tobefilled){
  141   retseq=session.get(oidseq);
  142   if(retseq==NULL)
  143     throw SNMPERR_NoResponse;
  144 
  145   if( !fillStruct(retseq,(unsigned char*)tobefilled)){
  146     fprintf(stderr,"Warning: printer did not respond with a value for one of the OIDs. Buggy firmware?\n");
  147     return NULL;
  148   }
  149 
  150   return tobefilled;
  151 }
  152 
  153 void *SNMP_structFiller::get_next(void *tobefilled){
  154   if(retseq){
  155     delete oidseq;
  156     oidseq=retseq;
  157     retseq=NULL;
  158   }
  159   retseq=session.get_next(oidseq);
  160   if(retseq==NULL)
  161     throw SNMPERR_NoResponse;
  162 
  163   if(!fillStruct(retseq,(unsigned char*)tobefilled))
  164     return NULL;
  165 
  166   return tobefilled;
  167 }
  168 
  169 void *SNMP_table::get(unsigned int &idx){
  170   idx=0; // sort of a second return value
  171   unsigned int maxlen=10;
  172   void *retval;
  173 
  174   retval=malloc(structlen*maxlen);
  175   assert(retval);
  176   /* this isn't strictly necessary but it does make debugging 
  177      easier notice I don't do it below when the array is resized.
  178    */
  179   memset(retval,0,structlen*maxlen); 
  180 
  181   // while we are still in the table
  182   while(get_next(((unsigned char*)retval)+idx*structlen)){ 
  183     idx++;
  184     if(idx==maxlen){ //this could be really slow with big structures.
  185       maxlen+=10;
  186       retval=realloc(retval,structlen*maxlen);
  187       assert(retval);
  188     }
  189   }
  190 
  191   assert(retval=realloc(retval,structlen*(idx+1)));
  192   return retval;
  193 }
  194 
  195 
  196