1 
2 /* $Id: elm_defs.h,v 1.7 1999/03/24 14:03:42 wfp5p Exp $ */
3 
4 /*******************************************************************************
5  *  The Elm Mail System  -  $Revision: 1.7 $   $State: Exp $
6  *
7  *                      Copyright (c) 1988-1998 USENET Community Trust
8  * 			Copyright (c) 1986,1987 Dave Taylor
9  *******************************************************************************
10  * Bug reports, patches, comments, suggestions should be sent to:
11  *
12  *      Bill Pemberton, Elm Coordinator
13  *      flash@virginia.edu
14  *
15  *******************************************************************************
16  * $Log: elm_defs.h,v $
17  * Revision 1.7  1999/03/24  14:03:42  wfp5p
18  * elm 2.5PL0
19  *
20  * Revision 1.6  1996/10/28  16:58:03  wfp5p
21  * Beta 1
22  *
23  * Revision 1.4  1996/05/09  15:50:55  wfp5p
24  * Alpha 10
25  *
26  * Revision 1.3  1996/03/14  17:27:21  wfp5p
27  * Alpha 9
28  *
29  * Revision 1.1  1995/09/29  17:40:47  wfp5p
30  * Alpha 8 (Chip's big changes)
31  *
32  * Revision 1.14  1995/09/11  15:18:45  wfp5p
33  * Alpha 7
34  *
35  * Revision 1.13  1995/07/18  18:59:45  wfp5p
36  * Alpha 6
37  *
38  * Revision 1.12  1995/06/30  14:56:17  wfp5p
39  * Alpha 5
40  *
41  * Revision 1.11  1995/06/21  15:26:34  wfp5p
42  * editflush and confirmtagsave are new in the elmrc (Keith Neufeld)
43  *
44  * Revision 1.10  1995/06/14  19:58:07  wfp5p
45  * Changes for alpha 3
46  *
47  * Revision 1.9  1995/06/12  20:32:29  wfp5p
48  * Fixed up a couple of multiple declares
49  *
50  * Revision 1.8  1995/06/09  22:06:53  wfp5p
51  * Added the correct date for the alpha 1 release
52  *
53  * Revision 1.7  1995/06/01  13:13:20  wfp5p
54  * Readmsg was fixed to work correctly if called from within elm.  From Chip
55  * Rosenthal <chip@unicom.com>
56  *
57  * Revision 1.6  1995/05/24  15:32:47  wfp5p
58  * Added a few changes from Keith Neufeld <neufeld@pvi.org>
59  *
60  * Revision 1.5  1995/05/10  13:34:27  wfp5p
61  * Added mailing list stuff by Paul Close <pdc@sgi.com>
62  * And NetBSD stuff.
63  *
64  * Revision 1.4  1995/04/21  18:05:36  wfp5p
65  * Added more options to attribution
66  *
67  * Revision 1.3  1995/04/21  13:30:21  wfp5p
68  * Added a the Ultirx fflush() bug fix.
69  *
70  * Revision 1.2  1995/04/20  21:01:08  wfp5p
71  * Removed filter
72  *
73  * Revision 1.1.1.1  1995/04/19  20:38:30  wfp5p
74  * Initial import of elm 2.4 PL0 as base for elm 2.5.
75  *
76  ******************************************************************************/
77 
78 /*
79  * This header file should be included first thing by all source
80  * modules throughout the Elm package (src, lib, and utils).
81  */
82 
83 #define VERSION		"2.5"			/* Version number... */
84 #define VERS_DATE	"August 18, 2005"		/* for elm -v option */
85 #define WHAT_STRING	\
86 	"@(#) Version 2.5, USENET supported version PL8"
87 
88 #include <sys/types.h>	/* for fundamental types */
89 #include <stdio.h>	/* Must get the _IOEOF flag for feof() on Convex */
90 #include <fcntl.h>
91 #include <errno.h>
92 #include <signal.h>
93 #include "config.h"
94 #include "sysdefs.h"	/* system/configurable defines */
95 
96 /* if not debugging, disable the assert() tests */
97 #ifndef DEBUG
98 # define NDEBUG
99 #endif
100 
101 #ifndef TRUE
102 # define TRUE		1
103 # define FALSE		0
104 #endif
105 
106 #ifndef _SIZE_T  /* not the greatest, but should work until I make Configure figure it out */
107 #define _SIZE_T
108 typedef unsigned long size_t;
109 #endif
110 
111 #define KLICK		32	/* increment for alias and mssg lists	    */
112 
113 #define TLEN		10	/* super short (tiny) strings		    */
114 #define WLEN		20	/* small words				    */
115 #define NLEN		48	/* name length for aliases		    */
116 #define STRING		128	/* reasonable string length for most..      */
117 #define SLEN		256	/* long for ensuring no overwrites...	    */
118 #define LONG_STRING	512	/* even longer string for group expansion   */
119 #define VERY_LONG_STRING 2560	/* huge string for group alias expansion    */
120 #define MAX_LINE_LEN	5120	/* even bigger string for "filter" prog..   */
121 
122 /* FOO - I believe these might belong in sysdefs.h */
123 
124 #define alias_file		".aliases"
125 #define group_file		".groups"
126 #define system_file		".systems"
127 
128 #define default_folders		"Mail"
129 #define default_recvdmail	"=received"
130 #define default_sentmail	"=sent"
131 #define default_to_chars	" TC*"
132 
133 #define streq(p, q)		(strcmp((p), (q)) == 0)
134 
135 /* use these ONLY where "d" is a constant string value */
136 #define strbegConst(s, d)	(strncmp((s), (d), sizeof(d)-1) == 0)
137 #define stribegConst(s, d)	(strincmp((s), (d), sizeof(d)-1) == 0)
138 
139 /*
140  * The macros implement speeded up constant string comparisons.
141  * They are useful alternatives when a string is subject to
142  * multiple comparisons.  The comparison target (the "d" value)
143  * *must* be a constant string, and the first character of this
144  * string *must* be upper case (or non-alphabetic).
145  *
146  * To use them, "FAST_COMP_DECLARE" must appear in variable declarations
147  * at the top of the procedure.  Then "fast_comp_load" must be invoked
148  * to preload the first character of the string.
149  */
150 #define FAST_COMP_DECLARE		int FAST_COMP_ch
151 #define fast_comp_load(c)		FAST_COMP_ch = toupper(c)
152 #define fast_strbegConst(s, d)		strbegConst(s, d)
153 #define fast_stribegConst(s, d)		(FAST_COMP_ch == (d)[0] \
154 	    && strincmp((s), (d), sizeof(d)-1) == 0)
155 #define fast_header_cmp(s, d, result)	(FAST_COMP_ch == (d)[0] \
156 	    && header_ncmp((s), (d), sizeof(d)-1, (result), sizeof(result)-1))
157 
158 
159 
160 /*****************************************************************************
161  *
162  * System portability definitions, header inclusions, and brokeness unbotching.
163  *
164  ****************************************************************************/
165 
166 #ifdef HAS_SETEGID
167 #define SETGID(s) setegid(s)
168 #else
169 #define SETGID(s) setgid(s)
170 #endif
171 
172 
173 #if defined(__STDC__) || defined(_AIX)
174 # define ANSI_C 1
175 #endif
176 
177 #ifndef P_
178 # ifdef ANSI_C
179 #   define P_(ARGS) ARGS
180 # else
181 #   define P_(ARGS) ()
182 #   define const
183 # endif
184 #endif
185 
186 #ifdef __alpha
187 # define int32 int
188 #else
189 # define int32 long
190 #endif
191 
192 /* avoid conflict with typedef'd word */
193 #ifdef CRAY
194 # define word wrd
195 #endif
196 
197 /*
198  *  Nice work Convex people! Thanks a million!
199  *  When STDC is used feof() is defined as a true library routine
200  *  in the header files and moreover the library routine also leaks
201  *  royally. (It returns always 1!!) Consequently this macro is
202  *  unavoidable.)
203  */
204 #ifdef	__convex__
205 # ifndef   feof
206 #   define feof(p) ((p)->_flag&_IOEOF)
207 # endif
208 #endif
209 
210 /*
211  * Ultrix's fflush returns EOF and sets error flag if the stream is read-only.
212  */
213 #if defined(ULTRIX_FFLUSH_BUG) && defined(ANSI_C)
214 # define fflush(fp) \
215 	    ((((fp)->_flag & (_IOREAD | _IORW)) == _IOREAD) ? 0 : fflush(fp))
216 #endif
217 
218 #ifdef SHORTNAMES	/* map long names to shorter ones */
219 # include <shortname.h>
220 #endif
221 
222 #ifdef ANSI_C
223   typedef void * malloc_t;
224 #else
225   typedef char * malloc_t;
226 #endif
227 
228 #ifdef I_STDLIB
229 # include <stdlib.h>
230 #else
231   extern malloc_t	malloc(), realloc(), calloc();
232   extern void		free(), exit(), _exit();
233   extern char		*getenv();
234 #endif
235 
236 #ifdef ANSI_C
237 # include <string.h>
238 #else
239 # if defined(_CONVEX_SOURCE) && defined(index)
240 #   undef _CONVEX_SOURCE
241 #   include <string.h>     /* Now there is no proto for index. */
242 #   define _CONVEX_SOURCE
243 # else
244 #   ifdef STRINGS
245 #     include <strings.h>
246 #   endif
247 # endif
248   extern char *index(), *rindex();
249   extern char *strcpy(), *strcat(), *strncpy();
250   /* following are provided by libutil.a for systems that lack them */
251   extern char *strstr(), *strtok(), *strpbrk();
252   extern int strspn(), strcspn();
253 #endif
254 
255 #ifdef MEMCPY
256 # ifndef ANSI_C
257 #   if defined(I_MEMORY)
258 #     include <memory.h>
259 #   else
260 #     if defined(__convexc__)
261         extern void *memcpy(), *memset();
262 #     else
263         extern char *memcpy(), *memset();
264 #     endif
265       extern int memcmp();
266 #   endif
267 # endif
268 # define bcopy(src, dest, len)	memcpy((dest), (src), (len))
269 # define bcmp(s1, s2, len)	memcmp((s1), (s2), (len))
270 # define bzero(s, len)		memset((s), 0, (len))
271 #endif
272 
273 /*
274  * Some of the old BSD ctype conversion macros corrupted characters.
275  * We will substitute our own versions if required.
276  */
277 #include <ctype.h>
278 #ifdef BROKE_CTYPE
279 # undef  toupper
280 # define toupper(c)	(islower(c) ? ((c) - 'a' + 'A') : (c))
281 # undef  tolower
282 # define tolower(c)	(isupper(c) ? ((c) - 'A' + 'a') : (c))
283 #endif
284 
285 #if defined(ANSI_C)
286 # include <unistd.h>
287 #else
288   char *getlogin();
289   long lseek();
290   unsigned sleep();
291 #endif
292 
293 /* things normally found in <unistd.h> */
294 #ifndef F_OK
295 # define F_OK	0
296 # define X_OK	1
297 # define W_OK	2
298 # define R_OK	4
299 #endif
300 #ifndef SEEK_SET
301 # define SEEK_SET	0
302 # define SEEK_CUR	1
303 # define SEEK_END	2
304 #endif
305 #ifndef STDIN_FILENO
306 # define STDIN_FILENO	0
307 # define STDOUT_FILENO	1
308 # define STDERR_FILENO	2
309 #endif
310 
311 /* Elm likes to use these happy names instead */
312 #define ACCESS_EXISTS	F_OK
313 #define EXECUTE_ACCESS	X_OK
314 #define WRITE_ACCESS	W_OK
315 #define READ_ACCESS	R_OK
316 #define EDIT_ACCESS	(R_OK|W_OK)
317 
318 /* <ulimit.h> is XPG3 ... but not POSIX nor ANSI */
319 extern long ulimit P_((int, ...));
320 
321 #ifdef POSIX_SIGNALS
322 # define signal posix_signal
323   extern SIGHAND_TYPE
324 	      (*posix_signal P_((int, SIGHAND_TYPE (*)(int)))) P_((int));
325 #else
326 # ifdef SIGSET
327 #   define signal sigset
328 #   ifdef _AIX
329       extern SIGHAND_TYPE (*sigset(int sig, SIGHAND_TYPE (*func)(int)))(int);
330 #   endif
331 # endif
332 #endif
333 
334 #if defined(POSIX_SIGNALS) && !defined(__386BSD__)
335 # define JMP_BUF		sigjmp_buf
336 # define SETJMP(env)		sigsetjmp((env), 1)
337 # define LONGJMP(env,val)	siglongjmp((env), (val))
338 #else
339 # define JMP_BUF		jmp_buf
340 # define SETJMP(env)		setjmp(env)
341 # define LONGJMP(env,val)	longjmp((env), (val))
342 #endif
343 
344 #ifdef I_LOCALE
345 # include <locale.h>
346 #endif
347 #ifdef I_NL_TYPES
348 # include <nl_types.h>
349 #else
350 # include "nl_types.h"
351 #endif
352 #ifndef	USENLS
353 # define MCprintf printf
354 # define MCfprintf fprintf
355 # define MCsprintf sprintf
356 #else
357 # include "mcprt.h"
358 #endif
359 
360 /* FOO - I wonder if we should be including <time.h> in this header */
361 char *ctime P_((const time_t *));
362 
363 
364 /*****************************************************************************
365  *
366  * data structures
367  *
368  ****************************************************************************/
369 
370 
371 /* defines (struct addrs) */
372 #include "parseaddrs.h"
373 
374 
375 /** "status" values for the header and alias record **/
376 
377 #define ACTION		(1<<0)
378 #define CONFIDENTIAL	(1<<1)
379 #define DELETED		(1<<2)
380 #define EXPIRED		(1<<3)
381 #define FORM_LETTER	(1<<4)
382 #define NEW		(1<<5)
383 #define PRIVATE		(1<<6)
384 #define TAGGED		(1<<7)
385 #define URGENT		(1<<8)
386 #define VISIBLE		(1<<9)
387 #define UNREAD		(1<<10)
388 #define REPLIED_TO	(1<<11)
389 #define MIME_MESSAGE	(1<<12)	/* indicates existence of MIME Header */
390 #define MIME_NEEDDECOD	(1<<13)	/* indicates that we need to call mmdecode */
391 #define MIME_NOTPLAIN	(1<<14)	/* indicates that we have a content-type,
392 				   for which we need metamail anyway. */
393 
394 /** "exit_disposition" values */
395 
396 #define UNSET		0
397 #define KEEP		1
398 #define STORE		2
399 #define DELETE		3
400 
401 struct header_rec {
402 	int  lines;		/** # of lines in the message	**/
403 	int  status;		/** Urgent, Deleted, Expired?	**/
404 	int  org_status;	/** to restore if requested     **/
405 	int  index_number;	/** relative loc in file...	**/
406 	int  encrypted;		/** whether msg has encryption	**/
407 	int  exit_disposition;	/** whether to keep, store, delete **/
408 	int  status_chgd;	/** whether became read or old, etc. **/
409 	long content_length;	/** content_length in bytes from message header	**/
410 	long offset;		/** offset in bytes of message	**/
411 	time_t received_time;	/** when elm received here	**/
412 	char from[STRING];	/** who sent the message?	**/
413 	char to[SLEN];	/** who it was sent to		**/
414 	char messageid[STRING];	/** the Message-ID: value	**/
415 	char time_zone[12];	/**                incl. tz	**/
416 	time_t time_sent;	/** gmt when sent for sorting	**/
417 	char time_menu[TLEN];	/** just the month..day for menu **/
418 	time_t tz_offset;	/** offset to gmt of time sent	**/
419 	char subject[STRING];   /** The subject of the mail	**/
420 	char mailx_status[WLEN];/** mailx status flags (RO...)	**/
421 	char allfrom[STRING];	/** The whole, unparsed From: field **/
422 	char allto[VERY_LONG_STRING];/** all to/cc fields, not just first **/
423 	long cc_index;		/** index in allto of cc fields **/
424 	struct addrs ml_to;	/** mlist parsed 'to' fields    **/
425 	long ml_cc_index;	/** index in ml_to of cc fields **/
426        };
427 
428 /** some defines for the "type" field of the alias record **/
429 
430 #define SYSTEM		(1<<0)
431 #define USER		(1<<1)
432 #define PERSON		(1<<2)
433 #define GROUP		(1<<3)
434 #define DUPLICATE	(1<<4)		/* system aliases only */
435 
436 /** some defines to aid in the limiting of alias displays **/
437 #define BY_NAME		(1<<6)
438 #define BY_ALIAS	(1<<7)
439 
440 
441 struct alias_disk_rec {
442 	int32 status;			/* DELETED, TAGGED, VISIBLE, ...     */
443 	int32 alias;			/* alias name                        */
444 	int32 last_name;		/* actual personal (last) name       */
445 	int32 name;			/* actual personal name (first last) */
446 	int32 comment;			/* comment, doesn't show in headers  */
447 	int32 address;			/* non expanded address              */
448 	int32 type;			/* mask-- sys/user, person/group     */
449 	int32 length;			/* length of alias data on file      */
450        };
451 
452 struct alias_rec {
453 	int   status;			/* DELETED, TAGGED, VISIBLE, ...     */
454 	char  *alias;			/* alias name                        */
455 	char  *last_name;		/* actual personal (last) name       */
456 	char  *name;			/* actual personal name (first last) */
457 	char  *comment;			/* comment, doesn't show in headers  */
458 	char  *address;			/* non expanded address              */
459 	int   type;			/* mask-- sys/user, person/group     */
460 	long  length;			/* length of alias data on file      */
461        };
462 
463 struct addr_rec {
464 	 char   address[NLEN];	/* machine!user you get mail as      */
465 	 struct addr_rec *next;	/* linked list pointer to next       */
466 	};
467 
468 
469 /*****************************************************************************
470  *
471  * Data common to many programs in the Elm package.
472  *
473  ****************************************************************************/
474 
475 
476 #ifdef INTERN
477 # define EXTERN
478 # define INIT(X) =X
479 #else
480 # define EXTERN extern
481 # define INIT(X)
482 #endif
483 
484 #ifdef INTERN
485 static char ident[] = WHAT_STRING;
486 static char copyright[] = "\
487 @(#)          (C) Copyright 1986,1987, Dave Taylor\n\
488 @(#)          (C) Copyright 1988-1995, The Usenet Community Trust\n";
489 #endif
490 
491 #ifdef DEBUG
492 #   define dprint(LVL, PRINTF_ARGS) \
493 	if (debug < (LVL)) ; else (fprintf PRINTF_ARGS, fflush(debugfile))
494 #else
495 #   define dprint(n,x)
496 #endif
497 
498 
499 /*
500  * The following globals are commonly used across all the programs in
501  * the Elm suite (either directly or through the library).
502  *
503  * The initialize_common() routine should be called *first thing*
504  * to set these values up.
505  *
506  * WARNING - Some of these items are overridden by the elmrc file, so
507  * Elm and the utilities may have different notions as to their proper
508  * values.  Yes, I do think this is a bug.
509  */
510 
511 EXTERN int debug;			/* debugging verbosity (0=off)	*/
512 EXTERN FILE *debugfile;   	        /* file for debut output	*/
513 EXTERN char *user_name;			/* user name, from passwd	*/
514 EXTERN char *user_home;			/* home directory, from passwd	*/
515 EXTERN char user_fullname[SLEN];	/* full username, from passwd	*/
516 EXTERN char host_name[SLEN];		/* uucp name of local machine	*/
517 EXTERN char host_domain[SLEN];		/* local domain with leading dot*/
518 EXTERN char host_fullname[SLEN];	/* local FQDN to use for mail	*/
519 EXTERN char *incoming_folder;		/* default folder ($MAIL)	*/
520 EXTERN nl_catd elm_msg_cat;		/* message catalog		*/
521 EXTERN struct addr_rec
522 	    *alternative_addresses;	/* other addrs where we get mail*/
523 
524 
525 /*****************************************************************************
526  *
527  * declarations for routines in lib/libutil.a
528  *
529  ****************************************************************************/
530 
531 #include "elm_lib.h"
532 
533