From 916690191222433a6923a4be54b0d8f6ac01bd02 Mon Sep 17 00:00:00 2001 From: markus schnalke Date: Wed, 5 Oct 2011 19:09:27 +0200 Subject: [PATCH] Removed msh, vmh and wmh. The latter ones were long time obsolete; now they went away. Msh has hardly to do with everyday mmh usage, and we don't support bboards anymore. This one changeset saves us about 7,000 lines of code. *yay* --- config/config.c | 14 - configure.ac | 24 - docs/COMPLETION-BASH | 2 +- h/Makefile.in | 4 +- h/mh.h | 8 +- h/msh.h | 104 -- h/prototypes.h | 1 - h/vmhsbr.h | 49 - man/Makefile.in | 5 +- man/burst.man | 2 +- man/mh-chart.man | 10 - man/mh-profile.man | 6 - man/mh-tailor.man | 1 - man/msh.man | 355 ------ man/nmh.man | 1 - man/vmh.man | 101 -- sbr/context_foil.c | 2 +- sbr/m_getfld.c | 20 +- sbr/readconfig.c | 2 - uip/Makefile.in | 15 +- uip/mhparam.c | 2 - uip/msh.c | 2395 ---------------------------------------- uip/mshcmds.c | 3004 -------------------------------------------------- uip/vmh.c | 1515 ------------------------- uip/vmhsbr.c | 227 ---- uip/vmhtest.c | 324 ------ 26 files changed, 13 insertions(+), 8180 deletions(-) delete mode 100644 h/msh.h delete mode 100644 h/vmhsbr.h delete mode 100644 man/msh.man delete mode 100644 man/vmh.man delete mode 100644 uip/msh.c delete mode 100644 uip/mshcmds.c delete mode 100644 uip/vmh.c delete mode 100644 uip/vmhsbr.c delete mode 100644 uip/vmhtest.c diff --git a/config/config.c b/config/config.c index 9b64e29..671292e 100644 --- a/config/config.c +++ b/config/config.c @@ -250,13 +250,6 @@ char *moreproc = "more"; char *mhlproc = nmhlibdir (/mhl); /* - * This is the super handy BBoard reading program, which is - * really just the nmh shell program. - */ - -char *mshproc = nmhbindir (/msh); - -/* * This program is called to pack a folder. */ @@ -313,13 +306,6 @@ char *showmimeproc = nmhbindir (/mhshow); char *showproc = nmhlibdir (/mhl); /* - * This program is called by vmh as the back-end to the window management - * protocol - */ - -char *vmhproc = nmhbindir (/msh); - -/* * This program is called after comp, et. al., have built a draft */ diff --git a/configure.ac b/configure.ac index 542fbde..f4d1dd6 100644 --- a/configure.ac +++ b/configure.ac @@ -778,51 +778,27 @@ AC_SUBST(SIGNAL_H)dnl dnl ---------------- dnl OS SPECIFIC DEFINES dnl ---------------- -AH_TEMPLATE(SYS5, [Defined for Solaris 2.x, Irix, OSF/1, HP-UX, AIX, SCO5; only used in vmh.c which is not built.]) -AH_TEMPLATE(SVR4, [Defined for Solaris 2.x, Irix, OSF/1, HP-UX, AIX; only used in vmh.c which is not built.]) -AH_TEMPLATE(BSD44, [Defined for SunOS 4, FreeBSD, NetBSD, OpenBSD, BSD/OS, Mac OS X/Rhapsody; only used in vmh.c which is not built.]) AH_TEMPLATE(BSD42, [Defined for SunOS 4, FreeBSD, NetBSD, OpenBSD, BSD/OS, Mac OS X/Rhapsody -- does PicoBSD have uname?]) AH_TEMPLATE(SCO_5_STDIO, [Defined for SCO5.]) case "$target_os" in - solaris2*) - AC_DEFINE(SYS5) - AC_DEFINE(SVR4) - ;; - irix*) - AC_DEFINE(SYS5) - AC_DEFINE(SVR4) - ;; - osf*) - AC_DEFINE(SYS5) - AC_DEFINE(SVR4) - ;; - aix*) - AC_DEFINE(SYS5) - AC_DEFINE(SVR4) - ;; sunos4*) AC_DEFINE(BSD42) ;; freebsd*) AC_DEFINE(BSD42) - AC_DEFINE(BSD44) ;; netbsd*) AC_DEFINE(BSD42) - AC_DEFINE(BSD44) ;; openbsd*) AC_DEFINE(BSD42) - AC_DEFINE(BSD44) ;; bsd/os*) AC_DEFINE(BSD42) - AC_DEFINE(BSD44) ;; sco5*) - AC_DEFINE(SYS5) AC_DEFINE(SCO_5_STDIO) ;; esac diff --git a/docs/COMPLETION-BASH b/docs/COMPLETION-BASH index e77e152..f759c35 100644 --- a/docs/COMPLETION-BASH +++ b/docs/COMPLETION-BASH @@ -161,4 +161,4 @@ _nmh() COMPREPLY=( $( compgen -W "${options[*]}" -- $current ) ) return 0 } -[ "$have" ] && complete -F _nmh ali anno burst comp dist flist flists folder folders forw inc mark mhbuild mhl mhlist mhmail mhn mhparam mhpath mhshow mhstore msgchk msh next packf pick prev prompter rcvdist rcvpack rcvstore rcvtty refile repl rmf rmm scan send sendfiles show slocal sortm whatnow whom +[ "$have" ] && complete -F _nmh ali anno burst comp dist flist flists folder folders forw inc mark mhbuild mhl mhlist mhmail mhn mhparam mhpath mhshow mhstore msgchk next packf pick prev prompter rcvdist rcvpack rcvstore rcvtty refile repl rmf rmm scan send sendfiles show slocal sortm whatnow whom diff --git a/h/Makefile.in b/h/Makefile.in index b616524..d40a92b 100644 --- a/h/Makefile.in +++ b/h/Makefile.in @@ -9,9 +9,9 @@ VPATH = @srcdir@ # header files included in distribution HDRS = addrsbr.h aliasbr.h crawl_folders.h dropsbr.h fmt_compile.h fmt_scan.h \ - md5.h mf.h mh.h mhcachesbr.h mhparse.h mime.h msh.h mts.h \ + md5.h mf.h mh.h mhcachesbr.h mhparse.h mime.h mts.h \ netdb.h nmh.h picksbr.h popsbr.h prototypes.h rcvmail.h \ - scansbr.h signals.h tws.h vmhsbr.h utils.h + scansbr.h signals.h tws.h utils.h # auxiliary files AUX = Makefile.in diff --git a/h/mh.h b/h/mh.h index 25bb475..5898831 100644 --- a/h/mh.h +++ b/h/mh.h @@ -74,9 +74,8 @@ extern struct swit anoyes[]; /* standard yes/no switches */ #define SEQMOD (1<<1) /* folder's sequences modifed */ #define ALLOW_NEW (1<<2) /* allow the "new" sequence */ #define OTHERS (1<<3) /* folder has other files */ -#define MODIFIED (1<<4) /* msh in-core folder modified */ -#define FBITS "\020\01READONLY\02SEQMOD\03ALLOW_NEW\04OTHERS\05MODIFIED" +#define FBITS "\020\01READONLY\02SEQMOD\03ALLOW_NEW\04OTHERS" /* * type for holding the sequence set of a message @@ -185,8 +184,6 @@ struct msgs { #define unset_unseen(mp,msgnum) ((mp)->msgstats[(msgnum) - mp->lowoff] &= ~SELECT_UNSEEN) #define set_unseen(mp,msgnum) ((mp)->msgstats[(msgnum) - mp->lowoff] |= SELECT_UNSEEN) -/* for msh only */ -#define set_deleted(mp,msgnum) ((mp)->msgstats[(msgnum) - mp->lowoff] |= DELETED) #define in_sequence(mp,seqnum,msgnum) \ ((mp)->msgstats[(msgnum) - mp->lowoff] & (1 << (FFATTRSLOT + seqnum))) @@ -247,7 +244,6 @@ struct msgs { #define MS_UNKNOWN 1 /* type not known yet */ #define MS_MBOX 2 /* Unix-style "from" lines */ #define MS_MMDF 3 /* string mmdlm2 */ -#define MS_MSH 4 /* whacko msh */ extern int msg_count; /* m_getfld() indicators */ extern int msg_style; /* .. */ @@ -327,7 +323,6 @@ extern char *mhlproc; extern char *mhlreply; extern char *moreproc; extern char *msgprot; -extern char *mshproc; extern char *nmhaccessftp; extern char *nmhstorage; extern char *nmhcache; @@ -350,7 +345,6 @@ extern char *showproc; extern char *usequence; extern char *version_num; extern char *version_str; -extern char *vmhproc; extern char *whatnowproc; extern char *whomproc; diff --git a/h/msh.h b/h/msh.h deleted file mode 100644 index 585e50a..0000000 --- a/h/msh.h +++ /dev/null @@ -1,104 +0,0 @@ - -/* - * msh.h -- definitions for msh - */ - -/* flags for stream */ -#define STDIO 0 /* regular stdoutput */ -#define CRTIO 1 /* create re-direct */ -#define APPIO 2 /* append re-direct */ -#define PIPIO 3 /* pipe re-direct */ - -struct Cmd { - char line[BUFSIZ]; - char *args[MAXARGS]; - char *redirect; - int direction; - FILE *stream; -}; - -#define NULLCMD ((struct Cmd *) 0) - -#define MHNCHK 0x0001 /* did nontext check */ -#define MHNYES 0x0002 /* .. and known to be non-text */ - -#define CUR (1 << (FFATTRSLOT + NUMATTRS - 1)) - -struct Msg { - struct drop m_drop; - char *m_scanl; - struct tws m_tb; - short m_flags; - seqset_t m_stats; -}; - -#define m_bboard_id m_drop.d_id -#define m_top m_drop.d_size -#define m_start m_drop.d_start -#define m_stop m_drop.d_stop - -/* - * FOLDER - */ -extern char *fmsh; /* folder instead of file */ -extern int modified; /* command modified folder */ -extern struct msgs *mp; /* used a lot */ -extern struct Msg *Msgs; /* Msgs[0] not used */ - -FILE *msh_ready (); - -/* - * COMMAND - */ -extern int interactive; /* running from a /dev/tty */ -extern int redirected; /* re-directing output */ -extern FILE *sp; /* original stdout */ -extern char *cmd_name; /* command being run */ -extern char myfilter[]; /* path to mhl.forward */ - -extern char *BBoard_ID; /* BBoard-ID constant */ - -/* - * SIGNALS - */ -extern SIGNAL_HANDLER istat; /* original SIGINT */ -extern SIGNAL_HANDLER qstat; /* original SIGQUIT */ -extern int interrupted; /* SIGINT detected */ -extern int broken_pipe; /* SIGPIPE detected */ -extern int told_to_quit; /* SIGQUIT detected */ - -#ifdef BSD42 -extern int should_intr; /* signal handler should interrupt call */ -extern jmp_buf sigenv; /* the environment pointer */ -#endif - -/* - * prototypes - */ -int readid (int); -int expand (char *); -void m_reset (void); -void fsetup (char *); -void setup (char *); -void readids (int); -void display_info (int); - -void forkcmd (char **s, char *); -void distcmd (char **); -void explcmd (char **); -int filehak (char **); -void filecmd (char **); -void foldcmd (char **); -void forwcmd (char **); -void helpcmd (char **); -void markcmd (char **); -void mhncmd (char **); -void showcmd (char **); -int pack (char *, int, int); -int packhak (char **); -void packcmd (char **); -void pickcmd (char **); -void replcmd (char **); -void rmmcmd (char **); -void scancmd (char **); -void sortcmd (char **); diff --git a/h/prototypes.h b/h/prototypes.h index 1bc19d4..c679ace 100644 --- a/h/prototypes.h +++ b/h/prototypes.h @@ -70,7 +70,6 @@ int m_atoi (char *); char *m_backup (char *); int m_convert (struct msgs *, char *); char *m_draft (char *, char *, int, int *); -void m_eomsbr (int (*)(int)); int m_getfld (int, unsigned char *, unsigned char *, int, FILE *); int m_gmprot (void); char *m_maildir (char *); diff --git a/h/vmhsbr.h b/h/vmhsbr.h deleted file mode 100644 index 0b5a9a3..0000000 --- a/h/vmhsbr.h +++ /dev/null @@ -1,49 +0,0 @@ - -/* - * vmhsbr.h -- definitions for the vmh protocol - */ - -#define RC_VRSN 1 - -/* flags for rh_type */ -#define RC_INI 0x01 /* must be greater than OK */ -#define RC_ACK 0x02 -#define RC_ERR 0x03 -#define RC_CMD 0x04 -#define RC_QRY 0x05 -#define RC_TTY 0x06 -#define RC_WIN 0x07 -#define RC_DATA 0x08 -#define RC_EOF 0x09 -#define RC_FIN 0x0a -#define RC_XXX 0x0b - -struct record { - struct rcheader { - char rh_type; /* type of record */ - int rh_len; /* length of data */ - } rc_header; - char *rc_data; /* extensible array */ -}; - -#define rc_head(rc) (&rc->rc_header) -#define RHSIZE(rc) (sizeof rc->rc_header) -#define rc_type rc_header.rh_type -#define rc_len rc_header.rh_len - -#define initrc(rc) rc->rc_data = NULL - -/* - * prototypes - */ -int rcinit (int, int); -int rcdone (void); -int rc2rc (char, int, char *, struct record *); -int str2rc (char, char *, struct record *); -int peer2rc (struct record *); -int rc2peer (char, int, char *); -int str2peer (char, char *); -int fmt2peer (char, char *, ...); -int err2peer (char, char *, char *, ...); -int verr2peer (char, char *, char *, va_list); - diff --git a/man/Makefile.in b/man/Makefile.in index c822d4a..589a0c8 100644 --- a/man/Makefile.in +++ b/man/Makefile.in @@ -48,7 +48,7 @@ MAN1SRC = ali. anno. burst. comp. \ forw. inc. install-mh. mark. mh-chart. \ nmh. mhbuild. mhl. mhlist. mhmail. \ mhn. mhparam. mhpath. mhshow. \ - mhstore. msgchk. msh. \ + mhstore. msgchk. \ new. fnext. fprev. unseen. \ next. packf. pick. prev. \ prompter. rcvdist. rcvpack. \ @@ -68,9 +68,6 @@ MAN1 = $(MAN1SRC:.=.$(manext1)) MAN5 = $(MAN5SRC:.=.$(manext5)) MAN8 = $(MAN8SRC:.=.$(manext8)) -# Since vmh is not built or distributed, neither should vmh.1 be -# MANEXTRA = vmh. - # source for man pages DIST_MANSRC = $(MAN1SRC) $(MAN5SRC) $(MAN8SRC) DIST_MAN = $(DIST_MANSRC:.=.man) diff --git a/man/burst.man b/man/burst.man index cb1e6f4..d7e28d5 100644 --- a/man/burst.man +++ b/man/burst.man @@ -77,7 +77,7 @@ or .fi .SH "SEE ALSO" -inc(1), msh(1), pack(1), +inc(1), pack(1), .I "Proposed Standard for Message Encapsulation" (RFC\-934) diff --git a/man/mh-chart.man b/man/mh-chart.man index 0c413f8..4414421 100644 --- a/man/mh-chart.man +++ b/man/mh-chart.man @@ -427,16 +427,6 @@ all/mail/nomail ] .RB [ \-help ] .HP 5 -.B msh -.RB [ \-prompt -.IR string ] -.RB [ \-scan " | " \-noscan ] -.RB [ \-topcur " | " \-notopcur ] -.RI [ file ] -.RB [ \-version ] -.RB [ \-help ] - -.HP 5 .B next .RI [ +folder ] .RB [\-showproc diff --git a/man/mh-profile.man b/man/mh-profile.man index 635fc32..19399fb 100644 --- a/man/mh-profile.man +++ b/man/mh-profile.man @@ -504,12 +504,6 @@ program used by to display message bodies (or message parts) of type text/plain. .RE .PP -.BR mshproc : -%bindir%/msh -.RS 5 -Currently not used. -.RE -.PP .BR packproc : %bindir%/packf .RS 5 diff --git a/man/mh-tailor.man b/man/mh-tailor.man index 4f2d755..0cf54dd 100644 --- a/man/mh-tailor.man +++ b/man/mh-tailor.man @@ -17,7 +17,6 @@ At present, these (user) programs are: .BR conflict , .BR inc , .BR msgchk , -.BR msh , .BR post , .BR rcvdist , and diff --git a/man/msh.man b/man/msh.man deleted file mode 100644 index 93d0282..0000000 --- a/man/msh.man +++ /dev/null @@ -1,355 +0,0 @@ -.\" -.\" %nmhwarning% -.\" -.TH MSH %manext1% "%nmhdate%" MH.6.8 [%nmhversion%] -.SH NAME -msh \- nmh shell (and BBoard reader) -.SH SYNOPSIS -.HP 5 -.na -.B msh -.RB [ \-prompt -.IR string ] -.RB [ \-scan " | " \-noscan ] -.RB [ \-topcur " | " \-notopcur ] -.RI [ file ] -.RB [ \-version ] -.RB [ \-help ] -.ad -.SH DESCRIPTION -.B msh -is an interactive program that implements a subset of the normal -.B nmh -commands operating on a single file in -.BR packf 'd format. -That is, -.B msh -is used to read a file that contains a number -of messages, as opposed to the standard -.B nmh -style of reading -a number of files, each file being a separate message in a folder. -.BR msh 's -chief advantage is that the normal -.B nmh -style does not -allow a file to have more than one message in it. Hence, -.B msh -is -ideal for reading BBoards, as these files are delivered by the -transport system in this format. In addition, -.B msh -can be used on -other files, such as message archives which have been -.BR pack ed -(see -.BR packf (1)). -Finally, -.B msh -is an excellent -.B nmh -tutor. -As the only commands available to the user are -.B nmh -commands, this -allows -.B nmh -beginners to concentrate on how commands to -.B nmh -are formed and (more or less) what they mean. -.PP -When invoked, -.B msh -reads the named file, and enters a command loop. -The user may type most of the normal -.B nmh -commands. The syntax and -semantics of these commands typed to -.B msh -are identical to their -.B nmh -counterparts. In cases where the nature of -.B msh -would be -inconsistent (e.g., specifying a -.I +folder -with some commands), -.B msh -will duly inform the user. The commands that -.B msh -currently supports -(in some slightly modified or restricted forms) are: -.PP -.RS 5 -.nf -ali -burst -comp -dist -folder -forw -inc -mark -mhmail -mhn -msgchk -next -packf -pick -prev -refile -repl -rmm -scan -send -show -sortm -whatnow -whom -.fi -.RE -.PP -In addition, -.B msh -has a -.B help -command which gives a -brief overview. To terminate -.BR msh , -type CTRL\-D, or use the -.B quit -command. If -.B msh -is being invoked from -.BR bbc , -then typing CTRL\-D will also tell -.B bbc -to exit as well, while -using the -.B quit -command will return control to -.BR bbc , -and -.B bbc -will continue examining the list of BBoards that it is scanning. -.PP -If the file is writable and has been modified, then using -.B quit -will query the user if the file should be updated. -.PP -The -.B \-prompt -.I string -switch sets the prompting string for -.BR msh . -.PP -You may wish to use an alternate -.B nmh -profile for the commands that -.B msh -executes; see -.BR mh-profile (5) -for details about the -.B $MH -environment variable. -.PP -When invoked from -.BR bbc , -two special features are enabled: -First, the -.B \-scan -switch directs -.B msh -to do a -.RB \*(lq scan -.BR unseen \*(rq -on start\-up if new items are present in the BBoard. This feature is -best used from -.BR bbc , -which correctly sets the stage. Second, the -.B mark -command in -.B msh -acts specially when you are reading a -BBoard, since -.B msh -will consult the sequence \*(lqunseen\*(rq in -determining what messages you have actually read. When -.B msh -exits, -it reports this information to -.BR bbc . -In addition, if you give the -.B mark -command with no arguments, -.B msh -will interpret it as -.RB \*(lq mark -.B \-sequence -.B unseen -.B \-delete -.B \-nozero -.BR all \*(rq -Hence, to discard -all of the messages in the current BBoard you're reading, just use the -.B mark -command with no arguments. -.PP -Normally, the -.B exit -command is identical to the -.B quit -command in -.BR msh . -When run under -.B bbc -however, -.B exit -directs -.B msh -to mark all messages as seen and then -.BR quit . -For speedy type\-in, this command is often abbreviated as just -.BR qe . -.PP -When invoked from -.BR vmh , -another special feature is enabled: -The `topcur' switch directs -.B msh -to have the current message -\*(lqtrack\*(rq the top line of the -.B vmh -scan window. Normally, -.B msh -has the current message \*(lqtrack\*(rq the center of the window -(under -.BR \-notopcur , -which is the default). -.PP -.B msh -supports an output redirection facility. Commands may be -followed by one of -.PP -.RS 5 -.nf -.ta \w'| \fIcommand\fR 'u -^> \fIfile\fR~^write output to \fIfile\fR -^>> \fIfile\fR~^append output to \fIfile\fR -^| \fIcommand\fR~^pipe output to UNIX \fIcommand\fR -.fi -.RE -.PP -If -.I file -starts with a \*(lq\~\*(rq (tilde), then a -.BR csh \-like -expansion -takes place. Note that -.I command -is interpreted by -.BR sh . -Also note that -.B msh -does NOT support history substitutions, variable -substitutions, or alias substitutions. -.PP -When parsing commands to the left of any redirection symbol, -.B msh -will honor `\\' (back\-slash) as the quote next\-character symbol, and -`\*(lq' (double\-quote) as quote\-word delimiters. All other input tokens -are separated by whitespace (spaces and tabs). - -.SH FILES -.fc ^ ~ -.nf -.ta \w'%etcdir%/ExtraBigFileName 'u -^$HOME/\&.mh\(ruprofile~^The user profile -^%etcdir%/mts.conf~^nmh mts configuration file -.fi - -.SH "PROFILE COMPONENTS" -.fc ^ ~ -.nf -.ta 2.4i -.ta \w'ExtraBigProfileName 'u -^Path:~^To determine the user's nmh directory -^Msg\-Protect:~^To set mode when creating a new `file' -^fileproc:~^Program to file messages -^showproc:~^Program to show messages -.fi - -.SH "SEE ALSO" -bbc(1) - -.SH DEFAULTS -.nf -.RB ` file "' defaults to \*(lq./msgbox\*(rq" -.RB ` "\-prompt\ (msh)\ "' -.RB ` \-noscan ' -.RB ` \-notopcur ' -.fi - -.SH CONTEXT -None - -.SH BUGS -The argument to the -.B \-prompt -switch must be interpreted as a single -token by the shell that invokes -.BR msh . -Therefore, one must usually -place the argument to this switch inside double\-quotes. -.PP -There is a strict limit of messages per file in -.BR packf 'd -format which -.B msh -can handle. Usually, this limit is 1000 messages. -.PP -Please remember that -.B msh -is not the C\-Shell, and that a lot of -the nice facilities provided by the latter are not present in the former. -.PP -In particular, -.B msh -does not understand back\-quoting, so the only -effective way to use -.B pick -inside -.B msh -is to always use the -.B \-seq -.I select -switch. Clever users of -.B nmh -will put the line -.P -.RS 5 -pick:\0\-seq\0select\0\-list -.RE -.PP -in their -.I \&.mh\(ruprofile -file so that -.B pick -works equally well from both the shell and -.BR msh . -.PP -.B sortm -always uses -.B \-noverbose -and if -.B \-textfield -.I field -is used, -.B \-limit -.IR 0 . -.PP -The -.B msh -program inherits most (if not all) of the bugs from the -.B nmh -commands it implements. diff --git a/man/nmh.man b/man/nmh.man index 46fd8fb..4c2b59a 100644 --- a/man/nmh.man +++ b/man/nmh.man @@ -213,7 +213,6 @@ commands: ^mhshow(1)~^\- display MIME messages ^mhstore(1)~^\- store contents of MIME messages into files ^msgchk(1)~^\- check for messages -^msh(1)~^\- nmh shell(and BBoard reader) ^next(1)~^\- show the next message ^packf(1)~^\- compress a folder into a single file ^pick(1)~^\- select messages by content diff --git a/man/vmh.man b/man/vmh.man deleted file mode 100644 index 9fe9220..0000000 --- a/man/vmh.man +++ /dev/null @@ -1,101 +0,0 @@ -.\" -.\" %nmhwarning% -.\" -.TH VMH %manext1% "%nmhdate%" MH.6.8 [%nmhversion%] -.SH NAME -vmh \- visual front-end to nmh -.SH SYNOPSIS -.in +.5i -.ti -.5i -vmh -\%[\-prompt\ string] -\%[\-vmhproc\ program] \%[\-novmhproc] -.br -\%[switches\ for\ \fIvmhproc\fR] -\%[\-version] -\%[\-help] -.in -.5i -.SH DESCRIPTION -\fIvmh\fR is a program which implements the server side of the \fInmh\fR -window management protocol and uses \fIcurses\fR\0(3) routines to maintain -a split\-screen interface to any program which implements the client -side of the protocol. This latter program, called the \fIvmhproc\fR, -is specified using the `\-vmhproc\ program' switch. - -The upshot of all this is that one can run \fImsh\fR on a display terminal -and get a nice visual interface. To do this, for example, just add -the line - -.ti +.5i -mshproc: vmh - -to your \&.mh\(ruprofile. (This takes advantage of the fact that -\fImsh\fR is the default \fIvmhproc\fR for \fIvmh\fR.) - -In order to facilitate things, if the `\-novmhproc' switch is given, -and \fIvmh\fR can't run on the user's terminal, the \fIvmhproc\fR is -run directly without the window management protocol. - -After initializing the protocol, \fIvmh\fR prompts the user for a command -to be given to the client. Usually, this results in output being sent to -one or more windows. If a output to a window would cause it to scroll, -\fIvmh\fR prompts the user for instructions, roughly permitting the -capabilities of \fIless\fR or \fImore\fR (e.g., the ability to scroll -backwards and forwards): - -.nf -.in +.5i -.ta \w'RETURN 'u +\w'* 'u -SPACE advance to the next windowful -RETURN * advance to the next line -y * retreat to the previous line -d * advance to the next ten lines -u * retreat to the previous ten lines -g * go to an arbitrary line - (preceed g with the line number) -G * go to the end of the window - (if a line number is given, this acts like `g') -CTRL\-L refresh the entire screen -h print a help message -q abort the window -.re -.in -.5i -.fi - -(A `*' indicates that a numeric prefix is meaningful for this command.) - -Note that if a command resulted in more than one window's worth of -information being displayed, and you allow the command which is generating -information for the window to gracefully finish (i.e., you don't use -the `q' command to abort information being sent to the window), then -\fIvmh\fR will give you one last change to peruse the window. This is -useful for scrolling back and forth. Just type `q' when you're done. - -To abnormally terminate \fIvmh\fR (without core dump), use -(usually CTRL\-\\). For instance, this does the \*(lqright\*(rq thing -with \fIbbc\fR and \fImsh\fR. - -.Fi -^$HOME/\&.mh\(ruprofile~^The user profile -.Pr -^Path:~^To determine the user's nmh directory -.Sa -msh(1) -.De -`\-prompt\ (vmh)\ ' -.Ds -`\-vmhproc\ msh' -.Co -None -.Bu -The argument to the `\-prompt' switch must be interpreted as a single -token by the shell that invokes \fIvmh\fR. Therefore, one must usually -place the argument to this switch inside double\-quotes. - -At present, there is no way to pass signals (e.g., interrupt, quit) to -the client. However, generating QUIT when \fIvmh\fR is reading a command -from the terminal is sufficient to tell the client to go away quickly. - -Acts strangely (loses peer or botches window management protocol with -peer) on random occasions. -.En diff --git a/sbr/context_foil.c b/sbr/context_foil.c index 12dab45..4a6e89b 100644 --- a/sbr/context_foil.c +++ b/sbr/context_foil.c @@ -24,7 +24,7 @@ context_foil (char *path) * it's been set by us -- the uses in the source tree are: * 1 sbr/context_read.c uses it only after setting it itself * 2 uip/install_mh.c uses it only after setting it itself - * 3 uip/mshcmds.c and uip/mark.c print it if given the -debug switch + * 3 uip/mark.c print it if given the -debug switch * A worthwhile piece of code cleanup would be to make 1 and * 2 use a local variable and just delete 3. * diff --git a/sbr/m_getfld.c b/sbr/m_getfld.c index be871c4..42bb72f 100644 --- a/sbr/m_getfld.c +++ b/sbr/m_getfld.c @@ -48,6 +48,9 @@ loop caused m_getfld() to return FMTERR. So, that logic was changed to check for (*eom_action) and act accordingly. + [ Note by meillo 2011-10: + as msh was removed from mmh, m_eomsbr() became irrelevant. ] + This worked fine, until one day: someone didn't use four CTRL:A's as their delimiters. So, the bullet got bit and we read mts.h and continue to struggle on. It's not that bad though, since the only time @@ -665,23 +668,6 @@ m_unknown(FILE *iob) } -void -m_eomsbr (int (*action)(int)) -{ - if ((eom_action = action)) { - msg_style = MS_MSH; - *msg_delim = 0; - fdelimlen = 1; - delimend = fdelim; - } else { - msg_style = MS_MMDF; - msg_delim = (char *)fdelim + 1; - fdelimlen = strlen((char *)fdelim); - delimend = (unsigned char *)(msg_delim + edelimlen); - } -} - - /* * test for msg delimiter string */ diff --git a/sbr/readconfig.c b/sbr/readconfig.c index 6eca286..671ada3 100644 --- a/sbr/readconfig.c +++ b/sbr/readconfig.c @@ -30,7 +30,6 @@ static struct procstr procs[] = { { "mailproc", &mailproc }, { "mhlproc", &mhlproc }, { "moreproc", &moreproc }, - { "mshproc", &mshproc }, { "packproc", &packproc }, { "postproc", &postproc }, { "rmfproc", &rmfproc }, @@ -39,7 +38,6 @@ static struct procstr procs[] = { { "sendproc", &sendproc }, { "showmimeproc", &showmimeproc }, { "showproc", &showproc }, - { "vmhproc", &vmhproc }, { "whatnowproc", &whatnowproc }, { "whomproc", &whomproc }, { NULL, NULL } diff --git a/uip/Makefile.in b/uip/Makefile.in index 2beef92..2423185 100644 --- a/uip/Makefile.in +++ b/uip/Makefile.in @@ -52,12 +52,9 @@ SETGID_MAIL = @SETGID_MAIL@ # commands to build CMDS = ali anno burst comp dist flist folder forw install-mh mark mhbuild \ mhlist mhmail mhn mhparam mhpath mhshow mhstore msgchk \ - msh new packf pick prompter refile repl rmf rmm scan send show \ + new packf pick prompter refile repl rmf rmm scan send show \ sortm whatnow whom -## removed this from CMDS until I can fix it -## OTHERCMDS = vmh - # commands that are links to other commands LCMDS = flists folders next prev @@ -75,11 +72,11 @@ SRCS = ali.c aliasbr.c anno.c annosbr.c ap.c burst.c comp.c \ mhbuildsbr.c mhcachesbr.c mhfree.c mhl.c mhlist.c mhlistsbr.c \ mhlsbr.c mhmail.c mhmisc.c mhn.c mhoutsbr.c mhparam.c mhparse.c \ mhpath.c mhshow.c mhshowsbr.c mhstore.c mhstoresbr.c mhtest.c \ - msgchk.c msh.c mshcmds.c new.c packf.c pick.c picksbr.c \ + msgchk.c new.c packf.c pick.c picksbr.c \ prompter.c rcvdist.c rcvpack.c rcvstore.c rcvtty.c \ refile.c repl.c replsbr.c rmf.c rmm.c scan.c scansbr.c send.c \ sendsbr.c show.c slocal.c sortm.c spost.c termsbr.c viamail.c \ - vmh.c vmhsbr.c vmhtest.c whatnow.c whatnowproc.c whatnowsbr.c \ + whatnow.c whatnowproc.c whatnowsbr.c \ whom.c # auxiliary files @@ -172,9 +169,6 @@ mhtest: mhtest.o mhparse.o mhcachesbr.o mhoutsbr.o mhmisc.o mhfree.o ftpsbr.o te msgchk: msgchk.o $(LOCALLIBS) $(LINK) msgchk.o $(LINKLIBS) -msh: msh.o mshcmds.o vmhsbr.o picksbr.o scansbr.o dropsbr.o mhlsbr.o termsbr.o $(LOCALLIBS) - $(LINK) msh.o mshcmds.o vmhsbr.o picksbr.o scansbr.o dropsbr.o mhlsbr.o termsbr.o $(LINKLIBS) $(TERMLIB) - new: new.o $(LOCALLIBS) $(LINK) new.o $(LINKLIBS) @@ -232,9 +226,6 @@ spost: spost.o aliasbr.o $(LOCALLIBS) viamail: viamail.o mhmisc.o mhoutsbr.o sendsbr.o annosbr.o distsbr.o $(LOCALLIBS) $(LINK) viamail.o mhmisc.o mhoutsbr.o sendsbr.o annosbr.o distsbr.o $(LINKLIBS) $(TERMLIB) -vmh: vmh.o vmhsbr.o $(LOCALLIBS) - $(LINK) vmh.o vmhsbr.o $(LINKLIBS) $(TERMLIB) - whatnow: whatnow.o whatnowsbr.o sendsbr.o annosbr.o distsbr.o $(LOCALLIBS) $(LINK) whatnow.o whatnowsbr.o sendsbr.o annosbr.o distsbr.o $(LINKLIBS) diff --git a/uip/mhparam.c b/uip/mhparam.c index 137a635..eae587d 100644 --- a/uip/mhparam.c +++ b/uip/mhparam.c @@ -51,7 +51,6 @@ static struct proc procs [] = { { "mhlproc", &mhlproc }, { "moreproc", &moreproc }, { "msgprot", &msgprot }, - { "mshproc", &mshproc }, { "packproc", &packproc }, { "postproc", &postproc }, { "rmfproc", &rmfproc }, @@ -61,7 +60,6 @@ static struct proc procs [] = { { "showmimeproc", &showmimeproc }, { "showproc", &showproc }, { "version", &version_num }, - { "vmhproc", &vmhproc }, { "whatnowproc", &whatnowproc }, { "whomproc", &whomproc }, { "etcdir", &mhetcdir }, diff --git a/uip/msh.c b/uip/msh.c deleted file mode 100644 index c2d4e1a..0000000 --- a/uip/msh.c +++ /dev/null @@ -1,2395 +0,0 @@ - -/* - * msh.c -- The nmh shell - * - * 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. - */ - -/* - * TODO: - * Keep more status information in maildrop map - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef HAVE_TERMIOS_H -# include -#else -# ifdef HAVE_TERMIO_H -# include -# else -# include -# endif -#endif - -#include -#include -#include -#include -#include - -#define QUOTE '\\' /* sigh */ - -static struct swit switches[] = { -#define IDSW 0 - { "idstart number", -7 }, /* interface from bbc */ -#define FDSW 1 - { "idstop number", -6 }, /* .. */ -#define QDSW 2 - { "idquit number", -6 }, /* .. */ -#define NMSW 3 - { "idname BBoard", -6 }, /* .. */ -#define PRMPTSW 4 - { "prompt string", 0 }, -#define SCANSW 5 - { "scan", 0 }, -#define NSCANSW 6 - { "noscan", 0 }, -#define READSW 7 - { "vmhread fd", -7 }, -#define WRITESW 8 - { "vmhwrite fd", -8 }, -#define PREADSW 9 - { "popread fd", -7 }, -#define PWRITSW 10 - { "popwrite fd", -8 }, -#define TCURSW 11 - { "topcur", 0 }, -#define NTCURSW 12 - { "notopcur", 0 }, -#define VERSIONSW 13 - { "version", 0 }, -#define HELPSW 14 - { "help", 0 }, - { NULL, 0 } -}; - -static int mbx_style = MMDF_FORMAT; - -/* - * FOLDER - */ -char*fmsh = NULL; /* folder instead of file */ -int modified; /* command modified folder */ -struct msgs *mp; /* used a lot */ -static int nMsgs = 0; -struct Msg *Msgs = NULL; /* Msgs[0] not used */ -static FILE *fp; /* input file */ -static FILE *yp = NULL; /* temporary file */ -static int mode; /* mode of file */ -static int numfds = 0; /* number of files cached */ -static int maxfds = 0; /* number of files cached to be cached */ -static time_t mtime = (time_t) 0; /* mtime of file */ - -/* - * VMH - */ -#define ALARM ((unsigned int) 10) -#define ttyN(c) ttyNaux ((c), NULL) - -static int vmh = 0; - -static int vmhpid = OK; -static int vmhfd0; -static int vmhfd1; -static int vmhfd2; - -static int vmhtty = NOTOK; - -#define SCAN 1 -#define STATUS 2 -#define DISPLAY 3 -#define NWIN DISPLAY - -static int topcur = 0; - -static int numwins = 0; -static int windows[NWIN + 1]; - -static jmp_buf peerenv; - -/* - * PARENT - */ -static int pfd = NOTOK; /* fd parent is reading from */ -static int ppid = 0; /* pid of parent */ - -/* - * COMMAND - */ -int interactive; /* running from a /dev/tty */ -int redirected; /* re-directing output */ -FILE *sp = NULL; /* original stdout */ - -char *cmd_name; /* command being run */ -char myfilter[BUFSIZ]; /* path to mhl.forward */ - -static char *myprompt = "(%s) ";/* prompting string */ - -/* - * BBOARDS - */ -static int gap; /* gap in BBoard-ID:s */ -static char *myname = NULL; /* BBoard name */ -char *BBoard_ID = "BBoard-ID"; /* BBoard-ID constant */ - -/* - * SIGNALS - */ -SIGNAL_HANDLER istat; /* original SIGINT */ -static SIGNAL_HANDLER pstat; /* current SIGPIPE */ -SIGNAL_HANDLER qstat; /* original SIGQUIT */ - -#ifdef SIGTSTP -SIGNAL_HANDLER tstat; /* original SIGTSTP */ -#endif - -int interrupted; /* SIGINT detected */ -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); -int expand (char *); -void m_reset (void); -void seq_setcur (struct msgs *, int); -void padios (char *, char *, ...); -void padvise (char *, char *, ...); - - -/* - * static prototypes - */ -static void msh (int); -static int read_map (char *, long); -static int read_file (long, int); - -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 write_ids (void); -static void quit (void); -static int getargs (char *, struct swit *, struct Cmd *); -static int getcmds (struct swit *, struct Cmd *, int); -static int parse (char *, struct Cmd *); -static int init_io (struct Cmd *, int); -static int initaux_io (struct Cmd *); -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 int pINI (void); -static int pQRY (char *, int); -static int pQRY1 (int); -static int pQRY2 (void); -static int pCMD (char *, struct swit *, struct Cmd *); -static int pFIN (void); -static int peerwait (void); -static int ttyNaux (struct Cmd *, char *); -static int ttyR (struct Cmd *); -static int winN (struct Cmd *, int, int); -static int winR (struct Cmd *); -static int winX (int); - - -int -main (int argc, char **argv) -{ - int id = 0, scansw = 0, vmh1 = 0, vmh2 = 0; - char *cp, *file = NULL, *folder = NULL; - char **argp, **arguments, buf[BUFSIZ]; - -#ifdef LOCALE - setlocale(LC_ALL, ""); -#endif - invo_name = r1bindex (argv[0], '/'); - - /* read user profile/context */ - context_read(); - - mts_init (invo_name); - arguments = getarguments (invo_name, argc,argv, 1); - argp = arguments; - - while ((cp = *argp++)) { - if (*cp == '-') - switch (smatch (++cp, switches)) { - case AMBIGSW: - ambigsw (cp, switches); - done (1); - case UNKWNSW: - adios (NULL, "-%s unknown", cp); - - case HELPSW: - snprintf (buf, sizeof(buf), "%s [switches] file", invo_name); - print_help (buf, switches, 1); - done (1); - case VERSIONSW: - print_version(invo_name); - done (1); - - case IDSW: - if (!(cp = *argp++) || *cp == '-') - adios (NULL, "missing argument to %s", argp[-2]); - if ((id = atoi (cp)) < 1) - adios (NULL, "bad argument %s %s", argp[-2], cp); - continue; - case FDSW: - if (!(cp = *argp++) || *cp == '-') - adios (NULL, "missing argument to %s", argp[-2]); - if ((pfd = atoi (cp)) <= 1) - adios (NULL, "bad argument %s %s", argp[-2], cp); - continue; - case QDSW: - if (!(cp = *argp++) || *cp == '-') - adios (NULL, "missing argument to %s", argp[-2]); - if ((ppid = atoi (cp)) <= 1) - adios (NULL, "bad argument %s %s", argp[-2], cp); - continue; - case NMSW: - if (!(myname = *argp++) || *myname == '-') - adios (NULL, "missing argument to %s", argp[-2]); - continue; - - case SCANSW: - scansw++; - continue; - case NSCANSW: - scansw = 0; - continue; - - case PRMPTSW: - if (!(myprompt = *argp++) || *myprompt == '-') - adios (NULL, "missing argument to %s", argp[-2]); - continue; - - case READSW: - if (!(cp = *argp++) || *cp == '-') - adios (NULL, "missing argument to %s", argp[-2]); - if ((vmh1 = atoi (cp)) < 1) - adios (NULL, "bad argument %s %s", argp[-2], cp); - continue; - case WRITESW: - if (!(cp = *argp++) || *cp == '-') - adios (NULL, "missing argument to %s", argp[-2]); - if ((vmh2 = atoi (cp)) < 1) - adios (NULL, "bad argument %s %s", argp[-2], cp); - continue; - - case PREADSW: - if (!(cp = *argp++) || *cp == '-') - adios (NULL, "missing argument to %s", argp[-2]); - continue; - case PWRITSW: - if (!(cp = *argp++) || *cp == '-') - adios (NULL, "missing argument to %s", argp[-2]); - continue; - - case TCURSW: - topcur++; - continue; - case NTCURSW: - topcur = 0; - continue; - } - if (*cp == '+' || *cp == '@') { - if (folder) - adios (NULL, "only one folder at a time!"); - else - folder = pluspath (cp); - } - else - if (file) - adios (NULL, "only one file at a time!"); - else - file = cp; - } - - if (!file && !folder) - file = "./msgbox"; - if (file && folder) - adios (NULL, "use a file or a folder, not both"); - strncpy (myfilter, etcpath (mhlforward), sizeof(myfilter)); -#ifdef FIOCLEX - if (pfd > 1) - ioctl (pfd, FIOCLEX, NULL); -#endif /* FIOCLEX */ - -#ifdef BSD42 - should_intr = 0; -#endif /* BSD42 */ - istat = SIGNAL2 (SIGINT, intrser); - qstat = SIGNAL2 (SIGQUIT, quitser); - - sc_width (); /* MAGIC... */ - - if ((vmh = vmh1 && vmh2)) { - rcinit (vmh1, vmh2); - pINI (); - SIGNAL (SIGINT, SIG_IGN); - SIGNAL (SIGQUIT, SIG_IGN); -#ifdef SIGTSTP - tstat = SIGNAL (SIGTSTP, SIG_IGN); -#endif /* SIGTSTP */ - } - - if (folder) - fsetup (folder); - else - setup (file); - readids (id); - display_info (id > 0 ? scansw : 0); - - msh (id > 0 ? scansw : 0); - - m_reset (); - - done (0); - return 1; -} - - -static struct swit mshcmds[] = { -#define ADVCMD 0 - { "advance", -7 }, -#define ALICMD 1 - { "ali", 0 }, -#define EXPLCMD 2 - { "burst", 0 }, -#define COMPCMD 3 - { "comp", 0 }, -#define DISTCMD 4 - { "dist", 0 }, -#define EXITCMD 5 - { "exit", 0 }, -#define FOLDCMD 6 - { "folder", 0 }, -#define FORWCMD 7 - { "forw", 0 }, -#define HELPCMD 8 - { "help", 0 }, -#define INCMD 9 - { "inc", 0 }, -#define MARKCMD 10 - { "mark", 0 }, -#define MAILCMD 11 - { "mhmail", 0 }, -#define MHNCMD 12 - { "mhn", 0 }, -#define MSGKCMD 13 - { "msgchk", 0 }, -#define NEXTCMD 14 - { "next", 0 }, -#define PACKCMD 15 - { "packf", 0 }, -#define PICKCMD 16 - { "pick", 0 }, -#define PREVCMD 17 - { "prev", 0 }, -#define QUITCMD 18 - { "quit", 0 }, -#define FILECMD 19 - { "refile", 0 }, -#define REPLCMD 20 - { "repl", 0 }, -#define RMMCMD 21 - { "rmm", 0 }, -#define SCANCMD 22 - { "scan", 0 }, -#define SENDCMD 23 - { "send", 0 }, -#define SHOWCMD 24 - { "show", 0 }, -#define SORTCMD 25 - { "sortm", 0 }, -#define WHATCMD 26 - { "whatnow", 0 }, -#define WHOMCMD 27 - { "whom", 0 }, - { NULL, 0 } -}; - - -static void -msh (int scansw) -{ - int i; - register char *cp, **ap; - char prompt[BUFSIZ], *vec[MAXARGS]; - struct Cmd typein; - register struct Cmd *cmdp; - static int once_only = ADVCMD; - - snprintf (prompt, sizeof(prompt), myprompt, invo_name); - cmdp = &typein; - - for (;;) { - if (yp) { - fclose (yp); - yp = NULL; - } - if (vmh) { - if ((i = getcmds (mshcmds, cmdp, scansw)) == EOF) { - rcdone (); - return; - } - } else { - check_folder (scansw); - if ((i = getargs (prompt, mshcmds, cmdp)) == EOF) { - putchar ('\n'); - return; - } - } - cmd_name = mshcmds[i].sw; - - switch (i) { - case QUITCMD: - quit (); - return; - - case ADVCMD: - if (once_only == ADVCMD) - once_only = i = SHOWCMD; - else - i = mp->curmsg != mp->hghmsg ? NEXTCMD : EXITCMD; - cmd_name = mshcmds[i].sw; - /* and fall... */ - - case EXITCMD: - case EXPLCMD: - case FOLDCMD: - case FORWCMD: /* sigh */ - case MARKCMD: - case NEXTCMD: - case PACKCMD: - case PICKCMD: - case PREVCMD: - case RMMCMD: - case SHOWCMD: - case SCANCMD: - case SORTCMD: - if ((cp = context_find (cmd_name))) { - cp = getcpy (cp); - ap = brkstring (cp, " ", "\n"); - ap = copyip (ap, vec, MAXARGS); - } else { - ap = vec; - } - break; - - default: - cp = NULL; - ap = vec; - break; - } - copyip (cmdp->args + 1, ap, MAXARGS); - - m_init (); - - if (!vmh && init_io (cmdp, vmh) == NOTOK) { - if (cp != NULL) - free (cp); - continue; - } - modified = 0; - redirected = vmh || cmdp->direction != STDIO; - - switch (i) { - case ALICMD: - case COMPCMD: - case INCMD: - case MAILCMD: - case MSGKCMD: - case SENDCMD: - case WHATCMD: - case WHOMCMD: - if (!vmh || ttyN (cmdp) != NOTOK) - forkcmd (vec, cmd_name); - break; - - case DISTCMD: - if (!vmh || ttyN (cmdp) != NOTOK) - distcmd (vec); - break; - - case EXPLCMD: - if (!vmh || winN (cmdp, DISPLAY, 1) != NOTOK) - explcmd (vec); - break; - - case FILECMD: - if (!vmh - || (filehak (vec) == OK ? ttyN (cmdp) - : winN (cmdp, DISPLAY, 1)) != NOTOK) - filecmd (vec); - break; - - case FOLDCMD: - if (!vmh || winN (cmdp, DISPLAY, 1) != NOTOK) - foldcmd (vec); - break; - - case FORWCMD: - if (!vmh || ttyN (cmdp) != NOTOK) - forwcmd (vec); - break; - - case HELPCMD: - if (!vmh || winN (cmdp, DISPLAY, 1) != NOTOK) - helpcmd (vec); - break; - - case EXITCMD: - case MARKCMD: - if (!vmh || winN (cmdp, DISPLAY, 1) != NOTOK) - markcmd (vec); - break; - - case MHNCMD: - if (!vmh || ttyN (cmdp) != NOTOK) - mhncmd (vec); - break; - - case NEXTCMD: - case PREVCMD: - case SHOWCMD: - if (!vmh || winN (cmdp, DISPLAY, 1) != NOTOK) - showcmd (vec); - break; - - case PACKCMD: - if (!vmh - || (packhak (vec) == OK ? ttyN (cmdp) - : winN (cmdp, DISPLAY, 1)) != NOTOK) - packcmd (vec); - break; - - case PICKCMD: - if (!vmh || winN (cmdp, DISPLAY, 1) != NOTOK) - pickcmd (vec); - break; - - case REPLCMD: - if (!vmh || ttyN (cmdp) != NOTOK) - replcmd (vec); - break; - - case RMMCMD: - if (!vmh || winN (cmdp, DISPLAY, 1) != NOTOK) - rmmcmd (vec); - break; - - case SCANCMD: - if (!vmh || winN (cmdp, DISPLAY, 1) != NOTOK) - scancmd (vec); - break; - - case SORTCMD: - if (!vmh || winN (cmdp, DISPLAY, 1) != NOTOK) - sortcmd (vec); - break; - - default: - padios (NULL, "no dispatch for %s", cmd_name); - } - - if (vmh) { - if (vmhtty != NOTOK) - ttyR (cmdp); - if (vmhpid > OK) - winR (cmdp); - } - else - fin_io (cmdp, vmh); - if (cp != NULL) - free (cp); - if (i == EXITCMD) { - quit (); - return; - } - } -} - - -void -fsetup (char *folder) -{ - register int msgnum; - char *maildir; - struct stat st; - - maildir = m_maildir (folder); - if (chdir (maildir) == NOTOK) - padios (maildir, "unable to change directory to"); - - /* read folder and create message structure */ - if (!(mp = folder_read (folder))) - padios (NULL, "unable to read folder %s", folder); - - /* check for empty folder */ - if (mp->nummsg == 0) - padios (NULL, "no messages in %s", folder); - - mode = m_gmprot (); - mtime = stat (mp->foldpath, &st) != NOTOK ? st.st_mtime : 0; - - m_gMsgs (mp->hghmsg); - - for (msgnum = mp->lowmsg; msgnum <= mp->hghmsg; msgnum++) { - Msgs[msgnum].m_bboard_id = 0; - Msgs[msgnum].m_top = NOTOK; - Msgs[msgnum].m_start = Msgs[msgnum].m_stop = 0L; - Msgs[msgnum].m_scanl = NULL; - } - - m_init (); - - fmsh = getcpy (folder); - - maxfds = OPEN_MAX / 2; - - if ((maxfds -= 2) < 1) - maxfds = 1; -} - - -void -setup (char *file) -{ - int i, msgp; - struct stat st; - if ((fp = fopen (file, "r")) == NULL) - padios (file, "unable to read"); -#ifdef FIOCLEX - ioctl (fileno (fp), FIOCLEX, NULL); -#endif /* FIOCLEX */ - if (fstat (fileno (fp), &st) != NOTOK) { - mode = (int) (st.st_mode & 0777), mtime = st.st_mtime; - msgp = read_map (file, (long) st.st_size); - } - else { - mode = m_gmprot (), mtime = 0; - msgp = 0; - } - - if ((msgp = read_file (msgp ? Msgs[msgp].m_stop : 0L, msgp + 1)) < 1) - padios (NULL, "no messages in %s", myname ? myname : file); - - if (!(mp = (struct msgs *) calloc ((size_t) 1, sizeof(*mp)))) - padios (NULL, "unable to allocate folder storage"); - - if (!(mp->msgstats = calloc ((size_t) msgp + 3, sizeof(*(mp->msgstats))))) - padios (NULL, "unable to allocate message status storage"); - - mp->hghmsg = msgp; - mp->nummsg = msgp; - mp->lowmsg = 1; - mp->curmsg = 0; - mp->foldpath = getcpy (myname ? myname : file); - clear_folder_flags (mp); - - stat (file, &st); - if (st.st_uid != getuid () || access (file, W_OK) == NOTOK) - set_readonly (mp); - - mp->lowoff = 1; - mp->hghoff = mp->hghmsg + 1; - - for (i = mp->lowmsg; i <= mp->hghmsg; i++) { - clear_msg_flags (mp, i); - set_exists (mp, i); - } - m_init (); - - mp->msgattrs[0] = getcpy ("unseen"); - mp->msgattrs[1] = NULL; - - m_unknown (fp); /* the MAGIC invocation */ - if (fmsh) { - free (fmsh); - fmsh = NULL; - } -} - - -static int -read_map (char *file, long size) -{ - register int i, msgp; - register struct drop *dp, *mp; - struct drop *rp; - - if ((i = map_read (file, size, &rp, 1)) == 0) - return 0; - - m_gMsgs (i); - - msgp = 1; - for (dp = rp + 1; i-- > 0; msgp++, dp++) { - mp = &Msgs[msgp].m_drop; - mp->d_id = dp->d_id; - mp->d_size = dp->d_size; - mp->d_start = dp->d_start; - mp->d_stop = dp->d_stop; - Msgs[msgp].m_scanl = NULL; - } - free ((char *) rp); - - return (msgp - 1); -} - - -static int -read_file (long pos, int msgp) -{ - register int i; - register struct drop *dp, *mp; - struct drop *rp; - - if ((i = mbx_read (fp, pos, &rp, 1)) <= 0) - return (msgp - 1); - - m_gMsgs ((msgp - 1) + i); - - for (dp = rp; i-- > 0; msgp++, dp++) { - mp = &Msgs[msgp].m_drop; - mp->d_id = 0; - mp->d_size = dp->d_size; - mp->d_start = dp->d_start; - mp->d_stop = dp->d_stop; - Msgs[msgp].m_scanl = NULL; - } - free ((char *) rp); - - return (msgp - 1); -} - - -static void -m_gMsgs (int n) -{ - int nmsgs; - - if (Msgs == NULL) { - nMsgs = n + MAXFOLDER / 2; - Msgs = (struct Msg *) calloc ((size_t) (nMsgs + 2), sizeof *Msgs); - if (Msgs == NULL) - padios (NULL, "unable to allocate Msgs structure"); - return; - } - - if (nMsgs >= n) - return; - - nmsgs = nMsgs + n + MAXFOLDER / 2; - Msgs = (struct Msg *) mh_xrealloc ((char *) Msgs, (size_t) (nmsgs + 2) * sizeof *Msgs); - memset((char *) (Msgs + nMsgs + 2), 0, (size_t) ((nmsgs - nMsgs) * sizeof *Msgs)); - - nMsgs = nmsgs; -} - - -FILE * -msh_ready (int msgnum, int full) -{ - register int msgp; - int fd; - char *cp; - - if (yp) { - fclose (yp); - yp = NULL; - } - - if (fmsh) { - if ((fd = Msgs[msgnum].m_top) == NOTOK) { - if (numfds >= maxfds) - for (msgp = mp->lowmsg; msgp <= mp->hghmsg; msgp++) - if (Msgs[msgp].m_top != NOTOK) { - close (Msgs[msgp].m_top); - Msgs[msgp].m_top = NOTOK; - numfds--; - break; - } - - if ((fd = open (cp = m_name (msgnum), O_RDONLY)) == NOTOK) - padios (cp, "unable to open message"); - Msgs[msgnum].m_top = fd; - numfds++; - } - - if ((fd = dup (fd)) == NOTOK) - padios ("cached message", "unable to dup"); - if ((yp = fdopen (fd, "r")) == NULL) - padios (NULL, "unable to fdopen cached message"); - fseek (yp, 0L, SEEK_SET); - return yp; - } - - m_eomsbr ((int (*)()) 0); /* XXX */ - fseek (fp, Msgs[msgnum].m_start, SEEK_SET); - return fp; -} - - -static int -check_folder (int scansw) -{ - int seqnum, i, low, hgh, msgp; - struct stat st; - - if (fmsh) { - if (stat (mp->foldpath, &st) == NOTOK) - padios (mp->foldpath, "unable to stat"); - if (mtime == st.st_mtime) - return 0; - mtime = st.st_mtime; - - low = mp->hghmsg + 1; - folder_free (mp); /* free folder/message structure */ - - if (!(mp = folder_read (fmsh))) - padios (NULL, "unable to re-read folder %s", fmsh); - - hgh = mp->hghmsg; - - for (msgp = mp->lowmsg; msgp <= mp->hghmsg; msgp++) { - if (Msgs[msgp].m_top != NOTOK) { - close (Msgs[msgp].m_top); - Msgs[msgp].m_top = NOTOK; - numfds--; - } - if (Msgs[msgp].m_scanl) { - free (Msgs[msgp].m_scanl); - Msgs[msgp].m_scanl = NULL; - } - } - - m_init (); - - if (modified || low > hgh) - return 1; - goto check_vmh; - } - if (fstat (fileno (fp), &st) == NOTOK) - padios (mp->foldpath, "unable to fstat"); - if (mtime == st.st_mtime) - return 0; - mode = (int) (st.st_mode & 0777); - mtime = st.st_mtime; - - if ((msgp = read_file (Msgs[mp->hghmsg].m_stop, mp->hghmsg + 1)) < 1) - padios (NULL, "no messages in %s", mp->foldpath); /* XXX */ - if (msgp >= MAXFOLDER) - padios (NULL, "more than %d messages in %s", MAXFOLDER, - mp->foldpath); - if (msgp <= mp->hghmsg) - return 0; /* XXX */ - - if (!(mp = folder_realloc (mp, mp->lowoff, msgp))) - padios (NULL, "unable to allocate folder storage"); - - low = mp->hghmsg + 1, hgh = msgp; - seqnum = scansw ? seq_getnum (mp, "unseen") : -1; - for (i = mp->hghmsg + 1; i <= msgp; i++) { - set_exists(mp, i); - if (seqnum != -1) - add_sequence(mp, seqnum, i); - mp->nummsg++; - } - mp->hghmsg = msgp; - m_init (); - -check_vmh: ; - if (vmh) - return 1; - - advise (NULL, "new messages have arrived!\007"); - if (scansw) - scanrange (low, hgh); - - return 1; -} - - -static void -scanrange (int low, int hgh) -{ - char buffer[BUFSIZ]; - - snprintf (buffer, sizeof(buffer), "%d-%d", low, hgh); - scanstring (buffer); -} - - -static void -scanstring (char *arg) -{ - char *cp, **ap, *vec[MAXARGS]; - - /* - * This should be replace with a call to getarguments() - */ - if ((cp = context_find (cmd_name = "scan"))) { - cp = getcpy (cp); - ap = brkstring (cp, " ", "\n"); - ap = copyip (ap, vec, MAXARGS); - } else { - ap = vec; - } - *ap++ = arg; - *ap = NULL; - m_init (); - scancmd (vec); - if (cp != NULL) - free (cp); -} - - -void -readids (int id) -{ - register int cur, seqnum, i=0, msgnum; - - if (mp->curmsg == 0) - seq_setcur (mp, mp->lowmsg); - if (id <= 0 || (seqnum = seq_getnum (mp, "unseen")) == -1) - return; - - for (msgnum = mp->hghmsg; msgnum >= mp->lowmsg; msgnum--) - add_sequence(mp, seqnum, msgnum); - - if (id != 1) { - cur = mp->curmsg; - - for (msgnum = mp->hghmsg; msgnum >= mp->lowmsg; msgnum--) - if (does_exist(mp, msgnum)) /* FIX */ - if ((i = readid (msgnum)) > 0 && i < id) { - cur = msgnum + 1; - clear_sequence(mp, seqnum, msgnum); - break; - } - for (i = mp->lowmsg; i < msgnum; i++) - clear_sequence(mp, seqnum, i); - - if (cur > mp->hghmsg) - cur = mp->hghmsg; - - seq_setcur (mp, cur); - } - - if ((gap = 1 < id && id < (i = readid (mp->lowmsg)) ? id : 0) && !vmh) - advise (NULL, "gap in ID:s, last seen %d, lowest present %d\n", - id - 1, i); -} - - -int -readid (int msgnum) -{ - int i, state; - char *bp, buf[BUFSIZ], name[NAMESZ]; - register FILE *zp; - - if (Msgs[msgnum].m_bboard_id) - return Msgs[msgnum].m_bboard_id; - - zp = msh_ready (msgnum, 0); - for (state = FLD;;) - switch (state = m_getfld (state, name, buf, sizeof(buf), zp)) { - case FLD: - case FLDEOF: - case FLDPLUS: - if (!mh_strcasecmp (name, BBoard_ID)) { - bp = getcpy (buf); - while (state == FLDPLUS) { - state = m_getfld (state, name, buf, sizeof(buf), zp); - bp = add (buf, bp); - } - i = atoi (bp); - free (bp); - if (i > 0) - return (Msgs[msgnum].m_bboard_id = i); - else - continue; - } - while (state == FLDPLUS) - state = m_getfld (state, name, buf, sizeof(buf), zp); - if (state != FLDEOF) - continue; - - default: - return 0; - } -} - - -void -display_info (int scansw) -{ - int seqnum, sd; - - interactive = isatty (fileno (stdout)); - 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"); - } - - m_putenv ("mhfolder", mp->foldpath); - if (vmh) - return; - - if (myname) { - printf ("Reading "); - if (SOprintf ("%s", myname)) - printf ("%s", myname); - printf (", currently at message %d of %d\n", - mp->curmsg, mp->hghmsg); - } - else { - printf ("Reading "); - if (fmsh) - printf ("+%s", fmsh); - else - printf ("%s", mp->foldpath); - printf (", currently at message %d of %d\n", - mp->curmsg, mp->hghmsg); - } - - if (((seqnum = seq_getnum (mp, "unseen")) != -1) - && scansw - && in_sequence(mp, seqnum, mp->hghmsg)) - scanstring ("unseen"); -} - - -static void -write_ids (void) -{ - int i = 0, seqnum, msgnum; - char buffer[80]; - - if (pfd <= 1) - return; - - if ((seqnum = seq_getnum (mp, "unseen")) != -1) - for (msgnum = mp->hghmsg; msgnum >= mp->lowmsg; msgnum--) - if (!in_sequence(mp, seqnum, msgnum)) { - if (Msgs[msgnum].m_bboard_id == 0) - readid (msgnum); - if ((i = Msgs[msgnum].m_bboard_id) > 0) - break; - } - - snprintf (buffer, sizeof(buffer), "%d %d\n", i, Msgs[mp->hghmsg].m_bboard_id); - write (pfd, buffer, sizeof(buffer)); - close (pfd); - pfd = NOTOK; -} - - -static void -quit (void) -{ - int i, md, msgnum; - char *cp, tmpfil[BUFSIZ]; - char map1[BUFSIZ], map2[BUFSIZ]; - struct stat st; - FILE *dp; - - if (!(mp->msgflags & MODIFIED) || is_readonly(mp) || fmsh) { - if (vmh) - rc2peer (RC_FIN, 0, NULL); - return; - } - - if (vmh) - ttyNaux (NULLCMD, "FAST"); - cp = NULL; - if ((dp = lkfopen (mp->foldpath, "r")) == NULL) { - advise (mp->foldpath, "unable to lock"); - if (vmh) { - ttyR (NULLCMD); - pFIN (); - } - return; - } - if (fstat (fileno (dp), &st) == NOTOK) { - advise (mp->foldpath, "unable to stat"); - goto release; - } - if (mtime != st.st_mtime) { - advise (NULL, "new messages have arrived, no update"); - goto release; - } - mode = (int) (st.st_mode & 0777); - - if (mp->nummsg == 0) { - cp = concat ("Zero file \"", mp->foldpath, "\"? ", NULL); - if (getanswer (cp)) { - if ((i = creat (mp->foldpath, mode)) != NOTOK) - close (i); - else - advise (mp->foldpath, "error zero'ing"); - unlink (map_name (mp->foldpath));/* XXX */ - } - goto release; - } - - cp = concat ("Update file \"", mp->foldpath, "\"? ", NULL); - if (!getanswer (cp)) - goto release; - strncpy (tmpfil, m_backup (mp->foldpath), sizeof(tmpfil)); - if ((md = mbx_open (tmpfil, mbx_style, st.st_uid, st.st_gid, mode)) == NOTOK) { - advise (tmpfil, "unable to open"); - goto release; - } - - for (msgnum = mp->lowmsg; msgnum <= mp->hghmsg; msgnum++) - if (does_exist(mp, msgnum) && pack (tmpfil, md, msgnum) == NOTOK) { - mbx_close (tmpfil, md); - unlink (tmpfil); - unlink (map_name (tmpfil)); - goto release; - } - mbx_close (tmpfil, md); - - if (rename (tmpfil, mp->foldpath) == NOTOK) - admonish (mp->foldpath, "unable to rename %s to", tmpfil); - else { - strncpy (map1, map_name (tmpfil), sizeof(map1)); - strncpy (map2, map_name (mp->foldpath), sizeof(map2)); - - if (rename (map1, map2) == NOTOK) { - admonish (map2, "unable to rename %s to", map1); - unlink (map1); - unlink (map2); - } - } - -release: ; - if (cp) - free (cp); - lkfclose (dp, mp->foldpath); - if (vmh) { - ttyR (NULLCMD); - pFIN (); - } -} - - -static int -getargs (char *prompt, struct swit *sw, struct Cmd *cmdp) -{ - int i; - char *cp; - static char buffer[BUFSIZ]; - - 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'); - break; - } - if (told_to_quit || i == EOF) { - if (ppid > 0) -#ifdef SIGEMT - kill (ppid, SIGEMT); -#else - kill (ppid, SIGTERM); -#endif - return EOF; - } -#else /* BSD42 */ - if (i == EOF) - longjmp (sigenv, DONE); -#endif /* BSD42 */ - if (cp < &buffer[sizeof buffer - 2]) - *cp++ = i; - } - *cp = 0; - - if (buffer[0] == 0) - continue; - if (buffer[0] == '?') { - printf ("commands:\n"); - print_sw (ALL, sw, "", stdout); - printf ("type CTRL-D or use ``quit'' to leave %s\n", - invo_name); - continue; - } - - if (parse (buffer, cmdp) == NOTOK) - continue; - - switch (i = smatch (cmdp->args[0], sw)) { - case AMBIGSW: - ambigsw (cmdp->args[0], sw); - continue; - case UNKWNSW: - printf ("say what: ``%s'' -- type ? (or help) for help\n", - cmdp->args[0]); - continue; - default: -#ifdef BSD42 - should_intr = 0; -#endif /* BSD42 */ - return i; - } - } -} - - -static int -getcmds (struct swit *sw, struct Cmd *cmdp, int scansw) -{ - int i; - struct record rcs, *rc; - - rc = &rcs; - initrc (rc); - - for (;;) - switch (peer2rc (rc)) { - case RC_QRY: - pQRY (rc->rc_data, scansw); - break; - - case RC_CMD: - if ((i = pCMD (rc->rc_data, sw, cmdp)) != NOTOK) - return i; - break; - - case RC_FIN: - if (ppid > 0) -#ifdef SIGEMT - kill (ppid, SIGEMT); -#else - kill (ppid, SIGTERM); -#endif - return EOF; - - case RC_XXX: - padios (NULL, "%s", rc->rc_data); - - default: - fmt2peer (RC_ERR, "pLOOP protocol screw-up"); - done (1); - } -} - - -static int -parse (char *buffer, struct Cmd *cmdp) -{ - int argp = 0; - unsigned char c, *cp; - char *pp; - - cmdp->line[0] = 0; - pp = cmdp->args[argp++] = cmdp->line; - cmdp->redirect = NULL; - cmdp->direction = STDIO; - cmdp->stream = NULL; - - for (cp = buffer; (c = *cp); cp++) { - if (!isspace (c)) - break; - } - if (c == '\0') { - if (vmh) - fmt2peer (RC_EOF, "null command"); - return NOTOK; - } - - while ((c = *cp++)) { - if (isspace (c)) { - while (isspace (c)) - c = *cp++; - if (c == 0) - break; - *pp++ = 0; - cmdp->args[argp++] = pp; - *pp = 0; - } - - switch (c) { - case '"': - for (;;) { - switch (c = *cp++) { - case 0: - padvise (NULL, "unmatched \""); - return NOTOK; - case '"': - break; - case QUOTE: - if ((c = *cp++) == 0) - goto no_quoting; - default: - *pp++ = c; - continue; - } - break; - } - continue; - - case QUOTE: - if ((c = *cp++) == 0) { - no_quoting: ; - padvise (NULL, "the newline character can not be quoted"); - return NOTOK; - } - - default: ; - *pp++ = c; - continue; - - case '>': - case '|': - if (pp == cmdp->line) { - padvise (NULL, "invalid null command"); - return NOTOK; - } - if (*cmdp->args[argp - 1] == 0) - argp--; - cmdp->direction = c == '>' ? CRTIO : PIPIO; - if (cmdp->direction == CRTIO && (c = *cp) == '>') { - cmdp->direction = APPIO; - cp++; - } - cmdp->redirect = pp + 1;/* sigh */ - for (; (c = *cp); cp++) - if (!isspace (c)) - break; - if (c == 0) { - padvise (NULL, cmdp->direction != PIPIO - ? "missing name for redirect" - : "invalid null command"); - return NOTOK; - } - strcpy (cmdp->redirect, cp); - if (cmdp->direction != PIPIO) { - for (; *cp; cp++) - if (isspace (*cp)) { - padvise (NULL, "bad name for redirect"); - return NOTOK; - } - if (expand (cmdp->redirect) == NOTOK) - return NOTOK; - } - break; - } - break; - } - - *pp++ = 0; - cmdp->args[argp] = NULL; - - return OK; -} - - -int -expand (char *redirect) -{ - char *cp, *pp; - char path[BUFSIZ]; - struct passwd *pw; - - if (*redirect != '~') - return OK; - - if ((cp = strchr(pp = redirect + 1, '/'))) - *cp++ = 0; - if (*pp == 0) - pp = mypath; - else - if ((pw = getpwnam (pp))) - pp = pw->pw_dir; - else { - padvise (NULL, "unknown user: %s", pp); - return NOTOK; - } - - snprintf (path, sizeof(path), "%s/%s", pp, cp ? cp : ""); - strcpy (redirect, path); - return OK; -} - - -static int -init_io (struct Cmd *cmdp, int vio) -{ - int io, result; - - io = vmh; - - vmh = vio; - result = initaux_io (cmdp); - vmh = io; - - return result; -} - - -static int -initaux_io (struct Cmd *cmdp) -{ - char *mode; - - switch (cmdp->direction) { - case STDIO: - return OK; - - case CRTIO: - case APPIO: - mode = cmdp->direction == CRTIO ? "write" : "append"; - if ((cmdp->stream = fopen (cmdp->redirect, mode)) == NULL) { - padvise (cmdp->redirect, "unable to %s ", mode); - cmdp->direction = STDIO; - return NOTOK; - } - break; - - case PIPIO: - if ((cmdp->stream = popen (cmdp->redirect, "w")) == NULL) { - padvise (cmdp->redirect, "unable to pipe"); - cmdp->direction = STDIO; - return NOTOK; - } - SIGNAL (SIGPIPE, pipeser); - broken_pipe = 0; - break; - - default: - padios (NULL, "unknown redirection for command"); - } - - fflush (stdout); - if (dup2 (fileno (cmdp->stream), fileno (stdout)) == NOTOK) - padios ("standard output", "unable to dup2"); - clearerr (stdout); - - return OK; -} - - -static void -fin_io (struct Cmd *cmdp, int vio) -{ - int io; - - io = vmh; - vmh = vio; - finaux_io (cmdp); - vmh = io; -} - - -static void -finaux_io (struct Cmd *cmdp) -{ - switch (cmdp->direction) { - case STDIO: - return; - - case CRTIO: - case APPIO: - fflush (stdout); - close (fileno (stdout)); - if (ferror (stdout)) - padvise (NULL, "problems writing %s", cmdp->redirect); - fclose (cmdp->stream); - break; - - case PIPIO: - fflush (stdout); - close (fileno (stdout)); - pclose (cmdp->stream); - SIGNAL (SIGPIPE, SIG_DFL); - break; - - default: - padios (NULL, "unknown redirection for command"); - } - - if (dup2 (fileno (sp), fileno (stdout)) == NOTOK) - padios ("standard output", "unable to dup2"); - clearerr (stdout); - - cmdp->direction = STDIO; -} - - -static void -m_init (void) -{ - int msgnum; - - for (msgnum = mp->lowmsg; msgnum <= mp->hghmsg; msgnum++) - unset_selected (mp, msgnum); - mp->lowsel = mp->hghsel = mp->numsel = 0; -} - - -void -m_reset (void) -{ - write_ids (); - folder_free (mp); /* free folder/message structure */ - myname = NULL; -} - - -void -seq_setcur (struct msgs *mp, int msgnum) -{ - if (mp->curmsg == msgnum) - return; - - if (mp->curmsg && Msgs[mp->curmsg].m_scanl) { - free (Msgs[mp->curmsg].m_scanl); - Msgs[mp->curmsg].m_scanl = NULL; - } - if (Msgs[msgnum].m_scanl) { - free (Msgs[msgnum].m_scanl); - Msgs[msgnum].m_scanl = NULL; - } - - mp->curmsg = msgnum; -} - - - -static RETSIGTYPE -intrser (int i) -{ -#ifndef RELIABLE_SIGNALS - SIGNAL (SIGINT, intrser); -#endif - - discard (stdout); - interrupted++; - -#ifdef BSD42 - if (should_intr) - longjmp (sigenv, NOTOK); -#endif -} - - -static RETSIGTYPE -pipeser (int i) -{ -#ifndef RELIABLE_SIGNALS - SIGNAL (SIGPIPE, pipeser); -#endif - - if (broken_pipe++ == 0) - fprintf (stderr, "broken pipe\n"); - told_to_quit++; - interrupted++; - -#ifdef BSD42 - if (should_intr) - longjmp (sigenv, NOTOK); -#endif -} - - -static RETSIGTYPE -quitser (int i) -{ -#ifndef RELIABLE_SIGNALS - SIGNAL (SIGQUIT, quitser); -#endif - - told_to_quit++; - interrupted++; - -#ifdef BSD42 - if (should_intr) - longjmp (sigenv, NOTOK); -#endif -} - - -static RETSIGTYPE -alrmser (int i) -{ - longjmp (peerenv, DONE); -} - - -static int -pINI (void) -{ - int i, vrsn; - unsigned char *bp; - struct record rcs, *rc; - - rc = &rcs; - initrc (rc); - - switch (peer2rc (rc)) { - case RC_INI: - bp = rc->rc_data; - while (isspace (*bp)) - bp++; - if (sscanf (bp, "%d", &vrsn) != 1) { - bad_init: ; - fmt2peer (RC_ERR, "bad init \"%s\"", rc->rc_data); - done (1); - } - if (vrsn != RC_VRSN) { - fmt2peer (RC_ERR, "version %d unsupported", vrsn); - done (1); - } - - while (*bp && !isspace (*bp)) - bp++; - while (isspace (*bp)) - bp++; - if (sscanf (bp, "%d", &numwins) != 1 || numwins <= 0) - goto bad_init; - if (numwins > NWIN) - numwins = NWIN; - - for (i = 1; i <= numwins; i++) { - while (*bp && !isspace (*bp)) - bp++; - while (isspace (*bp)) - bp++; - if (sscanf (bp, "%d", &windows[i]) != 1 || windows[i] <= 0) - goto bad_init; - } - rc2peer (RC_ACK, 0, NULL); - return OK; - - case RC_XXX: - padios (NULL, "%s", rc->rc_data); - - default: - fmt2peer (RC_ERR, "pINI protocol screw-up"); - done (1); /* NOTREACHED */ - } - - return 1; /* dead code to satisfy the compiler */ -} - - -static int -pQRY (char *str, int scansw) -{ - if (pQRY1 (scansw) == NOTOK || pQRY2 () == NOTOK) - return NOTOK; - - rc2peer (RC_EOF, 0, NULL); - return OK; -} - - -static int -pQRY1 (int scansw) -{ - int oldhgh; - static int lastlow = 0, - lastcur = 0, - lasthgh = 0, - lastnum = 0; - - oldhgh = mp->hghmsg; - if (check_folder (scansw) && oldhgh < mp->hghmsg) { - switch (winX (STATUS)) { - case NOTOK: - return NOTOK; - - case OK: - printf ("new messages have arrived!"); - fflush (stdout); - fflush (stderr); - _exit (0); /* NOTREACHED */ - - default: - lastlow = lastcur = lasthgh = lastnum = 0; - break; - } - - switch (winX (DISPLAY)) { - case NOTOK: - return NOTOK; - - case OK: - scanrange (oldhgh + 1, mp->hghmsg); - fflush (stdout); - fflush (stderr); - _exit (0); /* NOTREACHED */ - - default: - break; - } - return OK; - } - - if (gap) - switch (winX (STATUS)) { - case NOTOK: - return NOTOK; - - case OK: - printf ("%s: gap in ID:s, last seen %d, lowest present %d\n", - myname ? myname : fmsh ? fmsh : mp->foldpath, gap - 1, - readid (mp->lowmsg)); - fflush (stdout); - fflush (stderr); - _exit (0); /* NOTREACHED */ - - default: - gap = 0; - return OK; - } - - if (mp->lowmsg != lastlow - || mp->curmsg != lastcur - || mp->hghmsg != lasthgh - || mp->nummsg != lastnum) - switch (winX (STATUS)) { - case NOTOK: - return NOTOK; - - case OK: - foldcmd (NULL); - fflush (stdout); - fflush (stderr); - _exit (0); /* NOTREACHED */ - - default: - lastlow = mp->lowmsg; - lastcur = mp->curmsg; - lasthgh = mp->hghmsg; - lastnum = mp->nummsg; - return OK; - } - - return OK; -} - - -static int -pQRY2 (void) -{ - int i, j, k, msgnum, n; - static int cur = 0, - num = 0, - lo = 0, - hi = 0; - - if (mp->nummsg == 0 && mp->nummsg != num) - switch (winX (SCAN)) { - case NOTOK: - return NOTOK; - - case OK: - printf ("empty!"); - fflush (stdout); - fflush (stderr); - _exit (0); /* NOTREACHED */ - - default: - num = mp->nummsg; - return OK; - } - num = mp->nummsg; - - i = 0; - j = (k = windows[SCAN]) / 2; - for (msgnum = mp->curmsg; msgnum <= mp->hghmsg; msgnum++) - if (does_exist (mp, msgnum)) - i++; - if (i-- > 0) { - if (topcur) - k = i >= k ? 1 : k - i; - else - k -= i > j ? j : i; - } - - i = j = 0; - n = 1; - for (msgnum = mp->curmsg; msgnum >= mp->lowmsg; msgnum--) - if (does_exist (mp, msgnum)) { - i = msgnum; - if (j == 0) - j = msgnum; - if (n++ >= k) - break; - } - for (msgnum = mp->curmsg + 1; msgnum <= mp->hghmsg; msgnum++) - if (does_exist (mp, msgnum)) { - if (i == 0) - i = msgnum; - j = msgnum; - if (n++ >= windows[SCAN]) - break; - } - if (!topcur - && lo > 0 - && hi > 0 - && does_exist (mp, lo) - && does_exist (mp, hi) - && (lo < mp->curmsg - || (lo == mp->curmsg && lo == mp->lowmsg)) - && (mp->curmsg < hi - || (hi == mp->curmsg && hi == mp->hghmsg)) - && hi - lo == j - i) - i = lo, j = hi; - - if (mp->curmsg != cur || modified) - switch (winN (NULLCMD, SCAN, 0)) { - case NOTOK: - return NOTOK; - - case OK: - return OK; - - default: - scanrange (lo = i, hi = j); - cur = mp->curmsg; - winR (NULLCMD); - return OK; - } - - return OK; -} - - -static int -pCMD (char *str, struct swit *sw, struct Cmd *cmdp) -{ - int i; - - if (*str == '?') - switch (winX (DISPLAY)) { - case NOTOK: - return NOTOK; - - case OK: - printf ("commands:\n"); - print_sw (ALL, sw, "", stdout); - printf ("type ``quit'' to leave %s\n", invo_name); - fflush (stdout); - fflush (stderr); - _exit (0); /* NOTREACHED */ - - default: - rc2peer (RC_EOF, 0, NULL); - return NOTOK; - } - - if (parse (str, cmdp) == NOTOK) - return NOTOK; - - switch (i = smatch (cmdp->args[0], sw)) { - case AMBIGSW: - switch (winX (DISPLAY)) { - case NOTOK: - return NOTOK; - - case OK: - ambigsw (cmdp->args[0], sw); - fflush (stdout); - fflush (stderr); - _exit (0); /* NOTREACHED */ - - default: - rc2peer (RC_EOF, 0, NULL); - return NOTOK; - } - - case UNKWNSW: - fmt2peer (RC_ERR, - "say what: ``%s'' -- type ? (or help) for help", - cmdp->args[0]); - return NOTOK; - - default: - return i; - } -} - - -static int -pFIN (void) -{ - int status; - - switch (setjmp (peerenv)) { - case OK: - SIGNAL (SIGALRM, alrmser); - alarm (ALARM); - - status = peerwait (); - - alarm (0); - return status; - - default: - return NOTOK; - } -} - - -static int -peerwait (void) -{ - struct record rcs, *rc; - - rc = &rcs; - initrc (rc); - - switch (peer2rc (rc)) { - case RC_QRY: - case RC_CMD: - rc2peer (RC_FIN, 0, NULL); - return OK; - - case RC_XXX: - advise (NULL, "%s", rc->rc_data); - return NOTOK; - - default: - fmt2peer (RC_FIN, "pLOOP protocol screw-up"); - return NOTOK; - } -} - - -static int -ttyNaux (struct Cmd *cmdp, char *s) -{ - struct record rcs, *rc; - - rc = &rcs; - initrc (rc); - - if (cmdp && init_io (cmdp, vmh) == NOTOK) - return NOTOK; - - /* XXX: fseek() too tricky for our own good */ - if (!fmsh) - fseek (fp, 0L, SEEK_SET); - - vmhtty = NOTOK; - switch (rc2rc (RC_TTY, s ? strlen (s) : 0, s, rc)) { - case RC_ACK: - vmhtty = OK; /* fall */ - case RC_ERR: - break; - - case RC_XXX: - padios (NULL, "%s", rc->rc_data);/* NOTREACHED */ - - default: - fmt2peer (RC_ERR, "pTTY protocol screw-up"); - done (1); /* NOTREACHED */ - } - -#ifdef SIGTSTP - SIGNAL (SIGTSTP, tstat); -#endif - return vmhtty; -} - - -static int -ttyR (struct Cmd *cmdp) -{ - struct record rcs, *rc; - - rc = &rcs; - -#ifdef SIGTSTP - SIGNAL (SIGTSTP, SIG_IGN); -#endif - - if (vmhtty != OK) - return NOTOK; - - initrc (rc); - - if (cmdp) - fin_io (cmdp, 0); - - vmhtty = NOTOK; - switch (rc2rc (RC_EOF, 0, NULL, rc)) { - case RC_ACK: - rc2peer (RC_EOF, 0, NULL); - return OK; - - case RC_XXX: - padios (NULL, "%s", rc->rc_data);/* NOTREACHED */ - - default: - fmt2peer (RC_ERR, "pTTY protocol screw-up"); - done (1); /* NOTREACHED */ - } - - return 1; /* dead code to satisfy compiler */ -} - - -static int -winN (struct Cmd *cmdp, int n, int eof) -{ - int i, pd[2]; - char buffer[BUFSIZ]; - struct record rcs, *rc; - - rc = &rcs; - if (vmhpid == NOTOK) - return OK; - - initrc (rc); - - /* XXX: fseek() too tricky for our own good */ - if (!fmsh) - fseek (fp, 0L, SEEK_SET); - - vmhpid = OK; - - snprintf (buffer, sizeof(buffer), "%d", n); - switch (str2rc (RC_WIN, buffer, rc)) { - case RC_ACK: - break; - - case RC_ERR: - return NOTOK; - - case RC_XXX: - padios (NULL, "%s", rc->rc_data); - - default: - fmt2peer (RC_ERR, "pWIN protocol screw-up"); - done (1); - } - - if (pipe (pd) == NOTOK) { - err2peer (RC_ERR, "pipe", "unable to"); - return NOTOK; - } - - switch (vmhpid = fork()) { - case NOTOK: - err2peer (RC_ERR, "fork", "unable to"); - close (pd[0]); - close (pd[1]); - return NOTOK; - - case OK: - close (pd[1]); - SIGNAL (SIGPIPE, SIG_IGN); - while ((i = read (pd[0], buffer, sizeof buffer)) > 0) - switch (rc2rc (RC_DATA, i, buffer, rc)) { - case RC_ACK: - break; - - case RC_ERR: - _exit (1); - - case RC_XXX: - advise (NULL, "%s", rc->rc_data); - _exit (2); - - default: - fmt2peer (RC_ERR, "pWIN protocol screw-up"); - _exit (2); - } - if (i == OK) - switch (rc2rc (RC_EOF, 0, NULL, rc)) { - case RC_ACK: - if (eof) - rc2peer (RC_EOF, 0, NULL); - i = 0; - break; - - case RC_XXX: - advise (NULL, "%s", rc->rc_data); - i = 2; - break; - - default: - fmt2peer (RC_ERR, "pWIN protocol screw-up"); - i = 2; - break; - } - if (i == NOTOK) - err2peer (RC_ERR, "pipe", "error reading from"); - close (pd[0]); - _exit (i != NOTOK ? i : 1); - - default: - if ((vmhfd0 = dup (fileno (stdin))) == NOTOK) - padios ("standard input", "unable to dup"); - if ((vmhfd1 = dup (fileno (stdout))) == NOTOK) - padios ("standard output", "unable to dup"); - if ((vmhfd2 = dup (fileno (stderr))) == NOTOK) - padios ("diagnostic output", "unable to dup"); - - close (0); - if ((i = open ("/dev/null", O_RDONLY)) != NOTOK && i != fileno (stdin)) { - dup2 (i, fileno (stdin)); - close (i); - } - - fflush (stdout); - if (dup2 (pd[1], fileno (stdout)) == NOTOK) - padios ("standard output", "unable to dup2"); - clearerr (stdout); - - fflush (stderr); - if (dup2 (pd[1], fileno (stderr)) == NOTOK) - padios ("diagnostic output", "unable to dup2"); - clearerr (stderr); - - if (cmdp && init_io (cmdp, 0) == NOTOK) - return NOTOK; - pstat = SIGNAL (SIGPIPE, pipeser); - broken_pipe = 1; - - close (pd[0]); - close (pd[1]); - - return vmhpid; - } -} - - -static int -winR (struct Cmd *cmdp) -{ - int status; - - if (vmhpid <= OK) - return NOTOK; - - if (cmdp) - fin_io (cmdp, 0); - - if (dup2 (vmhfd0, fileno (stdin)) == NOTOK) - padios ("standard input", "unable to dup2"); - clearerr (stdin); - close (vmhfd0); - - fflush (stdout); - if (dup2 (vmhfd1, fileno (stdout)) == NOTOK) - padios ("standard output", "unable to dup2"); - clearerr (stdout); - close (vmhfd1); - - fflush (stderr); - if (dup2 (vmhfd2, fileno (stderr)) == NOTOK) - padios ("diagnostic output", "unable to dup2"); - clearerr (stderr); - close (vmhfd2); - - SIGNAL (SIGPIPE, pstat); - - if ((status = pidwait (vmhpid, OK)) == 2) - done (1); - - vmhpid = OK; - return (status == 0 ? OK : NOTOK); -} - - -static int -winX (int n) -{ - int i, pid, pd[2]; - char buffer[BUFSIZ]; - struct record rcs, *rc; - - rc = &rcs; - initrc (rc); - - /* XXX: fseek() too tricky for our own good */ - if (!fmsh) - fseek (fp, 0L, SEEK_SET); - - snprintf (buffer, sizeof(buffer), "%d", n); - switch (str2rc (RC_WIN, buffer, rc)) { - case RC_ACK: - break; - - case RC_ERR: - return NOTOK; - - case RC_XXX: - padios (NULL, "%s", rc->rc_data); - - default: - fmt2peer (RC_ERR, "pWIN protocol screw-up"); - done (1); - } - - if (pipe (pd) == NOTOK) { - err2peer (RC_ERR, "pipe", "unable to"); - return NOTOK; - } - - switch (pid = fork ()) { - case NOTOK: - err2peer (RC_ERR, "fork", "unable to"); - close (pd[0]); - close (pd[1]); - return NOTOK; - - case OK: - close (fileno (stdin)); - if ((i = open ("/dev/null", O_RDONLY)) != NOTOK && i != fileno (stdin)) { - dup2 (i, fileno (stdin)); - close (i); - } - dup2 (pd[1], fileno (stdout)); - dup2 (pd[1], fileno (stderr)); - close (pd[0]); - close (pd[1]); - vmhpid = NOTOK; - return OK; - - default: - close (pd[1]); - while ((i = read (pd[0], buffer, sizeof buffer)) > 0) - switch (rc2rc (RC_DATA, i, buffer, rc)) { - case RC_ACK: - break; - - case RC_ERR: - close (pd[0]); - pidwait (pid, OK); - return NOTOK; - - case RC_XXX: - padios (NULL, "%s", rc->rc_data); - - default: - fmt2peer (RC_ERR, "pWIN protocol screw-up"); - done (1); - } - if (i == OK) - switch (rc2rc (RC_EOF, 0, NULL, rc)) { - case RC_ACK: - break; - - case RC_XXX: - padios (NULL, "%s", rc->rc_data); - - default: - fmt2peer (RC_ERR, "pWIN protocol screw-up"); - done (1); - } - if (i == NOTOK) - err2peer (RC_ERR, "pipe", "error reading from"); - - close (pd[0]); - pidwait (pid, OK); - return (i != NOTOK ? pid : NOTOK); - } -} - - -void -padios (char *what, char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - if (vmh) { - verr2peer (RC_FIN, what, fmt, ap); - rcdone (); - } else { - advertise (what, NULL, fmt, ap); - } - va_end(ap); - - done (1); -} - - -void -padvise (char *what, char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - if (vmh) { - verr2peer (RC_ERR, what, fmt, ap); - } else { - advertise (what, NULL, fmt, ap); - } - va_end(ap); -} diff --git a/uip/mshcmds.c b/uip/mshcmds.c deleted file mode 100644 index 3bd4db3..0000000 --- a/uip/mshcmds.c +++ /dev/null @@ -1,3004 +0,0 @@ - -/* - * mshcmds.c -- command handlers in msh - * - * 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -static char delim3[] = "-------"; /* from burst.c */ - -static int mhlnum; -static FILE *mhlfp; - -/* - * Type for a compare function for qsort. This keeps - * the compiler happy. - */ -typedef int (*qsort_comp) (const void *, const void *); - -/* - * prototypes - */ -void clear_screen (void); /* from termsbr.c */ -int SOprintf (char *, ...); /* from termsbr.c */ -int sc_width (void); /* from termsbr.c */ - -/* - * static prototypes - */ -static int burst (struct Msg *, int, int, int, int); -static void forw (char *, char *, int, char **); -static void rmm (void); -static void show (int); -static int eom_action (int); -static FILE *mhl_action (char *); -static int ask (int); -static int is_nontext (int); -static int get_fields (char *, char *, int, struct Msg *); -static int msgsort (struct Msg *, struct Msg *); -static int subsort (struct Msg *, struct Msg *); -static char *sosmash (char *, char *); -static int process (int, char *, int, char **); -static void copy_message (int, FILE *); -static void copy_digest (int, FILE *); - -/* from mhlsbr.c */ -int mhlsbr (int, char **, FILE *(*)()); - -void -forkcmd (char **args, char *pgm) -{ - int child_id; - char *vec[MAXARGS]; - - vec[0] = r1bindex (pgm, '/'); - copyip (args, vec + 1, MAXARGS - 1); - - if (fmsh) { - context_del (pfolder); - context_replace (pfolder, fmsh);/* update current folder */ - seq_save (mp); - context_save (); /* save the context file */ - } - fflush (stdout); - switch (child_id = fork ()) { - case NOTOK: - advise ("fork", "unable to"); - return; - - case OK: - closefds (3); - SIGNAL (SIGINT, istat); - SIGNAL (SIGQUIT, qstat); - - execvp (pgm, vec); - fprintf (stderr, "unable to exec "); - perror (cmd_name); - _exit (1); - - default: - pidXwait (child_id, NULL); - break; - } - if (fmsh) { /* assume the worst case */ - mp->msgflags |= MODIFIED; - modified++; - } -} - - -static struct swit distswit[] = { -#define DIANSW 0 - { "annotate", 0 }, -#define DINANSW 1 - { "noannotate", 0 }, -#define DIDFSW 2 - { "draftfolder +folder", 0 }, -#define DIDMSW 3 - { "draftmessage msg", 0 }, -#define DINDFSW 4 - { "nodraftfolder", 0 }, -#define DIEDTSW 5 - { "editor editor", 0 }, -#define DINEDSW 6 - { "noedit", 0 }, -#define DIFRMSW 7 - { "form formfile", 0 }, -#define DIINSW 8 - { "inplace", 0 }, -#define DININSW 9 - { "noinplace", 0 }, -#define DIWHTSW 10 - { "whatnowproc program", 0 }, -#define DINWTSW 11 - { "nowhatnowproc", 0 }, -#define DIHELP 12 - { "help", 0 }, - { NULL, 0 } -}; - - -void -distcmd (char **args) -{ - int vecp = 1; - char *cp, *msg = NULL; - char buf[BUFSIZ], *vec[MAXARGS]; - - if (fmsh) { - forkcmd (args, cmd_name); - return; - } - - while ((cp = *args++)) { - if (*cp == '-') - switch (smatch (++cp, distswit)) { - case AMBIGSW: - ambigsw (cp, distswit); - return; - case UNKWNSW: - fprintf (stderr, "-%s unknown\n", cp); - return; - case DIHELP: - snprintf (buf, sizeof(buf), "%s [msgs] [switches]", cmd_name); - print_help (buf, distswit, 1); - return; - - case DIANSW: /* not implemented */ - case DINANSW: - case DIINSW: - case DININSW: - continue; - - case DINDFSW: - case DINEDSW: - case DINWTSW: - vec[vecp++] = --cp; - continue; - - case DIEDTSW: - case DIFRMSW: - case DIDFSW: - case DIDMSW: - case DIWHTSW: - vec[vecp++] = --cp; - if (!(cp = *args++) || *cp == '-') { - advise (NULL, "missing argument to %s", args[-2]); - return; - } - vec[vecp++] = cp; - continue; - } - if (*cp == '+' || *cp == '@') { - advise (NULL, "sorry, no folders allowed!"); - return; - } - else - if (msg) { - advise (NULL, "only one message at a time!"); - return; - } - else - msg = cp; - } - - vec[0] = cmd_name; - vec[vecp++] = "-file"; - vec[vecp] = NULL; - if (!msg) - msg = "cur"; - if (!m_convert (mp, msg)) - return; - seq_setprev (mp); - - if (mp->numsel > 1) { - advise (NULL, "only one message at a time!"); - return; - } - process (mp->hghsel, cmd_name, vecp, vec); - seq_setcur (mp, mp->hghsel); -} - - -static struct swit explswit[] = { -#define EXINSW 0 - { "inplace", 0 }, -#define EXNINSW 1 - { "noinplace", 0 }, -#define EXQISW 2 - { "quiet", 0 }, -#define EXNQISW 3 - { "noquiet", 0 }, -#define EXVBSW 4 - { "verbose", 0 }, -#define EXNVBSW 5 - { "noverbose", 0 }, -#define EXHELP 6 - { "help", 0 }, - { NULL, 0 } -}; - - -void -explcmd (char **args) -{ - int inplace = 0, quietsw = 0, verbosw = 0; - int msgp = 0, hi, msgnum; - char *cp, buf[BUFSIZ], *msgs[MAXARGS]; - struct Msg *smsgs; - - if (fmsh) { - forkcmd (args, cmd_name); - return; - } - - while ((cp = *args++)) { - if (*cp == '-') - switch (smatch (++cp, explswit)) { - case AMBIGSW: - ambigsw (cp, explswit); - return; - case UNKWNSW: - fprintf (stderr, "-%s unknown\n", cp); - return; - case EXHELP: - snprintf (buf, sizeof(buf), "%s [msgs] [switches]", cmd_name); - print_help (buf, explswit, 1); - return; - - case EXINSW: - inplace++; - continue; - case EXNINSW: - inplace = 0; - continue; - case EXQISW: - quietsw++; - continue; - case EXNQISW: - quietsw = 0; - continue; - case EXVBSW: - verbosw++; - continue; - case EXNVBSW: - verbosw = 0; - continue; - } - if (*cp == '+' || *cp == '@') { - advise (NULL, "sorry, no folders allowed!"); - return; - } - else - msgs[msgp++] = cp; - } - - if (!msgp) - msgs[msgp++] = "cur"; - for (msgnum = 0; msgnum < msgp; msgnum++) - if (!m_convert (mp, msgs[msgnum])) - return; - seq_setprev (mp); - - smsgs = (struct Msg *) - calloc ((size_t) (MAXFOLDER + 2), sizeof *smsgs); - if (smsgs == NULL) - adios (NULL, "unable to allocate folder storage"); - - hi = mp->hghmsg + 1; - interrupted = 0; - for (msgnum = mp->lowsel; - msgnum <= mp->hghsel && !interrupted; - msgnum++) - if (is_selected (mp, msgnum)) - if (burst (smsgs, msgnum, inplace, quietsw, verbosw) != OK) - break; - - free ((char *) smsgs); - - if (inplace) - seq_setcur (mp, mp->lowsel); - else - if (hi <= mp->hghmsg) - seq_setcur (mp, hi); - - mp->msgflags |= MODIFIED; - modified++; -} - - -static int -burst (struct Msg *smsgs, int msgnum, int inplace, int quietsw, int verbosw) -{ - int i, j, ld3, wasdlm, msgp; - long pos; - char c, buffer[BUFSIZ]; - register FILE *zp; - - ld3 = strlen (delim3); - - if (Msgs[msgnum].m_scanl) { - free (Msgs[msgnum].m_scanl); - Msgs[msgnum].m_scanl = NULL; - } - - pos = ftell (zp = msh_ready (msgnum, 1)); - for (msgp = 0; msgp <= MAXFOLDER;) { - while (fgets (buffer, sizeof buffer, zp) != NULL - && buffer[0] == '\n' - && pos < Msgs[msgnum].m_stop) - pos += (long) strlen (buffer); - if (feof (zp) || pos >= Msgs[msgnum].m_stop) - break; - fseek (zp, pos, SEEK_SET); - smsgs[msgp].m_start = pos; - - for (c = 0; - pos < Msgs[msgnum].m_stop - && fgets (buffer, sizeof buffer, zp) != NULL; - c = buffer[0]) - if (strncmp (buffer, delim3, ld3) == 0 - && (msgp == 1 || c == '\n') - && peekc (zp) == '\n') - break; - else - pos += (long) strlen (buffer); - - wasdlm = strncmp (buffer, delim3, ld3) == 0; - if (smsgs[msgp].m_start != pos) - smsgs[msgp++].m_stop = (c == '\n' && wasdlm) ? pos - 1 : pos; - if (feof (zp) || pos >= Msgs[msgnum].m_stop) { - if (wasdlm) - smsgs[msgp - 1].m_stop -= ((long) strlen (buffer) + 1); - break; - } - pos += (long) strlen (buffer); - } - - switch (msgp--) { /* toss "End of XXX Digest" */ - case 0: - adios (NULL, "burst() botch -- you lose big"); - - case 1: - if (!quietsw) - printf ("message %d not in digest format\n", msgnum); - return OK; - - default: - if (verbosw) - printf ("%d message%s exploded from digest %d\n", - msgp, msgp != 1 ? "s" : "", msgnum); - break; - } - - if ((i = msgp + mp->hghmsg) > MAXFOLDER) { - advise (NULL, "more than %d messages", MAXFOLDER); - return NOTOK; - } - if (!(mp = folder_realloc (mp, mp->lowoff, i))) - adios (NULL, "unable to allocate folder storage"); - - j = mp->hghmsg; - mp->hghmsg += msgp; - mp->nummsg += msgp; - if (mp->hghsel > msgnum) - mp->hghsel += msgp; - - if (inplace) - for (i = mp->hghmsg; j > msgnum; i--, j--) { - if (verbosw) - printf ("message %d becomes message %d\n", j, i); - - Msgs[i].m_bboard_id = Msgs[j].m_bboard_id; - Msgs[i].m_top = Msgs[j].m_top; - Msgs[i].m_start = Msgs[j].m_start; - Msgs[i].m_stop = Msgs[j].m_stop; - Msgs[i].m_scanl = NULL; - if (Msgs[j].m_scanl) { - free (Msgs[j].m_scanl); - Msgs[j].m_scanl = NULL; - } - copy_msg_flags (mp, i, j); - } - - if (Msgs[msgnum].m_bboard_id == 0) - readid (msgnum); - - unset_selected (mp, msgnum); - i = inplace ? msgnum + msgp : mp->hghmsg; - for (j = msgp; j >= (inplace ? 0 : 1); i--, j--) { - if (verbosw && i != msgnum) - printf ("message %d of digest %d becomes message %d\n", - j, msgnum, i); - - Msgs[i].m_bboard_id = Msgs[msgnum].m_bboard_id; - Msgs[i].m_top = Msgs[j].m_top; - Msgs[i].m_start = smsgs[j].m_start; - Msgs[i].m_stop = smsgs[j].m_stop; - Msgs[i].m_scanl = NULL; - copy_msg_flags (mp, i, msgnum); - } - - return OK; -} - - -static struct swit fileswit[] = { -#define FIDRFT 0 - { "draft", 0 }, -#define FILINK 1 - { "link", 0 }, -#define FINLINK 2 - { "nolink", 0 }, -#define FIPRES 3 - { "preserve", 0 }, -#define FINPRES 4 - { "nopreserve", 0 }, -#define FISRC 5 - { "src +folder", 0 }, -#define FIFILE 6 - { "file file", 0 }, -#define FIPROC 7 - { "rmmproc program", 0 }, -#define FINPRC 8 - { "normmproc", 0 }, -#define FIHELP 9 - { "help", 0 }, - { NULL, 0 } -}; - - -void -filecmd (char **args) -{ - int linksw = 0, msgp = 0; - int vecp = 1, i, msgnum; - char *cp, buf[BUFSIZ]; - char *msgs[MAXARGS], *vec[MAXARGS]; - - if (fmsh) { - forkcmd (args, cmd_name); - return; - } - - while ((cp = *args++)) { - if (*cp == '-') - switch (i = smatch (++cp, fileswit)) { - case AMBIGSW: - ambigsw (cp, fileswit); - return; - case UNKWNSW: - fprintf (stderr, "-%s unknown\n", cp); - return; - case FIHELP: - snprintf (buf, sizeof(buf), "%s +folder... [msgs] [switches]", cmd_name); - print_help (buf, fileswit, 1); - return; - - case FILINK: - linksw++; - continue; - case FINLINK: - linksw = 0; - continue; - - case FIPRES: - case FINPRES: - continue; - - case FISRC: - case FIDRFT: - case FIFILE: - case FIPROC: - case FINPRC: - advise (NULL, "sorry, -%s not allowed!", fileswit[i].sw); - return; - } - if (*cp == '+' || *cp == '@') - vec[vecp++] = cp; - else - msgs[msgp++] = cp; - } - - vec[0] = cmd_name; - vec[vecp++] = "-file"; - vec[vecp] = NULL; - if (!msgp) - msgs[msgp++] = "cur"; - for (msgnum = 0; msgnum < msgp; msgnum++) - if (!m_convert (mp, msgs[msgnum])) - return; - seq_setprev (mp); - - interrupted = 0; - for (msgnum = mp->lowsel; - msgnum <= mp->hghsel && !interrupted; - msgnum++) - if (is_selected (mp, msgnum)) - if (process (msgnum, fileproc, vecp, vec)) { - unset_selected (mp, msgnum); - mp->numsel--; - } - - if (mp->numsel != mp->nummsg || linksw) - seq_setcur (mp, mp->hghsel); - if (!linksw) - rmm (); -} - - -int -filehak (char **args) -{ - int result, vecp = 0; - char *cp, *cwd, *vec[MAXARGS]; - - while ((cp = *args++)) { - if (*cp == '-') - switch (smatch (++cp, fileswit)) { - case AMBIGSW: - case UNKWNSW: - case FIHELP: - return NOTOK; - - case FILINK: - case FINLINK: - case FIPRES: - case FINPRES: - continue; - - case FISRC: - case FIDRFT: - case FIFILE: - return NOTOK; - } - if (*cp == '+' || *cp == '@') - vec[vecp++] = cp; - } - vec[vecp] = NULL; - - result = NOTOK; - cwd = NULL; - for (vecp = 0; (cp = vec[vecp]) && result == NOTOK; vecp++) { - if (cwd == NULL) - cwd = getcpy (pwd ()); - chdir (m_maildir ("")); - cp = pluspath (cp); - if (access (m_maildir (cp), F_OK) == NOTOK) - result = OK; - free (cp); - } - if (cwd) - chdir (cwd); - - return result; -} - - -static struct swit foldswit[] = { -#define FLALSW 0 - { "all", 0 }, -#define FLFASW 1 - { "fast", 0 }, -#define FLNFASW 2 - { "nofast", 0 }, -#define FLHDSW 3 - { "header", 0 }, -#define FLNHDSW 4 - { "noheader", 0 }, -#define FLPKSW 5 - { "pack", 0 }, -#define FLNPKSW 6 - { "nopack", 0 }, -#define FLRCSW 7 - { "recurse", 0 }, -#define FLNRCSW 8 - { "norecurse", 0 }, -#define FLTLSW 9 - { "total", 0 }, -#define FLNTLSW 10 - { "nototal", 0 }, -#define FLPRSW 11 - { "print", 0 }, -#define FLPUSW 12 - { "push", 0 }, -#define FLPOSW 13 - { "pop", 0 }, -#define FLLISW 14 - { "list", 0 }, -#define FLHELP 15 - { "help", 0 }, - { NULL, 0 } -}; - - -void -foldcmd (char **args) -{ - int fastsw = 0, headersw = 0, packsw = 0; - int hole, msgnum; - char *cp, *folder = NULL, *msg = NULL; - char buf[BUFSIZ], **vec = args; - - if (args == NULL) - goto fast; - - while ((cp = *args++)) { - if (*cp == '-') - switch (smatch (++cp, foldswit)) { - case AMBIGSW: - ambigsw (cp, foldswit); - return; - case UNKWNSW: - fprintf (stderr, "-%s unknown\n", cp); - return; - case FLHELP: - snprintf (buf, sizeof(buf), "%s [+folder] [msg] [switches]", cmd_name); - print_help (buf, foldswit, 1); - return; - - case FLALSW: /* not implemented */ - case FLRCSW: - case FLNRCSW: - case FLTLSW: - case FLNTLSW: - case FLPRSW: - case FLPUSW: - case FLPOSW: - case FLLISW: - continue; - - case FLFASW: - fastsw++; - continue; - case FLNFASW: - fastsw = 0; - continue; - case FLHDSW: - headersw++; - continue; - case FLNHDSW: - headersw = 0; - continue; - case FLPKSW: - packsw++; - continue; - case FLNPKSW: - packsw = 0; - continue; - } - if (*cp == '+' || *cp == '@') { - if (folder) { - advise (NULL, "only one folder at a time!\n"); - return; - } - else - folder = fmsh ? pluspath (cp) - : cp + 1; - } - else - if (msg) { - advise (NULL, "only one message at a time!\n"); - return; - } - else - msg = cp; - } - - if (folder) { - if (*folder == 0) { - advise (NULL, "null folder names are not permitted"); - return; - } - if (fmsh) { - if (access (m_maildir (folder), R_OK) == NOTOK) { - advise (folder, "unable to read"); - return; - } - } - else { - strncpy (buf, folder, sizeof(buf)); - if (expand (buf) == NOTOK) - return; - folder = buf; - if (access (folder, R_OK) == NOTOK) { - advise (folder, "unable to read"); - return; - } - } - m_reset (); - - if (fmsh) - fsetup (folder); - else - setup (folder); - readids (0); - display_info (0); - } - - if (msg) { - if (!m_convert (mp, msg)) - return; - seq_setprev (mp); - - if (mp->numsel > 1) { - advise (NULL, "only one message at a time!"); - return; - } - seq_setcur (mp, mp->hghsel); - } - - if (packsw) { - if (fmsh) { - forkcmd (vec, cmd_name); - return; - } - - if (mp->lowoff > 1 && !(mp = folder_realloc (mp, 1, mp->hghmsg))) - adios (NULL, "unable to allocate folder storage"); - - for (msgnum = mp->lowmsg, hole = 1; msgnum <= mp->hghmsg; msgnum++) - if (does_exist (mp, msgnum)) { - if (msgnum != hole) { - Msgs[hole].m_bboard_id = Msgs[msgnum].m_bboard_id; - Msgs[hole].m_top = Msgs[msgnum].m_top; - Msgs[hole].m_start = Msgs[msgnum].m_start; - Msgs[hole].m_stop = Msgs[msgnum].m_stop; - Msgs[hole].m_scanl = NULL; - if (Msgs[msgnum].m_scanl) { - free (Msgs[msgnum].m_scanl); - Msgs[msgnum].m_scanl = NULL; - } - copy_msg_flags (mp, hole, msgnum); - if (mp->curmsg == msgnum) - seq_setcur (mp, hole); - } - hole++; - } - if (mp->nummsg > 0) { - mp->lowmsg = 1; - mp->hghmsg = hole - 1; - } - mp->msgflags |= MODIFIED; - modified++; - } - -fast: ; - if (fastsw) - printf ("%s\n", fmsh ? fmsh : mp->foldpath); - else { - if (headersw) - printf ("\t\tFolder %*s# of messages (%*srange%*s); cur%*smsg\n", - DMAXFOLDER, "", DMAXFOLDER - 2, "", DMAXFOLDER - 2, "", - DMAXFOLDER - 2, ""); - printf (args ? "%22s " : "%s ", fmsh ? fmsh : mp->foldpath); - - /* check for empty folder */ - if (mp->nummsg == 0) { - printf ("has no messages%*s", - mp->msgflags & OTHERS ? DMAXFOLDER * 2 + 4 : 0, ""); - } else { - printf ("has %*d message%s (%*d-%*d)", - DMAXFOLDER, mp->nummsg, mp->nummsg != 1 ? "s" : "", - DMAXFOLDER, mp->lowmsg, DMAXFOLDER, mp->hghmsg); - if (mp->curmsg >= mp->lowmsg - && mp->curmsg <= mp->hghmsg) - printf ("; cur=%*d", DMAXFOLDER, mp->curmsg); - } - printf (".\n"); - } -} - - -static struct swit forwswit[] = { -#define FOANSW 0 - { "annotate", 0 }, -#define FONANSW 1 - { "noannotate", 0 }, -#define FODFSW 2 - { "draftfolder +folder", 0 }, -#define FODMSW 3 - { "draftmessage msg", 0 }, -#define FONDFSW 4 - { "nodraftfolder", 0 }, -#define FOEDTSW 5 - { "editor editor", 0 }, -#define FONEDSW 6 - { "noedit", 0 }, -#define FOFTRSW 7 - { "filter filterfile", 0 }, -#define FOFRMSW 8 - { "form formfile", 0 }, -#define FOFTSW 9 - { "format", 5 }, -#define FONFTSW 10 - { "noformat", 7 }, -#define FOINSW 11 - { "inplace", 0 }, -#define FONINSW 12 - { "noinplace", 0 }, -#define FOMISW 13 - { "mime", 0 }, -#define FONMISW 14 - { "nomime", 0 }, -#define FOWHTSW 15 - { "whatnowproc program", 0 }, -#define FONWTSW 16 - { "nowhatnow", 0 }, -#define FOHELP 17 - { "help", 0 }, - { NULL, 0 } -}; - - -void -forwcmd (char **args) -{ - int msgp = 0, vecp = 1, msgnum; - char *cp, *filter = NULL, buf[BUFSIZ]; - char *msgs[MAXARGS], *vec[MAXARGS]; - char *tfile = NULL; - char tmpfil[BUFSIZ]; - - if (fmsh) { - forkcmd (args, cmd_name); - return; - } - - while ((cp = *args++)) { - if (*cp == '-') - switch (smatch (++cp, forwswit)) { - case AMBIGSW: - ambigsw (cp, forwswit); - return; - case UNKWNSW: - fprintf (stderr, "-%s unknown\n", cp); - return; - case FOHELP: - snprintf (buf, sizeof(buf), "%s [msgs] [switches]", cmd_name); - print_help (buf, forwswit, 1); - return; - - case FOANSW: /* not implemented */ - case FONANSW: - case FOINSW: - case FONINSW: - case FOMISW: - case FONMISW: - continue; - - case FONDFSW: - case FONEDSW: - case FONWTSW: - vec[vecp++] = --cp; - continue; - - case FOEDTSW: - case FOFRMSW: - case FODFSW: - case FODMSW: - case FOWHTSW: - vec[vecp++] = --cp; - if (!(cp = *args++) || *cp == '-') { - advise (NULL, "missing argument to %s", args[-2]); - return; - } - vec[vecp++] = cp; - continue; - case FOFTRSW: - if (!(filter = *args++) || *filter == '-') { - advise (NULL, "missing argument to %s", args[-2]); - return; - } - continue; - case FOFTSW: - if (access (filter = myfilter, R_OK) == NOTOK) { - advise (filter, "unable to read default filter file"); - return; - } - continue; - case FONFTSW: - filter = NULL; - continue; - } - if (*cp == '+' || *cp == '@') { - advise (NULL, "sorry, no folders allowed!"); - return; - } - else - msgs[msgp++] = cp; - } - - /* foil search of .mh_profile */ - snprintf (buf, sizeof(buf), "%sXXXXXX", invo_name); - - tfile = m_mktemp(buf, NULL, NULL); - if (tfile == NULL) adios("forwcmd", "unable to create temporary file"); - strncpy (tmpfil, tfile, sizeof(tmpfil)); - vec[0] = tmpfil; - - vec[vecp++] = "-file"; - vec[vecp] = NULL; - if (!msgp) - msgs[msgp++] = "cur"; - for (msgnum = 0; msgnum < msgp; msgnum++) - if (!m_convert (mp, msgs[msgnum])) - return; - seq_setprev (mp); - - if (filter) { - strncpy (buf, filter, sizeof(buf)); - if (expand (buf) == NOTOK) - return; - if (access (filter = getcpy (etcpath (buf)), R_OK) == NOTOK) { - advise (filter, "unable to read"); - free (filter); - return; - } - } - forw (cmd_name, filter, vecp, vec); - seq_setcur (mp, mp->hghsel); - if (filter) - free (filter); -} - - -static void -forw (char *proc, char *filter, int vecp, char **vec) -{ - int i, child_id, msgnum, msgcnt; - char tmpfil[BUFSIZ], *args[MAXARGS]; - FILE *out; - char *tfile = NULL; - - tfile = m_mktemp2(NULL, invo_name, NULL, NULL); - if (tfile == NULL) adios("forw", "unable to create temporary file"); - strncpy (tmpfil, tfile, sizeof(tmpfil)); - - interrupted = 0; - if (filter) - switch (child_id = fork ()) { - case NOTOK: - advise ("fork", "unable to"); - return; - - case OK: /* "trust me" */ - if (freopen (tmpfil, "w", stdout) == NULL) { - fprintf (stderr, "unable to create "); - perror (tmpfil); - _exit (1); - } - args[0] = r1bindex (mhlproc, '/'); - i = 1; - args[i++] = "-forwall"; - args[i++] = "-form"; - args[i++] = filter; - for (msgnum = mp->lowsel; msgnum <= mp->hghsel; msgnum++) - if (is_selected (mp, msgnum)) - args[i++] = getcpy (m_name (msgnum)); - args[i] = NULL; - mhlsbr (i, args, mhl_action); - m_eomsbr ((int (*) ()) 0); - fclose (stdout); - _exit (0); - - default: - if (pidXwait (child_id, NULL)) - interrupted++; - break; - } - else { - if ((out = fopen (tmpfil, "w")) == NULL) { - advise (tmpfil, "unable to create temporary file"); - return; - } - - msgcnt = 1; - for (msgnum = mp->lowsel; - msgnum <= mp->hghsel && !interrupted; - msgnum++) - if (is_selected (mp, msgnum)) { - fprintf (out, "\n\n-------"); - if (msgnum == mp->lowsel) - fprintf (out, " Forwarded Message%s", - mp->numsel > 1 ? "s" : ""); - else - fprintf (out, " Message %d", msgcnt); - fprintf (out, "\n\n"); - copy_digest (msgnum, out); - msgcnt++; - } - - fprintf (out, "\n\n------- End of Forwarded Message%s\n", - mp->numsel > 1 ? "s" : ""); - fclose (out); - } - - fflush (stdout); - if (!interrupted) - switch (child_id = fork ()) { - case NOTOK: - advise ("fork", "unable to"); - break; - - case OK: - closefds (3); - SIGNAL (SIGINT, istat); - SIGNAL (SIGQUIT, qstat); - - vec[vecp++] = tmpfil; - vec[vecp] = NULL; - - execvp (proc, vec); - fprintf (stderr, "unable to exec "); - perror (proc); - _exit (1); - - default: - pidXwait (child_id, NULL); - break; - } - - unlink (tmpfil); -} - - -static char *hlpmsg[] = { - "The %s program emulates many of the commands found in the nmh", - "system. Instead of operating on nmh folders, commands to %s concern", - "a single file.", - "", - "To see the list of commands available, just type a ``?'' followed by", - "the RETURN key. To find out what switches each command takes, type", - "the name of the command followed by ``-help''. To leave %s, use the", - "``quit'' command.", - "", - "Although a lot of nmh commands are found in %s, not all are fully", - "implemented. %s will always recognize all legal switches for a", - "given command though, and will let you know when you ask for an", - "option that it is unable to perform.", - "", - "Running %s is fun, but using nmh from your shell is far superior.", - "After you have familiarized yourself with the nmh style by using %s,", - "you should try using nmh from the shell. You can still use %s for", - "message files that aren't in nmh format, such as BBoard files.", - NULL -}; - - -void -helpcmd (char **args) -{ - int i; - - for (i = 0; hlpmsg[i]; i++) { - printf (hlpmsg[i], invo_name); - putchar ('\n'); - } -} - - -static struct swit markswit[] = { -#define MADDSW 0 - { "add", 0 }, -#define MDELSW 1 - { "delete", 0 }, -#define MLSTSW 2 - { "list", 0 }, -#define MSEQSW 3 - { "sequence name", 0 }, -#define MPUBSW 4 - { "public", 0 }, -#define MNPUBSW 5 - { "nopublic", 0 }, -#define MZERSW 6 - { "zero", 0 }, -#define MNZERSW 7 - { "nozero", 0 }, -#define MHELP 8 - { "help", 0 }, -#define MDBUGSW 9 - { "debug", -5 }, - { NULL, 0 } -}; - - -void -markcmd (char **args) -{ - int addsw = 0, deletesw = 0, debugsw = 0; - int listsw = 0, zerosw = 0, seqp = 0; - int msgp = 0, msgnum; - char *cp, buf[BUFSIZ]; - char *seqs[NUMATTRS + 1], *msgs[MAXARGS]; - - while ((cp = *args++)) { - if (*cp == '-') { - switch (smatch (++cp, markswit)) { - case AMBIGSW: - ambigsw (cp, markswit); - return; - case UNKWNSW: - fprintf (stderr, "-%s unknown\n", cp); - return; - case MHELP: - snprintf (buf, sizeof(buf), "%s [msgs] [switches]", cmd_name); - print_help (buf, markswit, 1); - return; - - case MADDSW: - addsw++; - deletesw = listsw = 0; - continue; - case MDELSW: - deletesw++; - addsw = listsw = 0; - continue; - case MLSTSW: - listsw++; - addsw = deletesw = 0; - continue; - - case MSEQSW: - if (!(cp = *args++) || *cp == '-') { - advise (NULL, "missing argument to %s", args[-2]); - return; - } - if (seqp < NUMATTRS) - seqs[seqp++] = cp; - else { - advise (NULL, "only %d sequences allowed!", NUMATTRS); - return; - } - continue; - - case MPUBSW: /* not implemented */ - case MNPUBSW: - continue; - - case MDBUGSW: - debugsw++; - continue; - - case MZERSW: - zerosw++; - continue; - case MNZERSW: - zerosw = 0; - continue; - } - } - if (*cp == '+' || *cp == '@') { - advise (NULL, "sorry, no folders allowed!"); - return; - } else { - msgs[msgp++] = cp; - } - } - - if (!addsw && !deletesw && !listsw) { - if (seqp) - addsw++; - else - if (debugsw) - listsw++; - else { - seqs[seqp++] = "unseen"; - deletesw++; - zerosw = 0; - if (!msgp) - msgs[msgp++] = "all"; - } - } - - if (!msgp) - msgs[msgp++] = listsw ? "all" :"cur"; - for (msgnum = 0; msgnum < msgp; msgnum++) - if (!m_convert (mp, msgs[msgnum])) - return; - - if (debugsw) { - printf ("invo_name=%s mypath=%s defpath=%s\n", - invo_name, mypath, defpath); - printf ("ctxpath=%s context flags=%s\n", - ctxpath, snprintb (buf, sizeof(buf), (unsigned) ctxflags, DBITS)); - printf ("foldpath=%s flags=%s\n", - mp->foldpath, - snprintb (buf, sizeof(buf), (unsigned) mp->msgflags, FBITS)); - printf ("hghmsg=%d lowmsg=%d nummsg=%d curmsg=%d\n", - mp->hghmsg, mp->lowmsg, mp->nummsg, mp->curmsg); - printf ("lowsel=%d hghsel=%d numsel=%d\n", - mp->lowsel, mp->hghsel, mp->numsel); - printf ("lowoff=%d hghoff=%d\n", mp->lowoff, mp->hghoff); - } - - if (seqp == 0 && (addsw || deletesw)) { - advise (NULL, "-%s requires at least one -sequence argument", - addsw ? "add" : "delete"); - return; - } - seqs[seqp] = NULL; - - if (addsw) { - for (seqp = 0; seqs[seqp]; seqp++) - if (!seq_addsel (mp, seqs[seqp], 0, zerosw)) - return; - } - - if (deletesw) { - for (seqp = 0; seqs[seqp]; seqp++) - if (!seq_delsel (mp, seqs[seqp], 0, zerosw)) - return; - } - - /* Listing messages in sequences */ - if (listsw) { - if (seqp) { - /* list the given sequences */ - for (seqp = 0; seqs[seqp]; seqp++) - seq_print (mp, seqs[seqp]); - } else { - /* else list them all */ - seq_printall (mp); - } - - interrupted = 0; - if (debugsw) - for (msgnum = mp->lowsel; - msgnum <= mp->hghsel && !interrupted; - msgnum++) - if (is_selected (mp, msgnum)) { - printf ("%*d: id=%d top=%d start=%ld stop=%ld %s\n", - DMAXFOLDER, - msgnum, - Msgs[msgnum].m_bboard_id, - Msgs[msgnum].m_top, - (long) Msgs[msgnum].m_start, - (long) Msgs[msgnum].m_stop, - snprintb (buf, sizeof(buf), - (unsigned) mp->msgstats[msgnum - mp->lowoff], - seq_bits (mp))); - if (Msgs[msgnum].m_scanl) - printf ("%s", Msgs[msgnum].m_scanl); - } - } -} - - -static struct swit mhnswit[] = { -#define MHNAUTOSW 0 - { "auto", 0 }, -#define MHNNAUTOSW 1 - { "noauto", 0 }, -#define MHNDEBUGSW 2 - { "debug", -5 }, -#define MHNEBCDICSW 3 - { "ebcdicsafe", 0 }, -#define MHNNEBCDICSW 4 - { "noebcdicsafe", 0 }, -#define MHNFORMSW 5 - { "form formfile", 4 }, -#define MHNHEADSW 6 - { "headers", 0 }, -#define MHNNHEADSW 7 - { "noheaders", 0 }, -#define MHNLISTSW 8 - { "list", 0 }, -#define MHNNLISTSW 9 - { "nolist", 0 }, -#define MHNPARTSW 10 - { "part number", 0 }, -#define MHNSIZESW 11 - { "realsize", 0 }, -#define MHNNSIZESW 12 - { "norealsize", 0 }, -#define MHNRFC934SW 13 - { "rfc934mode", 0 }, -#define MHNNRFC934SW 14 - { "norfc934mode", 0 }, -#define MHNSERIALSW 15 - { "serialonly", 0 }, -#define MHNNSERIALSW 16 - { "noserialonly", 0 }, -#define MHNSHOWSW 17 - { "show", 0 }, -#define MHNNSHOWSW 18 - { "noshow", 0 }, -#define MHNSTORESW 19 - { "store", 0 }, -#define MHNNSTORESW 20 - { "nostore", 0 }, -#define MHNTYPESW 21 - { "type content", 0 }, -#define MHNVERBSW 22 - { "verbose", 0 }, -#define MHNNVERBSW 23 - { "noverbose", 0 }, -#define MHNHELPSW 24 - { "help", 0 }, -#define MHNPROGSW 25 - { "moreproc program", -4 }, -#define MHNNPROGSW 26 - { "nomoreproc", -3 }, -#define MHNLENSW 27 - { "length lines", -4 }, -#define MHNWIDSW 28 - { "width columns", -4 }, - { NULL, 0 } -}; - - -void -mhncmd (char **args) -{ - int msgp = 0, vecp = 1; - int msgnum; - char *cp, buf[BUFSIZ]; - char *msgs[MAXARGS], *vec[MAXARGS]; - - if (fmsh) { - forkcmd (args, cmd_name); - return; - } - while ((cp = *args++)) { - if (*cp == '-') { - switch (smatch (++cp, mhnswit)) { - case AMBIGSW: - ambigsw (cp, mhnswit); - return; - case UNKWNSW: - fprintf (stderr, "-%s unknown\n", cp); - return; - case MHNHELPSW: - snprintf (buf, sizeof(buf), "%s [msgs] [switches]", cmd_name); - print_help (buf, mhnswit, 1); - return; - - case MHNAUTOSW: - case MHNNAUTOSW: - case MHNDEBUGSW: - case MHNEBCDICSW: - case MHNNEBCDICSW: - case MHNHEADSW: - case MHNNHEADSW: - case MHNLISTSW: - case MHNNLISTSW: - case MHNSIZESW: - case MHNNSIZESW: - case MHNRFC934SW: - case MHNNRFC934SW: - case MHNSERIALSW: - case MHNNSERIALSW: - case MHNSHOWSW: - case MHNNSHOWSW: - case MHNSTORESW: - case MHNNSTORESW: - case MHNVERBSW: - case MHNNVERBSW: - case MHNNPROGSW: - vec[vecp++] = --cp; - continue; - - case MHNFORMSW: - case MHNPARTSW: - case MHNTYPESW: - case MHNPROGSW: - case MHNLENSW: - case MHNWIDSW: - vec[vecp++] = --cp; - if (!(cp = *args++) || *cp == '-') { - advise (NULL, "missing argument to %s", args[-2]); - return; - } - vec[vecp++] = cp; - continue; - } - } - if (*cp == '+' || *cp == '@') { - advise (NULL, "sorry, no folders allowed!"); - return; - } else { - msgs[msgp++] = cp; - } - } - - vec[0] = cmd_name; - vec[vecp++] = "-file"; - vec[vecp] = NULL; - if (!msgp) - msgs[msgp++] = "cur"; - for (msgnum = 0; msgnum < msgp; msgnum++) - if (!m_convert (mp, msgs[msgnum])) - return; - seq_setprev (mp); - - interrupted = 0; - for (msgnum = mp->lowsel; - msgnum <= mp->hghsel && !interrupted; - msgnum++) - if (is_selected (mp, msgnum)) - if (process (msgnum, cmd_name, vecp, vec)) { - unset_selected (mp, msgnum); - mp->numsel--; - } - - seq_setcur (mp, mp->hghsel); -} - - -static struct swit packswit[] = { -#define PAFISW 0 - { "file name", 0 }, -#define PAHELP 1 - { "help", 0 }, - { NULL, 0 } -}; - -static int mbx_style = MMDF_FORMAT; - -void -packcmd (char **args) -{ - int msgp = 0, md, msgnum; - char *cp, *file = NULL; - char buf[BUFSIZ], *msgs[MAXARGS]; - struct stat st; - - if (fmsh) { - forkcmd (args, cmd_name); - return; - } - - while ((cp = *args++)) { - if (*cp == '-') - switch (smatch (++cp, packswit)) { - case AMBIGSW: - ambigsw (cp, packswit); - return; - case UNKWNSW: - fprintf (stderr, "-%s unknown\n", cp); - return; - case PAHELP: - snprintf (buf, sizeof(buf), "%s [msgs] [switches]", cmd_name); - print_help (buf, packswit, 1); - return; - - case PAFISW: - if (!(file = *args++) || *file == '-') { - advise (NULL, "missing argument to %s", args[-2]); - return; - } - continue; - } - if (*cp == '+' || *cp == '@') { - advise (NULL, "sorry, no folders allowed!"); - return; - } - else - msgs[msgp++] = cp; - } - - if (!file) - file = "./msgbox"; - file = path (file, TFILE); - if (stat (file, &st) == NOTOK) { - if (errno != ENOENT) { - advise (file, "error on file"); - goto done_pack; - } - md = getanswer (cp = concat ("Create file \"", file, "\"? ", NULL)); - free (cp); - if (!md) - goto done_pack; - } - - if (!msgp) - msgs[msgp++] = "all"; - for (msgnum = 0; msgnum < msgp; msgnum++) - if (!m_convert (mp, msgs[msgnum])) - goto done_pack; - seq_setprev (mp); - - if ((md = mbx_open (file, mbx_style, getuid (), getgid (), m_gmprot ())) == NOTOK) { - advise (file, "unable to open"); - goto done_pack; - } - for (msgnum = mp->lowsel; msgnum <= mp->hghsel; msgnum++) - if (is_selected (mp, msgnum)) - if (pack (file, md, msgnum) == NOTOK) - break; - mbx_close (file, md); - - if (mp->hghsel != mp->curmsg) - seq_setcur (mp, mp->lowsel); - -done_pack: ; - free (file); -} - - -int -pack (char *mailbox, int md, int msgnum) -{ - register FILE *zp; - - if (Msgs[msgnum].m_bboard_id == 0) - readid (msgnum); - - zp = msh_ready (msgnum, 1); - return mbx_write (mailbox, md, zp, Msgs[msgnum].m_bboard_id, - 0L, ftell (zp), Msgs[msgnum].m_stop, 1, 1); -} - - -int -packhak (char **args) -{ - int result; - char *cp, *file = NULL; - - while ((cp = *args++)) { - if (*cp == '-') - switch (smatch (++cp, packswit)) { - case AMBIGSW: - case UNKWNSW: - case PAHELP: - return NOTOK; - - case PAFISW: - if (!(file = *args++) || *file == '-') - return NOTOK; - continue; - } - if (*cp == '+' || *cp == '@') - return NOTOK; - } - - file = path (file ? file : "./msgbox", TFILE); - result = access (file, F_OK) == NOTOK ? OK : NOTOK; - free (file); - - return result; -} - - -static struct swit pickswit[] = { -#define PIANSW 0 - { "and", 0 }, -#define PIORSW 1 - { "or", 0 }, -#define PINTSW 2 - { "not", 0 }, -#define PILBSW 3 - { "lbrace", 0 }, -#define PIRBSW 4 - { "rbrace", 0 }, -#define PICCSW 5 - { "cc pattern", 0 }, -#define PIDASW 6 - { "date pattern", 0 }, -#define PIFRSW 7 - { "from pattern", 0 }, -#define PISESW 8 - { "search pattern", 0 }, -#define PISUSW 9 - { "subject pattern", 0 }, -#define PITOSW 10 - { "to pattern", 0 }, -#define PIOTSW 11 - { "-othercomponent pattern", 15 }, -#define PIAFSW 12 - { "after date", 0 }, -#define PIBFSW 13 - { "before date", 0 }, -#define PIDFSW 14 - { "datefield field", 5 }, -#define PISQSW 15 - { "sequence name", 0 }, -#define PIPUSW 16 - { "public", 0 }, -#define PINPUSW 17 - { "nopublic", 0 }, -#define PIZRSW 18 - { "zero", 0 }, -#define PINZRSW 19 - { "nozero", 0 }, -#define PILISW 20 - { "list", 0 }, -#define PINLISW 21 - { "nolist", 0 }, -#define PIHELP 22 - { "help", 0 }, - { NULL, 0 } -}; - - -void -pickcmd (char **args) -{ - int zerosw = 1, msgp = 0, seqp = 0; - int vecp = 0, hi, lo, msgnum; - char *cp, buf[BUFSIZ], *msgs[MAXARGS]; - char *seqs[NUMATTRS], *vec[MAXARGS]; - register FILE *zp; - - while ((cp = *args++)) { - if (*cp == '-') { - if (*++cp == '-') { - vec[vecp++] = --cp; - goto pattern; - } - switch (smatch (cp, pickswit)) { - case AMBIGSW: - ambigsw (cp, pickswit); - return; - case UNKWNSW: - fprintf (stderr, "-%s unknown\n", cp); - return; - case PIHELP: - snprintf (buf, sizeof(buf), "%s [msgs] [switches]", cmd_name); - print_help (buf, pickswit, 1); - return; - - case PICCSW: - case PIDASW: - case PIFRSW: - case PISUSW: - case PITOSW: - case PIDFSW: - case PIAFSW: - case PIBFSW: - case PISESW: - vec[vecp++] = --cp; -pattern: ; - if (!(cp = *args++)) {/* allow -xyz arguments */ - advise (NULL, "missing argument to %s", args[-2]); - return; - } - vec[vecp++] = cp; - continue; - case PIOTSW: - advise (NULL, "internal error!"); - return; - case PIANSW: - case PIORSW: - case PINTSW: - case PILBSW: - case PIRBSW: - vec[vecp++] = --cp; - continue; - - case PISQSW: - if (!(cp = *args++) || *cp == '-') { - advise (NULL, "missing argument to %s", args[-2]); - return; - } - if (seqp < NUMATTRS) - seqs[seqp++] = cp; - else { - advise (NULL, "only %d sequences allowed!", NUMATTRS); - return; - } - continue; - case PIZRSW: - zerosw++; - continue; - case PINZRSW: - zerosw = 0; - continue; - - case PIPUSW: /* not implemented */ - case PINPUSW: - case PILISW: - case PINLISW: - continue; - } - } - if (*cp == '+' || *cp == '@') { - advise (NULL, "sorry, no folders allowed!"); - return; - } - else - msgs[msgp++] = cp; - } - vec[vecp] = NULL; - - if (!msgp) - msgs[msgp++] = "all"; - for (msgnum = 0; msgnum < msgp; msgnum++) - if (!m_convert (mp, msgs[msgnum])) - return; - seq_setprev (mp); - - interrupted = 0; - if (!pcompile (vec, NULL)) - return; - - lo = mp->lowsel; - hi = mp->hghsel; - - for (msgnum = mp->lowsel; - msgnum <= mp->hghsel && !interrupted; - msgnum++) - if (is_selected (mp, msgnum)) { - zp = msh_ready (msgnum, 1); - if (pmatches (zp, msgnum, fmsh ? 0L : Msgs[msgnum].m_start, - fmsh ? 0L : Msgs[msgnum].m_stop)) { - if (msgnum < lo) - lo = msgnum; - if (msgnum > hi) - hi = msgnum; - } - else { - unset_selected (mp, msgnum); - mp->numsel--; - } - } - - if (interrupted) - return; - - mp->lowsel = lo; - mp->hghsel = hi; - - if (mp->numsel <= 0) { - advise (NULL, "no messages match specification"); - return; - } - - seqs[seqp] = NULL; - for (seqp = 0; seqs[seqp]; seqp++) - if (!seq_addsel (mp, seqs[seqp], 0, zerosw)) - return; - - printf ("%d hit%s\n", mp->numsel, mp->numsel == 1 ? "" : "s"); -} - - -static struct swit replswit[] = { -#define REANSW 0 - { "annotate", 0 }, -#define RENANSW 1 - { "noannotate", 0 }, -#define RECCSW 2 - { "cc type", 0 }, -#define RENCCSW 3 - { "nocc type", 0 }, -#define REDFSW 4 - { "draftfolder +folder", 0 }, -#define REDMSW 5 - { "draftmessage msg", 0 }, -#define RENDFSW 6 - { "nodraftfolder", 0 }, -#define REEDTSW 7 - { "editor editor", 0 }, -#define RENEDSW 8 - { "noedit", 0 }, -#define REFCCSW 9 - { "fcc +folder", 0 }, -#define REFLTSW 10 - { "filter filterfile", 0 }, -#define REFRMSW 11 - { "form formfile", 0 }, -#define REINSW 12 - { "inplace", 0 }, -#define RENINSW 13 - { "noinplace", 0 }, -#define REQUSW 14 - { "query", 0 }, -#define RENQUSW 15 - { "noquery", 0 }, -#define REWHTSW 16 - { "whatnowproc program", 0 }, -#define RENWTSW 17 - { "nowhatnow", 0 }, -#define REWIDSW 19 - { "width columns", 0 }, -#define REHELP 20 - { "help", 0 }, - { NULL, 0 } -}; - - -void -replcmd (char **args) -{ - int vecp = 1; - char *cp, *msg = NULL; - char buf[BUFSIZ], *vec[MAXARGS]; - - if (fmsh) { - forkcmd (args, cmd_name); - return; - } - - while ((cp = *args++)) { - if (*cp == '-') - switch (smatch (++cp, replswit)) { - case AMBIGSW: - ambigsw (cp, replswit); - return; - case UNKWNSW: - fprintf (stderr, "-%s unknown\n", cp); - return; - case REHELP: - snprintf (buf, sizeof(buf), "%s [msgs] [switches]", cmd_name); - print_help (buf, replswit, 1); - return; - - case REANSW: /* not implemented */ - case RENANSW: - case REINSW: - case RENINSW: - continue; - - case REQUSW: - case RENQUSW: - case RENDFSW: - case RENEDSW: - case RENWTSW: - vec[vecp++] = --cp; - continue; - - case RECCSW: - case RENCCSW: - case REEDTSW: - case REFCCSW: - case REFLTSW: - case REFRMSW: - case REWIDSW: - case REDFSW: - case REDMSW: - case REWHTSW: - vec[vecp++] = --cp; - if (!(cp = *args++) || *cp == '-') { - advise (NULL, "missing argument to %s", args[-2]); - return; - } - vec[vecp++] = cp; - continue; - } - if (*cp == '+' || *cp == '@') { - advise (NULL, "sorry, no folders allowed!"); - return; - } - else - if (msg) { - advise (NULL, "only one message at a time!"); - return; - } - else - msg = cp; - } - - vec[0] = cmd_name; - vec[vecp++] = "-file"; - vec[vecp] = NULL; - if (!msg) - msg = "cur"; - if (!m_convert (mp, msg)) - return; - seq_setprev (mp); - - if (mp->numsel > 1) { - advise (NULL, "only one message at a time!"); - return; - } - process (mp->hghsel, cmd_name, vecp, vec); - seq_setcur (mp, mp->hghsel); -} - - -static struct swit rmmswit[] = { -#define RMHELP 0 - { "help", 0 }, - { NULL, 0 } -}; - - -void -rmmcmd (char **args) -{ - int msgp = 0, msgnum; - char *cp, buf[BUFSIZ], *msgs[MAXARGS]; - - while ((cp = *args++)) { - if (*cp == '-') - switch (smatch (++cp, rmmswit)) { - case AMBIGSW: - ambigsw (cp, rmmswit); - return; - case UNKWNSW: - fprintf (stderr, "-%s unknown\n", cp); - return; - case RMHELP: - snprintf (buf, sizeof(buf), "%s [msgs] [switches]", cmd_name); - print_help (buf, rmmswit, 1); - return; - } - if (*cp == '+' || *cp == '@') { - advise (NULL, "sorry, no folders allowed!"); - return; - } - else - msgs[msgp++] = cp; - } - - if (!msgp) - msgs[msgp++] = "cur"; - for (msgnum = 0; msgnum < msgp; msgnum++) - if (!m_convert (mp, msgs[msgnum])) - return; - seq_setprev (mp); - - rmm (); -} - - -static void -rmm (void) -{ - register int msgnum, vecp; - register char *cp; - char buffer[BUFSIZ], *vec[MAXARGS]; - - if (fmsh) { - if (rmmproc) { - if (mp->numsel > MAXARGS - 1) { - advise (NULL, "more than %d messages for %s exec", - MAXARGS - 1, rmmproc); - return; - } - vecp = 0; - for (msgnum = mp->lowsel; msgnum <= mp->hghsel; msgnum++) - if (is_selected (mp, msgnum)) - vec[vecp++] = getcpy (m_name (msgnum)); - vec[vecp] = NULL; - forkcmd (vec, rmmproc); - for (vecp = 0; vec[vecp]; vecp++) - free (vec[vecp]); - } - else - for (msgnum = mp->lowsel; msgnum <= mp->hghsel; msgnum++) - if (is_selected (mp, msgnum)) { - strncpy (buffer, m_backup (cp = m_name (msgnum)), sizeof(buffer)); - if (rename (cp, buffer) == NOTOK) - admonish (buffer, "unable to rename %s to", cp); - } - } - - for (msgnum = mp->lowsel; msgnum <= mp->hghsel; msgnum++) - if (is_selected (mp, msgnum)) { - set_deleted (mp, msgnum); - unset_exists (mp, msgnum); - } - - if ((mp->nummsg -= mp->numsel) <= 0) { - if (fmsh) - admonish (NULL, "no messages remaining in +%s", fmsh); - else - admonish (NULL, "no messages remaining in %s", mp->foldpath); - mp->lowmsg = mp->hghmsg = mp->nummsg = 0; - } - if (mp->lowsel == mp->lowmsg) { - for (msgnum = mp->lowmsg + 1; msgnum <= mp->hghmsg; msgnum++) - if (does_exist (mp, msgnum)) - break; - mp->lowmsg = msgnum; - } - if (mp->hghsel == mp->hghmsg) { - for (msgnum = mp->hghmsg - 1; msgnum >= mp->lowmsg; msgnum--) - if (does_exist (mp, msgnum)) - break; - mp->hghmsg = msgnum; - } - - mp->msgflags |= MODIFIED; - modified++; -} - - -static struct swit scanswit[] = { -#define SCCLR 0 - { "clear", 0 }, -#define SCNCLR 1 - { "noclear", 0 }, -#define SCFORM 2 - { "form formatfile", 0 }, -#define SCFMT 3 - { "format string", 5 }, -#define SCHEAD 4 - { "header", 0 }, -#define SCNHEAD 5 - { "noheader", 0 }, -#define SCWID 6 - { "width columns", 0 }, -#define SCHELP 7 - { "help", 0 }, - { NULL, 0 } -}; - - -void -scancmd (char **args) -{ -#define equiv(a,b) (a ? b && !strcmp (a, b) : !b) - - int clearsw = 0, headersw = 0, width = 0, msgp = 0; - int msgnum, optim, state; - char *cp, *form = NULL, *format = NULL; - char buf[BUFSIZ], *nfs, *msgs[MAXARGS]; - register FILE *zp; - static int s_optim = 0; - static char *s_form = NULL, *s_format = NULL; - - while ((cp = *args++)) { - if (*cp == '-') - switch (smatch (++cp, scanswit)) { - case AMBIGSW: - ambigsw (cp, scanswit); - return; - case UNKWNSW: - fprintf (stderr, "-%s unknown\n", cp); - return; - case SCHELP: - snprintf (buf, sizeof(buf), "%s [msgs] [switches]", cmd_name); - print_help (buf, scanswit, 1); - return; - - case SCCLR: - clearsw++; - continue; - case SCNCLR: - clearsw = 0; - continue; - case SCHEAD: - headersw++; - continue; - case SCNHEAD: - headersw = 0; - continue; - case SCFORM: - if (!(form = *args++) || *form == '-') { - advise (NULL, "missing argument to %s", args[-2]); - return; - } - format = NULL; - continue; - case SCFMT: - if (!(format = *args++) || *format == '-') { - advise (NULL, "missing argument to %s", args[-2]); - return; - } - form = NULL; - continue; - case SCWID: - if (!(cp = *args++) || *cp == '-') { - advise (NULL, "missing argument to %s", args[-2]); - return; - } - width = atoi (cp); - continue; - } - if (*cp == '+' || *cp == '@') { - advise (NULL, "sorry, no folders allowed!"); - return; - } - else - msgs[msgp++] = cp; - } - - if (!msgp) - msgs[msgp++] = "all"; - for (msgnum = 0; msgnum < msgp; msgnum++) - if (!m_convert (mp, msgs[msgnum])) - return; - seq_setprev (mp); - - /* Get new format string */ - nfs = new_fs (form, format, FORMAT); - - /* force scansbr to (re)compile format */ - if (scanl) { - free (scanl); - scanl = NULL; - } - - if (s_optim == 0) { - s_optim = optim = 1; - s_form = form ? getcpy (form) : NULL; - s_format = format ? getcpy (format) : NULL; - - } - else - optim = equiv (s_form, form) && equiv (s_format, format); - - interrupted = 0; - for (msgnum = mp->lowsel; - msgnum <= mp->hghsel && !interrupted; - msgnum++) - if (is_selected (mp, msgnum)) { - if (optim && Msgs[msgnum].m_scanl) - printf ("%s", Msgs[msgnum].m_scanl); - else { - - zp = msh_ready (msgnum, 0); - switch (state = scan (zp, msgnum, 0, nfs, width, - msgnum == mp->curmsg, - is_unseen (mp, msgnum), - headersw ? (fmsh ? fmsh : mp->foldpath) : NULL, - fmsh ? 0L : (long) (Msgs[msgnum].m_stop - Msgs[msgnum].m_start), - 1)) { - case SCNMSG: - case SCNENC: - case SCNERR: - if (optim) - Msgs[msgnum].m_scanl = getcpy (scanl); - break; - - default: - advise (NULL, "scan() botch (%d)", state); - return; - - case SCNEOF: - printf ("%*d empty\n", DMAXFOLDER, msgnum); - break; - } - } - headersw = 0; - } - - if (clearsw) - clear_screen (); -} - - -static struct swit showswit[] = { -#define SHDRAFT 0 - { "draft", 5 }, -#define SHFORM 1 - { "form formfile", 4 }, -#define SHPROG 2 - { "moreproc program", 4 }, -#define SHNPROG 3 - { "nomoreproc", 3 }, -#define SHLEN 4 - { "length lines", 4 }, -#define SHWID 5 - { "width columns", 4 }, -#define SHSHOW 6 - { "showproc program", 4 }, -#define SHNSHOW 7 - { "noshowproc", 3 }, -#define SHHEAD 8 - { "header", 4 }, -#define SHNHEAD 9 - { "noheader", 3 }, -#define SHHELP 10 - { "help", 0 }, - { NULL, 0 } -}; - - -void -showcmd (char **args) -{ - int headersw = 1, nshow = 0, msgp = 0, vecp = 1; - int mhl = 0, seqnum = -1, mode = 0, i, msgnum; - char *cp, *proc = showproc, buf[BUFSIZ]; - char *msgs[MAXARGS], *vec[MAXARGS]; - - if (!mh_strcasecmp (cmd_name, "next")) - mode = 1; - else - if (!mh_strcasecmp (cmd_name, "prev")) - mode = -1; - while ((cp = *args++)) { - if (*cp == '-') - switch (i = smatch (++cp, showswit)) { - case AMBIGSW: - ambigsw (cp, showswit); - return; - case UNKWNSW: - case SHNPROG: - vec[vecp++] = --cp; - continue; - case SHHELP: - snprintf (buf, sizeof(buf), "%s %s[switches] [switches for showproc]", - cmd_name, mode ? NULL : "[msgs] "); - print_help (buf, showswit, 1); - return; - - case SHFORM: - case SHPROG: - case SHLEN: - case SHWID: - vec[vecp++] = --cp; - if (!(cp = *args++) || *cp == '-') { - advise (NULL, "missing argument to %s", args[-2]); - return; - } - vec[vecp++] = cp; - continue; - case SHHEAD: - headersw++; - continue; - case SHNHEAD: - headersw = 0; - continue; - case SHSHOW: - if (!(proc = *args++) || *proc == '-') { - advise (NULL, "missing argument to %s", args[-2]); - return; - } - nshow = 0; - continue; - case SHNSHOW: - nshow++; - continue; - - case SHDRAFT: - advise (NULL, "sorry, -%s not allowed!", showswit[i].sw); - return; - } - if (*cp == '+' || *cp == '@') { - advise (NULL, "sorry, no folders allowed!"); - return; - } - else - if (mode) { - fprintf (stderr, - "usage: %s [switches] [switches for showproc]\n", - cmd_name); - return; - } - else - msgs[msgp++] = cp; - } - vec[vecp] = NULL; - - if (!msgp) - msgs[msgp++] = mode > 0 ? "next" : mode < 0 ? "prev" : "cur"; - for (msgnum = 0; msgnum < msgp; msgnum++) - if (!m_convert (mp, msgs[msgnum])) - return; - seq_setprev (mp); - - if (!nshow && !getenv ("NOMHNPROC")) - for (msgnum = mp->lowsel; msgnum <= mp->hghsel; msgnum++) - if (is_selected (mp, msgnum) && is_nontext (msgnum)) { - proc = showmimeproc; - vec[vecp++] = "-file"; - vec[vecp] = NULL; - goto finish; - } - - if (nshow) - proc = catproc; - else - if (strcmp (showproc, "mhl") == 0) { - proc = mhlproc; - mhl++; - } - -finish: ; - seqnum = seq_getnum (mp, "unseen"); - vec[0] = r1bindex (proc, '/'); - if (mhl) { - msgp = vecp; - for (msgnum = mp->lowsel; msgnum <= mp->hghsel; msgnum++) - if (is_selected (mp, msgnum)) { - vec[vecp++] = getcpy (m_name (msgnum)); - if (seqnum != -1) - seq_delmsg (mp, "unseen", msgnum); - } - vec[vecp] = NULL; - if (mp->numsel == 1 && headersw) - show (mp->lowsel); - mhlsbr (vecp, vec, mhl_action); - m_eomsbr ((int (*)()) 0); - while (msgp < vecp) - free (vec[msgp++]); - } else { - interrupted = 0; - for (msgnum = mp->lowsel; - msgnum <= mp->hghsel && !interrupted; - msgnum++) - if (is_selected (mp, msgnum)) { - switch (ask (msgnum)) { - case NOTOK: /* QUIT */ - break; - - case OK: /* INTR */ - continue; - - default: - if (mp->numsel == 1 && headersw) - show (msgnum); - if (nshow) - copy_message (msgnum, stdout); - else - process (msgnum, proc, vecp, vec); - - if (seqnum != -1) - seq_delmsg (mp, "unseen", msgnum); - continue; - } - break; - } - } - - seq_setcur (mp, mp->hghsel); -} - - -static void -show (int msgnum) -{ - if (Msgs[msgnum].m_bboard_id == 0) - readid (msgnum); - - printf ("(Message %d", msgnum); - if (Msgs[msgnum].m_bboard_id > 0) - printf (", %s: %d", BBoard_ID, Msgs[msgnum].m_bboard_id); - printf (")\n"); -} - - - -static int -eom_action (int c) -{ - return (ftell (mhlfp) >= Msgs[mhlnum].m_stop); -} - - -static FILE * -mhl_action (char *name) -{ - int msgnum; - - if ((msgnum = m_atoi (name)) < mp->lowmsg - || msgnum > mp->hghmsg - || !does_exist (mp, msgnum)) - return NULL; - mhlnum = msgnum; - - mhlfp = msh_ready (msgnum, 1); - if (!fmsh) - m_eomsbr (eom_action); - - return mhlfp; -} - - - -static int -ask (int msgnum) -{ - char buf[BUFSIZ]; - - if (mp->numsel == 1 || !interactive || redirected) - return DONE; - - if (SOprintf ("Press to list \"%d\"...", msgnum)) { - if (mp->lowsel != msgnum) - printf ("\n\n\n"); - printf ("Press to list \"%d\"...", msgnum); - } - fflush (stdout); - buf[0] = 0; - -#ifndef BSD42 - read (fileno (stdout), buf, sizeof buf); -#else /* BSD42 */ - switch (setjmp (sigenv)) { - case OK: - should_intr = 1; - read (fileno (stdout), buf, sizeof buf);/* fall... */ - - default: - should_intr = 0; - break; - } -#endif /* BSD42 */ - - if (strchr(buf, '\n') == NULL) - putchar ('\n'); - - if (told_to_quit) { - told_to_quit = interrupted = 0; - return NOTOK; - } - if (interrupted) { - interrupted = 0; - return OK; - } - - return DONE; -} - - -#include - -static int -is_nontext (int msgnum) -{ - int result, state; - unsigned char *bp, *dp; - char *cp; - char buf[BUFSIZ], name[NAMESZ]; - FILE *fp; - - if (Msgs[msgnum].m_flags & MHNCHK) - return (Msgs[msgnum].m_flags & MHNYES); - Msgs[msgnum].m_flags |= MHNCHK; - - fp = msh_ready (msgnum, 1); - - for (state = FLD;;) - switch (state = m_getfld (state, name, buf, sizeof buf, fp)) { - case FLD: - case FLDPLUS: - case FLDEOF: - /* - * Check Content-Type field - */ - if (!mh_strcasecmp (name, TYPE_FIELD)) { - int passno; - char c; - - cp = add (buf, NULL); - while (state == FLDPLUS) { - state = m_getfld (state, name, buf, sizeof buf, fp); - cp = add (buf, cp); - } - bp = cp; - passno = 1; - -again: - for (; isspace (*bp); bp++) - continue; - if (*bp == '(') { - int i; - - for (bp++, i = 0;;) { - switch (*bp++) { - case '\0': -invalid: - result = 0; - goto out; - case '\\': - if (*bp++ == '\0') - goto invalid; - continue; - case '(': - i++; - /* and fall... */ - default: - continue; - case ')': - if (--i < 0) - break; - continue; - } - break; - } - } - if (passno == 2) { - if (*bp != '/') - goto invalid; - bp++; - passno = 3; - goto again; - } - for (dp = bp; istoken (*dp); dp++) - continue; - c = *dp; - *dp = '\0'; - if (!*bp) - goto invalid; - if (passno > 1) { - if ((result = (mh_strcasecmp (bp, "plain") != 0))) - goto out; - *dp = c; - for (dp++; isspace (*dp); dp++) - continue; - if (*dp) { - if ((result = !uprf (dp, "charset"))) - goto out; - dp += sizeof "charset" - 1; - while (isspace (*dp)) - dp++; - if (*dp++ != '=') - goto invalid; - while (isspace (*dp)) - dp++; - if (*dp == '"') { - if ((bp = strchr(++dp, '"'))) - *bp = '\0'; - } else { - for (bp = dp; *bp; bp++) - if (isspace (*bp)) { - *bp = '\0'; - break; - } - } - } else { - /* Default character set */ - dp = "US-ASCII"; - } - /* Check the character set */ - result = !check_charset (dp, strlen (dp)); - } else { - if (!(result = (mh_strcasecmp (bp, "text") != 0))) { - *dp = c; - bp = dp; - passno = 2; - goto again; - } - } -out: - free (cp); - if (result) { - Msgs[msgnum].m_flags |= MHNYES; - return result; - } - break; - } - - /* - * Check Content-Transfer-Encoding field - */ - if (!mh_strcasecmp (name, ENCODING_FIELD)) { - cp = add (buf, NULL); - while (state == FLDPLUS) { - state = m_getfld (state, name, buf, sizeof buf, fp); - cp = add (buf, cp); - } - for (bp = cp; isspace (*bp); bp++) - continue; - for (dp = bp; istoken (*dp); dp++) - continue; - *dp = '\0'; - result = (mh_strcasecmp (bp, "7bit") - && mh_strcasecmp (bp, "8bit") - && mh_strcasecmp (bp, "binary")); - - free (cp); - if (result) { - Msgs[msgnum].m_flags |= MHNYES; - return result; - } - break; - } - - /* - * Just skip the rest of this header - * field and go to next one. - */ - while (state == FLDPLUS) - state = m_getfld (state, name, buf, sizeof(buf), fp); - break; - - /* - * We've passed the message header, - * so message is just text. - */ - default: - return 0; - } -} - - -static struct swit sortswit[] = { -#define SODATE 0 - { "datefield field", 0 }, -#define SOSUBJ 1 - { "textfield field", 0 }, -#define SONSUBJ 2 - { "notextfield", 0 }, -#define SOLIMT 3 - { "limit days", 0 }, -#define SONLIMT 4 - { "nolimit", 0 }, -#define SOVERB 5 - { "verbose", 0 }, -#define SONVERB 6 - { "noverbose", 0 }, -#define SOHELP 7 - { "help", 0 }, - { NULL, 0 } -}; - - -void -sortcmd (char **args) -{ - int msgp = 0, msgnum; - char *cp, *datesw = NULL, *subjsw = NULL; - char buf[BUFSIZ], *msgs[MAXARGS]; - struct tws tb; - - if (fmsh) { - forkcmd (args, cmd_name); - return; - } - - while ((cp = *args++)) { - if (*cp == '-') - switch (smatch (++cp, sortswit)) { - case AMBIGSW: - ambigsw (cp, sortswit); - return; - case UNKWNSW: - fprintf (stderr, "-%s unknown\n", cp); - return; - case SOHELP: - snprintf (buf, sizeof(buf), "%s [msgs] [switches]", cmd_name); - print_help (buf, sortswit, 1); - return; - - case SODATE: - if (datesw) { - advise (NULL, "only one date field at a time!"); - return; - } - if (!(datesw = *args++) || *datesw == '-') { - advise (NULL, "missing argument to %s", args[-2]); - return; - } - continue; - - case SOSUBJ: - if (subjsw) { - advise (NULL, "only one text field at a time!"); - return; - } - if (!(subjsw = *args++) || *subjsw == '-') { - advise (NULL, "missing argument to %s", args[-2]); - return; - } - continue; - case SONSUBJ: - subjsw = (char *)0; - continue; - - case SOLIMT: /* too hard */ - if (!(cp = *args++) || *cp == '-') { - advise (NULL, "missing argument to %s", args[-2]); - return; - } - case SONLIMT: - case SOVERB: /* not implemented */ - case SONVERB: - continue; - } - if (*cp == '+' || *cp == '@') { - advise (NULL, "sorry, no folders allowed!"); - return; - } - else - msgs[msgp++] = cp; - } - - if (!msgp) - msgs[msgp++] = "all"; - if (!datesw) - datesw = "Date"; - for (msgnum = 0; msgnum < msgp; msgnum++) - if (!m_convert (mp, msgs[msgnum])) - return; - seq_setprev (mp); - - twscopy (&tb, dlocaltimenow ()); - - for (msgnum = mp->lowsel; msgnum <= mp->hghsel; msgnum++) { - if (Msgs[msgnum].m_scanl) { - free (Msgs[msgnum].m_scanl); - Msgs[msgnum].m_scanl = NULL; - } - if (is_selected (mp, msgnum)) { - if (get_fields (datesw, subjsw, msgnum, &Msgs[msgnum])) - twscopy (&Msgs[msgnum].m_tb, - msgnum != mp->lowsel ? &Msgs[msgnum - 1].m_tb : &tb); - } - else /* m_scaln is already NULL */ - twscopy (&Msgs[msgnum].m_tb, &tb); - Msgs[msgnum].m_stats = mp->msgstats[msgnum - mp->lowoff]; - if (mp->curmsg == msgnum) - Msgs[msgnum].m_stats |= CUR; - } - - qsort ((char *) &Msgs[mp->lowsel], mp->hghsel - mp->lowsel + 1, - sizeof(struct Msg), (qsort_comp) (subjsw ? subsort : msgsort)); - - for (msgnum = mp->lowsel; msgnum <= mp->hghsel; msgnum++) { - if (subjsw && Msgs[msgnum].m_scanl) { - free (Msgs[msgnum].m_scanl); /* from subjsort */ - Msgs[msgnum].m_scanl = NULL; - } - mp->msgstats[msgnum - mp->lowoff] = Msgs[msgnum].m_stats & ~CUR; - if (Msgs[msgnum].m_stats & CUR) - seq_setcur (mp, msgnum); - } - - mp->msgflags |= MODIFIED; - modified++; -} - - -/* - * get_fields - parse message, and get date and subject if needed. - * We'll use the msgp->m_tb tws struct for the date, and overload - * the msgp->m_scanl field with our subject string. - */ -static int -get_fields (char *datesw, char *subjsw, int msgnum, struct Msg *msgp) -{ - int state, gotdate = 0; - char *bp, buf[BUFSIZ], name[NAMESZ]; - struct tws *tw = (struct tws *) 0; - register FILE *zp; - - zp = msh_ready (msgnum, 0); - for (state = FLD;;) { - switch (state = m_getfld (state, name, buf, sizeof buf, zp)) { - case FLD: - case FLDEOF: - case FLDPLUS: - if (!mh_strcasecmp (name, datesw)) { - bp = getcpy (buf); - while (state == FLDPLUS) { - state = m_getfld (state, name, buf, sizeof buf, zp); - bp = add (buf, bp); - } - if ((tw = dparsetime (bp)) == NULL) - admonish (NULL, - "unable to parse %s field in message %d", - datesw, msgnum); - else - twscopy (&(msgp->m_tb), tw); - free (bp); - if (!subjsw) /* not using this, or already done */ - break; /* all done! */ - gotdate++; - } - else if (subjsw && !mh_strcasecmp(name, subjsw)) { - bp = getcpy (buf); - while (state == FLDPLUS) { - state = m_getfld (state, name, buf, sizeof buf, zp); - bp = add (buf, bp); - } - msgp->m_scanl = sosmash(subjsw, bp); - if (gotdate) - break; /* date done so we're done */ - else - subjsw = (char *)0;/* subject done, need date */ - } else { - while (state == FLDPLUS) /* flush this one */ - state = m_getfld (state, name, buf, sizeof buf, zp); - } - continue; - - case BODY: - case BODYEOF: - case FILEEOF: - break; - - case LENERR: - case FMTERR: - admonish (NULL, "format error in message %d", msgnum); - if (msgp->m_scanl) { /* this might need free'd */ - free (msgp->m_scanl); /* probably can't use subj anyway */ - msgp->m_scanl = NULL; - } - return NOTOK; - - default: - adios (NULL, "internal error -- you lose"); - } - break; - } - if (tw) - return OK; /* not an error if subj not found */ - - admonish (NULL, "no %s field in message %d", datesw, msgnum); - return NOTOK; /* NOTOK means use some other date */ -} - - -/* - * sort routines - */ - -static int -msgsort (struct Msg *a, struct Msg *b) -{ - return twsort (&a->m_tb, &b->m_tb); -} - - -static int -subsort (struct Msg *a, struct Msg *b) -{ - register int i; - - if (a->m_scanl && b->m_scanl) - if ((i = strcmp (a->m_scanl, b->m_scanl))) - return (i); - - return twsort (&a->m_tb, &b->m_tb); -} - - -/* - * try to make the subject "canonical": delete leading "re:", everything - * but letters & smash letters to lower case. - */ -static char * -sosmash (char *subj, char *s) -{ - register char *cp, *dp; - register unsigned char c; - - if (s) { - cp = s; - dp = s; /* dst pointer */ - if (!mh_strcasecmp (subj, "subject")) - while ((c = *cp)) { - if (! isspace(c)) { - if(uprf(cp, "re:")) - cp += 2; - else { - if (isalnum(c)) - *dp++ = isupper(c) ? tolower(c) : c; - break; - } - } - cp++; - } - while ((c = *cp++)) { - if (isalnum(c)) - *dp++ = isupper(c) ? tolower(c) : c; - - } - *dp = '\0'; - } - return s; -} - - -static int -process (int msgnum, char *proc, int vecp, char **vec) -{ - int child_id, status; - char tmpfil[BUFSIZ]; - FILE *out; - char *cp; - - if (fmsh) { - strncpy (tmpfil, m_name (msgnum), sizeof(tmpfil)); - context_del (pfolder); - context_replace (pfolder, fmsh);/* update current folder */ - seq_save (mp); - context_save (); /* save the context file */ - goto ready; - } - - cp = m_mktemp(invo_name, NULL, &out); - if (cp == NULL) { - /* Try again, but try to create under /tmp */ - int olderr = errno; - cp = m_mktemp2(NULL, invo_name, NULL, &out); - if (cp == NULL) { - errno = olderr; - advise (NULL, "unable to create temporary file"); - return NOTOK; - } - } - copy_message (msgnum, out); - fclose (out); - strncpy(tmpfil, cp, sizeof(tmpfil)); - -ready: ; - fflush (stdout); - switch (child_id = fork ()) { - case NOTOK: - advise ("fork", "unable to"); - status = NOTOK; - break; - - case OK: - closefds (3); - SIGNAL (SIGINT, istat); - SIGNAL (SIGQUIT, qstat); - - vec[vecp++] = tmpfil; - vec[vecp] = NULL; - - execvp (proc, vec); - fprintf (stderr, "unable to exec "); - perror (proc); - _exit (1); - - default: - status = pidXwait (child_id, NULL); - break; - } - - if (!fmsh) - unlink (tmpfil); - return status; -} - - -static void -copy_message (int msgnum, FILE *out) -{ - long pos; - static char buffer[BUFSIZ]; - register FILE *zp; - - zp = msh_ready (msgnum, 1); - if (fmsh) { - while (fgets (buffer, sizeof buffer, zp) != NULL) { - fputs (buffer, out); - if (interrupted && out == stdout) - break; - } - } - else { - pos = ftell (zp); - while (fgets (buffer, sizeof buffer, zp) != NULL - && pos < Msgs[msgnum].m_stop) { - fputs (buffer, out); - pos += (long) strlen (buffer); - if (interrupted && out == stdout) - break; - } - } -} - - -static void -copy_digest (int msgnum, FILE *out) -{ - char c; - long pos = 0L; - static char buffer[BUFSIZ]; - register FILE *zp; - - c = '\n'; - zp = msh_ready (msgnum, 1); - if (!fmsh) - pos = ftell (zp); - while (fgets (buffer, sizeof buffer, zp) != NULL - && !fmsh && pos < Msgs[msgnum].m_stop) { - if (c == '\n' && *buffer == '-') - fputc (' ', out); - fputs (buffer, out); - c = buffer[strlen (buffer) - 1]; - if (!fmsh) - pos += (long) strlen (buffer); - if (interrupted && out == stdout) - break; - } -} diff --git a/uip/vmh.c b/uip/vmh.c deleted file mode 100644 index 908df85..0000000 --- a/uip/vmh.c +++ /dev/null @@ -1,1515 +0,0 @@ - -/* - * vmh.c -- visual front-end to nmh - * - * 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 -#include - -#if 0 -#if defined(SYS5) && !defined(TERMINFO) -/* - * Define TERMINFO if you have it. - * You get it automatically if you're running SYS5, and you don't get - * it if you're not. (If you're not SYS5, you probably have termcap.) - * We distinguish TERMINFO from SYS5 because in this file SYS5 really - * means "AT&T line discipline" (termio, not sgttyb), whereas terminfo - * is quite a separate issue. - */ -#define TERMINFO 1 -#endif -#endif - -/* - * TODO: - * 1) Pass signals to client during execution - * 2) Figure out a way for the user to say how big the Scan/Display - * windows should be. - * 3) If curses ever gets fixed, then XYZ code can be removed - */ - -#include - -#ifdef ncr -# define _SYS_REG_H /* NCR redefines "ERR" in */ -#endif - -#undef OK /* tricky */ - -/* removed for right now */ -#if 0 -#ifdef TERMINFO -# include /* variables describing terminal capabilities */ -#endif /* TERMINFO */ -#endif - -#include -#include -#include -#include - -#ifndef sigmask -# define sigmask(s) (1 << ((s) - 1)) -#endif /* not sigmask */ - -#ifdef ridge -# undef SIGTSTP -#endif /* ridge */ - -#ifdef HAVE_WRITEV -# include -#else -struct iovec { - char *iov_base; - int iov_len; -}; -#endif - -#ifdef hpux -# include -# define TCGETATTR /* tcgetattr() */ -#endif - -#ifdef BSD44 -# define USE_OLD_TTY -# define _maxx maxx /* curses.h */ -# define _maxy maxy -# define _curx curx /* curses.h */ -# define _cury cury -void __cputchar __P((int)); -# undef _putchar -# define _putchar __cputchar -# include /* sgttyb */ -#endif - -#define ALARM ((unsigned int) 10) -#define PAUSE ((unsigned int) 2) - -#ifndef abs -# define abs(a) ((a) > 0 ? (a) : -(a)) -#endif - -#define SMALLMOVE 1 -#define LARGEMOVE 10 - -#define XYZ /* XXX */ - -static struct swit switches[] = { -#define PRMPTSW 0 - { "prompt string", 6 }, -#define PROGSW 1 - { "vmhproc program", 7 }, -#define NPROGSW 2 - { "novmhproc", 9 }, -#define VERSIONSW 3 - { "version", 0 }, -#define HELPSW 4 - { "help", 0 }, - { NULL, 0 } -}; - - /* PEERS */ -static int PEERpid = NOTOK; - -static jmp_buf PEERctx; - - /* WINDOWS */ -static char *myprompt = "(%s) "; - -static WINDOW *Scan; -static WINDOW *Status; -static WINDOW *Display; -static WINDOW *Command; - -#define NWIN 3 -static int numwins; -WINDOW *windows[NWIN + 1]; - - - /* LINES */ - -struct line { - int l_no; - char *l_buf; - struct line *l_prev; - struct line *l_next; -}; - -static struct line *lhead = NULL; -static struct line *ltop = NULL; -static struct line *ltail = NULL; - -static int did_less = 0; -static int smallmove = SMALLMOVE; -static int largemove = LARGEMOVE; - - - /* TTYS */ - -static int tty_ready = NOTOK; - -static int intrc; - -#ifndef SYS5 -# define ERASE sg.sg_erase -# define KILL sg.sg_kill -static struct sgttyb sg; - -#define EOFC tc.t_eofc -#define INTR tc.t_intrc -static struct tchars tc; -#else /* SYS5 */ -# define ERASE sg.c_cc[VERASE] -# define KILL sg.c_cc[VKILL] -# define EOFC sg.c_cc[VEOF] -# define INTR sg.c_cc[VINTR] -static struct termio sg; -#endif /* SYS5 */ - -#ifndef TIOCGLTC -# define WERASC ('W' & 037) -#else /* TIOCGLTC */ -# ifndef SVR4 -# define WERASC ltc.t_werasc -static struct ltchars ltc; -# else /* SVR4 */ -# define WERASC sg.c_cc[VWERASE] -# undef TIOCGLTC /* the define exists, but struct ltchars doesn't */ -# endif -#endif /* TIOCGLTC */ - - -#if !defined(SYS5) && !defined(BSD44) -int _putchar(); -#endif /* not SYS5 */ - -#ifdef SIGTSTP -char *tgoto(); -#endif /* SIGTSTP */ - - /* SIGNALS */ -static RETSIGTYPE ALRMser(int); -static RETSIGTYPE PIPEser(int); -static RETSIGTYPE SIGser(int); -#ifdef SIGTSTP -static RETSIGTYPE TSTPser(int); -#endif /* SIGTSTP */ - - - /* MISCELLANY */ - -/* - * static prototypes - */ -static void adorn (char *, char *, ...); - -static vmh(), lreset(), linsert(), ladvance(), lretreat(), lgo(); -static TTYon(), TTYoff(), foreground(); -static int PEERinit(), pINI(), pLOOP(), pTTY(), pWIN(), WINinit(); -static int WINgetstr(), WINless(), WINputc(), TTYinit(), pWINaux(); - - -int -main (int argc, char **argv) -{ - int vecp = 1, nprog = 0; - char *cp, buffer[BUFSIZ]; - char **argp, **arguments, *vec[MAXARGS]; - -#ifdef LOCALE - setlocale(LC_ALL, ""); -#endif - invo_name = r1bindex (argv[0], '/'); - - /* read user profile/context */ - context_read(); - - arguments = getarguments (invo_name, argc, argv, 1); - argp = arguments; - - while ((cp = *argp++)) - if (*cp == '-') - switch (smatch (++cp, switches)) { - case AMBIGSW: - ambigsw (cp, switches); - done (1); - case UNKWNSW: - vec[vecp++] = --cp; - continue; - - case HELPSW: - snprintf (buffer, sizeof(buffer), "%s [switches for vmhproc]", - invo_name); - print_help (buffer, switches, 1); - done (1); - case VERSIONSW: - print_version(invo_name); - done (1); - - case PRMPTSW: - if (!(myprompt = *argp++) || *myprompt == '-') - adios (NULL, "missing argument to %s", argp[-2]); - continue; - - case PROGSW: - if (!(vmhproc = *argp++) || *vmhproc == '-') - adios (NULL, "missing argument to %s", argp[-2]); - continue; - case NPROGSW: - nprog++; - continue; - } - else - vec[vecp++] = cp; - - if (TTYinit (nprog) == NOTOK || WINinit (nprog) == NOTOK) { - vec[vecp] = NULL; - - vec[0] = r1bindex (vmhproc, '/'); - execvp (vmhproc, vec); - adios (vmhproc, "unable to exec"); - } - TTYoff (); - PEERinit (vecp, vec); - TTYon (); - - vmh (); - - return done (0); -} - - -static void -vmh (void) -{ - char buffer[BUFSIZ]; - - for (;;) { - pLOOP (RC_QRY, NULL); - - wmove (Command, 0, 0); - wprintw (Command, myprompt, invo_name); - wclrtoeol (Command); - wrefresh (Command); - - switch (WINgetstr (Command, buffer)) { - case NOTOK: - break; - - case OK: - done (0); /* NOTREACHED */ - - default: - if (*buffer) - pLOOP (RC_CMD, buffer); - break; - } - } -} - -/* PEERS */ - -static int -PEERinit (int vecp, char *vec[]) -{ - int pfd0[2], pfd1[2]; - char buf1[BUFSIZ], buf2[BUFSIZ]; - - if (pipe (pfd0) == NOTOK || pipe (pfd1) == NOTOK) - adios ("pipe", "unable to"); -#ifdef hpux - switch (PEERpid = fork ()) { - /* - * Calling vfork() and then another routine [like close()] before - * an exec() messes up the stack frame, causing crib death. - * Use fork() instead. - */ -#else /* not hpux */ - switch (PEERpid = vfork ()) { -#endif /* not hpux */ - case NOTOK: - adios ("vfork", "unable to");/* NOTREACHED */ - - case OK: - close (pfd0[0]); - close (pfd1[1]); - - vec[vecp++] = "-vmhread"; - snprintf (buf1, sizeof(buf1), "%d", pfd1[0]); - vec[vecp++] = buf1; - vec[vecp++] = "-vmhwrite"; - snprintf (buf2, sizeof(buf2), "%d", pfd0[1]); - vec[vecp++] = buf2; - vec[vecp] = NULL; - - SIGNAL (SIGINT, SIG_DFL); - SIGNAL (SIGQUIT, SIG_DFL); - - vec[0] = r1bindex (vmhproc, '/'); - execvp (vmhproc, vec); - perror (vmhproc); - _exit (-1); /* NOTREACHED */ - - default: - close (pfd0[1]); - close (pfd1[0]); - - rcinit (pfd0[0], pfd1[1]); - return pINI (); - } -} - - -static int -pINI (void) -{ - int len, buflen; - char *bp, buffer[BUFSIZ]; - struct record rcs; - register struct record *rc = &rcs; - register WINDOW **w; - - initrc (rc); - - /* Get buffer ready to go */ - bp = buffer; - buflen = sizeof(buffer); - - snprintf (bp, buflen, "%d %d", RC_VRSN, numwins); - len = strlen (bp); - bp += len; - buflen -= len; - - for (w = windows; *w; w++) { - snprintf (bp, buflen, " %d", (*w)->_maxy); - len = strlen (bp); - bp += len; - buflen -= len; - } - - switch (str2rc (RC_INI, buffer, rc)) { - case RC_ACK: - return OK; - - case RC_ERR: - if (rc->rc_len) - adios (NULL, "%s", rc->rc_data); - else - adios (NULL, "pINI peer error"); - - case RC_XXX: - adios (NULL, "%s", rc->rc_data); - - default: - adios (NULL, "pINI protocol screw-up"); - } -/* NOTREACHED */ -} - - -static int -pLOOP (char *code, char *str) -{ - int i; - struct record rcs; - register struct record *rc = &rcs; - - initrc (rc); - - str2peer (code, str); - for (;;) - switch (peer2rc (rc)) { - case RC_TTY: - if (pTTY (rc) == NOTOK) - return NOTOK; - break; - - case RC_WIN: - if (sscanf (rc->rc_data, "%d", &i) != 1 - || i <= 0 - || i > numwins) { - fmt2peer (RC_ERR, "no such window \"%s\"", rc->rc_data); - return NOTOK; - } - if (pWIN (windows[i - 1]) == NOTOK) - return NOTOK; - break; - - case RC_EOF: - return OK; - - case RC_ERR: - if (rc->rc_len) - adorn (NULL, "%s", rc->rc_data); - else - adorn (NULL, "pLOOP(%s) peer error", - code == RC_QRY ? "QRY" : "CMD"); - return NOTOK; - - case RC_FIN: - if (rc->rc_len) - adorn (NULL, "%s", rc->rc_data); - rcdone (); - i = pidwait (PEERpid, OK); - PEERpid = NOTOK; - done (i); - - case RC_XXX: - adios (NULL, "%s", rc->rc_data); - - default: - adios (NULL, "pLOOP(%s) protocol screw-up", - code == RC_QRY ? "QRY" : "CMD"); - } -} - - -static int -pTTY (struct record *r) -{ - SIGNAL_HANDLER hstat, istat, qstat, tstat; - struct record rcs; - register struct record *rc = &rcs; - - initrc (rc); - - TTYoff (); - - /* should be changed to block instead of ignore */ - hstat = SIGNAL (SIGHUP, SIG_IGN); - istat = SIGNAL (SIGINT, SIG_IGN); - qstat = SIGNAL (SIGQUIT, SIG_IGN); - tstat = SIGNAL (SIGTERM, SIG_IGN); - - rc2rc (RC_ACK, 0, NULL, rc); - - SIGNAL (SIGHUP, hstat); - SIGNAL (SIGINT, istat); - SIGNAL (SIGQUIT, qstat); - SIGNAL (SIGTERM, tstat); - - TTYon (); - - if (r->rc_len && strcmp (r->rc_data, "FAST") == 0) - goto no_refresh; - -#ifdef SIGTSTP - SIGNAL (SIGTSTP, SIG_IGN); -#endif - -#ifndef TERMINFO - if (SO) - tputs (SO, 0, _putchar); -#else /* TERMINFO */ - putp(enter_standout_mode); -#endif /* TERMINFO */ - fprintf (stdout, "Type any key to continue... "); - fflush (stdout); -#ifndef TERMINFO - if (SE) - tputs (SE, 0, _putchar); -#else /* TERMINFO */ - putp(exit_standout_mode); -#endif /* TERMINFO */ - getc (stdin); -#ifdef SIGTSTP - SIGNAL (SIGTSTP, TSTPser); -#endif /* SIGTSTP */ - - wrefresh (curscr); - -no_refresh: ; - switch (rc->rc_type) { - case RC_EOF: - rc2peer (RC_ACK, 0, NULL); - return OK; - - case RC_ERR: - if (rc->rc_len) - adorn (NULL, "%s", rc->rc_data); - else - adorn (NULL, "pTTY peer error"); - return NOTOK; - - case RC_XXX: - adios (NULL, "%s", rc->rc_data); - - default: - adios (NULL, "pTTY protocol screw-up"); - } -/* NOTREACHED */ -} - - -static int -pWIN (WINDOW *w) -{ - int i; - - did_less = 0; - if ((i = pWINaux (w)) == OK && did_less) - WINless (w, 1); - - lreset (); - - return i; -} - - -static int -pWINaux (WINDOW *w) -{ - register int n; - int eol; - register char c, *bp; - struct record rcs; - register struct record *rc = &rcs; - - initrc (rc); - - werase (w); - wmove (w, 0, 0); -#ifdef XYZ - if (w == Status) - wstandout (w); -#endif /* XYZ */ - - for (eol = 0;;) - switch (rc2rc (RC_ACK, 0, NULL, rc)) { - case RC_DATA: - if (eol && WINputc (w, '\n') == ERR && WINless (w, 0)) - goto flush; - for (bp = rc->rc_data, n = rc->rc_len; n-- > 0; ) { - if ((c = *bp++) == '\n') - linsert (w); - if (WINputc (w, c) == ERR) - if (n == 0 && c == '\n') - eol++; - else - if (WINless (w, 0)) { -flush: ; - fmt2peer (RC_ERR, "flush window"); -#ifdef XYZ /* should NEVER happen... */ - if (w == Status) - wstandend (w); -#endif /* XYZ */ - wrefresh (w); - return NOTOK; - } - } - break; - - case RC_EOF: - rc2peer (RC_ACK, 0, NULL); -#ifdef XYZ - if (w == Status) - wstandend (w); -#endif /* XYZ */ - wrefresh (w); - return OK; - - case RC_ERR: - if (rc->rc_len) - adorn (NULL, "%s", rc->rc_data); - else - adorn (NULL, "pWIN peer error"); - return NOTOK; - - case RC_XXX: - adios (NULL, "%s", rc->rc_data); - - default: - adios (NULL, "pWIN protocol screw-up"); - } -/* NOTREACHED */ -} - - -static int -pFIN (void) -{ - int status; - - if (PEERpid <= OK) - return OK; - - rc2peer (RC_FIN, 0, NULL); - rcdone (); - - switch (setjmp (PEERctx)) { - case OK: - SIGNAL (SIGALRM, ALRMser); - alarm (ALARM); - - status = pidwait (PEERpid, OK); - - alarm (0); - break; - - default: - kill (PEERpid, SIGKILL); - status = NOTOK; - break; - } - PEERpid = NOTOK; - - return status; -} - -/* WINDOWS */ - -static int -WINinit (int nprog) -{ - register int nlines, /* not "lines" because terminfo uses that */ - top, - bottom; - - foreground (); - if (initscr () == (WINDOW *) ERR) - if (nprog) - return NOTOK; - else - adios (NULL, "could not initialize terminal"); -#ifdef SIGTSTP - SIGNAL (SIGTSTP, SIG_DFL); -#endif /* SIGTSTP */ - sideground (); - -#ifndef TERMINFO - if (CM == NULL) -#else /* TERMINFO */ - if (cursor_address == NULL) /* assume mtr wanted "cm", not "CM" */ -#endif /* TERMINFO */ - if (nprog) - return NOTOK; - else - adios (NULL, - "sorry, your terminal isn't powerful enough to run %s", - invo_name); - -#ifndef TERMINFO - if (tgetflag ("xt") || tgetnum ("sg") > 0) - SO = SE = US = UE = NULL; -#else /* TERMINFO */ -/* - * If termcap mapped directly to terminfo, we'd use the following: - * if (teleray_glitch || magic_cookie_glitch > 0) - * enter_standout_mode = exit_standout_mode = - * enter_underline_mode = exit_underline_mode = NULL; - * But terminfo does the right thing so we don't have to resort to that. - */ -#endif /* TERMINFO */ - - if ((nlines = LINES - 1) < 11) - adios (NULL, "screen too small"); - if ((top = nlines / 3 + 1) > LINES / 4 + 2) - top--; - bottom = nlines - top - 2; - - numwins = 0; - Scan = windows[numwins++] = newwin (top, COLS, 0, 0); - Status = windows[numwins++] = newwin (1, COLS, top, 0); -#ifndef XYZ - wstandout (Status); -#endif /* XYZ */ - Display = windows[numwins++] = newwin (bottom, COLS, top + 1, 0); - Command = newwin (1, COLS - 1, top + 1 + bottom, 0); - windows[numwins] = NULL; - - largemove = Display->_maxy / 2 + 2; - return OK; -} - - -static int WINgetstr (WINDOW *w, char *buffer) -{ - register int c; - register char *bp; - - bp = buffer; - *bp = 0; - - for (;;) { - switch (c = toascii (wgetch (w))) { - case ERR: - adios (NULL, "wgetch lost"); - - case '\f': - wrefresh (curscr); - break; - - case '\r': - case '\n': - *bp = 0; - if (bp > buffer) { - leaveok (curscr, FALSE); - wmove (w, 0, w->_curx - (bp - buffer)); - wrefresh (w); - leaveok (curscr, TRUE); - } - return DONE; - - default: - if (c == intrc) { - wprintw (w, " "); - wstandout (w); - wprintw (w, "Interrupt"); - wstandend (w); - wrefresh (w); - *buffer = 0; - return NOTOK; - } - if (c == EOFC) { - if (bp <= buffer) - return OK; - break; - } - if (c == ERASE) { - if (bp <= buffer) - continue; - bp--, w->_curx--; - wclrtoeol (w); - break; - } - if (c == KILL) { - if (bp <= buffer) - continue; - w->_curx -= bp - buffer; - bp = buffer; - wclrtoeol (w); - break; - } - if (c == WERASC) { - if (bp <= buffer) - continue; - do { - bp--, w->_curx--; - } while (isspace (*bp) && bp > buffer); - - if (bp > buffer) { - do { - bp--, w->_curx--; - } while (!isspace (*bp) && bp > buffer); - if (isspace (*bp)) - bp++, w->_curx++; - } - wclrtoeol (w); - break; - } - - if (c >= ' ' && c < '\177') - waddch (w, *bp++ = c); - break; - } - - wrefresh (w); - } -} - - -static int -WINwritev (WINDOW *w, struct iovec *iov, int n) -{ - register int i; - - werase (w); - wmove (w, 0, 0); - for (i = 0; i < n; i++, iov++) - wprintw (w, "%*.*s", iov->iov_len, iov->iov_len, iov->iov_base); - wrefresh (w); - - sleep (PAUSE); - - return OK; -} - - -static struct { - char *h_msg; - int *h_val; -} hlpmsg[] = { - " forward backwards", NULL, - " ------- ---------", NULL, - "next screen SPACE", NULL, - "next %d line%s RETURN y", &smallmove, - "next %d line%s EOT u", &largemove, - "go g G", NULL, - "", NULL, - "refresh CTRL-L", NULL, - "quit q", NULL, - - NULL, NULL -}; - - -static int -WINless (WINDOW *w, int fin) -{ - register int c, i, n; - char *cp; - register struct line *lbottom; - int nfresh, nwait; - -#ifdef notdef - int nlatch; -#endif - - did_less++; - - cp = NULL; -#ifdef notdef - if (fin) - ltop = NULL; -#endif /* notdef */ - lbottom = NULL; - nfresh = 1; - nwait = 0; - wrefresh (w); - - for (;;) { - if (nfresh || nwait) { - nfresh = 0; -#ifdef notdef - nlatch = 1; - -once_only: ; -#endif /* notdef */ - werase (w); - wmove (w, 0, 0); - - if (ltop == NULL) - if (fin) { - lgo (ltail->l_no - w->_maxy + 1); - if (ltop == NULL) - ltop = lhead; - } - else - ltop = lbottom && lbottom->l_prev ? lbottom->l_prev - : lbottom; - - for (lbottom = ltop; lbottom; lbottom = lbottom->l_next) - if (waddstr (w, lbottom->l_buf) == ERR - || waddch (w, '\n') == ERR) - break; - if (lbottom == NULL) - if (fin) { -#ifdef notdef - if (nlatch && (ltail->l_no >= w->_maxy)) { - lgo (ltail->l_no - w->_maxy + 1); - nlatch = 0; - goto once_only; - } -#endif /* notdef */ - lbottom = ltail; - while (waddstr (w, "~\n") != ERR) - continue; - } - else { - wrefresh (w); - return 0; - } - - if (!nwait) - wrefresh (w); - } - - wmove (Command, 0, 0); - if (cp) { - wstandout (Command); - wprintw (Command, "%s", cp); - wstandend (Command); - cp = NULL; - } - else - wprintw (Command, fin ? "top:%d bot:%d end:%d" : "top:%d bot:%d", - ltop->l_no, lbottom->l_no, ltail->l_no); - wprintw (Command, ">> "); - wclrtoeol (Command); - wrefresh (Command); - - c = toascii (wgetch (Command)); - - werase (Command); - wrefresh (Command); - - if (nwait) { - nwait = 0; - wrefresh (w); - } - - n = 0; -again: ; - switch (c) { - case ' ': - ltop = lbottom->l_next; - nfresh++; - break; - - case '\r': - case '\n': - case 'e': - case 'j': - if (n) - smallmove = n; - if (ladvance (smallmove)) - nfresh++; - break; - - case 'y': - case 'k': - if (n) - smallmove = n; - if (lretreat (smallmove)) - nfresh++; - break; - - case 'd': - eof: ; - if (n) - largemove = n; - if (ladvance (largemove)) - nfresh++; - break; - - case 'u': - if (n) - largemove = n; - if (lretreat (largemove)) - nfresh++; - break; - - case 'g': - if (lgo (n ? n : 1)) - nfresh++; - break; - - case 'G': - if (lgo (n ? n : ltail->l_no - w->_maxy + 1)) - nfresh++; - break; - - case '\f': - case 'r': - wrefresh (curscr); - break; - - case 'h': - case '?': - werase (w); - wmove (w, 0, 0); - for (i = 0; hlpmsg[i].h_msg; i++) { - if (hlpmsg[i].h_val) - wprintw (w, hlpmsg[i].h_msg, *hlpmsg[i].h_val, - *hlpmsg[i].h_val != 1 ? "s" : ""); - else - waddstr (w, hlpmsg[i].h_msg); - waddch (w, '\n'); - } - wrefresh (w); - nwait++; - break; - - case 'q': - return 1; - - default: - if (c == EOFC) - goto eof; - - if (isdigit (c)) { - wmove (Command, 0, 0); - i = 0; - while (isdigit (c)) { - wprintw (Command, "%c", c); - wrefresh (Command); - i = i * 10 + c - '0'; - c = toascii (wgetch (Command)); - } - werase (Command); - wrefresh (Command); - - if (i > 0) { - n = i; - goto again; - } - cp = "bad number"; - } - else - cp = "not understood"; - break; - } - } -} - - -static int -WINputc (WINDOW *w, char c) -{ - register int x, y; - - switch (c) { - default: - if (!isascii (c)) { - if (WINputc (w, 'M') == ERR || WINputc (w, '-') == ERR) - return ERR; - c = toascii (c); - } - else - if (c < ' ' || c == '\177') { - if (WINputc (w, '^') == ERR) - return ERR; - c ^= 0100; - } - break; - - case '\t': - case '\n': - break; - } - - if (w != Scan) - return waddch (w, c); - - if ((x = w->_curx) < 0 || x >= w->_maxx - || (y = w->_cury) < 0 || y >= w->_maxy) - return DONE; - - switch (c) { - case '\t': - for (x = 8 - (x & 0x07); x > 0; x--) - if (WINputc (w, ' ') == ERR) - return ERR; - break; - - case '\n': - if (++y < w->_maxy) - waddch (w, c); - else - wclrtoeol (w); - break; - - default: - if (++x < w->_maxx) - waddch (w, c); - break; - } - - return DONE; -} - -/* LINES */ - -static void -lreset (void) -{ - register struct line *lp, *mp; - - for (lp = lhead; lp; lp = mp) { - mp = lp->l_next; - free (lp->l_buf); - free ((char *) lp); - } - lhead = ltop = ltail = NULL; -} - - -static void -linsert (WINDOW *w) -{ - register char *cp; - register struct line *lp; - - if ((lp = (struct line *) calloc ((size_t) 1, sizeof *lp)) == NULL) - adios (NULL, "unable to allocate line storage"); - - lp->l_no = (ltail ? ltail->l_no : 0) + 1; -#ifndef BSD44 - lp->l_buf = getcpy (w->_y[w->_cury]); -#else - lp->l_buf = getcpy (w->lines[w->_cury]->line); -#endif - for (cp = lp->l_buf + strlen (lp->l_buf) - 1; cp >= lp->l_buf; cp--) - if (isspace (*cp)) - *cp = 0; - else - break; - - if (lhead == NULL) - lhead = lp; - if (ltop == NULL) - ltop = lp; - if (ltail) - ltail->l_next = lp; - lp->l_prev = ltail; - ltail = lp; -} - - -static int -ladvance (int n) -{ - register int i; - register struct line *lp; - - for (i = 0, lp = ltop; i < n && lp; i++, lp = lp->l_next) - continue; - - if (ltop == lp) - return 0; - - ltop = lp; - return 1; -} - - -static int -lretreat (int n) -{ - register int i; - register struct line *lp; - - for (i = 0, lp = ltop; i < n && lp; i++, lp = lp->l_prev) - if (!lp->l_prev) - break; - - if (ltop == lp) - return 0; - - ltop = lp; - return 1; -} - - -static int -lgo (int n) -{ - register int i, j; - register struct line *lp; - - if ((i = n - (lp = lhead)->l_no) - > (j = abs (n - (ltop ? ltop : ltail)->l_no))) - i = j, lp = ltop ? ltop : ltail; - if (i > (j = abs (ltail->l_no - n))) - i = j, lp = ltail; - - if (n >= lp->l_no) { - for (; lp; lp = lp->l_next) - if (lp->l_no == n) - break; - } - else { - for (; lp; lp = lp->l_prev) - if (lp->l_no == n) - break; - if (!lp) - lp = lhead; - } - - if (ltop == lp) - return 0; - - ltop = lp; - return 1; -} - -/* TTYS */ - -static int -TTYinit (int nprog) -{ - if (!isatty (fileno (stdin)) || !isatty (fileno (stdout))) - if (nprog) - return NOTOK; - else - adios (NULL, "not a tty"); - - foreground (); -#ifndef SYS5 - if (ioctl (fileno (stdin), TIOCGETP, (char *) &sg) == NOTOK) - adios ("failed", "ioctl TIOCGETP"); - if (ioctl (fileno (stdin), TIOCGETC, (char *) &tc) == NOTOK) - adios ("failed", "ioctl TIOCGETC"); -#else -#ifdef TCGETATTR - if( tcgetattr( fileno(stdin), &sg) == NOTOK) - adios( "failed", "tcgetattr"); -#else /* SYS5 */ - if (ioctl (fileno (stdin), TCGETA, &sg) == NOTOK) - adios ("failed", "ioctl TCGETA"); -#endif -#endif -#ifdef TIOCGLTC - if (ioctl (fileno (stdin), TIOCGLTC, (char *) <c) == NOTOK) - adios ("failed", "ioctl TIOCGLTC"); -#endif /* TIOCGLTC */ - intrc = INTR; - sideground (); - - tty_ready = OK; - - SIGNAL (SIGPIPE, PIPEser); - - return OK; -} - - -static void -TTYon (void) -{ - if (tty_ready == DONE) - return; - - INTR = NOTOK; -#ifndef SYS5 - ioctl (fileno (stdin), TIOCSETC, (char *) &tc); -#else /* SYS5 */ - ioctl (fileno (stdin), TCSETA, &sg); -#endif /* SYS5 */ - - crmode (); - noecho (); - nonl (); - scrollok (curscr, FALSE); - - discard (stdin); - - tty_ready = DONE; - - SIGNAL (SIGHUP, SIGser); - SIGNAL (SIGINT, SIGser); - SIGNAL (SIGQUIT, SIGser); -#ifdef SIGTSTP - SIGNAL (SIGTSTP, TSTPser); -#endif /* SIGTSTP */ -} - - -static void -TTYoff (void) -{ - if (tty_ready == NOTOK) - return; - - INTR = intrc; -#ifndef SYS5 - ioctl (fileno (stdin), TIOCSETC, (char *) &tc); -#else /* SYS5 */ - ioctl (fileno (stdin), TCSETA, &sg); -#endif /* SYS5 */ - - leaveok (curscr, TRUE); - mvcur (0, COLS - 1, LINES - 1, 0); - endwin (); - if (tty_ready == DONE) { -#ifndef TERMINFO - if (CE) - tputs (CE, 0, _putchar); - else -#else /* TERMINFO */ - putp(clr_eol); -#endif /* TERMINFO */ - fprintf (stdout, "\r\n"); - } - fflush (stdout); - - tty_ready = NOTOK; - - SIGNAL (SIGHUP, SIG_DFL); - SIGNAL (SIGINT, SIG_DFL); - SIGNAL (SIGQUIT, SIG_DFL); -#ifdef SIGTSTP - SIGNAL (SIGTSTP, SIG_DFL); -#endif /* SIGTSTP */ -} - - -static void -foreground (void) -{ -#ifdef TIOCGPGRP - int pgrp, tpgrp; - SIGNAL_HANDLER tstat; - - if ((pgrp = getpgrp()) == NOTOK) - adios ("process group", "unable to determine"); - for (;;) { - if (ioctl (fileno (stdin), TIOCGPGRP, (char *) &tpgrp) == NOTOK) - adios ("tty's process group", "unable to determine"); - if (pgrp == tpgrp) - break; - - tstat = SIGNAL (SIGTTIN, SIG_DFL); - kill (0, SIGTTIN); - SIGNAL (SIGTTIN, tstat); - } - - SIGNAL (SIGTTIN, SIG_IGN); - SIGNAL (SIGTTOU, SIG_IGN); - SIGNAL (SIGTSTP, SIG_IGN); -#endif /* TIOCGPGRP */ -} - - -void -sideground (void) -{ -#ifdef TIOCGPGRP - SIGNAL (SIGTTIN, SIG_DFL); - SIGNAL (SIGTTOU, SIG_DFL); - SIGNAL (SIGTSTP, SIG_DFL); -#endif /* TIOCGPGRP */ -} - -/* SIGNALS */ - - -static RETSIGTYPE -ALRMser (int sig) -{ - longjmp (PEERctx, DONE); -} - - -#ifdef BSD42 -/* ARGSUSED */ -#endif /* BSD42 */ - -static RETSIGTYPE -PIPEser (int sig) -{ -#ifndef RELIABLE_SIGNALS - SIGNAL (sig, SIG_IGN); -#endif - - adios (NULL, "lost peer"); -} - - -static RETSIGTYPE -SIGser (int sig) -{ -#ifndef RELIABLE_SIGNALS - SIGNAL (sig, SIG_IGN); -#endif - - done (1); -} - - -#ifdef SIGTSTP -static RETSIGTYPE -TSTPser (int sig) -{ -#ifndef TERMINFO - tputs (tgoto (CM, 0, LINES - 1), 0, _putchar); -#else /* TERMINFO */ - move(LINES - 1, 0); /* to lower left corner */ - clrtoeol(); /* clear bottom line */ - wrefresh(curscr); /* flush out everything */ -#endif /* TERMINFO */ - fflush (stdout); - - TTYoff (); -#ifdef BSD42 - sigsetmask (sigblock (0) & ~sigmask (SIGTSTP)); -#endif /* BSD42 */ - - kill (getpid (), sig); - -#ifdef BSD42 - sigblock (sigmask (SIGTSTP)); -#endif /* BSD42 */ - TTYon (); - - wrefresh (curscr); -} -#endif /* SIGTSTP */ - - -/* MISCELLANY */ - -int -done (int status) -{ - TTYoff (); - pFIN (); - - exit (status); - return 1; /* dead code to satisfy the compiler */ -} - - -static void -adorn (char *what, char *fmt, ...) -{ - va_list ap; - char *cp; - - cp = invo_name; - invo_name = NULL; - - va_start(ap, fmt); - advertise (what, NULL, fmt, ap); - va_end(ap); - - invo_name = cp; -} - - -void -advertise (char *what, char *tail, char *fmt, va_list ap) -{ - int eindex = errno; - char buffer[BUFSIZ], err[BUFSIZ]; - struct iovec iob[20]; - register struct iovec *iov = iob; - - fflush (stdout); - fflush (stderr); - - if (invo_name) { - iov->iov_len = strlen (iov->iov_base = invo_name); - iov++; - iov->iov_len = strlen (iov->iov_base = ": "); - iov++; - } - - vsnprintf (buffer, sizeof(buffer), fmt, ap); - iov->iov_len = strlen (iov->iov_base = buffer); - iov++; - if (what) { - if (*what) { - iov->iov_len = strlen (iov->iov_base = " "); - iov++; - iov->iov_len = strlen (iov->iov_base = what); - iov++; - iov->iov_len = strlen (iov->iov_base = ": "); - iov++; - } - if (!(iov->iov_base = strerror (eindex))) { - snprintf (err, sizeof(err), "Error %d", eindex); - iov->iov_base = err; - } - iov->iov_len = strlen (iov->iov_base); - iov++; - } - if (tail && *tail) { - iov->iov_len = strlen (iov->iov_base = ", "); - iov++; - iov->iov_len = strlen (iov->iov_base = tail); - iov++; - } - iov->iov_len = strlen (iov->iov_base = "\n"); - iov++; - - if (tty_ready == DONE) - WINwritev (Display, iob, iov - iob); - else - writev (fileno (stderr), iob, iov - iob); -} - diff --git a/uip/vmhsbr.c b/uip/vmhsbr.c deleted file mode 100644 index eb6e037..0000000 --- a/uip/vmhsbr.c +++ /dev/null @@ -1,227 +0,0 @@ - -/* - * vmhsbr.c -- routines to help vmh along - * - * 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. - */ - -/* - * TODO (for vrsn 2): - * INI: include width of windows - */ - -#include -#include -#include -#include - -static char *types[] = { - "OK", - "INI", "ACK", "ERR", "CMD", "QRY", "TTY", "WIN", "DATA", "EOF", "FIN", - "XXX", NULL -}; - -static FILE *fp = NULL; - -static int PEERrfd = NOTOK; -static int PEERwfd = NOTOK; - -/* - * static prototypes - */ -static int rclose (struct record *, char *, ...); - - -int -rcinit (int rfd, int wfd) -{ - char *cp, buffer[BUFSIZ]; - - PEERrfd = rfd; - PEERwfd = wfd; - - if ((cp = getenv ("MHVDEBUG")) && *cp) { - snprintf (buffer, sizeof(buffer), "%s.out", invo_name); - if ((fp = fopen (buffer, "w"))) { - fseek (fp, 0L, SEEK_END); - fprintf (fp, "%d: rcinit (%d, %d)\n", (int) getpid(), rfd, wfd); - fflush (fp); - } - } - - return OK; -} - - -int -rcdone (void) -{ - if (PEERrfd != NOTOK) - close (PEERrfd); - if (PEERwfd != NOTOK) - close (PEERwfd); - - if (fp) { - fclose (fp); - fp = NULL; - } - return OK; -} - - -int -rc2rc (char code, int len, char *data, struct record *rc) -{ - if (rc2peer (code, len, data) == NOTOK) - return NOTOK; - - return peer2rc (rc); -} - - -int -str2rc (char code, char *str, struct record *rc) -{ - return rc2rc (code, str ? strlen (str) : 0, str, rc); -} - - -int -peer2rc (struct record *rc) -{ - if (rc->rc_data) - free (rc->rc_data); - - if (read (PEERrfd, (char *) rc_head (rc), RHSIZE (rc)) != RHSIZE (rc)) - return rclose (rc, "read from peer lost(1)"); - if (rc->rc_len) { - rc->rc_data = mh_xmalloc ((unsigned) rc->rc_len + 1); - if (read (PEERrfd, rc->rc_data, rc->rc_len) != rc->rc_len) - return rclose (rc, "read from peer lost(2)"); - rc->rc_data[rc->rc_len] = 0; - } - else - rc->rc_data = NULL; - - if (fp) { - fseek (fp, 0L, SEEK_END); - fprintf (fp, "%d: <--- %s %d: \"%*.*s\"\n", (int) getpid(), - types[(unsigned char)rc->rc_type], rc->rc_len, - rc->rc_len, rc->rc_len, rc->rc_data); - fflush (fp); - } - - return rc->rc_type; -} - - -int -rc2peer (char code, int len, char *data) -{ - struct record rcs; - register struct record *rc = &rcs; - - rc->rc_type = code; - rc->rc_len = len; - - if (fp) { - fseek (fp, 0L, SEEK_END); - fprintf (fp, "%d: ---> %s %d: \"%*.*s\"\n", (int) getpid(), - types[(unsigned char)rc->rc_type], rc->rc_len, - rc->rc_len, rc->rc_len, data); - fflush (fp); - } - - if (write (PEERwfd, (char *) rc_head (rc), RHSIZE (rc)) != RHSIZE (rc)) - return rclose (rc, "write to peer lost(1)"); - - if (rc->rc_len) - if (write (PEERwfd, data, rc->rc_len) != rc->rc_len) - return rclose (rc, "write to peer lost(2)"); - - return OK; -} - - -int -str2peer (char code, char *str) -{ - return rc2peer (code, str ? strlen (str) : 0, str); -} - - -int -fmt2peer (char code, char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - return verr2peer (code, NULL, fmt, ap); - va_end(ap); -} - - -int -err2peer (char code, char *what, char *fmt, ...) -{ - int return_value; - va_list ap; - - va_start(ap, fmt); - return_value = verr2peer(code, what, fmt, ap); - va_end(ap); - return return_value; /* This routine returned garbage before 1999-07-15. */ -} - - -int -verr2peer (char code, char *what, char *fmt, va_list ap) -{ - int eindex = errno; - int len, buflen; - char *bp, *s, buffer[BUFSIZ * 2]; - - /* Get buffer ready to go */ - bp = buffer; - buflen = sizeof(buffer); - - vsnprintf (bp, buflen, fmt, ap); - len = strlen (bp); - bp += len; - buflen -= len; - - if (what) { - if (*what) { - snprintf (bp, buflen, " %s: ", what); - len = strlen (bp); - bp += len; - buflen -= len; - } - if ((s = strerror (eindex))) - strncpy (bp, s, buflen); - else - snprintf (bp, buflen, "unknown error %d", eindex); - len = strlen (bp); - bp += len; - buflen -= len; - } - - return rc2peer (code, bp - buffer, buffer); -} - - -static int -rclose (struct record *rc, char *fmt, ...) -{ - va_list ap; - static char buffer[BUFSIZ * 2]; - - va_start(ap, fmt); - vsnprintf (buffer, sizeof(buffer), fmt, ap); - va_end(ap); - - rc->rc_len = strlen (rc->rc_data = getcpy (buffer)); - return (rc->rc_type = RC_XXX); -} diff --git a/uip/vmhtest.c b/uip/vmhtest.c deleted file mode 100644 index 572bad5..0000000 --- a/uip/vmhtest.c +++ /dev/null @@ -1,324 +0,0 @@ - -/* - * vmhtest.c -- test out vmh protocol - * - * 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 -#include - -static struct swit switches[] = { -#define READSW 0 - { "vmhread fd", 7 }, -#define WRITESW 1 - { "vmhwrite fd", 8 }, -#define VERSIONSW 2 - { "version", 0 }, -#define HELPSW 3 - { "help", 0 }, - { NULL, NULL } -}; - -#define NWIN 20 -static int numwins = 0; -static int windows[NWIN + 1]; - - -static int selcmds = 0; -#define selcmd() (selcmds++ % 2) - -static int selwins = 0; -#define selwin() (selwins++ % 2 ? 3 : 1) - - -int -main (int argc, char **argv) -{ - int fd1, fd2; - char *cp, buffer[BUFSIZ]; - char **argp, **arguments; - -#ifdef LOCALE - setlocale(LC_ALL, ""); -#endif - invo_name = r1bindex (argv[0], '/'); - - /* foil search of user profile/context */ - if (context_foil (NULL) == -1) - done (1); - - arguments = getarguments (invo_name, argc, argv, 0); - argp = arguments; - - while ((cp = *argp++)) - if (*cp == '-') - switch (smatch (++cp, switches)) { - case AMBIGSW: - ambigsw (cp, switches); - done (1); - case UNKWNSW: - adios (NULL, "-%s unknown", cp); - - case HELPSW: - snprintf (buffer, sizeof(buffer), "%s [switches]", invo_name); - print_help (buffer, switches, 0); - done (1); - case VERSIONSW: - print_version(invo_name); - done (1); - - case READSW: - if (!(cp = *argp++) || *cp == '-') - adios (NULL, "missing argument to %s", argp[-2]); - if ((fd1 = atoi (cp)) < 1) - adios (NULL, "bad argument %s %s", argp[-2], cp); - continue; - case WRITESW: - if (!(cp = *argp++) || *cp == '-') - adios (NULL, "missing argument to %s", argp[-2]); - if ((fd2 = atoi (cp)) < 1) - adios (NULL, "bad argument %s %s", argp[-2], cp); - continue; - } - else - adios (NULL, "usage: %s [switches]", invo_name); - - rcinit (fd1, fd2); - pINI (); - pLOOP (); - - return done (0); -} - - -static int pINI () { - int i, - vrsn; - char *bp; - struct record rcs, - *rc = &rcs; - - initrc (rc); - - switch (peer2rc (rc)) { - case RC_INI: - bp = rc->rc_data; - while (isspace (*bp)) - bp++; - if (sscanf (bp, "%d", &vrsn) != 1) { - bad_init: ; - fmt2peer (RC_ERR, "bad init \"%s\"", rc->rc_data); - done (1); - } - if (vrsn != RC_VRSN) { - fmt2peer (RC_ERR, "version %d unsupported", vrsn); - done (1); - } - - while (*bp && !isspace (*bp)) - bp++; - while (isspace (*bp)) - bp++; - if (sscanf (bp, "%d", &numwins) != 1 || numwins <= 0) - goto bad_init; - if (numwins > NWIN) - numwins = NWIN; - - for (i = 1; i <= numwins; i++) { - while (*bp && !isspace (*bp)) - bp++; - while (isspace (*bp)) - bp++; - if (sscanf (bp, "%d", &windows[i]) != 1 || windows[i] <= 0) - goto bad_init; - } - rc2peer (RC_ACK, 0, NULL); - return OK; - - case RC_XXX: - adios (NULL, "%s", rc->rc_data); - - default: - fmt2peer (RC_ERR, "pINI protocol screw-up"); - done (1); /* NOTREACHED */ - } -} - - -static int pLOOP () { - struct record rcs, - *rc = &rcs; - - initrc (rc); - - for (;;) - switch (peer2rc (rc)) { - case RC_QRY: - pQRY (rc->rc_data); - break; - - case RC_CMD: - pCMD (rc->rc_data); - break; - - case RC_FIN: - done (0); - - case RC_XXX: - adios (NULL, "%s", rc->rc_data); - - default: - fmt2peer (RC_ERR, "pLOOP protocol screw-up"); - done (1); - } -} - - -static int pQRY (str) -char *str; -{ - rc2peer (RC_EOF, 0, NULL); - return OK; -} - - -static int pCMD (str) -char *str; -{ - if ((selcmd () ? pTTY (str) : pWIN (str)) == NOTOK) - return NOTOK; - rc2peer (RC_EOF, 0, NULL); - return OK; -} - - -static int pTTY (str) -char *str; -{ - struct record rcs, - *rc = &rcs; - - initrc (rc); - - switch (rc2rc (RC_TTY, 0, NULL, rc)) { - case RC_ACK: - break; - - case RC_ERR: - return NOTOK; - - case RC_XXX: - adios (NULL, "%s", rc->rc_data); - - default: - fmt2peer (RC_ERR, "pTTY protocol screw-up"); - done (1); - } - - system (str); - - switch (rc2rc (RC_EOF, 0, NULL, rc)) { - case RC_ACK: - return OK; - - case RC_XXX: - adios (NULL, "%s", rc->rc_data);/* NOTREACHED */ - - default: - fmt2peer (RC_ERR, "pTTY protocol screw-up"); - done (1); /* NOTREACHED */ - } -} - - -static int pWIN (str) -char *str; -{ - int i, - pid, - pd[2]; - char buffer[BUFSIZ]; - struct record rcs, - *rc = &rcs; - - initrc (rc); - - snprintf (buffer, sizeof(buffer), "%d", selwin ()); - switch (str2rc (RC_WIN, buffer, rc)) { - case RC_ACK: - break; - - case RC_ERR: - return NOTOK; - - case RC_XXX: - adios (NULL, "%s", rc->rc_data); - - default: - fmt2peer (RC_ERR, "pWIN protocol screw-up"); - done (1); - } - - if (pipe (pd) == NOTOK) { - fmt2peer (RC_ERR, "no pipes"); - return NOTOK; - } - - switch (pid = vfork ()) { - case NOTOK: - fmt2peer (RC_ERR, "no forks"); - return NOTOK; - - case OK: - close (0); - open ("/dev/null", O_RDONLY); - dup2 (pd[1], 1); - dup2 (pd[1], 2); - close (pd[0]); - close (pd[1]); - execlp ("/bin/sh", "sh", "-c", str, NULL); - write (2, "no shell\n", strlen ("no shell\n")); - _exit (1); - - default: - close (pd[1]); - while ((i = read (pd[0], buffer, sizeof buffer)) > 0) - switch (rc2rc (RC_DATA, i, buffer, rc)) { - case RC_ACK: - break; - - case RC_ERR: - close (pd[0]); - pidwait (pid, OK); - return NOTOK; - - case RC_XXX: - adios (NULL, "%s", rc->rc_data); - - default: - fmt2peer (RC_ERR, "pWIN protocol screw-up"); - done (1); - } - if (i == OK) - switch (rc2rc (RC_EOF, 0, NULL, rc)) { - case RC_ACK: - break; - - case RC_XXX: - adios (NULL, "%s", rc->rc_data); - - default: - fmt2peer (RC_ERR, "pWIN protocol screw-up"); - done (1); - } - if (i == NOTOK) - fmt2peer (RC_ERR, "read from pipe lost"); - - close (pd[0]); - pidwait (pid, OK); - return (i != NOTOK ? OK : NOTOK); - } -} -- 1.7.10.4