]>
diplodocus.org Git - nmh/blob - docs/historical/mh-6.8.5/uip/msh.c
1 /* msh.c - The MH shell (sigh) */
3 static char ident
[] = "@(#)$Id: msh.c,v 2.14 1995/12/06 21:04:11 jromine Exp $";
7 Keep more status information in maildrop map
11 #include "../h/dropsbr.h"
12 #include "../h/formatsbr.h"
13 #include "../h/scansbr.h"
14 #include "../zotnet/tws.h"
16 #include "../zotnet/mts.h"
18 #include <sys/types.h>
25 #include <sys/ioctl.h>
31 #include "../h/mshsbr.h"
32 #include "../h/vmhsbr.h"
38 #define MIMEminc(a) (a)
43 #define QUOTE '\\' /* sigh */
48 static struct swit switches
[] = {
50 "idstart number", -7, /* interface from bbc */
52 "idstop number", -6, /* .. */
54 "idquit number", -6, /* .. */
56 "idname BBoard", -6, /* .. */
89 char *fmsh
= NULL
; /* folder instead of file */
90 int modified
; /* command modified folder */
91 struct msgs
*mp
; /* used a lot */
93 struct Msg
*Msgs
= NULL
; /* Msgs[0] not used */
94 static FILE *fp
; /* input file */
95 static FILE *yp
= NULL
; /* temporary file */
96 static int mode
; /* mode of file */
97 static int numfds
= 0; /* number of files cached */
98 static int maxfds
= 0; /* number of files cached to be cached */
99 static time_t mtime
= (time_t) 0;/* mtime of file */
103 #define ALARM ((unsigned int) 10)
104 #define ttyN(c) ttyNaux ((c), NULLCP)
108 static int vmhpid
= OK
;
113 static int vmhtty
= NOTOK
;
120 static int topcur
= 0;
122 static int numwins
= 0;
123 static int windows
[NWIN
+ 1];
125 static jmp_buf peerenv
;
127 void padios (), padvise ();
128 static TYPESIG
alrmser ();
134 int pmsh
= 0; /* BPOP enabled */
136 extern char response
[];
141 static int pfd
= NOTOK
; /* fd parent is reading from */
142 static int ppid
= 0; /* pid of parent */
146 int interactive
; /* running from a /dev/tty */
147 int redirected
; /* re-directing output */
148 FILE *sp
= NULL
; /* original stdout */
150 char *cmd_name
; /* command being run */
152 char myfilter
[BUFSIZ
]; /* path to mhl.forward */
154 static char *myprompt
= "(%s) ";/* prompting string */
158 static int gap
; /* gap in BBoard-ID:s */
160 static char *myname
= NULL
; /* BBoard name */
162 char *BBoard_ID
= "BBoard-ID";/* BBoard-ID constant */
165 TYPESIG (*istat
) (); /* original SIGINT */
166 static TYPESIG (*pstat
) (); /* current SIGPIPE */
167 TYPESIG (*qstat
) (); /* original SIGQUIT */
169 static TYPESIG (*tstat
) (); /* original SIGTSTP */
171 int interrupted
; /* SIGINT detected */
172 int broken_pipe
; /* SIGPIPE detected */
173 int told_to_quit
; /* SIGQUIT detected */
176 int should_intr
; /* signal handler should interrupt call */
177 jmp_buf sigenv
; /* the environment pointer */
180 static TYPESIG
intrser (), pipeser (), quitser ();
185 struct passwd
*getpwnam ();
189 static int read_map(), read_file(), check_folder(), getargs(), parse();
190 static int getcmds(), init_io(), initaux_io(), finaux_io(), peerwait();
191 static int pINI(), pQRY(), pQRY1(), pQRY2(), pCMD(), pFIN();
192 static int ttyR(), ttyNaux(), winN(), winR(), winX();
193 static msh(), m_gMsgs(), scanrange(), scanstring(), quit();
194 static fin_io(), m_init();
196 static int read_pop();
223 setlocale(LC_ALL
, "");
225 invo_name
= r1bindex (argv
[0], '/');
226 mts_init (invo_name
);
227 if ((cp
= m_find (invo_name
)) != NULL
) {
228 ap
= brkstring (cp
= getcpy (cp
), " ", "\n");
229 ap
= copyip (ap
, arguments
);
233 (void) copyip (argv
+ 1, ap
);
238 while (cp
= *argp
++) {
240 switch (smatch (++cp
, switches
)) {
242 ambigsw (cp
, switches
);
245 adios (NULLCP
, "-%s unknown", cp
);
247 (void) sprintf (buf
, "%s [switches] file", invo_name
);
248 help (buf
, switches
);
252 if (!(cp
= *argp
++) || *cp
== '-')
253 adios (NULLCP
, "missing argument to %s", argp
[-2]);
254 if ((id
= atoi (cp
)) < 1)
255 adios (NULLCP
, "bad argument %s %s", argp
[-2], cp
);
258 if (!(cp
= *argp
++) || *cp
== '-')
259 adios (NULLCP
, "missing argument to %s", argp
[-2]);
260 if ((pfd
= atoi (cp
)) <= 1)
261 adios (NULLCP
, "bad argument %s %s", argp
[-2], cp
);
264 if (!(cp
= *argp
++) || *cp
== '-')
265 adios (NULLCP
, "missing argument to %s", argp
[-2]);
266 if ((ppid
= atoi (cp
)) <= 1)
267 adios (NULLCP
, "bad argument %s %s", argp
[-2], cp
);
270 if (!(myname
= *argp
++) || *myname
== '-')
271 adios (NULLCP
, "missing argument to %s", argp
[-2]);
282 if (!(myprompt
= *argp
++) || *myprompt
== '-')
283 adios (NULLCP
, "missing argument to %s", argp
[-2]);
287 if (!(cp
= *argp
++) || *cp
== '-')
288 adios (NULLCP
, "missing argument to %s", argp
[-2]);
289 if ((vmh1
= atoi (cp
)) < 1)
290 adios (NULLCP
, "bad argument %s %s", argp
[-2], cp
);
293 if (!(cp
= *argp
++) || *cp
== '-')
294 adios (NULLCP
, "missing argument to %s", argp
[-2]);
295 if ((vmh2
= atoi (cp
)) < 1)
296 adios (NULLCP
, "bad argument %s %s", argp
[-2], cp
);
300 if (!(cp
= *argp
++) || *cp
== '-')
301 adios (NULLCP
, "missing argument to %s", argp
[-2]);
303 if ((pmsh1
= atoi (cp
)) < 1)
304 adios (NULLCP
, "bad argument %s %s", argp
[-2], cp
);
308 if (!(cp
= *argp
++) || *cp
== '-')
309 adios (NULLCP
, "missing argument to %s", argp
[-2]);
311 if ((pmsh2
= atoi (cp
)) < 1)
312 adios (NULLCP
, "bad argument %s %s", argp
[-2], cp
);
323 if (*cp
== '+' || *cp
== '@') {
325 adios (NULLCP
, "only one folder at a time!");
327 folder
= path (cp
+ 1, *cp
== '+' ? TFOLDER
: TSUBCWF
);
331 adios (NULLCP
, "only one file at a time!");
338 if (!file
&& !folder
)
341 adios (NULLCP
, "use a file or a folder, not both");
342 (void) strcpy (myfilter
, libpath (mhlforward
));
345 (void) ioctl (pfd
, FIOCLEX
, NULLCP
);
351 setsigx (istat
, SIGINT
, intrser
);
352 setsigx (qstat
, SIGQUIT
, quitser
);
354 (void) sc_width (); /* MAGIC... */
356 if (vmh
= vmh1
&& vmh2
) {
357 (void) rcinit (vmh1
, vmh2
);
359 (void) signal (SIGINT
, SIG_IGN
);
360 (void) signal (SIGQUIT
, SIG_IGN
);
362 tstat
= signal (SIGTSTP
, SIG_IGN
);
367 if (pmsh
= pmsh1
&& pmsh2
) {
368 cp
= getenv ("MHPOPDEBUG");
370 if (pop_set (pmsh1
, pmsh2
, cp
&& *cp
, myname
) == NOTOK
)
372 if (pop_set (pmsh1
, pmsh2
, cp
&& *cp
) == NOTOK
)
374 padios (NULLCP
, "%s", response
);
376 file
= folder
, folder
= NULL
;
385 display_info (id
> 0 ? scansw
: 0);
387 msh (id
> 0 ? scansw
: 0);
396 static struct swit mshcmds
[] = {
468 register struct Cmd
*cmdp
;
469 static int once_only
= ADVCMD
;
471 (void) sprintf (prompt
, myprompt
, invo_name
);
480 if ((i
= getcmds (mshcmds
, cmdp
, scansw
)) == EOF
) {
486 (void) check_folder (scansw
);
487 if ((i
= getargs (prompt
, mshcmds
, cmdp
)) == EOF
) {
488 (void) putchar ('\n');
492 cmd_name
= mshcmds
[i
].sw
;
500 if (once_only
== ADVCMD
)
501 once_only
= i
= SHOWCMD
;
503 i
= mp
-> curmsg
!= mp
-> hghmsg
? NEXTCMD
: EXITCMD
;
504 cmd_name
= mshcmds
[i
].sw
;
510 case FORWCMD
: /* sigh */
520 if ((cp
= m_find (cmd_name
)) != NULL
) {
521 ap
= brkstring (cp
= getcpy (cp
), " ", "\n");
522 ap
= copyip (ap
, vec
);
533 (void) copyip (cmdp
-> args
+ 1, ap
);
537 if (!vmh
&& init_io (cmdp
, vmh
) == NOTOK
) {
543 redirected
= vmh
|| cmdp
-> direction
!= STDIO
;
554 if (!vmh
|| ttyN (cmdp
) != NOTOK
)
555 forkcmd (vec
, cmd_name
);
559 if (!vmh
|| ttyN (cmdp
) != NOTOK
)
564 if (!vmh
|| winN (cmdp
, DISPLAY
, 1) != NOTOK
)
570 || (filehak (vec
) == OK
? ttyN (cmdp
)
571 : winN (cmdp
, DISPLAY
, 1)) != NOTOK
)
576 if (!vmh
|| winN (cmdp
, DISPLAY
, 1) != NOTOK
)
581 if (!vmh
|| ttyN (cmdp
) != NOTOK
)
586 if (!vmh
|| winN (cmdp
, DISPLAY
, 1) != NOTOK
)
592 if (!vmh
|| winN (cmdp
, DISPLAY
, 1) != NOTOK
)
598 if (!vmh
|| ttyN (cmdp
) != NOTOK
)
606 if (!vmh
|| winN (cmdp
, DISPLAY
, 1) != NOTOK
)
612 || (packhak (vec
) == OK
? ttyN (cmdp
)
613 : winN (cmdp
, DISPLAY
, 1)) != NOTOK
)
618 if (!vmh
|| winN (cmdp
, DISPLAY
, 1) != NOTOK
)
623 if (!vmh
|| ttyN (cmdp
) != NOTOK
)
628 if (!vmh
|| winN (cmdp
, DISPLAY
, 1) != NOTOK
)
633 if (!vmh
|| winN (cmdp
, DISPLAY
, 1) != NOTOK
)
638 if (!vmh
|| winN (cmdp
, DISPLAY
, 1) != NOTOK
)
643 padios (NULLCP
, "no dispatch for %s", cmd_name
);
672 maildir
= m_maildir (folder
);
673 if (chdir (maildir
) == NOTOK
)
674 padios (maildir
, "unable to change directory to");
675 if (!(mp
= m_gmsg (folder
)))
676 padios (NULLCP
, "unable to read folder %s", folder
);
677 if (mp
-> hghmsg
== 0)
678 padios (NULLCP
, "no messages in %s", folder
);
681 mtime
= stat (mp
-> foldpath
, &st
) != NOTOK
? st
.st_mtime
: 0;
683 m_gMsgs (mp
-> hghmsg
);
685 for (msgnum
= mp
-> lowmsg
; msgnum
<= mp
-> hghmsg
; msgnum
++) {
686 Msgs
[msgnum
].m_bboard_id
= 0;
687 Msgs
[msgnum
].m_top
= NOTOK
;
688 Msgs
[msgnum
].m_start
= Msgs
[msgnum
].m_stop
= 0L;
689 Msgs
[msgnum
].m_scanl
= NULL
;
694 fmsh
= getcpy (folder
);
699 maxfds
= getdtablesize () / 2;
701 if ((maxfds
-= 2) < 1)
719 (void) strcpy (tmpfil
, m_tmpfil (invo_name
));
720 if ((fp
= fopen (tmpfil
, "w+")) == NULL
)
721 padios (tmpfil
, "unable to create");
722 (void) unlink (tmpfil
);
726 if ((fp
= fopen (file
, "r")) == NULL
)
727 padios (file
, "unable to read");
729 (void) ioctl (fileno (fp
), FIOCLEX
, NULLCP
);
731 if (fstat (fileno (fp
), &st
) != NOTOK
) {
732 mode
= (int) (st
.st_mode
& 0777), mtime
= st
.st_mtime
;
733 msgp
= read_map (file
, (long) st
.st_size
);
736 mode
= m_gmprot (), mtime
= 0;
740 if ((msgp
= read_file (msgp
? Msgs
[msgp
].m_stop
: 0L, msgp
+ 1)) < 1)
741 padios (NULLCP
, "no messages in %s", myname
? myname
: file
);
743 mp
= (struct msgs
*) calloc ((unsigned) 1, MHSIZE (mp
, 1, msgp
+ 1));
745 padios (NULLCP
, "unable to allocate folder storage");
752 mp
-> foldpath
= getcpy (myname
? myname
: file
);
756 mp
-> msgflags
|= READONLY
;
759 (void) stat (file
, &st
);
760 if (st
.st_uid
!= getuid () || access (file
, 02) == NOTOK
)
761 mp
-> msgflags
|= READONLY
;
766 mp
-> hghoff
= mp
-> hghmsg
+ 1;
769 mp
-> msgstats
= (short *)
770 calloc ((unsigned) 1, MHSIZEX (mp
, mp
-> lowmsg
, mp
-> hghmsg
));
771 if (mp
-> msgstats
== NULL
)
772 padios (NULLCP
, "unable to allocate messages storage");
773 mp
-> msgstats
= (mp
-> msgbase
= mp
-> msgstats
) - mp
-> lowoff
;
774 if (mp
-> msgstats
< (short *)0)
775 padios (NULLCP
, "setup() botch -- you lose big");
780 for (i
= mp
-> lowmsg
; i
<= mp
-> hghmsg
; i
++) {
782 mp
-> msgstats
[i
] = EXISTS
| VIRTUAL
;
785 for (i
= mp
-> lowmsg
; i
<= mp
-> hghmsg
; i
++) {
786 if (Msgs
[i
].m_top
) /* set in read_pop() */
787 mp
-> msgstats
[i
] = EXISTS
| VIRTUAL
;
793 for (i
= mp
-> lowmsg
; i
<= mp
-> hghmsg
; i
++)
794 mp
-> msgstats
[i
] = EXISTS
;
797 mp
-> msgattrs
[0] = getcpy ("unseen");
798 mp
-> msgattrs
[1] = NULL
;
800 m_unknown (fp
); /* the MAGIC invocation */
809 static int read_map (file
, size
)
815 register struct drop
*dp
,
824 if ((i
= map_read (file
, size
, &rp
, 1)) == 0)
830 for (dp
= rp
+ 1; i
-- > 0; msgp
++, dp
++) {
831 mp
= &Msgs
[msgp
].m_drop
;
832 mp
-> d_id
= dp
-> d_id
;
833 mp
-> d_size
= dp
-> d_size
;
834 mp
-> d_start
= dp
-> d_start
;
835 mp
-> d_stop
= dp
-> d_stop
;
836 Msgs
[msgp
].m_scanl
= NULL
;
845 static int read_file (pos
, msgp
)
850 register struct drop
*dp
,
859 if ((i
= mbx_read (fp
, pos
, &rp
, 1)) <= 0)
862 m_gMsgs ((msgp
- 1) + i
);
864 for (dp
= rp
; i
-- > 0; msgp
++, dp
++) {
865 mp
= &Msgs
[msgp
].m_drop
;
867 mp
-> d_size
= dp
-> d_size
;
868 mp
-> d_start
= dp
-> d_start
;
869 mp
-> d_stop
= dp
-> d_stop
;
870 Msgs
[msgp
].m_scanl
= NULL
;
881 static int pop_base
= 0;
883 static int pop_statmsg (s
)
888 n
= (i
= atoi (s
)) - pop_base
; /* s="nnn header-line..." */
889 Msgs
[n
].m_top
= Msgs
[n
].m_bboard_id
= i
;
893 static int read_pop () {
897 if (pop_stat (&nmsgs
, &nbytes
) == NOTOK
)
898 padios (NULLCP
, "%s", response
);
902 #ifdef NNTP /* this makes read_pop() do some real work... */
903 pop_base
= nbytes
- 1; /* nmsgs=last-first+1, nbytes=first */
904 pop_exists (pop_statmsg
);
910 static int pop_action (s
)
913 fprintf (yp
, "%s\n", s
);
925 nMsgs
= n
+ MAXFOLDER
/ 2;
926 Msgs
= (struct Msg
*) calloc ((unsigned) (nMsgs
+ 2), sizeof *Msgs
);
928 padios (NULLCP
, "unable to allocate Msgs structure");
935 nmsgs
= nMsgs
+ n
+ MAXFOLDER
/ 2;
936 Msgs
= (struct Msg
*) realloc ((char *) Msgs
,
937 (unsigned) (nmsgs
+ 2) * sizeof *Msgs
);
939 padios (NULLCP
, "unable to reallocate Msgs structure");
940 bzero ((char *) (Msgs
+ nMsgs
+ 2),
941 (unsigned) ((nmsgs
- nMsgs
) * sizeof *Msgs
));
948 FILE *msh_ready (msgnum
, full
)
965 if ((fd
= Msgs
[msgnum
].m_top
) == NOTOK
) {
966 if (numfds
>= maxfds
)
967 for (msgp
= mp
-> lowmsg
; msgp
<= mp
-> hghmsg
; msgp
++)
968 if (Msgs
[msgp
].m_top
!= NOTOK
) {
969 (void) close (Msgs
[msgp
].m_top
);
970 Msgs
[msgp
].m_top
= NOTOK
;
975 if ((fd
= open (cp
= m_name (msgnum
), 0)) == NOTOK
)
976 padios (cp
, "unable to open message");
977 Msgs
[msgnum
].m_top
= fd
;
981 if ((fd
= dup (fd
)) == NOTOK
)
982 padios ("cached message", "unable to dup");
983 if ((yp
= fdopen (fd
, "r")) == NULL
)
984 padios (NULLCP
, "unable to fdopen cached message");
985 (void) fseek (yp
, 0L, 0);
990 if (pmsh
&& (mp
-> msgstats
[msgnum
] & VIRTUAL
)) {
991 if (Msgs
[msgnum
].m_top
== 0)
992 padios (NULLCP
, "msh_ready (%d, %d) botch", msgnum
, full
);
994 (void) strcpy (tmpfil
, m_tmpfil (invo_name
));
995 if ((yp
= fopen (tmpfil
, "w+")) == NULL
)
996 padios (tmpfil
, "unable to create");
997 (void) unlink (tmpfil
);
999 if (pop_top (Msgs
[msgnum
].m_top
, 4, pop_action
) == NOTOK
)
1000 padios (NULLCP
, "%s", response
);
1002 m_eomsbr ((int (*)()) 0); /* XXX */
1003 msg_style
= MS_DEFAULT
; /* .. */
1004 (void) fseek (yp
, 0L, 0);
1008 (void) fseek (fp
, 0L, 2);
1009 (void) fwrite (mmdlm1
, 1, strlen (mmdlm1
), fp
);
1011 padios ("temporary file", "write error on");
1012 (void) fseek (fp
, 0L, 2);
1016 if (pop_retr (Msgs
[msgnum
].m_top
, pop_action
) == NOTOK
)
1017 padios (NULLCP
, "%s", response
);
1020 (void) fseek (fp
, 0L, 2);
1022 (void) fwrite (mmdlm2
, 1, strlen (mmdlm2
), fp
);
1024 padios ("temporary file", "write error on");
1026 Msgs
[msgnum
].m_start
= pos1
;
1027 Msgs
[msgnum
].m_stop
= pos2
;
1029 mp
-> msgstats
[msgnum
] &= ~VIRTUAL
;
1033 m_eomsbr ((int (*)()) 0); /* XXX */
1034 (void) fseek (fp
, Msgs
[msgnum
].m_start
, 0);
1040 static int check_folder (scansw
)
1056 if (stat (mp
-> foldpath
, &st
) == NOTOK
)
1057 padios (mp
-> foldpath
, "unable to stat");
1058 if (mtime
== st
.st_mtime
)
1060 mtime
= st
.st_mtime
;
1062 low
= mp
-> hghmsg
+ 1;
1065 if (!(mp
= m_gmsg (fmsh
)))
1066 padios (NULLCP
, "unable to re-read folder %s", fmsh
);
1070 for (msgp
= mp
-> lowmsg
; msgp
<= mp
-> hghmsg
; msgp
++) {
1071 if (Msgs
[msgp
].m_top
!= NOTOK
) {
1072 (void) close (Msgs
[msgp
].m_top
);
1073 Msgs
[msgp
].m_top
= NOTOK
;
1076 if (Msgs
[msgp
].m_scanl
) {
1077 free (Msgs
[msgp
].m_scanl
);
1078 Msgs
[msgp
].m_scanl
= NULL
;
1084 if (modified
|| low
> hgh
)
1088 if (fstat (fileno (fp
), &st
) == NOTOK
)
1089 padios (mp
-> foldpath
, "unable to fstat");
1090 if (mtime
== st
.st_mtime
)
1092 mode
= (int) (st
.st_mode
& 0777);
1093 mtime
= st
.st_mtime
;
1095 if ((msgp
= read_file (Msgs
[mp
-> hghmsg
].m_stop
, mp
-> hghmsg
+ 1)) < 1)
1096 padios (NULLCP
, "no messages in %s", mp
-> foldpath
); /* XXX */
1097 if (msgp
<= mp
-> hghmsg
)
1100 if ((mp
= m_remsg (mp
, 0, msgp
)) == NULL
)
1101 padios (NULLCP
, "unable to allocate folder storage");
1103 low
= mp
-> hghmsg
+ 1, hgh
= msgp
;
1104 flags
= scansw
? m_seqflag (mp
, "unseen") : 0;
1105 for (i
= mp
-> hghmsg
+ 1; i
<= msgp
; i
++) {
1106 mp
-> msgstats
[i
] = EXISTS
| flags
;
1109 mp
-> hghmsg
= msgp
;
1116 advise (NULLCP
, "new messages have arrived!\007");
1118 scanrange (low
, hgh
);
1125 static scanrange (low
, hgh
)
1129 char buffer
[BUFSIZ
];
1131 (void) sprintf (buffer
, "%d-%d", low
, hgh
);
1132 scanstring (buffer
);
1136 static scanstring (arg
)
1143 if ((cp
= m_find (cmd_name
= "scan")) != NULL
) {
1144 ap
= brkstring (cp
= getcpy (cp
), " ", "\n");
1145 ap
= copyip (ap
, vec
);
1167 if (mp
-> curmsg
== 0)
1168 m_setcur (mp
, mp
-> lowmsg
);
1169 if (id
<= 0 || (flags
= m_seqflag (mp
, "unseen")) == 0)
1172 for (msgnum
= mp
-> hghmsg
; msgnum
>= mp
-> lowmsg
; msgnum
--)
1173 mp
-> msgstats
[msgnum
] |= flags
;
1178 for (msgnum
= mp
-> hghmsg
; msgnum
>= mp
-> lowmsg
; msgnum
--)
1179 if (mp
-> msgstats
[msgnum
] & EXISTS
) /* FIX */
1180 if ((i
= readid (msgnum
)) > 0 && i
< id
) {
1182 mp
-> msgstats
[msgnum
] &= ~flags
;
1185 for (i
= mp
-> lowmsg
; i
< msgnum
; i
++)
1186 mp
-> msgstats
[i
] &= ~flags
;
1188 if (cur
> mp
-> hghmsg
)
1194 if ((gap
= 1 < id
&& id
< (i
= readid (mp
-> lowmsg
)) ? id
: 0) && !vmh
)
1195 advise (NULLCP
, "gap in ID:s, last seen %d, lowest present %d\n",
1216 if (Msgs
[msgnum
].m_bboard_id
)
1217 return Msgs
[msgnum
].m_bboard_id
;
1220 if (Msgs
[msgnum
].m_top
== 0)
1221 padios (NULLCP
, "readid (%d) botch", msgnum
);
1222 if (pop_list (Msgs
[msgnum
].m_top
, (int *) 0, &arg1
, &arg2
, &arg3
) == OK
1224 return (Msgs
[msgnum
].m_bboard_id
= arg3
);
1228 zp
= msh_ready (msgnum
, 0);
1230 switch (state
= m_getfld (state
, name
, buf
, sizeof buf
, zp
)) {
1234 if (uleq (name
, BBoard_ID
)) {
1236 while (state
== FLDPLUS
) {
1237 state
= m_getfld (state
, name
, buf
, sizeof buf
, zp
);
1243 return (Msgs
[msgnum
].m_bboard_id
= i
);
1247 while (state
== FLDPLUS
)
1248 state
= m_getfld (state
, name
, buf
, sizeof buf
, zp
);
1249 if (state
!= FLDEOF
)
1259 display_info (scansw
)
1265 interactive
= isatty (fileno (stdout
));
1267 if ((sd
= dup (fileno (stdout
))) == NOTOK
)
1268 padios ("standard output", "unable to dup");
1269 #ifndef BSD42 /* XXX */
1271 (void) ioctl (sd
, FIOCLEX
, NULL
);
1272 #endif /* FIOCLEX */
1273 #endif /* not BSD42 */
1274 if ((sp
= fdopen (sd
, "w")) == NULL
)
1275 padios ("standard output", "unable to fdopen");
1278 (void) m_putenv ("mhfolder", mp
-> foldpath
);
1283 printf ("Reading ");
1284 if (SOprintf ("%s", myname
))
1285 printf ("%s", myname
);
1286 printf (", currently at message %d of %d\n",
1287 mp
-> curmsg
, mp
-> hghmsg
);
1290 printf ("Reading ");
1292 printf ("+%s", fmsh
);
1294 printf ("%s", mp
-> foldpath
);
1295 printf (", currently at message %d of %d\n",
1296 mp
-> curmsg
, mp
-> hghmsg
);
1299 if ((flags
= m_seqflag (mp
, "unseen"))
1301 && (mp
-> msgstats
[mp
-> hghmsg
] & flags
))
1302 scanstring ("unseen");
1307 static write_ids () {
1316 if (flags
= m_seqflag (mp
, "unseen"))
1317 for (msgnum
= mp
-> hghmsg
; msgnum
>= mp
-> lowmsg
; msgnum
--)
1318 if (!(mp
-> msgstats
[msgnum
] & flags
)) {
1319 if (Msgs
[msgnum
].m_bboard_id
== 0)
1320 (void) readid (msgnum
);
1321 if ((i
= Msgs
[msgnum
].m_bboard_id
) > 0)
1325 (void) sprintf (buffer
, "%d %d\n", i
, Msgs
[mp
-> hghmsg
].m_bboard_id
);
1326 (void) write (pfd
, buffer
, sizeof buffer
);
1344 if (!(mp
-> msgflags
& MODIFIED
) || mp
-> msgflags
& READONLY
|| fmsh
) {
1346 (void) rc2peer (RC_FIN
, 0, NULLCP
);
1351 (void) ttyNaux (NULLCMD
, "FAST");
1353 if ((dp
= lkfopen (mp
-> foldpath
, "r")) == NULL
) {
1354 advise (mp
-> foldpath
, "unable to lock");
1356 (void) ttyR (NULLCMD
);
1361 if (fstat (fileno (dp
), &st
) == NOTOK
) {
1362 advise (mp
-> foldpath
, "unable to stat");
1365 if (mtime
!= st
.st_mtime
) {
1366 advise (NULLCP
, "new messages have arrived, no update");
1369 mode
= (int) (st
.st_mode
& 0777);
1371 if (mp
-> nummsg
== 0) {
1372 cp
= concat ("Zero file \"", mp
-> foldpath
, "\"? ", NULLCP
);
1373 if (getanswer (cp
)) {
1374 if ((i
= creat (mp
-> foldpath
, mode
)) != NOTOK
)
1377 advise (mp
-> foldpath
, "error zero'ing");
1378 (void) unlink (map_name (mp
-> foldpath
));/* XXX */
1383 cp
= concat ("Update file \"", mp
-> foldpath
, "\"? ", NULLCP
);
1384 if (!getanswer (cp
))
1386 (void) strcpy (tmpfil
, m_backup (mp
-> foldpath
));
1387 if ((md
= mbx_open (tmpfil
, st
.st_uid
, st
.st_gid
, mode
)) == NOTOK
) {
1388 advise (tmpfil
, "unable to open");
1392 for (msgnum
= mp
-> lowmsg
; msgnum
<= mp
-> hghmsg
; msgnum
++)
1393 if (mp
-> msgstats
[msgnum
] & EXISTS
1394 && pack (tmpfil
, md
, msgnum
) == NOTOK
) {
1395 (void) mbx_close (tmpfil
, md
);
1396 (void) unlink (tmpfil
);
1397 (void) unlink (map_name (tmpfil
));
1400 (void) mbx_close (tmpfil
, md
);
1402 if (rename (tmpfil
, mp
-> foldpath
) == NOTOK
)
1403 admonish (mp
-> foldpath
, "unable to rename %s to", tmpfil
);
1405 (void) strcpy (map1
, map_name (tmpfil
));
1406 (void) strcpy (map2
, map_name (mp
-> foldpath
));
1408 if (rename (map1
, map2
) == NOTOK
) {
1409 admonish (map2
, "unable to rename %s to", map1
);
1410 (void) unlink (map1
);
1411 (void) unlink (map2
);
1418 (void) lkfclose (dp
, mp
-> foldpath
);
1420 (void) ttyR (NULLCMD
);
1427 static int getargs (prompt
, sw
, cmdp
)
1434 static char buffer
[BUFSIZ
];
1440 switch (setjmp (sigenv
)) {
1447 if (interrupted
&& !told_to_quit
) {
1448 (void) putchar ('\n');
1452 (void) kill (ppid
, SIGEMT
);
1457 printf ("%s", prompt
);
1458 (void) fflush (stdout
);
1460 for (cp
= buffer
; (i
= getchar ()) != '\n';) {
1462 if (interrupted
&& !told_to_quit
) {
1464 (void) putchar ('\n');
1467 if (told_to_quit
|| i
== EOF
) {
1469 (void) kill (ppid
, SIGEMT
);
1474 longjmp (sigenv
, DONE
);
1476 if (cp
< &buffer
[sizeof buffer
- 2])
1483 if (buffer
[0] == '?') {
1484 printf ("commands:\n");
1485 printsw (ALL
, sw
, "");
1486 printf ("type CTRL-D or use ``quit'' to leave %s\n",
1491 if (parse (buffer
, cmdp
) == NOTOK
)
1494 switch (i
= smatch (cmdp
-> args
[0], sw
)) {
1496 ambigsw (cmdp
-> args
[0], sw
);
1499 printf ("say what: ``%s'' -- type ? (or help) for help\n",
1513 static int getcmds (sw
, cmdp
, scansw
)
1525 switch (peer2rc (rc
)) {
1527 (void) pQRY (rc
-> rc_data
, scansw
);
1531 if ((i
= pCMD (rc
-> rc_data
, sw
, cmdp
)) != NOTOK
)
1537 (void) kill (ppid
, SIGEMT
);
1541 padios (NULLCP
, "%s", rc
-> rc_data
);
1544 (void) fmt2peer (RC_ERR
, "pLOOP protocol screw-up");
1551 static int parse (buffer
, cmdp
)
1560 cmdp
-> line
[0] = 0;
1561 pp
= cmdp
-> args
[argp
++] = cmdp
-> line
;
1562 cmdp
-> redirect
= NULL
;
1563 cmdp
-> direction
= STDIO
;
1564 cmdp
-> stream
= NULL
;
1566 for (cp
= buffer
; c
= *cp
; cp
++)
1571 (void) fmt2peer (RC_EOF
, "null command");
1582 cmdp
-> args
[argp
++] = pp
;
1589 switch (c
= *cp
++) {
1591 padvise (NULLCP
, "unmatched \"");
1596 if ((c
= *cp
++) == 0)
1607 if ((c
= *cp
++) == 0) {
1609 padvise (NULLCP
, "the newline character can not be quoted");
1619 if (pp
== cmdp
-> line
) {
1620 padvise (NULLCP
, "invalid null command");
1623 if (*cmdp
-> args
[argp
- 1] == 0)
1625 cmdp
-> direction
= c
== '>' ? CRTIO
: PIPIO
;
1626 if (cmdp
-> direction
== CRTIO
&& (c
= *cp
) == '>') {
1627 cmdp
-> direction
= APPIO
;
1630 cmdp
-> redirect
= pp
+ 1;/* sigh */
1631 for (; c
= *cp
; cp
++)
1635 padvise (NULLCP
, cmdp
-> direction
!= PIPIO
1636 ? "missing name for redirect"
1637 : "invalid null command");
1640 (void) strcpy (cmdp
-> redirect
, cp
);
1641 if (cmdp
-> direction
!= PIPIO
) {
1643 if (isspace (*cp
)) {
1644 padvise (NULLCP
, "bad name for redirect");
1647 if (expand (cmdp
-> redirect
) == NOTOK
)
1656 cmdp
-> args
[argp
] = NULL
;
1663 int expand (redirect
)
1671 if (*redirect
!= '~')
1674 if (cp
= index (pp
= redirect
+ 1, '/'))
1679 if (pw
= getpwnam (pp
))
1682 padvise (NULLCP
, "unknown user: %s", pp
);
1686 (void) sprintf (path
, "%s/%s", pp
, cp
? cp
: "");
1687 (void) strcpy (redirect
, path
);
1693 static int init_io (cmdp
, vio
)
1694 register struct Cmd
*cmdp
;
1703 result
= initaux_io (cmdp
);
1710 static int initaux_io (cmdp
)
1711 register struct Cmd
*cmdp
;
1715 switch (cmdp
-> direction
) {
1721 mode
= cmdp
-> direction
== CRTIO
? "write" : "append";
1722 if ((cmdp
-> stream
= fopen (cmdp
-> redirect
, mode
)) == NULL
) {
1723 padvise (cmdp
-> redirect
, "unable to %s ", mode
);
1724 cmdp
-> direction
= STDIO
;
1730 if ((cmdp
-> stream
= popen (cmdp
-> redirect
, "w")) == NULL
) {
1731 padvise (cmdp
-> redirect
, "unable to pipe");
1732 cmdp
-> direction
= STDIO
;
1735 (void) signal (SIGPIPE
, pipeser
);
1740 padios (NULLCP
, "unknown redirection for command");
1743 (void) fflush (stdout
);
1744 if (dup2 (fileno (cmdp
-> stream
), fileno (stdout
)) == NOTOK
)
1745 padios ("standard output", "unable to dup2");
1753 static fin_io (cmdp
, vio
)
1754 register struct Cmd
*cmdp
;
1767 static int finaux_io (cmdp
)
1768 register struct Cmd
*cmdp
;
1770 switch (cmdp
-> direction
) {
1776 (void) fflush (stdout
);
1777 (void) close (fileno (stdout
));
1778 if (ferror (stdout
))
1779 padvise (NULLCP
, "problems writing %s", cmdp
-> redirect
);
1780 (void) fclose (cmdp
-> stream
);
1784 (void) fflush (stdout
);
1785 (void) close (fileno (stdout
));
1786 (void) pclose (cmdp
-> stream
);
1787 (void) signal (SIGPIPE
, SIG_DFL
);
1791 padios (NULLCP
, "unknown redirection for command");
1794 if (dup2 (fileno (sp
), fileno (stdout
)) == NOTOK
)
1795 padios ("standard output", "unable to dup2");
1798 cmdp
-> direction
= STDIO
;
1806 for (msgnum
= mp
-> lowmsg
; msgnum
<= mp
-> hghmsg
; msgnum
++)
1807 mp
-> msgstats
[msgnum
] &= ~SELECTED
;
1808 mp
-> lowsel
= mp
-> hghsel
= mp
-> numsel
= 0;
1826 void m_setcur (mp
, msgnum
)
1827 register struct msgs
*mp
;
1828 register int msgnum
;
1830 if (mp
-> curmsg
== msgnum
)
1833 if (mp
-> curmsg
&& Msgs
[mp
-> curmsg
].m_scanl
) {
1834 free (Msgs
[mp
-> curmsg
].m_scanl
);
1835 Msgs
[mp
-> curmsg
].m_scanl
= NULL
;
1837 if (Msgs
[msgnum
].m_scanl
) {
1838 free (Msgs
[msgnum
].m_scanl
);
1839 Msgs
[msgnum
].m_scanl
= NULL
;
1842 mp
-> curmsg
= msgnum
;
1849 static TYPESIG
intrser (i
)
1853 (void) signal (SIGINT
, intrser
);
1854 #endif /* not BSD42 */
1861 longjmp (sigenv
, NOTOK
);
1868 static TYPESIG
pipeser (i
)
1872 (void) signal (SIGPIPE
, pipeser
);
1873 #endif /* not BSD42 */
1875 if (broken_pipe
++ == 0)
1876 fprintf (stderr
, "broken pipe\n");
1881 longjmp (sigenv
, NOTOK
);
1888 static TYPESIG
quitser (i
)
1892 (void) signal (SIGQUIT
, quitser
);
1899 longjmp (sigenv
, NOTOK
);
1905 static int pINI () {
1914 switch (peer2rc (rc
)) {
1917 while (isspace (*bp
))
1919 if (sscanf (bp
, "%d", &vrsn
) != 1) {
1921 (void) fmt2peer (RC_ERR
, "bad init \"%s\"", rc
-> rc_data
);
1924 if (vrsn
!= RC_VRSN
) {
1925 (void) fmt2peer (RC_ERR
, "version %d unsupported", vrsn
);
1929 while (*bp
&& !isspace (*bp
))
1931 while (isspace (*bp
))
1933 if (sscanf (bp
, "%d", &numwins
) != 1 || numwins
<= 0)
1938 for (i
= 1; i
<= numwins
; i
++) {
1939 while (*bp
&& !isspace (*bp
))
1941 while (isspace (*bp
))
1943 if (sscanf (bp
, "%d", &windows
[i
]) != 1 || windows
[i
] <= 0)
1946 (void) rc2peer (RC_ACK
, 0, NULLCP
);
1950 padios (NULLCP
, "%s", rc
-> rc_data
);
1953 (void) fmt2peer (RC_ERR
, "pINI protocol screw-up");
1954 done (1); /* NOTREACHED */
1962 static int pQRY (str
, scansw
)
1966 if (pQRY1 (scansw
) == NOTOK
|| pQRY2 () == NOTOK
)
1969 (void) rc2peer (RC_EOF
, 0, NULLCP
);
1975 static int pQRY1 (scansw
)
1979 static int lastlow
= 0,
1984 oldhgh
= mp
-> hghmsg
;
1985 if (check_folder (scansw
) && oldhgh
< mp
-> hghmsg
) {
1986 switch (winX (STATUS
)) {
1991 printf ("new messages have arrived!");
1992 (void) fflush (stdout
);
1993 (void) fflush (stderr
);
1994 _exit (0); /* NOTREACHED */
1997 lastlow
= lastcur
= lasthgh
= lastnum
= 0;
2001 switch (winX (DISPLAY
)) {
2006 scanrange (oldhgh
+ 1, mp
-> hghmsg
);
2007 (void) fflush (stdout
);
2008 (void) fflush (stderr
);
2009 _exit (0); /* NOTREACHED */
2018 switch (winX (STATUS
)) {
2023 printf ("%s: gap in ID:s, last seen %d, lowest present %d\n",
2024 myname
? myname
: fmsh
? fmsh
: mp
-> foldpath
, gap
- 1,
2025 readid (mp
-> lowmsg
));
2026 (void) fflush (stdout
);
2027 (void) fflush (stderr
);
2028 _exit (0); /* NOTREACHED */
2035 if (mp
-> lowmsg
!= lastlow
2036 || mp
-> curmsg
!= lastcur
2037 || mp
-> hghmsg
!= lasthgh
2038 || mp
-> nummsg
!= lastnum
)
2039 switch (winX (STATUS
)) {
2045 (void) fflush (stdout
);
2046 (void) fflush (stderr
);
2047 _exit (0); /* NOTREACHED */
2050 lastlow
= mp
-> lowmsg
;
2051 lastcur
= mp
-> curmsg
;
2052 lasthgh
= mp
-> hghmsg
;
2053 lastnum
= mp
-> nummsg
;
2062 static int pQRY2 () {
2073 if (mp
-> nummsg
== 0 && mp
-> nummsg
!= num
)
2074 switch (winX (SCAN
)) {
2080 (void) fflush (stdout
);
2081 (void) fflush (stderr
);
2082 _exit (0); /* NOTREACHED */
2091 j
= (k
= windows
[SCAN
]) / 2;
2092 for (msgnum
= mp
-> curmsg
; msgnum
<= mp
-> hghmsg
; msgnum
++)
2093 if (mp
-> msgstats
[msgnum
] & EXISTS
)
2097 k
= i
>= k
? 1 : k
- i
;
2103 for (msgnum
= mp
-> curmsg
; msgnum
>= mp
-> lowmsg
; msgnum
--)
2104 if (mp
-> msgstats
[msgnum
] & EXISTS
) {
2111 for (msgnum
= mp
-> curmsg
+ 1; msgnum
<= mp
-> hghmsg
; msgnum
++)
2112 if (mp
-> msgstats
[msgnum
] & EXISTS
) {
2116 if (n
++ >= windows
[SCAN
])
2122 && mp
-> msgstats
[lo
] & EXISTS
2123 && mp
-> msgstats
[hi
] & EXISTS
2124 && (lo
< mp
-> curmsg
2125 || (lo
== mp
-> curmsg
&& lo
== mp
-> lowmsg
))
2126 && (mp
-> curmsg
< hi
2127 || (hi
== mp
-> curmsg
&& hi
== mp
-> hghmsg
))
2128 && hi
- lo
== j
- i
)
2131 if (mp
-> curmsg
!= cur
|| modified
)
2132 switch (winN (NULLCMD
, SCAN
, 0)) {
2140 scanrange (lo
= i
, hi
= j
);
2142 (void) winR (NULLCMD
);
2151 static int pCMD (str
, sw
, cmdp
)
2159 switch (winX (DISPLAY
)) {
2164 printf ("commands:\n");
2165 printsw (ALL
, sw
, "");
2166 printf ("type ``quit'' to leave %s\n", invo_name
);
2167 (void) fflush (stdout
);
2168 (void) fflush (stderr
);
2169 _exit (0); /* NOTREACHED */
2172 (void) rc2peer (RC_EOF
, 0, NULLCP
);
2176 if (parse (str
, cmdp
) == NOTOK
)
2179 switch (i
= smatch (cmdp
-> args
[0], sw
)) {
2181 switch (winX (DISPLAY
)) {
2186 ambigsw (cmdp
-> args
[0], sw
);
2187 (void) fflush (stdout
);
2188 (void) fflush (stderr
);
2189 _exit (0); /* NOTREACHED */
2192 (void) rc2peer (RC_EOF
, 0, NULLCP
);
2197 (void) fmt2peer (RC_ERR
,
2198 "say what: ``%s'' -- type ? (or help) for help",
2209 static int pFIN () {
2212 switch (setjmp (peerenv
)) {
2214 (void) signal (SIGALRM
, alrmser
);
2215 (void) alarm (ALARM
);
2217 status
= peerwait ();
2228 static int peerwait () {
2234 switch (peer2rc (rc
)) {
2237 (void) rc2peer (RC_FIN
, 0, NULLCP
);
2241 advise (NULLCP
, "%s", rc
-> rc_data
);
2245 (void) fmt2peer (RC_FIN
, "pLOOP protocol screw-up");
2253 static TYPESIG
alrmser (i
)
2256 longjmp (peerenv
, DONE
);
2261 static int ttyNaux (cmdp
, s
)
2262 register struct Cmd
*cmdp
;
2270 if (cmdp
&& init_io (cmdp
, vmh
) == NOTOK
)
2274 (void) fseek (fp
, 0L, 0);/* XXX: fseek() too tricky for our own good */
2277 switch (rc2rc (RC_TTY
, s
? strlen (s
) : 0, s
, rc
)) {
2279 vmhtty
= OK
; /* fall */
2284 padios (NULLCP
, "%s", rc
-> rc_data
);/* NOTREACHED */
2287 (void) fmt2peer (RC_ERR
, "pTTY protocol screw-up");
2288 done (1); /* NOTREACHED */
2292 (void) signal (SIGTSTP
, tstat
);
2293 #endif /* SIGTSTP */
2299 static int ttyR (cmdp
)
2300 register struct Cmd
*cmdp
;
2306 (void) signal (SIGTSTP
, SIG_IGN
);
2307 #endif /* SIGTSTP */
2318 switch (rc2rc (RC_EOF
, 0, NULLCP
, rc
)) {
2320 (void) rc2peer (RC_EOF
, 0, NULLCP
);
2324 padios (NULLCP
, "%s", rc
-> rc_data
);/* NOTREACHED */
2327 (void) fmt2peer (RC_ERR
, "pTTY protocol screw-up");
2328 done (1); /* NOTREACHED */
2334 static int winN (cmdp
, n
, eof
)
2335 register struct Cmd
*cmdp
;
2341 char buffer
[BUFSIZ
];
2345 if (vmhpid
== NOTOK
)
2351 (void) fseek (fp
, 0L, 0);/* XXX: fseek() too tricky for our own good */
2355 (void) sprintf (buffer
, "%d", n
);
2356 switch (str2rc (RC_WIN
, buffer
, rc
)) {
2364 padios (NULLCP
, "%s", rc
-> rc_data
);
2367 (void) fmt2peer (RC_ERR
, "pWIN protocol screw-up");
2371 if (pipe (pd
) == NOTOK
) {
2372 (void) err2peer (RC_ERR
, "pipe", "unable to");
2376 switch (vmhpid
= fork ()) {
2378 (void) err2peer (RC_ERR
, "fork", "unable to");
2379 (void) close (pd
[0]);
2380 (void) close (pd
[1]);
2384 (void) close (pd
[1]);
2385 (void) signal (SIGPIPE
, SIG_IGN
);
2386 while ((i
= read (pd
[0], buffer
, sizeof buffer
)) > 0)
2387 switch (rc2rc (RC_DATA
, i
, buffer
, rc
)) {
2395 advise (NULLCP
, "%s", rc
-> rc_data
);
2399 (void) fmt2peer (RC_ERR
, "pWIN protocol screw-up");
2403 switch (rc2rc (RC_EOF
, 0, NULLCP
, rc
)) {
2406 (void) rc2peer (RC_EOF
, 0, NULLCP
);
2411 advise (NULLCP
, "%s", rc
-> rc_data
);
2416 (void) fmt2peer (RC_ERR
, "pWIN protocol screw-up");
2421 (void) err2peer (RC_ERR
, "pipe", "error reading from");
2422 (void) close (pd
[0]);
2423 _exit (i
!= NOTOK
? i
: 1);
2426 if ((vmhfd0
= dup (fileno (stdin
))) == NOTOK
)
2427 padios ("standard input", "unable to dup");
2428 if ((vmhfd1
= dup (fileno (stdout
))) == NOTOK
)
2429 padios ("standard output", "unable to dup");
2430 if ((vmhfd2
= dup (fileno (stderr
))) == NOTOK
)
2431 padios ("diagnostic output", "unable to dup");
2434 if ((i
= open ("/dev/null", 0)) != NOTOK
&& i
!= fileno (stdin
)) {
2435 (void) dup2 (i
, fileno (stdin
));
2439 (void) fflush (stdout
);
2440 if (dup2 (pd
[1], fileno (stdout
)) == NOTOK
)
2441 padios ("standard output", "unable to dup2");
2444 (void) fflush (stderr
);
2445 if (dup2 (pd
[1], fileno (stderr
)) == NOTOK
)
2446 padios ("diagnostic output", "unable to dup2");
2449 if (cmdp
&& init_io (cmdp
, 0) == NOTOK
)
2451 pstat
= signal (SIGPIPE
, pipeser
);
2454 (void) close (pd
[0]);
2455 (void) close (pd
[1]);
2463 static int winR (cmdp
)
2464 register struct Cmd
*cmdp
;
2474 if (dup2 (vmhfd0
, fileno (stdin
)) == NOTOK
)
2475 padios ("standard input", "unable to dup2");
2477 (void) close (vmhfd0
);
2479 (void) fflush (stdout
);
2480 if (dup2 (vmhfd1
, fileno (stdout
)) == NOTOK
)
2481 padios ("standard output", "unable to dup2");
2483 (void) close (vmhfd1
);
2485 (void) fflush (stderr
);
2486 if (dup2 (vmhfd2
, fileno (stderr
)) == NOTOK
)
2487 padios ("diagnostic output", "unable to dup2");
2489 (void) close (vmhfd2
);
2491 (void) signal (SIGPIPE
, pstat
);
2493 if ((status
= pidwait (vmhpid
, OK
)) == 2)
2497 return (status
== 0 ? OK
: NOTOK
);
2508 char buffer
[BUFSIZ
];
2515 (void) fseek (fp
, 0L, 0);/* XXX: fseek() too tricky for our own good */
2517 (void) sprintf (buffer
, "%d", n
);
2518 switch (str2rc (RC_WIN
, buffer
, rc
)) {
2526 padios (NULLCP
, "%s", rc
-> rc_data
);
2529 (void) fmt2peer (RC_ERR
, "pWIN protocol screw-up");
2533 if (pipe (pd
) == NOTOK
) {
2534 (void) err2peer (RC_ERR
, "pipe", "unable to");
2538 switch (pid
= fork ()) {
2540 (void) err2peer (RC_ERR
, "fork", "unable to");
2541 (void) close (pd
[0]);
2542 (void) close (pd
[1]);
2546 (void) close (fileno (stdin
));
2547 if ((i
= open ("/dev/null", 0)) != NOTOK
&& i
!= fileno (stdin
)) {
2548 (void) dup2 (i
, fileno (stdin
));
2551 (void) dup2 (pd
[1], fileno (stdout
));
2552 (void) dup2 (pd
[1], fileno (stderr
));
2553 (void) close (pd
[0]);
2554 (void) close (pd
[1]);
2559 (void) close (pd
[1]);
2560 while ((i
= read (pd
[0], buffer
, sizeof buffer
)) > 0)
2561 switch (rc2rc (RC_DATA
, i
, buffer
, rc
)) {
2566 (void) close (pd
[0]);
2567 (void) pidwait (pid
, OK
);
2571 padios (NULLCP
, "%s", rc
-> rc_data
);
2574 (void) fmt2peer (RC_ERR
, "pWIN protocol screw-up");
2578 switch (rc2rc (RC_EOF
, 0, NULLCP
, rc
)) {
2583 padios (NULLCP
, "%s", rc
-> rc_data
);
2586 (void) fmt2peer (RC_ERR
, "pWIN protocol screw-up");
2590 (void) err2peer (RC_ERR
, "pipe", "error reading from");
2592 (void) close (pd
[0]);
2593 (void) pidwait (pid
, OK
);
2594 return (i
!= NOTOK
? pid
: NOTOK
);
2602 void padios (what
, fmt
, a
, b
, c
, d
, e
, f
)
2613 (void) err2peer (RC_FIN
, what
, fmt
, a
, b
, c
, d
, e
, f
);
2617 advise (what
, fmt
, a
, b
, c
, d
, e
, f
);
2625 void padvise (what
, fmt
, a
, b
, c
, d
, e
, f
)
2636 (void) err2peer (RC_ERR
, what
, fmt
, a
, b
, c
, d
, e
, f
);
2638 advise (what
, fmt
, a
, b
, c
, d
, e
, f
);