home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 13 / AACD13.ISO / AACD / System / Sysmon / src / ShowSys.c < prev    next >
C/C++ Source or Header  |  2000-08-01  |  13KB  |  453 lines

  1. /*
  2. **    $RCSfile: ShowSys.c,v $
  3. **    $Filename: ShowSys.c $
  4. **    $Revision: 1.5 $
  5. **    $Date: 2000/06/27 19:58:03 $
  6. **
  7. **    sysmon.library Task display command ShowSys (version 1.6)
  8. **    
  9. **    (C) Copyright 1995-2000 by Etienne Vogt
  10. **    64/32 Division algorithm kindly provided by Thomas Richter
  11. */
  12.  
  13. #include <exec/alerts.h>
  14. #include <exec/memory.h>
  15. #include <exec/execbase.h>
  16. #include <dos/dosextens.h>
  17. #include <dos/var.h>
  18. #include <dos/datetime.h>
  19. #include <workbench/startup.h>
  20. #include <devices/timer.h>
  21. #define __USE_SYSBASE
  22. #include <proto/exec.h>
  23. #include <proto/dos.h>
  24. #include <proto/utility.h>
  25. #include <proto/timer.h>
  26. #include <stdlib.h>
  27. #include <string.h>
  28. #include <ctype.h>
  29. #include "sysmon.h"
  30. #include "sysmon_protos.h"
  31. #include "sysmon_pragmas.h"
  32.  
  33. #define TIBUFMAX    30
  34. #define TNAMEMAX    31
  35. #define NT_CLI    NT_USER
  36.  
  37. struct tiBuffer
  38. {    struct TaskInfo tib_tinfo;
  39.     char    tib_name[TNAMEMAX];
  40.     UBYTE    tib_type;
  41.     LONG    tib_clinum;
  42.     ULONG    tib_stacksize;
  43.     ULONG    tib_sigalloc;
  44.     ULONG    tib_sigwait;
  45.     ULONG    tib_sigrecvd;
  46.     ULONG    tib_sigexcept;
  47.     BYTE    tib_pri;
  48.     UBYTE    tib_flags;
  49.     UBYTE    tib_state;
  50. };
  51.     
  52. struct tiBufArray
  53. {    struct tiBufArray *tba_Link;
  54.     struct tiBuffer tba_bufs[TIBUFMAX];
  55. };
  56.  
  57. struct ExecBase *SysBase;
  58. struct DosLibrary *DOSBase;
  59. struct SysmonBase *SysmonBase;
  60. struct Library *TimerBase;
  61. struct timerequest myTimeReq;
  62. static struct WBStartup *wbmsg;
  63. static struct RDArgs *myrda;
  64.  
  65. ULONG __saveds  main(void);
  66. static void cleanexit(ULONG rc);
  67. static char *uptimestr(struct EClockVal *clockval, ULONG clockrate);
  68. static char *cputimestr(struct EClockVal *clockval, ULONG clockrate);
  69. static char *taskstate(UBYTE state, ULONG sigwait);
  70. static char *taskflags(UBYTE flags, UBYTE moreflags);
  71. static char *tasktype(UBYTE type, LONG clinum);
  72. static char *bstr2c(BSTR bstring);
  73. static char *cpustr(UWORD cpuflags);
  74. static char *filterctrl(char *string);
  75. static ULONG EClockDivide(struct EClockVal *numerator, ULONG denominator);
  76. APTR SPrintf(STRPTR buffer, STRPTR format, ...);
  77. void KPrintf(STRPTR format, ...);
  78. void freetibufs(struct tiBufArray *tibufs);
  79.  
  80. static UBYTE version[] = "$VER: ShowSys 1.6 (1.8.2000)";
  81. static UBYTE template[] = "FULL/S";
  82.  
  83. #define    OPT_FULL    0
  84. #define OPTMAX        1
  85.  
  86. ULONG __saveds main(void)    /* No startup code */
  87. {
  88.   struct Process *myproc;
  89.   ULONG EClockRate;
  90.   struct tiBufArray *tibufs;
  91.   LONG opts[OPTMAX];
  92.  
  93.   SysBase = *(struct ExecBase **)4;
  94.   DOSBase = NULL;
  95.   SysmonBase = NULL;
  96.   TimerBase = NULL;
  97.   wbmsg = NULL;
  98.   myrda = NULL;
  99.  
  100.   myproc = (struct Process *)FindTask(NULL);
  101.   if ((DOSBase = (struct DosLibrary *)OpenLibrary("dos.library",36)) == NULL)
  102.   { Alert(AT_Recovery|AG_OpenLib|AO_DOSLib);
  103.     return 100;
  104.   }
  105.  
  106.   if (!(myproc->pr_CLI))        /* If started from WB, exit cleanly */
  107.   { WaitPort(&(myproc->pr_MsgPort));
  108.     wbmsg = (struct WBStartup *)GetMsg(&(myproc->pr_MsgPort));
  109.     cleanexit(20);
  110.   }
  111.  
  112.   if ((SysmonBase = (struct SysmonBase *)OpenLibrary("sysmon.library",1)) == NULL)
  113.   { if (DOSBase->dl_lib.lib_Version >= 36) PutStr("ShowSys : Couldn't open sysmon.library V1+.\n");
  114.     cleanexit(20);
  115.   }
  116.  
  117.   if (OpenDevice(TIMERNAME, UNIT_ECLOCK, (struct IORequest *)&myTimeReq, 0L))
  118.   { Alert(AT_Recovery|AG_OpenDev|AO_TimerDev);
  119.     cleanexit(100);
  120.   }
  121.   else
  122.   { char Workbench[8], NodeName[16];
  123.     struct EClockVal UpTime;
  124.     struct DateTime SysTime;
  125.     UBYTE strDate[LEN_DATSTRING], strTime[LEN_DATSTRING];
  126.  
  127.     memset((char *)opts, 0, sizeof(opts));
  128.     if ((myrda = ReadArgs(template, opts, NULL)) == NULL)
  129.     { PrintFault(IoErr(),"ShowSys");
  130.       cleanexit(20);
  131.     }
  132.  
  133.     TimerBase = (struct Library *)myTimeReq.tr_node.io_Device;
  134.     EClockRate = ReadEClock(&UpTime);
  135.     if (GetVar("Workbench", Workbench, sizeof(Workbench) - 1, GVF_GLOBAL_ONLY) > 0)
  136.       Printf("AmigaOS %s", Workbench);
  137.     else PutStr("AmigaOS ?????");
  138.     if (GetVar("HostName", NodeName, sizeof(NodeName) - 1, GVF_GLOBAL_ONLY) > 0)
  139.       Printf(" at %s", NodeName);
  140.     else PutStr(" at ????? ");
  141.     DateStamp(&SysTime.dat_Stamp);
  142.     SysTime.dat_Format = FORMAT_DOS;
  143.     SysTime.dat_Flags = 0;
  144.     SysTime.dat_StrDay = NULL;
  145.     SysTime.dat_StrDate = strDate;
  146.     SysTime.dat_StrTime = strTime;
  147.     if (DateToStr(&SysTime)) Printf("   %s %s", SysTime.dat_StrDate, SysTime.dat_StrTime);
  148.     else Printf("                    ");
  149.     Printf("   UpTime :%s\n", uptimestr(&UpTime, EClockRate));
  150.   }
  151.   
  152.   Printf("Address  Name                           State  Pri   CPU [%.5s]    Type\n",cpustr(SysBase->AttnFlags));
  153.   if (opts[OPT_FULL]) Printf(">  Stack  SigAlloc SigWait  SigRecvd SigExcpt  Flags      Dispatch\n");
  154.  
  155.   if ((tibufs = AllocVec(sizeof(struct tiBufArray), MEMF_PUBLIC | MEMF_CLEAR)) == NULL)
  156.   { PutStr("ShowSys : No memory for TaskInfo buffers.\n");
  157.     cleanexit(20);
  158.   }
  159.   else
  160.   { struct TaskInfo *tinfo = NULL;
  161.     struct tiBufArray *tba = tibufs;
  162.     struct tiBuffer *buf;
  163.     int j, i = 0, numtask = 0;
  164.  
  165.     smLockTaskTable(LTTF_READ);
  166.     while (tinfo = smNextTaskInfo(tinfo))
  167.     { struct Task *task;
  168.       struct CommandLineInterface *cli;
  169.       char *comname;
  170.       int n;
  171.  
  172.       numtask++;
  173.       buf = &tba->tba_bufs[i];
  174.       memcpy(buf, tinfo, sizeof(struct TaskInfo));
  175.       task = tinfo->ti_Task;
  176.       if (task->tc_Node.ln_Name) strcpy(buf->tib_name, filterctrl(task->tc_Node.ln_Name));
  177.       else strcpy(buf->tib_name, "<< No Name >>");
  178.       buf->tib_flags = task->tc_Flags;
  179.       buf->tib_state = task->tc_State;
  180.       buf->tib_sigalloc = task->tc_SigAlloc;
  181.       buf->tib_sigwait = task->tc_SigWait;
  182.       buf->tib_sigrecvd = task->tc_SigRecvd;
  183.       buf->tib_sigexcept = task->tc_SigExcept;
  184.       if (buf->tib_state == TS_WAIT && task->tc_SigWait == 0) buf->tib_state = TS_STOP;
  185.       buf->tib_pri = task->tc_Node.ln_Pri;
  186.       buf->tib_type = task->tc_Node.ln_Type;
  187.       if (buf->tib_type == NT_PROCESS && (cli = BADDR(((struct Process *)task)->pr_CLI)))
  188.       { buf->tib_clinum = ((struct Process *)task)->pr_TaskNum;
  189.     buf->tib_type = NT_CLI;
  190.     buf->tib_stacksize = cli->cli_DefaultStack * sizeof(ULONG);
  191.     if (cli->cli_Module && (comname = bstr2c(cli->cli_CommandName)) && (n = strlen(buf->tib_name)) < TNAMEMAX - 4)
  192.     { comname = filterctrl(FilePart(comname));
  193.       strcat(buf->tib_name, " (");
  194.       strncat(buf->tib_name, comname, TNAMEMAX - n - 4);
  195.       strcat(buf->tib_name, ")");
  196.     }
  197.       }
  198.       else if (buf->tib_type == NT_PROCESS) buf->tib_stacksize = ((struct Process *)task)->pr_StackSize;
  199.       else buf->tib_stacksize = (ULONG)task->tc_SPUpper - (ULONG)task->tc_SPLower;
  200.  
  201.       if (++i == TIBUFMAX)
  202.       { struct tiBufArray *tba1;
  203.  
  204.     if (tba1 = AllocVec(sizeof(struct tiBufArray), MEMF_PUBLIC | MEMF_CLEAR))
  205.     { tba->tba_Link = tba1;
  206.       tba = tba1;
  207.       i = 0;
  208.     }
  209.     else
  210.     { smUnLockTaskTable(LTTF_READ);
  211.       freetibufs(tibufs);
  212.       Printf("ShowSys : No memory for TaskInfo buffers.\n");
  213.       cleanexit(20);
  214.     }
  215.       }
  216.     }
  217.     smUnLockTaskTable(LTTF_READ);
  218.  
  219.     for (j = 0, tba = tibufs, i = 0 ; j < numtask ; j++)
  220.     { buf = &tba->tba_bufs[i];
  221.       Printf("%08lx %-30.30s %-5s %4ld %16s %-8s\n", buf->tib_tinfo.ti_Task,
  222.         buf->tib_name, taskstate(buf->tib_state, buf->tib_sigwait), buf->tib_pri,
  223.         cputimestr(&buf->tib_tinfo.ti_CPUTime, EClockRate),
  224.         tasktype(buf->tib_type, buf->tib_clinum));
  225.       if (opts[OPT_FULL]) Printf(">%7lu  %08lx %08lx %08lx %08lx  %8s %10lu\n", buf->tib_stacksize,
  226.         buf->tib_sigalloc, buf->tib_sigwait, buf->tib_sigrecvd, buf->tib_sigexcept,
  227.         taskflags(buf->tib_flags, buf->tib_tinfo.ti_Flags), buf->tib_tinfo.ti_DispCount);
  228.  
  229.       if (CheckSignal(SIGBREAKF_CTRL_C))
  230.       { PutStr("*** BREAK ***\n");
  231.     break;
  232.       }
  233.  
  234.       if (++i == TIBUFMAX) 
  235.       { tba = tba->tba_Link;
  236.     i = 0;
  237.       }
  238.     }
  239.     freetibufs(tibufs);
  240.   }
  241.   cleanexit(0);
  242. }
  243.  
  244. static void cleanexit(ULONG rc)
  245. {
  246.   if (TimerBase) CloseDevice((struct IORequest *)&myTimeReq);
  247.   if (SysmonBase) CloseLibrary((struct Library *)SysmonBase);
  248.   if (myrda) FreeArgs(myrda);
  249.   if (wbmsg)
  250.   { Forbid();
  251.     ReplyMsg((struct Message *)wbmsg);
  252.   }
  253.   if (DOSBase) CloseLibrary((struct Library *)DOSBase);
  254.   Exit(rc);
  255. }
  256.  
  257. static char *uptimestr(struct EClockVal *clockval, ULONG clockrate)
  258. { static char buffer[16];
  259.   ULONG seconds;
  260.   UWORD updays, uphours, upminutes, upseconds;
  261.  
  262.   seconds = EClockDivide(clockval, clockrate);
  263.   updays = seconds / (24*60*60);
  264.   seconds %= 24*60*60;
  265.   uphours = seconds / (60*60);
  266.   seconds %= 60*60;
  267.   upminutes = seconds / 60;
  268.   upseconds = seconds % 60;
  269.   SPrintf(buffer, "%4lu %02lu:%02lu:%02lu", updays, uphours, upminutes, upseconds);
  270.   return buffer; 
  271. }
  272.  
  273. static char *cputimestr(struct EClockVal *clockval, ULONG clockrate)
  274. { static char buffer[18];
  275.   ULONG seconds;
  276.   UWORD cpudays, cpuhours, cpuminutes, cpuseconds, cpumillis;
  277.  
  278.   seconds = EClockDivide(clockval, clockrate);
  279.   cpudays = seconds / (24*60*60);
  280.   seconds %= 24*60*60;
  281.   cpuhours = seconds / (60*60);
  282.   seconds %= 60*60;
  283.   cpuminutes = seconds / 60;
  284.   cpuseconds = seconds % 60;
  285.   cpumillis = clockval->ev_lo / (clockrate / 1000);
  286.   SPrintf(buffer, "%3lu %02lu:%02lu:%02lu.%03lu", cpudays, cpuhours, cpuminutes, cpuseconds, cpumillis);
  287.   return buffer;
  288. }
  289.  
  290. static ULONG EClockDivide(struct EClockVal *numerator, ULONG denominator)
  291. { int bits;
  292.   ULONG d1,d2,d3;
  293.  
  294.   d1 = 0x0;
  295.   d2 = numerator->ev_hi;
  296.   d3 = numerator->ev_lo;
  297.  
  298.   for (bits = 0; bits < 64; bits++)
  299.   { /* now left-shift d1,d2,d3 */
  300.     d1 <<= 1;
  301.     if (d2 & 0x80000000) d1 |= 0x1;
  302.     d2 <<= 1;
  303.     if (d3 & 0x80000000) d2 |= 0x1;
  304.     d3 <<= 1;
  305.  
  306.     if (d1 >= denominator) 
  307.     { d1 -= denominator;
  308.       d3 |= 0x1;
  309.     }
  310.   }
  311.  
  312.   /* fill in the remainder */
  313.   numerator->ev_lo = d1;
  314.  
  315.   /* return the quotient, or the low part of it, at least */
  316.   return d3;
  317. }
  318.  
  319. static char *taskflags(UBYTE flags, UBYTE moreflags)
  320. { static char buffer[9];
  321.  
  322.   buffer[0] = (flags & TF_LAUNCH) ? 'L' : '-';
  323.   buffer[1] = (flags & TF_SWITCH) ? 'S' : '-';
  324.   buffer[2] = (flags & TF_EXCEPT) ? 'E' : '-';
  325.   buffer[3] = (flags & TF_STACKCHK) ? 'C' : '-';
  326.   buffer[4] = (flags & TF_ETASK) ? 'X' : '-';
  327.   buffer[5] = (flags & TF_PROCTIME) ? 'P' : '-';
  328.   buffer[6] = (moreflags & TIF_INEXCEPT) ? 'I' : '-';
  329.   buffer[7] = (moreflags & TIF_WAKEUP) ? 'W' : '-';
  330.   buffer[8] = '\0';
  331.   return buffer;
  332. }
  333.  
  334. static char *taskstate(UBYTE state, ULONG sigwait)
  335. {
  336.   switch(state)
  337.   { case TS_INVALID:
  338.       return "INVLD";
  339.     case TS_ADDED:
  340.       return "ADDED";
  341.     case TS_RUN:
  342.       return "RUN";
  343.     case TS_READY:
  344.       return "READY";
  345.     case TS_WAIT:
  346.       if (sigwait == 0) return "STOP";
  347.       else if (sigwait == SIGF_ABORT) return "SWABO";
  348.       else if (sigwait == SIGF_CHILD) return "SWCHI";
  349.       else if (sigwait == SIGF_SINGLE) return "SWSIN";
  350.       else if (sigwait == SIGF_INTUITION) return "SWINT";
  351.       else if (sigwait == SIGF_NET) return "SWNET";
  352.       else if (sigwait == SIGF_DOS) return "SWDOS";
  353.       else if (sigwait == SIGBREAKF_CTRL_C) return "SWBRC";
  354.       else if (sigwait == SIGBREAKF_CTRL_D) return "SWBRD";
  355.       else if (sigwait == SIGBREAKF_CTRL_E) return "SWBRE";
  356.       else if (sigwait == SIGBREAKF_CTRL_F) return "SWBRF";
  357.       else return "WAIT";
  358.     case TS_EXCEPT:
  359.       return "EXCPT";
  360.     case TS_REMOVED:
  361.       return "REMVD";
  362.     case TS_STOP:
  363.       return "STOP";
  364.     case TS_FROZEN:
  365.       return "FROZN";
  366.     case TS_HIBERNATE:
  367.       return "HIBER";
  368.     case TS_PAGEFLTWAIT:
  369.       return "PGFWT";
  370.     case TS_WAITAND:
  371.       return "WAITA";
  372.     case TS_TRAP:
  373.       return "TRAP";
  374.     case TS_FREEWAIT:
  375.       return "FREWT";
  376.  
  377.     default:
  378.       return "?????";
  379.   }
  380. }
  381.  
  382. static char *tasktype(UBYTE type, LONG clinum)
  383. { static char buffer[10];
  384.  
  385.   switch(type)
  386.   { case NT_TASK:
  387.       SPrintf(buffer,"Task");
  388.       break;
  389.     case NT_PROCESS:
  390.       SPrintf(buffer,"Process");
  391.       break;
  392.     case NT_CLI:
  393.       SPrintf(buffer,"Cli %-4ld",clinum);
  394.       break;
  395.     default:
  396.       SPrintf(buffer,"???");
  397.       break;
  398.   }
  399.   return buffer;
  400. }
  401.  
  402. #define    AFB_68060    7
  403. #define AFF_68060    (1L<<7)
  404.  
  405. static char *cpustr(UWORD cpuflags)
  406. {
  407.   if (cpuflags & AFF_68060) return "68060";
  408.   else if (cpuflags & AFF_68040) return "68040";
  409.   else if (cpuflags & AFF_68030) return "68030";
  410.   else if (cpuflags & AFF_68020) return "68020";
  411.   else if (cpuflags & AFF_68010) return "68010";
  412.   else return "68000";
  413. }
  414.  
  415. static char *bstr2c(BSTR bstring)
  416. { static char buffer[256];
  417.   char *ptr;
  418.   int n;
  419.  
  420.   if ((ptr = BADDR(bstring)) == NULL || (n = *ptr++) == 0) return NULL;
  421.   strncpy(buffer, ptr, n + 1);
  422.   return buffer;
  423. }
  424.  
  425. static char *filterctrl(char *string)
  426. { static char buffer[TNAMEMAX];
  427.   int i;
  428.  
  429.   for (i = 0 ; *string && i < TNAMEMAX - 1 ; i++, string++)
  430.   { if ((*string & 0x7f) < ' ') buffer[i] = '.';
  431.     else buffer[i] = *string;
  432.   }
  433.   buffer[i] = 0;
  434.   return buffer;
  435. }
  436.  
  437. APTR SPrintf(STRPTR buffer, STRPTR format, ...)
  438. { return smVSPrintf(buffer, format, &format + 1);
  439. }
  440.  
  441. void KPrintf(STRPTR format, ...)
  442. { smVKPrintf(format, &format + 1);
  443. }
  444.  
  445. void freetibufs(struct tiBufArray *tibufs)
  446. { struct tiBufArray *nexttba;
  447.  
  448.   do
  449.   { nexttba = tibufs->tba_Link;
  450.     FreeVec(tibufs);
  451.   } while (tibufs = nexttba);
  452. }
  453.