home *** CD-ROM | disk | FTP | other *** search
/ Frozen Fish 1: Amiga / FrozenFish-Apr94.iso / bbs / dec93 / os20 / util / multiuser.lha / MultiUser / C.src / Tasks.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-12-21  |  6.2 KB  |  245 lines

  1. /************************************************************
  2. * MultiUser - MultiUser Task/File Support System                *
  3. * ---------------------------------------------------------    *
  4. * Get Information about Tasks                                            *
  5. * ---------------------------------------------------------    *
  6. * © Copyright 1993 by Geert Uytterhoeven                            *
  7. * All Rights Reserved.                                                    *
  8. ************************************************************/
  9.  
  10.  
  11. #include    <exec/memory.h>
  12. #include <exec/execbase.h>
  13. #include <proto/exec.h>
  14. #include <proto/dos.h>
  15. #include <string.h>
  16. #include <libraries/multiuser.h>
  17. #include <proto/multiuser.h>
  18.  
  19. #include "Tasks_rev.h"
  20.  
  21.  
  22. char __VersTag__[] = VERSTAG;
  23.  
  24.  
  25. struct TaskInfo {
  26.     struct Task *Task;
  27.     char Name[32];
  28.     ULONG TaskNum;
  29.     UBYTE Type;
  30.     BYTE Priority;
  31.     UWORD uid;
  32. };
  33.  
  34.  
  35. static ULONG CountTasks(struct ExecBase *SysBase);
  36. static BOOL FillTaskInfo(struct TaskInfo *tasks, ULONG maxtasks,
  37.                                  ULONG *numtasks, UWORD currentuid, BOOL all,
  38.                                  struct ExecBase *SysBase, struct muBase *muBase);
  39. static BOOL FillIt(struct Task *task, struct TaskInfo *info, UWORD currentuid,
  40.                          BOOL all, struct muBase *muBase);
  41. static ULONG DumpTaskInfo(struct TaskInfo *tasks, ULONG numtasks,
  42.                                   struct DosLibrary *DOSBase, struct muBase *muBase);
  43.  
  44.  
  45. int __saveds Start(char *arg)
  46. {
  47.     struct ExecBase *SysBase;
  48.     struct DosLibrary *DOSBase;
  49.     struct muBase *muBase = NULL;
  50.     struct RDArgs *args;
  51.     LONG argarray[] = {
  52.         NULL, NULL
  53.     };
  54.     UWORD currentuid;
  55.     struct TaskInfo *tasks;
  56.     ULONG maxtasks, numtasks;
  57.     struct muUserInfo *info;
  58.     LONG error = NULL;
  59.     int rc;
  60.  
  61.     SysBase = *(struct ExecBase **)4;
  62.     
  63.     if ((!(DOSBase = (struct DosLibrary *)OpenLibrary("dos.library", 37))) ||
  64.          (!(muBase = (struct muBase *)OpenLibrary("multiuser.library", 39)))) {
  65.         rc = RETURN_FAIL;
  66.         goto Exit;
  67.     }
  68.  
  69.     args = ReadArgs("USERID,ALL/S", argarray, NULL);
  70.     if (!args)
  71.         error = IoErr();
  72.     else {
  73.         if (!argarray[0])
  74.             currentuid = muGetTaskOwner(NULL)>>16;
  75.         else if (info = muAllocUserInfo()) {
  76.             strncpy(info->UserID, (char *)argarray[0], muUSERIDSIZE-1);
  77.             info->UserID[muUSERIDSIZE-1] = '\0';
  78.             if (muGetUserInfo(info, muKeyType_UserID))
  79.                 currentuid = info->uid;
  80.             else {
  81.                 VPrintf("Unknown user '%s'\n", &argarray[0]);
  82.                 goto Fail;
  83.             }
  84.             muFreeUserInfo(info);
  85.         } else {
  86.             error = IoErr();
  87.             goto Fail;
  88.         }
  89.         do {
  90.             maxtasks = CountTasks(SysBase)+5;
  91.             if (tasks = AllocVec(maxtasks*sizeof(struct TaskInfo), MEMF_CLEAR)) {
  92.                 if (FillTaskInfo(tasks, maxtasks, &numtasks, currentuid,
  93.                                       (BOOL)argarray[1], SysBase, muBase)) {
  94.                     error = DumpTaskInfo(tasks, numtasks, DOSBase, muBase);
  95.                     rc = RETURN_OK;
  96.                 } else
  97.                     rc = RETURN_ERROR;
  98.                 FreeVec(tasks);
  99.             } else
  100.                 error = IoErr();
  101.         } while (!error && (rc != RETURN_OK));
  102.     }
  103.     FreeArgs(args);
  104. Fail:
  105.     if (error) {
  106.         PrintFault(error, NULL);
  107.         rc = RETURN_ERROR;
  108.     }
  109.  
  110. Exit:
  111.     CloseLibrary((struct Library *)muBase);
  112.     CloseLibrary((struct Library *)DOSBase);
  113.  
  114.     return(rc);
  115. }    
  116.  
  117.  
  118.     /*
  119.      *        Count the number of tasks in the system
  120.      */
  121.  
  122. static ULONG CountTasks(struct ExecBase *SysBase)
  123. {
  124.     ULONG i = 1;
  125.     struct Task *task;
  126.  
  127.     Disable();
  128.     for (task = (struct Task *)SysBase->TaskReady.lh_Head;
  129.           task->tc_Node.ln_Succ; task = (struct Task *)task->tc_Node.ln_Succ)
  130.           i++;
  131.     for (task = (struct Task *)SysBase->TaskWait.lh_Head;
  132.           task->tc_Node.ln_Succ; task = (struct Task *)task->tc_Node.ln_Succ)
  133.           i++;
  134.     Enable();
  135.     return(i);
  136. }
  137.  
  138.  
  139.     /*
  140.      *        Fill in information about the tasks
  141.      */
  142.  
  143. static BOOL FillTaskInfo(struct TaskInfo *tasks, ULONG maxtasks,
  144.                                  ULONG *numtasks, UWORD currentuid, BOOL all,
  145.                                  struct ExecBase *SysBase, struct muBase *muBase)
  146. {
  147.     BOOL rc = TRUE;
  148.     struct Task *task;
  149.  
  150.     *numtasks = 0;
  151.     Disable();
  152.     if (FillIt(SysBase->ThisTask, &tasks[*numtasks], currentuid, all, muBase))
  153.         (*numtasks)++;
  154.     for (task = (struct Task *)SysBase->TaskReady.lh_Head;
  155.           (task->tc_Node.ln_Succ) && (*numtasks < maxtasks);
  156.           task = (struct Task *)task->tc_Node.ln_Succ)
  157.         if (FillIt(task, &tasks[*numtasks], currentuid, all, muBase))
  158.             (*numtasks)++;
  159.     if (task->tc_Node.ln_Succ)
  160.         rc = FALSE;
  161.     else {
  162.         for (task = (struct Task *)SysBase->TaskWait.lh_Head;
  163.               (task->tc_Node.ln_Succ) && (*numtasks < maxtasks);
  164.               task = (struct Task *)task->tc_Node.ln_Succ)
  165.             if (FillIt(task, &tasks[*numtasks], currentuid, all, muBase))
  166.                 (*numtasks)++;
  167.         if (task->tc_Node.ln_Succ)
  168.             rc = FALSE;
  169.     }
  170.     Enable();
  171.     return(rc);
  172. }
  173.  
  174.  
  175. static BOOL FillIt(struct Task *task, struct TaskInfo *info, UWORD currentuid,
  176.                          BOOL all, struct muBase *muBase)
  177. {
  178.     UWORD uid;
  179.     struct CommandLineInterface *cli;
  180.     char *name;
  181.     ULONG i;
  182.  
  183.     uid = muGetTaskOwner(task)>>16;
  184.     if (all || (uid == currentuid)) {
  185.         info->Task = task;
  186.         if (((info->Type = task->tc_Node.ln_Type) == NT_PROCESS) &&
  187.              (info->TaskNum = ((struct Process *)task)->pr_TaskNum) &&
  188.              (cli = (struct CommandLineInterface *)BADDR(((struct Process *)task)->pr_CLI)) &&
  189.              (name = BADDR(cli->cli_CommandName)) && name[0]) {
  190.             for (i = 0; (i < name[0]) && (i < 31); i++)
  191.                 info->Name[i] = name[i+1];
  192.             info->Name[i] = '\0';
  193.         } else {
  194.             strncpy(info->Name, task->tc_Node.ln_Name, 31);
  195.             info->Name[31] = '\0';
  196.         }
  197.         info->Priority = task->tc_Node.ln_Pri;
  198.         info->uid = uid;
  199.         return(TRUE);
  200.     } else
  201.         return(FALSE);
  202. }
  203.  
  204.  
  205.     /*
  206.      *        Dump the information
  207.      */
  208.  
  209. static ULONG DumpTaskInfo(struct TaskInfo *tasks, ULONG numtasks,
  210.                                   struct DosLibrary *DOSBase, struct muBase *muBase)
  211. {
  212.     struct muUserInfo *info;
  213.     ULONG error = NULL;
  214.     ULONG i;
  215.     LONG stream[3];
  216.  
  217.     if (info = muAllocUserInfo()) {
  218.         PutStr("Type    Node     Pri Name/Command                     Owner\n");
  219.         PutStr("-----------------------------------------------------------\n");
  220.          for (i= 0; (i < numtasks) && !CheckSignal(SIGBREAKF_CTRL_C); i++) {
  221.              if (tasks[i].Type == NT_PROCESS)
  222.                  if (stream[0] = tasks[i].TaskNum)
  223.                      VPrintf("CLI %3ld ", stream);
  224.                  else
  225.                      PutStr("Process ");
  226.             else
  227.                 PutStr("Task    ");
  228.              stream[0] = (LONG)tasks[i].Task;
  229.              stream[1] = (LONG)tasks[i].Priority;
  230.              stream[2] = (LONG)tasks[i].Name;
  231.             VPrintf("%08lx %3ld %-32s ", stream);
  232.             if ((info->uid = tasks[i].uid) == muOWNER_NOBODY)
  233.                 PutStr("\n");
  234.             else if (muGetUserInfo(info, muKeyType_uid)) {
  235.                 stream[0] = (LONG)info->UserID;
  236.                 VPrintf("%s\n", stream);
  237.             } else
  238.                 PutStr("???\n");
  239.         }
  240.         muFreeUserInfo(info);
  241.     } else
  242.         error = IoErr();
  243.     return(error);
  244. }
  245.