Added all of the MH sources, including RCS files, in
[mmh] / docs / historical / mh-6.8.5 / uip / ap.c
1 /* ap.c - parse addresses 822-style */
2 #ifndef lint
3 static char ident[] = "@(#)$Id: ap.c,v 1.7 1992/12/15 00:20:22 jromine Exp $";
4 #endif  /* lint */
5
6 #include "../h/mh.h"
7 #include "../h/addrsbr.h"
8 #include "../h/formatsbr.h"
9 #include <stdio.h>
10 #ifdef LOCALE
11 #include        <locale.h>
12 #endif
13
14
15 #define NADDRS  100
16
17 #define WIDTH   78
18 #define WBUFSIZ BUFSIZ
19
20 #define FORMAT  "%<{error}%{error}: %{text}%|%(putstr(proper{text}))%>"
21
22 /* \f */
23
24 static struct swit switches[] = {
25 #define FORMSW  0
26     "form formatfile", 0,
27 #define FMTSW   1
28     "format string", 5,
29
30 #define NORMSW  2
31     "normalize", 0,
32 #define NNORMSW 3
33     "nonormalize", 0,
34
35 #define WIDSW   4
36     "width columns", 0,
37
38 #define HELPSW  5
39     "help", 4,
40
41     NULL, 0
42 };
43
44 /* \f */
45
46 static struct format *fmt;
47
48 static int dat[5];
49
50 static int      process();
51 /* \f */
52
53 /* ARGSUSED */
54
55 main (argc, argv)
56 int     argc;
57 char   **argv;
58 {
59     int     addrp = 0,
60             normalize = AD_HOST,
61             width = 0,
62             status = 0;
63     char   *cp,
64            *form = NULL,
65            *format = NULL,
66            *nfs,
67             buf[80],
68           **ap,
69           **argp,
70            *arguments[MAXARGS],
71            *addrs[NADDRS];
72
73 #ifdef LOCALE
74         setlocale(LC_ALL, "");
75 #endif
76     invo_name = r1bindex (argv[0], '/');
77     mts_init (invo_name);
78     if ((cp = m_find (invo_name)) != NULL) {
79         ap = brkstring (cp = getcpy (cp), " ", "\n");
80         ap = copyip (ap, arguments);
81     }
82     else
83         ap = arguments;
84     (void) copyip (argv + 1, ap);
85     argp = arguments;
86
87 /* \f */
88
89     while (cp = *argp++) {
90         if (*cp == '-')
91             switch (smatch (++cp, switches)) {
92                 case AMBIGSW: 
93                     ambigsw (cp, switches);
94                     done (1);
95
96                 case UNKWNSW: 
97                     adios (NULLCP, "-%s unknown", cp);
98
99                 case HELPSW: 
100                     (void) sprintf (buf, "%s [switches] addrs ...", invo_name);
101                     help (buf, switches);
102                     done (1);
103
104                 case FORMSW: 
105                     if (!(form = *argp++) || *form == '-')
106                         adios (NULLCP, "missing argument to %s", argp[-2]);
107                     format = NULL;
108                     continue;
109                 case FMTSW: 
110                     if (!(format = *argp++) || *format == '-')
111                         adios (NULLCP, "missing argument to %s", argp[-2]);
112                     form = NULL;
113                     continue;
114
115                 case WIDSW: 
116                     if (!(cp = *argp++) || *cp == '-')
117                         adios (NULLCP, "missing argument to %s", argp[-2]);
118                     width = atoi (cp);
119                     continue;
120
121                 case NORMSW: 
122                     normalize = AD_HOST;
123                     continue;
124                 case NNORMSW: 
125                     normalize = AD_NHST;
126                     continue;
127             }
128         if (addrp > NADDRS)
129             adios (NULLCP, "more than %d addresses", NADDRS);
130         else
131             addrs[addrp++] = cp;
132     }
133     addrs[addrp] = NULL;
134
135 /* \f */
136
137     if (addrp == 0)
138         adios (NULLCP, "usage: %s [switches] addrs ...", invo_name);
139
140     nfs = new_fs (form, format, FORMAT);
141     if (width == 0) {
142         if ((width = sc_width ()) < WIDTH / 2)
143             width = WIDTH / 2;
144         width -= 2;
145     }
146     if (width > WBUFSIZ)
147         width = WBUFSIZ;
148     fmt_norm = normalize;
149     (void) fmt_compile (nfs, &fmt);
150     dat[0] = dat[1] = dat[2] = dat[4] = 0;
151     dat[3] = width;
152
153     for (addrp = 0; addrs[addrp]; addrp++)
154         status += process (addrs[addrp], width, normalize);
155
156     done (status);
157 }
158
159 /* \f */
160
161 struct pqpair {
162     char    *pq_text;
163     char    *pq_error;
164     struct pqpair *pq_next;
165 };
166
167
168 static int  process (arg, length, norm)
169 register char  *arg;
170 int     length,
171         norm;
172 {
173     int     status = 0;
174     register char  *cp;
175     char    buffer[WBUFSIZ + 1],
176             error[BUFSIZ];
177     register struct comp   *cptr;
178     register struct pqpair *p,
179                            *q;
180     struct pqpair   pq;
181     register struct mailname   *mp;
182
183     (q = &pq) -> pq_next = NULL;
184     while (cp = getname (arg)) {
185         if ((p = (struct pqpair *) calloc ((unsigned) 1, sizeof *p)) == NULL)
186             adios (NULLCP, "unable to allocate pqpair memory");
187         if ((mp = getm (cp, NULLCP, 0, norm, error)) == NULL) {
188             p -> pq_text = getcpy (cp);
189             p -> pq_error = getcpy (error);
190             status++;
191         }
192         else {
193             p -> pq_text = getcpy (mp -> m_text);
194             mnfree (mp);
195         }
196         q = (q -> pq_next = p);
197     }
198
199     for (p = pq.pq_next; p; p = q) {
200         FINDCOMP (cptr, "text");
201         if (cptr)
202             cptr -> c_text = p -> pq_text;
203         FINDCOMP (cptr, "error");
204         if (cptr)
205             cptr -> c_text = p -> pq_error;
206
207         (void) fmtscan (fmt, buffer, length, dat);
208         (void) fputs (buffer, stdout);
209
210         free (p -> pq_text);
211         if (p -> pq_error)
212             free (p -> pq_error);
213         q = p -> pq_next;
214         free ((char *) p);
215     }
216
217     return status;
218 }