Minor changes.
[egate.git] / kernel / monitor.c
index 43249b0..d557979 100644 (file)
  * Europagate, 1995
  *
  * $Log: monitor.c,v $
- * Revision 1.8  1995/05/16 09:40:42  adam
+ * Revision 1.15  1995/07/11 11:49:12  adam
+ * LINE_MAX renamed to STR_LINE_MAX.
+ *
+ * Revision 1.14  1995/05/23  08:12:59  adam
+ * Minor changes.
+ *
+ * Revision 1.13  1995/05/22  11:42:48  adam
+ * Minor changes on dtbsun.
+ *
+ * Revision 1.12  1995/05/19  14:51:06  adam
+ * Bug fix: stopped kernels sometimes got IPC messages from the monitor.
+ *
+ * Revision 1.11  1995/05/19  13:26:00  adam
+ * Bug fixes. Better command line options.
+ *
+ * Revision 1.10  1995/05/18  12:03:09  adam
+ * Bug fixes and minor improvements.
+ *
+ * Revision 1.9  1995/05/17  10:51:32  adam
+ * Added a few more error checks to the show command.
+ *
+ * Revision 1.8  1995/05/16  09:40:42  adam
  * LICENSE. Setting of CCL token names (and/or/not/set) in read_kernel_res.
  *
  * Revision 1.7  1995/05/03  12:18:46  adam
 #include <strqueue.h>
 #include <lgets.h>
 
-#define LINE_MAX 1024
+#define STR_LINE_MAX 1024
 
 #define MONITOR_FIFO_S "fifo.s.m"
 #define MONITOR_FIFO_C "fifo.c.m"
@@ -134,6 +155,7 @@ static void reread_resources (void)
 
 struct ke_info {
     int id;                     /* email user-id */
+    int stopped;                /* stop flag */
     pid_t pid;                  /* pid of email kernel child */
     GIP gip;                    /* fifo information */
     struct str_queue *queue;    /* message queue */
@@ -161,6 +183,7 @@ struct ke_info *ke_info_add (int id)
     (*kip)->id = id;
     (*kip)->gip = NULL;
     (*kip)->queue = NULL;
+    (*kip)->stopped = 0;
     return *kip;
 }
 
@@ -352,7 +375,10 @@ static int deliver (int argc, char **argv, int id, struct str_queue *queue,
     }
     index = 0;                         /* transfer. may be interrupted */
     while ((msg = str_queue_get (queue, index++)))
+    {
+        gw_log (GW_LOG_DEBUG, module, "deliver: %s", msg);
         gip_wline (*gip, msg);
+    }
     signal (SIGPIPE, oldsig);
     return pass;                       /* successful transfer */
 }
@@ -365,16 +391,20 @@ static int deliver (int argc, char **argv, int id, struct str_queue *queue,
 static void monitor_events (int argc, char **argv)
 {
     GIP gip_m;
-    int r, gip_m_fd;
+    int r, gip_m_fd, too_many;
     char line_buf[1024];
     fd_set set_r;
     char command[128], *cp;
 
+    mknod (MONITOR_FIFO_C, S_IFIFO|0666, 0);
+    open (MONITOR_FIFO_C, O_RDONLY|O_NONBLOCK);
     gip_m = gips_initialize (MONITOR_FIFO_S);
-    r = gips_open (gip_m, MONITOR_FIFO_C);
+    r = gips_open (gip_m, MONITOR_FIFO_C, 0);
     gip_m_fd = gip_infileno (gip_m);
+#if 1
     open (MONITOR_FIFO_S, O_WRONLY);
-
+#endif
+    gw_log (GW_LOG_DEBUG, module, "Starting event loop");
     while (1)
     {
         int fd_max;
@@ -403,17 +433,50 @@ static void monitor_events (int argc, char **argv)
                 exit (0);
             }
             /* deliver any unsent messages to Email kernels */
+            too_many = 0;
             for (ki = ke_info_list; ki; ki = ki->next)
             {
-                if (!ki->queue)
+                if (!ki->queue || ki->stopped)
                     continue;
                 gw_log (GW_LOG_DEBUG, module, "Transfer mail to %d", ki->id);
                 r = deliver (argc, argv, ki->id, ki->queue, &ki->gip, &ki->pid,
                              no_process >= max_process);
                 if (r == 2)             /* new child was spawned? */
+                {
                     ++no_process;
+                    gw_log (GW_LOG_DEBUG, module, "Start of %d", ki->id);
+                }
                 if (r == 1 || r == 2)   /* transfer at all? */
                     str_queue_rm (&ki->queue);
+                if (r == 0)             /* too many pending? */
+                    too_many++;
+            }
+            if (too_many)
+            {
+                gw_log (GW_LOG_DEBUG, module, "%d too many pending",
+                        too_many);
+                for (ki = ke_info_list; ki; ki = ki->next)
+                {
+                    if (!ki->queue && ki->pid != -1 && !ki->stopped)
+                    {
+                        if (!(ki->queue = str_queue_mk ()))
+                        {
+                            gw_log (GW_LOG_FATAL|GW_LOG_ERRNO, module,
+                                    "str_queue_mk");
+                            exit (1);
+                        }
+                        str_queue_enq (ki->queue, "stop\n");
+                        str_queue_enq (ki->queue, "\001");
+                        r = deliver (argc, argv, ki->id, ki->queue, &ki->gip,
+                                     &ki->pid, 1);
+                        if (r != 1)
+                            gw_log (GW_LOG_DEBUG, module, 
+                                    "Stop not sent: %d", r);
+                        str_queue_rm (&ki->queue);
+                        ki->stopped = 1;
+                        break;
+                    }
+                }
             }
             FD_ZERO (&set_r);
             FD_SET (gip_m_fd, &set_r);
@@ -431,6 +494,7 @@ static void monitor_events (int argc, char **argv)
                         gipc_close (ki->gip);
                         gipc_destroy (ki->gip);
                         ki->gip = NULL;
+                        ki->stopped = 0;
                     }
                     else if ((fd = gip_infileno (ki->gip)) != -1)
                     {                    /* read select on child FIFO */
@@ -475,6 +539,7 @@ static void monitor_events (int argc, char **argv)
                         gipc_close (ki->gip);
                         gipc_destroy (ki->gip);
                         ki->gip = NULL;
+                        ki->stopped = 0;
                     }
                 }
            }
@@ -531,20 +596,44 @@ int main (int argc, char **argv)
     {
         if (argv[argno][0] == '-')
         {
+            if (argv[argno][1] == '-')
+                break;
             switch (argv[argno][1])
             {
+            case 'h':
             case 'H':
-                fprintf (stderr, "monitor [option..] [resource]\n");
-                fprintf (stderr, "If no resource file is given");
+                fprintf (stderr, "monitor [options] [resourceFile]"
+                         " -- [kernelOptions]\n");
+                fprintf (stderr, "If no resource file is specified");
                 fprintf (stderr, " default.res is used\n");
-                fprintf (stderr, "Options are transferred to kernel\n");
+                fprintf (stderr, "Options:\n");
+                fprintf (stderr, " -l log  Set Log file\n");
+                fprintf (stderr, " -d      Enable debugging log\n");
+                fprintf (stderr, " -D      Enable more debugging log\n");
+                fprintf (stderr, " --      Precedes kernel options\n");
+                fprintf (stderr, "Kernel options are transferred to kernel\n");
                 exit (1);
+            case 'l':
+                if (argv[argno][2])
+                    gw_log_file (GW_LOG_ALL, argv[argno]+2);
+                else if (++argno < argc)
+                    gw_log_file (GW_LOG_ALL, argv[argno]);
+                else
+                {
+                    fprintf (stderr, "%s: missing log filename\n", *argv);
+                    exit (1);
+                }
+                break;
             case 'd':
                 gw_log_level (GW_LOG_ALL & ~RES_DEBUG);
                 break;
             case 'D':
                 gw_log_level (GW_LOG_ALL);
                 break;
+            default:
+                fprintf (stderr, "%s: unknown option `%s'; use -H for help\n",
+                         *argv, argv[argno]);
+                exit (1);
             }
         }
         else
@@ -555,9 +644,6 @@ int main (int argc, char **argv)
     signal (SIGHUP, catch_hup);
     signal (SIGTERM, catch_term);
     signal (SIGINT, catch_int);
-#if 0
-    gw_log_file (GW_LOG_ALL, "monitor.log");
-#endif
-    monitor_events (argc, argv);
+    monitor_events (argc-argno, argv+argno);
     exit (0);
 }