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