82 size_t len = strlen(
group) + 1;
88 mdata->deleted =
true;
110 if (
mdata->acache[i].path)
112 unlink(
mdata->acache[i].path);
139 if ((
mdata->last_message == 0) ||
146 for (
unsigned int i = 0; i <
mdata->newsrc_len; i++)
150 first =
mdata->first_message;
152 if (last >
mdata->last_message)
153 last =
mdata->last_message;
155 mdata->unread -= last - first + 1;
172 struct stat st = { 0 };
209 if ((adata->
size == st.st_size) && (adata->
mtime == st.st_mtime))
212 adata->
size = st.st_size;
213 adata->
mtime = st.st_mtime;
218 for (
unsigned int i = 0; i < adata->
groups_num; i++)
224 mdata->subscribed =
false;
225 mdata->newsrc_len = 0;
230 while (st.st_size && fgets(line, st.st_size + 1,
adata->
fp_newsrc))
232 char *b = NULL, *h = NULL;
237 char *p = strpbrk(line,
":!");
256 mdata->subscribed = subs;
276 if ((sscanf(b,
ANUM_FMT, &
mdata->newsrc_ent[j].first) == 1) &&
284 mdata->newsrc_ent[j].first = 1;
285 mdata->newsrc_ent[j].last = 0;
288 if (
mdata->last_message == 0)
289 mdata->last_message =
mdata->newsrc_ent[j - 1].last;
290 mdata->newsrc_len = j;
309 anum_t last = 0, first = 1;
311 unsigned int entries;
320 entries =
mdata->newsrc_len;
329 mdata->newsrc_len = 0;
368 if (series && (first <= mdata->last_loaded))
403 snprintf(tmpfile,
sizeof(tmpfile),
"%s.tmp", filename);
411 if (fputs(buf, fp) == EOF)
423 if (rename(tmpfile, filename) < 0)
452 size_t buflen = 10240;
457 for (
unsigned int i = 0; i < adata->
groups_num; i++)
465 if ((off + strlen(
mdata->group) + 3) > buflen)
470 snprintf(buf + off, buflen - off,
"%s%c ",
mdata->group,
mdata->subscribed ?
':' :
'!');
471 off += strlen(buf + off);
474 for (
unsigned int j = 0; j <
mdata->newsrc_len; j++)
476 if ((off + 1024) > buflen)
483 if (
mdata->newsrc_ent[j].first ==
mdata->newsrc_ent[j].last)
485 snprintf(buf + off, buflen - off,
ANUM_FMT,
mdata->newsrc_ent[j].first);
487 else if (
mdata->newsrc_ent[j].first <
mdata->newsrc_ent[j].last)
490 mdata->newsrc_ent[j].first,
mdata->newsrc_ent[j].last);
492 off += strlen(buf + off);
502 struct stat st = { 0 };
507 adata->
size = st.st_size;
508 adata->
mtime = st.st_mtime;
531 struct Url url = { 0 };
538 char *c = file + strlen(file) - 1;
547 snprintf(dst, dstlen,
"%s/%s", c_news_cache_dir,
buf_string(tmp));
560 struct Url url = { 0 };
578 char group[1024] = { 0 };
579 char desc[8192] = { 0 };
581 anum_t first = 0, last = 0;
588 &last, &first, &mod,
desc) < 4)
595 mdata->deleted =
false;
596 mdata->first_message = first;
597 mdata->last_message = last;
598 mdata->allowed = (mod ==
'y') || (mod ==
'm');
600 if (
mdata->newsrc_ent || (
mdata->last_cached != 0))
602 else if (
mdata->last_message && (
mdata->first_message <=
mdata->last_message))
617 char buf[8192] = { 0 };
618 char file[4096] = { 0 };
627 if (!fgets(buf,
sizeof(buf), fp) || (sscanf(buf,
"%jd%4095s", &t, file) != 1) || (t == 0))
635 while (fgets(buf,
sizeof(buf), fp))
654 size_t buflen = 10240;
657 size_t off = strlen(buf);
666 if ((off + strlen(
mdata->group) + (
mdata->desc ? strlen(
mdata->desc) : 0) + 50) > buflen)
673 mdata->allowed ?
'y' :
'n',
mdata->desc ?
" " :
"",
675 off += strlen(buf + off);
697 if (first && last && (last > first))
699 memmove(first, last, strlen(last) + 1);
711 struct Url url = { 0 };
738 char buf[32] = { 0 };
740 anum_t first = 0, last = 0;
753 for (
anum_t current = first; current <= last; current++)
755 if ((current >= mdata->
first_message) && (current <= mdata->last_message))
758 snprintf(buf,
sizeof(buf),
ANUM_FMT, current);
848 struct dirent *de = NULL;
861 while ((de = readdir(dir)))
863 char *group = de->d_name;
868 struct stat st = { 0 };
873 if (S_ISREG(st.st_mode))
875 char *ext = group + strlen(group) - 7;
882 if (!S_ISDIR(st.st_mode))
892 mdata->bcache = NULL;
894 else if (
mdata->newsrc_ent ||
mdata->subscribed || c_save_unsubscribed)
900 if (S_ISDIR(st.st_mode))
917 int max_cols,
struct Buffer *buf)
922 char tmp[128] = { 0 };
924 struct Url url = { 0 };
927 char *p = strchr(tmp,
'/');
965 int max_cols,
struct Buffer *buf)
980 int max_cols,
struct Buffer *buf)
985 char tmp[128] = { 0 };
997 int max_cols,
struct Buffer *buf)
1002 char tmp[128] = { 0 };
1004 struct Url url = { 0 };
1007 char *p = strchr(tmp,
':');
1020 int max_cols,
struct Buffer *buf)
1025 const char *s = cac->
user;
1071 if (!server || (*server ==
'\0'))
1084 snprintf(file,
sizeof(file),
"%s%s", strstr(server,
"://") ?
"" :
"news://", server);
1086 if (!url || (url->
path && *url->
path) ||
1091 mutt_error(
_(
"%s is an invalid news server specification"), server);
1102 const char *
user = NULL;
1103 const char *
pass = NULL;
1133 if ((rc >= 0) && c_news_cache_dir)
1138 mutt_error(
_(
"Can't create %s: %s"), file, strerror(errno));
1175 struct dirent *de = NULL;
1180 while ((de = readdir(dir)))
1183 char *group = de->d_name;
1185 char *p = group + strlen(group) - 7;
1201 anum_t first = 0, last = 0;
1207 mdata->first_message = first;
1208 mdata->last_message = last;
1212 mdata->last_cached = last;
1225 if ((rc < 0) || !leave_lock)
1265 for (
unsigned int i = 0; i <
mdata->newsrc_len; i++)
1276 if (anum >
mdata->last_cached)
1298 mdata->subscribed =
true;
1299 if (!
mdata->newsrc_ent)
1302 mdata->newsrc_len = 1;
1303 mdata->newsrc_ent[0].first = 1;
1304 mdata->newsrc_ent[0].last = 0;
1325 mdata->subscribed =
false;
1327 if (!c_save_unsubscribed)
1329 mdata->newsrc_len = 0;
1353 if (
mdata->newsrc_ent)
1356 mdata->newsrc_len = 1;
1357 mdata->newsrc_ent[0].first = 1;
1358 mdata->newsrc_ent[0].last =
mdata->last_message;
1363 for (
unsigned int i = 0; i < m->
msg_count; i++)
1392 if (
mdata->newsrc_ent)
1395 mdata->newsrc_len = 1;
1396 mdata->newsrc_ent[0].first = 1;
1397 mdata->newsrc_ent[0].last =
mdata->first_message - 1;
1402 for (
unsigned int i = 0; i < m->
msg_count; i++)
1442 for (
unsigned int j = 0; j < m->
msg_count; j++)
1471 { -1, -1, NULL, NULL },
Body Caching (local copies of email bodies)
struct BodyCache * mutt_bcache_open(struct ConnAccount *account, const char *mailbox)
Open an Email-Body Cache.
int mutt_bcache_list(struct BodyCache *bcache, bcache_list_t want_id, void *data)
Find matching entries in the Body Cache.
void mutt_bcache_close(struct BodyCache **ptr)
Close an Email-Body Cache.
int mutt_bcache_del(struct BodyCache *bcache, const char *id)
Delete a file from the Body Cache.
int buf_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
int buf_add_printf(struct Buffer *buf, const char *fmt,...)
Format a string appending a Buffer.
size_t buf_addch(struct Buffer *buf, char c)
Add a single character to a Buffer.
size_t buf_addstr(struct Buffer *buf, const char *s)
Add a string to a Buffer.
size_t buf_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
char * buf_strdup(const struct Buffer *buf)
Copy a Buffer's string.
static const char * buf_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
const char * cs_subset_string(const struct ConfigSubset *sub, const char *name)
Get a string config item by name.
const char * cs_subset_path(const struct ConfigSubset *sub, const char *name)
Get a path config item by name.
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
short cs_subset_sort(const struct ConfigSubset *sub, const char *name)
Get a sort config item by name.
const struct Expando * cs_subset_expando(const struct ConfigSubset *sub, const char *name)
Get an Expando config item by name.
Convenience wrapper for the config headers.
ConnAccountField
Login credentials.
@ MUTT_CA_OAUTH_CMD
OAuth refresh command.
@ MUTT_CA_LOGIN
Login name.
@ MUTT_CA_HOST
Server name.
#define MUTT_ACCT_SSL
Account uses SSL/TLS.
@ ED_NTP_SCHEMA
ConnAccount.account.
@ ED_NTP_USERNAME
ConnAccount.user.
@ ED_NTP_PORT_IF
ConnAccount.port.
@ ED_NTP_SERVER
ConnAccount.account.
@ ED_NTP_ACCOUNT
ConnAccount.account.
@ ED_NTP_PORT
ConnAccount.port.
#define MUTT_ACCT_PASS
Password field has been set.
#define MUTT_ACCT_USER
User field has been set.
#define MUTT_ACCT_PORT
Port field has been set.
Convenience wrapper for the core headers.
void mailbox_changed(struct Mailbox *m, enum NotifyMailbox action)
Notify observers of a change to a Mailbox.
@ NT_MAILBOX_RESORT
Email list needs resorting.
@ MUTT_NNTP
'NNTP' (Usenet) Mailbox type
@ ED_NNTP
Nntp ED_NTP_ ExpandoDataNntp.
Structs that make up an email.
int expando_filter(const struct Expando *exp, const struct ExpandoRenderData *rdata, void *data, MuttFormatFlags flags, int max_cols, struct Buffer *buf)
Render an Expando and run the result through a filter.
int mutt_file_mkdir(const char *path, mode_t mode)
Recursively create directories.
int mutt_file_lock(int fd, bool excl, bool timeout)
(Try to) Lock a file using fcntl()
int mutt_file_unlock(int fd)
Unlock a file previously locked by mutt_file_lock()
DIR * mutt_file_opendir(const char *path, enum MuttOpenDirMode mode)
Open a directory.
@ MUTT_OPENDIR_NONE
Plain opendir()
#define mutt_file_fclose(FP)
#define mutt_file_fopen(PATH, MODE)
void mutt_set_flag(struct Mailbox *m, struct Email *e, enum MessageType flag, bool bf, bool upd_mbox)
Set a flag on an email.
static int nntp_bcache_delete(const char *id, struct BodyCache *bcache, void *data)
Delete an entry from the message cache - Implements bcache_list_t -.
static const char * nntp_get_field(enum ConnAccountField field, void *gf_data)
Get connection login credentials - Implements ConnAccount::get_field() -.
long nntp_p_num(const struct ExpandoNode *node, void *data, MuttFormatFlags flags)
Newsrc: Port - Implements ExpandoRenderData::get_number() -.
long nntp_P_num(const struct ExpandoNode *node, void *data, MuttFormatFlags flags)
Newsrc: Port if specified - Implements ExpandoRenderData::get_number() -.
void nntp_s(const struct ExpandoNode *node, void *data, MuttFormatFlags flags, int max_cols, struct Buffer *buf)
Newsrc: News server name - Implements ExpandoRenderData::get_string() -.
void nntp_P(const struct ExpandoNode *node, void *data, MuttFormatFlags flags, int max_cols, struct Buffer *buf)
Newsrc: Port if specified - Implements ExpandoRenderData::get_string() -.
void nntp_a(const struct ExpandoNode *node, void *data, MuttFormatFlags flags, int max_cols, struct Buffer *buf)
Newsrc: Account url - Implements ExpandoRenderData::get_string() -.
void nntp_u(const struct ExpandoNode *node, void *data, MuttFormatFlags flags, int max_cols, struct Buffer *buf)
Newsrc: Username - Implements ExpandoRenderData::get_string() -.
void nntp_S(const struct ExpandoNode *node, void *data, MuttFormatFlags flags, int max_cols, struct Buffer *buf)
Newsrc: Url schema - Implements ExpandoRenderData::get_string() -.
static void nntp_hcache_namer(const char *path, struct Buffer *dest)
Compose hcache file names - Implements hcache_namer_t -.
#define mutt_message(...)
#define mutt_debug(LEVEL,...)
struct HashElem * mutt_hash_insert(struct HashTable *table, const char *strkey, void *data)
Add a new element to the Hash Table (with string keys)
void * mutt_hash_find(const struct HashTable *table, const char *strkey)
Find the HashElem data in a Hash Table element using a key.
void mutt_hash_free(struct HashTable **ptr)
Free a hash table.
struct HeaderCache * hcache_open(const char *path, const char *folder, hcache_namer_t namer, bool create)
Multiplexor for StoreOps::open.
int hcache_delete_email(struct HeaderCache *hc, const char *key, size_t keylen)
Multiplexor for StoreOps::delete_record.
void hcache_close(struct HeaderCache **ptr)
Multiplexor for StoreOps::close.
char * hcache_fetch_raw_str(struct HeaderCache *hc, const char *key, size_t keylen)
Fetch a string from the cache.
int hcache_store_raw(struct HeaderCache *hc, const char *key, size_t keylen, void *data, size_t dlen)
Store a key / data pair.
Header cache multiplexor.
@ LL_DEBUG2
Log at debug level 2.
@ LL_DEBUG1
Log at debug level 1.
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
void * mutt_mem_malloc(size_t size)
Allocate memory on the heap.
void mutt_mem_realloc(void *ptr, size_t size)
Resize a block of memory on the heap.
Convenience wrapper for the library headers.
char * mutt_str_dup(const char *str)
Copy a string, safely.
char * mutt_str_lower(char *str)
Convert all characters in the string to lowercase.
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
size_t mutt_str_copy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)
char * mutt_str_replace(char **p, const char *s)
Replace one string with another.
Many unsorted constants and some structs.
@ MUTT_READ
Messages that have been read.
int mutt_account_fromurl(struct ConnAccount *cac, const struct Url *url)
Fill ConnAccount with information from url.
void mutt_account_tourl(struct ConnAccount *cac, struct Url *url)
Fill URL with info from account.
ConnAccount object used by POP and IMAP.
@ MUTT_ACCT_TYPE_NNTP
Nntp (Usenet) Account.
void mutt_clear_error(void)
Clear the message line (bottom line of screen)
struct Connection * mutt_conn_find(const struct ConnAccount *cac)
Find a connection from a list.
void buf_expand_path(struct Buffer *buf)
Create the canonical path.
void mutt_encode_path(struct Buffer *buf, const char *src)
Convert a path to 'us-ascii'.
Some miscellaneous functions.
struct HeaderCache * nntp_hcache_open(struct NntpMboxData *mdata)
Open newsgroup hcache.
void nntp_clear_cache(struct NntpAccountData *adata)
Clear the NNTP cache.
void nntp_delete_group_cache(struct NntpMboxData *mdata)
Remove hcache and bcache of newsgroup.
const struct ExpandoRenderData NntpRenderData[]
Callbacks for Newsrc Expandos.
void nntp_newsrc_gen_entries(struct Mailbox *m)
Generate array of .newsrc entries.
void nntp_hcache_update(struct NntpMboxData *mdata, struct HeaderCache *hc)
Remove stale cached headers.
void nntp_article_status(struct Mailbox *m, struct Email *e, char *group, anum_t anum)
Get status of articles from .newsrc.
static int update_file(char *filename, char *buf)
Update file with new contents.
int nntp_add_group(char *line, void *data)
Parse newsgroup.
int nntp_newsrc_parse(struct NntpAccountData *adata)
Parse .newsrc file.
void nntp_mailbox(struct Mailbox *m, char *buf, size_t buflen)
Get first newsgroup with new messages.
void nntp_newsrc_close(struct NntpAccountData *adata)
Unlock and close .newsrc file.
struct NntpMboxData * mutt_newsgroup_catchup(struct Mailbox *m, struct NntpAccountData *adata, char *group)
Catchup newsgroup.
int nntp_newsrc_update(struct NntpAccountData *adata)
Update .newsrc file.
struct NntpMboxData * mutt_newsgroup_subscribe(struct NntpAccountData *adata, char *group)
Subscribe newsgroup.
void nntp_expand_path(char *buf, size_t buflen, struct ConnAccount *cac)
Make fully qualified url from newsgroup name.
static int active_get_cache(struct NntpAccountData *adata)
Load list of all newsgroups from cache.
static void cache_expand(char *dst, size_t dstlen, struct ConnAccount *cac, const char *src)
Make fully qualified cache file name.
static struct NntpMboxData * mdata_find(struct NntpAccountData *adata, const char *group)
Find NntpMboxData for given newsgroup or add it.
struct NntpMboxData * mutt_newsgroup_uncatchup(struct Mailbox *m, struct NntpAccountData *adata, char *group)
Uncatchup newsgroup.
int nntp_active_save_cache(struct NntpAccountData *adata)
Save list of all newsgroups to cache.
void nntp_bcache_update(struct NntpMboxData *mdata)
Remove stale cached messages.
void nntp_group_unread_stat(struct NntpMboxData *mdata)
Count number of unread articles using .newsrc data.
void nntp_acache_free(struct NntpMboxData *mdata)
Remove all temporarily cache files.
struct NntpAccountData * nntp_select_server(struct Mailbox *m, const char *server, bool leave_lock)
Open a connection to an NNTP server.
struct NntpMboxData * mutt_newsgroup_unsubscribe(struct NntpAccountData *adata, char *group)
Unsubscribe newsgroup.
struct NntpAccountData * nntp_adata_new(struct Connection *conn)
Allocate and initialise a new NntpAccountData structure.
struct NntpEmailData * nntp_edata_get(struct Email *e)
Get the private data for this Email.
int nntp_active_fetch(struct NntpAccountData *adata, bool mark_new)
Fetch list of all newsgroups from server.
struct NntpAccountData * CurrentNewsSrv
Current NNTP news server.
int nntp_check_new_groups(struct Mailbox *m, struct NntpAccountData *adata)
Check for new groups/articles in subscribed groups.
int nntp_open_connection(struct NntpAccountData *adata)
Connect to server, authenticate and get capabilities.
Notmuch-specific Mailbox data.
struct Buffer * buf_pool_get(void)
Get a Buffer from the pool.
void buf_pool_release(struct Buffer **ptr)
Return a Buffer to the pool.
Pop-specific Account data.
Prototypes for many functions.
#define MUTT_FORMAT_NO_FLAGS
No flags are set.
uint8_t MuttFormatFlags
Flags for expando_render(), e.g. MUTT_FORMAT_FORCESUBJ.
int mutt_socket_close(struct Connection *conn)
Close a socket.
SortType
Methods for sorting.
@ SORT_ORDER
Sort by the order the messages appear in the mailbox.
void * adata
Private data (for Mailbox backends)
Local cache of email bodies.
String manipulation buffer.
size_t dsize
Length of data.
char * data
Pointer to data.
Login details for a remote server.
const char * service
Name of the service, e.g. "imap".
char host[128]
Server to login to.
const char *(* get_field)(enum ConnAccountField field, void *gf_data)
unsigned char type
Connection type, e.g. MUTT_ACCT_TYPE_IMAP.
MuttAccountFlags flags
Which fields are initialised, e.g. MUTT_ACCT_USER.
void * gf_data
Private data to pass to get_field()
unsigned short port
Port to connect to.
struct ConnAccount account
Account details: username, password, etc.
The envelope/body of an email.
bool old
Email is seen, but unread.
bool deleted
Email is deleted.
int msg_count
Total number of messages.
enum MailboxType type
Mailbox type.
void * mdata
Driver specific data.
struct Email ** emails
Array of Emails.
Container for Accounts, Notifications.
struct ConfigSubset * sub
Inherited config items.
An entry in a .newsrc (subscribed newsgroups)
anum_t last
Last article number in run.
anum_t first
First article number in run.
NNTP-specific Account data -.
struct HashTable * groups_hash
Hash Table: "newsgroup" -> NntpMboxData.
struct Connection * conn
Connection to NNTP Server.
anum_t article_num
NNTP article number.
NNTP-specific Mailbox data -.
struct BodyCache * bcache
char * group
Name of newsgroup.
struct NntpAccountData * adata
char * desc
Description of newsgroup.
struct NewsrcEntry * newsrc_ent
A parsed URL proto://user:password@host:port/path?a=1&b=2
char * src
Raw URL string.
enum UrlScheme scheme
Scheme, e.g. U_SMTPS.
int cs_subset_str_native_set(const struct ConfigSubset *sub, const char *name, intptr_t value, struct Buffer *err)
Natively set the value of a string config item.
struct Url * url_parse(const char *src)
Fill in Url.
void url_free(struct Url **ptr)
Free the contents of a URL.
int url_tostring(const struct Url *url, char *dest, size_t len, uint8_t flags)
Output the URL string for a given Url object.
@ U_NNTPS
Url is nntps://.