80 size_t len = strlen(
group) + 1;
86 mdata->deleted =
true;
108 if (
mdata->acache[i].path)
110 unlink(
mdata->acache[i].path);
137 if ((
mdata->last_message == 0) ||
144 for (
unsigned int i = 0; i <
mdata->newsrc_len; i++)
148 first =
mdata->first_message;
150 if (last >
mdata->last_message)
151 last =
mdata->last_message;
153 mdata->unread -= last - first + 1;
170 struct stat st = { 0 };
207 if ((adata->
size == st.st_size) && (adata->
mtime == st.st_mtime))
210 adata->
size = st.st_size;
211 adata->
mtime = st.st_mtime;
216 for (
unsigned int i = 0; i < adata->
groups_num; i++)
222 mdata->subscribed =
false;
223 mdata->newsrc_len = 0;
228 while (st.st_size && fgets(line, st.st_size + 1,
adata->
fp_newsrc))
230 char *b = NULL, *h = NULL;
235 char *p = strpbrk(line,
":!");
254 mdata->subscribed = subs;
274 if ((sscanf(b,
ANUM_FMT, &
mdata->newsrc_ent[j].first) == 1) &&
282 mdata->newsrc_ent[j].first = 1;
283 mdata->newsrc_ent[j].last = 0;
286 if (
mdata->last_message == 0)
287 mdata->last_message =
mdata->newsrc_ent[j - 1].last;
288 mdata->newsrc_len = j;
307 anum_t last = 0, first = 1;
309 unsigned int entries;
318 entries =
mdata->newsrc_len;
327 mdata->newsrc_len = 0;
366 if (series && (first <= mdata->last_loaded))
401 snprintf(tmpfile,
sizeof(tmpfile),
"%s.tmp", filename);
409 if (fputs(buf, fp) == EOF)
421 if (rename(tmpfile, filename) < 0)
450 size_t buflen = 10240;
455 for (
unsigned int i = 0; i < adata->
groups_num; i++)
463 if ((off + strlen(
mdata->group) + 3) > buflen)
468 snprintf(buf + off, buflen - off,
"%s%c ",
mdata->group,
mdata->subscribed ?
':' :
'!');
469 off += strlen(buf + off);
472 for (
unsigned int j = 0; j <
mdata->newsrc_len; j++)
474 if ((off + 1024) > buflen)
481 if (
mdata->newsrc_ent[j].first ==
mdata->newsrc_ent[j].last)
483 snprintf(buf + off, buflen - off,
ANUM_FMT,
mdata->newsrc_ent[j].first);
485 else if (
mdata->newsrc_ent[j].first <
mdata->newsrc_ent[j].last)
488 mdata->newsrc_ent[j].first,
mdata->newsrc_ent[j].last);
490 off += strlen(buf + off);
500 struct stat st = { 0 };
505 adata->
size = st.st_size;
506 adata->
mtime = st.st_mtime;
529 struct Url url = { 0 };
536 char *c = file + strlen(file) - 1;
545 snprintf(dst, dstlen,
"%s/%s", c_news_cache_dir,
buf_string(tmp));
558 struct Url url = { 0 };
576 char group[1024] = { 0 };
577 char desc[8192] = { 0 };
579 anum_t first = 0, last = 0;
586 &last, &first, &mod,
desc) < 4)
593 mdata->deleted =
false;
594 mdata->first_message = first;
595 mdata->last_message = last;
596 mdata->allowed = (mod ==
'y') || (mod ==
'm');
598 if (
mdata->newsrc_ent || (
mdata->last_cached != 0))
600 else if (
mdata->last_message && (
mdata->first_message <=
mdata->last_message))
615 char buf[8192] = { 0 };
616 char file[4096] = { 0 };
625 if (!fgets(buf,
sizeof(buf), fp) || (sscanf(buf,
"%jd%4095s", &t, file) != 1) || (t == 0))
633 while (fgets(buf,
sizeof(buf), fp))
652 size_t buflen = 10240;
655 size_t off = strlen(buf);
664 if ((off + strlen(
mdata->group) + (
mdata->desc ? strlen(
mdata->desc) : 0) + 50) > buflen)
671 mdata->allowed ?
'y' :
'n',
mdata->desc ?
" " :
"",
673 off += strlen(buf + off);
695 if (first && last && (last > first))
697 memmove(first, last, strlen(last) + 1);
709 struct Url url = { 0 };
736 char buf[32] = { 0 };
738 anum_t first = 0, last = 0;
751 for (
anum_t current = first; current <= last; current++)
753 if ((current >= mdata->
first_message) && (current <= mdata->last_message))
756 snprintf(buf,
sizeof(buf),
ANUM_FMT, current);
846 struct dirent *de = NULL;
859 while ((de = readdir(dir)))
861 char *group = de->d_name;
866 struct stat st = { 0 };
871 if (S_ISREG(st.st_mode))
873 char *ext = group + strlen(group) - 7;
880 if (!S_ISDIR(st.st_mode))
890 mdata->bcache = NULL;
892 else if (
mdata->newsrc_ent ||
mdata->subscribed || c_save_unsubscribed)
898 if (S_ISDIR(st.st_mode))
953 if (!server || (*server ==
'\0'))
966 snprintf(file,
sizeof(file),
"%s%s", strstr(server,
"://") ?
"" :
"news://", server);
968 if (!url || (url->
path && *url->
path) ||
973 mutt_error(
_(
"%s is an invalid news server specification"), server);
984 const char *
user = NULL;
985 const char *
pass = NULL;
1015 if ((rc >= 0) && c_news_cache_dir)
1020 mutt_error(
_(
"Can't create %s: %s"), file, strerror(errno));
1058 struct dirent *de = NULL;
1063 while ((de = readdir(dir)))
1066 char *group = de->d_name;
1068 char *p = group + strlen(group) - 7;
1084 anum_t first = 0, last = 0;
1090 mdata->first_message = first;
1091 mdata->last_message = last;
1095 mdata->last_cached = last;
1108 if ((rc < 0) || !leave_lock)
1148 for (
unsigned int i = 0; i <
mdata->newsrc_len; i++)
1159 if (anum >
mdata->last_cached)
1181 mdata->subscribed =
true;
1182 if (!
mdata->newsrc_ent)
1185 mdata->newsrc_len = 1;
1186 mdata->newsrc_ent[0].first = 1;
1187 mdata->newsrc_ent[0].last = 0;
1208 mdata->subscribed =
false;
1210 if (!c_save_unsubscribed)
1212 mdata->newsrc_len = 0;
1236 if (
mdata->newsrc_ent)
1239 mdata->newsrc_len = 1;
1240 mdata->newsrc_ent[0].first = 1;
1241 mdata->newsrc_ent[0].last =
mdata->last_message;
1246 for (
unsigned int i = 0; i < m->
msg_count; i++)
1275 if (
mdata->newsrc_ent)
1278 mdata->newsrc_len = 1;
1279 mdata->newsrc_ent[0].first = 1;
1280 mdata->newsrc_ent[0].last =
mdata->first_message - 1;
1285 for (
unsigned int i = 0; i < m->
msg_count; i++)
1325 for (
unsigned int j = 0; j < m->
msg_count; j++)
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.
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.
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.
#define MUTT_ACCT_PASS
Password field has been set.
#define MUTT_ACCT_USER
User 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
Structs that make up an email.
EmailSortType
Methods for sorting Emails.
@ EMAIL_SORT_UNSORTED
Sort by the order the messages appear in the mailbox.
int expando_filter(const struct Expando *exp, const struct ExpandoRenderCallback *erc, void *data, MuttFormatFlags flags, int max_cols, struct Buffer *buf)
Render an Expando and run the result through a filter.
const struct ExpandoRenderCallback NntpRenderCallbacks[]
Callbacks for Newsrc Expandos.
NNTP Expando definitions.
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() -.
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.
#define MUTT_MEM_CALLOC(n, type)
#define MUTT_MEM_REALLOC(pptr, n, type)
#define MUTT_MEM_MALLOC(n, type)
Convenience wrapper for the library headers.
char * mutt_str_dup(const char *str)
Copy a string, safely.
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.
void account_to_url(struct ConnAccount *cac, struct Url *url)
Fill URL with info from account.
int account_from_url(struct ConnAccount *cac, const struct Url *url)
Fill ConnAccount with information from url.
@ 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.
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.
int mutt_socket_close(struct Connection *conn)
Close a socket.
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".
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.
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 NntpMboxData ** groups_list
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://.