2 Proprietary Rand Corporation
, 1981.
3 Further distribution of
this software
4 subject to the terms of the Rand
8 /* THIS command is included wholesale by show.c, which calls
9 * its `main' rather than execing it when showproc is "mhl"
16 #ifndef INCLUDED_BY_SHOW
19 #endif INCLUDED_BY_SHOW
22 extern char *sprintf();
25 char **igp
= ignores
; /* List of ignored components */
26 char *parptr
, *parse();
27 char *fmtfile
; /* User specified format file */
28 char *folder
; /* Name of folder messages are in */
29 char *profargs
[32]; /* Args extracted from profile */
30 int ofilec
; /* Count of real output file args */
31 int ofilen
; /* Number of output file */
32 int ontty
; /* Output to char device */
33 int clearflg
; /* Overrides format screen clear */
34 int row
, column
; /* For character output routine */
35 int alength
, awidth
; /* -length and -width args */
41 extern char _sobuf
[]; /* MLW standard out buffer */
44 /* Defines for c_flags (see below) */
45 #define NOCOMPONENT 01 /* Don't show component name */
46 #define UPPERCASE 02 /* Display in all upper case */
47 #define CENTER 04 /* Center line within width */
48 #define CLEARTEXT 010 /* Clear text line--simply copy to output */
49 #define PROCESSED 020 /* This item processed already */
50 #define EXTRA 040 /* This message comp is an "extra" */
51 #define HDROUTPUT 0100 /* This comp's hdr has been output */
52 #define CLEARSCR 0200 /* Clear screen before each file */
53 #define LEFTADJUST 0400 /* Left adjust mult lines of component */
54 #define COMPRESS 01000 /* Compress text--ignore <lf's> */
57 struct comp
*c_next
; /* Chain to next */
58 char *c_name
, /* Component name */
59 *c_text
, /* Text associated with component */
60 *c_ovtxt
; /* Line overflow indicator text */
61 int c_offset
, /* Left margin indent */
62 c_ovoff
, /* Line overflow indent */
63 c_width
, /* Width of field */
64 c_cwidth
, /* Component width (default strlen(comp)) */
65 c_length
; /* Length in lines */
66 short c_flags
; /* Special flags (see above) */
68 } *msghd
, *msgtl
, *fmthd
, *fmttl
,
69 /* Global contains global len/wid info */
70 global
= { NULL
, NULL
, NULL
, "", 0, 0, 80, 0, 40, 0 },
71 holder
= { NULL
, NULL
, NULL
, NULL
, 0, 0, 0, 0, 0, NOCOMPONENT
};
73 /* Defines for putcomp subrutine mode arg */
74 #define ONECOMP 0 /* Display only control comp name */
75 #define BOTHCOMP 1 /* Display both comp names (conditionally) */
82 register struct comp
*comp
;
83 register char *cp
, **ap
;
85 char line
[256], name
[64];
89 setbuf(stdout
, _sobuf
);
90 VOID
signal(SIGQUIT
, out
);
91 ontty
= gtty(1, (struct sgttyb
*)name
) != -1;
92 cp
= r1bindex(argv
[0], '/');
93 if((cp
= m_find(cp
)) != NULL
) {
94 ap
= brkstring(getcpy(cp
), " ", "\n");
95 VOID
copyip(ap
, profargs
);
101 folder
= getenv("mhfolder");
103 if((fp
= fopen(m_maildir(fmtfile
), "r")) == NULL
) {
104 fprintf(stderr
, "mhl: Can't open format file: %s\n",
108 } else if((fp
= fopen(m_maildir(mhlformat
), "r")) == NULL
&&
109 (fp
= fopen(mhlstdfmt
, "r")) == NULL
) {
110 fprintf(stderr
, "mhl: Can't open default format file.\n");
113 while(fgets(line
, sizeof line
, fp
)) {
114 if(line
[0] == ';') /* Comment line */
117 line
[strlen(line
)-1] = 0; /* Zap the <lf> */
119 if(line
[0] == ':') { /* Clear text line */
120 comp
= (struct comp
*) calloc(1, sizeof (struct comp
));
121 comp
->c_text
= getcpy(line
+1);
122 comp
->c_flags
= CLEARTEXT
;
129 strcpy(name
, parse());
130 /*** printf("%s %c %s\n", name, *parptr, parptr+1); */
136 if(uleq(name
, "ignores")) {
137 igp
= copyip(brkstring(getcpy(++parptr
), ",", NULLCP
), igp
);
142 if(evalvar(&global
)) {
143 fmterr
: fprintf(stderr
, "mhl: format file syntax error: %s\n",
153 comp
= (struct comp
*) calloc(1, sizeof (struct comp
));
154 comp
->c_name
= getcpy(name
);
157 while(*parptr
== ':' || *parptr
== ',') {
163 fmthd
= fmttl
= comp
;
165 fmttl
->c_next
= comp
;
176 global
.c_flags
|= CLEARSCR
;
177 else if(clearflg
== -1)
178 global
.c_flags
&= ~CLEARSCR
;
179 if(awidth
) global
.c_width
= awidth
;
180 if(alength
) global
.c_length
= alength
;
181 if(global
.c_width
< 5) global
.c_width
= 10000;
182 if(global
.c_length
< 5) global
.c_length
= 10000;
187 for(ap
= profargs
; *ap
; ap
++)
190 for(ap
= argv
+1; *ap
; ap
++)
199 register struct comp
*sp
;
207 strcpy(name
, parse());
208 /***printf("evalvar: %s %c %s\n", name, *parptr, parptr+1); */
209 if(uleq(name
, "width")) {
210 if(!*parptr
++ == '=' || !*(cp
= parse())) {
211 missing
: fprintf(stderr
, "mhl: missing arg to variable %s\n",
215 sp
->c_width
= atoi(cp
);
218 if(uleq(name
, "compwidth")) {
219 if(!*parptr
++ == '=' || !*(cp
= parse())) goto missing
;
220 sp
->c_cwidth
= atoi(cp
);
223 if(uleq(name
, "length")) {
224 if(!*parptr
++ == '=' || !*(cp
= parse())) goto missing
;
225 sp
->c_length
= atoi(cp
);
228 if(uleq(name
, "overflowtext")) {
229 if(!*parptr
++ == '=') goto missing
;
231 while(*parptr
&& *parptr
!= ':' && *parptr
!= ',') parptr
++;
234 sp
->c_ovtxt
= getcpy(cp
);
238 if(uleq(name
, "offset")) {
239 if(!*parptr
++ == '=' || !*(cp
= parse())) goto missing
;
240 sp
->c_offset
= atoi(cp
);
243 if(uleq(name
, "overflowoffset")) {
244 if(!*parptr
++ == '=' || !*(cp
= parse())) goto missing
;
245 sp
->c_ovoff
= atoi(cp
);
248 if(uleq(name
, "nocomponent")) {
249 sp
->c_flags
|= NOCOMPONENT
;
252 if(uleq(name
, "uppercase")) {
253 sp
->c_flags
|= UPPERCASE
;
256 if(uleq(name
, "center")) {
257 sp
->c_flags
|= CENTER
;
260 if(uleq(name
, "clearscreen")) {
261 sp
->c_flags
|= CLEARSCR
;
264 if(uleq(name
, "leftadjust")) {
265 sp
->c_flags
|= LEFTADJUST
;
268 if(uleq(name
, "compress")) {
269 sp
->c_flags
|= COMPRESS
;
279 static char result
[64];
285 if(isalnum(c
) || c
== '.' || c
== '-' || c
== '_') {
294 struct swit switches
[] = {
296 "noclear", 0, /* 1 */
297 "folder folder", 0, /* 2 */
298 "form formfile", 0, /* 3 */
299 "length of page", 0, /* 4 */
300 "width of line", 0, /* 5 */
311 if(*cp
== '-') switch(smatch(++cp
, switches
)) {
312 case -2:ambigsw(cp
, switches
); /* ambiguous */
315 case -1:fprintf(stderr
, "mhl: -%s unknown\n", cp
);
318 case 0: clearflg
= 1; /* -clear */
322 case 1: clearflg
= -1; /* -noclear */
326 case 2: if(!(folder
= *ap
++) || *folder
== '-') {
327 missing
: fprintf(stderr
, "mhl: Missing arg for %s\n", ap
[-2]);
330 ap
[-2] = ""; ap
[-1] = "";
333 case 3: if(!(fmtfile
= *ap
++) || *fmtfile
== '-')
335 ap
[-2] = ""; ap
[-1] = "";
338 case 4: if(!(cp
= *ap
++) || *cp
== '-')
341 ap
[-2] = ""; ap
[-1] = "";
344 case 5: if(!(cp
= *ap
++) || *cp
== '-')
347 ap
[-2] = ""; ap
[-1] = "";
350 case 6: help("mhl [switches] [files]", switches
);
363 register struct comp
*comp
, *c2
, *c3
;
364 char *cp
, **ip
, name
[NAMESZ
], buf
[BUFSIZ
];
371 VOID
signal(SIGINT
, sigcatch
);
373 if((fp
= fopen(fname
, "r")) == NULL
) {
374 fprintf(stderr
, "mhl: Can't open ");
377 VOID
signal(SIGINT
, SIG_IGN
);
387 printf("Press <return> to list \"");
388 if(folder
) printf("%s:", folder
);
389 printf("%s\"...", fname
);
392 VOID
read(1, buf
, sizeof buf
);
394 if(index(buf
, '\n')) {
395 if(global
.c_flags
& CLEARSCR
)
399 } else if(ofilec
> 1) {
403 if(folder
) printf("%s: ", folder
);
404 printf("%s\n\n", fname
);
410 for(state
= FLD
; ;) {
411 state
= m_getfld(state
, name
, buf
, sizeof buf
, fp
);
417 for(ip
= ignores
; *ip
; ip
++)
418 if(uleq(name
, *ip
)) {
419 while(state
== FLDPLUS
)
420 state
= m_getfld(state
, name
, buf
, sizeof buf
, fp
);
423 for(c3
= msghd
; c3
; c3
= c3
->c_next
)
424 if(uleq(name
, c3
->c_name
))
428 comp
->c_text
= add(buf
, comp
->c_text
);
430 comp
= (struct comp
*) calloc(1, sizeof (struct comp
));
431 comp
->c_name
= getcpy(name
);
432 comp
->c_text
= getcpy(buf
);
436 while(state
== FLDPLUS
) {
437 state
= m_getfld(state
, name
, buf
, sizeof buf
, fp
);
438 comp
->c_text
= add(buf
, comp
->c_text
);
440 for(c2
= fmthd
; c2
; c2
= c2
->c_next
)
441 if(uleq(c2
->c_name
, comp
->c_name
))
443 comp
->c_flags
|= EXTRA
;
446 msghd
= msgtl
= comp
;
448 msgtl
->c_next
= comp
;
459 fprintf(stderr
, "Message format error!\n");
467 for(comp
= fmthd
; comp
; comp
= comp
->c_next
) {
468 if(comp
->c_flags
& CLEARTEXT
) {
469 putcomp(comp
, comp
, ONECOMP
);
472 if(uleq(comp
->c_name
, "messagename")) {
473 cp
= concat(fname
, "\n", NULLCP
);
475 holder
.c_text
= concat(folder
, ":", cp
, NULLCP
);
479 putcomp(comp
, &holder
, ONECOMP
);
483 if(uleq(comp
->c_name
, "extras")) {
484 for(c2
= msghd
; c2
; c2
= c2
->c_next
)
485 if(c2
->c_flags
& EXTRA
)
486 putcomp(comp
, c2
, BOTHCOMP
);
489 if(uleq(comp
->c_name
, "body")) {
491 putcomp(comp
, &holder
, ONECOMP
);
493 while(state
== BODY
) {
494 state
= m_getfld(state
, name
, buf
, sizeof buf
, fp
);
496 putcomp(comp
, &holder
, ONECOMP
);
501 for(c2
= msghd
; c2
; c2
= c2
->c_next
)
502 if(uleq(c2
->c_name
, comp
->c_name
)) {
503 putcomp(comp
, c2
, ONECOMP
);
511 if(holder
.c_text
) cndfree(holder
.c_text
);
513 for(c2
= msghd
; c2
; c2
= comp
) {
519 msghd
= msgtl
= NULL
;
520 for(c2
= fmthd
; c2
; c2
= c2
->c_next
)
521 c2
->c_flags
&= ~HDROUTPUT
;
522 VOID
signal(SIGINT
, SIG_IGN
);
529 int lm
; /* Left Margin for putstr */
530 int llim
; /* line limit for this component */
531 int wid
; /* width limit for this comp */
532 int ovoff
; /* overflow offset for this comp */
533 char *ovtxt
; /* overflow text for this comp */
534 int term
; /* term from last oneline() */
535 char *onelp
; /* oneline() text pointer */
537 putcomp(cc
, c2
, flag
)
538 register struct comp
*cc
, *c2
;
542 int count
, cchdr
= 0;
545 printf("%s(%o):%s:%s", cc
->c_name
, cc
->c_flags
, c2
->c_name
,
550 llim
= cc
->c_length
? cc
->c_length
: -1;
551 wid
= cc
->c_width
? cc
->c_width
: global
.c_width
;
552 ovoff
= cc
->c_ovoff
>= 0 ? cc
->c_ovoff
: global
.c_ovoff
;
553 ovoff
+= cc
->c_offset
;
554 ovtxt
= cc
->c_ovtxt
? cc
->c_ovtxt
: global
.c_ovtxt
;
555 if(!ovtxt
) ovtxt
= "";
556 if(wid
< ovoff
+ strlen(ovtxt
) + 5) {
557 fprintf(stderr
, "mhl: component: %s width too small for overflow.\n",
561 if(cc
->c_flags
& CLEARTEXT
) {
566 if(cc
->c_flags
& CENTER
) {
567 count
= global
.c_width
;
568 if(cc
->c_width
) count
= cc
->c_width
;
569 count
-= cc
->c_offset
;
570 count
-= strlen(c2
->c_text
);
571 if(!(cc
->c_flags
&HDROUTPUT
) && !(cc
->c_flags
&NOCOMPONENT
))
572 count
-= strlen(cc
->c_name
) + 2;
573 lm
= cc
->c_offset
+(count
/2);
574 } else if(cc
->c_offset
)
576 if(!(cc
->c_flags
& HDROUTPUT
) && !(cc
->c_flags
& NOCOMPONENT
)) {
577 putstr(cc
->c_name
); putstr(": ");
578 cc
->c_flags
|= HDROUTPUT
;
580 if((count
= cc
->c_cwidth
- strlen(cc
->c_name
) - 2) > 0)
581 while(count
--) putstr(" ");
583 if(flag
== BOTHCOMP
&& !(c2
->c_flags
& HDROUTPUT
) &&
584 !(c2
->c_flags
& NOCOMPONENT
)) {
585 putstr(c2
->c_name
); putstr(": ");
586 c2
->c_flags
|= HDROUTPUT
;
588 if(cc
->c_flags
& UPPERCASE
)
589 for(cp
= c2
->c_text
; *cp
; cp
++)
594 count
= (cc
->c_cwidth
>=0) ? cc
->c_cwidth
: strlen(cc
->c_name
)+2;
595 count
+= cc
->c_offset
;
596 putstr(oneline(c2
->c_text
, cc
->c_flags
));
597 /*** if(cc->c_flags & COMPRESS) printf("-1-"); /***/
600 while(cp
= oneline(c2
->c_text
, cc
->c_flags
)) {
601 /*** if(cc->c_flags & COMPRESS) printf("-2-"); /***/
611 c2
->c_flags
|= PROCESSED
;
615 register char *string
;
617 if(!column
&& lm
> 0)
642 if(ontty
&& row
== global
.c_length
) {
646 VOID
read(1, buf
, sizeof buf
);
647 if(index(buf
, '\n')) {
648 if(global
.c_flags
& CLEARSCR
) {
655 row
= global
.c_length
/ 3;
708 if(flgs
& COMPRESS
) {
712 if(*onelp
== '\n' || *onelp
== '\t' || *onelp
== ' '){
713 if(*onelp
== '\n' && !onelp
[1]) {
729 while(*onelp
&& *onelp
!= '\n') onelp
++;
735 while(*ret
== ' ' || *ret
== '\t') ret
++;
759 if (ioctl(fileno (io
), TIOCGETP
, &sg
) >= 0)
760 ioctl(fileno (io
), TIOCSETP
, &sg
);