#ifdef public_domain_notice Copyright (c) 1996 David P. Murphy for Datametrics Systems Corporation --- please send all comments and bug reports to murphy@connor.datametrics.com Permission is granted to any individual or institution to use, copy, or redistribute this software so long as all of the original files are included, that it is not sold for profit, and that this copyright notice is retained. Use at your own risk. Neither Murphy nor Datametrics assumes responsibility. Do not taunt Happy Fun Ball. #endif /* display the current status & statistics of the process and system */ #include "dscstd.h" #include #include #include #include #include #include #include #include /* macros specific to this module */ #define MAXSIZE_ACCOUNT 8 #define MAXSIZE_DEVICELOCKNAME 64 #define MAXSIZE_DEVICENAME 64 #define MAXSIZE_FULLNODENAME 15 #define MAXSIZE_HWNAME 31 #define MAXSIZE_IDENTIFIER (1 + 31 + 1 + 31 + 1) #define MAXSIZE_LOCKNAME 31 #define MAXSIZE_NODENAME 6 #define MAXSIZE_PROCESSNAME 15 #define MAXSIZE_QUEUENAME 31 #define MAXSIZE_SYSTEMVERSION 8 #define MAXSIZE_TERMINAL 8 #define MAXSIZE_USERNAME 12 #define MAXSIZE_VOLUMENAME 12 #ifndef JPI$_NODENAME # define JPI$_NODENAME 809 /* Name of node on which process is running */ #endif #define NODENAME_RETLEN 0 /* system */ #define TERMINAL_RETLEN 0 /* process */ #define VERSION_RETLEN 1 /* system */ #define USERNAME_RETLEN 1 /* process */ #define SWTYPE_RETLEN 2 /* system */ #define PROCESSNAME_RETLEN 2 /* process */ #define HWNAME_RETLEN 3 /* system */ #define ACCOUNT_RETLEN 3 /* process */ #define IMAGESPEC_RETLEN 4 /* process */ #define NUMBER_OF_RETLEN 5 #define COMMONSIZE 31 #define FILENAMESIZE 255 #define BIGSIZE 512 #define DEBUGON(foo) /* internal data structures */ typedef struct PROCESS_DATA { long pid; long owner; long cpuTime; long mode; long group; long member; long uic; long state; long prib; long prio; long dfwscnt; long wsquota; long wsextent; long wssize; long wspeak; long ppgcnt; long gpgcnt; long pageflts; long astcount; long astlimit; long biocount; long biolimit; long bytcount; long bytlimit; long diocount; long diolimit; long enqcount; long enqlimit; long filcount; long fillimit; long pgflcount; long pgfllimit; long prccount; long prclimit; long tmqcount; long tmqlimit; long efmask; long eflag[2]; long loginTime[2]; unsigned long curpriv[2]; unsigned long defpriv[2]; unsigned long authpriv[2]; unsigned long exepriv[2]; char processType; char nodename[MAXSIZE_FULLNODENAME + 1]; char account[MAXSIZE_ACCOUNT + 1]; char username[MAXSIZE_USERNAME + 1]; char process[MAXSIZE_PROCESSNAME + 1]; char terminal[MAXSIZE_TERMINAL + 1]; char theCpuTime[32]; char theLoginTime[32]; char imageSpec[FILENAMESIZE]; char defaultDir[FILENAMESIZE]; } ProcessData; typedef struct SYSTEM_DATA { unsigned long totpf; unsigned long freepf; unsigned long totsf; unsigned long freesf; unsigned long freegp; unsigned long freegs; unsigned long booted[2]; unsigned short hwmodel; char nodename[MAXSIZE_FULLNODENAME + 1]; char version[MAXSIZE_SYSTEMVERSION + 1]; char swtype[4+1]; char hwname[MAXSIZE_HWNAME+1]; } SystemData; /* operating-system function declarations */ #ifdef __ALPHA #define lib$mult_delta_time LIB$MULT_DELTA_TIME #define lib$signal LIB$SIGNAL #define sys$asctim SYS$ASCTIM #define sys$getjpiw SYS$GETJPIW #define sys$getsyiw SYS$GETSYIW #define sys$numtim SYS$NUMTIM #define sys$setddir SYS$SETDDIR #endif #include /* prototypes for the SYS$xxxxx() functions */ #include /* " " " LIB$xxxxx() " */ extern CONDVAL sys$setddir(); /* external function declarations */ /* internal function declarations */ /* external data declarations */ /* internal data declarations */ LOCALDATA long TheMagicFactor = 100000; LOCALDATA unsigned short retlen[NUMBER_OF_RETLEN]; LOCALDATA SystemData sz; LOCALDATA ProcessData pz; LOCALDATA ItemList TheSList[] = { sizeof(sz.booted), SYI$_BOOTTIME, &sz.booted[0], NULL, sizeof(sz.totpf), SYI$_PAGEFILE_PAGE, &sz.totpf, NULL, sizeof(sz.freepf), SYI$_PAGEFILE_FREE, &sz.freepf, NULL, sizeof(sz.totsf), SYI$_SWAPFILE_PAGE, &sz.totsf, NULL, sizeof(sz.freesf), SYI$_SWAPFILE_FREE, &sz.freesf, NULL, sizeof(sz.freegp), SYI$_FREE_GBLPAGES, &sz.freegp, NULL, sizeof(sz.freegs), SYI$_FREE_GBLSECTS, &sz.freegs, NULL, sizeof(sz.hwmodel), SYI$_HW_MODEL, &sz.hwmodel, NULL, sizeof(sz.nodename)-1, SYI$_NODENAME, sz.nodename, &retlen[NODENAME_RETLEN], sizeof(sz.version)-1, SYI$_VERSION, sz.version, &retlen[ VERSION_RETLEN], sizeof(sz.swtype)-1, SYI$_NODE_SWTYPE, sz.swtype, &retlen[ SWTYPE_RETLEN], sizeof(sz.hwname)-1, SYI$_HW_NAME, sz.hwname, &retlen[ HWNAME_RETLEN], 0, SYI$C_LISTEND, NULL, NULL }; LOCALDATA ItemList ThePList[] = { sizeof(pz.terminal)-1, JPI$_TERMINAL, pz.terminal, &retlen[ TERMINAL_RETLEN], sizeof(pz.username)-1, JPI$_USERNAME, pz.username, &retlen[ USERNAME_RETLEN], sizeof(pz.nodename)-1, JPI$_NODENAME, pz.nodename, &retlen[ NODENAME_RETLEN], sizeof(pz.process)-1, JPI$_PRCNAM, pz.process, &retlen[PROCESSNAME_RETLEN], sizeof(pz.account)-1, JPI$_ACCOUNT, pz.account, &retlen[ ACCOUNT_RETLEN], sizeof(pz.imageSpec)-1, JPI$_IMAGNAME, pz.imageSpec, &retlen[ IMAGESPEC_RETLEN], sizeof(pz.state), JPI$_STATE, &pz.state, NULL, sizeof(pz.pid), JPI$_PID, &pz.pid, NULL, sizeof(pz.mode), JPI$_MODE, &pz.mode, NULL, sizeof(pz.group), JPI$_GRP, &pz.group, NULL, sizeof(pz.member), JPI$_MEM, &pz.member, NULL, sizeof(pz.prio), JPI$_PRI, &pz.prio, NULL, sizeof(pz.prib), JPI$_PRIB, &pz.prib, NULL, sizeof(pz.owner), JPI$_OWNER, &pz.owner, NULL, sizeof(pz.efmask), JPI$_EFWM, &pz.efmask, NULL, sizeof(pz.eflag[0]), JPI$_EFCS, &pz.eflag[0], NULL, sizeof(pz.eflag[1]), JPI$_EFCU, &pz.eflag[1], NULL, sizeof(pz.cpuTime), JPI$_CPUTIM, &pz.cpuTime, NULL, sizeof(pz.loginTime), JPI$_LOGINTIM, pz.loginTime, NULL, sizeof(pz.wsextent), JPI$_WSEXTENT, &pz.wsextent, NULL, sizeof(pz.wsquota), JPI$_WSQUOTA, &pz.wsquota, NULL, sizeof(pz.dfwscnt), JPI$_DFWSCNT, &pz.dfwscnt, NULL, sizeof(pz.wssize), JPI$_WSSIZE, &pz.wssize, NULL, sizeof(pz.wspeak), JPI$_WSPEAK, &pz.wspeak, NULL, sizeof(pz.ppgcnt), JPI$_PPGCNT, &pz.ppgcnt, NULL, sizeof(pz.gpgcnt), JPI$_GPGCNT, &pz.gpgcnt, NULL, sizeof(pz.pageflts), JPI$_PAGEFLTS, &pz.pageflts, NULL, sizeof(pz.astcount), JPI$_ASTCNT, &pz.astcount, NULL, sizeof(pz.astlimit), JPI$_ASTLM, &pz.astlimit, NULL, sizeof(pz.biocount), JPI$_BIOCNT, &pz.biocount, NULL, sizeof(pz.biolimit), JPI$_BIOLM, &pz.biolimit, NULL, sizeof(pz.bytcount), JPI$_BYTCNT, &pz.bytcount, NULL, sizeof(pz.bytlimit), JPI$_BYTLM, &pz.bytlimit, NULL, sizeof(pz.diocount), JPI$_DIOCNT, &pz.diocount, NULL, sizeof(pz.diolimit), JPI$_DIOLM, &pz.diolimit, NULL, sizeof(pz.enqcount), JPI$_ENQCNT, &pz.enqcount, NULL, sizeof(pz.enqlimit), JPI$_ENQLM, &pz.enqlimit, NULL, sizeof(pz.filcount), JPI$_FILCNT, &pz.filcount, NULL, sizeof(pz.fillimit), JPI$_FILLM, &pz.fillimit, NULL, sizeof(pz.pgflcount), JPI$_PAGFILCNT, &pz.pgflcount, NULL, sizeof(pz.pgfllimit), JPI$_PGFLQUOTA, &pz.pgfllimit, NULL, sizeof(pz.prccount), JPI$_PRCCNT, &pz.prccount, NULL, sizeof(pz.prclimit), JPI$_PRCLM, &pz.prclimit, NULL, sizeof(pz.tmqcount), JPI$_TQCNT, &pz.tmqcount, NULL, sizeof(pz.tmqlimit), JPI$_TQLM, &pz.tmqlimit, NULL, sizeof(pz.curpriv), JPI$_CURPRIV, &pz.curpriv, NULL, sizeof(pz.defpriv), JPI$_PROCPRIV, &pz.defpriv, NULL, sizeof(pz.authpriv), JPI$_AUTHPRIV, &pz.authpriv, NULL, sizeof(pz.exepriv), JPI$_IMAGPRIV, &pz.exepriv, NULL, 0, JPI$C_LISTEND, NULL, NULL }; LOCALDATA char *ThePrivileges[] = { "CMKRNL", "CMEXEC", "SYSNAM", "GRPNAM", "ALLSPOOL", "DETACH", "DIAGNOSE", "LOG_IO", "GROUP", "NOACNT", "PRMCEB", "PRMMBX", "PSWAPM", "ALTPRI", "SETPRV", "TMPMBX", "WORLD", "MOUNT", "OPER", "EXQUOTA", "NETMBX", "VOLPRO", "PHY_IO", "BUGCHK", "PRMGBL", "SYSGBL", "PFNMAP", "SHMEM", "SYSPRV", "BYPASS", "SYSLCK", "SHARE", "UPGRADE", "DOWNGRADE", "GRPPRV", "READALL", " ", " ", "SECURITY", NULL }; MEP__ PRIVATE void DSC_I_TrimAsciz( char *txtptr ) { char *endptr; endptr = txtptr + strlen(txtptr) - 1; while (endptr >= txtptr) { if (*endptr == '\0' || *endptr > ' ') { *(++endptr) = '\0'; break; } --endptr; } return; } MEP__ PRIVATE void DSC_I_ShowPrivileges( unsigned long privptr[], char *bufptr ) { int j; int k; char *endptr; unsigned long tmpmask; *bufptr = '\0'; j = 0; k = 0; tmpmask = privptr[0]; while (ThePrivileges[j] != NULL) { if (tmpmask & (1 << k)) { if (ThePrivileges[j][0] > ' ') { strcat(bufptr, ThePrivileges[j]); strcat(bufptr, ","); } } if (j == 31) { k = -1; tmpmask = privptr[1]; } ++j; ++k; } endptr = bufptr + strlen(bufptr) - 1; if (*endptr == ',') *endptr = '\0'; return; } MEP__ PUBLIC void DSC_ShowProcessData( void *dummy1, FILE *fp, void *dummy2 ) { int n; CONDVAL cv0; unsigned short ddlen; unsigned long elapsedTime[2]; char *tmpptr; IOStatusBlock iosb; DeltaTimeBuf timbuf; struct dsc$descriptor_s temp_sd; char timebuf[COMMONSIZE]; char tmpitembuf[132]; char directory[FILENAMESIZE]; char prvbuf[BIGSIZE]; char outbuf[BIGSIZE * 2]; #ifdef sample_output Process Information: Username = MURPHY Pid = 2020009d Processname = MURPHY Priority = 6/4 Account = R&D UIC = [000100,000012] Terminal = TXA4: Node = DUNCAN Login Time = 13-SEP 8:15:00 Cpu Time = 1:11:50.65 Main Image = $1$DKB0:[MURPHY.DSJ]SAMPLE.EXE;18 Default Dir = SYS$SYSDEVICE:[MURPHY.DSJ] Privileges = d31de18f fffffffc : CMKRNL,CMEXEC,SYSNAM,GRPNAM,LOG_IO,GROUP,ALTPRI,SETPRV,TMPMBX,WORLD,OPER,EXQUOTA,NETMBX,PRMGBL,SYSGBL,SYSPRV,SYSLCK,SHARE,GRPPRV,READALL,SECURITY (def) = d31de18f fffffffc : CMKRNL,CMEXEC,SYSNAM,GRPNAM,LOG_IO,GROUP,ALTPRI,SETPRV,TMPMBX,WORLD,OPER,EXQUOTA,NETMBX,PRMGBL,SYSGBL,SYSPRV,SYSLCK,SHARE,GRPPRV,READALL,SECURITY (auth) = d31de18f fffffffc : CMKRNL,CMEXEC,SYSNAM,GRPNAM,LOG_IO,GROUP,ALTPRI,SETPRV,TMPMBX,WORLD,OPER,EXQUOTA,NETMBX,PRMGBL,SYSGBL,SYSPRV,SYSLCK,SHARE,GRPPRV,READALL,SECURITY (image) = 00000000 00000000 : Working Set = 2048 Locks = 100/100 (default) = 2048 Timers = 10/10 (quota) = 2048 Open Files = 28/40 (extent) = 4096 Asych Traps = 21/24 (peak) = 4096 Direct I/O = 18/18 Buffered I/O = 18/18 Byte Limit = 4288/4288 Mode = 03 Event Flags = e10004fe Process Pages = 315 Type = 00 fe000000 Global Pages = 199 State = 0e EF WaitMask = dfffffff Page Faults = 502768 #endif if (dummy1 != NULL || dummy2 != NULL) { lib$signal(SS$_ACCVIO); return; } /* gather the data into the static buffer */ IFBAD(sys$getjpiw(0, NULL, NULL, ThePList, &iosb, NULL, 0)) { DEBUGON(printf("cannot getjpi, status is (hex) %x.\n", cv0);) return; } IFBAD(iosb.cond) { DEBUGON(printf("cannot getjpi, iosbcond is (hex) %x.\n", cv0);) return; } /* format the login time. returns "24-MAY-1996 23:38:02.76" but we want "24-MAY 23:38:02". * also, we do not want a leading zero on the hour. */ temp_sd.dsc$a_pointer = timebuf; temp_sd.dsc$w_length = sizeof(timebuf); temp_sd.dsc$b_dtype = 0; temp_sd.dsc$b_class = 0; sys$asctim(NULL, &temp_sd, pz.loginTime, 0); tmpitembuf[0] = timebuf[0]; tmpitembuf[1] = timebuf[1]; tmpitembuf[2] = timebuf[2]; tmpitembuf[3] = timebuf[3]; tmpitembuf[4] = timebuf[4]; tmpitembuf[5] = timebuf[5]; tmpitembuf[6] = ' '; tmpitembuf[7] = timebuf[12]; tmpitembuf[8] = timebuf[13]; tmpitembuf[9] = ':'; tmpitembuf[10] = timebuf[15]; tmpitembuf[11] = timebuf[16]; tmpitembuf[12] = ':'; tmpitembuf[13] = timebuf[18]; tmpitembuf[14] = timebuf[19]; tmpitembuf[15] = '\0'; if (tmpitembuf[7] == '0') tmpitembuf[7] = ' '; strcpy(pz.theLoginTime, tmpitembuf); /* format the cpu time * * we must convert a process' cpu-time to DEC's system quadword time --- * this involves going from tenths of milliseconds to hundreds of nanoseconds, * which is a factor of one hundred thousand. the extra longword is set to * the maximum value allowed an unsigned long to ensure that the time will be * seen as a "delta" instead of an "absolute". leading zeroes and colons are * then stripped off, except for times less than one second. */ elapsedTime[0] = (long) pz.cpuTime * (-1); elapsedTime[1] = 0xFFFFFFFF; lib$mult_delta_time(&TheMagicFactor, &elapsedTime[0]); sys$numtim(&timbuf, &elapsedTime[0]); sprintf(pz.theCpuTime, "%01d:%02d:%02d:%02d.%02d", timbuf.nDays, timbuf.nHours, timbuf.nMinutes, timbuf.nSeconds, timbuf.nCentiseconds); /* need a null byte for easier printfing */ pz.process[ retlen[PROCESSNAME_RETLEN]] = '\0'; pz.account[ retlen[ ACCOUNT_RETLEN]] = '\0'; pz.nodename[ retlen[ NODENAME_RETLEN]] = '\0'; pz.terminal[ retlen[ TERMINAL_RETLEN]] = '\0'; pz.username[ retlen[ USERNAME_RETLEN]] = '\0'; pz.imageSpec[retlen[ IMAGESPEC_RETLEN]] = '\0'; /* still need to hack at these two fields, because * their returned lengths are the blank-filled value (hahaha) */ DSC_I_TrimAsciz(pz.account); DSC_I_TrimAsciz(pz.username); /* finally, get the default directory */ temp_sd.dsc$a_pointer = directory; temp_sd.dsc$w_length = sizeof(directory) - 1; temp_sd.dsc$b_dtype = 0; temp_sd.dsc$b_class = 0; IFBAD(sys$setddir(NULL, &ddlen, &temp_sd)) { lib$signal(cv0, 0); ddlen = 0; } directory[ddlen] = '\0'; strcpy(pz.defaultDir, getenv("SYS$DISK")); strcat(pz.defaultDir, directory); /* done preparing the data, time to display it */ if (fp == NULL) fp = stdout; fprintf(fp, "\n\tProcess Information:\n"); fprintf(fp, "\n\t\tUsername = %-*s Pid = %08X", MAXSIZE_USERNAME, pz.username, pz.pid); fprintf(fp, "\n\t\tProcessname = %-*s Priority = %d/%d", MAXSIZE_PROCESSNAME, pz.process, pz.prio, pz.prib); fprintf(fp, "\n\t\tAccount = %-*s UIC = [%06o,%06o]", MAXSIZE_ACCOUNT, pz.account, pz.group, pz.member); fprintf(fp, "\n\t\tTerminal = %-*s Node = %s", MAXSIZE_TERMINAL, pz.terminal, pz.nodename); tmpptr = pz.theCpuTime; while (*tmpptr == '0' || *tmpptr == ':') ++tmpptr; fprintf(fp, "\n\t\tLogin Time = %-15s Cpu Time = %s", pz.theLoginTime, tmpptr); fprintf(fp, "\n"); fprintf(fp, "\n\t\tMain Image = %s", pz.imageSpec); fprintf(fp, "\n\t\tDefault Dir = %s", pz.defaultDir); fprintf(fp, "\n"); DSC_I_ShowPrivileges(pz.curpriv, prvbuf); fprintf(fp, "\n\t\tPrivileges = %08X %08X : %s", pz.curpriv[0], pz.curpriv[1], prvbuf); DSC_I_ShowPrivileges(pz.defpriv, prvbuf); fprintf(fp, "\n\t\t (def) = %08X %08X : %s", pz.defpriv[0], pz.defpriv[1], prvbuf); DSC_I_ShowPrivileges(pz.authpriv, prvbuf); fprintf(fp, "\n\t\t (auth) = %08X %08X : %s", pz.authpriv[0], pz.authpriv[1], prvbuf); DSC_I_ShowPrivileges(pz.exepriv, prvbuf); fprintf(fp, "\n\t\t (image) = %08X %08X : %s", pz.exepriv[0], pz.exepriv[1], prvbuf); fprintf(fp, "\n"); fprintf(fp, "\n\t\tWorking Set = %5d Locks = %5d/%d", pz.wssize, pz.enqcount, pz.enqlimit); fprintf(fp, "\n\t\t (default) = %5d Timers = %5d/%d", pz.dfwscnt, pz.tmqcount, pz.tmqlimit); fprintf(fp, "\n\t\t (quota) = %5d Open Files = %5d/%d", pz.wsquota, pz.filcount, pz.fillimit); fprintf(fp, "\n\t\t (extent) = %5d Asych Traps = %5d/%d", pz.wsextent, pz.astcount, pz.astlimit); fprintf(fp, "\n\t\t (peak) = %5d Direct I/O = %5d/%d", pz.wspeak, pz.diocount, pz.diolimit); fprintf(fp, "\n\t\t Buffered I/O = %5d/%d", pz.biocount, pz.biolimit); fprintf(fp, "\n\t\t Byte Limit = %5d/%d", pz.bytcount, pz.bytlimit); fprintf(fp, "\n"); fprintf(fp, "\n\t\tMode = %02X Event Flags = %08X Process Pages = %6d", pz.mode, pz.eflag[0], pz.ppgcnt); fprintf(fp, "\n\t\tType = %02X %08X Global Pages = %6d", pz.processType, pz.eflag[1], pz.gpgcnt); fprintf(fp, "\n\t\tState = %02X EF WaitMask = %08X Page Faults = %6d", pz.state, pz.efmask, pz.pageflts); fprintf(fp, "\n"); return; } MEP__ PUBLIC void DSC_ShowSystemData( void *dummy1, FILE *fp, void *dummy2 ) { CONDVAL cv0; IOStatusBlock iosb; long swappct; long pagepct; char *machptr; struct dsc$descriptor_s temp_sd; char timebuf[COMMONSIZE]; char outbuf[BIGSIZE * 2]; #ifdef sample_output System Information: this VAX machine --- a MicroVax 3100 (model 156) --- is a node called FOOBAR running OpenVMS version V5.3 which was last booted 12-SEP-1993 14:15:16.17 there are 1552 free global pages there are 93 free global section table entries there are 42000 pages in the paging files ( 87% free) there are 9000 pages in the swapping files (100% free) #endif if (dummy1 != NULL || dummy2 != NULL) { lib$signal(SS$_ACCVIO); return; } /* gather the data into the static buffer, then copy it into the caller's buffer */ IFBAD(sys$getsyiw(0, NULL, NULL, &TheSList[0], &iosb, NULL, 0)) { DEBUGON(printf("cannot getsyi, status is (hex) %x.\n", cv0);) return; } IFBAD(iosb.cond) { DEBUGON(printf("cannot getsyi, iosbcond is (hex) %x.\n", cv0);) return; } /* need a null byte for easier printfing. also need to trim them * because their returned lengths are the blank-filled value */ sz.swtype[ retlen[ SWTYPE_RETLEN]] = '\0'; sz.hwname[ retlen[ HWNAME_RETLEN]] = '\0'; sz.version[ retlen[ VERSION_RETLEN]] = '\0'; sz.nodename[retlen[NODENAME_RETLEN]] = '\0'; DSC_I_TrimAsciz(sz.swtype); DSC_I_TrimAsciz(sz.hwname); DSC_I_TrimAsciz(sz.version); DSC_I_TrimAsciz(sz.nodename); /* done preparing the data, time to display it */ if (fp == NULL) fp = stdout; fprintf(fp, "\n\tSystem Information:\n"); machptr = (sz.hwmodel < 1024) ? "VAX" : "AXP"; temp_sd.dsc$a_pointer = timebuf; temp_sd.dsc$w_length = sizeof(timebuf); temp_sd.dsc$b_dtype = 0; temp_sd.dsc$b_class = 0; sys$asctim(NULL, &temp_sd, sz.booted, 0); timebuf[23] = '\0'; fprintf(fp, "\n\t\tthis %s machine --- a %s (model %d) ---", machptr, sz.hwname, sz.hwmodel); fprintf(fp, "\n\t\tis a node named %s running OpenVMS version %s", sz.nodename, sz.version); fprintf(fp, "\n\t\twhich was last booted at %s", timebuf); fprintf(fp, "\n"); pagepct = sz.freepf * 100 / sz.totpf; swappct = sz.freesf * 100 / sz.totsf; fprintf(fp, "\n\t\tthere are %7d free global pages", sz.freegp); fprintf(fp, "\n\t\tthere are %7d free global section table entries", sz.freegs); fprintf(fp, "\n\t\tthere are %7d pages in the paging files (%3d%% free)", sz.totpf, pagepct); fprintf(fp, "\n\t\tthere are %7d pages in the swapping files (%3d%% free)", sz.totsf, swappct); fprintf(fp, "\n"); return; }