NeoMutt  2020-06-26-30-g76c339
Teaching an old dog new tricks
DOXYGEN
lib.h File Reference

Body Caching - local copies of email bodies. More...

#include <stdio.h>
+ Include dependency graph for lib.h:
+ This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Typedefs

typedef int(* bcache_list_t) (const char *id, struct BodyCache *bcache, void *data)
 Prototype for mutt_bcache_list() callback. More...
 

Functions

void mutt_bcache_close (struct BodyCache **bcache)
 Close an Email-Body Cache. More...
 
int mutt_bcache_commit (struct BodyCache *bcache, const char *id)
 Move a temporary file into the Body Cache. More...
 
int mutt_bcache_del (struct BodyCache *bcache, const char *id)
 Delete a file from the Body Cache. More...
 
int mutt_bcache_exists (struct BodyCache *bcache, const char *id)
 Check if a file exists in the Body Cache. More...
 
FILE * mutt_bcache_get (struct BodyCache *bcache, const char *id)
 Open a file in the Body Cache. More...
 
int mutt_bcache_list (struct BodyCache *bcache, bcache_list_t want_id, void *data)
 Find matching entries in the Body Cache. More...
 
struct BodyCachemutt_bcache_open (struct ConnAccount *account, const char *mailbox)
 Open an Email-Body Cache. More...
 
FILE * mutt_bcache_put (struct BodyCache *bcache, const char *id)
 Create a file in the Body Cache. More...
 

Variables

char * C_MessageCachedir
 Config: (imap/pop) Directory for the message cache. More...
 

Detailed Description

Body Caching - local copies of email bodies.

Authors
  • Brendan Cully
  • Rocco Rutte

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/.

Definition in file lib.h.

Typedef Documentation

◆ bcache_list_t

typedef int(* bcache_list_t) (const char *id, struct BodyCache *bcache, void *data)

Prototype for mutt_bcache_list() callback.

Parameters
bcacheBody Cache from mutt_bcache_open()
want_idCallback function called for each match
dataData to pass to the callback function
Return values
-1Failure
>=0count of matching items

mutt_bcache_list() will call this function once for each item in the cache.

Definition at line 45 of file lib.h.

Function Documentation

◆ mutt_bcache_close()

void mutt_bcache_close ( struct BodyCache **  bcache)

Close an Email-Body Cache.

Parameters
[out]bcacheBody cache

Free all memory of bcache and finally FREE() it, too.

Definition at line 153 of file bcache.c.

154 {
155  if (!bcache || !*bcache)
156  return;
157  FREE(&(*bcache)->path);
158  FREE(bcache);
159 }
#define FREE(x)
Definition: memory.h:40
+ Here is the caller graph for this function:

◆ mutt_bcache_commit()

int mutt_bcache_commit ( struct BodyCache bcache,
const char *  id 
)

Move a temporary file into the Body Cache.

Parameters
bcacheBody Cache from mutt_bcache_open()
idPer-mailbox unique identifier for the message
Return values
0Success
-1Failure

Definition at line 235 of file bcache.c.

236 {
237  struct Buffer *tmpid = mutt_buffer_pool_get();
238  mutt_buffer_printf(tmpid, "%s.tmp", id);
239 
240  int rc = mutt_bcache_move(bcache, mutt_b2s(tmpid), id);
241  mutt_buffer_pool_release(&tmpid);
242  return rc;
243 }
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:101
void mutt_buffer_pool_release(struct Buffer **pbuf)
Free a Buffer from the pool.
Definition: pool.c:112
String manipulation buffer.
Definition: buffer.h:33
int mutt_buffer_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
Definition: buffer.c:160
#define mutt_b2s(buf)
Definition: buffer.h:41
static int mutt_bcache_move(struct BodyCache *bcache, const char *id, const char *newid)
Change the id of a message in the cache.
Definition: bcache.c:103
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_bcache_del()

int mutt_bcache_del ( struct BodyCache bcache,
const char *  id 
)

Delete a file from the Body Cache.

Parameters
bcacheBody Cache from mutt_bcache_open()
idPer-mailbox unique identifier for the message
Return values
0Success
-1Failure

Definition at line 252 of file bcache.c.

253 {
254  if (!id || (*id == '\0') || !bcache)
255  return -1;
256 
257  struct Buffer *path = mutt_buffer_pool_get();
258  mutt_buffer_addstr(path, bcache->path);
259  mutt_buffer_addstr(path, id);
260 
261  mutt_debug(LL_DEBUG3, "bcache: del: '%s'\n", mutt_b2s(path));
262 
263  int rc = unlink(mutt_b2s(path));
265  return rc;
266 }
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:101
void mutt_buffer_pool_release(struct Buffer **pbuf)
Free a Buffer from the pool.
Definition: pool.c:112
String manipulation buffer.
Definition: buffer.h:33
char * path
Definition: bcache.c:51
size_t mutt_buffer_addstr(struct Buffer *buf, const char *s)
Add a string to a Buffer.
Definition: buffer.c:225
#define mutt_b2s(buf)
Definition: buffer.h:41
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
Log at debug level 3.
Definition: logging.h:42
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_bcache_exists()

int mutt_bcache_exists ( struct BodyCache bcache,
const char *  id 
)

Check if a file exists in the Body Cache.

Parameters
bcacheBody Cache from mutt_bcache_open()
idPer-mailbox unique identifier for the message
Return values
0Success
-1Failure

Definition at line 275 of file bcache.c.

276 {
277  if (!id || (*id == '\0') || !bcache)
278  return -1;
279 
280  struct Buffer *path = mutt_buffer_pool_get();
281  mutt_buffer_addstr(path, bcache->path);
282  mutt_buffer_addstr(path, id);
283 
284  int rc = 0;
285  struct stat st;
286  if (stat(mutt_b2s(path), &st) < 0)
287  rc = -1;
288  else
289  rc = (S_ISREG(st.st_mode) && (st.st_size != 0)) ? 0 : -1;
290 
291  mutt_debug(LL_DEBUG3, "bcache: exists: '%s': %s\n", mutt_b2s(path),
292  (rc == 0) ? "yes" : "no");
293 
295  return rc;
296 }
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:101
void mutt_buffer_pool_release(struct Buffer **pbuf)
Free a Buffer from the pool.
Definition: pool.c:112
String manipulation buffer.
Definition: buffer.h:33
char * path
Definition: bcache.c:51
size_t mutt_buffer_addstr(struct Buffer *buf, const char *s)
Add a string to a Buffer.
Definition: buffer.c:225
#define mutt_b2s(buf)
Definition: buffer.h:41
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
Log at debug level 3.
Definition: logging.h:42
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_bcache_get()

FILE* mutt_bcache_get ( struct BodyCache bcache,
const char *  id 
)

Open a file in the Body Cache.

Parameters
bcacheBody Cache from mutt_bcache_open()
idPer-mailbox unique identifier for the message
Return values
ptrSuccess
NULLFailure

Definition at line 168 of file bcache.c.

169 {
170  if (!id || (*id == '\0') || !bcache)
171  return NULL;
172 
173  struct Buffer *path = mutt_buffer_pool_get();
174  mutt_buffer_addstr(path, bcache->path);
175  mutt_buffer_addstr(path, id);
176 
177  FILE *fp = mutt_file_fopen(mutt_b2s(path), "r");
178 
179  mutt_debug(LL_DEBUG3, "bcache: get: '%s': %s\n", mutt_b2s(path), fp ? "yes" : "no");
180 
182  return fp;
183 }
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:101
void mutt_buffer_pool_release(struct Buffer **pbuf)
Free a Buffer from the pool.
Definition: pool.c:112
String manipulation buffer.
Definition: buffer.h:33
char * path
Definition: bcache.c:51
size_t mutt_buffer_addstr(struct Buffer *buf, const char *s)
Add a string to a Buffer.
Definition: buffer.c:225
#define mutt_b2s(buf)
Definition: buffer.h:41
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
FILE * mutt_file_fopen(const char *path, const char *mode)
Call fopen() safely.
Definition: file.c:588
Log at debug level 3.
Definition: logging.h:42
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_bcache_list()

int mutt_bcache_list ( struct BodyCache bcache,
bcache_list_t  want_id,
void *  data 
)

Find matching entries in the Body Cache.

Parameters
bcacheBody Cache from mutt_bcache_open()
want_idCallback function called for each match
dataData to pass to the callback function
Return values
-1Failure
>=0count of matching items

This more or less "examines" the cache and calls a function with each id it finds if given.

The optional callback function gets the id of a message, the very same body cache handle mutt_bcache_list() is called with (to, perhaps, perform further operations on the bcache), and a data cookie which is just passed as-is. If the return value of the callback is non-zero, the listing is aborted and continued otherwise. The callback is optional so that this function can be used to count the items in the cache (see below for return value).

Definition at line 317 of file bcache.c.

318 {
319  DIR *d = NULL;
320  struct dirent *de = NULL;
321  int rc = -1;
322 
323  if (!bcache || !(d = opendir(bcache->path)))
324  goto out;
325 
326  rc = 0;
327 
328  mutt_debug(LL_DEBUG3, "bcache: list: dir: '%s'\n", bcache->path);
329 
330  while ((de = readdir(d)))
331  {
332  if (mutt_str_startswith(de->d_name, ".") || mutt_str_startswith(de->d_name, ".."))
333  {
334  continue;
335  }
336 
337  mutt_debug(LL_DEBUG3, "bcache: list: dir: '%s', id :'%s'\n", bcache->path, de->d_name);
338 
339  if (want_id && (want_id(de->d_name, bcache, data) != 0))
340  goto out;
341 
342  rc++;
343  }
344 
345 out:
346  if (d)
347  {
348  if (closedir(d) < 0)
349  rc = -1;
350  }
351  mutt_debug(LL_DEBUG3, "bcache: list: did %d entries\n", rc);
352  return rc;
353 }
char * path
Definition: bcache.c:51
size_t mutt_str_startswith(const char *str, const char *prefix)
Check whether a string starts with a prefix.
Definition: string.c:165
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
Log at debug level 3.
Definition: logging.h:42
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_bcache_open()

struct BodyCache* mutt_bcache_open ( struct ConnAccount account,
const char *  mailbox 
)

Open an Email-Body Cache.

Parameters
accountcurrent mailbox' account (required)
mailboxpath to the mailbox of the account (optional)
Return values
NULLFailure

The driver using it is responsible for ensuring that hierarchies are separated by '/' (if it knows of such a concepts like mailboxes or hierarchies)

Definition at line 132 of file bcache.c.

133 {
134  if (!account)
135  return NULL;
136 
137  struct BodyCache *bcache = mutt_mem_calloc(1, sizeof(struct BodyCache));
138  if (bcache_path(account, mailbox, bcache) < 0)
139  {
140  mutt_bcache_close(&bcache);
141  return NULL;
142  }
143 
144  return bcache;
145 }
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
Definition: memory.c:50
Local cache of email bodies.
Definition: bcache.c:49
static int bcache_path(struct ConnAccount *account, const char *mailbox, struct BodyCache *bcache)
Create the cache path for a given account/mailbox.
Definition: bcache.c:62
void mutt_bcache_close(struct BodyCache **bcache)
Close an Email-Body Cache.
Definition: bcache.c:153
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_bcache_put()

FILE* mutt_bcache_put ( struct BodyCache bcache,
const char *  id 
)

Create a file in the Body Cache.

Parameters
bcacheBody Cache from mutt_bcache_open()
idPer-mailbox unique identifier for the message
Return values
ptrSuccess
NULLFailure

The returned FILE* is in a temporary location. Use mutt_bcache_commit to put it into place

Definition at line 195 of file bcache.c.

196 {
197  if (!id || (*id == '\0') || !bcache)
198  return NULL;
199 
200  struct Buffer *path = mutt_buffer_pool_get();
201  mutt_buffer_printf(path, "%s%s%s", bcache->path, id, ".tmp");
202 
203  struct stat sb;
204  if (stat(bcache->path, &sb) == 0)
205  {
206  if (!S_ISDIR(sb.st_mode))
207  {
208  mutt_error(_("Message cache isn't a directory: %s"), bcache->path);
209  return NULL;
210  }
211  }
212  else
213  {
214  if (mutt_file_mkdir(bcache->path, S_IRWXU | S_IRWXG | S_IRWXO) < 0)
215  {
216  mutt_error(_("Can't create %s: %s"), bcache->path, strerror(errno));
217  return NULL;
218  }
219  }
220 
221  mutt_debug(LL_DEBUG3, "bcache: put: '%s'\n", path);
222 
223  FILE *fp = mutt_file_fopen(mutt_b2s(path), "w+");
225  return fp;
226 }
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:101
void mutt_buffer_pool_release(struct Buffer **pbuf)
Free a Buffer from the pool.
Definition: pool.c:112
String manipulation buffer.
Definition: buffer.h:33
char * path
Definition: bcache.c:51
#define _(a)
Definition: message.h:28
int mutt_buffer_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
Definition: buffer.c:160
int mutt_file_mkdir(const char *path, mode_t mode)
Recursively create directories.
Definition: file.c:875
#define mutt_b2s(buf)
Definition: buffer.h:41
#define mutt_error(...)
Definition: logging.h:84
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
FILE * mutt_file_fopen(const char *path, const char *mode)
Call fopen() safely.
Definition: file.c:588
Log at debug level 3.
Definition: logging.h:42
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Variable Documentation

◆ C_MessageCachedir

char* C_MessageCachedir

Config: (imap/pop) Directory for the message cache.

Definition at line 44 of file bcache.c.