/*
* msh.c -- The nmh shell
*
- * $Id$
- *
* This code is Copyright (c) 2002, by the authors of nmh. See the
* COPYRIGHT file in the root directory of the nmh distribution for
* complete copyright information.
#include <h/mts.h>
#include <h/utils.h>
-#ifdef HAVE_TERMIOS_H
-# include <termios.h>
-#else
-# ifdef HAVE_TERMIO_H
-# include <termio.h>
-# else
-# include <sgtty.h>
-# endif
-#endif
+#include <termios.h>
#include <pwd.h>
#include <setjmp.h>
static jmp_buf peerenv;
-#ifdef BPOP
-int pmsh = 0; /* BPOP enabled */
-extern char response[];
-#endif /* BPOP */
-
/*
* PARENT
*/
int broken_pipe; /* SIGPIPE detected */
int told_to_quit; /* SIGQUIT detected */
-#ifdef BSD42
-int should_intr; /* signal handler should interrupt call */
-jmp_buf sigenv; /* the environment pointer */
-#endif
-
/*
* prototypes
*/
-int SOprintf (char *, ...); /* from termsbr.c */
-int sc_width (void); /* from termsbr.c */
void fsetup (char *);
void setup (char *);
-FILE *msh_ready (int, int);
void readids (int);
int readid (int);
void display_info (int);
static int read_map (char *, long);
static int read_file (long, int);
-#ifdef BPOP
-# ifdef NNTP
-static int pop_statmsg (char *);
-# endif /* NNTP */
-static int read_pop (void);
-static int pop_action (char *);
-#endif /* BPOP */
-
static void m_gMsgs (int);
-FILE *msh_ready (int, int);
static int check_folder (int);
static void scanrange (int, int);
static void scanstring (char *);
static void fin_io (struct Cmd *, int);
static void finaux_io (struct Cmd *);
static void m_init (void);
-static RETSIGTYPE intrser (int);
-static RETSIGTYPE pipeser (int);
-static RETSIGTYPE quitser (int);
-static RETSIGTYPE alrmser (int);
+static void intrser (int);
+static void pipeser (int);
+static void quitser (int);
+static void alrmser (int);
static int pINI (void);
static int pQRY (char *, int);
static int pQRY1 (int);
int id = 0, scansw = 0, vmh1 = 0, vmh2 = 0;
char *cp, *file = NULL, *folder = NULL;
char **argp, **arguments, buf[BUFSIZ];
-#ifdef BPOP
- int pmsh1 = 0, pmsh2 = 0;
-#endif
#ifdef LOCALE
setlocale(LC_ALL, "");
case PREADSW:
if (!(cp = *argp++) || *cp == '-')
adios (NULL, "missing argument to %s", argp[-2]);
-#ifdef BPOP
- if ((pmsh1 = atoi (cp)) < 1)
- adios (NULL, "bad argument %s %s", argp[-2], cp);
-#endif /* BPOP */
continue;
case PWRITSW:
if (!(cp = *argp++) || *cp == '-')
adios (NULL, "missing argument to %s", argp[-2]);
-#ifdef BPOP
- if ((pmsh2 = atoi (cp)) < 1)
- adios (NULL, "bad argument %s %s", argp[-2], cp);
-#endif /* BPOP */
continue;
case TCURSW:
if (folder)
adios (NULL, "only one folder at a time!");
else
- folder = path (cp + 1, *cp == '+' ? TFOLDER : TSUBCWF);
+ folder = pluspath (cp);
}
else
if (file)
ioctl (pfd, FIOCLEX, NULL);
#endif /* FIOCLEX */
-#ifdef BSD42
- should_intr = 0;
-#endif /* BSD42 */
istat = SIGNAL2 (SIGINT, intrser);
qstat = SIGNAL2 (SIGQUIT, quitser);
#endif /* SIGTSTP */
}
-#ifdef BPOP
- if (pmsh = pmsh1 && pmsh2) {
- cp = getenv ("MHPOPDEBUG");
-#ifdef NNTP
- if (pop_set (pmsh1, pmsh2, cp && *cp, myname) == NOTOK)
-#else /* NNTP */
- if (pop_set (pmsh1, pmsh2, cp && *cp) == NOTOK)
-#endif /* NNTP */
- padios (NULL, "%s", response);
- if (folder)
- file = folder, folder = NULL;
- }
-#endif /* BPOP */
-
if (folder)
fsetup (folder);
else
m_reset ();
- return done (0);
+ done (0);
+ return 1;
}
{
int i, msgp;
struct stat st;
-#ifdef BPOP
- char tmpfil[BUFSIZ];
-#endif
-
-#ifdef BPOP
- if (pmsh) {
- strncpy (tmpfil, m_tmpfil (invo_name), sizeof(tmpfil));
- if ((fp = fopen (tmpfil, "w+")) == NULL)
- padios (tmpfil, "unable to create");
- unlink (tmpfil);
- }
- else
-#endif /* BPOP */
if ((fp = fopen (file, "r")) == NULL)
padios (file, "unable to read");
#ifdef FIOCLEX
mp->foldpath = getcpy (myname ? myname : file);
clear_folder_flags (mp);
-#ifdef BPOP
- if (pmsh)
- set_readonly (mp);
- else {
-#endif /* BPOP */
stat (file, &st);
if (st.st_uid != getuid () || access (file, W_OK) == NOTOK)
set_readonly (mp);
-#ifdef BPOP
- }
-#endif /* BPOP */
mp->lowoff = 1;
mp->hghoff = mp->hghmsg + 1;
-#ifdef BPOP
- if (pmsh) {
-#ifndef NNTP
- for (i = mp->lowmsg; i <= mp->hghmsg; i++) {
- Msgs[i].m_top = i;
- clear_msg_flags (mp, i);
- set_exists (mp, i);
- set_virtual (mp, i);
- }
-#else /* NNTP */
- for (i = mp->lowmsg; i <= mp->hghmsg; i++) {
- if (Msgs[i].m_top) /* set in read_pop() */
- clear_msg_flags (mp, i);
- set_exists (mp, i);
- set_virtual (mp, i);
- }
-#endif /* NNTP */
- }
- else
-#endif /* BPOP */
for (i = mp->lowmsg; i <= mp->hghmsg; i++) {
clear_msg_flags (mp, i);
set_exists (mp, i);
register struct drop *dp, *mp;
struct drop *rp;
-#ifdef BPOP
- if (pmsh)
- return read_pop ();
-#endif /* BPOP */
-
if ((i = map_read (file, size, &rp, 1)) == 0)
return 0;
register struct drop *dp, *mp;
struct drop *rp;
-#ifdef BPOP
- if (pmsh)
- return (msgp - 1);
-#endif /* BPOP */
-
if ((i = mbx_read (fp, pos, &rp, 1)) <= 0)
return (msgp - 1);
}
-#ifdef BPOP
-#ifdef NNTP
-static int pop_base = 0;
-
-static int
-pop_statmsg (char *s)
-{
- register int i, n;
-
- n = (i = atoi (s)) - pop_base; /* s="nnn header-line..." */
- Msgs[n].m_top = Msgs[n].m_bboard_id = i;
-}
-
-#endif /* NNTP */
-
-static int
-read_pop (void)
-{
- int nmsgs, nbytes;
-
- if (pop_stat (&nmsgs, &nbytes) == NOTOK)
- padios (NULL, "%s", response);
-
- m_gMsgs (nmsgs);
-
-#ifdef NNTP /* this makes read_pop() do some real work... */
- pop_base = nbytes - 1; /* nmsgs=last-first+1, nbytes=first */
- pop_exists (pop_statmsg);
-#endif /* NNTP */
- return nmsgs;
-}
-
-
-static int
-pop_action (char *s)
-{
- fprintf (yp, "%s\n", s);
-}
-#endif /* BPOP */
-
-
static void
m_gMsgs (int n)
{
register int msgp;
int fd;
char *cp;
-#ifdef BPOP
- char tmpfil[BUFSIZ];
- long pos1, pos2;
-#endif
+ NMH_UNUSED (full);
if (yp) {
fclose (yp);
return yp;
}
-#ifdef BPOP
- if (pmsh && is_virtual (mp, msgnum)) {
- if (Msgs[msgnum].m_top == 0)
- padios (NULL, "msh_ready (%d, %d) botch", msgnum, full);
- if (!full) {
- strncpy (tmpfil, m_tmpfil (invo_name), sizeof(tmpfil));
- if ((yp = fopen (tmpfil, "w+")) == NULL)
- padios (tmpfil, "unable to create");
- unlink (tmpfil);
-
- if (pop_top (Msgs[msgnum].m_top, 4, pop_action) == NOTOK)
- padios (NULL, "%s", response);
-
- m_eomsbr ((int (*)()) 0); /* XXX */
- msg_style = MS_DEFAULT; /* .. */
- fseek (yp, 0L, SEEK_SET);
- return yp;
- }
-
- fseek (fp, 0L, SEEK_END);
- fwrite (mmdlm1, 1, strlen (mmdlm1), fp);
- if (fflush (fp))
- padios ("temporary file", "write error on");
- fseek (fp, 0L, SEEK_END);
- pos1 = ftell (fp);
-
- yp = fp;
- if (pop_retr (Msgs[msgnum].m_top, pop_action) == NOTOK)
- padios (NULL, "%s", response);
- yp = NULL;
-
- fseek (fp, 0L, SEEK_END);
- pos2 = ftell (fp);
- fwrite (mmdlm2, 1, strlen (mmdlm2), fp);
- if (fflush (fp))
- padios ("temporary file", "write error on");
-
- Msgs[msgnum].m_start = pos1;
- Msgs[msgnum].m_stop = pos2;
-
- unset_virtual (mp, msgnum);
- }
-#endif /* BPOP */
-
m_eomsbr ((int (*)()) 0); /* XXX */
fseek (fp, Msgs[msgnum].m_start, SEEK_SET);
return fp;
int seqnum, i, low, hgh, msgp;
struct stat st;
-#ifdef BPOP
- if (pmsh)
- return 0;
-#endif /* BPOP */
-
if (fmsh) {
if (stat (mp->foldpath, &st) == NOTOK)
padios (mp->foldpath, "unable to stat");
void
readids (int id)
{
- register int cur, seqnum, i, msgnum;
+ register int cur, seqnum, i=0, msgnum;
if (mp->curmsg == 0)
seq_setcur (mp, mp->lowmsg);
int i, state;
char *bp, buf[BUFSIZ], name[NAMESZ];
register FILE *zp;
-#ifdef BPOP
- int arg1, arg2, arg3;
-#endif
if (Msgs[msgnum].m_bboard_id)
return Msgs[msgnum].m_bboard_id;
-#ifdef BPOP
- if (pmsh) {
- if (Msgs[msgnum].m_top == 0)
- padios (NULL, "readid (%d) botch", msgnum);
- if (pop_list (Msgs[msgnum].m_top, (int *) 0, &arg1, &arg2, &arg3) == OK
- && arg3 > 0)
- return (Msgs[msgnum].m_bboard_id = arg3);
- }
-#endif /* BPOP */
zp = msh_ready (msgnum, 0);
for (state = FLD;;)
case FLD:
case FLDEOF:
case FLDPLUS:
- if (!strcasecmp (name, BBoard_ID)) {
+ if (!mh_strcasecmp (name, BBoard_ID)) {
bp = getcpy (buf);
while (state == FLDPLUS) {
state = m_getfld (state, name, buf, sizeof(buf), zp);
if (sp == NULL) {
if ((sd = dup (fileno (stdout))) == NOTOK)
padios ("standard output", "unable to dup");
-#ifndef BSD42 /* XXX */
#ifdef FIOCLEX
ioctl (sd, FIOCLEX, NULL);
#endif /* FIOCLEX */
-#endif /* not BSD42 */
if ((sp = fdopen (sd, "w")) == NULL)
padios ("standard output", "unable to fdopen");
}
told_to_quit = 0;
for (;;) {
interrupted = 0;
-#ifdef BSD42
- switch (setjmp (sigenv)) {
- case OK:
- should_intr = 1;
- break;
-
- default:
- should_intr = 0;
- if (interrupted && !told_to_quit) {
- putchar ('\n');
- continue;
- }
- if (ppid > 0)
-#ifdef SIGEMT
- kill (ppid, SIGEMT);
-#else
- kill (ppid, SIGTERM);
-#endif
- return EOF;
- }
-#endif /* BSD42 */
if (interactive) {
printf ("%s", prompt);
fflush (stdout);
}
for (cp = buffer; (i = getchar ()) != '\n';) {
-#ifndef BSD42
if (interrupted && !told_to_quit) {
buffer[0] = '\0';
putchar ('\n');
#endif
return EOF;
}
-#else /* BSD42 */
- if (i == EOF)
- longjmp (sigenv, DONE);
-#endif /* BSD42 */
if (cp < &buffer[sizeof buffer - 2])
*cp++ = i;
}
continue;
if (buffer[0] == '?') {
printf ("commands:\n");
- print_sw (ALL, sw, "");
+ print_sw (ALL, sw, "", stdout);
printf ("type CTRL-D or use ``quit'' to leave %s\n",
invo_name);
continue;
cmdp->args[0]);
continue;
default:
-#ifdef BSD42
- should_intr = 0;
-#endif /* BSD42 */
return i;
}
}
parse (char *buffer, struct Cmd *cmdp)
{
int argp = 0;
- char c, *cp, *pp;
+ unsigned char c, *cp;
+ char *pp;
cmdp->line[0] = 0;
pp = cmdp->args[argp++] = cmdp->line;
write_ids ();
folder_free (mp); /* free folder/message structure */
myname = NULL;
-#ifdef BPOP
- if (pmsh) {
- pop_done ();
- pmsh = 0;
- }
-#endif /* BPOP */
}
-static RETSIGTYPE
+static void
intrser (int i)
{
-#ifndef RELIABLE_SIGNALS
- SIGNAL (SIGINT, intrser);
-#endif
-
+ NMH_UNUSED (i);
discard (stdout);
interrupted++;
-
-#ifdef BSD42
- if (should_intr)
- longjmp (sigenv, NOTOK);
-#endif
}
-static RETSIGTYPE
+static void
pipeser (int i)
{
-#ifndef RELIABLE_SIGNALS
- SIGNAL (SIGPIPE, pipeser);
-#endif
-
+ NMH_UNUSED (i);
if (broken_pipe++ == 0)
fprintf (stderr, "broken pipe\n");
told_to_quit++;
interrupted++;
-
-#ifdef BSD42
- if (should_intr)
- longjmp (sigenv, NOTOK);
-#endif
}
-static RETSIGTYPE
+static void
quitser (int i)
{
-#ifndef RELIABLE_SIGNALS
- SIGNAL (SIGQUIT, quitser);
-#endif
-
+ NMH_UNUSED (i);
told_to_quit++;
interrupted++;
-
-#ifdef BSD42
- if (should_intr)
- longjmp (sigenv, NOTOK);
-#endif
}
-static RETSIGTYPE
+static void
alrmser (int i)
{
+ NMH_UNUSED (i);
longjmp (peerenv, DONE);
}
pINI (void)
{
int i, vrsn;
- char *bp;
+ unsigned char *bp;
struct record rcs, *rc;
rc = &rcs;
static int
pQRY (char *str, int scansw)
{
+ NMH_UNUSED (str);
if (pQRY1 (scansw) == NOTOK || pQRY2 () == NOTOK)
return NOTOK;
case OK:
printf ("commands:\n");
- print_sw (ALL, sw, "");
+ print_sw (ALL, sw, "", stdout);
printf ("type ``quit'' to leave %s\n", invo_name);
fflush (stdout);
fflush (stderr);