NeoMutt  2024-11-14-34-g5aaf0d
Teaching an old dog new tricks
DOXYGEN
Loading...
Searching...
No Matches
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)
 

Functions

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

Detailed Description

Body Caching (local copies of email bodies)

Authors
  • Richard Russon

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)

Definition at line 54 of file lib.h.

Function Documentation

◆ mutt_bcache_close()

void mutt_bcache_close ( struct BodyCache **  ptr)

Close an Email-Body Cache.

Parameters
[out]ptrBody cache

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

Definition at line 169 of file bcache.c.

170{
171 if (!ptr || !*ptr)
172 return;
173
174 struct BodyCache *bcache = *ptr;
175 FREE(&bcache->path);
176
177 FREE(ptr);
178}
#define FREE(x)
Definition: memory.h:55
Local cache of email bodies.
Definition: bcache.c:51
char * path
On-disk path to the file.
Definition: bcache.c:52
+ 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 254 of file bcache.c.

255{
256 struct Buffer *tmpid = buf_pool_get();
257 buf_printf(tmpid, "%s.tmp", id);
258
259 int rc = mutt_bcache_move(bcache, buf_string(tmpid), id);
260 buf_pool_release(&tmpid);
261 return rc;
262}
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:119
int buf_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
Definition: buffer.c:161
static const char * buf_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition: buffer.h:96
struct Buffer * buf_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:81
void buf_pool_release(struct Buffer **ptr)
Return a Buffer to the pool.
Definition: pool.c:94
String manipulation buffer.
Definition: buffer.h:36
+ 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 271 of file bcache.c.

272{
273 if (!id || (*id == '\0') || !bcache)
274 return -1;
275
276 struct Buffer *path = buf_pool_get();
277 buf_addstr(path, bcache->path);
278 buf_addstr(path, id);
279
280 mutt_debug(LL_DEBUG3, "bcache: del: '%s'\n", buf_string(path));
281
282 int rc = unlink(buf_string(path));
283 buf_pool_release(&path);
284 return rc;
285}
size_t buf_addstr(struct Buffer *buf, const char *s)
Add a string to a Buffer.
Definition: buffer.c:226
#define mutt_debug(LEVEL,...)
Definition: logging2.h:89
@ LL_DEBUG3
Log at debug level 3.
Definition: logging2.h:45
+ 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 294 of file bcache.c.

295{
296 if (!id || (*id == '\0') || !bcache)
297 return -1;
298
299 struct Buffer *path = buf_pool_get();
300 buf_addstr(path, bcache->path);
301 buf_addstr(path, id);
302
303 int rc = 0;
304 struct stat st = { 0 };
305 if (stat(buf_string(path), &st) < 0)
306 rc = -1;
307 else
308 rc = (S_ISREG(st.st_mode) && (st.st_size != 0)) ? 0 : -1;
309
310 mutt_debug(LL_DEBUG3, "bcache: exists: '%s': %s\n", buf_string(path),
311 (rc == 0) ? "yes" : "no");
312
313 buf_pool_release(&path);
314 return rc;
315}
+ 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 187 of file bcache.c.

188{
189 if (!id || (*id == '\0') || !bcache)
190 return NULL;
191
192 struct Buffer *path = buf_pool_get();
193 buf_addstr(path, bcache->path);
194 buf_addstr(path, id);
195
196 FILE *fp = mutt_file_fopen(buf_string(path), "r");
197
198 mutt_debug(LL_DEBUG3, "bcache: get: '%s': %s\n", buf_string(path), fp ? "yes" : "no");
199
200 buf_pool_release(&path);
201 return fp;
202}
#define mutt_file_fopen(PATH, MODE)
Definition: file.h:137
+ 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 336 of file bcache.c.

337{
338 DIR *dir = NULL;
339 struct dirent *de = NULL;
340 int rc = -1;
341
342 if (!bcache || !(dir = mutt_file_opendir(bcache->path, MUTT_OPENDIR_NONE)))
343 goto out;
344
345 rc = 0;
346
347 mutt_debug(LL_DEBUG3, "bcache: list: dir: '%s'\n", bcache->path);
348
349 while ((de = readdir(dir)))
350 {
351 if (mutt_str_startswith(de->d_name, ".") || mutt_str_startswith(de->d_name, ".."))
352 {
353 continue;
354 }
355
356 mutt_debug(LL_DEBUG3, "bcache: list: dir: '%s', id :'%s'\n", bcache->path, de->d_name);
357
358 if (want_id && (want_id(de->d_name, bcache, data) != 0))
359 goto out;
360
361 rc++;
362 }
363
364out:
365 if (dir)
366 {
367 if (closedir(dir) < 0)
368 rc = -1;
369 }
370 mutt_debug(LL_DEBUG3, "bcache: list: did %d entries\n", rc);
371 return rc;
372}
DIR * mutt_file_opendir(const char *path, enum MuttOpenDirMode mode)
Open a directory.
Definition: file.c:642
@ MUTT_OPENDIR_NONE
Plain opendir()
Definition: file.h:63
size_t mutt_str_startswith(const char *str, const char *prefix)
Check whether a string starts with a prefix.
Definition: string.c:230
+ 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 148 of file bcache.c.

149{
150 if (!account)
151 return NULL;
152
153 struct BodyCache *bcache = MUTT_MEM_CALLOC(1, struct BodyCache);
154 if (bcache_path(account, mailbox, bcache) < 0)
155 {
156 mutt_bcache_close(&bcache);
157 return NULL;
158 }
159
160 return bcache;
161}
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:63
void mutt_bcache_close(struct BodyCache **ptr)
Close an Email-Body Cache.
Definition: bcache.c:169
#define MUTT_MEM_CALLOC(n, type)
Definition: memory.h:40
+ 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 214 of file bcache.c.

215{
216 if (!id || (*id == '\0') || !bcache)
217 return NULL;
218
219 struct Buffer *path = buf_pool_get();
220 buf_printf(path, "%s%s%s", bcache->path, id, ".tmp");
221
222 struct stat st = { 0 };
223 if (stat(bcache->path, &st) == 0)
224 {
225 if (!S_ISDIR(st.st_mode))
226 {
227 mutt_error(_("Message cache isn't a directory: %s"), bcache->path);
228 return NULL;
229 }
230 }
231 else
232 {
233 if (mutt_file_mkdir(bcache->path, S_IRWXU | S_IRWXG | S_IRWXO) < 0)
234 {
235 mutt_error(_("Can't create %s: %s"), bcache->path, strerror(errno));
236 return NULL;
237 }
238 }
239
240 mutt_debug(LL_DEBUG3, "bcache: put: '%s'\n", buf_string(path));
241
242 FILE *fp = mutt_file_fopen(buf_string(path), "w+");
243 buf_pool_release(&path);
244 return fp;
245}
int mutt_file_mkdir(const char *path, mode_t mode)
Recursively create directories.
Definition: file.c:974
#define mutt_error(...)
Definition: logging2.h:92
#define _(a)
Definition: message.h:28
+ Here is the call graph for this function:
+ Here is the caller graph for this function: