"Fossies" - the Fresh Open Source Software Archive

Member "npadmin-0.14/npadmin.C" (19 Nov 2002, 24362 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 "config.h"
   22 #include <limits.h>
   23 #include <errno.h>
   24 #include <stdio.h>
   25 #include <unistd.h>
   26 #include <assert.h>
   27 //#include <string.h>
   28 #include <ctype.h>
   29 #include <pthread.h>
   30 #include <signal.h>       
   31 #include <sys/time.h>
   32 #include <sys/types.h>
   33 
   34 #ifdef HAVE_GETOPT_H
   35 #include <getopt.h>
   36 #else
   37 #include "getopt.h"
   38 #endif
   39 
   40 #include "compat.h"
   41 #include "structfill.h"
   42 #include "argflags.h"
   43 #include "npaoids.h"
   44 #include "npaconsts.h"
   45 #include "npastructs.h"
   46 #include "npahelpers.h"
   47 #include "printmib.h"
   48 #include "snmpsock.h"
   49 
   50 #define MAXTHREADS 100
   51 
   52 #define ERR_UNKNOWN_OPT 1
   53 #define ERR_BAD_PORT 2
   54 #define ERR_MISSING_PARAMETER 3
   55 #define ERR_SNMP_OID_NOT_FOUND 4 //hardcoded in session.C
   56 #define ERR_NO_HOSTMIB_SUPPORT 5
   57 #define ERR_NO_PRINTMIB_SUPPORT 6
   58 #define ERR_NO_HOST_SPECIFIED 7
   59 // ERR_NO_RESPONSE 8 defined in npahelpers.C
   60 // ERR_SOCK_ERROR 9 defined in npahelpers.C
   61 // ERR_NOT_PRINTER 10 defined in npahelpers.C
   62 // ERR_UNKNOWN_DEVICE 11 defined in npahelpers.C
   63 
   64 extern char *optarg;
   65 
   66 struct thr_dat{
   67   SNMP_session *session;
   68   char **optparams;
   69   unsigned long operflags;
   70   unsigned long argflags[3];
   71   ConnectionInfoRequest *cir;
   72 };
   73 
   74 struct privmib_hdlr{
   75   const char *oid;
   76   void (*hfunct)(SNMP_session &,unsigned long *,BerBase *);
   77 };
   78 
   79 char *progname; //lookey my one global variable.
   80 
   81 
   82 static unsigned int num_sessions=0;
   83 static unsigned int act_sessions=0;
   84 static unsigned int thr_reaped=0;
   85 static pthread_mutex_t act_sessions_m=PTHREAD_MUTEX_INITIALIZER;
   86 
   87 static char HPNPCFGSOURCE[]=_HPNPCFGSOURCE_;
   88 
   89 void *do_reqs(void*);
   90 void *join_threads(void*);
   91 
   92 int main(int argc, char **argv){
   93   int retval=0;
   94 
   95   // don't change the order of these without changing the order in npaconsts.h
   96   /* I don't know why I put that comment in a long time ago. But the way that 
   97      this works is way too clever. Instead of having a nice easy switch case 
   98      sort of thing, I'm fancy. What I do is reserve the final 3 bits of the 
   99      value to indicate what long in the argflags array is being specified and 
  100      then I use the upper 29 bits to specify the actual option that is being 
  101      specified. This took me at least an hour to figure out a couple of years 
  102      after I wrote it. 
  103      The values of these flags are in argflags.h
  104      -ben Nov 18, 2002 */
  105   static const struct option options[]= { 
  106     {"version",     no_argument,&retval,VERSION_FLAG},
  107     {"all",         no_argument,&retval,ALL_FLAG}, 
  108     {"debugsnmp",   no_argument,&retval,DEBUGSNMP_FLAG},
  109     {"name",        no_argument,&retval,NAME_FLAG},
  110 
  111     {"vendor",      no_argument,&retval,VENDOR_FLAG},
  112     {"model",       no_argument,&retval,MODEL_FLAG},
  113     {"contact",     no_argument,&retval,CONTACT_FLAG},
  114     {"netconfig",   no_argument,&retval,NETCONFIG_FLAG},
  115     {"printmib",    no_argument,&retval,PRINTMIB_FLAG},
  116     {"hostmib",     no_argument,&retval,HOSTMIB_FLAG},
  117 
  118     {"memory",      no_argument,&retval,MEMORY_FLAG},
  119     {"storage",     no_argument,&retval,STORAGE_FLAG},
  120     {"status",      no_argument,&retval,STATUS_FLAG},
  121 
  122     {"mediapath",   no_argument,&retval,MEDIAPATH_FLAG},
  123     {"maxpapersize",no_argument,&retval,MAXPAPERSIZE_FLAG},
  124     {"enginespeed", no_argument,&retval,ENGINESPEED_FLAG},
  125     {"duplex",      no_argument,&retval,DUPLEX_FLAG},
  126     {"minpapersize",no_argument,&retval,MINPAPERSIZE_FLAG}, 
  127 
  128     {"inputtray",   no_argument,&retval,INPUTTRAY_FLAG},
  129     {"tabloid",     no_argument,&retval,TABLOID_FLAG},
  130     {"a4",          no_argument,&retval,A4_FLAG},
  131     {"b4",          no_argument,&retval,B4_FLAG},
  132     {"executive",   no_argument,&retval,EXECUTIVE_FLAG}, 
  133     {"a3",          no_argument,&retval,A3_FLAG},
  134     {"b5",          no_argument,&retval,B5_FLAG},
  135     {"letter",      no_argument,&retval,LETTER_FLAG},
  136     {"legal",       no_argument,&retval,LEGAL_FLAG},
  137 
  138     {"display",     no_argument,&retval,DISPLAY_FLAG}, 
  139     {"covers",      no_argument,&retval,COVER_FLAG},
  140 
  141     // From here down These all get an extra bit to indicate that they belong
  142     // to argval[1] rather than argval[0]
  143     {"languages",   no_argument,&retval,LANGUAGES_FLAG+1},
  144     {"pjl",         no_argument,&retval,PJL_FLAG+1},
  145     {"hpgl",        no_argument,&retval,HPGL_FLAG+1},
  146     {"psprinter",   no_argument,&retval,PSPRINTER_FLAG+1},
  147     {"autolang",    no_argument,&retval,AUTOLANG_FLAG+1},
  148     {"pcl",         no_argument,&retval,PCL_FLAG+1},
  149     {"postscript",  no_argument,&retval,POSTSCRIPT_FLAG+1},
  150 
  151     {"marker",      no_argument,&retval,MARKER_FLAG+1},
  152     {"pagecount",   no_argument,&retval,PAGECOUNT_FLAG+1},
  153     {"colors",      no_argument,&retval,COLORS_FLAG+1},
  154     {"resolution",  no_argument,&retval,RESOLUTION_FLAG+1},
  155     {"minmargin",   no_argument,&retval,MINMARGIN_FLAG+1},
  156 
  157     {"protocol",    no_argument,&retval,PROTOCOL_FLAG+1},
  158     {"appletalk",   no_argument,&retval,APPLETALK_FLAG+1}, 
  159     {"lpd",         no_argument,&retval,LPD_FLAG+1},
  160     {"netware",     no_argument,&retval,NETWARE_FLAG+1}, 
  161     {"port9100",    no_argument,&retval,PORT9100_FLAG+1},
  162 
  163     {"supplies",    no_argument,&retval,SUPPLIES_FLAG+1},
  164     {"cfgsrc",      no_argument,&retval,CFGSRC_FLAG+1},
  165     {"alerts",      no_argument,&retval,ALERTS_FLAG+1},
  166     {"reboot",      no_argument,&retval,REBOOT_FLAG+1},
  167     {"serialnum",   no_argument,&retval,SERIALNUM_FLAG+1},
  168 
  169     // From here down These all get an extra bit 2 to indicate that they belong
  170     // to argval[2] rather than argval[0] or argval[1]
  171     {"maxproc",required_argument,&retval,MAXPROC_FLAG+2},
  172     {"setcontact",required_argument,&retval,SETCONTACT_FLAG+2},
  173     {"setlocation",required_argument,&retval,SETLOCATION_FLAG+2},
  174     {"updatefirmware",required_argument,&retval,UPDATEFIRM_FLAG+2},
  175 
  176     {"community",required_argument,NULL,    'c'},
  177     {"timeout",required_argument,NULL,      't'},
  178     {"connection",required_argument,NULL,   'n'},
  179     {"help",no_argument,NULL,               'h'},
  180     //    {"bootp",no_argument,NULL,              'B'},
  181     //    {"dhcp",no_argument,NULL,               'B'}, //yes exactly the same
  182     //    {"setaccesslist",required_argument,NULL,'C'},
  183     //    {"disable",required_argument,NULL,      'D'},
  184     //    {"enable",required_argument,NULL,       'E'},
  185     //    {"default",required_argument,NULL,      'F'},
  186     //    {"formatterver",no_argument,NULL,       't'},
  187     //    {"serialnum",no_argument,NULL,          'u'},
  188     //    {"jamrecovery",no_argument,NULL,        'j'},
  189     //    {"panellocked",no_argument,NULL,        'k'},
  190     //    {"errors",no_argument,NULL,             'e'},
  191     //    {"firmwarever",no_argument,NULL,        'f'},
  192     //    {"serviceperson",required_argument,NULL,'I'},
  193     //    {"lockkeypad",no_argument,NULL,         ''},
  194     //    {"operator",required_argument,NULL,     'O'},
  195     //    {"location",required_argument,NULL,     ''},
  196     //    {"reset",no_argument,NULL,              'R'},
  197     //    {"staticip",no_argument,NULL,           'S'},
  198     //    {"accesslist",no_argument,NULL,         ''},
  199     //    {"answer",no_argument,&answer_flag,1},
  200     //    {"adam"},
  201     //    {"html"},
  202     //    {"human"},
  203     //    {"verbose"},
  204     //    {"reallyverbose"},
  205     //    {"debugsnmp"},
  206     //    {"isthisaprinter"},
  207     //    {"shorttimeout"}
  208     //    {"alive"}
  209     // also add support for multiple hosts.
  210     {0,0,0,0}
  211   };
  212 
  213   /* you can have multiple Connection Info requests and so this is the head 
  214      linked list of those requests. */
  215   ConnectionInfoRequest *cir=NULL;
  216   char *community=NULL;
  217   int timeout=50;
  218 
  219   int optval;
  220   int error=0;
  221   unsigned long argflags[3]={0,0,0};
  222   unsigned long operflags=0;
  223   char *optparams[MAXOPTWPARAMS];
  224 
  225   while((optval=getopt_long(argc,argv,"+cn:",options,NULL))!=EOF){
  226     long int port;
  227     switch(optval){
  228     case '?':
  229       error=ERR_UNKNOWN_OPT;
  230       break;
  231     case ':':
  232       error=ERR_MISSING_PARAMETER;
  233       break;
  234     case 'c':
  235       community=optarg;
  236       break;
  237     case 't':
  238       timeout=strtoul(optarg,NULL,0);
  239       break;
  240     case 'n':
  241       port=strtol(optarg,NULL,10);
  242       // problem converting
  243       assert(!(errno==ERANGE && (port==LONG_MIN || port==LONG_MAX)));
  244       // value out of bounds
  245       if(port<=0 || port>USHRT_MAX){
  246     fprintf(stderr, "%s: port number is out of range.\n", argv[0]);
  247     exit(ERR_BAD_PORT);
  248       }
  249       cir=new ConnectionInfoRequest(port,cir);
  250       break;
  251     case 'h':
  252       fprintf(stderr,"npadmin [OPTIONS] printername\n\n"
  253           "\t-c {COMMUNITY}\t\tSet the community name to do request\n"
  254           "\t--community {COMMUNITY}\n"
  255           "\t-n {PORT}\t\tCommunicate on a port other than the standard"
  256           " SNMP port UDP 161\n"  
  257           "\t--version\tPrint out the version info.\n"
  258           "\t--vendor\tPrint out the printer's vendor\n" 
  259           "\t--model\tPrint out the printer's model\n" 
  260           "\t--contact\tPrint out the location and contact\n"
  261           "\t--netconfig\tPrint out the network configuration\n"  
  262           "\t--printmib\tPrint out whether the printer supports the"
  263           " printer MIB\n"   
  264           "\t--hostmib\tPrint out whether the printer supports the host"
  265           " MIB\n"  
  266           "\t--memory\tPrint out the amount of memory that the printer"
  267           " has in it.\n"  
  268           "\t--storage\tPrint out the storage table\n"  
  269           "\t--status\tPrint out the printer status\n"
  270           "\t--mediapath\tPrint out the media path table\n"
  271           "\t--maxpapersize\tPrint out the maximum paper size\n" 
  272           "\t--enginespeed\tPrint out the print engine speed\n"  
  273           "\t--duplex\tPrint out whether the printer supports duplex"
  274           " printing.\n"  
  275           "\t--minpapersize\tPrint out the minimum paper size\n"  
  276           "\t--inputtray\tPrint out the input tray table\n"  
  277           "\t--tabloid\tPrint out an esitmate of the number of tabloid"
  278           " size sheets in the printer\n"  
  279           "\t--a4\tPrint out an esitmate of the number of a4"
  280           " size sheets in the printer\n" 
  281           "\t--b4\tPrint out an esitmate of the number of b4"
  282           " size sheets in the printer\n" 
  283           "\t--executive\tPrint out an esitmate of the number of executive"
  284           " size sheets in the printer\n"  
  285           "\t--a3\tPrint out an esitmate of the number of a3"
  286           " size sheets in the printer\n"  
  287           "\t--b5\tPrint out an esitmate of the number of b5"
  288           " size sheets in the printer\n"  
  289           "\t--letter\tPrint out an esitmate of the number of letter"
  290           " size sheets in the printer\n"  
  291           "\t--legal\tPrint out an esitmate of the number of legal"
  292           " size sheets in the printer\n"  
  293           "\t--protocol\tPrint out the ways of getting print data into"
  294           " a printer\n"
  295           "\t--appletalk\tPrint out if the printer supports appletalk\n"  
  296           "\t--lpd\tPrint out if the printer supports the LPD protocol\n"  
  297           "\t--netware\tPrint out if the printer is capable of acting like"
  298           " a netware server\n"  
  299           "\t--port9100\t prints out if the printer admits to having a "
  300           "bidirectional TCP/IP port\n"  
  301           "\t--languages\t\n"  
  302           "\t--pjl\t\n"   
  303           "\t--hpgl\t\n"   
  304           "\t--psprinter\t\n"   
  305           "\t--autolang\t\n"
  306           "\t--pcl\t\n" 
  307           "\t--postscript\t\n" 
  308           "\t--marker\t\n" 
  309           "\t--pagecount\t\n" 
  310           "\t--colors\t\n"
  311           "\t--resolution\t\n"   
  312           "\t--minmargin\t\n"   
  313           "\t--supplies\t\n"   
  314           "\t--alerts\t\n"
  315           "\t--display\t\n" 
  316           "\t--covers\t\n" 
  317           "\t--community SNMP community string \t\n" 
  318           "\t--connection port\t\n" 
  319           "\t--debugsnmp\tprovide debugging info in snmplog.* files\n"
  320           "\t--reboot\treboot the printer\n"
  321           "\t--timeout\tbetween SNMP queries\n"
  322           "\t--serialnum\tgrab the printer's serial number\n" 
  323           );
  324     exit(0);
  325       break;
  326     case 0: // all these long options
  327       assert((retval&0x7)<=2);/*right now we only need three words for the 
  328                 options */
  329       argflags[retval&0x7]|=retval&0xFFFFFFF8ul;
  330       if((retval&0x07)==2){ /* word 2 is reserved for items that need a 
  331                  parameter */
  332     // count how far over the bit is
  333     unsigned long tmpval=retval&0xfffffff8ul;
  334     int i;
  335     for(i=0;tmpval!=1;tmpval/=2,i++);
  336     optparams[i-3]=optarg;
  337       }
  338       break;
  339     default:
  340       assert(0); // huh -- never should get here.
  341     }
  342   }
  343 
  344   progname=argv[0];
  345 
  346   if(error) {
  347     usage();
  348     exit(error);
  349   }
  350 
  351   if(CK_VERSION_FLAG){
  352     printf("npadmin version %s\n",VERSION);
  353     exit(0);
  354   }
  355 
  356   if(CK_HOSTMIB_FLAGS){
  357     operflags|=NEED_HOSTMIB_FLAG;
  358   }
  359 
  360   if(CK_PRINTMIB_FLAGS){
  361     operflags|=NEED_PRINTMIB_FLAG;
  362   }
  363 
  364   if(CK_PRIVATEMIB_FLAGS){
  365     operflags|=NEED_VENDOR_FLAG;
  366   }
  367 
  368   if(optind>=argc){  // the user didn't specify a hostname
  369     fprintf(stderr,"npadmin: no printer name specified.\n");
  370     exit(ERR_NO_HOST_SPECIFIED);
  371   }
  372   /* ------------------- Real code begins --------------------- */
  373   SNMP_socket  sock(2,timeout/2);
  374   SNMP_session *sessions=NULL;
  375 
  376   for(;optind<argc;optind++){
  377     // strip off the community name
  378     char *cmty;
  379     if(strchr(argv[optind],'(')==NULL)
  380       cmty=community;
  381     else{
  382       strtok(argv[optind],"(");
  383       cmty=strtok(NULL,")");
  384       assert(cmty!=NULL);
  385     }
  386 
  387     if(isdigit(*argv[optind])){
  388       /* assume that this is 
  389      a) an ipaddress like 10.1.1.102
  390      b) a range of ipaddresses line 10.1.1.102-150
  391      c) a network and a subnet mask 10.1.1.0/24
  392       */
  393       if(strchr(argv[optind],'-')){ // the range case
  394     unsigned int val[5];
  395     int vals=sscanf(argv[optind],"%u.%u.%u.%u-%u",val,val+1,val+2,val+3,
  396             val+4);
  397     assert(vals==5);
  398     assert(val[0]<256 && val[1]<256 && val[2]<256 && val[3]<256 && 
  399            val[4]<256);
  400     for(;val[3]<=val[4];val[3]++){
  401       char buf[20];
  402       snprintf(buf,20,"%u.%u.%u.%u",val[0],val[1],val[2],val[3]);
  403       SNMP_session *newone=new SNMP_session(&sock,buf,cmty);
  404       num_sessions++;
  405       newone->next=sessions;
  406       sessions=newone;
  407     }
  408       } else if(strchr(argv[optind],'/')){ // the network case
  409     unsigned int val[8];
  410     unsigned int baseaddr, topaddr, mask;
  411     int num_read=sscanf(argv[optind],"%u.%u.%u.%u/%u.%u.%u.%u",val,val+1,
  412             val+2,val+3,val+4,val+5,val+6,val+7);
  413     assert((num_read==5||num_read==8) && val[0]<256 && val[1]<256 && 
  414            val[2]<256 && val[3]<256);
  415     if(num_read==5){
  416       assert(val[4]<30);
  417       mask=0xffffffffu << (32-val[4]);
  418     }else{
  419       assert(val[4]<256 && val[5]<256 && val[6]<256 && val[7]<256);
  420       mask=(val[4]<<24)|(val[5]<<16)|(val[6]<<8)|val[7];
  421     }
  422     baseaddr=((val[0]<<24)|(val[1]<<16)|(val[2]<<8)|val[3]) & mask;
  423     topaddr=baseaddr|~mask;
  424     
  425     // loop through all the addrs skipping the network and broadcast
  426     for(baseaddr++;baseaddr<topaddr;baseaddr++){
  427       char buf[20];
  428       snprintf(buf,20,"%u.%u.%u.%u",(baseaddr&0xff000000u)>>24,
  429           (baseaddr&0xff0000)>>16,(baseaddr&0xff00)>>8,baseaddr&0xff);
  430       SNMP_session *newone=new SNMP_session(&sock,buf,cmty);
  431       num_sessions++;
  432       newone->next=sessions;
  433       sessions=newone;
  434     }   
  435       } else { // the single ip case
  436     SNMP_session *newone=new SNMP_session(&sock,argv[optind],cmty);
  437     num_sessions++;
  438     newone->next=sessions;
  439     sessions=newone;
  440       }
  441     }else{
  442       // a hostname
  443       SNMP_session *newone=new SNMP_session(&sock,argv[optind],cmty);
  444       num_sessions++;
  445       newone->next=sessions;
  446       sessions=newone;
  447     }
  448   }
  449 
  450   if(CK_DEBUGSNMP_FLAG)
  451     for(SNMP_session *cur=sessions;cur!=NULL;cur=cur->next)
  452       cur->setDebug();
  453 
  454   if(error)
  455     exit(error);
  456 
  457   if(num_sessions>1)
  458     SET_NAME_FLAG;
  459 
  460   pthread_t thrds[num_sessions+1];
  461   pthread_t joiner;
  462   int rv=pthread_create(&joiner,NULL,join_threads,thrds);
  463   assert(rv==0);
  464 
  465   thr_dat thrdat[num_sessions];
  466   unsigned int thr_idx=0;
  467   for(SNMP_session *cur=sessions;cur!=NULL;cur=cur->next){
  468     thrdat[thr_idx].session=cur;
  469     thrdat[thr_idx].optparams=optparams;
  470     thrdat[thr_idx].cir=cir;
  471     thrdat[thr_idx].operflags=operflags;
  472     for(char i=0;i<3;i++)
  473       thrdat[thr_idx].argflags[i]=argflags[i];
  474 
  475     rv=pthread_create(thrds+thr_idx,NULL,do_reqs,thrdat+thr_idx);
  476     assert(rv==0);
  477 
  478     pthread_mutex_lock(&act_sessions_m);
  479     act_sessions++;
  480     pthread_mutex_unlock(&act_sessions_m);
  481 
  482     if(thr_idx-thr_reaped>MAXTHREADS)
  483       sleep(2);
  484 
  485     thr_idx++;
  486   }
  487   
  488   int *retval2;
  489   pthread_join(joiner,(void**)&retval2);
  490 
  491   SNMP_session::end();
  492   exit(*retval2);
  493 }
  494 
  495 
  496 /* This function runs a thread whose whole purpose is to clean up
  497    the various threads as they complete. It gathers the error 
  498    values and then trys to come up with some semblence of an exit 
  499    value for the whole process. */
  500 void *join_threads(void *thrds_raw){
  501   pthread_t *thrds=(pthread_t*)thrds_raw;
  502   int *error=NULL;
  503 
  504   for(thr_reaped=0;thr_reaped<num_sessions;thr_reaped++){
  505     pthread_mutex_lock(&act_sessions_m);
  506     while(thr_reaped>=act_sessions){
  507       pthread_mutex_unlock(&act_sessions_m);
  508       sleep(1);
  509       pthread_mutex_lock(&act_sessions_m);
  510     }
  511     pthread_mutex_unlock(&act_sessions_m);
  512     
  513     int *retval;
  514     pthread_join(thrds[thr_reaped],(void**)&retval);
  515     if(!error || *retval)
  516       error=retval;
  517   }
  518   return error;
  519 }
  520 
  521 /* This function runs a thread for a particular printer. There is
  522    basically one instance of this function running in a thread per
  523    printer specified on the commmand line. It basically does the 
  524    work of calling out to the functions that actually do the snmp 
  525    queries to the printers. */ 
  526 void *do_reqs(void *raw_dat_in){
  527   static const privmib_hdlr hp_priv[]={
  528     {HPNPCFGSOURCE,hpcfgsrc}
  529   };
  530   static const privmib_hdlr *privmibtab[]={hp_priv,NULL,NULL,NULL,NULL};
  531 
  532   thr_dat *dat_in=(thr_dat*)raw_dat_in;
  533 
  534   SNMP_session &session=*dat_in->session;
  535   unsigned long &operflags=dat_in->operflags;
  536   unsigned long *argflags=dat_in->argflags;
  537   /* Don't modify any of the values in optparams. It will mess up 
  538      the other threads */ 
  539   char **optparams=dat_in->optparams; 
  540   ConnectionInfoRequest *cir=dat_in->cir;
  541   int *errorp=new int;
  542   int &error=*errorp;
  543   error=0;
  544 
  545   operflags&=~NEED_HOSTMIB_FLAG;
  546   if(CK_HOSTMIB_FLAGS){
  547     operflags|=NEED_HOSTMIB_FLAG;
  548   }
  549 
  550   operflags&=~NEED_PRINTMIB_FLAG;
  551   if(CK_PRINTMIB_FLAGS){
  552     operflags|=NEED_PRINTMIB_FLAG;
  553   }
  554 
  555   operflags&=~NEED_VENDOR_FLAG;
  556   if(CK_PRIVATEMIB_FLAGS || CK_UPDATEFIRM_FLAG){
  557     operflags|=NEED_VENDOR_FLAG;
  558   }
  559 
  560   /* ---- stage the general requests ---- */
  561   if(CK_GENERALMIB_FLAGS || 
  562      operflags&(NEED_HOSTMIB_FLAG | NEED_PRINTMIB_FLAG | NEED_VENDOR_FLAG)){
  563     do_general_get(session,argflags,operflags,optparams);
  564   }
  565 
  566   /* Deal with the generalmib sets */
  567   if(CK_SGENERALMIB_FLAGS){
  568     OidSeq gensets;
  569     if(CK_SETCONTACT_FLAG){
  570       gensets.append(SYSCONTACT,STRING_TAG,optparams[SETCONTACT_PARAM],
  571              strlen(optparams[SETCONTACT_PARAM]));
  572     }
  573     if(CK_SETLOCATION_FLAG){
  574       gensets.append(SYSLOCATION,STRING_TAG,optparams[SETLOCATION_PARAM],
  575              strlen(optparams[SETLOCATION_PARAM]));
  576     }
  577     session.set(&gensets);
  578   }
  579 
  580   /* ---- Connection information ------------------------------ */
  581   if(cir){
  582     do_connections(argflags,session,cir);
  583   } // ends the general section
  584 
  585 
  586   /* -------------------------------------------------------------
  587      get the things out of the hostmib 
  588      -----------------------------------------------------------*/
  589   if(operflags&NEED_HOSTMIB_FLAG){
  590     if(!(operflags&HAS_HOSTMIB_FLAG)){
  591       if(!(CK_ALL_FLAG)){
  592     error=ERR_NO_HOSTMIB_SUPPORT;
  593     if(CK_MEMORY_FLAG) not_sup("memory",session.Hostname());
  594     if(CK_STORAGE_FLAG) not_sup("storage",session.Hostname());
  595     if(CK_STATUS_FLAG) not_sup("status",session.Hostname());
  596       }
  597     } else 
  598       do_hostmib_get(session,argflags,operflags);
  599   }
  600 
  601   /* -------------------------------------------------------------
  602      get things out of printmib
  603      -----------------------------------------------------------*/
  604   if(operflags&NEED_PRINTMIB_FLAG){
  605     if(!(operflags&HAS_PRINTMIB_FLAG)){
  606       if(!(CK_ALL_FLAG)){
  607     if(CK_MEDIAPATH_FLAG) not_sup("mediapath",session.Hostname());
  608     if(CK_MAXPAPERSIZE_FLAG) not_sup("maxpapersize",session.Hostname());
  609     if(CK_MINPAPERSIZE_FLAG) not_sup("minpapersize",session.Hostname());
  610     if(CK_ENGINESPEED_FLAG) not_sup("enginespeed",session.Hostname());
  611     if(CK_DUPLEX_FLAG) not_sup("duplex",session.Hostname());
  612     if(CK_DISPLAY_FLAG) not_sup("display",session.Hostname());
  613     if(CK_INPUTTRAY_FLAG) not_sup("inputtray",session.Hostname());
  614     if(CK_LETTER_FLAG) not_sup("letter",session.Hostname());
  615     if(CK_LEGAL_FLAG) not_sup("legal",session.Hostname());
  616     if(CK_TABLOID_FLAG) not_sup("tabloid",session.Hostname());
  617     if(CK_EXECUTIVE_FLAG) not_sup("executive",session.Hostname());
  618     if(CK_A3_FLAG) not_sup("a3",session.Hostname());
  619     if(CK_A4_FLAG) not_sup("a4",session.Hostname());
  620     if(CK_B4_FLAG) not_sup("b4",session.Hostname());
  621     if(CK_B5_FLAG) not_sup("b5",session.Hostname());
  622     if(CK_COVER_FLAG) not_sup("cover",session.Hostname());
  623     if(CK_ALERTS_FLAG) not_sup("alerts",session.Hostname());
  624     if(CK_LANGUAGES_FLAG) not_sup("languages",session.Hostname());
  625     if(CK_PCL_FLAG) not_sup("pcl",session.Hostname());
  626     if(CK_PJL_FLAG) not_sup("pjl",session.Hostname());
  627     if(CK_HPGL_FLAG) not_sup("hpgl",session.Hostname());    
  628     if(CK_POSTSCRIPT_FLAG) not_sup("postscript",session.Hostname());
  629     if(CK_PSPRINTER_FLAG) not_sup("psprinter",session.Hostname());  
  630     if(CK_AUTOLANG_FLAG) not_sup("autolang",session.Hostname());    
  631     if(CK_PORT9100_FLAG) not_sup("port9100",session.Hostname());
  632     if(CK_APPLETALK_FLAG) not_sup("appletalk",session.Hostname());
  633     if(CK_LPD_FLAG) not_sup("lpd",session.Hostname());
  634     if(CK_NETWARE_FLAG) not_sup("netware",session.Hostname());
  635     if(CK_PROTOCOL_FLAG) not_sup("protocol",session.Hostname());
  636     if(CK_PAGECOUNT_FLAG) not_sup("pagecount",session.Hostname());
  637     if(CK_MARKER_FLAG) not_sup("marker",session.Hostname());
  638     if(CK_RESOLUTION_FLAG) not_sup("resolution",session.Hostname());
  639     if(CK_COLORS_FLAG) not_sup("color",session.Hostname());
  640     if(CK_MINMARGIN_FLAG) not_sup("minmargin",session.Hostname());
  641     if(CK_SUPPLIES_FLAG) not_sup("supplies",session.Hostname());
  642     if(CK_REBOOT_FLAG) not_sup("reboot",session.Hostname());
  643     if(CK_SERIALNUM_FLAG) not_sup("serial number", session.Hostname());
  644     error=ERR_NO_PRINTMIB_SUPPORT;
  645       }
  646       pthread_exit(&error);
  647     } 
  648     if(CK_PRINTMIB_RFLAGS)
  649       do_printmib_get(session,argflags);
  650     if(CK_PRINTMIB_SFLAGS)
  651       do_printmib_set(session,argflags);
  652   } // ends printmib processing
  653 
  654   if(CK_CFGSRC_FLAG){
  655     const privmib_hdlr *curprivhdlr;
  656     /* Right now this works fine because there is only one thing 
  657        that we get out of the private mib and so there is no 
  658        potential for multiple items in the private area to be set.
  659        However, as soon as we have one more item out of the 
  660        private mib that needs to be set, then we will have to 
  661        iterate through the bits rather than simply test one of the
  662        bits */
  663     curprivhdlr=privmibtab[((operflags&VENDOR_BITS)>>VENDOR_OFFSET)-1];
  664     if(curprivhdlr==NULL || 
  665        curprivhdlr[(CK_PRIVATEMIB_FLAGS)>>PRIVATEMIB_OFFSET].oid==NULL){
  666       if(CK_CFGSRC_FLAG) {
  667     not_sup("cfgsrc",session.Hostname());
  668     error=-1;
  669     pthread_exit(&error);
  670       }
  671     }else{
  672       curprivhdlr+=((CK_PRIVATEMIB_FLAGS)>>PRIVATEMIB_OFFSET)-1;
  673       OidSeq privreq(1,curprivhdlr->oid);
  674       OidSeq *privresp;
  675       try{
  676     privresp=session.get(&privreq);
  677       } catch (SNMP_error_unrecoverable &error_code){
  678     handle_unrecoverable(progname, session.ConnHost(),error_code);
  679       }
  680       assert(privresp);
  681       BerBase *privinfo=privresp->value(curprivhdlr->oid);
  682       assert(privinfo);
  683       (curprivhdlr->hfunct)(session,argflags,privinfo);
  684     }
  685   } // end of private mib processing
  686 
  687   return errorp;
  688 }
  689