home *** CD-ROM | disk | FTP | other *** search
/ Aminet 3 / Aminet 3 - July 1994.iso / Aminet / util / misc / MUser17src.lha / MultiUser / src / Library / Misc.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-03-07  |  13.6 KB  |  583 lines

  1. /************************************************************
  2. * MultiUser - MultiUser Task/File Support System                *
  3. * ---------------------------------------------------------    *
  4. * Miscellaneous Routines                                                *
  5. * ---------------------------------------------------------    *
  6. * © Copyright 1993-1994 Geert Uytterhoeven                        *
  7. * All Rights Reserved.                                                    *
  8. ************************************************************/
  9.  
  10.  
  11. #include <exec/execbase.h>
  12. #include <utility/tagitem.h>
  13.  
  14.     /*
  15.      *        Password encryption
  16.      *
  17.      *        This function must be defined here because its prototype in
  18.      *        <clib/alib_protos.h> does not contain the __stdargs keyword
  19.      */
  20.  
  21. extern STRPTR __stdargs ACrypt(STRPTR buffer, STRPTR password, STRPTR username);
  22.  
  23.  
  24. #include <proto/exec.h>
  25. #include <proto/dos.h>
  26. #include <proto/intuition.h>
  27. #include <proto/utility.h>
  28. #include <proto/reqtools.h>
  29. #include <libraries/reqtools.h>
  30. #include <string.h>
  31.  
  32. #include "Memory.h"
  33. #include "Server.h"
  34. #include "Config.h"
  35. #include "LibHeader.h"
  36. #include "Misc.h"
  37. #include "Task.h"
  38. #include "Segment.h"
  39. #include "Protection.h"
  40. #include "UserInfo.h"
  41. #include "Monitor.h"
  42.  
  43.  
  44.     /*
  45.      *        Library Bases
  46.      */
  47.  
  48. struct ExecBase *SysBase;
  49. struct muBase *muBase;
  50. struct DosLibrary *DOSBase = NULL;
  51. struct IntuitionBase *IntuitionBase = NULL;
  52. struct Library *UtilityBase = NULL;
  53. struct ReqToolsBase *ReqToolsBase = NULL;
  54.  
  55.  
  56.     /*
  57.      *        Library Vector Offsets for SetFunction()
  58.      */
  59.  
  60. extern __far LVOAddTask;
  61. extern __far LVORemTask;
  62. extern __far LVOLoadSeg;
  63. extern __far LVONewLoadSeg;
  64. extern __far LVOUnLoadSeg;
  65. extern __far LVOInternalLoadSeg;
  66. extern __far LVOInternalUnLoadSeg;
  67. extern __far LVOCreateProc;
  68. extern __far LVOCreateNewProc;
  69. extern __far LVORunCommand;
  70. extern __far LVOSetProtection;
  71.  
  72.  
  73.     /*
  74.      *        Initialisation
  75.      */
  76.  
  77. BOOL Init(void)
  78. {
  79.     struct Task *task;
  80.  
  81.         /*
  82.          *        Initialise Memory Management
  83.          */
  84.  
  85.     if (!InitMemory())
  86.         return(FALSE);
  87.  
  88.         /*
  89.          *        Initialise the Semaphores
  90.          */
  91.  
  92.     InitSemaphore(&muBase->TaskOwnerSem);
  93.     InitSemaphore(&muBase->SegOwnerSem);
  94.     InitSemaphore(&muBase->VolumesSem);
  95.     InitSemaphore(&muBase->MonitorSem);
  96.  
  97.         /*
  98.          *        Open dos.library, intuition.library and utility.library V37+,
  99.          *        reqtools.library V38+ and create the Server
  100.          */
  101.  
  102.     if (!(DOSBase = (struct DosLibrary *)OpenLibrary("dos.library", 37)) ||
  103.          !(IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library", 37)) ||
  104.          !(UtilityBase = OpenLibrary("utility.library", 37)) ||
  105.          !(ReqToolsBase = (struct ReqToolsBase *)OpenLibrary("reqtools.library", 38)) ||
  106.          !CreateServer())
  107.         return(FALSE);
  108.  
  109.         /*
  110.          *        Initialise Task Owner, Segment Owner and Monitor Lists
  111.          */
  112.  
  113.     InitTaskList();
  114.     InitSegList();
  115.     InitMonList();
  116.  
  117.         /*
  118.          *        Initialise Task Control
  119.          */
  120.  
  121.     NewList((struct List *)&muBase->Frozen);
  122.  
  123.         /*
  124.          *        Create Task/User list
  125.          *
  126.          *        All tasks have no owner.
  127.          */
  128.  
  129.     Forbid();
  130.     CreateOrphanTask(SysBase->ThisTask, DEFPROTECTION);
  131.     for (task = (struct Task *)SysBase->TaskReady.lh_Head;
  132.           task->tc_Node.ln_Succ; task = (struct Task *)task->tc_Node.ln_Succ)
  133.           CreateOrphanTask(task, DEFPROTECTION);
  134.     for (task = (struct Task *)SysBase->TaskWait.lh_Head;
  135.           task->tc_Node.ln_Succ; task = (struct Task *)task->tc_Node.ln_Succ)
  136.           CreateOrphanTask(task, DEFPROTECTION);
  137.  
  138.         /*
  139.          *        Make sure the Server is owned by the system
  140.          */
  141.  
  142.     PushTask((struct Task *)muBase->Server, &RootExtOwner);
  143.  
  144.         /*
  145.          *        Patch exec.library functions:
  146.          *
  147.          *            AddTask()
  148.          *            RemTask()
  149.          *
  150.          *        Patch dos.library functions:
  151.          *
  152.          *            LoadSeg()
  153.          *            NewLoadSeg()
  154.          *            UnLoadSeg()
  155.          *            InternalLoadSeg()
  156.          *            InternalUnLoadSeg()
  157.          *            CreateProc()
  158.          *            CreateNewProc()
  159.          *            RunCommand()
  160.          *            SetProtection()
  161.          *
  162.          *        This must be done inside this Forbid()/Permit() pair
  163.          *        to prevent the birth of orphan-tasks
  164.          */
  165.  
  166.     muBase->OLDAddTask = SetFunction((struct Library *)SysBase,
  167.                                                 (LONG)&LVOAddTask,
  168.                                                 (ULONG (*)())NEWAddTask);
  169.     muBase->OLDRemTask = SetFunction((struct Library *)SysBase,
  170.                                                 (LONG)&LVORemTask,
  171.                                                 (ULONG (*)())NEWRemTask);
  172.     muBase->OLDLoadSeg = SetFunction((struct Library *)DOSBase,
  173.                                                           (LONG)&LVOLoadSeg,
  174.                                                           (ULONG (*)())NEWLoadSeg);
  175.     muBase->OLDNewLoadSeg = SetFunction((struct Library *)DOSBase,
  176.                                                           (LONG)&LVONewLoadSeg,
  177.                                                           (ULONG (*)())NEWNewLoadSeg);
  178.     muBase->OLDUnLoadSeg = SetFunction((struct Library *)DOSBase,
  179.                                                           (LONG)&LVOUnLoadSeg,
  180.                                                           (ULONG (*)())NEWUnLoadSeg);
  181.     muBase->OLDInternalLoadSeg = SetFunction((struct Library *)DOSBase,
  182.                                                           (LONG)&LVOInternalLoadSeg,
  183.                                                           (ULONG (*)())NEWInternalLoadSeg);
  184.     muBase->OLDInternalUnLoadSeg = SetFunction((struct Library *)DOSBase,
  185.                                                              (LONG)&LVOInternalUnLoadSeg,
  186.                                                              (ULONG (*)())NEWInternalUnLoadSeg);
  187.     muBase->OLDCreateProc = SetFunction((struct Library *)DOSBase,
  188.                                                     (LONG)&LVOCreateProc,
  189.                                                     (ULONG (*)())NEWCreateProc);
  190.     muBase->OLDCreateNewProc = SetFunction((struct Library *)DOSBase,
  191.                                                         (LONG)&LVOCreateNewProc,
  192.                                                         (ULONG (*)())NEWCreateNewProc);
  193.     muBase->OLDRunCommand = SetFunction((struct Library *)DOSBase,
  194.                                                     (LONG)&LVORunCommand,
  195.                                                     (ULONG (*)())NEWRunCommand);
  196.     muBase->OLDSetProtection = SetFunction((struct Library *)DOSBase,
  197.                                                         (LONG)&LVOSetProtection,
  198.                                                         (ULONG (*)())NEWSetProtection);
  199.  
  200.     Permit();
  201.  
  202.         /*
  203.          *        Activate the Server
  204.          */
  205.  
  206.     if (!StartServer())
  207.         return(FALSE);
  208.  
  209.     return(TRUE);
  210. }
  211.  
  212.  
  213.     /*
  214.      *        Clean Up
  215.      */
  216.  
  217. BOOL CleanUp(void)
  218. {
  219.         /*
  220.          *        Kill the Server
  221.          */
  222.  
  223.     if (!KillServer())
  224.         return(FALSE);
  225.  
  226.         /*
  227.          *        Restore exec.library functions:
  228.          *
  229.          *            AddTask()
  230.          *            RemTask()
  231.          *
  232.          *        Restore dos.library functions:
  233.          *
  234.          *            LoadSeg()
  235.          *            NewLoadSeg()
  236.          *            UnLoadSeg()
  237.          *            InternalLoadSeg()
  238.          *            InternalUnLoadSeg()
  239.          *            CreateProc()
  240.          *            CreateNewProc()
  241.          *            RunCommand()
  242.          *            SetProtection()
  243.          *
  244.          *        WARNING:    This routine does NOT check for a pending patch
  245.          *                    by someone else!!
  246.          */
  247.  
  248.     if (muBase->OLDAddTask) {
  249.         SetFunction((struct Library *)SysBase, (LONG)&LVOAddTask,
  250.                         (ULONG (*)())muBase->OLDAddTask);
  251.         muBase->OLDAddTask = NULL;
  252.     }
  253.     if (muBase->OLDRemTask) {
  254.         SetFunction((struct Library *)SysBase, (LONG)&LVORemTask,
  255.                         (ULONG (*)())muBase->OLDRemTask);
  256.         muBase->OLDRemTask = NULL;
  257.     }
  258.     if (muBase->OLDLoadSeg) {
  259.         SetFunction((struct Library *)DOSBase, (LONG)&LVOLoadSeg,
  260.                         (ULONG (*)())muBase->OLDLoadSeg);
  261.         muBase->OLDLoadSeg = NULL;
  262.     }
  263.     if (muBase->OLDNewLoadSeg) {
  264.         SetFunction((struct Library *)DOSBase, (LONG)&LVONewLoadSeg,
  265.                         (ULONG (*)())muBase->OLDNewLoadSeg);
  266.         muBase->OLDNewLoadSeg = NULL;
  267.     }
  268.     if (muBase->OLDUnLoadSeg) {
  269.         SetFunction((struct Library *)DOSBase, (LONG)&LVOUnLoadSeg,
  270.                         (ULONG (*)())muBase->OLDUnLoadSeg);
  271.         muBase->OLDUnLoadSeg = NULL;
  272.     }
  273.     if (muBase->OLDInternalLoadSeg) {
  274.         SetFunction((struct Library *)DOSBase, (LONG)&LVOInternalLoadSeg,
  275.                         (ULONG (*)())muBase->OLDInternalLoadSeg);
  276.         muBase->OLDInternalLoadSeg = NULL;
  277.     }
  278.     if (muBase->OLDInternalUnLoadSeg) {
  279.         SetFunction((struct Library *)DOSBase, (LONG)&LVOInternalUnLoadSeg,
  280.                         (ULONG (*)())muBase->OLDInternalUnLoadSeg);
  281.         muBase->OLDInternalUnLoadSeg = NULL;
  282.     }
  283.     if (muBase->OLDCreateProc) {
  284.         SetFunction((struct Library *)DOSBase, (LONG)&LVOCreateProc,
  285.                         (ULONG (*)())muBase->OLDCreateProc);
  286.         muBase->OLDCreateProc = NULL;
  287.     }
  288.     if (muBase->OLDCreateNewProc) {
  289.         SetFunction((struct Library *)DOSBase, (LONG)&LVOCreateNewProc,
  290.                         (ULONG (*)())muBase->OLDCreateNewProc);
  291.         muBase->OLDCreateNewProc = NULL;
  292.     }
  293.     if (muBase->OLDRunCommand) {
  294.         SetFunction((struct Library *)DOSBase, (LONG)&LVORunCommand,
  295.                         (ULONG (*)())muBase->OLDRunCommand);
  296.         muBase->OLDRunCommand = NULL;
  297.     }
  298.     if (muBase->OLDSetProtection) {
  299.         SetFunction((struct Library *)DOSBase, (LONG)&LVOSetProtection,
  300.                         (ULONG (*)())muBase->OLDSetProtection);
  301.         muBase->OLDSetProtection = NULL;
  302.     }
  303.  
  304.     RemAllTaskNodes();
  305.  
  306.     CleanUpMemory();
  307.  
  308.     if (ReqToolsBase)
  309.         CloseLibrary((struct Library *)ReqToolsBase);
  310.     if (UtilityBase)
  311.         CloseLibrary(UtilityBase);
  312.     if (IntuitionBase)
  313.         CloseLibrary((struct Library *)IntuitionBase);
  314.     if (DOSBase)
  315.         CloseLibrary((struct Library *)DOSBase);
  316.  
  317.     return(TRUE);
  318. }
  319.  
  320.  
  321.     /*
  322.      *        Entry for Obsolete Library Functions
  323.      */
  324.  
  325. ULONG __asm muOBSOLETE(void)
  326. {
  327.     return(NULL);
  328. }
  329.  
  330.  
  331.     /*
  332.      *        Make a Rendez-Vous with the MultiUserFileSystem
  333.      *
  334.      *        Private Library Function
  335.      */
  336.  
  337. BOOL __asm __saveds muFSRendezVous(register __a6 struct muBase *muBase)
  338. {
  339.     BOOL res = FALSE;
  340.  
  341.     Forbid();
  342.     if (muBase->Server && muBase->ConsistencySig) {
  343.         Signal(muBase->Server, 1<<muBase->ConsistencySig);
  344.         res = TRUE;
  345.     }
  346.     Permit();
  347.     return(res);
  348. }
  349.  
  350.  
  351.     /*
  352.      *        Get a Shared Lock on the Directory of the Password File
  353.      *
  354.      *        Public Library Function
  355.      */
  356.  
  357. BPTR __asm __saveds muGetPasswdDirLock(void)
  358. {
  359.     return((BPTR)SendServerPacket(muSAction_PasswdDirLock, NULL, NULL, NULL,
  360.                                             NULL));
  361. }
  362.  
  363.  
  364.     /*
  365.      *        Get a Shared Lock on the Directory of the Configuration File
  366.      *
  367.      *        Public Library Function
  368.      */
  369.  
  370. BPTR __asm __saveds muGetConfigDirLock(void)
  371. {
  372.     return((BPTR)SendServerPacket(muSAction_ConfigDirLock, NULL, NULL, NULL,
  373.                                             NULL));
  374. }
  375.  
  376.  
  377.     /*
  378.      *        Interprete a Tag List
  379.      */
  380.  
  381. BOOL InterpreteTagList(struct TagItem *taglist, struct muTags *tags)
  382. {
  383.     struct TagItem *tstate = taglist;
  384.     struct TagItem *tag;
  385.     struct muExtOwner *xuser;
  386.     ULONG user;
  387.     BOOL res = TRUE;
  388.  
  389.         /*
  390.          *        Fill in the default values
  391.          */
  392.  
  393.     tags->Input = Input();
  394.     tags->Output = Output();
  395.     tags->PubScrName = NULL;
  396.     tags->Task = NULL;
  397.     tags->UserID = NULL;
  398.     tags->Password = NULL;
  399.     tags->DefProtection = DEFPROTECTION;
  400.     tags->Graphical = FALSE;
  401.     tags->Own = FALSE;
  402.     tags->Global = FALSE;
  403.     tags->Quiet = FALSE;
  404.     tags->All = FALSE;
  405.     tags->NoLog = FALSE;
  406.  
  407.         /*
  408.          *        Change them according to the tags
  409.          */
  410.  
  411.     if (taglist)
  412.         while (tag = NextTagItem(&tstate))
  413.             switch (tag->ti_Tag) {
  414.                 case muT_Input:
  415.                     tags->Input = (BPTR)tag->ti_Data;
  416.                     break;
  417.  
  418.                 case muT_Output:
  419.                     tags->Output = (BPTR)tag->ti_Data;
  420.                     break;
  421.  
  422.                 case muT_PubScrName:
  423.                     tags->PubScrName = (STRPTR)tag->ti_Data;
  424.                     break;
  425.  
  426.                 case muT_Task:
  427.                     tags->Task = (struct Task *)tag->ti_Data;
  428.                     break;
  429.  
  430.                 case muT_UserID:
  431.                     tags->UserID = (STRPTR)tag->ti_Data;
  432.                     break;
  433.  
  434.                 case muT_Password:
  435.                     tags->Password = (STRPTR)tag->ti_Data;
  436.                     break;
  437.  
  438.                 case muT_DefProtection:
  439.                     tags->DefProtection = (ULONG)tag->ti_Data;
  440.                     break;
  441.  
  442.                 case muT_Graphical:
  443.                     tags->Graphical = (BOOL)tag->ti_Data;
  444.                     break;
  445.  
  446.                 case muT_Own:
  447.                     tags->Own = (BOOL)tag->ti_Data;
  448.                     break;
  449.  
  450.                 case muT_Global:
  451.                     tags->Global = (BOOL)tag->ti_Data;
  452.                     break;
  453.  
  454.                 case muT_Quiet:
  455.                     tags->Quiet = (BOOL)tag->ti_Data;
  456.                     break;
  457.  
  458.                 case muT_All:
  459.                     tags->All = (BOOL)tag->ti_Data;
  460.                     break;
  461.  
  462.                 case muT_NoLog:
  463.                     tags->NoLog = (BOOL)tag->ti_Data;
  464.                     break;
  465.             }
  466.  
  467.     if (!tags->Task)
  468.         tags->Task = SysBase->ThisTask;
  469.     else if (tags->Task != SysBase->ThisTask) {
  470.         xuser = GetTaskExtOwner(SysBase->ThisTask);
  471.         user = GetTaskOwner(tags->Task);
  472.         if (!(muGetRelationshipA(xuser, user, NULL) & muRelF_UID_MATCH))
  473.             res = FALSE;
  474.         muFreeExtOwner(xuser);
  475.     }
  476.     if (tags->NoLog) {
  477.         xuser = GetTaskExtOwner(SysBase->ThisTask);
  478.         if (!muGetRelationshipA(xuser, NULL, NULL) & muRelF_ROOT_UID)
  479.             tags->NoLog = FALSE;
  480.         muFreeExtOwner(xuser);
  481.     }
  482.     if (tags->Graphical &&
  483.          (((struct Process *)SysBase->ThisTask)->pr_WindowPtr == (APTR)-1))
  484.         tags->Graphical = FALSE;
  485.     return(res);
  486. }
  487.  
  488.  
  489.     /*
  490.      *        Post a warning
  491.      */
  492.  
  493.  
  494. void Warn(STRPTR msg, APTR argarray)
  495. {
  496.     struct rtHandlerInfo *hinfo;
  497.     ULONG sigs, timersig, ret;
  498.     struct MsgPort *timerport;
  499.     struct timerequest *timerequest;
  500.  
  501.     if (timerport = CreateMsgPort()) {
  502.         if (timerequest = CreateIORequest(timerport,
  503.                                                      sizeof(struct timerequest))) {
  504.             if (!OpenDevice(TIMERNAME, UNIT_VBLANK,
  505.                                  (struct IORequest *)timerequest, 0)) {
  506.                 if (rtEZRequestTags(msg, "Resume", NULL, argarray,
  507.                                           RTEZ_ReqTitle, "MultiUser Warning",
  508.                                           RTEZ_Flags, EZREQF_CENTERTEXT,
  509.                                           RT_ReqPos, REQPOS_CENTERSCR,
  510.                                           RT_ReqHandler, &hinfo,
  511.                                           TAG_DONE) == CALL_HANDLER) {
  512.                     timerequest->tr_node.io_Command = TR_ADDREQUEST;
  513.                     timerequest->tr_time.tv_secs = 10;
  514.                     timerequest->tr_time.tv_micro = 0;
  515.                     SendIO((struct IORequest *)timerequest);
  516.                     timersig = 1<<timerport->mp_SigBit;
  517.                     do {
  518.                         if (!hinfo->DoNotWait)
  519.                             sigs = Wait(hinfo->WaitMask | timersig);
  520.                         if (sigs & timersig)
  521.                             ret = rtReqHandler(hinfo, sigs,
  522.                                                      RTRH_EndRequest, TRUE, TAG_END);
  523.                         else
  524.                             ret = rtReqHandler(hinfo, sigs, TAG_END);
  525.                     } while (ret == CALL_HANDLER);
  526.                     AbortIO((struct IORequest *)timerequest);
  527.                     WaitIO((struct IORequest *)timerequest);
  528.                 }
  529.                 CloseDevice((struct IORequest*)timerequest);
  530.             }
  531.             DeleteIORequest(timerequest);
  532.         }
  533.         DeleteMsgPort(timerport);
  534.     }
  535. }
  536.  
  537.  
  538.     /*
  539.      *        Painless dead :-)
  540.      */
  541.  
  542. void Die(STRPTR msg, ULONG code)
  543. {
  544.     if (code)
  545.         Alert(code);
  546.     else {
  547.         static UBYTE string[] = {
  548.             0, 236, 19, 'M', 'u', 'l', 't', 'i', 'U', 's', 'e', 'r', ' ',
  549.                             'F', 'a', 't', 'a', 'l', ' ',
  550.                             'E', 'r', 'r', 'o', 'r', 0, 1,
  551.             0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  552.                          0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  553.                          0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  554.                          0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
  555.         };
  556.         int xpos;
  557.  
  558.         xpos = 320-4*strlen(msg);
  559.         string[26] = xpos>>8;
  560.         string[27] = xpos & 0xff;
  561.         strncpy(&string[29], msg, 78);
  562.         DisplayBeep(NULL);
  563.         Delay(20);
  564.         DisplayAlert(RECOVERY_ALERT, string, 51);
  565.     }
  566.  
  567.     for (;;)
  568.         Wait(NULL);
  569. }
  570.  
  571.  
  572.     /*
  573.      *        Encrypt a Password
  574.      */
  575.  
  576. STRPTR Encrypt(STRPTR buffer, STRPTR pwd, STRPTR userid)
  577. {
  578.     if (strlen(pwd))
  579.         return(ACrypt(buffer, pwd, userid));
  580.     else
  581.         return(memset(buffer, '\0', 12));
  582. }
  583.