"Fossies" - the Fresh Open Source Software Archive

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