Added all of the MH sources, including RCS files, in
[mmh] / docs / historical / mh-6.8.5 / sbr / RCS / formatsbr.c,v
1 head    1.25;
2 access;
3 symbols;
4 locks
5         shettich:1.25; strict;
6 comment @ * @;
7
8
9 1.25
10 date    95.12.06.20.59.41;      author jromine; state Exp;
11 branches;
12 next    1.24;
13
14 1.24
15 date    93.08.20.15.48.14;      author jromine; state Exp;
16 branches;
17 next    1.23;
18
19 1.23
20 date    93.06.12.06.46.16;      author jromine; state Exp;
21 branches;
22 next    1.22;
23
24 1.22
25 date    93.02.26.21.56.37;      author jromine; state Exp;
26 branches;
27 next    1.21;
28
29 1.21
30 date    92.12.15.00.20.22;      author jromine; state Exp;
31 branches;
32 next    1.20;
33
34 1.20
35 date    92.11.24.18.06.01;      author jromine; state Exp;
36 branches;
37 next    1.19;
38
39 1.19
40 date    92.11.09.17.53.13;      author jromine; state Exp;
41 branches;
42 next    1.18;
43
44 1.18
45 date    92.11.05.17.02.34;      author jromine; state Exp;
46 branches;
47 next    1.17;
48
49 1.17
50 date    92.10.26.22.49.45;      author jromine; state Exp;
51 branches;
52 next    1.16;
53
54 1.16
55 date    92.02.09.07.11.55;      author jromine; state Exp;
56 branches;
57 next    1.15;
58
59 1.15
60 date    92.01.31.21.49.21;      author jromine; state Exp;
61 branches;
62 next    1.14;
63
64 1.14
65 date    92.01.24.18.09.25;      author jromine; state Exp;
66 branches;
67 next    1.13;
68
69 1.13
70 date    92.01.23.23.10.58;      author jromine; state Exp;
71 branches;
72 next    1.12;
73
74 1.12
75 date    91.01.09.22.34.45;      author mh;      state Exp;
76 branches;
77 next    1.11;
78
79 1.11
80 date    90.12.27.17.19.03;      author mh;      state Exp;
81 branches;
82 next    1.10;
83
84 1.10
85 date    90.04.05.15.30.45;      author sources; state Exp;
86 branches;
87 next    1.9;
88
89 1.9
90 date    90.04.05.14.44.48;      author sources; state Exp;
91 branches;
92 next    1.8;
93
94 1.8
95 date    90.03.23.15.16.29;      author sources; state Exp;
96 branches;
97 next    1.7;
98
99 1.7
100 date    90.03.23.14.38.52;      author sources; state Exp;
101 branches;
102 next    1.6;
103
104 1.6
105 date    90.03.13.15.41.41;      author sources; state Exp;
106 branches;
107 next    1.5;
108
109 1.5
110 date    90.02.21.16.03.22;      author sources; state Exp;
111 branches;
112 next    1.4;
113
114 1.4
115 date    90.02.21.15.58.58;      author sources; state Exp;
116 branches;
117 next    1.3;
118
119 1.3
120 date    90.02.06.16.34.54;      author sources; state Exp;
121 branches;
122 next    1.2;
123
124 1.2
125 date    90.02.06.13.02.35;      author sources; state Exp;
126 branches;
127 next    1.1;
128
129 1.1
130 date    90.01.30.10.44.13;      author sources; state Exp;
131 branches;
132 next    ;
133
134
135 desc
136 @@
137
138
139 1.25
140 log
141 @x.400 fixes from mtr
142 @
143 text
144 @/* formatsbr.c - format string interpretation */
145 #ifndef lint
146 static char ident[] = "@@(#)$Id: formatsbr.c,v 1.24 1993/08/20 15:48:14 jromine Exp jromine $";
147 #endif  /* lint */
148
149 #include "../h/mh.h"
150 #include "../h/addrsbr.h"
151 #include "../h/formatsbr.h"
152 #include "../zotnet/tws.h"
153 #include "../h/fmtcompile.h"
154 #include <ctype.h>
155 #include <stdio.h>
156 #include <sys/types.h>
157 #include <sys/stat.h>
158
159 /* \f */
160
161
162 #define NFMTS   MAXARGS
163 #define QUOTE '\\'
164
165 static char  *formats = 0;
166 extern char *formataddr ();     /* hook for custom address formatting */
167 #ifdef  LBL
168 struct msgs *fmt_current_folder; /* current folder (set by main program) */
169 #endif
170
171 static normalize();
172 static int   get_x400_comp();
173
174 extern int fmt_norm;            /* defined in sbr/formatdef.c = AD_NAME */
175 struct mailname fmt_mnull;
176
177
178 long    time ();
179
180 /* \f */
181
182 /* MAJOR HACK:  See MHCHANGES for discussion */
183
184 char  *new_fs (form, format, def)
185 register char  *form,
186                *format,
187                *def;
188 {
189     struct stat st;
190     register    FILE *fp;
191
192     if (formats)
193         free (formats);
194
195     if (form) {
196         if ((fp = fopen (libpath (form), "r")) == NULL)
197             adios (form, "unable to open format file");
198
199         if (fstat (fileno (fp), &st) == NOTOK)
200             adios (form, "unable to stat format file");
201
202         if ((formats = malloc ((unsigned) st.st_size + 1)) == NULLCP)
203             adios (form, "unable to allocate space for format");
204
205         if (read (fileno(fp), formats, (int) st.st_size) != st.st_size)
206             adios (form, "error reading format file");
207
208         formats[st.st_size] = '\0';
209
210         (void) fclose (fp);
211     }
212     else {
213         formats = getcpy (format ? format : def);
214     }
215
216     normalize (formats);
217
218     return formats;
219 }
220
221 /* \f */
222
223 static  normalize (cp)
224 register char  *cp;
225 {
226     register char  *dp;
227
228     for (dp = cp; *cp; cp++)
229         if (*cp != QUOTE)
230             *dp++ = *cp;
231         else
232             switch (*++cp) {
233 #define grot(y,z) case y: *dp++ = z; break;
234                 grot ('b', '\b');
235                 grot ('f', '\f');
236                 grot ('n', '\n');
237                 grot ('r', '\r');
238                 grot ('t', '\t');
239
240                 case '\n':
241                     break;
242
243                 case 0: 
244                     cp--;       /* fall */
245                 default: 
246                     *dp++ = *cp;
247                     break;
248             }
249
250     *dp = 0;
251 }
252
253 /* \f */
254 /*
255  * test if string "sub" appears anywhere in string "str"
256  * (case insensitive).
257  */
258
259 static int match (str, sub)
260 register char  *str,
261                *sub;
262 {
263     register int    c1;
264     register int    c2;
265     register char   *s1;
266     register char   *s2;
267
268 #ifdef LOCALE
269     while (c1 = *sub) {
270         c1 = (isalpha(c1) && isupper(c1)) ? tolower(c1) : c1;
271         while ((c2 = *str++) && c1 != ((isalpha(c2) && isupper(c2)) ? tolower(c2) : c2))
272             ;
273         if (! c2)
274             return 0;
275         s1 = sub + 1; s2 = str;
276         while ((c1 = *s1++) && ((isalpha(c1) && isupper(c1)) ? tolower(c1) : c1) == ((isalpha(c2 =*s2++) && isupper(c2)) ? tolower(c2) : c2))
277             ;
278         if (! c1)
279             return 1;
280     }
281 #else
282     while (c1 = *sub) {
283         while ((c2 = *str++) && (c1 | 040) != (c2 | 040))
284             ;
285         if (! c2)
286             return 0;
287         s1 = sub + 1; s2 = str;
288         while ((c1 = *s1++) && (c1 | 040) == (*s2++ | 040))
289             ;
290         if (! c1)
291             return 1;
292     }
293 #endif
294     return 1;
295 }
296 /* \f */
297
298 /* macros to format data */
299
300 #define PUTDF(cp, num, wid, fill) if (cp + wid < ep){\
301                 if((i = (num))<0) i = -(num);\
302                 if((c = (wid))<0) c = -c;\
303                 sp = cp + c;\
304                 do {\
305                     *--sp = (i % 10) + '0';\
306                     i /= 10;\
307                 } while (i > 0 && sp > cp);\
308                 if (i > 0)\
309                     *sp = '?';\
310                 else if ((num) < 0 && sp > cp)\
311                     *--sp = '-';\
312                 while (sp > cp)\
313                     *--sp = fill;\
314                 cp += c;\
315                 }
316 #define PUTD(cp, num) if (cp < ep){\
317                 if((i = (num))==0) *cp++ = '0';\
318                 else {\
319                     if((i = (num))<0) \
320                         *cp++ = '-', i = -(num);\
321                     c = 10;\
322                     while (c <= i) \
323                         c *= 10;\
324                     while (cp < ep && c > 1) {\
325                         c /= 10;\
326                         *cp++ = (i / c) + '0';\
327                         i %= c;\
328                         }\
329                     }\
330                 }
331 #ifdef LOCALE
332 #define PUTSF(cp, str, wid, fill) {\
333                 ljust = 0;\
334                 if ((i = (wid)) < 0) {\
335                         i = -i;\
336                         ljust++;\
337                 }\
338                 if (sp = (str)) {\
339                         if (ljust) {\
340                                 c = strlen(sp);\
341                                 if (c > i)\
342                                         sp += c - i;\
343                                 else {\
344                                         while( --i >= c && cp < ep)\
345                                                 *cp++ = fill;\
346                                         i++;\
347                                 }\
348                         } else {\
349                             while ((c = *sp) && (iscntrl(c) || isspace(c)))\
350                                 sp++;\
351                         }\
352                         while ((c = *sp++) && --i >= 0 && cp < ep)\
353                                 if (isgraph(c)) \
354                                     *cp++ = c;\
355                                 else {\
356                                         while ((c = *sp) && (iscntrl(c) || isspace(c)))\
357                                                 sp++;\
358                                             *cp++ = ' ';\
359                                 }\
360                 }\
361                 if (!ljust)\
362                 while( --i >= 0 && cp < ep)\
363                     *cp++ = fill;\
364         }
365 #define PUTS(cp, str) {\
366                 if (sp = (str)) {\
367                     while ((c = *sp) && (iscntrl(c) || isspace(c)))\
368                         sp++;\
369                     while((c = *sp++) && cp < ep)\
370                         if (isgraph(c)) \
371                             *cp++ = c;\
372                         else {\
373                             while ((c = *sp) && (iscntrl(c) || isspace(c)))\
374                                 sp++;\
375                             *cp++ = ' ';\
376                         }\
377                 }\
378         }
379 #else /* LOCALE */
380 #define PUTSF(cp, str, wid, fill) {\
381                 ljust = 0;\
382                 if ((i = (wid)) < 0) {\
383                         i = -i;\
384                         ljust++;\
385                 }\
386                 if (sp = (str)) {\
387                         if (ljust) {\
388                                 c = strlen(sp);\
389                                 if (c > i)\
390                                         sp += c - i;\
391                                 else {\
392                                         while( --i >= c && cp < ep)\
393                                                 *cp++ = fill;\
394                                         i++;\
395                                 }\
396                         } else {\
397                     while ((c = *sp) && c <= 32)\
398                         sp++;\
399                         }\
400                         while ((c = *sp++) && --i >= 0 && cp < ep)\
401                                 if (c > 32) \
402                             *cp++ = c;\
403                         else {\
404                                         while ((c = *sp) && c <= 32)\
405                                 sp++;\
406                             *cp++ = ' ';\
407                         }\
408                 }\
409                 if (!ljust)\
410                 while( --i >= 0 && cp < ep)\
411                     *cp++ = fill;\
412                 }
413 #define PUTS(cp, str) {\
414                 if (sp = (str)) {\
415                     while ((c = *sp) && c <= 32)\
416                         sp++;\
417                     while( (c = *sp++) && cp < ep)\
418                         if ( c > 32 ) \
419                             *cp++ = c;\
420                         else {\
421                             while ( (c = *sp) && c <= 32 )\
422                                 sp++;\
423                             *cp++ = ' ';\
424                         }\
425                 }\
426                 }
427 #endif
428
429
430 static char *lmonth[] = { "January",  "February","March",   "April",
431                           "May",      "June",    "July",    "August",
432                           "September","October", "November","December" };
433
434 static char *get_x400_friendly (mbox, buffer)
435 char   *mbox,
436        *buffer;
437 {
438     char    given[BUFSIZ],
439             surname[BUFSIZ];
440
441     if (mbox == NULLCP)
442         return NULLCP;
443     if (*mbox == '"')
444         mbox++;
445     if (*mbox != '/')
446         return NULLCP;
447
448     if (get_x400_comp (mbox, "/PN=", buffer)) {
449         for (mbox = buffer; mbox = index (mbox, '.'); )
450             *mbox++ = ' ';
451
452         return buffer;
453     }
454
455     if (!get_x400_comp (mbox, "/S=", surname))
456         return NULLCP;
457
458     if (get_x400_comp (mbox, "/G=", given))
459         (void) sprintf (buffer, "%s %s", given, surname);
460     else
461         (void) strcpy (buffer, surname);
462
463     return buffer;
464 }
465
466 static int get_x400_comp (mbox, key, buffer)
467 char   *mbox,
468        *key,
469        *buffer;
470 {
471     int     idx;
472     char   *cp;
473
474     if ((idx = stringdex (key, mbox)) < 0
475             || !(cp = index (mbox += idx + strlen (key), '/')))
476         return 0;
477
478     (void) sprintf (buffer, "%*.*s", cp - mbox, cp - mbox, mbox);
479     return 1;
480 }
481
482 struct format *
483 fmtscan (format, scanl, width, dat)
484         struct format *format;
485         char    *scanl;
486         int     width;
487         int     dat[];
488 {
489     register char       *cp = scanl;
490     register char       *ep = scanl + width - 1;
491     register struct format *fmt = format;
492     register char       *str = NULLCP;
493     register int        value = 0;
494     register char       *sp;
495     register int        i;
496     register int        c;
497     register struct comp *comp;
498     register struct tws *tws;
499     register struct mailname *mn;
500     int ljust;
501     long l;
502     char        *savestr;
503     char        buffer[BUFSIZ];
504
505     while (cp < ep) {
506         switch (fmt->f_type) {
507
508         case FT_COMP:
509             PUTS (cp, fmt->f_comp->c_text);
510             break;
511         case FT_COMPF:
512             PUTSF (cp, fmt->f_comp->c_text, fmt->f_width, fmt->f_fill);
513             break;
514
515         case FT_LIT:
516             sp = fmt->f_text;
517             while( (c = *sp++) && cp < ep)
518                 *cp++ = c;
519             break;
520         case FT_LITF:
521             sp = fmt->f_text;
522             ljust = 0;
523             i = fmt->f_width;
524             if (i < 0) {
525                 i = -i;
526                 ljust++;                /* XXX should do something with this */
527             }
528             while( (c = *sp++) && --i >= 0 && cp < ep)
529                 *cp++ = c;
530             while( --i >= 0 && cp < ep)
531                 *cp++ = fmt->f_fill;
532             break;
533
534         case FT_STR:
535             PUTS (cp, str);
536             break;
537         case FT_STRF:
538             PUTSF (cp, str, fmt->f_width, fmt->f_fill);
539             break;
540         case FT_STRFW:
541             adios (NULLCP, "internal error (FT_STRFW)");
542
543         case FT_NUM:
544             PUTD (cp, value);
545             break;
546         case FT_NUMF:
547             PUTDF (cp, value, fmt->f_width, fmt->f_fill);
548             break;
549
550         case FT_CHAR:
551             *cp++ = fmt->f_char;
552             break;
553
554         case FT_DONE:
555             goto finished;
556
557         case FT_IF_S:
558             if (!(value = (str && *str))) {
559                 fmt += fmt->f_skip;
560                 continue;
561             }
562             break;
563
564         case FT_IF_S_NULL:
565             if (!(value = (str == NULLCP || *str == 0))) {
566                 fmt += fmt->f_skip;
567                 continue;
568             }
569             break;
570
571         case FT_IF_V_EQ:
572             if (value != fmt->f_value) {
573                 fmt += fmt->f_skip;
574                 continue;
575             }
576             break;
577
578         case FT_IF_V_NE:
579             if (value == fmt->f_value) {
580                 fmt += fmt->f_skip;
581                 continue;
582             }
583             break;
584
585         case FT_IF_V_GT:
586             if (value <= fmt->f_value) {
587                 fmt += fmt->f_skip;
588                 continue;
589             }
590             break;
591
592         case FT_IF_MATCH:
593             if (!(value = (str && match (str, fmt->f_text)))) {
594                 fmt += fmt->f_skip;
595                 continue;
596             }
597             break;
598
599         case FT_V_MATCH:
600             if (str)
601                 value = match (str, fmt->f_text);
602             else
603                 value = 0;
604             break;
605
606         case FT_IF_AMATCH:
607             if (!(value = (str && uprf (str, fmt->f_text)))) {
608                 fmt += fmt->f_skip;
609                 continue;
610             }
611             break;
612
613         case FT_V_AMATCH:
614             value = uprf (str, fmt->f_text);
615             break;
616
617         case FT_S_NONNULL:
618             value = (str != NULLCP && *str != 0);
619             break;
620
621         case FT_S_NULL:
622             value = (str == NULLCP || *str == 0);
623             break;
624
625         case FT_V_EQ:
626             value = (fmt->f_value == value);
627             break;
628
629         case FT_V_NE:
630             value = (fmt->f_value != value);
631             break;
632
633         case FT_V_GT:
634             value = (fmt->f_value > value);
635             break;
636
637         case FT_GOTO:
638             fmt += fmt->f_skip;
639             continue;
640
641         case FT_NOP:
642             break;
643
644         case FT_LS_COMP:
645             str = fmt->f_comp->c_text;
646             break;
647         case FT_LS_LIT:
648             str = fmt->f_text;
649             break;
650         case FT_LS_GETENV:
651             if (!(str = getenv (fmt->f_text)))
652                 str = "";
653             break;
654         case FT_LS_MFIND:
655             if (!(str = m_find (fmt->f_text)))
656                 str = "";
657             break;
658         case FT_LS_TRIM:
659             if (str) {
660                     register char *xp;
661
662                     (void) strcpy(buffer, str);
663                     str = buffer;
664                     while (isspace(*str))
665                             str++;
666                     ljust = 0;
667                     if ((i = fmt->f_width) < 0) {
668                             i = -i;
669                             ljust++;
670                     }
671
672                     if (!ljust && i > 0 && strlen(str) > i)
673                             str[i] = '\0';
674                     xp = str;
675                     xp += strlen(str) - 1;
676                     while (xp > str && isspace(*xp))
677                             *xp-- = '\0';
678                     if (ljust && i > 0 && strlen(str) > i)
679                         str += strlen(str) - i;
680             }
681             break;
682
683         case FT_LV_COMPFLAG:
684             value = fmt->f_comp->c_flags;
685             break;
686         case FT_LV_COMP:
687             value = (comp = fmt->f_comp)->c_text ? atoi(comp->c_text) : 0;
688             break;
689         case FT_LV_LIT:
690             value = fmt->f_value;
691             break;
692         case FT_LV_DAT:
693             value = dat[fmt->f_value];
694             break;
695         case FT_LV_STRLEN:
696             value = strlen(str);
697             break;
698         case FT_LV_CHAR_LEFT:
699             value = width - (cp - scanl);
700             break;
701         case FT_LV_PLUS_L:
702             value += fmt->f_value;
703             break;
704         case FT_LV_MINUS_L:
705             value = fmt->f_value - value;
706             break;
707         case FT_LV_DIVIDE_L:
708             if (fmt->f_value)
709                 value = value / fmt->f_value;
710             else
711                 value = 0;
712             break;
713         case FT_LV_MODULO_L:
714             if (fmt->f_value)
715                 value = value % fmt->f_value;
716             else
717                 value = 0;
718             break;
719         case FT_SAVESTR:
720             savestr = str;
721             break;
722
723         case FT_LV_SEC:
724             value = fmt->f_comp->c_tws->tw_sec;
725             break;
726         case FT_LV_MIN:
727             value = fmt->f_comp->c_tws->tw_min;
728             break;
729         case FT_LV_HOUR:
730             value = fmt->f_comp->c_tws->tw_hour;
731             break;
732         case FT_LV_MDAY:
733             value = fmt->f_comp->c_tws->tw_mday;
734             break;
735         case FT_LV_MON:
736             value = fmt->f_comp->c_tws->tw_mon + 1;
737             break;
738         case FT_LS_MONTH:
739             str = tw_moty[fmt->f_comp->c_tws->tw_mon];
740             break;
741         case FT_LS_LMONTH:
742             str = lmonth[fmt->f_comp->c_tws->tw_mon];
743             break;
744         case FT_LS_ZONE:
745             str = dtwszone (fmt->f_comp->c_tws);
746             break;
747         case FT_LV_YEAR:
748 #ifndef YEARMOD
749             value = fmt->f_comp->c_tws->tw_year;
750 #else   /* YEARMOD */
751             value = (fmt->f_comp->c_tws->tw_year) % 100;
752 #endif  /* YEARMOD */
753             break;
754         case FT_LV_WDAY:
755             if (!(((tws = fmt->f_comp->c_tws)->tw_flags) & (TW_SEXP|TW_SIMP)))
756                 set_dotw (tws);
757             value = tws->tw_wday;
758             break;
759         case FT_LS_DAY:
760             if (!(((tws = fmt->f_comp->c_tws)->tw_flags) & (TW_SEXP|TW_SIMP)))
761                 set_dotw (tws);
762             str = tw_dotw[tws->tw_wday];
763             break;
764         case FT_LS_WEEKDAY:
765             if (!(((tws = fmt->f_comp->c_tws)->tw_flags) & (TW_SEXP|TW_SIMP)))
766                 set_dotw (tws);
767             str = tw_ldotw[tws->tw_wday];
768             break;
769         case FT_LV_YDAY:
770             value = fmt->f_comp->c_tws->tw_yday;
771             break;
772         case FT_LV_ZONE:
773             value = fmt->f_comp->c_tws->tw_zone;
774             break;
775         case FT_LV_CLOCK:
776             if ((value = fmt->f_comp->c_tws->tw_clock) == 0)
777                 value = twclock(fmt->f_comp->c_tws);
778             break;
779         case FT_LV_RCLOCK:
780             if ((value = fmt->f_comp->c_tws->tw_clock) == 0)
781                 value = twclock(fmt->f_comp->c_tws);
782             value = time((long *) 0) - value;
783             break;
784         case FT_LV_DAYF:
785             if (!(((tws = fmt->f_comp->c_tws)->tw_flags) & (TW_SEXP|TW_SIMP)))
786                 set_dotw (tws);
787             switch (fmt->f_comp->c_tws->tw_flags & TW_SDAY) {
788                 case TW_SEXP:
789                     value = 1; break;
790                 case TW_SIMP:
791                     value = 0; break;
792                 default:
793                     value = -1; break;
794             }
795         case FT_LV_ZONEF:
796             if ((fmt->f_comp->c_tws->tw_flags & TW_SZONE) == TW_SZEXP)
797                     value = 1;
798             else
799                     value = -1;
800             break;
801         case FT_LV_DST:
802             value = fmt->f_comp->c_tws->tw_flags & TW_DST;
803             break;
804         case FT_LS_822DATE:
805             str = dasctime ( fmt->f_comp->c_tws , TW_ZONE);
806             break;
807         case FT_LS_PRETTY:
808             str = dasctime ( fmt->f_comp->c_tws, TW_NULL);
809             break;
810
811         case FT_LS_PERS:
812             str = fmt->f_comp->c_mn->m_pers;
813             break;
814         case FT_LS_MBOX:
815             str = fmt->f_comp->c_mn->m_mbox;
816             break;
817         case FT_LS_HOST:
818             str = fmt->f_comp->c_mn->m_host;
819             break;
820         case FT_LS_PATH:
821             str = fmt->f_comp->c_mn->m_path;
822             break;
823         case FT_LS_GNAME:
824             str = fmt->f_comp->c_mn->m_gname;
825             break;
826         case FT_LS_NOTE:
827             str = fmt->f_comp->c_mn->m_note;
828             break;
829         case FT_LS_822ADDR:
830             str = adrformat( fmt->f_comp->c_mn );
831             break;
832         case FT_LV_HOSTTYPE:
833             value = fmt->f_comp->c_mn->m_type;
834             break;
835         case FT_LV_INGRPF:
836             value = fmt->f_comp->c_mn->m_ingrp;
837             break;
838         case FT_LV_NOHOSTF:
839             value = fmt->f_comp->c_mn->m_nohost;
840             break;
841         case FT_LS_ADDR:
842         case FT_LS_FRIENDLY:
843 #ifdef BERK
844             str = fmt->f_comp->c_mn->m_mbox;
845 #else   /* not BERK */
846             if ((mn = fmt -> f_comp -> c_mn) == &fmt_mnull) {
847                 str = fmt -> f_comp -> c_text;
848                 break;
849             }
850             if (fmt -> f_type == FT_LS_ADDR)
851                 goto unfriendly;
852             if (!(str = mn -> m_pers)
853                     && (!(str = get_x400_friendly (mn -> m_mbox, buffer)))) {
854                 if (str = mn -> m_note) {
855                     (void) strcpy (buffer, str);
856                     str = buffer;
857                     if (*str == '(')
858                         str++;
859                     sp = str + strlen (str) - 1;
860                     if (*sp == ')') {
861                         *sp-- = '\0';
862                         while (sp >= str)
863                             if (*sp == ' ')
864                                 *sp-- = '\0';
865                             else
866                                 break;
867                     }
868                     if (*str)
869                         break;
870                 }           
871
872 unfriendly: ;
873                 switch (mn -> m_type) {
874                     case LOCALHOST:
875                         str = mn -> m_mbox;
876                         break;
877                     case UUCPHOST:
878                         (void) sprintf (str = buffer, "%s!%s",
879                                         mn -> m_host, mn -> m_mbox);
880                         break;
881                     default:
882                         if (mn -> m_mbox)
883                             (void) sprintf (str= buffer, "%s@@%s", mn -> m_mbox,
884                                             mn -> m_host);
885                         else
886                             str = mn -> m_text;
887                         break;
888                 }
889             }
890 #endif  /* BERK */
891             break;
892
893         case FT_LOCALDATE:
894             comp = fmt->f_comp;
895             if ((l = comp->c_tws->tw_clock) == 0)
896                 l = twclock(comp->c_tws);
897             tws = dlocaltime(&l);
898             *comp->c_tws = *tws;
899             break;
900
901         case FT_GMTDATE:
902             comp = fmt->f_comp;
903             if ((l = comp->c_tws->tw_clock) == 0)
904                 l = twclock(comp->c_tws);
905             tws = dgmtime(&l);
906             *comp->c_tws = *tws;
907             break;
908
909         case FT_PARSEDATE:
910             comp = fmt->f_comp;
911             if ((sp = comp->c_text) && (tws = dparsetime(sp))) {
912                 *comp->c_tws = *tws;
913                 comp->c_flags = 0;
914             } else if (comp->c_flags >= 0) {
915                 bzero ((char *) comp -> c_tws, sizeof *comp -> c_tws);
916                 comp->c_flags = 1;
917             }
918             break;
919
920         case FT_FORMATADDR:
921             /* hook for custom address list formatting (see replsbr.c) */
922             str = formataddr (savestr, str);
923             break;
924
925         case FT_PUTADDR:
926             /* output the str register as an address component,
927              * splitting it into multiple lines if necessary.  The
928              * value reg. contains the max line length.  The lit.
929              * field may contain a string to prepend to the result
930              * (e.g., "To: ")
931              */
932             {
933             register char *lp = str;
934             register int indent;
935             register int wid = value;
936             register int len = strlen (str);
937             register char *lastb;
938
939             sp = fmt->f_text;
940             indent = strlen (sp);
941             wid -= indent;
942             while( (c = *sp++) && cp < ep)
943                 *cp++ = c;
944             while (len > wid) {
945                 /* try to break at a comma; failing that, break at a
946                  * space, failing that, just split the line.
947                  */
948                 lastb = 0; sp = lp + wid;
949                 while (sp > lp && (c = *--sp) != ',') {
950                     if (! lastb && isspace(c))
951                         lastb = sp - 1;
952                 }
953                 if (sp == lp)
954                     if (! (sp = lastb))
955                         sp = lp + wid - 1;
956                 len -= sp - lp + 1;
957                 while (cp < ep && lp <= sp)
958                     *cp++ = *lp++;
959                 *cp++ = '\n';
960                 for (i=indent; cp < ep && i > 0; i--)
961                     *cp++ = ' ';
962                 while (isspace(*lp))
963                     lp++, len--;
964             }
965             PUTS (cp, lp);
966             }
967             break;
968
969         case FT_PARSEADDR:
970             comp = fmt->f_comp;
971             if (comp->c_mn != &fmt_mnull)
972                 mnfree (comp->c_mn);
973             if ((sp = comp->c_text) && (sp = getname(sp)) &&
974                 (mn = getm (sp, NULLCP, 0, fmt_norm, NULLCP))) {
975                 comp->c_mn = mn;
976                 while (getname(""))
977                     ;
978             } else {
979                 while (getname(""))             /* XXX */
980                     ;
981                 comp->c_mn = &fmt_mnull;
982             }
983             break;
984             
985         case FT_MYMBOX:
986             /*
987              * if there's no component, we say true.  Otherwise we
988              * say "true" only if we can parse the address and it
989              * matches one of our addresses.
990              */
991             comp = fmt->f_comp;
992             if (comp->c_mn != &fmt_mnull)
993                 mnfree (comp->c_mn);
994             if ((sp = comp->c_text) && (sp = getname(sp)) &&
995                 (mn = getm (sp, NULLCP, 0, AD_NAME, NULLCP))) {
996                 comp->c_mn = mn;
997                 comp->c_flags = ismymbox(mn);
998                 while (sp = getname(sp))
999                     if (comp->c_flags == 0 &&
1000                         (mn = getm (sp, NULLCP, 0, AD_NAME, NULLCP)))
1001                         comp->c_flags |= ismymbox(mn);
1002             } else {
1003                 while (getname(""))             /* XXX */
1004                     ;
1005                 comp->c_flags = (comp->c_text == 0);
1006                 comp->c_mn = &fmt_mnull;
1007             }
1008             break;
1009
1010         case FT_ADDTOSEQ:
1011 #ifdef  LBL
1012             /* If we're working on a folder (as opposed to a file), add the
1013              * current msg to sequence given in literal field.  Don't
1014              * disturb string or value registers.
1015              */
1016             if (fmt_current_folder)
1017                     (void)m_seqadd(fmt_current_folder, fmt->f_text, dat[0], -1);
1018 #endif
1019             break;
1020         }
1021         fmt++;
1022     }
1023 #ifndef JLR
1024     finished:;
1025     if (cp[-1] != '\n')
1026         *cp++ = '\n';
1027     *cp   = 0;
1028     return ((struct format *)0);
1029 #else   /* JLR */
1030     if (cp[-1] != '\n')
1031         *cp++ = '\n';
1032     while (fmt->f_type != FT_DONE)
1033         fmt++;
1034
1035     finished:;    
1036     *cp = '\0';
1037     return (fmt -> f_value ? ++fmt : (struct format *)0);
1038
1039 #endif /* JLR */
1040 }
1041 @
1042
1043
1044 1.24
1045 log
1046 @small patch to make funny X.400 addresses look better  /mtr
1047 @
1048 text
1049 @d3 1
1050 a3 1
1051 static char ident[] = "@@(#)$Id: formatsbr.c,v 1.23 1993/06/12 06:46:16 jromine Exp jromine $";
1052 d709 22
1053 a730 18
1054             if ((str = mn -> m_pers) == NULL)
1055                 if ((str = mn -> m_note)) {
1056                     (void) strcpy (buffer, str);
1057                     str = buffer;
1058                     if (*str == '(')
1059                         str++;
1060                     sp = str + strlen(str) - 1;
1061                     if (*sp == ')') {
1062                         *sp-- = '\0';
1063                         while (sp >= str)
1064                             if (*sp == ' ')
1065                                 *sp-- = '\0';
1066                             else
1067                                 break;
1068                     }
1069                 } else if (!(str = get_x400_friendly (mn -> m_mbox, buffer))) {
1070         unfriendly: ;
1071                   switch (mn -> m_type) {
1072 d732 1
1073 a732 1
1074                         str = mn -> m_mbox;
1075 d735 1
1076 a735 1
1077                         (void) sprintf (buffer, "%s!%s",
1078 a736 1
1079                         str = buffer;
1080 d739 3
1081 a741 5
1082                         if (mn -> m_mbox) {
1083                             (void) sprintf (buffer, "%s@@%s",
1084                                             mn -> m_mbox, mn -> m_host);
1085                             str= buffer;
1086                         }
1087 a744 1
1088                   }
1089 d746 1
1090 @
1091
1092
1093 1.23
1094 log
1095 @add %(profile xxx) to return m_find(xxx)
1096 @
1097 text
1098 @d3 1
1099 a3 1
1100 static char ident[] = "@@(#)$Id: formatsbr.c,v 1.22 1993/02/26 21:56:37 jromine Exp jromine $";
1101 d307 1
1102 a307 1
1103             *mbox++ = 0;
1104 @
1105
1106
1107 1.22
1108 log
1109 @386BSD/BSD44
1110 @
1111 text
1112 @d3 1
1113 a3 1
1114 static char ident[] = "@@(#)$Id: formatsbr.c,v 1.21 1992/12/15 00:20:22 jromine Exp jromine $";
1115 d509 4
1116 @
1117
1118
1119 1.21
1120 log
1121 @endif sugar
1122 @
1123 text
1124 @d3 1
1125 a3 1
1126 static char ident[] = "@@(#)$Id: formatsbr.c,v 1.20 1992/11/24 18:06:01 jromine Exp jromine $";
1127 d62 1
1128 a62 1
1129         if (read (fileno(fp), formats, st.st_size) != st.st_size)
1130 @
1131
1132
1133 1.20
1134 log
1135 @add decl
1136 @
1137 text
1138 @d3 2
1139 a4 2
1140 static char ident[] = "@@(#)$Id: formatsbr.c,v 1.19 1992/11/09 17:53:13 jromine Exp jromine $";
1141 #endif  lint
1142 d698 1
1143 a698 1
1144 #else not BERK
1145 d742 1
1146 a742 1
1147 #endif BERK
1148 @
1149
1150
1151 1.19
1152 log
1153 @add YEARMOD to force 2-digit years
1154 @
1155 text
1156 @d3 1
1157 a3 1
1158 static char ident[] = "@@(#)$Id: formatsbr.c,v 1.18 1992/11/05 17:02:34 jromine Exp jromine $";
1159 d29 1
1160 @
1161
1162
1163 1.18
1164 log
1165 @try to be friendly with x400 rfc987 addresses
1166 @
1167 text
1168 @d3 1
1169 a3 1
1170 static char ident[] = "@@(#)$Id: formatsbr.c,v 1.17 1992/10/26 22:49:45 jromine Exp jromine $";
1171 d600 1
1172 d602 3
1173 @
1174
1175
1176 1.17
1177 log
1178 @LOCALE
1179 @
1180 text
1181 @d3 1
1182 a3 1
1183 static char ident[] = "@@(#)$Id: formatsbr.c,v 1.16 1992/02/09 07:11:55 jromine Exp jromine $";
1184 d290 6
1185 d297 41
1186 d715 1
1187 a715 1
1188                 } else {
1189 @
1190
1191
1192 1.16
1193 log
1194 @put Van Jacobson "addtoseq" option under "options LBL"
1195 make sure combined "if"s set value (for later testing)
1196 add modulo function
1197 @
1198 text
1199 @d3 1
1200 a3 1
1201 static char ident[] = "@@(#)$Id: formatsbr.c,v 1.15 1992/01/31 21:49:21 jromine Exp $";
1202 d124 1
1203 d126 13
1204 d149 1
1205 d187 1
1206 d205 48
1207 d283 1
1208 @
1209
1210
1211 1.15
1212 log
1213 @kerberos
1214 @
1215 text
1216 @d3 1
1217 a3 1
1218 static char ident[] = "@@(#)$Id: formatsbr.c,v 1.14 1992/01/24 18:09:25 jromine Exp jromine $";
1219 d24 1
1220 a24 1
1221 #ifdef  VAN
1222 d302 1
1223 a302 1
1224             if (str == NULLCP || *str == 0) {
1225 d309 1
1226 a309 1
1227             if (str != NULLCP && *str != 0) {
1228 d337 1
1229 a337 1
1230             if (!str || !match (str, fmt->f_text)) {
1231 d345 1
1232 a345 1
1233             value = match (str, fmt->f_text);
1234 d351 1
1235 a351 1
1236             if (!str || !uprf (str, fmt->f_text)) {
1237 d453 6
1238 a744 1
1239 #ifdef  VAN
1240 d746 1
1241 d753 1
1242 a754 1
1243 #endif
1244 @
1245
1246
1247 1.14
1248 log
1249 @move fmt_norm to formatdef.c for shared libs
1250 @
1251 text
1252 @d3 1
1253 a3 1
1254 static char ident[] = "@@(#)$Id: formatsbr.c,v 1.13 1992/01/23 23:10:58 jromine Exp jromine $";
1255 d99 1
1256 a99 1
1257                 case NULL: 
1258 d106 1
1259 a106 1
1260     *dp = NULL;
1261 d302 1
1262 a302 1
1263             if (str == NULLCP || *str == NULL) {
1264 d309 1
1265 a309 1
1266             if (str != NULLCP && *str != NULL) {
1267 d362 1
1268 a362 1
1269             value = (str != NULLCP && *str != NULL);
1270 d366 1
1271 a366 1
1272             value = (str == NULLCP || *str == NULL);
1273 d756 1
1274 a756 1
1275     *cp   = NULL;
1276 @
1277
1278
1279 1.13
1280 log
1281 @new formatsbr changes under JLR
1282 @
1283 text
1284 @d3 1
1285 a3 1
1286 static char ident[] = "@@(#)$Id: formatsbr.c,v 1.12 1991/01/09 22:34:45 mh Exp jromine $";
1287 d30 1
1288 a30 1
1289 int     fmt_norm = AD_NAME;
1290 @
1291
1292
1293 1.12
1294 log
1295 @allow %-n(trim) to right-justify and length limit
1296 jlr
1297 @
1298 text
1299 @d3 1
1300 a3 1
1301 static char ident[] = "@@(#)$Id: formatsbr.c,v 1.11 90/12/27 17:19:03 mh Exp Locker: mh $";
1302 d226 1
1303 d394 4
1304 d752 1
1305 d757 12
1306 a768 1
1307     return (value);
1308 @
1309
1310
1311 1.11
1312 log
1313 @add "addr" address format.
1314 jlr
1315 @
1316 text
1317 @d3 1
1318 a3 1
1319 static char ident[] = "@@(#)$Id: formatsbr.c,v 1.10 90/04/05 15:30:45 sources Exp Locker: mh $";
1320 d404 1
1321 a404 1
1322                             ljust++;    /* XXX should do something with this */
1323 d407 1
1324 a407 1
1325                     if (i > 0 && strlen(str) > i)
1326 d413 2
1327 @
1328
1329
1330 1.10
1331 log
1332 @add ID
1333 @
1334 text
1335 @d3 1
1336 a3 1
1337 static char ident[] = "@@(#)$Id:$";
1338 d564 1
1339 d573 2
1340 d590 3
1341 a592 2
1342                 } else
1343                 switch (mn -> m_type) {
1344 d610 1
1345 @
1346
1347
1348 1.9
1349 log
1350 @add ID
1351 @
1352 text
1353 @d3 1
1354 a3 1
1355 static char ident[] = "$Id:";
1356 @
1357
1358
1359 1.8
1360 log
1361 @remove JLR ifdef around fix
1362 @
1363 text
1364 @d2 3
1365 @
1366
1367
1368 1.7
1369 log
1370 @make friendly just return text if unparseable
1371 @
1372 text
1373 @a692 1
1374 #ifdef  JLR
1375 a694 1
1376 #endif  JLR
1377 a716 1
1378 #ifdef  JLR
1379 a718 1
1380 #endif  JLR
1381 @
1382
1383
1384 1.6
1385 log
1386 @horrible fix for bad address parsing
1387 @
1388 text
1389 @d565 4
1390 a568 1
1391             mn = fmt -> f_comp -> c_mn;
1392 @
1393
1394
1395 1.5
1396 log
1397 @Fixes from Van Jacobson
1398 @
1399 text
1400 @d689 5
1401 a693 1
1402             } else
1403 d695 1
1404 d716 4
1405 @
1406
1407
1408 1.4
1409 log
1410 @checkpoint
1411 @
1412 text
1413 @d134 1
1414 a201 1
1415
1416 d223 1
1417 a223 1
1418 fmtscan(format, scanl, width, dat)
1419 d525 1
1420 a525 1
1421             str = dasctime(fmt->f_comp->c_tws, TW_ZONE);
1422 d528 1
1423 a528 1
1424             str = dasctime(fmt->f_comp->c_tws, TW_NULL);
1425 d716 1
1426 d725 1
1427 @
1428
1429
1430 1.3
1431 log
1432 @make "friendly" more friendly -- it'll pick up "(full name)" now.
1433 @
1434 text
1435 @d21 3
1436 a133 1
1437 /* \f */
1438 d139 2
1439 a140 1
1440                 sp = cp + wid;\
1441 d151 1
1442 a151 1
1443                 cp += wid;\
1444 d169 5
1445 a173 1
1446                 i = (wid);\
1447 d175 10
1448 d187 3
1449 a189 2
1450                     while( (c = *sp++) && --i >= 0 && cp < ep)\
1451                         if ( c > 32 ) \
1452 d192 1
1453 a192 1
1454                             while ( (c = *sp) && c <= 32 )\
1455 d197 1
1456 d201 1
1457 d223 1
1458 a223 1
1459 fmtscan (format, scanl, width, dat)
1460 d240 2
1461 d245 1
1462 a245 1
1463     for (;;) {
1464 d261 7
1465 a267 1
1466             sp = fmt->f_text; i = fmt->f_width;
1467 d333 1
1468 a333 1
1469             if (! match (str, fmt->f_text)) {
1470 d340 1
1471 d342 2
1472 d347 1
1473 a347 1
1474             if (! uprf (str, fmt->f_text)) {
1475 d390 3
1476 d394 19
1477 d437 6
1478 d515 5
1479 d521 1
1480 a521 1
1481         case FT_LV_TZONEF:
1482 d525 1
1483 a525 1
1484             str = dasctime ( fmt->f_comp->c_tws , TW_ZONE);
1485 d528 1
1486 a528 1
1487             str = dasctime ( fmt->f_comp->c_tws, TW_NULL);
1488 d604 16
1489 d706 4
1490 a709 2
1491                 while (getname(""))
1492                     ;
1493 d714 9
1494 @
1495
1496
1497 1.2
1498 log
1499 @ANSI Compilance
1500 @
1501 text
1502 @d503 15
1503 @
1504
1505
1506 1.1
1507 log
1508 @Initial revision
1509 @
1510 text
1511 @d22 2
1512 d83 6
1513 a88 6
1514 #define grot(x) case 'x': *dp++ = '\x'; break;
1515                     grot (b);
1516                     grot (f);
1517                     grot (n);
1518                     grot (r);
1519                     grot (t);
1520 @