"Fossies" - the Fresh Open Source Software Archive

Member "npadmin-0.14/npahelpers.C" (30 Mar 2006, 32340 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) 2002 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 <stdio.h>
   22 #include <assert.h>
   23 #include <string.h>
   24 
   25 #include "argflags.h"
   26 #include "npaconsts.h"
   27 #include "npastructs.h"
   28 #include "npaoids.h"
   29 #include "structfill.h"
   30 #include "compat.h"
   31 
   32 #define MAXSTR 1024
   33 
   34 #define ERR_NO_RESPONSE 8 
   35 #define ERR_SOCK_ERROR 9 
   36 #define ERR_NOT_PRINTER 10
   37 #define ERR_UNKNOWN_DEVICE 11
   38 
   39 #define CAN_VENDOR         0x00000900ul
   40 
   41 extern char *progname;
   42 
   43 static ConnectionInfo DUMMY_CONNINFO;
   44 static HrStorageTable BHSID;
   45 
   46 static const char EFISTR2[]="EFI Fiery Server ZX";
   47 static const char EFISTR3[]="EFI Fiery XJ/XJ+";
   48 static const char EFISTR[]="EFI Fiery Color Printer Server";
   49 static const char FUJISTR[]="Able Model-PRII";
   50 static const char HPSTR[]="JETDIRECT";
   51 static const char IBMSTR[]="IBM";
   52 static const char LEXMARKSTR[]="Lexmark";
   53 static const char QMSSTR[]="QMS";
   54 static const char RICOHSTR[]="RICOH Aficio";
   55 static const char TEKTRONIXSTR[]="Tektronix";
   56 static const char XEROXDC220STR[]="181;HD8005858;";
   57 static const char XEROXDC230STR2[]=";C1H017730;";
   58 static const char XEROXDC230STR[]="131;C1H011131;";
   59 static const char XEROXDC265STR[]="3UP060485";
   60 static const char XEROXSTR[]="Xerox";
   61 static const char XEROXTEKTRONIXSTR[]="XEROX";
   62 static const char CANONSTR[]="Canon";
   63 
   64 static const char *TCPSTATES[]={
   65   NULL,"closed","listen","synSent","synReceived","established",
   66   "finWait1","finWait2","closeWait","lastAck","closing","timeWait"};
   67 static const char *HRSTATUSSTATES[]={
   68   NULL,"other","unknown","idle","printing","warmup"};
   69 static const char *HPCFGSOURCESTATES[]={
   70   "bootp","manual","unknown","manual","bootp","dhcp"};
   71 
   72 static char HPINFO[]=_HPINFO_;
   73 static char HPNPSYSSTATUSMESSAGE[]=_HPNPSYSSTATUSMESSAGE_;
   74 static char HPNPGDSTATUSDISPLAY[]=_HPNPGDSTATUSDISPLAY_;
   75 // static char HPNPPAGECOUNT[]=_HPNPPAGECOUNT_;
   76 static char HPREBOOT[]=_HPREBOOT_;
   77 static char HPICFDOWNLOADSTATUS[]=_HPICFDOWNLOADSTATUS_;
   78 static char HPICFDOWNLOADTDOMAIN[]=_HPICFDOWNLOADTDOMAIN_;
   79 static char HPICFDOWNLOADTADDRESS[]=_HPICFDOWNLOADTADDRESS_;
   80 static char HPICFDOWNLOADFILENAME[]=_HPICFDOWNLOADFILENAME_;
   81 static char SYSDESC[]=_SYSDESC_;
   82 char SYSCONTACT[]=_SYSCONTACT_;
   83 char SYSLOCATION[]=_SYSLOCATION_;
   84 static char IFTYPE[]=_IFTYPE_;
   85 static char IFPHYSICALADDRESS[]=_IFPHYSICALADDRESS_;
   86 static char IPROUTENEXTHOP[]=_IPROUTENEXTHOP_;
   87 static char HRDEVICEDESC[]=_HRDEVICEDESC_;
   88 static char HRMEMORYSIZE[]=_HRMEMORYSIZE_;
   89 static char HRMEMORYSIZE1[]=_HRMEMORYSIZE1_;
   90 static char HRPRINTERSTATUS[]=_HRPRINTERSTATUS_;
   91 static char TKMODEL[]=_TKMODEL_;
   92 static char IPENTNETMASK_BASE[]=_IPENTNETMASK_BASE_;
   93 static char TCPCONNSTATE_BASE[]=_TCPCONNSTATE_BASE_;
   94 static char TCPCONNREMADDRESS_BASE[]=_TCPCONNREMADDRESS_BASE_;
   95 static char IFTYPE_BASE[]=_IFTYPE_BASE_;
   96 static char IFPHYSICALADDRESS_BASE[]=_IFPHYSICALADDRESS_BASE_;
   97 static char HRSSTORAGEDESCR_BASE[]=_HRSSTORAGEDESCR_BASE_;
   98 static char HRSTORAGEALLOCATIONUNITS_BASE[]=_HRSTORAGEALLOCATIONUNITS_BASE_;
   99 static char HRSTORAGESIZE_BASE[]=_HRSTORAGESIZE_BASE_;
  100 static char HRSTORAGEUSED_BASE[]=_HRSTORAGEUSED_BASE_;
  101 static char HRSTORAGEALLOCATIONFAILURES_BASE[]=_HRSTORAGEALLOCATIONFAILURES_BASE_;
  102 
  103 void handle_unrecoverable(char *prog_name,char *hostname,
  104               SNMP_error_unrecoverable &error){
  105   char errnum=0;
  106   switch(error){
  107   case SNMPERR_NoResponse:
  108     fprintf(stderr,"%s: No response from %s\n",prog_name,hostname);
  109     errnum=ERR_NO_RESPONSE;
  110     break;
  111   case SNMPERR_SocketErr:
  112     char buf[50];
  113     snprintf(buf,50,"%s: Socket error from %s\n",prog_name,hostname);
  114     perror(buf);
  115     errnum=ERR_SOCK_ERROR;
  116     break;
  117   }
  118   int *i=new int;
  119   *i=errnum;
  120   pthread_exit(i);
  121 }
  122 
  123 void usage(){
  124   fprintf(stderr,"npadmin [-c community] {options} printername\n");
  125 }
  126 
  127 void not_sup(const char *option,const char *hostname){
  128   fprintf(stderr,"%s: %s option not supported on this printer type.\n",
  129       hostname,option);
  130 }
  131 
  132 char *decode_status(long stat){
  133   char *buf=new char[256];
  134   memset(buf,0,256);
  135   if(stat&64) strcat(buf,"Transitioning ");
  136   if(stat&32) strcat(buf,"Off-Line ");
  137   if(stat&16) strcat(buf,"Critical Alerts ");
  138   if(stat&8) strcat(buf,"Non-Critical Alerts ");
  139   switch(stat&7){
  140   case 0:
  141     strcat(buf,"Available and Idle");
  142     break;
  143   case 2:
  144     strcat(buf,"Available and Standby");
  145     break;
  146   case 4:
  147     strcat(buf,"Available and Active");
  148     break;
  149   case 6:
  150     strcat(buf,"Available and Busy");
  151     break;
  152   case 1:
  153     strcat(buf,"Unavailable and OnRequest");
  154     break;
  155   case 3:
  156     strcat(buf,"Unavailable because Broken");
  157     break;
  158   case 5:
  159     strcat(buf,"Unknown");
  160     break;
  161   default:
  162     assert(0); //undefined state
  163   }
  164   return buf;
  165 }
  166 
  167 /* XXX: This is an ugly evil nasty hack. Basically HP 4 series
  168    printers and below do not support the hostmib or the printmib 
  169    but yet we still want to be able to get their current status
  170    information as well as the information in the display and so we
  171    need to get it out of the private mibs. This seems like the 
  172    right place to do it because it is before the hostmib 
  173    processing is run and after we know what kind of printer we
  174    are dealing with.  */
  175 void do_hppriv_get(SNMP_session &session, unsigned long *argflags,
  176            unsigned long &operflags){
  177   SNMP_structFiller hpprivreq(session);
  178   HPPrivInfo privinfo;
  179   char buf[MAXSTR];
  180   if(CK_STATUS_FLAG)
  181     hpprivreq.append(HPNPSYSSTATUSMESSAGE,STRING_TAG,
  182              (char*)&(privinfo.status)-(char*)&privinfo);
  183   if(CK_DISPLAY_FLAG)
  184     hpprivreq.append(HPNPGDSTATUSDISPLAY,STRING_TAG,
  185              (char*)&(privinfo.frontpanel)-(char*)&privinfo);
  186 
  187   try{
  188     hpprivreq.get(&privinfo);
  189   } catch (SNMP_error_unrecoverable &error){
  190     handle_unrecoverable(progname, session.Hostname(),error);
  191   }
  192   
  193   /* reset the flags -- we got the message but we don't want it to
  194      propegating down. */
  195   if(CK_STATUS_FLAG){
  196     RST_STATUS_FLAG;
  197     if(!(CK_HOSTMIB_FLAGS))
  198       operflags&=~NEED_HOSTMIB_FLAG;
  199     snprintf(buf,MAXSTR,"status=\"%s\";",privinfo.status);
  200     session.printstr(argflags,NEEDNL_ENTRY,buf);
  201   }
  202   if(CK_DISPLAY_FLAG){
  203     RST_DISPLAY_FLAG;
  204     if(!(CK_PRINTMIB_FLAGS))
  205       operflags&=~NEED_PRINTMIB_FLAG;
  206     snprintf(buf,MAXSTR,"displayBufferText=\"%s\";\n",privinfo.frontpanel);
  207     session.printstr(argflags,NEEDNL_ENTRY,buf);
  208   }
  209 }
  210 
  211 /* XXX: Another ugly evil nasty hack. */
  212 void do_hppriv_set(SNMP_session &session, unsigned long *argflags,
  213            char **optparam){
  214   OidSeq hpprivsets;
  215   if(CK_REBOOT_FLAG)
  216     hpprivsets.append(HPREBOOT,INT_TAG,1);
  217 
  218   if(CK_UPDATEFIRM_FLAG){
  219     //  fprintf(stderr,"debug: %s \n",optparam[UPDATEFIRM_PARAM]);
  220     hpprivsets.append(HPICFDOWNLOADSTATUS,INT_TAG,4); // create and go
  221     char prefix[]="1.3.6.1.6.1.1";
  222     hpprivsets.append(HPICFDOWNLOADTDOMAIN,OID_TAG,prefix,13);
  223     
  224     char *server,*filename;
  225     // fprintf(stderr, "debug: %s \n",optparam[UPDATEFIRM_PARAM]);
  226     server=strdup(optparam[UPDATEFIRM_PARAM]);
  227     assert(server);
  228     filename=strchr(server,':');
  229     assert(filename);
  230     *filename=0;
  231     filename++;
  232     
  233     struct hostent *he=gethostbyname(server);
  234     assert(he!=NULL);
  235     char *svrip=strdup(he->h_addr);
  236     assert(svrip!=NULL);
  237     svrip=(char*)realloc(svrip,he->h_length+3);
  238     assert(svrip!=NULL);
  239     svrip[he->h_length]=0;
  240     svrip[he->h_length+1]=0x45;
  241     svrip[he->h_length+2]=0;
  242     hpprivsets.append(HPICFDOWNLOADTADDRESS,STRING_TAG,svrip,he->h_length+2);
  243     hpprivsets.append(HPICFDOWNLOADFILENAME,STRING_TAG,filename,
  244               strlen(filename)+1);
  245     free(server);
  246   }
  247 
  248   session.set(&hpprivsets);
  249   RST_REBOOT_FLAG;
  250 }
  251 
  252 void do_general_get(SNMP_session &session, unsigned long *argflags,
  253         unsigned long &operflags,char **optparam){
  254   // setup the requests
  255   SNMP_structFiller getreq(session);
  256   GeneralPrinterInfo gpi;
  257   if(CK_VENDOR_FLAG || CK_MODEL_FLAG || CK_HOSTMIB_FLAG || CK_PRINTMIB_FLAG ||
  258      operflags&(NEED_HOSTMIB_FLAG | NEED_PRINTMIB_FLAG | NEED_VENDOR_FLAG))
  259     getreq.append(SYSDESC,STRING_TAG,(char*)&gpi.sysDesc-(char*)&gpi); 
  260   //vendor done, model done for lexmarks
  261   if(CK_CONTACT_FLAG){
  262     getreq.append(SYSCONTACT,STRING_TAG,(char*)&gpi.sysContact-(char*)&gpi);
  263     getreq.append(SYSLOCATION,STRING_TAG,(char*)&gpi.sysLocation-
  264           (char*)&gpi); 
  265     // contact done
  266   }
  267   if(CK_NETCONFIG_FLAG){
  268     getreq.append(IFPHYSICALADDRESS,STRING_TAG,(char*)&gpi.hwaddr-
  269           (char*)&gpi);
  270     getreq.append(IFTYPE,INT_TAG,(char*)&gpi.iftype-(char*)&gpi);
  271     getreq.append(IPROUTENEXTHOP,IPADDR_TAG,(char*)&gpi.gateway-(char*)&gpi);
  272 
  273     char maskbuf[50]; // should be big enough
  274     char *connhost=session.ConnHost();
  275     snprintf(maskbuf,50,"%s.%u.%u.%u.%u",IPENTNETMASK_BASE,
  276          ((unsigned)connhost[0] & 0xff),
  277          ((unsigned)connhost[1] & 0xff),
  278          ((unsigned)connhost[2] & 0xff),
  279          ((unsigned)connhost[3] & 0xff));
  280     
  281     getreq.append(maskbuf,IPADDR_TAG,(char*)&gpi.netmask-(char*)&gpi); 
  282   } // end of if(CK_NETCONFIG_FLAG)
  283   
  284   /* all the oids that fit in one packet have been loaded send 
  285      the request */
  286   char retry=0;
  287   do{
  288     try{
  289       getreq.get(&gpi);
  290       retry=0;
  291     } catch(SNMP_error_unrecoverable &error){
  292       handle_unrecoverable(progname, session.Hostname(),error);
  293     } catch(SNMP_error_oid *error){
  294       assert(retry<=2);
  295       if(*error==NOCONSTCAST IPROUTENEXTHOP){
  296     getreq.remove(IPROUTENEXTHOP);
  297     retry++;
  298       } else if(*error==SYSDESC){
  299     fprintf(stderr, 
  300         "Warning: %s does not have a system.sysDescr.0 probably "
  301         "Windows NT. Skipping.\n",session.Hostname());
  302     int *i=new int;
  303     *i=-3;
  304     pthread_exit(i);
  305       } else if(*error==SYSCONTACT || *error==SYSLOCATION){
  306     getreq.remove(SYSCONTACT);
  307     getreq.remove(SYSLOCATION);
  308     RST_CONTACT_FLAG;
  309     fprintf(stderr,
  310         "Warning: %s does't provide system.sys%s ignoring --contact."
  311         "\n",session.Hostname(),
  312         *error==SYSCONTACT?"Contact":"Location");
  313     retry++;
  314       } else {
  315     fprintf(stderr,"debug: Bad things from %s\n",session.Hostname());
  316     assert(0);
  317       }
  318     }
  319   }while(retry);
  320 
  321   char buf[MAXSTR];
  322  
  323   // print out netconfig info
  324   if(CK_NETCONFIG_FLAG){
  325     /* make sure that we have the right interface basically this 
  326        is a problem for the lexmarks because they have a psudo 
  327        interface at .1 */
  328     if(gpi.iftype!=6){ // 6 just happens to be the # for ethernet
  329       SNMP_structFiller ifreq(session);
  330       ifreq.append(IFPHYSICALADDRESS_BASE,STRING_TAG,(char*)&gpi.hwaddr-
  331            (char*)&gpi);
  332       ifreq.append(IFTYPE_BASE,INT_TAG,(char*)&gpi.iftype-(char*)&gpi);
  333       while(gpi.iftype!=6)
  334     try{
  335       if(ifreq.get_next(&gpi)==NULL){
  336         fprintf(stderr,"Warning: %s doesn't appear to have an ethernet "
  337             "interface. Can't detect hwaddr.\n",session.Hostname());
  338         break;
  339       }
  340     } catch (SNMP_error_unrecoverable &error){
  341       handle_unrecoverable(progname, session.Hostname(),error);
  342     }
  343     }
  344     
  345     /* this line expects the ip addresses to always be 4 bytes. */
  346     char *connhost=session.ConnHost();
  347     snprintf(buf,MAXSTR,"ipaddr=\"%u.%u.%u.%u\";netmask=\"%u.%u.%u.%u\";",
  348          ((unsigned)connhost[0] & 0xff),((unsigned)connhost[1] & 0xff),
  349          ((unsigned)connhost[2] & 0xff),((unsigned)connhost[3] & 0xff),
  350          ((unsigned)gpi.netmask[0] & 0xff),
  351          ((unsigned)gpi.netmask[1] & 0xff),
  352          ((unsigned)gpi.netmask[2] & 0xff),
  353          ((unsigned)gpi.netmask[3] & 0xff));
  354     session.printstr(argflags,NEEDNL_ENTRY,buf);
  355 
  356     if(gpi.iftype==6){
  357       snprintf(buf,MAXSTR,"hwaddr=\"%02x:%02x:%02x:%02x:%02x:%02x:\";",
  358            ((unsigned)gpi.hwaddr[0] & 0xff),
  359            ((unsigned)gpi.hwaddr[1] & 0xff),
  360            ((unsigned)gpi.hwaddr[2] & 0xff),
  361            ((unsigned)gpi.hwaddr[3] & 0xff),
  362            ((unsigned)gpi.hwaddr[4] & 0xff),
  363            ((unsigned)gpi.hwaddr[5] & 0xff));
  364       session.printstr(argflags,NEEDNL_ENTRY,buf);
  365     }
  366     
  367     if(gpi.gateway!=NULL){
  368       snprintf(buf,MAXSTR,"gateway=\"%u.%u.%u.%u\";",
  369            ((unsigned)gpi.gateway[0] & 0xff),
  370            ((unsigned)gpi.gateway[1] & 0xff),
  371            ((unsigned)gpi.gateway[2] & 0xff),
  372            ((unsigned)gpi.gateway[3] & 0xff));
  373       session.printstr(argflags,NEEDNL_ENTRY,buf);
  374     }else{
  375     fprintf(stderr,
  376         "Warning: %s did not report a default gateway.\n",
  377         session.Hostname());
  378     }
  379   }
  380   /* ------ model and vendor ---------------------------------- */
  381   if(gpi.sysDesc){
  382     if(strstr(gpi.sysDesc,HPSTR)){
  383       operflags|=HP_VENDOR;
  384 
  385       /* This could be located in down in the section where there 
  386      it is only executed if it is run on a 4 series printer 
  387      that  doesn't support the host mib but I am having some 
  388      trouble with sets on the 5 series printers and so I think 
  389      that it will be better to put it up here for the time 
  390      being.*/
  391       if(CK_REBOOT_FLAG || CK_UPDATEFIRM_FLAG)
  392     do_hppriv_set(session,argflags,optparam);
  393 
  394       if(CK_VENDOR_FLAG)
  395     session.printstr(argflags,NEEDNL_ENTRY,"vendor=\"HP\";");
  396 
  397       /* damn hp makes us go down to the private enterprises area 
  398      to find out the model. The new 5 series printers are a bit
  399      easier but the 4 series don't support the host mib. */
  400       if(CK_MODEL_FLAG || CK_HOSTMIB_FLAG || CK_PRINTMIB_FLAG || 
  401      operflags&(NEED_HOSTMIB_FLAG | NEED_PRINTMIB_FLAG)){
  402     OidSeq modelreq(1,HPINFO);
  403     OidSeq *modelresp;
  404     try{
  405       //fputs("debug: getting modelstr\n",stderr);
  406       modelresp=session.get(&modelreq);
  407     } catch (SNMP_error_unrecoverable &error){
  408       handle_unrecoverable(progname, session.Hostname(),error);
  409     }
  410     assert(modelresp);
  411     BerBase *hpinfo=modelresp->value(HPINFO);
  412     assert(hpinfo);
  413     assert(hpinfo->type()==STRING_TAG);
  414     char hpbuf[256];
  415     char buf2[100];
  416     char *begin;
  417     ((BerString*)hpinfo)->copy(hpbuf, 256);
  418     if(((BerString*)hpinfo)->strlen()==0){
  419       fprintf(stderr,"Warning: %s model not reported.\n",
  420           session.Hostname());
  421       if(CK_STATUS_FLAG || CK_DISPLAY_FLAG) {
  422         do_hppriv_get(session,argflags,operflags);
  423       }
  424     } else {
  425       if((begin=strstr(hpbuf, "MODEL:"))!=NULL){
  426         begin+=6; 
  427         begin+=!strncmp(begin,"HP ",3)?3:0; 
  428       } else if((begin=strstr(hpbuf,"MDL:"))
  429             !=NULL){
  430         /* work around the fact that a 1600cm doesn't have 
  431            MODEL it has MDL */
  432         begin+=4; //skip past "MDL:"
  433       } else {
  434         fprintf(stderr,
  435             "%s: Can't find \"MODEL:\" or \"MDL:\" in \"%s\"\n",
  436             session.Hostname(),hpbuf);
  437         int *i=new int;
  438         *i=-3;
  439         pthread_exit(i);
  440       }
  441       
  442       char *end=strchr(begin,';');
  443           if (end==NULL)
  444         end=begin+strlen(begin);
  445       strncpy(buf2,begin,end-begin);
  446       buf2[end-begin]='\0';
  447       if(CK_MODEL_FLAG){
  448         snprintf(buf,MAXSTR,"model=\"%s\";",buf2);
  449         session.printstr(argflags,NEEDNL_ENTRY,buf);
  450       }
  451 
  452       /* this line will probably have to be tweaked a bit I 
  453          basically believe all the HP printers except for the 
  454          5 series and the *000 series do not support the host 
  455          or printmib */
  456       /* We need to come up with a better way to do this :-) */
  457       if((strstr(buf2,"000") && !strstr(buf2,"2000")) || 
  458          (strstr(buf2,"LaserJet 5") && !strstr(buf2,"Color") && 
  459           !strstr(gpi.sysDesc,"JETDIRECT EX")) ||
  460          strstr(buf2, "4500") || strstr(buf2, "8500") || //color printers
  461 
  462          strstr(buf2, "2100") || strstr(buf2, "2200") || 
  463 
  464          strstr(buf2, "4050") || strstr(buf2, "4100") || 
  465          strstr(buf2, "4200") || strstr(buf2, "4300") || 
  466 
  467          strstr(buf2, "5100") ||
  468 
  469          strstr(buf2, "8100") || strstr(buf2, "8150") ||
  470          strstr(buf2, "9000")){
  471         operflags|=HAS_PRINTMIB_FLAG;
  472         // work around acient broken firmware
  473         if(!strstr(gpi.sysDesc,"EEPROM A.03."))
  474           operflags|=HAS_HOSTMIB_FLAG;
  475         else
  476           fprintf(stderr,
  477               "Warning: %s has ancient firmware. Please upgrade it!\n",
  478               session.Hostname());
  479       } else {
  480         if(CK_STATUS_FLAG || CK_DISPLAY_FLAG) 
  481           do_hppriv_get(session,argflags,operflags);
  482         if (CK_LANGUAGES_FLAGS){
  483           if((begin=strstr(hpbuf,
  484                "COMMAND SET:"))!=NULL){
  485         begin+=12;
  486           } else if((begin=strstr(hpbuf,"CMD:"))
  487                     !=NULL){
  488         begin+=4;
  489           }
  490           end=strchr(begin,';');
  491               if (end==NULL)
  492                 end=begin+strlen(begin);
  493           strncpy(buf2,begin,end-begin);
  494           buf2[end-begin]='\0';
  495           end=buf2-1;
  496           do
  497           {
  498         begin=end+1;
  499             end=strchr(begin, ',');
  500             if (end)
  501           *end='\0';
  502 
  503             if(CK_POSTSCRIPT_FLAG && strcmp(begin, "POSTSCRIPT")==0) {
  504           session.printstr(argflags,NEEDNL_ENTRY,"postscript=\"Y\";");
  505                   RST_POSTSCRIPT_FLAG;
  506             }
  507 
  508             if(CK_PCL_FLAG && strcmp(begin, "PCL")==0) {
  509           session.printstr(argflags,NEEDNL_ENTRY,"pcl=\"Y\";");
  510                   RST_PCL_FLAG;
  511             }
  512 
  513             if(CK_HPGL_FLAG && strcmp(begin, "HP-GL")==0) {
  514           session.printstr(argflags,NEEDNL_ENTRY,"hpgl=\"Y\";");
  515                   RST_HPGL_FLAG;
  516             }
  517 
  518             if(CK_PJL_FLAG && strcmp(begin, "PJL")==0) {
  519           session.printstr(argflags,NEEDNL_ENTRY,"pjl=\"Y\";");
  520                   RST_PJL_FLAG;
  521             }
  522 
  523           } while(end);
  524         }
  525       }
  526     }
  527     delete modelresp;
  528       }
  529     } else if(!strncmp(gpi.sysDesc,LEXMARKSTR,7)){
  530       operflags|=LEX_VENDOR;
  531       operflags|=HAS_HOSTMIB_FLAG|HAS_PRINTMIB_FLAG;
  532       if(CK_VENDOR_FLAG){
  533     session.printstr(argflags,NEEDNL_ENTRY,"vendor=\"Lexmark\";");
  534       }
  535       if(CK_MODEL_FLAG){
  536     char buf2[50];
  537     char *begin=gpi.sysDesc+8;
  538     /* this is a cool thing. On the lexmarks that I have 
  539        looked at they seperate the version and the model with 
  540        a double space. This makes parsing easier. */
  541     int len=strstr(begin,"  ")-begin;
  542     strncpy(buf2,begin,len);
  543     buf2[len]=0;
  544     snprintf(buf,MAXSTR,"model=\"%s\";",buf2);
  545     session.printstr(argflags,NEEDNL_ENTRY,buf);
  546       }
  547     } else if(!strncmp(gpi.sysDesc,TEKTRONIXSTR,9)){
  548       char tekbuf[256];
  549       operflags|=HAS_HOSTMIB_FLAG|HAS_PRINTMIB_FLAG|TEK_VENDOR;
  550       OidSeq modelreq(1,HRDEVICEDESC);
  551       OidSeq *modelresp;
  552       try{
  553     modelresp=session.get(&modelreq);
  554       } catch (SNMP_error_unrecoverable &error){
  555     handle_unrecoverable(progname, session.Hostname(),error);
  556       } catch(SNMP_error_oid *error){
  557     fprintf(stderr,
  558            "Warning: Tektronix printer %s does not support the hostmib.\n",
  559         session.Hostname());
  560     operflags&=~(HAS_HOSTMIB_FLAG|HAS_PRINTMIB_FLAG);
  561     modelreq.remove(HRDEVICEDESC);
  562     modelreq.append(TKMODEL);
  563     try{
  564       modelresp=session.get(&modelreq);
  565     } catch (SNMP_error_unrecoverable &err){
  566       handle_unrecoverable(progname, session.Hostname(),err);
  567     } catch (SNMP_error_oid *err){
  568       assert(0);
  569     }
  570     if(CK_MODEL_FLAG){
  571       RST_MODEL_FLAG;
  572       BerBase *hrdevdesc=modelresp->value(TKMODEL);
  573       assert(hrdevdesc->type()==STRING_TAG);
  574       ((BerString*)hrdevdesc)->copy(tekbuf, 256);
  575       snprintf(buf,MAXSTR,"model=\"%s\";",tekbuf);
  576       session.printstr(argflags,NEEDNL_ENTRY,buf);
  577       delete modelresp;
  578     }
  579     if(CK_SERIALNUM_FLAG){
  580       
  581     }
  582       }
  583       if(CK_VENDOR_FLAG){
  584     session.printstr(argflags,NEEDNL_ENTRY,"vendor=\"Tektronix\";");
  585       }
  586       if(CK_MODEL_FLAG){
  587     assert(modelresp);
  588     BerBase *hrdevdesc=modelresp->value(HRDEVICEDESC);
  589     assert(hrdevdesc->type()==STRING_TAG);
  590         ((BerString*)hrdevdesc)->copy(tekbuf, 256);
  591     char *begin=strstr(tekbuf,"Inc., ");
  592     if (begin) {
  593       char buf2[50];
  594           begin+=6;
  595       int len=strchr(begin,',')-begin;
  596       strncpy(buf2,begin,len);
  597       buf2[len]=0;
  598       snprintf(buf,MAXSTR,"model=\"%s\";",buf2);
  599       session.printstr(argflags,NEEDNL_ENTRY,buf);
  600     } else {
  601       fprintf(stderr,
  602             "%s: Can't find \"Inc., \" in \"%s\"\n",
  603             session.Hostname(),tekbuf);
  604     }
  605     delete modelresp;
  606       }      
  607     } else if(!strncmp(gpi.sysDesc,XEROXTEKTRONIXSTR,5)){
  608       if(CK_VENDOR_FLAG)
  609        session.printstr(argflags,NEEDNL_ENTRY,"vendor=\"Xerox/Tektronix\";");
  610       if(strstr(gpi.sysDesc,"???")){
  611        if(CK_MODEL_FLAG)
  612          not_sup("model",session.Hostname());
  613        operflags|=XER_VENDOR;
  614       } else {
  615        if(CK_MODEL_FLAG){
  616          char *model=strchr(gpi.sysDesc,' ')+1;
  617          snprintf(buf,MAXSTR,"model=\"%s\";",model);
  618          session.printstr(argflags,NEEDNL_ENTRY,buf);
  619        }
  620        operflags|=HAS_HOSTMIB_FLAG|HAS_PRINTMIB_FLAG|XER_VENDOR;
  621       }
  622     } else if(!strncmp(gpi.sysDesc,XEROXSTR,5)){
  623       if(CK_VENDOR_FLAG)
  624     session.printstr(argflags,NEEDNL_ENTRY,"vendor=\"Xerox\";");
  625       if(strstr(gpi.sysDesc,"???")){
  626     if(CK_MODEL_FLAG)
  627       not_sup("model",session.Hostname());
  628     operflags|=XER_VENDOR;
  629       } else {
  630     if(CK_MODEL_FLAG){
  631       char *model=strchr(gpi.sysDesc,' ')+1;
  632       snprintf(buf,MAXSTR,"model=\"%s\";",model);
  633       session.printstr(argflags,NEEDNL_ENTRY,buf);
  634     }
  635     operflags|=HAS_HOSTMIB_FLAG|HAS_PRINTMIB_FLAG|XER_VENDOR;
  636       }
  637     } else if(!strncmp(gpi.sysDesc,XEROXDC230STR,14) || 
  638           !strncmp(gpi.sysDesc,XEROXDC230STR2,10)){
  639       operflags|=HAS_HOSTMIB_FLAG|HAS_PRINTMIB_FLAG|XER_VENDOR;
  640       if(CK_VENDOR_FLAG)
  641     session.printstr(argflags,NEEDNL_ENTRY,"vendor=\"Xerox\";");
  642       if(CK_MODEL_FLAG)
  643     session.printstr(argflags,NEEDNL_ENTRY,
  644              "model=\"Document Centre 230ST\";");
  645     } else if(!strncmp(gpi.sysDesc,XEROXDC265STR,9)){
  646       operflags|=HAS_HOSTMIB_FLAG|HAS_PRINTMIB_FLAG|XER_VENDOR;
  647       if(CK_VENDOR_FLAG)
  648     session.printstr(argflags,NEEDNL_ENTRY,"vendor=\"Xerox\";");
  649       if(CK_MODEL_FLAG)
  650     session.printstr(argflags,NEEDNL_ENTRY,
  651              "model=\"Document Centre 265\";");      
  652     } else if(!strncmp(gpi.sysDesc,XEROXDC220STR,9)){
  653       operflags|=HAS_HOSTMIB_FLAG|HAS_PRINTMIB_FLAG|XER_VENDOR;
  654       if(CK_VENDOR_FLAG)
  655     session.printstr(argflags,NEEDNL_ENTRY,"vendor=\"Xerox\";");
  656       if(CK_MODEL_FLAG)
  657     session.printstr(argflags,NEEDNL_ENTRY,
  658              "model=\"Document Centre 220ST\";");      
  659     }  else if(!strncmp(gpi.sysDesc,QMSSTR,3)){
  660       operflags|=QMS_VENDOR;
  661       if(CK_VENDOR_FLAG)
  662     session.printstr(argflags,NEEDNL_ENTRY,"vendor=\"QMS\";");
  663       if(CK_MODEL_FLAG){
  664     strtok(gpi.sysDesc,";");
  665     snprintf(buf,MAXSTR,"model=\"%s\";",gpi.sysDesc+4);
  666     session.printstr(argflags,NEEDNL_ENTRY,buf);
  667       }      
  668     } else if(!strncmp(gpi.sysDesc,IBMSTR,3)){
  669       operflags|=IBM_VENDOR;
  670       if(CK_VENDOR_FLAG)
  671     session.printstr(argflags,NEEDNL_ENTRY,"vendor=\"IBM\";");
  672       if(CK_MODEL_FLAG){
  673     strtok(gpi.sysDesc+4," ");
  674     snprintf(buf,MAXSTR,"model=\"%s\";",gpi.sysDesc+4);
  675     session.printstr(argflags,NEEDNL_ENTRY,buf);
  676       }
  677     } else if(!strncmp(gpi.sysDesc,EFISTR,strlen(EFISTR))){
  678       operflags|=HAS_HOSTMIB_FLAG|EFI_VENDOR;
  679       if(CK_VENDOR_FLAG)
  680     session.printstr(argflags,NEEDNL_ENTRY,"vendor=\"EFI\";");
  681       if(CK_MODEL_FLAG)
  682     not_sup("model",session.Hostname());
  683     } else if(!strncmp(gpi.sysDesc,EFISTR2,strlen(EFISTR2)) ||
  684              !strncmp(gpi.sysDesc,EFISTR3,strlen(EFISTR3))){ 
  685       operflags|=HAS_HOSTMIB_FLAG|EFI_VENDOR;
  686       if(CK_VENDOR_FLAG)
  687        session.printstr(argflags,NEEDNL_ENTRY,"vendor=\"EFI\";");
  688       if(CK_MODEL_FLAG){
  689        strtok(gpi.sysDesc+4," ");
  690        snprintf(buf,MAXSTR,"model=\"%s\";",gpi.sysDesc+4);
  691        session.printstr(argflags,NEEDNL_ENTRY,buf);
  692       }
  693     } else if(!strncmp(gpi.sysDesc,FUJISTR,strlen(FUJISTR))){
  694       /* I think that this was a mistake and so I commented this
  695      out. However, there might be a fuji printer out there
  696      somewhere which does support the host mib and the print
  697      mib. If there is then we will have to make a much more
  698      exacting test. */
  699       // operflags|=HAS_HOSTMIB_FLAG|FUJI_VENDOR;
  700       if(CK_VENDOR_FLAG)
  701     session.printstr(argflags,NEEDNL_ENTRY,"vendor=\"Fuji\";");
  702       if(CK_MODEL_FLAG)
  703     session.printstr(argflags,NEEDNL_ENTRY,"model=\"Able PRII\";");
  704     } else if(!strncmp(gpi.sysDesc,RICOHSTR,strlen(RICOHSTR))){
  705       if(CK_VENDOR_FLAG)
  706        session.printstr(argflags,NEEDNL_ENTRY,"vendor=\"Ricoh\";");
  707       if(CK_MODEL_FLAG){
  708        snprintf(buf,MAXSTR,"model=\"%s\";",gpi.sysDesc+6);
  709        session.printstr(argflags,NEEDNL_ENTRY,buf);
  710       }
  711       operflags|=HAS_HOSTMIB_FLAG|HAS_PRINTMIB_FLAG|RICOH_VENDOR;
  712       /* Hopefully none of these give false positives. This sort of filter's
  713      out some of the more obvious non-printer snmp services */
  714     } else if(!strncmp(gpi.sysDesc,CANONSTR,5)){
  715       if(CK_VENDOR_FLAG)
  716     session.printstr(argflags,NEEDNL_ENTRY,"vendor=\"Canon\";");
  717       if(strstr(gpi.sysDesc,"???")){
  718     if(CK_MODEL_FLAG)
  719       not_sup("model",session.Hostname());
  720     operflags|=XER_VENDOR;
  721       } else {
  722     if(CK_MODEL_FLAG){
  723       char *model=strchr(gpi.sysDesc,' ')+1;
  724       snprintf(buf,MAXSTR,"model=\"%s\";",model);
  725       session.printstr(argflags,NEEDNL_ENTRY,buf);
  726     }
  727     operflags|=HAS_HOSTMIB_FLAG|HAS_PRINTMIB_FLAG|CAN_VENDOR;
  728       }
  729     } else if(!strstr(gpi.sysDesc,"HP-UX") || !strstr(gpi.sysDesc,"HPUX") || 
  730            !strstr(gpi.sysDesc,"Windows NT") || 
  731            !strstr(gpi.sysDesc,"Sun SNMP Agent") ||
  732            !strstr(gpi.sysDesc,"SunOS") || 
  733            !strstr(gpi.sysDesc,"Macintosh") || 
  734            !strstr(gpi.sysDesc,"UNIX")){
  735        fprintf(stderr,
  736            "Warning: %s does not appear to be a printer. Skipping.\n",
  737            session.Hostname());
  738       int *i=new int;
  739       *i=ERR_NOT_PRINTER;
  740       pthread_exit(i);       
  741      } else {
  742       fprintf(stderr,"Warning: %s: unknown printer vendor. Describes itself "
  743           "as \"%s\"\n",session.Hostname(),gpi.sysDesc);
  744       int *i=new int;
  745       *i=ERR_UNKNOWN_DEVICE;
  746       pthread_exit(i);
  747     }
  748   }
  749 
  750   /* ------- print out the contact information --------------------------- */
  751   if(CK_CONTACT_FLAG){
  752     snprintf(buf,MAXSTR,"contact=\"%s\";location=\"%s\";",
  753          gpi.sysContact?gpi.sysContact:"",
  754          gpi.sysLocation?gpi.sysLocation:"");
  755     session.printstr(argflags,NEEDNL_ENTRY,buf);
  756   }
  757 
  758   if(CK_HOSTMIB_FLAG){
  759     snprintf(buf,MAXSTR,"hostmib=\"%c\";",operflags&HAS_HOSTMIB_FLAG?'Y':'N');
  760     session.printstr(argflags,NEEDNL_ENTRY,buf);
  761   }
  762   if(CK_PRINTMIB_FLAG){
  763     snprintf(buf,MAXSTR,"printmib=\"%c\";",
  764          operflags&HAS_PRINTMIB_FLAG?'Y':'N');
  765     session.printstr(argflags,NEEDNL_ENTRY,buf);
  766   }
  767 }
  768 
  769 void do_connections(unsigned long *argflags,SNMP_session &session,
  770             ConnectionInfoRequest *cir){
  771   ConnectionInfoRequest *cur=cir;
  772   
  773   while(cur){
  774     SNMP_table conntabreq(session, sizeof(ConnectionInfo));
  775     cur->statebuf=new char[1024];
  776     int len=strlen(TCPCONNSTATE_BASE);
  777     /* we can assume that this worked otherwise the session would
  778        have failed above and we can also assume that printers 
  779        only have one ip address right? */
  780     strcpy(cur->statebuf,TCPCONNSTATE_BASE);
  781     // append the ipaddress and the port to the base oid
  782     len+=sprintf(cur->statebuf+strlen(cur->statebuf),".%u.%u.%u.%u.%u",
  783          ((unsigned)session.ConnHost()[0] & 0xff),
  784          ((unsigned)session.ConnHost()[1] & 0xff),
  785          ((unsigned)session.ConnHost()[2] & 0xff),
  786          ((unsigned)session.ConnHost()[3] & 0xff),
  787          ((unsigned)cur->port & 0xffff))+1;
  788     cur->statebuf=(char*)realloc(cur->statebuf,len+1);
  789     conntabreq.append(cur->statebuf,INT_TAG,
  790               ((char*)&(DUMMY_CONNINFO.connState))-
  791               (char*)&DUMMY_CONNINFO);
  792       
  793     cur->remaddrbuf=new char[1024];
  794     len=strlen(TCPCONNREMADDRESS_BASE);
  795     char *p=session.ConnHost();
  796     strcpy(cur->remaddrbuf,TCPCONNREMADDRESS_BASE);
  797     // append the ipaddress and the port to the base oid
  798     len+=sprintf(cur->remaddrbuf+strlen(cur->remaddrbuf),".%u.%u.%u.%u.%u",
  799          ((unsigned)p[0] & 0xff),((unsigned)p[1] & 0xff),
  800          ((unsigned)p[2] & 0xff),((unsigned)p[3] & 0xff),
  801          ((unsigned)cur->port & 0xffff))+1;
  802     cur->remaddrbuf=(char*)realloc(cur->remaddrbuf,len+1);
  803     conntabreq.append(cur->remaddrbuf,IPADDR_TAG,
  804               ((char*)&(DUMMY_CONNINFO.remhost))-
  805               (char*)&DUMMY_CONNINFO);
  806     unsigned int numrecords;
  807     try{
  808       cur->conninfo=(ConnectionInfo*)conntabreq.get(numrecords);
  809     } catch (SNMP_error_unrecoverable &error){
  810       handle_unrecoverable(progname, session.Hostname(),error);
  811     }    
  812     cur=cur->next;
  813   }  
  814 
  815   // print out connection info
  816   for(cur=cir;cur!=NULL;cur=cur->next){
  817     char buf[MAXSTR];
  818     assert(cur->conninfo->connState>0 && cur->conninfo->connState<=11);
  819     snprintf(buf,MAXSTR,
  820          "port=\"%u\";state=\"%s\";remotehost=\"%u.%u.%u.%u\"\n",
  821          cur->port,TCPSTATES[cur->conninfo->connState],
  822          ((unsigned)cur->conninfo->remhost[0] & 0xff),
  823          ((unsigned)cur->conninfo->remhost[1] & 0xff),
  824          ((unsigned)cur->conninfo->remhost[2] & 0xff),
  825          ((unsigned)cur->conninfo->remhost[3] & 0xff));
  826     session.printstr(argflags,NEEDNL_LINE,buf);
  827   }
  828 }
  829 
  830 void do_hostmib_get(SNMP_session &session, unsigned long *argflags,
  831             unsigned long &operflags){
  832   if(CK_MEMORY_FLAG || CK_STATUS_FLAG){
  833     HostPrinterInfo hprinfo;
  834     char buf[MAXSTR];
  835 
  836     SNMP_structFiller getreq(session);
  837     if(CK_MEMORY_FLAG)
  838       getreq.append(HRMEMORYSIZE,INT_TAG,
  839             (char*)&(hprinfo.memsize)-(char*)&hprinfo);
  840     if(CK_STATUS_FLAG)
  841       getreq.append(HRPRINTERSTATUS,INT_TAG,
  842             (char*)&(hprinfo.prstatus)-(char*)&hprinfo);
  843 
  844     char retry=0;
  845     do{
  846       try{
  847     getreq.get(&hprinfo);
  848     retry=0;
  849       } catch(SNMP_error_unrecoverable &error){
  850     handle_unrecoverable(progname, session.Hostname(),error);
  851       } catch(SNMP_error_oid *error){
  852     assert(retry<=2); //something is bad the request is looping
  853     if(*error==HRMEMORYSIZE){
  854       /* this is a hack that takes care of a xerox printer that
  855          stores it in .1 rather than .0 */
  856       getreq.remove(HRMEMORYSIZE);
  857       getreq.append(HRMEMORYSIZE1,INT_TAG,
  858             (char*)&(hprinfo.memsize)-(char*)&hprinfo);
  859       retry++;
  860     } else if(*error==HRPRINTERSTATUS && operflags&HP_VENDOR){
  861       getreq.remove(HRPRINTERSTATUS);
  862       fprintf(stderr,
  863           "Warning: %s has an old firmware. Please upgrade it!\n",
  864           session.Hostname());
  865       do_hppriv_get(session,argflags,operflags);
  866       if(CK_MEMORY_FLAG) // only retry if there is another oid
  867         retry++;
  868     } else {
  869       assert(0); //tell me about this something went really wrong
  870     }
  871       }
  872     }while(retry);
  873 
  874     if(CK_MEMORY_FLAG){
  875       snprintf(buf,MAXSTR,"memsize=\"%lu\";",hprinfo.memsize);
  876       session.printstr(argflags,NEEDNL_ENTRY,buf);
  877     }
  878     if(CK_STATUS_FLAG){
  879       assert(hprinfo.prstatus>=0 && hprinfo.prstatus<=5 && 
  880          HRSTATUSSTATES[hprinfo.prstatus]!=NULL);
  881       snprintf(buf,MAXSTR,"status=\"%s\";",HRSTATUSSTATES[hprinfo.prstatus]);
  882       session.printstr(argflags,NEEDNL_ENTRY,buf);
  883     }
  884   }
  885   if(CK_STORAGE_FLAG){
  886     HrStorageTable *storage;
  887     unsigned int len;
  888     SNMP_table stortabreq(session,sizeof(HrStorageTable));
  889     stortabreq.append(HRSSTORAGEDESCR_BASE,STRING_TAG,
  890               (char*)&BHSID.desc-(char*)&BHSID);
  891     stortabreq.append(HRSTORAGEALLOCATIONUNITS_BASE,INT_TAG,
  892               (char*)&BHSID.allocunits-(char*)&BHSID);
  893     stortabreq.append(HRSTORAGESIZE_BASE,INT_TAG,
  894               (char*)&BHSID.size-(char*)&BHSID);
  895     stortabreq.append(HRSTORAGEUSED_BASE,INT_TAG,
  896               (char*)&BHSID.used-(char*)&BHSID);
  897     stortabreq.append(HRSTORAGEALLOCATIONFAILURES_BASE,COUNTER_TAG,
  898               (char*)&BHSID.failures-(char*)&BHSID);
  899     try{
  900       storage=(HrStorageTable*)stortabreq.get(len);
  901       assert(storage);
  902     } catch (SNMP_error_unrecoverable &error){
  903       handle_unrecoverable(progname, session.Hostname(),error);
  904     }
  905 
  906     while(len){
  907       len--;
  908       char buf[MAXSTR];
  909       snprintf(buf,MAXSTR,"desc=\"%s\";allocunits=\"%lu\";size=\"%lu\";"
  910            "used=\"%lu\";allocfail=\"%lu\";\n",storage[len].desc,
  911          storage[len].allocunits,storage[len].size,storage[len].used,
  912          storage[len].failures);
  913       session.printstr(argflags,NEEDNL_ENTRY,buf);
  914     }
  915     delete storage;
  916   }
  917 }
  918 
  919 void hpcfgsrc(SNMP_session &session,unsigned long *argflags,
  920           BerBase *cfgsrcdat){
  921   assert(cfgsrcdat->type()==INT_TAG);
  922   unsigned long cfgtype=((BerInt*)cfgsrcdat)->value();
  923   assert(cfgtype<=5 && HPCFGSOURCESTATES[cfgtype]!=NULL);
  924   char buf[MAXSTR];
  925   snprintf(buf,MAXSTR,"cfgsrc=\"%s\";",HPCFGSOURCESTATES[cfgtype]);
  926   session.printstr(argflags,NEEDNL_ENTRY,buf);
  927 }