+static void kernel_events (struct str_queue *queue)
+{
+ char fifo_client_name[1024];
+ char fifo_server_name[1024];
+ char line_buf[1024];
+ GIP gip;
+ fd_set set_r;
+ int r, gip_fd;
+ struct timeval tv;
+ int timeout;
+ int continuation = 0;
+ int extra_fd;
+ int persist_flag;
+
+ persist_flag = gw_res_bool (info.kernel_res, "gw.persist", 0);
+ timeout = gw_res_int (info.kernel_res, "gw.timeout", 600);
+ gw_log (GW_LOG_DEBUG, KERNEL_LOG, "event loop");
+
+ sprintf (fifo_client_name, "fifo.c.%d", info.userid);
+ sprintf (fifo_server_name, "fifo.s.%d", info.userid);
+
+ gip = gips_initialize (fifo_server_name);
+ gips_open (gip, fifo_client_name);
+ gip_fd = gip_infileno (gip);
+ extra_fd = open (fifo_server_name, O_WRONLY);
+
+ while (1)
+ {
+ FD_ZERO (&set_r);
+ FD_SET (gip_fd, &set_r);
+ tv.tv_sec = timeout;
+ tv.tv_usec = 0;
+
+ gw_log (GW_LOG_DEBUG, KERNEL_LOG, "IPC select");
+ r = select (gip_fd+1, &set_r, NULL, NULL, &tv);
+ if (r == -1)
+ {
+ gw_log (GW_LOG_FATAL|GW_LOG_ERRNO, KERNEL_LOG, "select");
+ exit (1);
+ }
+ if (r == 0)
+ {
+ gw_log (GW_LOG_STAT, KERNEL_LOG, "Timeout after %d seconds",
+ timeout);
+ if (info.zass && persist_flag)
+ save_p_state (info.userid);
+ break;
+ }
+ if (FD_ISSET (gip_fd, &set_r))
+ {
+ char command[128], *cp;
+
+ if (!(lgets (command, 127, gip_fd)))
+ {
+ gw_log (GW_LOG_WARN, KERNEL_LOG, "Unexpected close");
+ break;
+ }
+ if ((cp = strchr (command, '\n')))
+ *cp = '\0';
+ gw_log (GW_LOG_STAT, KERNEL_LOG, "IPC: %s", command);
+ if (!strcmp (command, "mail"))
+ {
+ gw_log (GW_LOG_DEBUG, KERNEL_LOG, "Incoming mail");
+ while (lgets (line_buf, sizeof(line_buf)-1, gip_fd))
+ str_queue_enq (queue, line_buf);
+ urp_start (continuation, queue);
+ if (persist_flag && !continuation)
+ load_p_state (info.userid);
+ r = urp_command (queue);
+ if (r == 1) /* stop? */
+ {
+ info.zass = NULL; /* delete association */
+ *info.target = 0; /* indicate no target */
+ read_kernel_res(); /* reread resources */
+ if (persist_flag)
+ del_p_state (info.userid); /* remove persist file */
+ }
+ urp_end ();
+ while (str_queue_deq (queue, 0, 0))
+ ;
+ }
+ else if (!strcmp (command, "stop"))
+ {
+ gw_log (GW_LOG_DEBUG, KERNEL_LOG, "stop");
+ break;
+ }
+ else
+ {
+ gw_log (GW_LOG_WARN, KERNEL_LOG, "Unknown IPC: %s", command);
+ }
+ continuation = 1;
+ }
+ }
+ close (extra_fd);
+ gips_close (gip);
+ gips_destroy (gip);
+
+ unlink (fifo_client_name);
+ unlink (fifo_server_name);
+}
+