home *** CD-ROM | disk | FTP | other *** search
/ ARM Club 1 / ARM_CLUB_CD.iso / contents / apps / desktop / t / utils / !Logger_C_NETLOG < prev    next >
Encoding:
Text File  |  1993-05-31  |  10.4 KB  |  460 lines

  1. /*
  2.  *
  3.  *      Title     : NetLog.C
  4.  *      System    : Any */
  5. #define Version     "2.0"
  6. /*      Copyright : John H. Winters
  7.  *      Date      : 23rd September, 1992
  8.  *      Author    : John H. Winters
  9.  *
  10.  *      Function  : Defines the netlog routines.
  11.  *
  12.  *      Modification history.
  13.  *
  14.  *      Version   : 1.1
  15.  *      Date      : 10th January, 1993
  16.  *      Author    : John H. Winters
  17.  *      Changes   : Adapted to new SDF i/f.
  18.  *
  19.  *      Version   : 2.0
  20.  *      Date      : 31st May, 1993
  21.  *      Author    : John H. Winters
  22.  *      Changes   : Updated for RISC OS 3.1 and new WIMP_ReportError
  23.  *
  24.  *      Version   :
  25.  *      Date      :
  26.  *      Author    :
  27.  *      Changes   :
  28.  *
  29.  */
  30.  
  31. #include <stdio.h>
  32. #include <stdlib.h>
  33. #include <string.h>
  34.  
  35. #if defined (OS2)
  36. #define INCL_DOSQUEUES
  37. #define INCL_VIO
  38. #include <os2.h>
  39. #endif
  40.  
  41. #include "global.h"
  42. #if defined (ARTHUR)
  43. #include "kernel.h"
  44. #include "wimplib.h"
  45. #include "winapp.h"
  46. #endif
  47. #include "sdf.h"
  48. #include "logging.h"
  49. #include "netlog.h"
  50. #include "internal.h"
  51.  
  52. /*
  53.  *============================================================================
  54.  *
  55.  *  Hash defines.
  56.  *
  57.  *============================================================================
  58.  */
  59.  
  60. #define MESSAGEACTION "Logger$MessNo"
  61.  
  62. /*
  63.  *============================================================================
  64.  *
  65.  *  Local data.
  66.  *
  67.  *============================================================================
  68.  */
  69.  
  70. #if defined (OS2)
  71. static USHORT LoggerId ;
  72. static uint   LogQueueOpen = FALSE ;
  73. static HQUEUE QueueHandle ;
  74. #endif
  75.  
  76. #if defined (ARTHUR)
  77. static uint   MessageAction = 0 ;
  78. #endif
  79.  
  80. static u8 ProcessName [LOG_MAX_TASKNAME + 1] ;
  81.  
  82. /*
  83.  *============================================================================
  84.  *
  85.  *  Forward declarations.
  86.  *
  87.  *============================================================================
  88.  */
  89.  
  90. #if defined (OS2)
  91. static void CloseLogQueue (void) ;
  92. #endif
  93.  
  94. #if defined (ARTHUR)
  95. static uint FallBack (
  96.     t_LOG_Severity  severity,
  97.     const u8       *message,
  98.     const u8       *timestamp) ;
  99. #endif
  100.  
  101. static uint MessageHandler (
  102.     t_LOG_Severity  severity,
  103.     const u8       *message,
  104.     const u8       *timestamp) ;
  105.  
  106. #if defined (OS2)
  107. static void OpenLogQueue (void) ;
  108.  
  109. static void SendText (
  110.     t_LOG_Severity  severity,
  111.     const u8       *message,
  112.     const u8       *timestamp) ;
  113. #endif
  114.  
  115. /*
  116.  *============================================================================
  117.  *
  118.  *  Externally visible routines.
  119.  *
  120.  *============================================================================
  121.  */
  122.  
  123. uint NL_Init (
  124.     const char *proc_name)
  125.  
  126. /*
  127.  *  Function :
  128.  *                  Registers our routine as a message handler.
  129.  *
  130.  *  Parameters :
  131.  *                  None.
  132.  *
  133.  *  Returns :
  134.  *                  TRUE if we succeed, FALSE if we fail.
  135.  *
  136.  */
  137.  
  138. {
  139.     uint              length ;
  140.     t_LOG_HandlerMask mask ;
  141.  
  142.     length = strlen (proc_name) ;
  143.     if (length > LOG_MAX_TASKNAME)
  144.     {
  145.         length = LOG_MAX_TASKNAME ;
  146.     }
  147.     memset (ProcessName, ' ', LOG_MAX_TASKNAME) ;
  148.     memcpy (ProcessName, proc_name, length) ;
  149.     ProcessName [LOG_MAX_TASKNAME] = '\0' ;
  150.     mask.value             = 0 ;
  151.     mask.b.LHM_Debug       = TRUE ;
  152.     mask.b.LHM_Info        = TRUE ;
  153.     mask.b.LHM_Warning     = TRUE ;
  154.     mask.b.LHM_Error       = TRUE ;
  155.     mask.b.LHM_SevereError = TRUE ;
  156.     return (LOG_AddHandler (mask, MessageHandler)
  157. #if defined (ARTHUR)
  158.             && LOG_AddHandler (mask, FallBack)
  159. #endif
  160. ) ;
  161. }
  162.  
  163. /*
  164.  *============================================================================
  165.  *
  166.  *  Local routines.
  167.  *
  168.  *============================================================================
  169.  */
  170.  
  171. #if defined (OS2)
  172. static void CloseLogQueue (void)
  173.  
  174. /*
  175.  *  Function :
  176.  *                  Close the queue to the logger process.
  177.  *
  178.  *  Parameters :
  179.  *                  None.
  180.  *
  181.  *  Returns :
  182.  *                  None, but may alter log_queue_open.
  183.  *
  184.  */
  185.  
  186. {
  187.     if (LogQueueOpen)
  188.     {
  189.         DosCloseQueue (QueueHandle) ;
  190.         LogQueueOpen = FALSE ;
  191.     }
  192. }
  193. #endif
  194.  
  195.  
  196. #if defined (ARTHUR)
  197. static uint FallBack (
  198.     t_LOG_Severity  severity,
  199.     const u8       *message,
  200.     const u8       *timestamp)
  201.  
  202. /*
  203.  *  Function :
  204.  *                  Fall back handler for when the main one fails.
  205.  *
  206.  *  Parameters :
  207.  *                  severity    Severity of the relevant message.
  208.  *                  message     Message to log.
  209.  *                  timestamp   Timestamp for the message.
  210.  *
  211.  *  Returns :
  212.  *                  TRUE
  213.  *
  214.  */
  215.  
  216. {
  217.     _kernel_oserror error ;
  218.     t_error_flags   flags ;
  219.     unsigned int    result ;
  220.  
  221.     severity  = severity ;
  222.     timestamp = timestamp ;
  223.     error.errnum = 0 ;
  224.     strcpy (error.errmess, message) ;
  225.     flags.value = 0 ;
  226.     flags.m.ok  = TRUE ;
  227.     WIMP_ReportError (&error, flags, ProcessName, &result) ;
  228.     return (TRUE) ;
  229. }
  230. #endif
  231.  
  232.  
  233. static uint MessageHandler (
  234.     t_LOG_Severity  severity,
  235.     const u8       *message,
  236.     const u8       *timestamp)
  237.  
  238. /*
  239.  *  Function :
  240.  *                  Handles messages and sends them off to the log process.
  241.  *                  N.B.  The logging module guarantees that this routine
  242.  *                  will not be pre-emptively or recursively re-entered.
  243.  *
  244.  *  Parameters :
  245.  *                  severity    Message severity.
  246.  *                  message     Message text.
  247.  *                  timestamp   Textual time stamp.
  248.  *
  249.  *  Returns :
  250.  *                  TRUE if we handled it, FALSE otherwise.
  251.  *
  252.  */
  253.  
  254. {
  255. #if defined (ARTHUR)
  256.     u8              *body ;
  257.     t_destinee       destinee ;
  258.     t_NL_Header      header ;
  259.     t_message_block  item ;
  260.     uint             length ;
  261. #endif
  262.     uint             result ;
  263. #if !defined (OS2)
  264.     const u8        *string ;
  265. #endif
  266.  
  267.     result = FALSE ;
  268. #if defined (OS2)
  269.     if (!LogQueueOpen)
  270.     {
  271.         OpenLogQueue () ;
  272.     }
  273.     if (LogQueueOpen)
  274.     {
  275.         SendText (severity, message, timestamp) ;
  276.         if (LogQueueOpen)
  277.         {
  278.             result = TRUE ;
  279.         }
  280.     }
  281. #else
  282.     /*
  283.      *  Do we know what message number to use?
  284.      */
  285.     if (MessageAction == 0)
  286.     {
  287.         string = getenv (MESSAGEACTION) ;
  288.         if (string != NULL)
  289.         {
  290.             MessageAction = atoi (string) ;
  291.         }
  292.     }
  293.     if (MessageAction != 0)
  294.     {
  295.         /*
  296.          *  Let's try to send it.
  297.          */
  298.         length = strlen (message) ;
  299.         if (length > 236 - sizeof (t_NL_Header))
  300.         {
  301.             length = 236 - sizeof (t_NL_Header) ;
  302.         }
  303.         while ((length > 0) &&
  304.                (message [length - 1] == '\n'))
  305.         {
  306.             length-- ;
  307.         }
  308.         header.ident          = LOG_IDENT ;
  309.         header.format_version = FORMAT_VERSION ;
  310.         SDF_Putu16 ((u16) length,
  311.                     header.text_length) ;
  312.         header.severity       = severity ;
  313.         memcpy (header.task_name, ProcessName, LOG_MAX_TASKNAME) ;
  314.         memcpy (header.timestamp,
  315.                 timestamp,
  316.                 LOG_TIMESTAMP_LEN) ;
  317.         memcpy (item.data.bytes,
  318.                 &header,
  319.                 sizeof (t_NL_Header)) ;
  320.         body = item.data.bytes + sizeof (t_NL_Header) ;
  321.         memcpy (body,
  322.                 message,
  323.                 length) ;
  324.         while ((((length + 3) / 4) * 4) != length)
  325.         {
  326.             length++ ;
  327.         }
  328.         item.size  = sizeof (t_message_header) + sizeof (t_NL_Header) + length ;
  329.         item.sender   = 0 ;
  330.         item.my_ref   = 0 ;
  331.         item.your_ref = 0 ;
  332.         item.action   = MessageAction ;
  333.         destinee.value = 0 ;
  334.         if (LOG_OSError (WIMP_SendMessage (ET_UserMessage,
  335.                                            &item,
  336.                                            destinee,
  337.                                            0)) == NULL)
  338.         {
  339.             result = TRUE ;
  340.         }
  341.     }
  342. #endif
  343.     return (result) ;
  344. }
  345.  
  346.  
  347. #if defined (OS2)
  348. static void OpenLogQueue (void)
  349.  
  350. /*
  351.  *  Function :
  352.  *                  Attempts to open the queue to a logger process.
  353.  *
  354.  *  Parameters :
  355.  *                  None.
  356.  *
  357.  *  Returns :
  358.  *                  None, but updates the value of log_queue_open
  359.  *                  depending on the result.
  360.  *
  361.  */
  362.  
  363. {
  364.     if (!LogQueueOpen)
  365.     {
  366.         if (DosOpenQueue (&LoggerId,
  367.                           &QueueHandle,
  368.                           QUEUE_NAME) == 0)
  369.         {
  370.             LogQueueOpen = TRUE ;
  371.         }
  372.     }
  373. }
  374.  
  375.  
  376. static void SendText (
  377.     t_LOG_Severity  severity,
  378.     const u8       *message,
  379.     const u8       *timestamp)
  380.  
  381. /*
  382.  *  Function :
  383.  *                  Send a text message to the log process.
  384.  *
  385.  *  Parameters :
  386.  *                  severity    Severity of the message.
  387.  *                  message     Text of the message.
  388.  *                  timestamp   Textual time stamp.
  389.  *
  390.  *  Returns :
  391.  *
  392.  */
  393.  
  394. {
  395.     u8          *body ;
  396.     t_NL_Header *buffer ;
  397.     SEL          handle ;
  398.     SEL          his_handle ;
  399.     u16          size ;
  400.  
  401.     size = (U16) strlen (message) ;
  402.     /*
  403.      *  Need to allocate a shared segment to pass the data in.
  404.      */
  405.     if (DosAllocSeg (size + sizeof (t_NL_Header),
  406.                      &handle,
  407.                      SEG_GIVEABLE) == 0)
  408.     {
  409.         buffer = MAKEP (handle, 0) ;
  410.         buffer->ident          = LOG_IDENT ;
  411.         buffer->format_version = FORMAT_VERSION ;
  412.         SDF_Putu16 (size,
  413.                     buffer->text_length) ;
  414.         buffer->severity       = (u8) severity ;
  415.         memcpy (buffer->task_name, ProcessName, LOG_MAX_TASKNAME) ;
  416.         memcpy (buffer->timestamp,
  417.                 timestamp,
  418.                 LOG_TIMESTAMP_LEN) ;
  419.         body = (u8 *) (buffer + 1) ;
  420.         memcpy (body,
  421.                 message,
  422.                 size) ;
  423.         /*
  424.          *  Give the destination process access to the segment.
  425.          */
  426.         if (DosGiveSeg (handle,
  427.                         LoggerId,
  428.                         &his_handle) == 0)
  429.         {
  430.             /*
  431.              *  Notify him about it.
  432.              */
  433.             if (DosWriteQueue (QueueHandle,
  434.                                his_handle,
  435.                                size + sizeof (t_NL_Header),
  436.                                (PBYTE) buffer,
  437.                                QUEUE_PRIORITY) != 0)
  438.             {
  439.                 LOG_Error ("LOG: Failed to write to logger's queue.\n") ;
  440.                 CloseLogQueue () ;
  441.             }
  442.         }
  443.         else
  444.         {
  445.             LOG_Error ("LOG: Failed to pass a segment to logger.\n") ;
  446.             CloseLogQueue () ;
  447.         }
  448.         /*
  449.          *  Relinquish access to the segment.
  450.          */
  451.         DosFreeSeg (handle) ;
  452.     }
  453.     else
  454.     {
  455.         LOG_Error ("LOG: Failed to allocate a shared segment.\n") ;
  456.     }
  457. }
  458. #endif
  459.  
  460.