[Pkg-wmaker-commits] [wmbiff] 24/77: return sigchld to default hander before using popen; handle text input. Much complexity, I hope it's worth it.
Doug Torrance
dtorrance-guest at moszumanska.debian.org
Thu Aug 20 03:01:06 UTC 2015
This is an automated email from the git hooks/post-receive script.
dtorrance-guest pushed a commit to tag wmbiff_0_4_0
in repository wmbiff.
commit 8fb72ee607b8250a2b7cb4e27575ae45a9dfd507
Author: bluehal <bluehal>
Date: Mon Apr 15 01:26:05 2002 +0000
return sigchld to default hander before using popen; handle text input. Much complexity, I hope it's worth it.
---
wmbiff/ShellClient.c | 106 ++++++++++++++++++++++++++++++++++++++++++---------
1 file changed, 87 insertions(+), 19 deletions(-)
diff --git a/wmbiff/ShellClient.c b/wmbiff/ShellClient.c
index e1cf744..9c030bf 100644
--- a/wmbiff/ShellClient.c
+++ b/wmbiff/ShellClient.c
@@ -12,70 +12,138 @@
#include <errno.h>
#include <string.h>
#include <stdio.h>
+#include <ctype.h>
+#include <signal.h>
+#include <assert.h>
+#include "charutil.h"
#ifdef USE_DMALLOC
#include <dmalloc.h>
#endif
#define SH_DM(pc, lvl, args...) DM(pc, lvl, "shell: " args)
+/* kind_popen bumps off the sigchld handler - we care whether
+ a checking program fails. */
+
+sighandler_t old_signal_handler;
+
+FILE *kind_popen(const char *command, const char *type)
+{
+ FILE *ret;
+ assert(strcmp(type, "r") == 0);
+ assert(old_signal_handler == NULL);
+ old_signal_handler = signal(SIGCHLD, SIG_DFL);
+ ret = popen(command, type);
+ if (ret == NULL) {
+ DMA(DEBUG_ERROR, "popen: error while reading '%s': %s\n",
+ command, strerror(errno));
+ signal(SIGCHLD, old_signal_handler);
+ old_signal_handler = NULL;
+ }
+ return (ret);
+}
+
/* kind_pclose checks the return value from pclose and prints
some nice error messages about it. ordinarily, this would be
a good idea, but wmbiff has a sigchld handler that reaps
children immediately (needed when spawning other child processes),
so no error checking can be done here until that's disabled */
-/* TODO: block or unbind sigchld before popen, and reenable on pclose */
-static void kind_pclose(FILE * F, const char *command, Pop3 pc)
+/* returns as a mailcheck function does: -1 on fail, 0 on success */
+static int kind_pclose(FILE * F, const char *command, Pop3 pc)
{
int exit_status = pclose(F);
+
+ if (old_signal_handler != NULL) {
+ signal(SIGCHLD, old_signal_handler);
+ old_signal_handler = NULL;
+ }
+
if (exit_status != 0) {
if (exit_status == -1) {
/* wmbiff has a sigchld handler already, so wait is likely
to fail */
- if (errno != ECHILD) {
- SH_DM(pc, DEBUG_ERROR, "pclose '%s' failed: %s\n",
- command, strerror(errno));
- }
+ SH_DM(pc, DEBUG_ERROR, "pclose '%s' failed: %s\n",
+ command, strerror(errno));
+ return (-1);
} else {
SH_DM(pc, DEBUG_ERROR,
"'%s' exited with non-zero status %d\n", command,
exit_status);
+ return (-1);
}
}
+ return (0);
}
int shellCmdCheck(Pop3 pc)
{
FILE *F;
int count_status = 0;
+ char linebuf[256];
if (pc == NULL)
return -1;
SH_DM(pc, DEBUG_INFO, ">Mailbox: '%s'\n", pc->path);
- if ((F = popen(pc->path, "r")) == NULL) {
- SH_DM(pc, DEBUG_ERROR, "popen: error while reading '%s': %s\n",
- pc->path, strerror(errno));
+ /* run the program and disable the signal handler (if successful) */
+ if ((F = kind_popen(pc->path, "r")) == NULL) {
return -1;
}
- /* doesn't really need to be handled separately, but it
- seems worth an error message */
- if (fscanf(F, "%d\n", &(count_status)) != 1) {
+ /* fetch the first line of input */
+ pc->TextStatus[0] = '\0';
+ if (fgets(linebuf, 256, F) == NULL) {
SH_DM(pc, DEBUG_ERROR,
- "'%s' returned something other than an integer message count.\n",
+ "fgets: unable to read the output of '%s': %s\n", pc->path,
+ strerror(errno));
+ kind_pclose(F, pc->path, pc);
+ return -1;
+ }
+ chomp(linebuf);
+ SH_DM(pc, DEBUG_INFO, "'%s' returned '%s'\n", pc->path, linebuf);
+
+ /* see if it's numeric; the numeric check is somewhat
+ useful, as wmbiff renders 4-digit numbers, but not
+ 4-character strings. */
+ if (sscanf(linebuf, "%d", &(count_status)) == 1) {
+ if (strstr(linebuf, "new")) {
+ pc->UnreadMsgs = count_status;
+ pc->TotalMsgs = 0;
+ } else if (strstr(linebuf, "old")) {
+ pc->UnreadMsgs = 0;
+ pc->TotalMsgs = count_status;
+ } else {
+ /* this default should be configurable. */
+ pc->UnreadMsgs = 0;
+ pc->TotalMsgs = count_status;
+ }
+ } else if (sscanf(linebuf, "%9s\n", pc->TextStatus) == 1) {
+ /* validate the string input */
+ int i;
+ for (i = 0;
+ pc->TextStatus[i] != '\0' && isalnum(pc->TextStatus[i])
+ && i < 10; i++);
+ if (pc->TextStatus[i] != '\0') {
+ SH_DM(pc, DEBUG_ERROR,
+ "sorry, wmbiff supports only alphanumeric (isalnum()) strings ('%s' is not ok)\n",
+ pc->TextStatus);
+ pc->TextStatus[i] = '\0'; /* null terminate it at the first bad char. */
+ }
+ /* see if we should print as new or not */
+ pc->UnreadMsgs = (strstr(linebuf, "new")) ? 1 : 0;
+ } else {
+ SH_DM(pc, DEBUG_ERROR,
+ "'%s' returned something other than an integer message count or short string.\n",
pc->path);
kind_pclose(F, pc->path, pc);
return -1;
}
- pc->TotalMsgs = pc->UnreadMsgs + count_status;
- pc->UnreadMsgs = count_status;
- SH_DM(pc, DEBUG_INFO, "from: %d status: %d\n", pc->TotalMsgs,
- pc->UnreadMsgs);
+ SH_DM(pc, DEBUG_INFO, "from: %s status: %s %d %d\n",
+ pc->path, pc->TextStatus, pc->TotalMsgs, pc->UnreadMsgs);
- kind_pclose(F, pc->path, pc);
- return 0;
+ return (kind_pclose(F, pc->path, pc));
}
int shellCreate(Pop3 pc, const char *str)
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-wmaker/wmbiff.git
More information about the Pkg-wmaker-commits
mailing list