1 /* mh.h -- main header file for all of nmh 2 */ 3 4 #include <h/nmh.h> 5 6 /* 7 * Well-used constants 8 */ 9 #define NOTOK (-1) /* syscall()s return this on error */ 10 #define OK 0 /* ditto on success */ 11 #define DONE 1 /* ternary logic */ 12 #define ALL "" 13 14 #define MAXARGS 1000 /* max arguments to exec */ 15 #define NFOLDERS 1000 /* max folder arguments on command line */ 16 #define DMAXFOLDER 4 /* typical number of digits */ 17 #define MAXFOLDER 1000 /* message increment */ 18 19 /* 20 * This macro is for use by scan, for example, so that platforms with 21 * a small BUFSIZ can easily allocate larger buffers. 22 */ 23 #define NMH_BUFSIZ max(BUFSIZ, 8192) 24 25 #ifndef FALSE 26 #define FALSE false 27 #endif 28 #ifndef TRUE 29 #define TRUE true 30 #endif 31 typedef unsigned char boolean; /* not int so we can pack in a structure */ 32 33 /* If we're using gcc then give it some information about 34 * functions that abort. 35 */ 36 #if __GNUC__ > 2 37 #define NORETURN __attribute__((__noreturn__)) 38 #define NMH_UNUSED(i) (void) i 39 #else 40 #define NORETURN 41 #define NMH_UNUSED(i) i 42 #endif 43 44 /* DIM gives the number of elements in the one-dimensional array a. */ 45 #define DIM(a) (sizeof (a) / sizeof (*(a))) 46 47 /* LEN gives the strlen() of string constant s, excluding the 48 * terminating NUL. */ 49 #define LEN(s) (sizeof (s) - 1) 50 51 /* FENDNULL fends off NULL by giving an empty string instead. */ 52 #define FENDNULL(s) ((s) ? (s) : "") 53 54 /* 55 * char array that keeps track of size in both bytes and characters 56 * Usage note: 57 * Don't store return value of charstring_buffer() and use later 58 * after intervening push_back's; use charstring_buffer_copy() 59 * instead. 60 */ 61 typedef struct charstring *charstring_t; 62 63 charstring_t charstring_create (size_t); 64 charstring_t charstring_copy (const charstring_t); 65 void charstring_free (charstring_t); 66 /* Append a single-byte character: */ 67 void charstring_push_back (charstring_t, const char); 68 /* Append possibly multi-byte character(s): */ 69 void charstring_push_back_chars (charstring_t, const char [], size_t, size_t); 70 void charstring_append (charstring_t, const charstring_t); 71 void charstring_append_cstring (charstring_t, const char []); 72 void charstring_clear (charstring_t); 73 /* Don't store return value of charstring_buffer() and use later after 74 intervening push_back's; use charstring_buffer_copy() instead. */ 75 const char *charstring_buffer (const charstring_t); 76 /* User is responsible for free'ing result of buffer copy. */ 77 char *charstring_buffer_copy (const charstring_t); 78 size_t charstring_bytes (const charstring_t); 79 size_t charstring_chars (const charstring_t); 80 /* Length of the last character in the charstring. */ 81 int charstring_last_char_len (const charstring_t); 82 83 /* 84 * user context/profile structure 85 */ 86 struct node { 87 char *n_name; /* key */ 88 char *n_field; /* value */ 89 char n_context; /* context, not profile */ 90 struct node *n_next; /* next entry */ 91 }; 92 93 /* 94 * switches structure 95 */ 96 #define AMBIGSW (-2) /* from smatch() on ambiguous switch */ 97 #define UNKWNSW (-1) /* from smatch() on unknown switch */ 98 99 struct swit { 100 101 /* 102 * Switch name 103 */ 104 105 char *sw; 106 107 /* The minchars field is apparently used like this: 108 109 -# : Switch can be abbreviated to # characters; switch hidden in -help. 110 0 : Switch can't be abbreviated; switch shown in -help. 111 # : Switch can be abbreviated to # characters; switch shown in -help. */ 112 int minchars; 113 114 /* 115 * If we pick this switch, return this value from smatch 116 */ 117 118 int swret; 119 }; 120 121 /* 122 * Macros to use when declaring struct swit arrays. 123 * 124 * These macros use a technique known as X-Macros. In your source code you 125 * use them like this: 126 * 127 * #define FOO_SWITCHES \ 128 * X("switch1", 0, SWITCHSW) \ 129 * X("switch2", 0, SWITCH2SW) \ 130 * X("thirdswitch", 2, SWITCH3SW) \ 131 * 132 * The argument to each entry in FOO_SWITCHES are the switch name (sw), 133 * the minchars field (see above) and the return value for this switch. 134 * Note that the last entry in the above definition must either omit the 135 * continuation backslash, or be followed by a blank line. In the nmh 136 * code the style is to have every line include a backslash and follow 137 * the SWITCHES macro definition by a blank line. 138 * 139 * After you define FOO_SWITCHES, you instantiate it as follows: 140 * 141 * #define X(sw, minchars, id) id, 142 * DEFINE_SWITCH_ENUM(FOO); 143 * #undef X 144 * 145 * #define X(sw, minchars, id) { sw, minchars, id }, 146 * DEFINE_SWITCH_ARRAY(FOO); 147 * #undef X 148 * 149 * DEFINE_SWITCH_ENUM defines an extra enum at the end of the list called 150 * LEN_FOO. 151 */ 152 153 #define DEFINE_SWITCH_ENUM(name) \ 154 enum { \ 155 name ## _SWITCHES \ 156 LEN_ ## name \ 157 } 158 159 #define DEFINE_SWITCH_ARRAY(name, array) \ 160 static struct swit array[] = { \ 161 name ## _SWITCHES \ 162 { NULL, 0, 0 } \ 163 } 164 165 extern struct swit anoyes[]; /* standard yes/no switches */ 166 167 /* 168 * general folder attributes 169 */ 170 #define READONLY (1<<0) /* No write access to folder */ 171 #define SEQMOD (1<<1) /* folder's sequences modified */ 172 #define ALLOW_NEW (1<<2) /* allow the "new" sequence */ 173 #define OTHERS (1<<3) /* folder has other files */ 174 175 #define FBITS "\020\01READONLY\02SEQMOD\03ALLOW_NEW\04OTHERS" 176 177 /* 178 * first free slot for user defined sequences 179 * and attributes 180 */ 181 #define FFATTRSLOT 4 182 183 /* 184 * internal messages attributes (sequences) 185 */ 186 #define EXISTS (0) /* exists */ 187 #define SELECTED (1) /* selected for use */ 188 #define SELECT_EMPTY (2) /* "new" message */ 189 #define SELECT_UNSEEN (3) /* inc/show "unseen" */ 190 191 #define MBITS "\020\01EXISTS\02SELECTED\03NEW\04UNSEEN" 192 193 /* A vector of bits for tracking the sequence membership of a single 194 * message. Do not access the struct members; use vector.c. 195 * Do not move or copy this struct as it may contain a pointer to 196 * itself; use bvector_copy(). */ 197 struct bvector { 198 unsigned long *bits; 199 size_t maxsize; 200 unsigned long tiny[2]; /* Default fixed-size storage for bits. */ 201 }; 202 typedef struct bvector *bvector_t; 203 204 bvector_t bvector_create (void); 205 void bvector_init(struct bvector *bv); 206 void bvector_copy (bvector_t, bvector_t); 207 void bvector_free (bvector_t); 208 void bvector_fini(struct bvector *bv); 209 void bvector_clear (bvector_t, size_t); 210 void bvector_clear_all (bvector_t); 211 void bvector_set (bvector_t, size_t); 212 unsigned int bvector_at (bvector_t, size_t); 213 unsigned long bvector_first_bits (bvector_t); 214 215 typedef struct svector *svector_t; 216 217 svector_t svector_create (size_t); 218 void svector_free (svector_t); 219 char *svector_push_back (svector_t, char *); 220 char *svector_at (svector_t, size_t); 221 char **svector_find(svector_t, const char *); 222 char **svector_strs (svector_t); 223 size_t svector_size (svector_t); 224 225 typedef struct ivector *ivector_t; 226 227 ivector_t ivector_create (size_t); 228 void ivector_free (ivector_t); 229 int ivector_push_back (ivector_t, int); 230 int ivector_at (ivector_t, size_t); 231 int *ivector_atp (ivector_t, size_t); 232 233 /* 234 * Primary structure of folder/message information 235 */ 236 struct msgs { 237 int lowmsg; /* Lowest msg number */ 238 int hghmsg; /* Highest msg number */ 239 int nummsg; /* Actual Number of msgs */ 240 241 int lowsel; /* Lowest selected msg number */ 242 int hghsel; /* Highest selected msg number */ 243 int numsel; /* Number of msgs selected */ 244 245 int curmsg; /* Number of current msg if any */ 246 247 int msgflags; /* Folder attributes (READONLY, etc) */ 248 char *foldpath; /* Pathname of folder */ 249 250 /* 251 * Name of sequences in this folder. 252 */ 253 svector_t msgattrs; 254 255 /* 256 * bit flags for whether sequence 257 * is public (0), or private (1) 258 */ 259 bvector_t attrstats; 260 261 /* 262 * These represent the lowest and highest possible 263 * message numbers we can put in the message status 264 * area, without calling folder_realloc(). 265 */ 266 int lowoff; 267 int hghoff; 268 269 /* 270 * This is an array of bvector_t which we allocate dynamically. 271 * Each bvector_t is a set of bits flags for a particular message. 272 * These bit flags represent general attributes such as 273 * EXISTS, SELECTED, etc. as well as track if message is 274 * in a particular sequence. 275 */ 276 size_t num_msgstats; 277 struct bvector *msgstats; /* msg status */ 278 279 /* 280 * A FILE handle containing an open filehandle for the sequence file 281 * for this folder. If non-NULL, use it when the sequence file is 282 * written. 283 */ 284 FILE *seqhandle; 285 286 /* 287 * The name of the public sequence file; required by lkfclose() 288 */ 289 char *seqname; 290 }; 291 292 /* 293 * Amount of space to allocate for msgstats. Allocate 294 * the array to have space for messages numbered lo to hi. 295 * Use MSGSTATNUM to load mp->num_msgstats first. 296 */ 297 #define MSGSTATNUM(lo, hi) ((size_t) ((hi) - (lo) + 1)) 298 #define MSGSTATSIZE(mp) ((mp)->num_msgstats * sizeof *(mp)->msgstats) 299 300 /* 301 * macros for message and sequence manipulation 302 */ 303 #define msgstat(mp,n) ((mp)->msgstats + (n) - mp->lowoff) 304 #define clear_msg_flags(mp,msgnum) bvector_clear_all (msgstat(mp, msgnum)) 305 #define copy_msg_flags(mp,i,j) bvector_copy (msgstat(mp,i), msgstat(mp,j)) 306 #define get_msg_flags(mp,ptr,msgnum) bvector_copy (ptr, msgstat(mp, msgnum)) 307 #define set_msg_flags(mp,ptr,msgnum) bvector_copy (msgstat(mp, msgnum), ptr) 308 309 #define does_exist(mp,msgnum) bvector_at (msgstat(mp, msgnum), EXISTS) 310 #define unset_exists(mp,msgnum) bvector_clear (msgstat(mp, msgnum), EXISTS) 311 #define set_exists(mp,msgnum) bvector_set (msgstat(mp, msgnum), EXISTS) 312 313 #define is_selected(mp,msgnum) bvector_at (msgstat(mp, msgnum), SELECTED) 314 #define unset_selected(mp,msgnum) bvector_clear (msgstat(mp, msgnum), SELECTED) 315 #define set_selected(mp,msgnum) bvector_set (msgstat(mp, msgnum), SELECTED) 316 317 #define is_select_empty(mp,msgnum) \ 318 bvector_at (msgstat(mp, msgnum), SELECT_EMPTY) 319 #define set_select_empty(mp,msgnum) \ 320 bvector_set (msgstat(mp, msgnum), SELECT_EMPTY) 321 322 #define is_unseen(mp,msgnum) \ 323 bvector_at (msgstat(mp, msgnum), SELECT_UNSEEN) 324 #define unset_unseen(mp,msgnum) \ 325 bvector_clear (msgstat(mp, msgnum), SELECT_UNSEEN) 326 #define set_unseen(mp,msgnum) \ 327 bvector_set (msgstat(mp, msgnum), SELECT_UNSEEN) 328 329 #define in_sequence(mp,seqnum,msgnum) \ 330 bvector_at (msgstat(mp, msgnum), FFATTRSLOT + seqnum) 331 #define clear_sequence(mp,seqnum,msgnum) \ 332 bvector_clear (msgstat(mp, msgnum), FFATTRSLOT + seqnum) 333 #define add_sequence(mp,seqnum,msgnum) \ 334 bvector_set (msgstat(mp, msgnum), FFATTRSLOT + seqnum) 335 336 #define is_seq_private(mp,seqnum) \ 337 bvector_at (mp->attrstats, FFATTRSLOT + seqnum) 338 #define make_seq_public(mp,seqnum) \ 339 bvector_clear (mp->attrstats, FFATTRSLOT + seqnum) 340 #define make_seq_private(mp,seqnum) \ 341 bvector_set (mp->attrstats, FFATTRSLOT + seqnum) 342 #define make_all_public(mp) \ 343 mp->attrstats = bvector_create(); bvector_clear_all (mp->attrstats) 344 345 /* 346 * macros for folder attributes 347 */ 348 #define clear_folder_flags(mp) ((mp)->msgflags = 0) 349 350 #define is_readonly(mp) ((mp)->msgflags & READONLY) 351 #define set_readonly(mp) ((mp)->msgflags |= READONLY) 352 353 #define other_files(mp) ((mp)->msgflags & OTHERS) 354 #define set_other_files(mp) ((mp)->msgflags |= OTHERS) 355 356 /* 357 * m_getfld() message parsing 358 */ 359 360 #define NAMESZ 999 /* Limit on component name size. 361 RFC 2822 limits line lengths to 362 998 characters, so a header name 363 can be at most that long. 364 m_getfld limits header names to 2 365 less than NAMESZ, which is fine, 366 because header names must be 367 followed by a colon. Add one for 368 terminating NULL. */ 369 370 #define LENERR (-2) /* Name too long error from getfld */ 371 #define FMTERR (-3) /* Message Format error */ 372 #define FLD 0 /* Field returned */ 373 #define FLDPLUS 1 /* Field returned with more to come */ 374 #define BODY 3 /* Body returned with more to come */ 375 #define FILEEOF 5 /* Reached end of input file */ 376 377 typedef struct m_getfld_state *m_getfld_state_t; 378 379 #define NOUSE 0 /* draft being re-used */ 380 381 #define TFOLDER 0 /* path() given a +folder */ 382 #define TFILE 1 /* path() given a file */ 383 #define TSUBCWF 2 /* path() given a @folder */ 384 385 #define OUTPUTLINELEN 72 /* default line length for headers */ 386 387 #define LINK "@" /* Name of link to file to which you are */ 388 /* replying. */ 389 390 /* 391 * credentials management 392 */ 393 typedef struct nmh_creds *nmh_creds_t; 394 395 /* 396 * miscellaneous macros 397 */ 398 #define pidXwait(pid,cp) pidstatus (pidwait (pid, NOTOK), stdout, cp) 399 400 #ifndef max 401 # define max(a,b) ((a) > (b) ? (a) : (b)) 402 #endif 403 404 #ifndef min 405 # define min(a,b) ((a) < (b) ? (a) : (b)) 406 #endif 407 408 #ifndef abs 409 # define abs(a) ((a) > 0 ? (a) : -(a)) 410 #endif 411 412 /* 413 * GLOBAL VARIABLES 414 */ 415 #define CTXMOD 0x01 /* context information modified */ 416 #define DBITS "\020\01CTXMOD" 417 extern char ctxflags; 418 419 extern char *invo_name; /* command invocation name */ 420 extern char *mypath; /* user's $HOME */ 421 extern char *defpath; /* pathname of user's profile */ 422 extern char *ctxpath; /* pathname of user's context */ 423 extern struct node *m_defs; /* list of profile/context entries */ 424 425 /* 426 * These standard strings are defined in config.c. They are the 427 * only system-dependent parameters in nmh, and thus by redefining 428 * their values and reloading the various modules, nmh will run 429 * on any system. 430 */ 431 extern char *buildmimeproc; 432 extern char *catproc; 433 extern char *components; 434 extern char *context; 435 extern char *current; 436 extern char *credentials_file; 437 extern int credentials_no_perm_check; 438 extern char *defaultfolder; 439 extern char *digestcomps; 440 extern char *distcomps; 441 extern char *draft; 442 extern char *fileproc; 443 extern char *foldprot; 444 extern char *formatproc; 445 extern char *forwcomps; 446 extern char *inbox; 447 extern char *incproc; 448 extern char *lproc; 449 extern char *mailproc; 450 extern char *mh_defaults; 451 extern char *mh_profile; 452 extern char *mh_seq; 453 extern char *mhlformat; 454 extern char *mhlforward; 455 extern char *mhlproc; 456 extern char *mhlreply; 457 extern char *moreproc; 458 extern char *msgprot; 459 extern char *nmhaccessftp; 460 extern char *nmhaccessurl; 461 extern char *nmhstorage; 462 extern char *nmhcache; 463 extern char *nmhprivcache; 464 extern char *nsequence; 465 extern char *packproc; 466 extern char *postproc; 467 extern char *pfolder; 468 extern char *psequence; 469 extern char *rcvdistcomps; 470 extern char *rcvstoreproc; 471 extern char *replcomps; 472 extern char *replgroupcomps; 473 extern char *rmmproc; 474 extern char *sendproc; 475 extern char *showmimeproc; 476 extern char *showproc; 477 extern char *usequence; 478 extern char *user_agent; 479 extern char *version_num; 480 extern char *version_str; 481 extern char *whatnowproc; 482 extern char *whomproc; 483 484 extern void (*done) (int) NORETURN; 485 486 #include <h/prototypes.h> 487