Sqlite: fix segfault on bad/missing sqlite_dbfile. Bug 2606
[users/jgh/exim.git] / src / exim_monitor / em_menu.c
index d3e93a4754295762c070e5e8b92ddc0b7cdf815a..18e6a87dafd93dac5b108b78f5c76e9b5bb52465 100644 (file)
@@ -1,10 +1,8 @@
-/* $Cambridge: exim/src/exim_monitor/em_menu.c,v 1.3 2006/02/07 11:18:59 ph10 Exp $ */
-
 /*************************************************
 *                  Exim Monitor                  *
 *************************************************/
 
-/* Copyright (c) University of Cambridge 1995 - 2006 */
+/* Copyright (c) University of Cambridge 1995 - 2018 */
 /* See the file NOTICE for conditions of use and distribution. */
 
 
@@ -119,8 +117,6 @@ static Arg item_99_arg[] = {
 
 static void popdownAction(Widget w, XtPointer client_data, XtPointer call_data)
 {
-client_data = client_data;    /* Keep picky compilers happy */
-call_data = call_data;
 if (highlighted_x >= 0)
   XawTextSinkDisplayText(queue_text_sink,
     highlighted_x, highlighted_y,
@@ -135,32 +131,29 @@ menu_is_up = FALSE;
 *          Display the message log               *
 *************************************************/
 
-static void msglogAction(Widget w, XtPointer client_data, XtPointer call_data)
+static void
+msglogAction(Widget w, XtPointer client_data, XtPointer call_data)
 {
-int i;
-uschar buffer[256];
-Widget text = text_create((uschar *)client_data, text_depth);
-FILE *f = NULL;
-
-w = w;      /* Keep picky compilers happy */
-call_data = call_data;
+Widget text = text_create(US client_data, text_depth);
+uschar * fname = NULL;
+FILE * f = NULL;
 
 /* End up with the split version, so message looks right when non-exist */
 
-for (i = 0; i < (spool_is_split? 2:1); i++)
+for (int i = 0; i < (spool_is_split ? 2:1); i++)
   {
-  message_subdir[0] = (i != 0)? ((uschar *)client_data)[5] : 0;
-  sprintf(CS buffer, "%s/msglog/%s/%s", spool_directory, message_subdir,
-    (uschar *)client_data);
-  f = fopen(CS buffer, "r");
-  if (f != NULL) break;
+  message_subdir[0] = i != 0 ? (US client_data)[5] : 0;
+  fname = spool_fname(US"msglog", message_subdir, US client_data, US"");
+  if ((f = fopen(CS fname, "r")))
+    break;
   }
 
-if (f == NULL)
-  text_showf(text, "%s: %s\n", buffer, strerror(errno));
+if (!f)
+  text_showf(text, "%s: %s\n", fname, strerror(errno));
 else
   {
-  while (Ufgets(buffer, 256, f) != NULL) text_show(text, buffer);
+  uschar buffer[256];
+  while (Ufgets(buffer, sizeof(buffer), f) != NULL) text_show(text, buffer);
   fclose(f);
   }
 }
@@ -171,31 +164,29 @@ else
 *          Display the message body               *
 *************************************************/
 
-static void bodyAction(Widget w, XtPointer client_data, XtPointer call_data)
+static void
+bodyAction(Widget w, XtPointer client_data, XtPointer call_data)
 {
-int i;
-uschar buffer[256];
-Widget text = text_create((uschar *)client_data, text_depth);
+Widget text = text_create(US client_data, text_depth);
 FILE *f = NULL;
 
-w = w;      /* Keep picky compilers happy */
-call_data = call_data;
-
-for (i = 0; i < (spool_is_split? 2:1); i++)
+for (int i = 0; i < (spool_is_split? 2:1); i++)
   {
-  message_subdir[0] = (i != 0)? ((uschar *)client_data)[5] : 0;
-  sprintf(CS buffer, "%s/input/%s/%s-D", spool_directory, message_subdir,
-    (uschar *)client_data);
-  f = fopen(CS buffer, "r");
-  if (f != NULL) break;
+  uschar * fname;
+  message_subdir[0] = i != 0 ? (US client_data)[5] : 0;
+  fname = spool_fname(US"input", message_subdir, US client_data, US"-D");
+  if ((f = fopen(CS fname, "r")))
+    break;
   }
 
-if (f == NULL)
+if (!f)
   text_showf(text, "Failed to open file: %s\n", strerror(errno));
 else
   {
+  uschar buffer[256];
   int count = 0;
-  while (Ufgets(buffer, 256, f) != NULL)
+
+  while (Ufgets(buffer, sizeof(buffer), f) != NULL)
     {
     text_show(text, buffer);
     count += Ustrlen(buffer);
@@ -275,8 +266,12 @@ if (pipe(pipe_fd) != 0)
   return;
   }
 
-fcntl(pipe_fd[0], F_SETFL, O_NONBLOCK);
-fcntl(pipe_fd[1], F_SETFL, O_NONBLOCK);
+if (  fcntl(pipe_fd[0], F_SETFL, O_NONBLOCK)
+   || fcntl(pipe_fd[1], F_SETFL, O_NONBLOCK))
+  {
+  perror("set nonblocking on pipe");
+  exit(1);
+  }
 
 /* Delivering a message can take some time, and we want to show the
 output as it goes along. This requires subprocesses and is coded below. For
@@ -329,9 +324,9 @@ if (!delivery)
   if (rc == 0 && Ustrcmp(action + Ustrlen(action) - 4, "-Mes") == 0)
     {
     queue_item *q = find_queue(id, queue_noop, 0);
-    if (q != NULL)
+    if (q)
       {
-      if (q->sender != NULL) store_free(q->sender);
+      if (q->sender) store_free(q->sender);
       q->sender = store_malloc(Ustrlen(address_arg) + 1);
       Ustrcpy(q->sender, address_arg);
       }
@@ -375,7 +370,7 @@ if ((pid = fork()) == 0)
 
 /* Main process - set up an item for the main ticker to watch. */
 
-if (pid < 0) text_showf(text, "Failed to fork: %s\n", strerror(pid)); else
+if (pid < 0) text_showf(text, "Failed to fork: %s\n", strerror(errno)); else
   {
   pipe_item *p = (pipe_item *)store_malloc(sizeof(pipe_item));
 
@@ -404,9 +399,7 @@ if (pid < 0) text_showf(text, "Failed to fork: %s\n", strerror(pid)); else
 
 static void deliverAction(Widget w, XtPointer client_data, XtPointer call_data)
 {
-w = w;      /* Keep picky compilers happy */
-call_data = call_data;
-ActOnMessage((uschar *)client_data, US"-v -M", US"");
+ActOnMessage(US client_data, US"-v -M", US"");
 }
 
 
@@ -417,9 +410,7 @@ ActOnMessage((uschar *)client_data, US"-v -M", US"");
 
 static void freezeAction(Widget w, XtPointer client_data, XtPointer call_data)
 {
-w = w;      /* Keep picky compilers happy */
-call_data = call_data;
-ActOnMessage((uschar *)client_data, US"-Mf", US"");
+ActOnMessage(US client_data, US"-Mf", US"");
 }
 
 
@@ -430,9 +421,7 @@ ActOnMessage((uschar *)client_data, US"-Mf", US"");
 
 static void thawAction(Widget w, XtPointer client_data, XtPointer call_data)
 {
-w = w;      /* Keep picky compilers happy */
-call_data = call_data;
-ActOnMessage((uschar *)client_data, US"-Mt", US"");
+ActOnMessage(US client_data, US"-Mt", US"");
 }
 
 
@@ -449,21 +438,14 @@ XtActionProc dialogAction(Widget w, XEvent *event, String *ss, Cardinal *c)
 {
 uschar *s = US XawDialogGetValueString(dialog_widget);
 
-w = w;      /* Keep picky compilers happy */
-event = event;
-ss = ss;
-c = c;
-
 XtPopdown((Widget)dialog_shell);
 XtDestroyWidget((Widget)dialog_shell);
 while (isspace(*s)) s++;
 if (s[0] != 0)
-  {
   if (actioned_message[0] != 0)
     ActOnMessage(actioned_message, action_required, s);
   else
     NonMessageDialogue(s);    /* When called from somewhere else */
-  }
 return NULL;
 }
 
@@ -551,9 +533,8 @@ in. */
 
 static void addrecipAction(Widget w, XtPointer client_data, XtPointer call_data)
 {
-w = w;      /* Keep picky compilers happy */
-call_data = call_data;
-Ustrcpy(actioned_message, (uschar *)client_data);
+Ustrncpy(actioned_message, client_data, 24);
+actioned_message[23] = '\0';
 action_required = US"-Mar";
 dialog_ref_widget = menushell;
 create_dialog(US"Recipient address to add?", US"");
@@ -567,9 +548,8 @@ create_dialog(US"Recipient address to add?", US"");
 
 static void markdelAction(Widget w, XtPointer client_data, XtPointer call_data)
 {
-w = w;      /* Keep picky compilers happy */
-call_data = call_data;
-Ustrcpy(actioned_message, (uschar *)client_data);
+Ustrncpy(actioned_message, client_data, 24);
+actioned_message[23] = '\0';
 action_required = US"-Mmd";
 dialog_ref_widget = menushell;
 create_dialog(US"Recipient address to mark delivered?", US"");
@@ -582,9 +562,7 @@ create_dialog(US"Recipient address to mark delivered?", US"");
 
 static void markalldelAction(Widget w, XtPointer client_data, XtPointer call_data)
 {
-w = w;      /* Keep picky compilers happy */
-call_data = call_data;
-ActOnMessage((uschar *)client_data, US"-Mmad", US"");
+ActOnMessage(US client_data, US"-Mmad", US"");
 }
 
 
@@ -597,11 +575,11 @@ static void editsenderAction(Widget w, XtPointer client_data,
 {
 queue_item *q;
 uschar *sender;
-w = w;      /* Keep picky compilers happy */
-call_data = call_data;
-Ustrcpy(actioned_message, (uschar *)client_data);
+
+Ustrncpy(actioned_message, client_data, 24);
+actioned_message[23] = '\0';
 q = find_queue(actioned_message, queue_noop, 0);
-sender = (q == NULL)? US"" : (q->sender[0] == 0)? US"<>" : q->sender;
+sender = !q ? US"" : q->sender[0] == 0 ? US"<>" : q->sender;
 action_required = US"-Mes";
 dialog_ref_widget = menushell;
 create_dialog(US"New sender address?", sender);
@@ -614,9 +592,7 @@ create_dialog(US"New sender address?", sender);
 
 static void giveupAction(Widget w, XtPointer client_data, XtPointer call_data)
 {
-w = w;      /* Keep picky compilers happy */
-call_data = call_data;
-ActOnMessage((uschar *)client_data, US"-v -Mg", US"");
+ActOnMessage(US client_data, US"-v -Mg", US"");
 }
 
 
@@ -627,9 +603,7 @@ ActOnMessage((uschar *)client_data, US"-v -Mg", US"");
 
 static void removeAction(Widget w, XtPointer client_data, XtPointer call_data)
 {
-w = w;      /* Keep picky compilers happy */
-call_data = call_data;
-ActOnMessage((uschar *)client_data, US"-Mrm", US"");
+ActOnMessage(US client_data, US"-Mrm", US"");
 }
 
 
@@ -642,18 +616,15 @@ static void headersAction(Widget w, XtPointer client_data, XtPointer call_data)
 {
 uschar buffer[256];
 header_line *h, *next;
-Widget text = text_create((uschar *)client_data, text_depth);
-void *reset_point;
-
-w = w;      /* Keep picky compilers happy */
-call_data = call_data;
+Widget text = text_create(US client_data, text_depth);
+rmark reset_point;
 
 /* Remember the point in the dynamic store so we can recover to it afterwards.
 Then use Exim's function to read the header. */
 
-reset_point = store_get(0);
+reset_point = store_mark();
 
-sprintf(CS buffer, "%s-H", (uschar *)client_data);
+sprintf(CS buffer, "%s-H", US client_data);
 if (spool_read_header(buffer, TRUE, FALSE) != spool_read_OK)
   {
   if (errno == ERRNO_SPOOLFORMAT)
@@ -661,8 +632,8 @@ if (spool_read_header(buffer, TRUE, FALSE) != spool_read_OK)
     struct stat statbuf;
     sprintf(CS big_buffer, "%s/input/%s", spool_directory, buffer);
     if (Ustat(big_buffer, &statbuf) == 0)
-      text_showf(text, "Format error in spool file %s: size=%d\n", buffer,
-        statbuf.st_size);
+      text_showf(text, "Format error in spool file %s: size=%lu\n", buffer,
+        (ulong)statbuf.st_size);
     else text_showf(text, "Format error in spool file %s\n", buffer);
     }
   else text_showf(text, "Read error for spool file %s\n", buffer);
@@ -670,26 +641,24 @@ if (spool_read_header(buffer, TRUE, FALSE) != spool_read_OK)
   return;
   }
 
-if (sender_address != NULL)
+if (sender_address)
   {
-  text_showf(text, "%s sender: <%s>\n", sender_local? "Local" : "Remote",
+  text_showf(text, "%s sender: <%s>\n", f.sender_local ? "Local" : "Remote",
     sender_address);
   }
 
-if (recipients_list != NULL)
+if (recipients_list)
   {
   int i;
   text_show(text, US"Recipients:\n");
   for (i = 0; i < recipients_count; i++)
-    {
     text_showf(text, "  %s %s\n",
       (tree_search(tree_nonrecipients, recipients_list[i].address) == NULL)?
         " ":"*", recipients_list[i].address);
-    }
   text_show(text, US"\n");
   }
 
-for (h = header_list; h != NULL; h = next)
+for (h = header_list; h; h = next)
   {
   next = h->next;
   text_showf(text, "%c ", h->type);   /* Don't push h->text through a %s */
@@ -708,11 +677,6 @@ store_reset(reset_point);
 
 static void dismissAction(Widget w, XtPointer client_data, XtPointer call_data)
 {
-pipe_item *p = pipe_chain;
-
-w = w;      /* Keep picky compilers happy */
-call_data = call_data;
-
 XtPopdown((Widget)client_data);
 XtDestroyWidget((Widget)client_data);
 
@@ -721,16 +685,9 @@ the chain so that subsequent data doesn't try to use it. We have
 to search the parents of the saved widget to see if one of them
 is what we have just destroyed. */
 
-while (p != NULL)
-  {
-  Widget pp = p->widget;
-  while (pp != NULL)
-    {
+for (pipe_item * p = pipe_chain; p; p = p->next)
+  for (Widget pp = p->widget; pp; pp = XtParent(pp))
     if (pp == (Widget)client_data) { p->widget = NULL; return; }
-    pp = XtParent(pp);
-    }
-  p = p->next;
-  }
 }
 
 
@@ -816,9 +773,6 @@ XtTranslations menu_trans = XtParseTranslationTable(
    <BtnUp>:         MenuPopdown()notify()unhighlight()\n\
   ");
 
-actargs = actargs;   /* Keep picky compilers happy */
-count = count;
-
 /* Get the sink and source and the current text pointer */
 
 queue_get_arg[0].value = (XtArgVal)(&queue_text_sink);