#include <stdlib.h>
#include <assert.h>
#include <stdio.h>
#include <limits.h>
#include <time.h>

#include "printmib.h"
#include "npaconsts.h"
#include "npastructs.h"
#include "npaoids.h"
#include "argflags.h"
#include "npahelpers.h"

#define MAXSTR 512

extern char *progname;

MarkerTable BMTID;
MediaPathInfo BMPID;
InputTrayInfo BITID;
CoverTable BCTID;
LangInfo BLTID;
ProtocolTable BPTID;
MarkerSuppliesTable BMSTID;
AlertTable BATID;

static const char OTHERSTR[]="other";
static const char UNKNOWNSTR[]="unknown";
static const char TENTHOUSANDTHSOFINCHES[]="tenThousandthsOfInches";
static const char MICROMETERS[]="micrometers";
static const char IMPRESSIONS[]="impressions";
static const char SHEETS[]="sheets";
static const char HOURS[]="hours";

static const char *MARKTECH[]={NULL,OTHERSTR,UNKNOWNSTR,
			       "electrophotographicLED",
			       "electrophotographicLaser",
			       "electrophotographicOther",
			       "impactMovingHeadDotMatrix9pin",
			       "impactMovingHeadDotMatrix24pin",
			       "impactMovingHeadDotMatrixOther",
			       "impactMovingHeadFullyFormed",
			       "impactBand","impactOther",
			       "inkjetAqueous","inkjetSolid",
			       "inkjetOther","pen","thermalTransfer",
			       "thermalSensitive","thermalDiffusion",
			       "thermalOther","electroerosion",
			       "electrostatic","photographicMicrofiche",
			       "photographicImagesetter",
			       "photographicOther","ionDeposition",
			       "eBeam","typesetter"};

static const char *MARKERCOUNTERUNIT[]={NULL,NULL,NULL,
					TENTHOUSANDTHSOFINCHES,MICROMETERS,
					"characters","lines",IMPRESSIONS,
					SHEETS,"dotRow",NULL,HOURS,NULL,NULL,
					NULL,NULL,"feet","meters"};

static const char *MEDIAUNIT[]={NULL,NULL,NULL,TENTHOUSANDTHSOFINCHES,
				MICROMETERS};

/* xxx check input tray & marker processing code before you change this. */
static const char *MEDIASPEEDUNIT[]={NULL,NULL,NULL,
				     "tenThousandthsOfInchesPerHour",
				     "micrometersPerHour","charactersPerHour",
				     "linesPerHour","impressionsPerHour",
				     "sheetsPerHour","dotRowPerHour",NULL,NULL,
				     NULL,NULL,NULL,NULL,"feetPerHour",
				     "metersPerHour"};

static const char *MEDIATYPE[]={NULL,OTHERSTR,UNKNOWNSTR,
				"longEdgeBindingDuplex",
				"shortEdgeBindingDuplex","simplex"};
static const char *INPUTTYPE[]={NULL,OTHERSTR,UNKNOWNSTR,
				"sheetFeedAutoRemovableTray",
				"sheetFeedAutoNonRemovableTray",
				"sheetFeedManual","continuousRoll",
				"continuousFanFold"};
static const char *CAPACITYUNIT[]={NULL,NULL,NULL,TENTHOUSANDTHSOFINCHES,
				   MICROMETERS,NULL,NULL,NULL,SHEETS,NULL,
				   NULL,NULL,NULL,NULL,NULL,NULL,"feet",
				   "meters"};
static const char *LANGUAGES[]={NULL,OTHERSTR,NULL,"PCL","HPGL","PJL","PS",
				"IDPS","PPDS","EscapeP","Epson","DDIF",
				"Interpress","ISO6429","LineData","MODCA",
				"REGIS","SCS","SPDL","TEK401","PDS","IGP",
				"CodeV","DSCDSE","WPS","LN03","CCITT","QUIC",
				"CPAP","DecPPL","SimpleText","NPAP","DOC",
				"imPress","Pinwriter","NPDL","NEC201PL",
				"Automatic","Pages","LIPS","TIFF","Diagnostic",
				"PSPrinter","CaPSL","EXCL","LCDS","XES",
				"PCLXL"};
static const char *ORIENTATIONS[]={NULL,OTHERSTR,NULL,"portrait","landscape"};
static const char *COVERSTATUS[]={NULL,OTHERSTR,NULL,"doorOpen","doorClosed",
				  "interlockOpen","interlockClosed"};
static const char *CHANNELTYPE[]={NULL,OTHERSTR,NULL,"SerialPort",
				  "ParallelPort","IEEE1284Port",
				  "SCSIPort","AppleTalkPAP","LPDServer",
				  "NetwareRPrinter","NetwarePServer",
				  "Port9100(depricated)","AppSocket","FTP",
				  "TFTP","DLCLLCPort","IBM3270","IBM5250",
				  "Fax","IEEE1394","Transport1","CPAP",NULL,
				  NULL,NULL,NULL,"PCPrint",
				  "ServerMessageBlock","PSM",NULL,NULL,
				  "SystemObjectManager","DECLAT","NPAP","USB",
				  "IRDA","PrintXChange","PortTCP",
				  "BidirPortTCP","UNPP","AppleTalkADSP",
				  "PortSPX","PortHTTP","NDPS"};
static const char *CHANNELSTATE[]={NULL,OTHERSTR,NULL,"printDataAccepted",
				   "noDataAccepted"};
static const char *MARKERSUPPLIESCLASS[]={NULL,OTHERSTR,NULL,
					  "supplyThatIsConsumed",
					  "receptacleThatIsFilled"};
static const char *MARKERSUPPLIESTYPE[]={NULL,OTHERSTR,UNKNOWNSTR,"toner",
					 "wasteToner","ink","inkCartridge",
					 "inkRibbon","wasteInk","opc",
					 "developer","fuserOil","solidWax",
					 "ribbonWax","wasteWax","fuser",
					 "coronaWire","fuserOilWick",
					 "cleanerUnit","fuserCleaningPad",
					 "transferUnit","tonerCartridge",
					 "fuserOiler"};
static const char *MARKERSUPPLIESSUPPLYUNIT[]={NULL,NULL,NULL,
					       TENTHOUSANDTHSOFINCHES,
					       MICROMETERS,NULL,NULL,
					       IMPRESSIONS,SHEETS,
					       NULL,HOURS,NULL,
					       "thousandthsOfOunces",
					       "tenthsOfGrams",
					       "hundrethsOfFluidOunces",
					       "tenthsOfMilliliters","feet",
					       "meters"};
static const char *PRTALERTSEVERITYLEVEL[]={NULL,OTHERSTR,NULL,"critical",
					    "warning"};
static const char *PRTALERTTRAININGLEVEL[]={NULL,OTHERSTR,UNKNOWNSTR,
					    "untrained","trained",
					    "fieldService","management"};
static const char *PRTALERTGROUP[]={NULL,OTHERSTR,NULL,
				    "hostResourcesMIBStorageTable",
				    "hostResourcesMIBDeviceTable",
				    "generalPrinter","cover","localization",
				    "input","output","marker","markerSupplies",
				    "markerColorant","mediaPath","channel",
				    "interpreter","consoleDisplayBuffer",
				    "consoleLights"};

// All the values <100 indexes 0-38
static const char *ALERTCODES[]={NULL,"other","unknown","coverOpen",
				 "coverClosed","interlockOpen",
				 "interlockClosed","configurationChange",
				 "jammed","subunitMissing",
				 "subunitLifeAlmostOver","subunitLifeOver",
				 "subunitAlmostEmpty","subunitEmpty",
				 "subunitAlmostFull","subunitFull",
				 "subunitNearLimit","subunitAtLimit",
				 "subunitOpened","subunitClosed",
				 "subunitTurnedOn","subunitTurnedOff",
				 "subunitOffline","subunitPowerSaver",
				 "subunitWarmingUp","subunitAdded",
				 "subunitRemoved","subunitResourceAdded",
				 "subunitResourceRemoved",
				 "subunitRecoverableFailure",
				 "subunitUnrecoverableFailure",
				 "subunitRecoverableStorageError",
				 "subunitUnrecoverableStorageError",
				 "subunitMotorFailure",
				 "subunitMemoryExhausted",
				 "subunitUnderTemperature",
				 "subunitOverTemperature",
				 "subunitTimingFailure",
				 "subunitThermistorFailure",

// all the values in the 500's indexes 39-45
				 "doorOpen","doorClosed","powerUp","powerDown",
				 "printerNMSReset","printerManualReset",
				 "printerReadyToPrint",

// all the values in the 800's indexes 46-58
				 "inputMediaTrayMissing",
				 "inputMediaSizeChange",
				 "inputMediaWeightChange",
				 "inputMediaTypeChange",
				 "inputMediaColorChange",
				 "inputMediaFormPartsChange",
				 "inputMediaSupplyLow","inputMediaSupplyEmpty",
				 "inputMediaChangeRequest",
				 "inputManualInputRequest",
				 "inputTrayPositionFailure",
				 "inputTrayElevationFailure",
				 "inputCannotFeedSizeSelected",

// all the values in the 900's indexes 59-62
				 "outputMediaTrayMissing",
				 "outputMediaTrayAlmostFull",
				 "outputMediaTrayFull",
				 "outputMailboxSelectFailure",

// all the values in the 1000's indexes 63-67
				 "markerFuserUnderTemperature",
				 "markerFuserOverTemperature",
				 "markerFuserTimingFailure",
				 "markerFuserThermistorFailure",
				 "markerAdjustingPrintQuality",

// all the values in the 1100's indexes 68-82
				 "markerTonerEmpty",
				 "markerInkEmpty","markerPrintRibbonEmpty",
				 "markerTonerAlmostEmpty",
				 "markerInkAlmostEmpty",
				 "markerPrintRibbonAlmostEmpty",
				 "markerWasteTonerReceptacleAlmostFull",
				 "markerWasteInkReceptacleAlmostFull",
				 "markerWasteTonerReceptacleFull",
				 "markerWasteInkReceptacleFull",
				 "markerOpcLifeAlmostOver","markerOpcLifeOver",
				 "markerDeveloperAlmostEmpty",
				 "markerDeveloperEmpty",
				 "markerTonerCartridgeMissing",

// all the values in the 1300's indexes 83-85
				 "mediaPathMediaTrayMissing",
				 "mediaPathMediaTrayAlmostFull",
				 "mediaPathMediaTrayFull",

// all the values in the 1500's indexes 86-93
				 "interpreterMemoryIncrease",
				 "interpreterMemoryDecrease",
				 "interpreterCartridgeAdded",
				 "interpreterCartridgeDeleted",
				 "interpreterResourceAdded",
				 "interpreterResourceDeleted",
				 "interpreterResourceUnavailable",
				 "interpreterComplexPageEncountered",

// all the values in the 1800's indexes 94
				 "alertRemovalOfBinaryChangeEntry"};

const char *AlertTable::decode_code(){ 
/* the code is a sparse enumeration and instead of making a totally
   huge vector I made a more complicated function. */
  switch(code/100){
  case 0:
    assert(code>=1 && code<=38);
    return ALERTCODES[code];
  case 5:
    assert(code>=501 && code<=507);
    return ALERTCODES[code-500+38];
  case 8:
    assert(code>=801 && code<=813);
    return ALERTCODES[code-800+45];
  case 9:
    assert(code>=901 && code<=904);
    return ALERTCODES[code-900+58];
  case 10:
    assert(code>=1001 && code<1005);
    return ALERTCODES[code-1000+62];
  case 11:
    assert(code>=1101 && code<1115);
    return ALERTCODES[code-1100+67];
  case 13:
    assert(code>=1301 && code<1303);
    return ALERTCODES[code-1300+82];
  case 15:
    assert(code>=1501 && code<1509);
    return ALERTCODES[code-1500+85];
  case 18:
    assert(code==1801);
    return ALERTCODES[code-1800+93];
  default:
    assert(0); //bad value
  }
}

void do_printmib_get(SNMP_session &session, unsigned long *argflags){
  char buf[MAXSTR];
  /* ----- marker table -----------------------------------------------*/
  if(CK_MARKER_FLAGS){
    MarkerTable *markerinfo;
    unsigned int len;
    SNMP_table markerinforeq(session,sizeof(struct MarkerTable));
    if(CK_MARKER_FLAG || CK_PAGECOUNT_FLAG){
      markerinforeq.append(PRTMARKERLIFECOUNT_BASE,COUNTER_TAG,
			   (char*)&BMTID.lifecount-(char*)&BMTID);
      markerinforeq.append(PRTMARKERCOUNTERUNITS_BASE,INT_TAG,
			   (char*)&BMTID.counterunits-(char*)&BMTID);
    }
    if(CK_MARKER_FLAG || CK_COLORS_FLAG)
      markerinforeq.append(PRTMARKERPROCESSCOLORANTS_BASE,INT_TAG,
			   (char*)&BMTID.processcolorants-(char*)&BMTID);
    if(CK_MARKER_FLAG || CK_RESOLUTION_FLAG || CK_MINMARGIN_FLAG)
      markerinforeq.append(PRTMARKERADDRESSABILITYUNIT_BASE,INT_TAG,
			   (char*)&BMTID.addrunits-(char*)&BMTID);
    if(CK_MARKER_FLAG || CK_RESOLUTION_FLAG){
      markerinforeq.append(PRTMARKERADDRESSABILITYFEEDDIR_BASE,INT_TAG,
			   (char*)&BMTID.addrfeeddir-(char*)&BMTID);
      markerinforeq.append(PRTMARKERADDRESSABILITYXFEEDDIR_BASE,INT_TAG,
			   (char*)&BMTID.addrxfeeddir-(char*)&BMTID);
    }
    if(CK_MARKER_FLAG || CK_MINMARGIN_FLAG){
      markerinforeq.append(PRTMARKERNORTHMARGIN_BASE,INT_TAG,
			   (char*)&BMTID.northmargin-(char*)&BMTID);
      markerinforeq.append(PRTMARKERSOUTHMARGIN_BASE,INT_TAG,
			   (char*)&BMTID.southmargin-(char*)&BMTID);
      markerinforeq.append(PRTMARKEREASTMARGIN_BASE,INT_TAG,
			   (char*)&BMTID.eastmargin-(char*)&BMTID);
      markerinforeq.append(PRTMARKERWESTMARGIN_BASE,INT_TAG,
			   (char*)&BMTID.westmargin-(char*)&BMTID);
    }
    if(CK_MARKER_FLAG){
      markerinforeq.append(PRTMARKERMARKTECH_BASE,INT_TAG,
			   (char*)&BMTID.marktech-(char*)&BMTID);
      markerinforeq.append(PRTMARKERSTATUS_BASE,INT_TAG,
			   (char*)&BMTID.status-(char*)&BMTID);
    }
    try{
      assert(markerinfo=(MarkerTable*)markerinforeq.get(len));
    } catch (SNMP_error_unrecoverable &error){
      handle_unrecoverable(progname, session.Hostname(),error);
    }
    for(int i=0;i<len;i++){
      //check marktech
      if(CK_MARKER_FLAG)
	assert(markerinfo[i].marktech>0 && markerinfo[i].marktech<=27 &&
	       MARKTECH[markerinfo[i].marktech]!=NULL);

      //check couterunits
      if(CK_MARKER_FLAG || CK_PAGECOUNT_FLAG)
	assert(markerinfo[i].counterunits>0 && markerinfo[i].counterunits<=17
	       && MARKERCOUNTERUNIT[markerinfo[i].counterunits]!=NULL);
      //check addrunits
      if(CK_MARKER_FLAG || CK_RESOLUTION_FLAG || CK_MINMARGIN_FLAG)
	assert(markerinfo[i].addrunits>0 && markerinfo[i].addrunits<=4 &&
	       MEDIAUNIT[markerinfo[i].addrunits]);
      if(CK_MARKER_FLAG){
	snprintf(buf,MAXSTR,"markerTechnology=\"%s\";counterUnits=\"%s\";"
		 "lifeCount=\"%ld\";processColorants=\"%ld\";"
		 "addressabilityUnit=\"%s\";addressabilityFeedDir=\"%ld\";"
		 "addressabilityXFeedDir=\"%ld\";northMargin=\"%ld\";"
		 "southMargin=\"%ld\";eastMargin=\"%ld\";westMargin=\"%ld\";"
		 "status=\"%s\";\n",MARKTECH[markerinfo[i].marktech],
		 MARKERCOUNTERUNIT[markerinfo[i].counterunits],
		 markerinfo[i].lifecount,markerinfo[i].processcolorants,
		 MEDIAUNIT[markerinfo[i].addrunits],markerinfo[i].addrfeeddir,
		 markerinfo[i].addrxfeeddir,markerinfo[i].northmargin,
		 markerinfo[i].southmargin,markerinfo[i].eastmargin,
		 markerinfo[i].westmargin,decode_status(markerinfo[i].status));
	session.printstr(argflags,NEEDNL_LINE,buf);
      }
      if(CK_PAGECOUNT_FLAG){
	snprintf(buf,MAXSTR,"counterUnits=\"%s\";pagecount=\"%ld\";\n",
		 MARKERCOUNTERUNIT[markerinfo[i].counterunits],
		 markerinfo[i].lifecount);
	session.printstr(argflags,NEEDNL_ENTRY,buf);
      }
      if(CK_COLORS_FLAG){
	snprintf(buf,MAXSTR,"processColorants=\"%ld\";\n",markerinfo[i].processcolorants);
	session.printstr(argflags,NEEDNL_ENTRY,buf);
      }
      if(CK_RESOLUTION_FLAG){
	snprintf(buf,MAXSTR,"addressabilityUnit=\"%s\";"
		 "addressabilityFeedDir=\"%ld\";"
		 "addressabilityXFeedDir=\"%ld\";",
		 MEDIAUNIT[markerinfo[i].addrunits],markerinfo[i].addrfeeddir,
		 markerinfo[i].addrxfeeddir);
	session.printstr(argflags,NEEDNL_ENTRY,buf);
      }	
      if(CK_MINMARGIN_FLAG){
	if(CK_RESOLUTION_FLAG){
	  snprintf(buf,MAXSTR,"northMargin=\"%ld\";southMargin=\"%ld\";"
		   "eastMargin=\"%ld\";westMargin=\"%ld\";",
		   markerinfo[i].northmargin,markerinfo[i].southmargin,
		   markerinfo[i].eastmargin,markerinfo[i].westmargin);
	}else{
	  snprintf(buf,MAXSTR,"addressabilityUnit=\"%s\";northMargin=\"%ld\";"
		   "southMargin=\"%ld\";eastMargin=\"%ld\";westMargin=\"%ld\";"
		   ,MEDIAUNIT[markerinfo[i].addrunits],
		   markerinfo[i].northmargin,markerinfo[i].southmargin,
		   markerinfo[i].eastmargin,markerinfo[i].westmargin);
	}
	session.printstr(argflags,NEEDNL_ENTRY,buf);
      }
    }
  } // end of processing marker table

  /* ----- media path table -------------------------------------------*/
  if(CK_MEDIAPATH_FLAGS){
    MediaPathInfo *mpi;
    unsigned int len;
    SNMP_table mediapathreq(session,sizeof(MediaPathInfo));
    mediapathreq.append(PRTMEDIAPATHMAXSPEEDPRINTUNIT_BASE,INT_TAG,
			(char*)&BMPID.maxSpeedPrintUnit-(char*)&BMPID);
    mediapathreq.append(PRTMEDIAPATHMEDIASIZEUNIT_BASE,INT_TAG,
			(char*)&BMPID.mediaSizeUnit-(char*)&BMPID);
    mediapathreq.append(PRTMEDIAPATHMAXSPEED_BASE,INT_TAG,
			(char*)&BMPID.maxSpeed-(char*)&BMPID);
    mediapathreq.append(PRTMEDIAPATHMAXMEDIAFEEDDIR_BASE,INT_TAG,
			(char*)&BMPID.maxMediaFeedDir-(char*)&BMPID);
    mediapathreq.append(PRTMEDIAPATHMAXMEDIAXFEEDDIR_BASE,INT_TAG,
			(char*)&BMPID.maxMediaXFeedDir-(char*)&BMPID);
    mediapathreq.append(PRTMEDIAPATHMINMEDIAFEEDDIR_BASE,INT_TAG,
			(char*)&BMPID.minMediaFeedDir-(char*)&BMPID);
    mediapathreq.append(PRTMEDIAPATHMINMEDIAXFEEDDIR_BASE,INT_TAG,
			(char*)&BMPID.minMediaXFeedDir-(char*)&BMPID);
    mediapathreq.append(PRTMEDIAPATHTYPE_BASE,INT_TAG,
			(char*)&BMPID.type-(char*)&BMPID);
    mediapathreq.append(PRTMEDIAPATHSTATUS_BASE,INT_TAG,
			(char*)&BMPID.status-(char*)&BMPID);
    mediapathreq.append(PRTMEDIAPATHDESCRIPTION_BASE,STRING_TAG,
			(char*)&BMPID.description-(char*)&BMPID);
    try{
      assert(mpi=(MediaPathInfo*)mediapathreq.get(len));
    } catch (SNMP_error_unrecoverable &error){
      handle_unrecoverable(progname, session.Hostname(),error);
    }

    long maxSpeed=0;
    unsigned int maxSpeedIndex=0;
    long maxMediaFeedDir=0;
    long maxMediaXFeedDir=0;
    unsigned int maxMediaIndex=0;
    long minMediaFeedDir=LONG_MAX;
    long minMediaXFeedDir=LONG_MAX;
    unsigned int minMediaIndex=0;
    char duplex=0;
    for(unsigned int i=0;i<len;i++){
      /* this computes the maximum and the minumum paper size by area rather
	 than having one dimension be more important than the other. This 
	 should not cause a problem in most modern printers. 

	 It also assumes that the printer is doesn't have different units 
	 for 	different media paths. 

	 If either of these assumptions are found to be in error on any 
	 printer please let me know. */

      // check for undocumented units
      assert(mpi[i].mediaSizeUnit>=0 && mpi[i].mediaSizeUnit<=4 && 
	     MEDIAUNIT[mpi[i].mediaSizeUnit]!=NULL); 
      // check for undocumented speeds
      assert(mpi[i].maxSpeedPrintUnit>=0 && mpi[i].maxSpeedPrintUnit<=17 &&
	     MEDIASPEEDUNIT[mpi[i].maxSpeedPrintUnit]!=NULL);
      // check for undocumented media path types;
      assert(mpi[i].type<=5 && MEDIATYPE[mpi[i].type]!=NULL);
	
      if((float)mpi[i].maxMediaFeedDir*(float)mpi[i].maxMediaXFeedDir>
	 (float)maxMediaFeedDir*(float)maxMediaXFeedDir){
	maxMediaFeedDir=mpi[i].maxMediaFeedDir;
	maxMediaXFeedDir=mpi[i].maxMediaXFeedDir;
	maxMediaIndex=i;
      }
      if((float)mpi[i].minMediaFeedDir*(float)mpi[i].minMediaXFeedDir<
	 (float)minMediaFeedDir*(float)minMediaXFeedDir){
	minMediaFeedDir=mpi[i].minMediaFeedDir;
	minMediaXFeedDir=mpi[i].minMediaXFeedDir;
	minMediaIndex=i;
      }
      if(mpi[i].maxSpeed>maxSpeed){
	maxSpeed=mpi[i].maxSpeed;
	maxSpeedIndex=i;
      }
      if(mpi[i].type==3 || mpi[i].type==4)
	duplex=1;
      if(CK_MEDIAPATH_FLAG){
	char *tmp;
	snprintf(buf,MAXSTR,"maxSpeedPrintUnit=\"%s\";mediaSizeUnit=\"%s\";"
		 "maxSpeed=\"%ld\";maxMediaFeedDir=\"%ld\";"
		 "maxMediaXFeedDir=\"%ld\";minMediaFeedDir=\"%ld\";"
		 "minMediaXFeedDir=\"%ld\";type=\"%s\";description=\"%s\";"
		 "status=\"%s\";\n",
		 MEDIASPEEDUNIT[mpi[i].maxSpeedPrintUnit],
		 MEDIAUNIT[mpi[i].mediaSizeUnit],mpi[i].maxSpeed,
		 mpi[i].maxMediaFeedDir,mpi[i].maxMediaXFeedDir,
		 mpi[i].minMediaFeedDir,mpi[i].minMediaXFeedDir,
		 MEDIATYPE[mpi[i].type],mpi[i].description,
		 tmp=decode_status(mpi[i].status));
	session.printstr(argflags,NEEDNL_LINE,buf);
	delete tmp;
      }
    }
    /* the for loop above will have gathered the information from the all the
       media path table entries and now we just have to print them. */
    if(CK_DUPLEX_FLAG){
      snprintf(buf,MAXSTR,"duplex=\"%c\";",duplex==1?'Y':'N');
      session.printstr(argflags,NEEDNL_ENTRY,buf);
    }
    if(CK_MAXPAPERSIZE_FLAG){
      snprintf(buf,MAXSTR,"maxMediaUnit=\"%s\";maxMediaFeedDir=\"%ld\";"
	       "maxMediaXFeedDir=\"%d\";",
	       MEDIAUNIT[mpi[maxMediaIndex].mediaSizeUnit],
	       maxMediaFeedDir,maxMediaXFeedDir);
      session.printstr(argflags,NEEDNL_ENTRY,buf);
    }
    if(CK_MINPAPERSIZE_FLAG){
      snprintf(buf,MAXSTR,"minMediaUnit=\"%s\";minMediaFeedDir=\"%ld\";"
	       "minMediaXFeedDir=\"%d\";",
	       MEDIAUNIT[mpi[minMediaIndex].mediaSizeUnit],
	       minMediaFeedDir,minMediaXFeedDir);
      session.printstr(argflags,NEEDNL_ENTRY,buf);
    }
    if(CK_ENGINESPEED_FLAG){
      snprintf(buf,MAXSTR,"maxSpeedUnit=\"%s\";maxSpeed=\"%ld\";",
	     MEDIASPEEDUNIT[mpi[maxSpeedIndex].maxSpeedPrintUnit],maxSpeed);
      session.printstr(argflags,NEEDNL_ENTRY,buf);
    }
  } // ends the section processing the media path table

  /* ----- display table -------------------------------------------------*/
  if(CK_DISPLAY_FLAG){
    char **dispbuf;
    unsigned int len;
    SNMP_table dispbufreq(session,sizeof(char*));
    dispbufreq.append(PRTCONSOLEDISPLAYBUFFERTEXT_BASE,STRING_TAG,0);
    try{
      assert(dispbuf=(char**)dispbufreq.get(len));
    } catch (SNMP_error_unrecoverable &error){
      handle_unrecoverable(progname, session.Hostname(),error);
    }

    for(unsigned int i=0;i<len;i++){
      snprintf(buf,MAXSTR,"displayBufferText=\"%s\";\n",dispbuf[i]);
      session.printstr(argflags,NEEDNL_ENTRY,buf);
    }
  } // ends the section processint the display path

  /* ----- input tray table ----------------------------------------------*/
  if(CK_INPUTTRAY_FLAGS){
    struct InputTrayInfo *trayinfo;
    unsigned int len;
    SNMP_table trayinforeq(session,sizeof(struct InputTrayInfo));
    trayinforeq.append(PRTINPUTTYPE_BASE,INT_TAG,
		       (char*)&BITID.type-(char*)&BITID);
    trayinforeq.append(PRTINPUTDIMUNIT_BASE,INT_TAG,
		       (char*)&BITID.dimUnit-(char*)&BITID);
    trayinforeq.append(PRTINPUTMEDIADIMFEEDDIRCHOSEN_BASE,INT_TAG,
		       (char*)&BITID.dimFeedDir-(char*)&BITID);
    trayinforeq.append(PRTINPUTMEDIADIMXFEEDDIRCHOSEN_BASE,INT_TAG,
		       (char*)&BITID.dimXFeedDir-(char*)&BITID);
    trayinforeq.append(PRTINPUTCAPACITYUNIT_BASE,INT_TAG,
		       (char*)&BITID.capUnit-(char*)&BITID);
    trayinforeq.append(PRTINPUTMAXCAPACITY_BASE,INT_TAG,
		       (char*)&BITID.maxCap-(char*)&BITID);
    trayinforeq.append(PRTINPUTCURRENTLEVEL_BASE,INT_TAG,
		       (char*)&BITID.curLev-(char*)&BITID);
    trayinforeq.append(PRTINPUTINPUTSTATUS_BASE,INT_TAG,
		       (char*)&BITID.status-(char*)&BITID);
    trayinforeq.append(PRTINPUTMEDIANAME_BASE,STRING_TAG,
		       (char*)&BITID.mediaName-(char*)&BITID);
    trayinforeq.append(PRTINPUTNAME_BASE,STRING_TAG,
		       (char*)&BITID.name-(char*)&BITID);
    trayinforeq.append(PRTINPUTINPUTDESCRIPTION_BASE,STRING_TAG,
		       (char*)&BITID.desc-(char*)&BITID);
    try{
      assert(trayinfo=(InputTrayInfo*)trayinforeq.get(len));
    } catch (SNMP_error_unrecoverable &error){
      handle_unrecoverable(progname, session.Hostname(),error);
    }

    int letter=0;
    int legal=0;
    int tabloid=0;
    int executive=0;
    int a3=0;
    int a4=0;
    int b4=0;
    int b5=0;
    for(unsigned int i=0;i<len;i++){
      InputTrayInfo &ti=trayinfo[i];
      // check for undocumented input tray types.
      assert(ti.type>=0 && ti.type<=7 && 
	     INPUTTYPE[ti.type]!=NULL);
      // check for undocumented dimunits.
      assert(ti.dimUnit>=0 && ti.dimUnit<=4 &&
	     MEDIAUNIT[ti.dimUnit]!=NULL);
      // check for undocumented capacity types.
      assert(ti.capUnit>=0 && ti.capUnit<=17 &&
	     CAPACITYUNIT[ti.capUnit]!=NULL);

      if(CK_PAPERSIZE_FLAGS){
	long shortedge,longedge;
	if(ti.dimFeedDir<ti.dimXFeedDir){
	  shortedge=ti.dimFeedDir;
	  longedge=ti.dimXFeedDir;
	} else {
	  shortedge=ti.dimXFeedDir;
	  longedge=ti.dimFeedDir;
	}
	if(ti.curLev>=0){
	  if(ti.dimUnit==3){ // ten thousands of an inch
	    if(shortedge==LETTER_SHORT_IN && longedge==LETTER_LONG_IN) 
	      letter+=ti.curLev;
	    if(shortedge==LEGAL_SHORT_IN && longedge==LEGAL_LONG_IN) 
	      legal+=ti.curLev;
	    if(shortedge==TABLOID_SHORT_IN && longedge==TABLOID_LONG_IN) 
	      tabloid+=ti.curLev;
	    if(shortedge==EXECUTIVE_SHORT_IN && longedge==EXECUTIVE_LONG_IN) 
	      executive+=ti.curLev;
	    if(shortedge==A4_SHORT_IN && longedge==A4_LONG_IN) 
	      a4+=ti.curLev;
	    if(shortedge==A3_SHORT_IN && longedge==A3_LONG_IN) 
	      a4+=ti.curLev;
	    if(shortedge==B5_SHORT_IN && longedge==B5_LONG_IN) 
	      a4+=ti.curLev;
	    if(shortedge==B4_SHORT_IN && longedge==B4_LONG_IN) 
	      a4+=ti.curLev;
	  } else { /* micrometers
		      there are currently only two dimunits if this changes 
		      then we will need to change this code */
	    if(shortedge==LETTER_SHORT_M && longedge==LETTER_LONG_M) 
	      letter+=ti.curLev;
	    if(shortedge==LEGAL_SHORT_M && longedge==LEGAL_LONG_M) 
	      legal+=ti.curLev;
	    if(shortedge==TABLOID_SHORT_M && longedge==TABLOID_LONG_M) 
	      tabloid+=ti.curLev;
	    if(shortedge==EXECUTIVE_SHORT_M && longedge==EXECUTIVE_LONG_M) 
	      executive+=ti.curLev;
	    if(shortedge==A4_SHORT_M && longedge==A4_LONG_M) 
	      a4+=ti.curLev;
	    if(shortedge==A3_SHORT_M && longedge==A3_LONG_M) 
	      a4+=ti.curLev;
	    if(shortedge==B5_SHORT_M && longedge==B5_LONG_M) 
	      a4+=ti.curLev;
	    if(shortedge==B4_SHORT_M && longedge==B4_LONG_M) 
	      a4+=ti.curLev;
	  }
	} else {
	  fprintf(stderr,"Warning: Can't sense paper level.\n");
	}
      } // ends section counting pages of a size
      if(CK_INPUTTRAY_FLAG){
	char *tmp=decode_status(ti.status);
	snprintf(buf,MAXSTR,"type=\"%s\";dimUnit=\"%s\";dimFeedDir=\"%ld\";"
	       "dimXFeedDir=\"%ld\";capUnit=\"%s\";maxCap=\"%ld\";"
	       "curLevel=\"%ld\";mediaName=\"%s\";name=\"%s\";"
	       "description=\"%s\";status=\"%s\";\n",
	       INPUTTYPE[ti.type],MEDIAUNIT[ti.dimUnit],ti.dimFeedDir,
	       ti.dimXFeedDir,CAPACITYUNIT[ti.capUnit],ti.maxCap,
	       ti.curLev,ti.mediaName,ti.name,ti.desc,
	       tmp);
	session.printstr(argflags,NEEDNL_LINE,buf);
	delete tmp;
      }
    } // ends iterating through each one of the trays
    if(CK_LEGAL_FLAG){
      snprintf(buf,MAXSTR,"legal=\"%d\";",legal);      
      session.printstr(argflags,NEEDNL_ENTRY,buf);
    }
    if(CK_TABLOID_FLAG){
      snprintf(buf,MAXSTR,"tabloid=\"%d\";",tabloid);
      session.printstr(argflags,NEEDNL_ENTRY,buf);
    }
    if(CK_A4_FLAG){
      snprintf(buf,MAXSTR,"a4=\"%d\";",a4);
      session.printstr(argflags,NEEDNL_ENTRY,buf);
    }
    if(CK_B4_FLAG){
      snprintf(buf,MAXSTR,"b4=\"%d\";",b4);
      session.printstr(argflags,NEEDNL_ENTRY,buf);
    }
    if(CK_B5_FLAG){
      snprintf(buf,MAXSTR,"b5=\"%d\";",b5);
      session.printstr(argflags,NEEDNL_ENTRY,buf);
    }
    if(CK_LETTER_FLAG){
      snprintf(buf,MAXSTR,"letter=\"%d\";",letter);
      session.printstr(argflags,NEEDNL_ENTRY,buf);
    }
    if(CK_A3_FLAG){
      snprintf(buf,MAXSTR,"a3=\"%d\";",a3);
      session.printstr(argflags,NEEDNL_ENTRY,buf);
    }
    if(CK_EXECUTIVE_FLAG){
      snprintf(buf,MAXSTR,"executive=\"%d\";",executive);
      session.printstr(argflags,NEEDNL_ENTRY,buf);
    }
  } // ends the section processing input tray table

  /* ----- covers table ------------------------------------------------- */
  if(CK_COVER_FLAG){
    struct CoverTable *coverinfo;
    unsigned int len;
      
    SNMP_table coverinforeq(session,sizeof(struct CoverTable));
    coverinforeq.append(PRTCOVERDESCRIPTION_BASE,STRING_TAG,
			(char*)&BCTID.desc-(char*)&BCTID);
    coverinforeq.append(PRTCOVERSTATUS_BASE,INT_TAG,
			(char*)&BCTID.status-(char*)&BCTID);
    try{
      assert(coverinfo=(CoverTable*)coverinforeq.get(len));
    } catch (SNMP_error_unrecoverable &error){
      handle_unrecoverable(progname, session.Hostname(),error);
    }

    for(unsigned int i=0;i<len;i++){
      //make sure we didn't get something weird for a cover status
      assert(coverinfo[i].status>0 && coverinfo[i].status<=6 && 
	     COVERSTATUS[coverinfo[i].status]!=NULL);
      snprintf(buf,MAXSTR,"description=\"%s\";status=\"%s\";\n",
	       coverinfo[i].desc,COVERSTATUS[coverinfo[i].status]);
      session.printstr(argflags,NEEDNL_LINE,buf);
    }
  } // ends the section processing the cover table

  /* ----- Languages table ----------------------------------------------- */
  /* these two variables are put outside of the loop so that they do not go
     out of scope when the language table is finished being printed out that
     way they can be used when processing the protocol table */
  struct LangInfo *langinfo; 
  unsigned int langlen;

  if(CK_PROTOCOL_FLAGS || CK_LANGUAGES_FLAGS){
    SNMP_table langinforeq(session,sizeof(struct LangInfo));

    langinforeq.append(PRTINTERPRETERLANGFAMILY_BASE,INT_TAG,
		       (char*)&BLTID.family-(char*)&BLTID);
    if(CK_LANGUAGES_FLAG){
      langinforeq.append(PRTINTERPRETERLANGLEVEL_BASE,STRING_TAG,
			 (char*)&BLTID.langLevel-(char*)&BLTID);
      langinforeq.append(PRTINTERPRETERLANGVERSION_BASE,STRING_TAG,
			 (char*)&BLTID.langVersion-(char*)&BLTID);
      langinforeq.append(PRTINTERPRETERDESCRIPTION_BASE,STRING_TAG,
			 (char*)&BLTID.description-(char*)&BLTID);
      langinforeq.append(PRTINTERPRETERVERSION_BASE,STRING_TAG,
			 (char*)&BLTID.version-(char*)&BLTID);
      langinforeq.append(PRTINTERPRETERDEFAULTORIENTATION_BASE,INT_TAG,
			 (char*)&BLTID.orientation-(char*)&BLTID);
      langinforeq.append(PRTINTERPRETERFEEDADDRESSABILITY_BASE,INT_TAG,
			 (char*)&BLTID.feedAddressability-(char*)&BLTID);
      langinforeq.append(PRTINTERPRETERXFEEDADDRESSABILITY_BASE,INT_TAG,
			 (char*)&BLTID.xFeedAddressability-(char*)&BLTID);
      langinforeq.append(PRTINTERPRETERTWOWAY_BASE,INT_TAG,
			 (char*)&BLTID.twoWay-(char*)&BLTID);
    }
    try{
      assert(langinfo=(LangInfo*)langinforeq.get(langlen));
    } catch (SNMP_error_unrecoverable &error){
      handle_unrecoverable(progname, session.Hostname(),error);
    }

    char flags=0;
    for( int i=0; i<langlen;i++){
      switch(langinfo[i].family){
      case 3:
	flags|=PCL_C_FLAG;
	break;
      case 4:
	flags|=HPGL_C_FLAG;
	break;
      case 5:
	flags|=PJL_C_FLAG;
	break;
      case 6:
	flags|=PS_C_FLAG;
	break;
      case 42:
	flags|=PSPRINTER_C_FLAG;
	break;
      case 37:
	flags|=AUTOLANG_C_FLAG;
	break;
      } // pretty much ignore the rest.

      // toss out any unknown printer language families
      assert(langinfo[i].family>0 && langinfo[i].family<=47 && 
	     LANGUAGES[langinfo[i].family]!=NULL);

      if(CK_LANGUAGES_FLAG){
	// toss out any unknown orientations
	assert(langinfo[i].orientation>0 && langinfo[i].orientation<=4 &&
	       ORIENTATIONS[langinfo[i].orientation]!=NULL);
	// toss out undefined communication info
	assert(langinfo[i].twoWay==3 || langinfo[i].twoWay==4);
	  
	snprintf(buf,MAXSTR,"langFamily=\"%s\";langLevel=\"%s\";"
		 "langVersion=\"%s\";description=\"%s\";version=\"%s\";"
		 "orientation=\"%s\";feedAddressability=\"%ld\";"
		 "xFeedAddressability=\"%ld\";twoWay=\"%c\";\n",
		 LANGUAGES[langinfo[i].family],langinfo[i].langLevel,
		 langinfo[i].langVersion,langinfo[i].description,
		 langinfo[i].version,ORIENTATIONS[langinfo[i].orientation],
		 langinfo[i].feedAddressability,
		 langinfo[i].xFeedAddressability,
		 langinfo[i].twoWay==3?'Y':'N');
	session.printstr(argflags,NEEDNL_LINE,buf);
      }
    }  
    if(CK_POSTSCRIPT_FLAG){
      snprintf(buf,MAXSTR,"postscript=\"%c\";",flags&PS_C_FLAG?'Y':'N');
      session.printstr(argflags,NEEDNL_ENTRY,buf);
    }
    if(CK_PCL_FLAG){
      snprintf(buf,MAXSTR,"pcl=\"%c\";",flags&PCL_C_FLAG?'Y':'N');
      session.printstr(argflags,NEEDNL_ENTRY,buf);
    }
    if(CK_PJL_FLAG){
      snprintf(buf,MAXSTR,"pjl=\"%c\";",flags&PJL_C_FLAG?'Y':'N');
      session.printstr(argflags,NEEDNL_ENTRY,buf);
    }
    if(CK_HPGL_FLAG){
      snprintf(buf,MAXSTR,"hpgl=\"%c\";",flags&HPGL_C_FLAG?'Y':'N');
      session.printstr(argflags,NEEDNL_ENTRY,buf);
    }
    if(CK_PSPRINTER_FLAG){
      snprintf(buf,MAXSTR,"psprinter=\"%c\";",flags&PSPRINTER_C_FLAG?'Y':'N');
      session.printstr(argflags,NEEDNL_ENTRY,buf);
    }
    if(CK_AUTOLANG_FLAG){
      snprintf(buf,MAXSTR,"autolang=\"%c\";",flags&AUTOLANG_C_FLAG?'Y':'N');
      session.printstr(argflags,NEEDNL_ENTRY,buf);
    }
  } // ends the section proccessing the languages table
    
  /* ----- channel table ----------------------------------------------- */
  if(CK_PROTOCOL_FLAGS){
    struct ProtocolTable *protoinfo;
    unsigned int len;

    SNMP_table protoinforeq(session,sizeof(struct ProtocolTable));
    protoinforeq.append(PRTCHANNELTYPE_BASE,INT_TAG,
			(char*)&BPTID.type-(char*)&BPTID);
    if(CK_PROTOCOL_FLAG){
      protoinforeq.append(PRTCHANNELPROTOCOLVERSION_BASE,STRING_TAG,
			  (char*)&BPTID.version-(char*)&BPTID);
      protoinforeq.append(PRTCHANNELCURRENTJOBCNTLLANGINDEX_BASE,INT_TAG,
			  (char*)&BPTID.curjclidx-(char*)&BPTID);
      protoinforeq.append(PRTCHANNELDEFAULTPAGEDESCLANGINDEX_BASE,INT_TAG,
			  (char*)&BPTID.defpdlidx-(char*)&BPTID);
      protoinforeq.append(PRTCHANNELSTATE_BASE,INT_TAG,
			  (char*)&BPTID.state-(char*)&BPTID);
      protoinforeq.append(PRTCHANNELSTATUS_BASE,INT_TAG,
			  (char*)&BPTID.status-(char*)&BPTID);
    }
    try{
      assert(protoinfo=(ProtocolTable*)protoinforeq.get(len));
    } catch (SNMP_error_unrecoverable &error){
      handle_unrecoverable(progname, session.Hostname(),error);
    }

    char flags=0;
    for(int i=0;i<len;i++){
      switch(protoinfo[i].type){
      case 7: 
	flags|=APPLETALK_C_FLAG;
	break;
      case 8:
	flags|=LPD_C_FLAG;
	break;
      case 10:
	flags|=NETWARE_C_FLAG;
	break;
      case 11: // old depricated port 9100
      case 38: // new bidirectional tcp port
      case 12: // appsocket on tek's
	flags|=PORT9100_C_FLAG;
	break;
      }
      //kick out bad types.
      assert(protoinfo[i].type>0 && protoinfo[i].type<=43 && 
	     CHANNELTYPE[protoinfo[i].type]!=NULL);
      if(CK_PROTOCOL_FLAG){
	//kick out bad states
	assert(protoinfo[i].state>0 && protoinfo[i].state<=4 &&
	       CHANNELSTATE[protoinfo[i].state]!=NULL);
	//make sure the jcl index is valid we have already made sure that 
	//the type is valid above
	assert(protoinfo[i].curjclidx>0 && protoinfo[i].curjclidx<=langlen);
	//make sure the pdl index is valid
	assert(protoinfo[i].defpdlidx>0 && protoinfo[i].defpdlidx<=langlen);

	snprintf(buf,MAXSTR,"type=\"%s\";version=\"%s\";"
		 "currentJobControlLang=\"%s\";defaultPageDescLang=\"%s\";"
		 "state=\"%s\";status=\"%s\";\n",
		 CHANNELTYPE[protoinfo[i].type],protoinfo[i].version,
		 LANGUAGES[langinfo[protoinfo[i].curjclidx-1].family],
		 LANGUAGES[langinfo[protoinfo[i].defpdlidx-1].family],
		 CHANNELSTATE[protoinfo[i].state],
		 decode_status(protoinfo[i].status));
	session.printstr(argflags,NEEDNL_LINE,buf);
      }
    }

    if(CK_APPLETALK_FLAG){
      snprintf(buf,MAXSTR,"appletalk=\"%c\";",flags&APPLETALK_C_FLAG?'Y':'N');
      session.printstr(argflags,NEEDNL_ENTRY,buf);
    }
    if(CK_LPD_FLAG){
      snprintf(buf,MAXSTR,"lpd=\"%c\";",flags&LPD_C_FLAG?'Y':'N');
      session.printstr(argflags,NEEDNL_ENTRY,buf);
    }
    if(CK_NETWARE_FLAG){
      snprintf(buf,MAXSTR,"netware=\"%c\";",flags&NETWARE_C_FLAG?'Y':'N');
      session.printstr(argflags,NEEDNL_ENTRY,buf);
    }
    if(CK_PORT9100_FLAG){
      snprintf(buf,MAXSTR,"port9100=\"%c\";",flags&PORT9100_C_FLAG?'Y':'N');
      session.printstr(argflags,NEEDNL_ENTRY,buf);
    }

  } // ends the section processing the channel table
  /* ----- Marker Supplies table ------------------------------ */
  if(CK_SUPPLIES_FLAG){
    struct MarkerSuppliesTable *msupplyinfo;
    unsigned int len;

    SNMP_table msuppreq(session,sizeof(MarkerSuppliesTable));
    // msupreq.append(PRTMARKERSUPPLIESCOLORANTINDEX_BASE,INT_TAG,
    //		     (char*)&BMSTID.colorantidx-(char*)&BMSTID);
    msuppreq.append(PRTMARKERSUPPLIESCLASS_BASE,INT_TAG,
		    (char*)&BMSTID.msclass-(char*)&BMSTID);
    msuppreq.append(PRTMARKERSUPPLIESTYPE_BASE,INT_TAG,
		    (char*)&BMSTID.type-(char*)&BMSTID);
    msuppreq.append(PRTMARKERSUPPLIESDESCRIPTION_BASE,STRING_TAG,
		    (char*)&BMSTID.desc-(char*)&BMSTID);
    msuppreq.append(PRTMARKERSUPPLIESSUPPLYUNIT_BASE,INT_TAG,
		    (char*)&BMSTID.supplyunit-(char*)&BMSTID);
    msuppreq.append(PRTMARKERSUPPLIESMAXCAPACITY_BASE,INT_TAG,
		    (char*)&BMSTID.maxcap-(char*)&BMSTID);
    msuppreq.append(PRTMARKERSUPPLIESLEVEL_BASE,INT_TAG,
		    (char*)&BMSTID.level-(char*)&BMSTID);
    try{
      assert(msupplyinfo=(MarkerSuppliesTable*)msuppreq.get(len));
    } catch (SNMP_error_unrecoverable &error){
      handle_unrecoverable(progname, session.Hostname(),error);
    }

    for(int i=0;i<len;i++){
      //really should make sure colorant is actually used
      assert(msupplyinfo[i].msclass>0 && msupplyinfo[i].msclass<=4 &&
	     MARKERSUPPLIESCLASS[msupplyinfo[i].msclass]!=NULL);
      if(!(msupplyinfo[i].type>0 && msupplyinfo[i].type<=22 &&
	   MARKERSUPPLIESTYPE[msupplyinfo[i].type]!=NULL)){
	// Seems apropriate to print out type number as type
	fprintf(stderr,"Warning: markerSupplyType=%d out of bounds.\n",
		msupplyinfo[i].type);
	snprintf(buf,MAXSTR,"type=\"%d\";",msupplyinfo[i].type);
	session.printstr(argflags,NEEDNL_ENTRY,buf);
      }else{
	snprintf(buf,MAXSTR,"type=\"%s\";",
		 MARKERSUPPLIESTYPE[msupplyinfo[i].type]);
	session.printstr(argflags,NEEDNL_ENTRY,buf);
      }
      if(!(msupplyinfo[i].supplyunit>0 && msupplyinfo[i].supplyunit<=17 &&
	   MARKERSUPPLIESSUPPLYUNIT[msupplyinfo[i].supplyunit]))
	// Skipping the unit seems like the best thing to do here
	fprintf(stderr,"Warning: markerSupplyUnit=%d out of bounds.\n",
		msupplyinfo[i].supplyunit);
      else{
        snprintf(buf,MAXSTR,"supplyunit=\"%s\";",
		 MARKERSUPPLIESSUPPLYUNIT[msupplyinfo[i].supplyunit]);
	session.printstr(argflags,NEEDNL_ENTRY,buf);
      }
      snprintf(buf,MAXSTR,"class=\"%s\";desc=\"%s\";maxcap=\"%ld\";"
	       "level=\"%ld\";\n",
	       MARKERSUPPLIESCLASS[msupplyinfo[i].msclass],msupplyinfo[i].desc,
	       msupplyinfo[i].maxcap,msupplyinfo[i].level);
      session.printstr(argflags,NEEDNL_LINE,buf);

    }
  } // end processing supplies table
  
  /* ----- Alerts table --------------------------------------- */
  if(CK_ALERTS_FLAG){
    struct AlertTable *alertinfo;
    unsigned int len;

    SNMP_table alertreq(session,sizeof(AlertTable));
    alertreq.append(PRTALERTSEVERITYLEVEL_BASE,INT_TAG,
		    (char*)&BATID.severityLevel-(char*)&BATID);
    alertreq.append(PTRALERTTRAININGLEVEL_BASE,INT_TAG,
		    (char*)&BATID.trainingLevel-(char*)&BATID);
    alertreq.append(PRTALERTGROUP_BASE,INT_TAG,
		    (char*)&BATID.group-(char*)&BATID);
    alertreq.append(PRTALERTGROUPINDEX_BASE,INT_TAG,
		    (char*)&BATID.groupIndex-(char*)&BATID);
    alertreq.append(PRTALERTLOCATION_BASE,INT_TAG,
		    (char*)&BATID.location-(char*)&BATID);
    alertreq.append(PRTALERTCODE_BASE,INT_TAG,
		    (char*)&BATID.code-(char*)&BATID);
    alertreq.append(PRTALERTDESCRIPTION_BASE,STRING_TAG,
		    (char*)&BATID.desc-(char*)&BATID);
    alertreq.append(PRTALERTTIME_BASE,TIME_TICK_TAG,
		    (char*)&BATID.time-(char*)&BATID);
    try{
      alertinfo=(AlertTable*)alertreq.get(len);
      assert(alertinfo);
    }catch(SNMP_error_unrecoverable &error){
      handle_unrecoverable(progname, session.Hostname(),error);
    }catch(SNMP_error_oid &error){ 
      /* This is a workaround for broken HP firmware. Instead of 
	 returning timeticks like they are supposed to do. They 
	 return a time in the form of a string. */
      fprintf(stderr,"Trying a work around for broken HP firmware.\n");
      SNMP_table alertreq2(session,sizeof(AlertTable));
      alertreq2.append(PRTALERTSEVERITYLEVEL_BASE,INT_TAG,
		      (char*)&BATID.severityLevel-(char*)&BATID);
      alertreq2.append(PTRALERTTRAININGLEVEL_BASE,INT_TAG,
		      (char*)&BATID.trainingLevel-(char*)&BATID);
      alertreq2.append(PRTALERTGROUP_BASE,INT_TAG,
		      (char*)&BATID.group-(char*)&BATID);
      alertreq2.append(PRTALERTGROUPINDEX_BASE,INT_TAG,
		      (char*)&BATID.groupIndex-(char*)&BATID);
      alertreq2.append(PRTALERTLOCATION_BASE,INT_TAG,
		      (char*)&BATID.location-(char*)&BATID);
      alertreq2.append(PRTALERTCODE_BASE,INT_TAG,
		      (char*)&BATID.code-(char*)&BATID);
      alertreq2.append(PRTALERTDESCRIPTION_BASE,STRING_TAG,
		      (char*)&BATID.desc-(char*)&BATID);
      alertreq2.append(PRTALERTTIME_BASE,INT_TAG,
		      (char*)&BATID.time-(char*)&BATID);
      try{
	alertinfo=(AlertTable*)alertreq2.get(len);
	assert(alertinfo);
      }catch(SNMP_error_unrecoverable &error){
	handle_unrecoverable(progname, session.Hostname(),error);
      }catch(SNMP_error_oid &error){
	assert(0); // never should happen.
      }
    }

    unsigned long printertime;
    SNMP_structFiller timereq(session);
    timereq.append(SYSUPTIME,TIME_TICK_TAG,0);
    try{
      timereq.get(&printertime);
    }catch(SNMP_error_unrecoverable &error){
      handle_unrecoverable(progname, session.Hostname(),error);
    } 
    unsigned long systemtime=time(NULL);

    for(int i=0;i<len;i++){
      int bufpos;
      if(alertinfo[i].severityLevel>0 && alertinfo[i].severityLevel<=4 
	   && PRTALERTSEVERITYLEVEL[alertinfo[i].severityLevel]!=NULL){
	bufpos=snprintf(buf,MAXSTR,"severityLevel=\"%s\";",
			PRTALERTSEVERITYLEVEL[alertinfo[i].severityLevel]);
      }else{
	fprintf(stderr,"Warning: invalid severity level. Buggy firmware?\n");
	bufpos=snprintf(buf,MAXSTR,"severityLevel=\"%d\";",
			alertinfo[i].severityLevel);
      }
      assert(alertinfo[i].trainingLevel>0 && alertinfo[i].trainingLevel<=6 &&
	     PRTALERTTRAININGLEVEL[alertinfo[i].trainingLevel]!=NULL);
      assert(alertinfo[i].group>0 && alertinfo[i].group<=17 && 
	     PRTALERTGROUP[alertinfo[i].group]!=NULL);
      /* although the code is an enumeration -- it has a decode 
	 function which will catch any cases where it fails to 
	 reference anything valid in the vector. */
      snprintf(buf+bufpos,MAXSTR-bufpos,"trainingLevel=\"%s\";"
	       "group=\"%s\";groupIndex=\"%ld\";location=\"%ld\";code=\"%s\";"
	       "description=\"%s\";time=\"%lu\";\n",
	       PRTALERTTRAININGLEVEL[alertinfo[i].trainingLevel],
	       PRTALERTGROUP[alertinfo[i].group],
	       alertinfo[i].groupIndex,alertinfo[i].location,
	       alertinfo[i].decode_code(),alertinfo[i].desc,
	       (printertime-alertinfo[i].time)/100+systemtime);
      session.printstr(argflags,NEEDNL_LINE,buf);
    }
  } // end processing alert table
}

void do_printmib_set(SNMP_session &session, unsigned long *argflags){
   OidSeq hpprivsets;
  if(CK_REBOOT_FLAG)
    hpprivsets.append(PRTGENERALRESET,INT_TAG,4);
  OidSeq *response=session.set(&hpprivsets);
}


syntax highlighted by Code2HTML, v. 0.9.1