home *** CD-ROM | disk | FTP | other *** search
/ The Best of Mecomp Multimedia 1 / Mecomp-CD.iso / amiga / tools / system / shutdown / shutdownsetup.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-03-01  |  8.1 KB  |  449 lines

  1. #include "ShutdownSetup.h"
  2.  
  3. #include "shutdownbase.h"
  4.  
  5. #include "LocaleSupport.h"
  6. #include "shutdown.h"
  7.  
  8. enum    {    ARG_POPKEY,ARG_PRIORITY,ARG_NOCX };
  9.  
  10. #define SIG_KILL    SIGBREAKF_CTRL_C
  11. #define SIG_HANDSHAKE    SIGBREAKF_CTRL_C
  12.  
  13. #define PROMPT        "K=CX_PopKey/K,P=CX_Priority/K/N,N=NoCx/S"
  14.  
  15. struct ShutdownBase
  16. {
  17.     struct Library         LibNode;
  18.  
  19.     struct SignalSemaphore     BlockLock;
  20.     struct SignalSemaphore     DevBlockLock;
  21.     struct SignalSemaphore     AccessLock;
  22.     struct SignalSemaphore     ShutdownLock;
  23.  
  24.     BYTE             Shutdown;
  25.     BYTE             DevShutdown;
  26.     BYTE             Running;
  27.     BYTE             Closing;
  28.  
  29.     struct MinList         AccessList;
  30.     struct MinList         ShutdownList;
  31.  
  32.     VOID            (*Main)();
  33.  
  34.     struct Process        *Father,
  35.                 *Child,
  36.                 *CxProcess;
  37.  
  38.     LONG             OpenCount;
  39.  
  40.     LONG             ErrorCode;
  41. };
  42.  
  43. STATIC STRPTR         VersTag = VERSTAG;
  44.  
  45. struct ExecBase        *SysBase;
  46. struct DosLibrary    *DOSBase;
  47.  
  48. struct Library        *CxBase;
  49. struct ShutdownBase    *ShutdownBase;
  50.  
  51. struct NewBroker NewBroker =
  52. {
  53.     NB_VERSION,
  54.     NULL,
  55.     NULL,
  56.     NULL,
  57.     NBU_UNIQUE,
  58.     NULL,
  59.     0,NULL,0
  60. };
  61.  
  62. CxObj            *Broker;
  63. struct MsgPort        *CxPort;
  64.  
  65. UBYTE             CxPopKey[256];
  66. LONG             CxPriority    = 0,
  67.              CxError    = 0;
  68.  
  69. LONG __saveds        Main(VOID);
  70. VOID __saveds __asm    ProcessCleanup(register __d1 BPTR SegList);
  71. struct Process *    Detach(STRPTR Name,BYTE Pri,LONG StackSize,APTR Function);
  72. CxObj * __regargs    CustomHotKey(STRPTR Code,struct MsgPort *Port,LONG ID);
  73. VOID            ShutdownCx(VOID);
  74. BYTE            SetupCx(VOID);
  75. VOID __saveds        CxServer(VOID);
  76.  
  77. LONG __saveds
  78. Main()
  79. {
  80.     struct Process        *ThisProcess;
  81.     LONG             Result = RETURN_FAIL;
  82.  
  83.     SysBase = *(struct ExecBase **)4;
  84.  
  85.     ThisProcess = (struct Process *)SysBase -> ThisTask;
  86.  
  87.     if(ThisProcess -> pr_CLI)
  88.     {
  89.         APTR OldPtr = ThisProcess -> pr_WindowPtr;
  90.  
  91.         if(DOSBase = (struct DosLibrary *)OpenLibrary("dos.library",37))
  92.         {
  93.             struct Process    *Father;
  94.             BPTR         StdOut;
  95.             struct RDArgs    *ArgsPtr;
  96.             STRPTR         Args[3] = { NULL, NULL, NULL };
  97.             BYTE             UseCx = TRUE;
  98.  
  99.             LocaleOpen("shutdown.catalog","english");
  100.  
  101.             if(ArgsPtr = ReadArgs(PROMPT,(LONG *)Args,NULL))
  102.             {
  103.                 if(Args[ARG_NOCX])
  104.                     UseCx = FALSE;
  105.  
  106.                 if(Args[ARG_POPKEY])
  107.                     strcpy(CxPopKey,Args[ARG_POPKEY]);
  108.                 else
  109.                     strcpy(CxPopKey,"lcommand rcommand tab");
  110.  
  111.                 if(Args[ARG_PRIORITY])
  112.                     CxPriority = *((LONG *)Args[ARG_PRIORITY]);
  113.  
  114.                 FreeArgs(ArgsPtr);
  115.             }
  116.             else
  117.             {
  118.                 PrintFault(IoErr(),"ShutdownSetup");
  119.  
  120.                 CloseLibrary(DOSBase);
  121.  
  122.                 return(RETURN_ERROR);
  123.             }
  124.  
  125.             Printf(GetString(MSG_HEADER_TXT),VERS);
  126.  
  127.             Father = (struct Process *)SysBase -> ThisTask;
  128.  
  129.             StdOut = Father -> pr_COS;
  130.  
  131.             if(ShutdownBase = (struct ShutdownBase *)OpenLibrary("shutdown.library",2))
  132.             {
  133.                 if(ShutdownBase -> Child)
  134.                 {
  135.                     Printf(GetString(MSG_REMOVING_TXT));
  136.  
  137.                     Flush(StdOut);
  138.  
  139.                     ShutdownBase -> Father = Father;
  140.  
  141.                     Signal(ShutdownBase -> Child,SIG_KILL);
  142.  
  143.                     Wait(SIG_HANDSHAKE);
  144.  
  145.                     if(ShutdownBase -> CxProcess)
  146.                     {
  147.                         ShutdownBase -> Father = Father;
  148.  
  149.                         Signal(ShutdownBase -> CxProcess,SIG_KILL);
  150.  
  151.                         Wait(SIG_HANDSHAKE);
  152.                     }
  153.  
  154.                     Printf(GetString(MSG_DONE_TXT));
  155.  
  156.                     Result = RETURN_OK;
  157.                 }
  158.                 else
  159.                 {
  160.                     Printf(GetString(MSG_INSTALLING_TXT));
  161.  
  162.                     Flush(StdOut);
  163.  
  164.                     ShutdownBase -> Father = Father;
  165.  
  166.                     if(CreateNewProcTags(
  167.                         NP_Entry,    ShutdownBase -> Main,
  168.                         NP_StackSize,    4000,
  169.                         NP_Name,    GetString(MSG_TASKNAME_NAME),
  170.                         NP_Priority,    5,
  171.                         NP_WindowPtr,    -1,
  172.                     TAG_DONE))
  173.                     {
  174.                         Wait(SIG_HANDSHAKE);
  175.  
  176.                         if(!ShutdownBase -> Child)
  177.                             Printf(GetString(MSG_PROCESS_CREATION_FAILED_TXT));
  178.                         else
  179.                         {
  180.                             if(UseCx)
  181.                             {
  182.                                 ShutdownBase -> Father = Father;
  183.  
  184.                                 Detach(GetString(MSG_BROKERNAME_TXT),80,4000,CxServer);
  185.  
  186.                                 Wait(SIG_HANDSHAKE);
  187.  
  188.                                 if(ShutdownBase -> CxProcess)
  189.                                 {
  190.                                     Printf(GetString(MSG_DONE_TXT));
  191.  
  192.                                     Result = RETURN_OK;
  193.                                 }
  194.                                 else
  195.                                 {
  196.                                     ShutdownBase -> Father = Father;
  197.  
  198.                                     Signal(ShutdownBase -> Child,SIG_KILL);
  199.  
  200.                                     Wait(SIG_HANDSHAKE);
  201.  
  202.                                     Printf(GetString(MSG_HOTKEYS_FAILED_TXT),CxError);
  203.                                 }
  204.                                                         }
  205.                                                         else
  206.                                                         {
  207.                                 Printf(GetString(MSG_DONE_TXT));
  208.  
  209.                                 Result = RETURN_OK;
  210.                                                         }
  211.                         }
  212.                     }
  213.                     else
  214.                         Printf(GetString(MSG_PROCESS_CREATION_FAILED_TXT));
  215.                 }
  216.             }
  217.             else
  218.                 Printf(GetString(MSG_OPENFAIL_TXT),"shutdown.library");
  219.  
  220.             LocaleClose();
  221.  
  222.             if(ShutdownBase)
  223.             {
  224.                 if(!ShutdownBase -> CxProcess)
  225.                 {
  226.                     CloseLibrary(DOSBase);
  227.  
  228.                     CloseLibrary(ShutdownBase);
  229.                 }
  230.             }
  231.             else
  232.                 CloseLibrary(DOSBase);
  233.         }
  234.  
  235.         ThisProcess -> pr_WindowPtr = OldPtr;
  236.     }
  237.     else
  238.     {
  239.         WaitPort(&ThisProcess -> pr_MsgPort);
  240.  
  241.         Forbid();
  242.  
  243.         ReplyMsg(GetMsg(&ThisProcess -> pr_MsgPort));
  244.     }
  245.  
  246.     return(Result);
  247. }
  248.  
  249. VOID __saveds __asm
  250. ProcessCleanup(register __d1 BPTR SegList)
  251. {
  252.     Forbid();
  253.  
  254.     UnLoadSeg(SegList);
  255.  
  256.     CloseLibrary(ShutdownBase);
  257.  
  258.     CloseLibrary(DOSBase);
  259. }
  260.  
  261. struct Process *
  262. Detach(STRPTR Name,BYTE Pri,LONG StackSize,APTR Function)
  263. {
  264.     struct Process            *Child;
  265.     struct CommandLineInterface    *CLI;
  266.  
  267.     CLI = (struct CommandLineInterface *)BADDR(((struct Process *)SysBase -> ThisTask) -> pr_CLI);
  268.  
  269.     if(Child = CreateNewProcTags(
  270.         NP_Name,    Name,
  271.         NP_CommandName,    Name,
  272.         NP_Priority,    Pri,
  273.         NP_StackSize,    StackSize,
  274.         NP_Entry,    Function,
  275.         NP_Cli,        TRUE,
  276.         NP_ExitCode,    ProcessCleanup,
  277.         NP_ExitData,    CLI -> cli_Module,
  278.     TAG_DONE))
  279.     {
  280.         CLI -> cli_Module = NULL;
  281.  
  282.         return(Child);
  283.     }
  284.     else
  285.         return(NULL);
  286. }
  287.  
  288. CxObj * __regargs
  289. CustomHotKey(STRPTR Code,struct MsgPort *Port,LONG ID)
  290. {
  291.     CxObj *Filter;
  292.  
  293.     if(Filter = CxFilter(Code))
  294.     {
  295.         CxObj *Sender;
  296.  
  297.         if(Sender = CxSender(Port,ID))
  298.         {
  299.             CxObj *Translator;
  300.  
  301.             AttachCxObj(Filter,Sender);
  302.  
  303.             if(Translator = CxTranslate(NULL))
  304.             {
  305.                 AttachCxObj(Filter,Translator);
  306.  
  307.                 if(!(CxError = CxObjError(Filter)))
  308.                     return(Filter);
  309.             }
  310.         }
  311.  
  312.         DeleteCxObjAll(Filter);
  313.     }
  314.  
  315.     return(NULL);
  316. }
  317.  
  318. VOID
  319. ShutdownCx()
  320. {
  321.     if(CxPort)
  322.     {
  323.         struct Message *Message;
  324.  
  325.         if(Broker)
  326.             DeleteCxObjAll(Broker);
  327.  
  328.         RemPort(CxPort);
  329.  
  330.         while(Message = GetMsg(CxPort))
  331.             ReplyMsg(Message);
  332.  
  333.         DeleteMsgPort(CxPort);
  334.  
  335.         CxPort = NULL;
  336.         Broker = NULL;
  337.     }
  338. }
  339.  
  340. BYTE
  341. SetupCx()
  342. {
  343.     ShutdownCx();
  344.  
  345.     if(CxPort = CreateMsgPort())
  346.     {
  347.         NewBroker . nb_Name    = GetString(MSG_BROKERTITLE_TXT);
  348.         NewBroker . nb_Title    = GetString(MSG_BROKERTITLE_TXT);
  349.         NewBroker . nb_Descr    = GetString(MSG_BROKERDESCRIPTION_TXT);
  350.  
  351.         CxPort -> mp_Node . ln_Name = NewBroker . nb_Name;
  352.  
  353.         AddPort(CxPort);
  354.  
  355.         NewBroker . nb_Port = CxPort;
  356.         NewBroker . nb_Pri  = CxPriority;
  357.  
  358.         if(Broker = CxBroker(&NewBroker,NULL))
  359.         {
  360.             AttachCxObj(Broker,CustomHotKey(CxPopKey,CxPort,0));
  361.  
  362.             if(!CxObjError(Broker))
  363.             {
  364.                 ActivateCxObj(Broker,TRUE);
  365.  
  366.                 return(TRUE);
  367.             }
  368.         }
  369.     }
  370.  
  371.     ShutdownCx();
  372.  
  373.     return(FALSE);
  374. }
  375.  
  376. VOID __saveds
  377. CxServer()
  378. {
  379.     if(CxBase = OpenLibrary("commodities.library",37))
  380.     {
  381.         if(SetupCx())
  382.         {
  383.             ULONG    SignalSet;
  384.             BYTE    Terminated = FALSE;
  385.  
  386.             ShutdownBase -> CxProcess = (struct Process *)SysBase -> ThisTask;
  387.  
  388.             Signal(ShutdownBase -> Father,SIG_HANDSHAKE);
  389.  
  390.             ShutdownBase -> Father = NULL;
  391.  
  392.             while(!Terminated)
  393.             {
  394.                 SignalSet = Wait(SIG_KILL | (1 << CxPort -> mp_SigBit));
  395.  
  396.                 if(SignalSet & SIG_KILL)
  397.                     Terminated = TRUE;
  398.  
  399.                 if(SignalSet & (1 << CxPort -> mp_SigBit))
  400.                 {
  401.                     ULONG     MessageType,
  402.                          MessageID;
  403.                     CxMsg    *Message;
  404.  
  405.                     while(Message = (CxMsg *)GetMsg(CxPort))
  406.                     {
  407.                         MessageType    = CxMsgID(Message);
  408.                         MessageID    = CxMsgType(Message);
  409.  
  410.                         ReplyMsg((struct Message *)Message);
  411.  
  412.                         switch(MessageID)
  413.                         {
  414.                             case CXM_IEVENT:    Shutdown(SHUTDOWN_FAST);
  415.  
  416.                             case CXM_COMMAND:    switch(MessageType)
  417.                                         {
  418.                                             case CXCMD_DISABLE:    ActivateCxObj(Broker,FALSE);
  419.                                                         break;
  420.  
  421.                                             case CXCMD_ENABLE:    ActivateCxObj(Broker,TRUE);
  422.                                                         break;
  423.  
  424.                                             case CXCMD_KILL:    Terminated = TRUE;
  425.                                                         break;
  426.  
  427.                                             default:        break;
  428.                                         }
  429.  
  430.                                         break;
  431.                         }
  432.                     }
  433.                 }
  434.             }
  435.  
  436.             ShutdownCx();
  437.         }
  438.  
  439.         CloseLibrary(CxBase);
  440.     }
  441.  
  442.     Forbid();
  443.  
  444.     ShutdownBase -> CxProcess = NULL;
  445.  
  446.     if(ShutdownBase -> Father)
  447.         Signal(ShutdownBase -> Father,SIG_HANDSHAKE);
  448. }
  449.