-/* $Cambridge: exim/src/exim_monitor/em_menu.c,v 1.4 2007/01/08 10:50:17 ph10 Exp $ */
-
/*************************************************
* Exim Monitor *
*************************************************/
-/* Copyright (c) University of Cambridge 1995 - 2007 */
+/* Copyright (c) University of Cambridge 1995 - 2018 */
+/* Copyright (c) The Exim Maintainers 2021 */
/* See the file NOTICE for conditions of use and distribution. */
+/* SPDX-License-Identifier: GPL-2.0-or-later */
#include "em_hdr.h"
* Destroy the menu when popped down *
*************************************************/
-static void popdownAction(Widget w, XtPointer client_data, XtPointer call_data)
+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,
* 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);
}
}
* 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);
the command whether we want the output or not, so the pipe has to be set up in
all cases. */
-static void ActOnMessage(uschar *id, uschar *action, uschar *address_arg)
+static void
+ActOnMessage(uschar *id, uschar *action, uschar *address_arg)
{
int pid;
int pipe_fd[2];
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
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);
}
/* 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));
* Cause a message to be delivered *
*************************************************/
-static void deliverAction(Widget w, XtPointer client_data, XtPointer call_data)
+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"");
}
-
-
/*************************************************
* Cause a message to be Frozen *
*************************************************/
-static void freezeAction(Widget w, XtPointer client_data, XtPointer call_data)
+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"");
}
-
-
/*************************************************
* Cause a message to be thawed *
*************************************************/
-static void thawAction(Widget w, XtPointer client_data, XtPointer call_data)
+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"");
}
-
-
/*************************************************
* Take action using dialog data *
*************************************************/
in. It is global because it is set up in the action table at
start-up time. If the string is empty, do nothing. */
-XtActionProc dialogAction(Widget w, XEvent *event, String *ss, Cardinal *c)
+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;
}
be done to the application until the box is filled in. This
function is also used by the Hide button handler. */
-void create_dialog(uschar *label, uschar *value)
+void
+create_dialog(uschar *label, uschar *value)
{
Arg warg[4];
Dimension x, y, xx, yy;
}
-
-
-
/*************************************************
* Cause a recipient to be added *
*************************************************/
/* This just sets up the dialog box; the action happens when it has been filled
in. */
-static void addrecipAction(Widget w, XtPointer client_data, XtPointer call_data)
+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"");
}
-
-
/*************************************************
* Cause an address to be marked delivered *
*************************************************/
-static void markdelAction(Widget w, XtPointer client_data, XtPointer call_data)
+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"");
}
-
/*************************************************
* Cause all addresses to be marked delivered *
*************************************************/
-static void markalldelAction(Widget w, XtPointer client_data, XtPointer call_data)
+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"");
}
-
/*************************************************
* Edit the message's sender *
*************************************************/
-static void editsenderAction(Widget w, XtPointer client_data,
- XtPointer call_data)
+static void
+editsenderAction(Widget w, XtPointer client_data, XtPointer call_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);
}
-
/*************************************************
* Cause a message to be returned to sender *
*************************************************/
-static void giveupAction(Widget w, XtPointer client_data, XtPointer call_data)
+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"");
}
-
-
/*************************************************
* Cause a message to be cancelled *
*************************************************/
-static void removeAction(Widget w, XtPointer client_data, XtPointer call_data)
+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"");
}
-
-
/*************************************************
* Display a message's headers *
*************************************************/
-static void headersAction(Widget w, XtPointer client_data, XtPointer call_data)
+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)
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,
+ (unsigned long)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);
return;
}
-if (sender_address != NULL)
- {
- text_showf(text, "%s sender: <%s>\n", sender_local? "Local" : "Remote",
+if (sender_address)
+ 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++)
- {
+ for (int 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);
- }
+ tree_search(tree_nonrecipients, recipients_list[i].address)
+ ? "*" : " ",
+ recipients_list[i].address);
text_show(text, US"\n");
}
-for (h = header_list; h != NULL; h = next)
+for (header_line * next, * h = header_list; h; h = next)
{
next = h->next;
text_showf(text, "%c ", h->type); /* Don't push h->text through a %s */
store_reset(reset_point);
}
-
-
-
/*************************************************
* Dismiss a text window *
*************************************************/
-static void dismissAction(Widget w, XtPointer client_data, XtPointer call_data)
+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);
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;
- }
}
* Set up popup text window *
*************************************************/
-static Widget text_create(uschar *name, int height)
+static Widget
+text_create(uschar *name, int height)
{
Widget textshell, form, text, button;
return text;
}
-
-
-
/*************************************************
* Set up menu in queue window *
*************************************************/
/* We have added an action table that causes this function to
be called, and set up button 2 in the text widgets to call it. */
-void menu_create(Widget w, XEvent *event, String *actargs, Cardinal *count)
+void
+menu_create(Widget w, XEvent *event, String *actargs, Cardinal *count)
{
int line;
int i;
<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);
/* Now pointing at first character of a main line. */
-Ustrncpy(message_id, s+p+11, MESSAGE_ID_LENGTH);
+Ustrncpy(message_id, s+p+11, MESSAGE_ID_LENGTH); /*III*/
message_id[MESSAGE_ID_LENGTH] = 0;
/* Highlight the line being menued, and save its parameters so that it