X-Git-Url: https://diplodocus.org/git/nmh/blobdiff_plain/03fe41ba1d68108808c966c6d7ff74bd8c1d648c..eda0cc87eedfbbe5a15a91a59489e31f69e30998:/h/mh.h?ds=sidebyside diff --git a/h/mh.h b/h/mh.h index e3a382a3..67b71702 100644 --- a/h/mh.h +++ b/h/mh.h @@ -1,4 +1,3 @@ - /* * mh.h -- main header file for all of nmh */ @@ -19,11 +18,17 @@ #define DMAXFOLDER 4 /* typical number of digits */ #define MAXFOLDER 1000 /* message increment */ +/* + * This macro is for use by scan, for example, so that platforms with + * a small BUFSIZ can easily allocate larger buffers. + */ +#define NMH_BUFSIZ (BUFSIZ>=8192 ? BUFSIZ : 8192) + #ifndef FALSE -#define FALSE 0 +#define FALSE false #endif #ifndef TRUE -#define TRUE 1 +#define TRUE true #endif typedef unsigned char boolean; /* not int so we can pack in a structure */ @@ -32,10 +37,48 @@ typedef unsigned char boolean; /* not int so we can pack in a structure */ */ #if __GNUC__ > 2 #define NORETURN __attribute__((__noreturn__)) +#define NMH_UNUSED(i) (void) i #else #define NORETURN +#define NMH_UNUSED(i) i #endif +/* DIM gives the number of elements in the one-dimensional array a. */ +#define DIM(a) (sizeof (a) / sizeof (*(a))) + +/* LEN gives the strlen() of string constant s, excluding the + * terminating NUL. */ +#define LEN(s) (sizeof (s) - 1) + +/* + * char array that keeps track of size in both bytes and characters + * Usage note: + * Don't store return value of charstring_buffer() and use later + * after intervening push_back's; use charstring_buffer_copy() + * instead. + */ +typedef struct charstring *charstring_t; + +charstring_t charstring_create (size_t); +charstring_t charstring_copy (const charstring_t); +void charstring_free (charstring_t); +/* Append a single-byte character: */ +void charstring_push_back (charstring_t, const char); +/* Append possibly multi-byte character(s): */ +void charstring_push_back_chars (charstring_t, const char [], size_t, size_t); +void charstring_append (charstring_t, const charstring_t); +void charstring_append_cstring (charstring_t, const char []); +void charstring_clear (charstring_t); +/* Don't store return value of charstring_buffer() and use later after + intervening push_back's; use charstring_buffer_copy() instead. */ +const char *charstring_buffer (const charstring_t); +/* User is responsible for free'ing result of buffer copy. */ +char *charstring_buffer_copy (const charstring_t); +size_t charstring_bytes (const charstring_t); +size_t charstring_chars (const charstring_t); +/* Length of the last character in the charstring. */ +int charstring_last_char_len (const charstring_t); + /* * user context/profile structure */ @@ -53,6 +96,11 @@ struct node { #define UNKWNSW (-1) /* from smatch() on unknown switch */ struct swit { + + /* + * Switch name + */ + char *sw; /* The minchars field is apparently used like this: @@ -61,35 +109,71 @@ struct swit { 0 : Switch can't be abbreviated; switch shown in -help. # : Switch can be abbreviated to # characters; switch shown in -help. */ int minchars; + + /* + * If we pick this switch, return this value from smatch + */ + + int swret; }; -extern struct swit anoyes[]; /* standard yes/no switches */ +/* + * Macros to use when declaring struct swit arrays. + * + * These macros use a technique known as X-Macros. In your source code you + * use them like this: + * + * #define FOO_SWITCHES \ + * X("switch1", 0, SWITCHSW) \ + * X("switch2", 0, SWITCH2SW) \ + * X("thirdswitch", 2, SWITCH3SW) \ + * + * The argument to each entry in FOO_SWITCHES are the switch name (sw), + * the minchars field (see above) and the return value for this switch. + * Note that the last entry in the above definition must either omit the + * continuation backslash, or be followed by a blank line. In the nmh + * code the style is to have every line include a backslash and follow + * the SWITCHES macro definition by a blank line. + * + * After you define FOO_SWITCHES, you instantiate it as follows: + * + * #define X(sw, minchars, id) id, + * DEFINE_SWITCH_ENUM(FOO); + * #undef X + * + * #define X(sw, minchars, id) { sw, minchars, id }, + * DEFINE_SWITCH_ARRAY(FOO); + * #undef X + * + * DEFINE_SWITCH_ENUM defines an extra enum at the end of the list called + * LEN_FOO. + */ + +#define DEFINE_SWITCH_ENUM(name) \ + enum { \ + name ## _SWITCHES \ + LEN_ ## name \ + } + +#define DEFINE_SWITCH_ARRAY(name, array) \ + static struct swit array[] = { \ + name ## _SWITCHES \ + { NULL, 0, 0 } \ + } -#define ATTACHFORMATS 3 /* Number of send attach formats. */ +extern struct swit anoyes[]; /* standard yes/no switches */ /* * general folder attributes */ #define READONLY (1<<0) /* No write access to folder */ -#define SEQMOD (1<<1) /* folder's sequences modifed */ +#define SEQMOD (1<<1) /* folder's sequences modified */ #define ALLOW_NEW (1<<2) /* allow the "new" sequence */ #define OTHERS (1<<3) /* folder has other files */ #define MODIFIED (1<<4) /* msh in-core folder modified */ #define FBITS "\020\01READONLY\02SEQMOD\03ALLOW_NEW\04OTHERS\05MODIFIED" -/* - * type for holding the sequence set of a message - */ -typedef unsigned int seqset_t; - -/* - * Determine the number of user defined sequences we - * can have. The first 5 sequence flags are for - * internal nmh message flags. - */ -#define NUMATTRS ((sizeof(seqset_t) * Nbby) - 5) - /* * first free slot for user defined sequences * and attributes @@ -99,14 +183,48 @@ typedef unsigned int seqset_t; /* * internal messages attributes (sequences) */ -#define EXISTS (1<<0) /* exists */ -#define DELETED (1<<1) /* deleted */ -#define SELECTED (1<<2) /* selected for use */ -#define SELECT_EMPTY (1<<3) /* "new" message */ -#define SELECT_UNSEEN (1<<4) /* inc/show "unseen" */ +#define EXISTS (0) /* exists */ +#define DELETED (1) /* deleted */ +#define SELECTED (2) /* selected for use */ +#define SELECT_EMPTY (3) /* "new" message */ +#define SELECT_UNSEEN (4) /* inc/show "unseen" */ #define MBITS "\020\01EXISTS\02DELETED\03SELECTED\04NEW\05UNSEEN" +/* + * type for holding the sequence set of a message + */ +typedef struct bvector *bvector_t; + +bvector_t bvector_create (size_t /* initial size in bits, can be 0 */); +void bvector_copy (bvector_t, bvector_t); +void bvector_free (bvector_t); +void bvector_clear (bvector_t, size_t); +void bvector_clear_all (bvector_t); +void bvector_set (bvector_t, size_t); +unsigned int bvector_at (bvector_t, size_t); +const unsigned long *bvector_bits (bvector_t); +size_t bvector_maxsize (bvector_t); + +typedef struct svector *svector_t; + +svector_t svector_create (size_t); +void svector_free (svector_t); +char *svector_push_back (svector_t, char *); +char *svector_at (svector_t, size_t); +char **svector_find(svector_t, const char *); +char **svector_strs (svector_t); +size_t svector_size (svector_t); + +typedef struct ivector *ivector_t; + +ivector_t ivector_create (size_t); +void ivector_free (ivector_t); +int ivector_push_back (ivector_t, int); +int ivector_at (ivector_t, size_t); +int *ivector_atp (ivector_t, size_t); +size_t ivector_size (ivector_t); + /* * Primary structure of folder/message information */ @@ -125,16 +243,15 @@ struct msgs { char *foldpath; /* Pathname of folder */ /* - * Name of sequences in this folder. We add an - * extra slot, so we can NULL terminate the list. + * Name of sequences in this folder. */ - char *msgattrs[NUMATTRS + 1]; + svector_t msgattrs; /* * bit flags for whether sequence * is public (0), or private (1) */ - seqset_t attrstats; + bvector_t attrstats; /* * These represent the lowest and highest possible @@ -145,64 +262,83 @@ struct msgs { int hghoff; /* - * This is an array of seqset_t which we allocate dynamically. - * Each seqset_t is a set of bits flags for a particular message. + * This is an array of bvector_t which we allocate dynamically. + * Each bvector_t is a set of bits flags for a particular message. * These bit flags represent general attributes such as * EXISTS, SELECTED, etc. as well as track if message is * in a particular sequence. */ - seqset_t *msgstats; /* msg status */ + size_t num_msgstats; + bvector_t *msgstats; /* msg status */ + + /* + * A FILE handle containing an open filehandle for the sequence file + * for this folder. If non-NULL, use it when the sequence file is + * written. + */ + FILE *seqhandle; + + /* + * The name of the public sequence file; required by lkfclose() + */ + char *seqname; }; /* * Amount of space to allocate for msgstats. Allocate - * the array to have space for messages numbers lo to hi. + * the array to have space for messages numbered lo to hi. + * Use MSGSTATNUM to load mp->num_msgstats first. */ -#define MSGSTATSIZE(mp,lo,hi) ((size_t) (((hi) - (lo) + 1) * sizeof(*(mp)->msgstats))) +#define MSGSTATNUM(lo, hi) ((size_t) ((hi) - (lo) + 1)) +#define MSGSTATSIZE(mp) ((mp)->num_msgstats * sizeof *(mp)->msgstats) /* * macros for message and sequence manipulation */ -#define clear_msg_flags(mp,msgnum) ((mp)->msgstats[(msgnum) - mp->lowoff] = 0) -#define copy_msg_flags(mp,i,j) \ - ((mp)->msgstats[(i) - mp->lowoff] = (mp)->msgstats[(j) - mp->lowoff]) -#define get_msg_flags(mp,ptr,msgnum) (*(ptr) = (mp)->msgstats[(msgnum) - mp->lowoff]) -#define set_msg_flags(mp,ptr,msgnum) ((mp)->msgstats[(msgnum) - mp->lowoff] = *(ptr)) - -#define does_exist(mp,msgnum) ((mp)->msgstats[(msgnum) - mp->lowoff] & EXISTS) -#define unset_exists(mp,msgnum) ((mp)->msgstats[(msgnum) - mp->lowoff] &= ~EXISTS) -#define set_exists(mp,msgnum) ((mp)->msgstats[(msgnum) - mp->lowoff] |= EXISTS) - -#define is_selected(mp,msgnum) ((mp)->msgstats[(msgnum) - mp->lowoff] & SELECTED) -#define unset_selected(mp,msgnum) ((mp)->msgstats[(msgnum) - mp->lowoff] &= ~SELECTED) -#define set_selected(mp,msgnum) ((mp)->msgstats[(msgnum) - mp->lowoff] |= SELECTED) - -#define is_select_empty(mp,msgnum) ((mp)->msgstats[(msgnum) - mp->lowoff] & SELECT_EMPTY) +#define msgstat(mp,n) (mp)->msgstats[(n) - mp->lowoff] +#define clear_msg_flags(mp,msgnum) bvector_clear_all (msgstat(mp, msgnum)) +#define copy_msg_flags(mp,i,j) bvector_copy (msgstat(mp,i), msgstat(mp,j)) +#define get_msg_flags(mp,ptr,msgnum) bvector_copy (ptr, msgstat(mp, msgnum)) +#define set_msg_flags(mp,ptr,msgnum) bvector_copy (msgstat(mp, msgnum), ptr) + +#define does_exist(mp,msgnum) bvector_at (msgstat(mp, msgnum), EXISTS) +#define unset_exists(mp,msgnum) bvector_clear (msgstat(mp, msgnum), EXISTS) +#define set_exists(mp,msgnum) bvector_set (msgstat(mp, msgnum), EXISTS) + +#define is_selected(mp,msgnum) bvector_at (msgstat(mp, msgnum), SELECTED) +#define unset_selected(mp,msgnum) bvector_clear (msgstat(mp, msgnum), SELECTED) +#define set_selected(mp,msgnum) bvector_set (msgstat(mp, msgnum), SELECTED) + +#define is_select_empty(mp,msgnum) \ + bvector_at (msgstat(mp, msgnum), SELECT_EMPTY) #define set_select_empty(mp,msgnum) \ - ((mp)->msgstats[(msgnum) - mp->lowoff] |= SELECT_EMPTY) + bvector_set (msgstat(mp, msgnum), SELECT_EMPTY) -#define is_unseen(mp,msgnum) ((mp)->msgstats[(msgnum) - mp->lowoff] & SELECT_UNSEEN) -#define unset_unseen(mp,msgnum) ((mp)->msgstats[(msgnum) - mp->lowoff] &= ~SELECT_UNSEEN) -#define set_unseen(mp,msgnum) ((mp)->msgstats[(msgnum) - mp->lowoff] |= SELECT_UNSEEN) +#define is_unseen(mp,msgnum) \ + bvector_at (msgstat(mp, msgnum), SELECT_UNSEEN) +#define unset_unseen(mp,msgnum) \ + bvector_clear (msgstat(mp, msgnum), SELECT_UNSEEN) +#define set_unseen(mp,msgnum) \ + bvector_set (msgstat(mp, msgnum), SELECT_UNSEEN) /* for msh only */ -#define set_deleted(mp,msgnum) ((mp)->msgstats[(msgnum) - mp->lowoff] |= DELETED) +#define set_deleted(mp,msgnum) bvector_set (msgstat(mp, msgnum), DELETED) #define in_sequence(mp,seqnum,msgnum) \ - ((mp)->msgstats[(msgnum) - mp->lowoff] & (1 << (FFATTRSLOT + seqnum))) + bvector_at (msgstat(mp, msgnum), FFATTRSLOT + seqnum) #define clear_sequence(mp,seqnum,msgnum) \ - ((mp)->msgstats[(msgnum) - mp->lowoff] &= ~(1 << (FFATTRSLOT + seqnum))) + bvector_clear (msgstat(mp, msgnum), FFATTRSLOT + seqnum) #define add_sequence(mp,seqnum,msgnum) \ - ((mp)->msgstats[(msgnum) - mp->lowoff] |= (1 << (FFATTRSLOT + seqnum))) + bvector_set (msgstat(mp, msgnum), FFATTRSLOT + seqnum) #define is_seq_private(mp,seqnum) \ - ((mp)->attrstats & (1 << (FFATTRSLOT + seqnum))) + bvector_at (mp->attrstats, FFATTRSLOT + seqnum) #define make_seq_public(mp,seqnum) \ - ((mp)->attrstats &= ~(1 << (FFATTRSLOT + seqnum))) + bvector_clear (mp->attrstats, FFATTRSLOT + seqnum) #define make_seq_private(mp,seqnum) \ - ((mp)->attrstats |= (1 << (FFATTRSLOT + seqnum))) + bvector_set (mp->attrstats, FFATTRSLOT + seqnum) #define make_all_public(mp) \ - ((mp)->attrstats = 0) + mp->attrstats = bvector_create(0); bvector_clear_all (mp->attrstats) /* * macros for folder attributes @@ -235,11 +371,12 @@ struct msgs { #define FMTERR (-3) /* Message Format error */ #define FLD 0 /* Field returned */ #define FLDPLUS 1 /* Field returned with more to come */ -#define FLDEOF 2 /* Field returned ending at eom */ #define BODY 3 /* Body returned with more to come */ -#define BODYEOF 4 /* Body returned ending at eom */ #define FILEEOF 5 /* Reached end of input file */ +struct m_getfld_state; +typedef struct m_getfld_state *m_getfld_state_t; + /* * Maildrop styles */ @@ -247,11 +384,6 @@ struct msgs { #define MS_UNKNOWN 1 /* type not known yet */ #define MS_MBOX 2 /* Unix-style "from" lines */ #define MS_MMDF 3 /* string mmdlm2 */ -#define MS_MSH 4 /* whacko msh */ - -extern int msg_count; /* m_getfld() indicators */ -extern int msg_style; /* .. */ -extern char *msg_delim; /* .. */ #define NOUSE 0 /* draft being re-used */ @@ -264,6 +396,12 @@ extern char *msg_delim; /* .. */ #define LINK "@" /* Name of link to file to which you are */ /* replying. */ +/* + * credentials management + */ +struct nmh_creds; +typedef struct nmh_creds *nmh_creds_t; + /* * miscellaneous macros */ @@ -294,6 +432,13 @@ extern char *defpath; /* pathname of user's profile */ extern char *ctxpath; /* pathname of user's context */ extern struct node *m_defs; /* list of profile/context entries */ +/* What style to use for generated Message-ID and Content-ID header + fields. The localname style is pid.time@localname, where time is + in seconds. The random style replaces the localname with some + (pseudo)random bytes and uses microsecond-resolution time. */ +int save_message_id_style (const char *); +char *message_id (time_t, int); + /* * These standard strings are defined in config.c. They are the * only system-dependent parameters in nmh, and thus by redefining @@ -305,18 +450,18 @@ extern char *catproc; extern char *components; extern char *context; extern char *current; -extern char *defaulteditor; +extern char *credentials_file; +extern int credentials_no_perm_check; extern char *defaultfolder; extern char *digestcomps; extern char *distcomps; extern char *draft; -extern char *faceproc; extern char *fileproc; extern char *foldprot; +extern char *formatproc; extern char *forwcomps; extern char *inbox; extern char *incproc; -extern char *installproc; extern char *lproc; extern char *mailproc; extern char *mh_defaults; @@ -328,8 +473,8 @@ extern char *mhlproc; extern char *mhlreply; extern char *moreproc; extern char *msgprot; -extern char *mshproc; extern char *nmhaccessftp; +extern char *nmhaccessurl; extern char *nmhstorage; extern char *nmhcache; extern char *nmhprivcache; @@ -342,15 +487,14 @@ extern char *rcvdistcomps; extern char *rcvstoreproc; extern char *replcomps; extern char *replgroupcomps; -extern char *rmfproc; extern char *rmmproc; extern char *sendproc; extern char *showmimeproc; extern char *showproc; extern char *usequence; +extern char *user_agent; extern char *version_num; extern char *version_str; -extern char *vmhproc; extern char *whatnowproc; extern char *whomproc;