_MONITORING DISTRIBUTED PRITNERS UNDER NOVELL NETWARE_ by V. James Krammes [LISTING ONE] #include extern char far *screen; void CursorOff() { union REGS regs; regs.h.ah = 1; regs.h.ch = 0x20; regs.h.cl = 0; int86(0x10,®s,®s); } void CursorOn() { union REGS regs; regs.h.ah = 1; regs.h.ch = 11; regs.h.cl = 12; int86(0x10,®s,®s); } void CursorAt(r,c) unsigned char r,c; { union REGS regs; regs.h.ah = 02; regs.h.bh = 0; regs.h.dh = r; regs.h.dl = c; int86(0x10,®s,®s); } void _cls(attr) unsigned char attr; { union REGS regs; regs.h.ah = 0x06; /* scroll window up */ regs.h.al = 0; /* clear entire window */ regs.h.bh = attr; regs.x.cx = 0; /* upper left = (0,0) */ regs.h.dh = 23; regs.h.dl = 79; int86(0x10,®s,®s); } void clearline(row,attr) unsigned char row,attr; { union REGS regs; regs.h.ah = 0x06; /* scroll window up */ regs.h.al = 1; /* clear 1 line */ regs.h.bh = attr; regs.h.ch = row; /* upper left = (row,0) */ regs.h.cl = 0; regs.h.dh = row; /* lower right = (row,79) */ regs.h.dl = 79; int86(0x10,®s,®s); } void PutStrNoAttr(row,col,str,len) unsigned char row,col; int len; char *str; { register int offset = (row * 160) + (col << 1); while (len--) { *(screen + offset) = *str++; offset += 2; } } void putattr(row,col,attr,cnt) unsigned char row,col,attr; int cnt; { register int offset = (row * 160) + (col << 1) + 1; while (cnt--) { *(screen + offset) = attr; offset += 2; } } [LISTING TWO] void CursorOff(void); void CursorOn(void); void CursorAt(unsigned char,unsigned char); void _cls(unsigned char); void clearline(unsigned char,unsigned char); void PutStrNoAttr(unsigned char,unsigned char,char *,int); void putattr(unsigned char,unsigned char,unsigned char,int); [LISTING THREE] /* PMON.H - header file for PMON: printer monitor. */ /** define structures **/ typedef struct _Printer { BYTE Printer; int Status; BYTE Problem; BYTE HasJob; WORD Copies; WORD CopiesDone; long JobSize; long BytesDone; float PercentDone; struct _Printer *next; } Printer; typedef struct _PrintServer { WORD ConnectionID; char Name[48]; WORD SPXConnection; int Error; Printer *Printers; } PrintServer; [LISTING FOUR] #include #include #include #include #include #include #include "pmon.h" #include "intrface.h" char ConfigFileName[128]; FILE *ConfigFile; unsigned DelayValue = 500; PrintServer PS[8]; Printer *P; char far *screen; void OpenConfigFile(void) { ConfigFile = fopen(ConfigFileName,"r"); if (!ConfigFile) { printf("Unable to open configuration file \"%s\"\n",ConfigFileName); exit(1); } } void strrep(char *s,char c1,char c2) { while (*s) { if (*s == c1) *s = c2; s++; } } void AddPrinterToServer(int psnum,BYTE prnum) { register Printer *p = PS[psnum].Printers; if (!p) { PS[psnum].Printers = calloc(1,sizeof(Printer)); PS[psnum].Printers->Printer = prnum; } else { while (p->next) p = p->next; p->next = calloc(1,sizeof(Printer)); p = p->next; p->Printer = prnum; } } void BuildServerList(void) { char buf[256]; char *ptr; int status; WORD ConnectionID; fgets(buf,255,ConfigFile); while (strlen(buf)) { strrep(buf,'\n',0); if (buf[0] != ';' && strlen(buf)) { ptr = strtok(buf,"/"); if (!ptr || strlen(ptr) > 47) { printf("Error: expected /\n"); printf(" found \"%s\"\n",buf); exit(1); } status = GetConnectionID(ptr,&ConnectionID); if (status) { printf("Error: You are not logged in to server \"%s\"\n",ptr); exit(1); } if (!PS[ConnectionID-1].ConnectionID) { PS[ConnectionID-1].ConnectionID = ConnectionID; strcpy(PS[ConnectionID-1].Name,ptr); } ptr = strtok(NULL," \n\t;"); if (!ptr || !isdigit(*ptr)) { printf("Error: expected /\n"); printf(" found \"%s\"\n",buf); exit(1); } AddPrinterToServer(ConnectionID-1,atoi(ptr)); } fgets(buf,255,ConfigFile); } } void Initialize() { register int i; printf("PMON 1.00 - (C) 1991 The Midland Mutual Life Insurance Company\n\n"); screen = (char far *) MK_FP(0xB800,0x0000); for (i=0; i < 8; i++) memset((char *) &PS[i],0,sizeof(PrintServer)); OpenConfigFile(); BuildServerList(); fclose(ConfigFile); } void ScreenSetup(void) { static char *title = "(C) 1991 The Midland Mutual Life Insurance Company"; static char *header = " Server /P# Status #Copies Size of 1 Done So Far Percent"; static char *footer = "Press any Key to Exit"; _cls(0x1F); PutStrNoAttr(0,(80-strlen(title)) >> 1,title,strlen(title)); PutStrNoAttr(2,6,header,strlen(header)); PutStrNoAttr(23,(80-strlen(footer)) >> 1,footer,strlen(footer)); } void LoginToServer(int i) { register int status; BYTE CAL; if (PS[i].ConnectionID) { SetPreferredConnectionID(PS[i].ConnectionID); status = PSAttachToPrintServer(PS[i].Name,&PS[i].SPXConnection); if (status) PS[i].Error = status; else { status = PSLoginToPrintServer(PS[i].SPXConnection,&CAL); if (status) PS[i].Error = status; } } } void DetachFromServer(int i) { if (PS[i].ConnectionID) PSDetachFromPrintServer(PS[i].SPXConnection); } void GetPrinterInformation(WORD spxid,Printer *p) { char sdummy[128]; BYTE dummy; WORD wdummy; register int status; status = PSGetPrinterStatus(spxid,p->Printer,&dummy,&(p->Problem), &(p->HasJob),&dummy,&wdummy,sdummy,sdummy); p->Status = status; if (p->HasJob) { PSGetPrintJobStatus(spxid,p->Printer,sdummy,sdummy, &wdummy,sdummy,&(p->Copies),&(p->JobSize), &(p->CopiesDone),&(p->BytesDone),&wdummy, &dummy); if (p->JobSize == 0.0 || p->BytesDone == 0.0) p->PercentDone = 0.0; else p->PercentDone = (float) (p->BytesDone) / (float) (p->JobSize) * 100.0; } } char *TroubleDescription(BYTE code) { static char *Desc[] = { " OK ", " JAMMED ", "No Paper" }; if (code == 1) return Desc[1]; else if (code == 2) return Desc[2]; else return Desc[0]; } char *CommaString(long num) { static char buf2[15]; char buf1[15]; register int p1,p2; int positions = 0; memset(buf1,0,15); memset(buf2,0,15); sprintf(buf1,"%ld",num); p1 = strlen(buf1); p2 = (p1 > 9) ? p1 + 3 : (p1 > 6) ? p1 + 2 : (p1 > 3) ? p1 + 1 : p1; p1--; p2--; while (p1 >= 0) { buf2[p2--] = buf1[p1--]; if (++positions % 3 == 0) buf2[p2--] = ','; } return buf2; } void DisplayPrinterInformation(PrintServer *ps,Printer *p,int row) { char buf[80],s1[15],s2[15]; if (row <= 21) { if (ps->Error) sprintf(buf,"%-10s/%02d Error #%d",ps->Name, p->Printer,ps->Error); else if (p->Status) sprintf(buf,"%-10s/%02d Error #%d",ps->Name, p->Printer,p->Status); else if (!p->HasJob) sprintf(buf,"%-10s/%02d %-8s",ps->Name,p->Printer, TroubleDescription(p->Problem)); else { strcpy(s1,CommaString(p->JobSize)); strcpy(s2,CommaString(p->BytesDone)); sprintf(buf,"%-10s/%02d %-8s %02d/%02d %11s %11s %5.2f", ps->Name,p->Printer,TroubleDescription(p->Problem), p->CopiesDone,p->Copies,s1,s2,p->PercentDone); } clearline(row,0x1f); PutStrNoAttr(row,6,buf,strlen(buf)); if (p->Problem == 1) putattr(row,0,0x9C,80); else if (p->Problem == 2) putattr(row,00,0x9E,80); } } void MainLoop(void) { register Printer *p; register int i; int CurrentRow = 4; for (i=0; i<8; i++) if (PS[i].ConnectionID) { LoginToServer(i); p = PS[i].Printers; while (p) { GetPrinterInformation(PS[i].SPXConnection,p); DisplayPrinterInformation(&PS[i],p,CurrentRow++); p = p->next; } DetachFromServer(i); } } main(int argc,char *argv[]) { if (argc == 1) strcpy(ConfigFileName,"PMON.CFG"); else if (argc == 2) strcpy(ConfigFileName,argv[1]); else { printf("Usage - PMON []\n"); exit(1); } Initialize(); CursorOff(); ScreenSetup(); while (!kbhit()) { MainLoop(); delay(DelayValue); } CursorOn(); if (!getch()) getch(); CursorAt(24,0); return 0; }