1 /* GNU Mailutils -- a suite of utilities for electronic mail
2    Copyright (C) 1999-2021 Free Software Foundation, Inc.
3 
4    This library is free software; you can redistribute it and/or
5    modify it under the terms of the GNU Lesser General Public
6    License as published by the Free Software Foundation; either
7    version 3 of the License, or (at your option) any later version.
8 
9    This library is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12    Lesser General Public License for more details.
13 
14    You should have received a copy of the GNU Lesser General
15    Public License along with this library.  If not, see
16    <http://www.gnu.org/licenses/>. */
17 
18 #ifndef _MAILUTILS_SYS_AMD_H
19 # define _MAILUTILS_SYS_AMD_H
20 # define MAX_OPEN_STREAMS 16
21 
22 /* Notifications ADD_MESG. */
23 # define DISPATCH_ADD_MSG(mbox,mhd,n)					\
24   do									\
25     {									\
26       int bailing = 0;							\
27       mu_monitor_unlock (mbox->monitor);				\
28       if (mbox->observable)						\
29 	{								\
30 	  size_t tmp = n;						\
31 	  bailing = mu_observable_notify (mbox->observable,		\
32 					  MU_EVT_MESSAGE_ADD,		\
33 					  &tmp);			\
34 	}								\
35       if (bailing != 0)							\
36 	{								\
37 	  if (pcount)							\
38 	    *pcount = (mhd)->msg_count;					\
39 	  mu_locker_unlock (mbox->locker);				\
40 	  return EINTR;							\
41 	}								\
42       mu_monitor_wrlock (mbox->monitor);				\
43 } while (0);
44 
45 #define _MU_AMD_PROP_UIDVALIDITY "uid-validity"
46 #define _MU_AMD_PROP_UIDNEXT "uidnext"
47 #define _MU_AMD_PROP_SIZE "size"
48 
49 #define _MU_AMD_PROP_FILE_NAME ".mu-prop"
50 
51 struct _amd_data;
52 struct _amd_message
53 {
54   mu_stream_t stream;       /* Associated file stream */
55   mu_off_t body_start;      /* Offset of body start in the message file */
56   mu_off_t body_end;        /* Offset of body end (size of file, effectively)*/
57 
58   int attr_flags;           /* Current attribute flags */
59 
60   time_t mtime;             /* Time of last modification */
61   size_t header_lines;      /* Number of lines in the header part */
62   size_t body_lines;        /* Number of lines in the body */
63 
64   mu_message_t message;     /* Corresponding mu_message_t */
65   struct _amd_data *amd;    /* Back pointer.  */
66 };
67 
68 /* AMD capabilities */
69 #define MU_AMD_STATUS           0x01  /* format keeps status flags */
70 #define MU_AMD_VOLATILE_UIDNEXT 0x02  /* Reset UIDNEXT and UIDVALIDITY
71   when the last message is removed.  This helps implement the traditional
72   MH behavior: sequence number for the new message is computed as that of
73   the last message incremented by one.  Normally this behavior is enabled
74   by setting the 'Volatile-uidnext' parameter in mh_profile to 'true'.
75   See _mailbox_mh_init in libproto/mh/mh.c.
76 */
77 
78 #define MU_AMD_F_INIT_SCAN    0x01  /* Done initial scanning */
79 #define MU_AMD_F_PROP         0x02  /* prop file existed */
80 
81 struct _amd_data
82 {
83   int flags; /* MU_AMD_F_ bits above */
84   size_t msg_size;               /* Size of struct _amd_message */
85   int (*create) (struct _amd_data *, int flags);
86   int (*msg_init_delivery) (struct _amd_data *, struct _amd_message *);
87   int (*msg_finish_delivery) (struct _amd_data *, struct _amd_message *,
88 			      const mu_message_t);
89   void (*msg_free) (struct _amd_message *);
90   int (*cur_msg_file_name) (struct _amd_message *, int, char **);
91   int (*new_msg_file_name) (struct _amd_message *, int, int, char **);
92   int (*scan0)     (mu_mailbox_t mailbox, size_t msgno, size_t *pcount,
93 		    int do_notify);
94   int (*mailbox_size) (mu_mailbox_t mailbox, mu_off_t *psize);
95   int (*qfetch)    (struct _amd_data *, mu_message_qid_t qid);
96   int (*msg_cmp) (struct _amd_message *, struct _amd_message *);
97   int (*message_uid) (mu_message_t msg, size_t *puid);
98   int (*remove) (struct _amd_data *);
99   int (*delete_msg) (struct _amd_data *, struct _amd_message *);
100   int (*chattr_msg) (struct _amd_message *, int);
101 
102   /* List of messages: */
103   size_t msg_count; /* number of messages in the list */
104   size_t msg_max;   /* maximum message buffer capacity */
105   struct _amd_message **msg_array;
106 
107   int capabilities;
108   int has_new_msg;  /* New messages have been appended */
109   char *name;                    /* Directory name */
110 
111   mu_property_t prop; /* Properties: uidvalidity, uidnext, etc. */
112 
113   /* Pool of open message streams */
114   struct _amd_message *msg_pool[MAX_OPEN_STREAMS];
115   int pool_first;    /* Index to the first used entry in msg_pool */
116   int pool_last;     /* Index to the first free entry in msg_pool */
117 
118   time_t mtime;      /* Time of last modification */
119 
120   mu_mailbox_t mailbox; /* Back pointer. */
121 };
122 
123 
124 int amd_init_mailbox (mu_mailbox_t mailbox, size_t mhd_size,
125 		      struct _amd_data **pmhd);
126 int _amd_message_lookup_or_insert (struct _amd_data *amd,
127 				   struct _amd_message *key,
128 				   size_t *pindex);
129 int _amd_message_insert (struct _amd_data *mhd, struct _amd_message *msg);
130 int _amd_message_append (struct _amd_data *amd, struct _amd_message *msg);
131 void amd_sort (struct _amd_data *amd);
132 int amd_message_stream_open (struct _amd_message *mhm);
133 void amd_message_stream_close (struct _amd_message *mhm);
134 void amd_cleanup (void *arg);
135 struct _amd_message *_amd_get_message (struct _amd_data *amd, size_t msgno);
136 int amd_msg_lookup (struct _amd_data *amd, struct _amd_message *msg,
137 		    size_t *pret);
138 int amd_remove_dir (const char *name);
139 int amd_reset_uidvalidity (struct _amd_data *amd);
140 int amd_update_uidnext (struct _amd_data *amd, size_t *newval);
141 int amd_alloc_uid (struct _amd_data *amd, size_t *newval);
142 
143 #endif
144