Even more spelling fixed
[oweals/cde.git] / cde / programs / dtmail / dtmailpr / utils.C
1 /*
2  * CDE - Common Desktop Environment
3  *
4  * Copyright (c) 1993-2012, The Open Group. All rights reserved.
5  *
6  * These libraries and programs are free software; you can
7  * redistribute them and/or modify them under the terms of the GNU
8  * Lesser General Public License as published by the Free Software
9  * Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * These libraries and programs are distributed in the hope that
13  * they will be useful, but WITHOUT ANY WARRANTY; without even the
14  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15  * PURPOSE. See the GNU Lesser General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with these libraries and programs; if not, write
20  * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21  * Floor, Boston, MA 02110-1301 USA
22  */
23 /* $XConsortium: utils.C /main/4 1996/04/21 19:44:10 drk $ */
24
25 /*
26  *+SNOTICE
27  *
28  *      $:$
29  *
30  *      RESTRICTED CONFIDENTIAL INFORMATION:
31  *      
32  *      The information in this document is subject to special
33  *      restrictions in a confidential disclosure agreement between
34  *      HP, IBM, Sun, USL, SCO and Univel.  Do not distribute this
35  *      document outside HP, IBM, Sun, USL, SCO, or Univel without
36  *      Sun's specific written approval.  This document and all copies
37  *      and derivative works thereof must be returned or destroyed at
38  *      Sun's request.
39  *
40  *      Copyright 1994 Sun Microsystems, Inc.  All rights reserved.
41  *
42  *+ENOTICE
43  */
44
45 #include "dmx.hh"
46
47 // fn proto for mailx fn
48 static char * dispname(const char *hdr);
49
50 // error-handling: should do something with minor codes
51
52 boolean_t
53 handleError (DtMailEnv &dterror, char *msg)
54 {
55         if (dterror.isSet () == DTM_TRUE)
56         {
57                 fprintf (stderr, "dtmailpr: (%s) %s\n", 
58                         msg, (const char *)dterror);
59                 dterror.logError (DTM_FALSE, "dtmailpr: (%s) %s\n",
60                         msg, (const char *)dterror);
61
62                 dterror.clear ();
63                 return B_TRUE;
64         }
65
66         dterror.clear ();
67         return B_FALSE;
68 }
69         
70
71 char *
72 errorString (enum DmxHeaders hdr)
73 {
74         switch (hdr)
75         {
76                 case DMXFROM:
77                         return "(unknown)";
78                 case DMXSUBJ:
79                         return "(no subject)";
80                 case DMXCLENGTH:
81                         return "0";
82                 case DMXSTATUS:
83                         return "  ";
84                 case DMXDATE:
85                         return "(unknown date)";
86                 case DMXTO:
87                         return " ";
88                 case DMXNUMHDRS:
89                 default:
90                         return " ";
91         }
92 }
93
94 char *
95 formatHeader (DtMailHeaderLine &info, enum DmxHeaderType htype)
96 {
97         int     i = 0, length = 0;
98         int     buflength = 0;
99         char    *fbuf;
100
101         const char      *header [DMXNUMHDRS];
102
103         for (i = 0; i < DMXNUMHDRS; i++)
104         {
105                 length = info.header_values[i].length ();
106                 if (length == 0)
107                 {
108                         header [i] = errorString ((enum DmxHeaders)i);
109                 } else {
110                         header [i] = *((info.header_values[i])[0]);
111                 }
112         }
113
114         for (i = 0; i < DMXNUMHDRS; i++)
115         {
116                 buflength += strlen (header [i]);
117         }
118
119         fbuf = new char [buflength + 64];
120
121         switch (htype)
122         {
123                 case MSGLIST:
124                         sprintf (fbuf,
125                         "%-18.18s %-16.16s %4d/%-5s %-.25s",
126                                 dispname (header [DMXFROM]),
127                                 header [DMXDATE],
128                                 atoi (header [DMXCLENGTH]) / 40,
129                                 header [DMXCLENGTH],
130                                 header [DMXSUBJ]
131                                 );
132                         break;
133                 case MSGHEADER:
134                         sprintf (fbuf,
135                         "From: %s\nDate: %s\nTo: %s\nSubject: %s\n",
136                                 dispname (header [DMXFROM]),
137                                 header [DMXDATE],
138                                 header [DMXTO],
139                                 header [DMXSUBJ]);
140                         break;
141                 case NUMHDRTYPES:
142                 default:
143                         delete [] fbuf;
144                         return "";
145         }
146         return (fbuf); //need to free this after using it
147 }
148
149 // stuff grabbed from mailx...it's ugly, but it looks pretty
150
151 #define NOSTR ((char *) 0)    /* Nill string pointer */
152 #define LINESIZE 5120            /* max readable line width */
153 static char *phrase(char *, int , int );
154
155 /*
156  * Return a pointer to a dynamic copy of the argument.
157  */
158 // changed salloc to malloc
159 char *
160 savestr(char *str)
161 {
162         register char *cp, *cp2, *top;
163
164         for (cp = str; *cp; cp++)
165                 ;
166         top = (char *)malloc((unsigned)(cp-str + 1));
167         if (top == NOSTR)
168                 return(NOSTR);
169         for (cp = str, cp2 = top; *cp; cp++)
170                 *cp2++ = *cp;
171         *cp2 = 0;
172         return(top);
173 }
174
175
176 char *
177 skin(char *name)
178 {
179         return phrase(name, 0, 0);
180 }
181 /*
182  * Return the full name from an RFC-822 header line
183  * or the last two (or one) component of the address.
184  */
185
186 static char *
187 dispname(const char *hdr)
188 // made it a const char * instead of a char *
189 {
190         char *cp, *cp2;
191
192         if (hdr == 0)
193                 return 0;
194         if (((cp = const_cast <char *> (strchr(hdr, '<'))) != 0) && (cp > hdr)) {
195                 *cp = 0;
196                 if ((*hdr == '"') && ((cp = const_cast <char *> (strrchr(++hdr, '"'))) != 0))
197                         *cp = 0;
198                 return (char *)hdr;
199         } else if ((cp = const_cast <char *> (strchr(hdr, '('))) != 0) {
200                 hdr = ++cp;
201                 if ((cp = const_cast <char *> (strchr(hdr, '+'))) != 0)
202                         *cp = 0;
203                 if ((cp = const_cast <char *> (strrchr(hdr, ')'))) != 0)
204                         *cp = 0;
205                 return (char *)hdr;
206         }
207         cp = skin((char *)hdr);
208         if ((cp2 = strrchr(cp, '!')) != 0) {
209                 while (cp2 >= cp && *--cp2 != '!');
210                 cp = ++cp2;
211         }
212         return cp;
213 }
214
215
216 #define equal(a, b)     (strcmp(a,b)==0)/* A nice function to string compare */
217
218 /*
219  * Skin an arpa net address according to the RFC 822 interpretation
220  * of "host-phrase."
221  */
222 // changed salloc to malloc
223 static char *
224 phrase(char *name, int token, int comma)
225 {
226         register char c;
227         register char *cp, *cp2;
228         char *bufend, *nbufp;
229         int gotlt, lastsp, didq;
230         char nbuf[LINESIZE];
231         int nesting;
232
233         if (name == NOSTR)
234                 return(NOSTR);
235         if (strlen(name) >= (unsigned)LINESIZE)
236                 nbufp = (char *)malloc(strlen(name));
237         else
238                 nbufp = nbuf;
239         gotlt = 0;
240         lastsp = 0;
241         bufend = nbufp;
242         for (cp = name, cp2 = bufend; (c = *cp++) != 0;) {
243                 switch (c) {
244                 case '(':
245                         /*
246                                 Start of a comment, ignore it.
247                         */
248                         nesting = 1;
249                         while ((c = *cp) != 0) {
250                                 cp++;
251                                 switch(c) {
252                                 case '\\':
253                                         if (*cp == 0) goto outcm;
254                                         cp++;
255                                         break;
256                                 case '(':
257                                         nesting++;
258                                         break;
259                                 case ')':
260                                         --nesting;
261                                         break;
262                                 }
263                                 if (nesting <= 0) break;
264                         }
265                 outcm:
266                         lastsp = 0;
267                         break;
268                 case '"':
269                         /*
270                                 Start a quoted string.
271                                 Copy it in its entirety.
272                         */
273                         didq = 0;
274                         while ((c = *cp) != 0) {
275                                 cp++;
276                                 switch (c) {
277                                 case '\\':
278                                         if ((c = *cp) == 0) goto outqs;
279                                         cp++;
280                                         break;
281                                 case '"':
282                                         goto outqs;
283                                 }
284                                 if (gotlt == 0 || gotlt == '<') {
285                                         if (lastsp) {
286                                                 lastsp = 0;
287                                                 *cp2++ = ' ';
288                                         }
289                                         if (!didq) {
290                                                 *cp2++ = '"';
291                                                 didq++;
292                                         }
293                                         *cp2++ = c;
294                                 }
295                         }
296                 outqs:
297                         if (didq)
298                                 *cp2++ = '"';
299                         lastsp = 0;
300                         break;
301
302                 case ' ':
303                 case '\t':
304                 case '\n':
305                         if (token && (!comma || c == '\n')) {
306                         done:
307                                 cp[-1] = 0;
308                                 return cp;
309                         }
310                         lastsp = 1;
311                         break;
312
313                 case ',':
314                         *cp2++ = c;
315                         if (gotlt != '<') {
316                                 if (token)
317                                         goto done;
318                                 bufend = cp2 + 1;
319                                 gotlt = 0;
320                         }
321                         break;
322
323                 case '<':
324                         cp2 = bufend;
325                         gotlt = c;
326                         lastsp = 0;
327                         break;
328
329                 case '>':
330                         if (gotlt == '<') {
331                                 gotlt = c;
332                                 break;
333                         }
334
335                         /* FALLTHROUGH . . . */
336
337                 default:
338                         if (gotlt == 0 || gotlt == '<') {
339                                 if (lastsp) {
340                                         lastsp = 0;
341                                         *cp2++ = ' ';
342                                 }
343                                 *cp2++ = c;
344                         }
345                         break;
346                 }
347         }
348         *cp2 = 0;
349         return (token ? --cp : equal(name, nbufp) ? name :
350             nbufp == nbuf ? savestr(nbuf) : nbufp);
351 }
352
353
354