NeoMutt  2021-02-05-89-gabe350
Teaching an old dog new tricks
DOXYGEN
lib.h File Reference
#include <stddef.h>
#include <stdint.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.

Data Structures

struct  HeaderCache
 header cache structure More...
 
struct  HCacheEntry
 Wrapper for Email retrieved from the header cache. More...
 

Typedefs

typedef void(* hcache_namer_t) (const char *path, struct Buffer *dest)
 Prototype for function to compose hcache file names. More...
 

Functions

struct HeaderCachemutt_hcache_open (const char *path, const char *folder, hcache_namer_t namer)
 open the connection to the header cache More...
 
void mutt_hcache_close (struct HeaderCache *hc)
 close the connection to the header cache More...
 
int mutt_hcache_store (struct HeaderCache *hc, const char *key, size_t keylen, struct Email *e, uint32_t uidvalidity)
 store a Header along with a validity datum More...
 
struct HCacheEntry mutt_hcache_fetch (struct HeaderCache *hc, const char *key, size_t keylen, uint32_t uidvalidity)
 fetch and validate a message's header from the cache More...
 
int mutt_hcache_store_raw (struct HeaderCache *hc, const char *key, size_t keylen, void *data, size_t dlen)
 store a key / data pair More...
 
void * mutt_hcache_fetch_raw (struct HeaderCache *hc, const char *key, size_t keylen, size_t *dlen)
 Fetch a message's header from the cache. More...
 
void mutt_hcache_free_raw (struct HeaderCache *hc, void **data)
 free data fetched with mutt_hcache_fetch_raw() More...
 
int mutt_hcache_delete_record (struct HeaderCache *hc, const char *key, size_t keylen)
 delete a key / data pair More...
 

Variables

char * C_HeaderCache
 Config: (hcache) Directory/file for the header cache database. More...
 
char * C_HeaderCacheBackend
 Config: (hcache) Header cache backend to use. More...
 
short C_HeaderCacheCompressLevel
 Config: (hcache) Level of compression for method. More...
 
char * C_HeaderCacheCompressMethod
 Config: (hcache) Enable generic hcache database compression. More...
 

Detailed Description

Header cache multiplexor

Authors
  • Thomas Glanzmann
  • Tobias Werth
  • Brian Fundakowski Feldman
  • Pietro Cerutti
  • Tino Reichardt

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

◆ hcache_namer_t

typedef void(* hcache_namer_t) (const char *path, struct Buffer *dest)

Prototype for function to compose hcache file names.

Parameters
pathPath of message
destBuffer for filename

Definition at line 108 of file lib.h.

Function Documentation

◆ mutt_hcache_open()

struct HeaderCache* mutt_hcache_open ( const char *  path,
const char *  folder,
hcache_namer_t  namer 
)

open the connection to the header cache

Parameters
pathLocation of the header cache (often as specified by the user)
folderName of the folder containing the messages
namerOptional (might be NULL) client-specific function to form the final name of the hcache database file.
Return values
ptrSuccess, struct HeaderCache struct
NULLOtherwise

open the connection to the header cache

Definition at line 322 of file hcache.c.

323 {
324  const struct StoreOps *ops = hcache_get_ops();
325  if (!ops)
326  return NULL;
327 
328  struct HeaderCache *hc = mutt_mem_calloc(1, sizeof(struct HeaderCache));
329 
330  /* Calculate the current hcache version from dynamic configuration */
331  if (hcachever == 0x0)
332  {
333  union
334  {
335  unsigned char charval[16];
336  unsigned int intval;
337  } digest;
338  struct Md5Ctx md5ctx;
339 
340  hcachever = HCACHEVER;
341 
342  mutt_md5_init_ctx(&md5ctx);
343 
344  /* Seed with the compiled-in header structure hash */
345  mutt_md5_process_bytes(&hcachever, sizeof(hcachever), &md5ctx);
346 
347  /* Mix in user's spam list */
348  struct Replace *sp = NULL;
349  STAILQ_FOREACH(sp, &SpamList, entries)
350  {
351  mutt_md5_process(sp->regex->pattern, &md5ctx);
352  mutt_md5_process(sp->templ, &md5ctx);
353  }
354 
355  /* Mix in user's nospam list */
356  struct RegexNode *np = NULL;
357  STAILQ_FOREACH(np, &NoSpamList, entries)
358  {
359  mutt_md5_process(np->regex->pattern, &md5ctx);
360  }
361 
362  /* Get a hash and take its bytes as an (unsigned int) hash version */
363  mutt_md5_finish_ctx(&md5ctx, digest.charval);
364  hcachever = digest.intval;
365  }
366 
367 #ifdef USE_HCACHE_COMPRESSION
369  {
370  const struct ComprOps *cops = compr_get_ops();
371 
372  hc->cctx = cops->open(C_HeaderCacheCompressLevel);
373  if (!hc->cctx)
374  {
375  FREE(&hc);
376  return NULL;
377  }
378 
379  /* remember the buffer of database backend */
380  mutt_debug(LL_DEBUG3, "Header cache will use %s compression\n", cops->name);
381  }
382 #endif
383 
384  hc->folder = get_foldername(folder);
385  hc->crc = hcachever;
386 
387  if (!path || (path[0] == '\0'))
388  {
389  FREE(&hc->folder);
390  FREE(&hc);
391  return NULL;
392  }
393 
394  struct Buffer *hcpath = mutt_buffer_pool_get();
395  hcache_per_folder(hcpath, path, hc->folder, namer);
396 
397  hc->ctx = ops->open(mutt_buffer_string(hcpath));
398  if (!hc->ctx)
399  {
400  /* remove a possibly incompatible version */
401  if (unlink(mutt_buffer_string(hcpath)) == 0)
402  {
403  hc->ctx = ops->open(mutt_buffer_string(hcpath));
404  if (!hc->ctx)
405  {
406  FREE(&hc->folder);
407  FREE(&hc);
408  }
409  }
410  }
411 
412  mutt_buffer_pool_release(&hcpath);
413  return hc;
414 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_hcache_close()

void mutt_hcache_close ( struct HeaderCache hc)

close the connection to the header cache

Parameters
hcPointer to the struct HeaderCache structure got by mutt_hcache_open()

close the connection to the header cache

Definition at line 419 of file hcache.c.

420 {
421  const struct StoreOps *ops = hcache_get_ops();
422  if (!hc || !ops)
423  return;
424 
425 #ifdef USE_HCACHE_COMPRESSION
427  compr_get_ops()->close(&hc->cctx);
428 #endif
429 
430  ops->close(&hc->ctx);
431  FREE(&hc->folder);
432  FREE(&hc);
433 }
+ Here is the caller graph for this function:

◆ mutt_hcache_store()

int mutt_hcache_store ( struct HeaderCache hc,
const char *  key,
size_t  keylen,
struct Email e,
uint32_t  uidvalidity 
)

store a Header along with a validity datum

Parameters
hcPointer to the struct HeaderCache structure got by mutt_hcache_open()
keyMessage identification string
keylenLength of the key string
eEmail to store
uidvalidityIMAP-specific UIDVALIDITY value, or 0 to use the current time
Return values
0Success
numGeneric or backend-specific error code otherwise

store a Header along with a validity datum

Definition at line 527 of file hcache.c.

529 {
530  if (!hc)
531  return -1;
532 
533  int dlen = 0;
534  char *data = dump(hc, e, &dlen, uidvalidity);
535 
536 #ifdef USE_HCACHE_COMPRESSION
538  {
539  /* We don't compress uidvalidity and the crc, so we can check them before
540  * decompressing on fetch(). */
541  size_t hlen = header_size();
542 
543  const struct ComprOps *cops = compr_get_ops();
544 
545  /* data / dlen gets ptr to compressed data here */
546  size_t clen = dlen;
547  void *cdata = cops->compress(hc->cctx, data + hlen, dlen - hlen, &clen);
548  if (!cdata)
549  {
550  FREE(&data);
551  return -1;
552  }
553 
554  char *whole = mutt_mem_malloc(hlen + clen);
555  memcpy(whole, data, hlen);
556  memcpy(whole + hlen, cdata, clen);
557 
558  FREE(&data);
559 
560  data = whole;
561  dlen = hlen + clen;
562  }
563 #endif
564 
565  /* store uncompressed data */
566  struct RealKey *rk = realkey(key, keylen);
567  int rc = mutt_hcache_store_raw(hc, rk->key, rk->len, data, dlen);
568 
569  FREE(&data);
570 
571  return rc;
572 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_hcache_fetch()

struct HCacheEntry mutt_hcache_fetch ( struct HeaderCache hc,
const char *  key,
size_t  keylen,
uint32_t  uidvalidity 
)

fetch and validate a message's header from the cache

Parameters
hcPointer to the struct HeaderCache structure got by mutt_hcache_open()
keyMessage identification string
keylenLength of the string pointed to by key
uidvalidityOnly restore if it matches the stored uidvalidity
Return values
objHCacheEntry containing an Email, empty on failure
Note
This function performs a check on the validity of the data found by comparing it with the crc value of the struct HeaderCache structure.

fetch and validate a message's header from the cache

Definition at line 438 of file hcache.c.

440 {
441  struct RealKey *rk = realkey(key, keylen);
442  struct HCacheEntry entry = { 0 };
443 
444  size_t dlen;
445  void *data = mutt_hcache_fetch_raw(hc, rk->key, rk->len, &dlen);
446  void *to_free = data;
447  if (!data)
448  {
449  goto end;
450  }
451 
452  /* restore uidvalidity and crc */
453  size_t hlen = header_size();
454  int off = 0;
455  serial_restore_uint32_t(&entry.uidvalidity, data, &off);
456  serial_restore_int(&entry.crc, data, &off);
457  assert((size_t) off == hlen);
458  if (entry.crc != hc->crc || ((uidvalidity != 0) && uidvalidity != entry.uidvalidity))
459  {
460  goto end;
461  }
462 
463 #ifdef USE_HCACHE_COMPRESSION
465  {
466  const struct ComprOps *cops = compr_get_ops();
467 
468  void *dblob = cops->decompress(hc->cctx, (char *) data + hlen, dlen - hlen);
469  if (!dblob)
470  {
471  goto end;
472  }
473  data = (char *) dblob - hlen; /* restore skips uidvalidity and crc */
474  }
475 #endif
476 
477  entry.email = restore(data);
478 
479 end:
480  mutt_hcache_free_raw(hc, &to_free);
481  return entry;
482 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_hcache_store_raw()

int mutt_hcache_store_raw ( struct HeaderCache hc,
const char *  key,
size_t  keylen,
void *  data,
size_t  dlen 
)

store a key / data pair

Parameters
hcPointer to the struct HeaderCache structure got by mutt_hcache_open()
keyMessage identification string
keylenLength of the string pointed to by key
dataPayload to associate with key
dlenLength of the buffer pointed to by the data parameter
Return values
0Success
numGeneric or backend-specific error code otherwise

Definition at line 584 of file hcache.c.

586 {
587  const struct StoreOps *ops = hcache_get_ops();
588 
589  if (!hc || !ops)
590  return -1;
591 
592  struct Buffer path = mutt_buffer_make(1024);
593 
594  keylen = mutt_buffer_printf(&path, "%s%.*s", hc->folder, (int) keylen, key);
595  int rc = ops->store(hc->ctx, mutt_buffer_string(&path), keylen, data, dlen);
596  mutt_buffer_dealloc(&path);
597 
598  return rc;
599 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_hcache_fetch_raw()

void* mutt_hcache_fetch_raw ( struct HeaderCache hc,
const char *  key,
size_t  keylen,
size_t *  dlen 
)

Fetch a message's header from the cache.

Parameters
[in]hcPointer to the struct HeaderCache structure got by mutt_hcache_open()
[in]keyMessage identification string
[in]keylenLength of the string pointed to by key
[out]dlenLength of the fetched data
Return values
ptrSuccess, the data if found
NULLOtherwise
Note
This function does not perform any check on the validity of the data found.
The returned data must be free with mutt_hcache_free_raw().

Definition at line 496 of file hcache.c.

498 {
499  const struct StoreOps *ops = hcache_get_ops();
500 
501  if (!hc || !ops)
502  return NULL;
503 
504  struct Buffer path = mutt_buffer_make(1024);
505  keylen = mutt_buffer_printf(&path, "%s%.*s", hc->folder, (int) keylen, key);
506  void *blob = ops->fetch(hc->ctx, mutt_buffer_string(&path), keylen, dlen);
507  mutt_buffer_dealloc(&path);
508  return blob;
509 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_hcache_free_raw()

void mutt_hcache_free_raw ( struct HeaderCache hc,
void **  data 
)

free data fetched with mutt_hcache_fetch_raw()

Parameters
hcPointer to the struct HeaderCache structure got by mutt_hcache_open()
dataPointer to the data got using mutt_hcache_fetch_raw

free data fetched with mutt_hcache_fetch_raw()

Definition at line 514 of file hcache.c.

515 {
516  const struct StoreOps *ops = hcache_get_ops();
517 
518  if (!hc || !ops || !data || !*data)
519  return;
520 
521  ops->free(hc->ctx, data);
522 }
+ Here is the caller graph for this function:

◆ mutt_hcache_delete_record()

int mutt_hcache_delete_record ( struct HeaderCache hc,
const char *  key,
size_t  keylen 
)

delete a key / data pair

Parameters
hcPointer to the struct HeaderCache structure got by mutt_hcache_open()
keyMessage identification string
keylenLength of the string pointed to by key
Return values
0Success
numGeneric or backend-specific error code otherwise

delete a key / data pair

Definition at line 604 of file hcache.c.

605 {
606  const struct StoreOps *ops = hcache_get_ops();
607  if (!hc)
608  return -1;
609 
610  struct Buffer path = mutt_buffer_make(1024);
611 
612  keylen = mutt_buffer_printf(&path, "%s%s", hc->folder, key);
613 
614  int rc = ops->delete_record(hc->ctx, mutt_buffer_string(&path), keylen);
615  mutt_buffer_dealloc(&path);
616  return rc;
617 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Variable Documentation

◆ C_HeaderCache

char* C_HeaderCache

Config: (hcache) Directory/file for the header cache database.

Definition at line 40 of file config.c.

◆ C_HeaderCacheBackend

char* C_HeaderCacheBackend

Config: (hcache) Header cache backend to use.

Definition at line 41 of file config.c.

◆ C_HeaderCacheCompressLevel

short C_HeaderCacheCompressLevel

Config: (hcache) Level of compression for method.

Definition at line 43 of file config.c.

◆ C_HeaderCacheCompressMethod

char* C_HeaderCacheCompressMethod

Config: (hcache) Enable generic hcache database compression.

Definition at line 44 of file config.c.

dump
static void * dump(struct HeaderCache *hc, const struct Email *e, int *off, uint32_t uidvalidity)
Serialise an Email object.
Definition: hcache.c:89
mutt_mem_calloc
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
Definition: memory.c:50
restore
static struct Email * restore(const unsigned char *d)
Restore an Email from data retrieved from the cache.
Definition: hcache.c:146
mutt_hcache_store_raw
int mutt_hcache_store_raw(struct HeaderCache *hc, const char *key, size_t keylen, void *data, size_t dlen)
store a key / data pair
Definition: hcache.c:584
serial_restore_uint32_t
void serial_restore_uint32_t(uint32_t *s, const unsigned char *d, int *off)
Unpack an uint32_t from a binary blob.
Definition: serialize.c:108
Buffer
String manipulation buffer.
Definition: buffer.h:33
RealKey::key
char key[1024]
Definition: hcache.c:180
LL_DEBUG3
@ LL_DEBUG3
Log at debug level 3.
Definition: logging.h:42
Md5Ctx
Cursor for the MD5 hashing.
Definition: md5.h:36
HeaderCache::cctx
void * cctx
Definition: lib.h:90
mutt_buffer_dealloc
void mutt_buffer_dealloc(struct Buffer *buf)
Release the memory allocated by a buffer.
Definition: buffer.c:294
ComprOps::name
const char * name
Compression name.
Definition: lib.h:57
StoreOps
Key Value Store API.
Definition: lib.h:61
ComprOps::open
void *(* open)(short level)
Open a compression context.
Definition: lib.h:67
FREE
#define FREE(x)
Definition: memory.h:40
HeaderCache::ctx
void * ctx
Definition: lib.h:89
mutt_md5_finish_ctx
void * mutt_md5_finish_ctx(struct Md5Ctx *md5ctx, void *resbuf)
Process the remaining bytes in the buffer.
Definition: md5.c:286
RealKey
Definition: hcache.c:178
compr_get_ops
#define compr_get_ops()
Definition: hcache.c:66
mutt_buffer_pool_release
void mutt_buffer_pool_release(struct Buffer **pbuf)
Free a Buffer from the pool.
Definition: pool.c:112
StoreOps::free
void(* free)(void *store, void **ptr)
Free a Value returned by fetch()
Definition: lib.h:93
STAILQ_FOREACH
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:349
mutt_md5_init_ctx
void mutt_md5_init_ctx(struct Md5Ctx *md5ctx)
Initialise the MD5 computation.
Definition: md5.c:262
NoSpamList
struct RegexList NoSpamList
List of regexes to whitelist non-spam emails.
Definition: globals.c:43
header_size
static size_t header_size(void)
Compute the size of the header with uuid validity and crc.
Definition: hcache.c:73
mutt_md5_process
void mutt_md5_process(const char *str, struct Md5Ctx *md5ctx)
Process a NULL-terminated string.
Definition: md5.c:355
RegexNode
List of regular expressions.
Definition: regex3.h:99
mutt_buffer_pool_get
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:101
hcachever
static unsigned int hcachever
Definition: hcache.c:61
HeaderCache::folder
char * folder
Definition: lib.h:87
serial_restore_int
void serial_restore_int(unsigned int *i, const unsigned char *d, int *off)
Unpack an integer from a binary blob.
Definition: serialize.c:96
ComprOps::decompress
void *(* decompress)(void *cctx, const char *cbuf, size_t clen)
Decompress header cache data.
Definition: lib.h:94
StoreOps::close
void(* close)(void **ptr)
Close a Store connection.
Definition: lib.h:121
mutt_hcache_free_raw
void mutt_hcache_free_raw(struct HeaderCache *hc, void **data)
Multiplexor for StoreOps::free.
Definition: hcache.c:514
HCacheEntry::email
struct Email * email
Retrieved email.
Definition: lib.h:100
mutt_debug
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
C_HeaderCacheCompressMethod
char * C_HeaderCacheCompressMethod
Config: (hcache) Enable generic hcache database compression.
Definition: config.c:44
HCacheEntry
Wrapper for Email retrieved from the header cache.
Definition: lib.h:96
ComprOps
Header Cache Compression API.
Definition: lib.h:55
mutt_buffer_string
static const char * mutt_buffer_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition: buffer.h:77
mutt_md5_process_bytes
void mutt_md5_process_bytes(const void *buf, size_t buflen, struct Md5Ctx *md5ctx)
Process a block of data.
Definition: md5.c:373
HeaderCache
header cache structure
Definition: lib.h:85
StoreOps::fetch
void *(* fetch)(void *store, const char *key, size_t klen, size_t *vlen)
Fetch a Value from the Store.
Definition: lib.h:86
get_foldername
static char * get_foldername(const char *folder)
Where should the cache be stored?
Definition: hcache.c:308
ComprOps::compress
void *(* compress)(void *cctx, const char *data, size_t dlen, size_t *clen)
Compress header cache data.
Definition: lib.h:81
mutt_mem_malloc
void * mutt_mem_malloc(size_t size)
Allocate memory on the heap.
Definition: memory.c:90
hcache_per_folder
static void hcache_per_folder(struct Buffer *hcpath, const char *path, const char *folder, hcache_namer_t namer)
Generate the hcache pathname.
Definition: hcache.c:257
StoreOps::delete_record
int(* delete_record)(void *store, const char *key, size_t klen)
Delete a record from the Store.
Definition: lib.h:115
hcache_get_ops
#define hcache_get_ops()
Definition: hcache.c:63
StoreOps::store
int(* store)(void *store, const char *key, size_t klen, void *value, size_t vlen)
Write a Value to the Store.
Definition: lib.h:105
RegexNode::regex
struct Regex * regex
Regex containing a regular expression.
Definition: regex3.h:101
Replace
List of regular expressions.
Definition: regex3.h:109
Regex::pattern
char * pattern
printable version
Definition: regex3.h:91
mutt_hcache_fetch_raw
void * mutt_hcache_fetch_raw(struct HeaderCache *hc, const char *key, size_t keylen, size_t *dlen)
Fetch a message's header from the cache.
Definition: hcache.c:496
RealKey::len
size_t len
Definition: hcache.c:181
StoreOps::open
void *(* open)(const char *path)
Open a connection to a Store.
Definition: lib.h:75
C_HeaderCacheCompressLevel
short C_HeaderCacheCompressLevel
Config: (hcache) Level of compression for method.
Definition: config.c:43
HCacheEntry::uidvalidity
uint32_t uidvalidity
IMAP-specific UIDVALIDITY.
Definition: lib.h:98
SpamList
struct ReplaceList SpamList
List of regexes and patterns to match spam emails.
Definition: globals.c:44
Buffer::data
char * data
Pointer to data.
Definition: buffer.h:35
realkey
static struct RealKey * realkey(const char *key, size_t keylen)
Compute the real key used in the backend, taking into account the compression method.
Definition: hcache.c:190
mutt_buffer_printf
int mutt_buffer_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
Definition: buffer.c:160
mutt_buffer_make
struct Buffer mutt_buffer_make(size_t size)
Make a new buffer on the stack.
Definition: buffer.c:61
HeaderCache::crc
unsigned int crc
Definition: lib.h:88
Replace::regex
struct Regex * regex
Regex containing a regular expression.
Definition: regex3.h:111
HCacheEntry::crc
unsigned int crc
CRC of Email/Body/etc structs.
Definition: lib.h:99
Replace::templ
char * templ
Template to match.
Definition: regex3.h:113