NeoMutt  2024-04-25-97-g7d2481
Teaching an old dog new tricks
DOXYGEN
Loading...
Searching...
No Matches
lib.h File Reference

Usenet network mailbox type; talk to an NNTP server. More...

#include <stdbool.h>
#include <stdio.h>
#include "core/lib.h"
#include "expando/lib.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  NntpAcache
 NNTP article cache. More...
 
struct  NewsrcEntry
 An entry in a .newsrc (subscribed newsgroups) More...
 

Macros

#define anum_t   long
 
#define ANUM_FMT   "%ld"
 
#define NNTP_ACACHE_LEN   10
 

Functions

struct NntpAccountDatanntp_select_server (struct Mailbox *m, const char *server, bool leave_lock)
 Open a connection to an NNTP server.
 
struct NntpMboxDatamutt_newsgroup_subscribe (struct NntpAccountData *adata, char *group)
 Subscribe newsgroup.
 
struct NntpMboxDatamutt_newsgroup_unsubscribe (struct NntpAccountData *adata, char *group)
 Unsubscribe newsgroup.
 
struct NntpMboxDatamutt_newsgroup_catchup (struct Mailbox *m, struct NntpAccountData *adata, char *group)
 Catchup newsgroup.
 
struct NntpMboxDatamutt_newsgroup_uncatchup (struct Mailbox *m, struct NntpAccountData *adata, char *group)
 Uncatchup newsgroup.
 
int nntp_active_fetch (struct NntpAccountData *adata, bool mark_new)
 Fetch list of all newsgroups from server.
 
int nntp_newsrc_update (struct NntpAccountData *adata)
 Update .newsrc file.
 
int nntp_post (struct Mailbox *m, const char *msg)
 Post article.
 
int nntp_check_msgid (struct Mailbox *m, const char *msgid)
 Fetch article by Message-ID.
 
int nntp_check_children (struct Mailbox *m, const char *msgid)
 Fetch children of article with the Message-ID.
 
int nntp_newsrc_parse (struct NntpAccountData *adata)
 Parse .newsrc file.
 
void nntp_newsrc_close (struct NntpAccountData *adata)
 Unlock and close .newsrc file.
 
void nntp_mailbox (struct Mailbox *m, char *buf, size_t buflen)
 Get first newsgroup with new messages.
 
void nntp_expand_path (char *buf, size_t buflen, struct ConnAccount *acct)
 Make fully qualified url from newsgroup name.
 
void nntp_clear_cache (struct NntpAccountData *adata)
 Clear the NNTP cache.
 
int nntp_compare_order (const struct Email *a, const struct Email *b, bool reverse)
 Restore the 'unsorted' order of emails - Implements sort_mail_t -.
 
enum MailboxType nntp_path_probe (const char *path, const struct stat *st)
 Is this an NNTP Mailbox? - Implements MxOps::path_probe() -.
 
int nntp_complete (struct Buffer *buf)
 Auto-complete NNTP newsgroups.
 
void group_index_d (const struct ExpandoNode *node, void *data, MuttFormatFlags flags, int max_cols, struct Buffer *buf)
 NNTP: Description - Implements ExpandoRenderData::get_string() -.
 
void group_index_f (const struct ExpandoNode *node, void *data, MuttFormatFlags flags, int max_cols, struct Buffer *buf)
 NNTP: Newsgroup name - Implements ExpandoRenderData::get_string() -.
 
void group_index_M (const struct ExpandoNode *node, void *data, MuttFormatFlags flags, int max_cols, struct Buffer *buf)
 NNTP: Moderated flag - Implements ExpandoRenderData::get_string() -.
 
void group_index_N (const struct ExpandoNode *node, void *data, MuttFormatFlags flags, int max_cols, struct Buffer *buf)
 NNTP: New flag - Implements ExpandoRenderData::get_string() -.
 
long group_index_a_num (const struct ExpandoNode *node, void *data, MuttFormatFlags flags)
 NNTP: Alert for new mail - Implements ExpandoRenderData::get_number() -.
 
long group_index_C_num (const struct ExpandoNode *node, void *data, MuttFormatFlags flags)
 NNTP: Index number - Implements ExpandoRenderData::get_number() -.
 
long group_index_n_num (const struct ExpandoNode *node, void *data, MuttFormatFlags flags)
 NNTP: Number of new articles - Implements ExpandoRenderData::get_number() -.
 
long group_index_p_num (const struct ExpandoNode *node, void *data, MuttFormatFlags flags)
 NNTP: Poll for new mail - Implements ExpandoRenderData::get_number() -.
 
long group_index_s_num (const struct ExpandoNode *node, void *data, MuttFormatFlags flags)
 NNTP: Number of unread articles - Implements ExpandoRenderData::get_number() -.
 
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_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_S (const struct ExpandoNode *node, void *data, MuttFormatFlags flags, int max_cols, struct Buffer *buf)
 Newsrc: Url schema - Implements ExpandoRenderData::get_string() -.
 
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_u (const struct ExpandoNode *node, void *data, MuttFormatFlags flags, int max_cols, struct Buffer *buf)
 Newsrc: Username - Implements ExpandoRenderData::get_string() -.
 
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() -.
 

Variables

struct NntpAccountDataCurrentNewsSrv
 Current NNTP news server.
 
const struct MxOps MxNntpOps
 NNTP Mailbox - Implements MxOps -.
 
const struct ExpandoRenderData NntpRenderData []
 Callbacks for Newsrc Expandos.
 

Detailed Description

Usenet network mailbox type; talk to an NNTP server.

Authors
  • Richard Russon
  • Tóth János

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.

Macro Definition Documentation

◆ anum_t

#define anum_t   long

Definition at line 60 of file lib.h.

◆ ANUM_FMT

#define ANUM_FMT   "%ld"

Definition at line 61 of file lib.h.

◆ NNTP_ACACHE_LEN

#define NNTP_ACACHE_LEN   10

Definition at line 82 of file lib.h.

Function Documentation

◆ nntp_select_server()

struct NntpAccountData * nntp_select_server ( struct Mailbox m,
const char *  server,
bool  leave_lock 
)

Open a connection to an NNTP server.

Parameters
mMailbox
serverServer URL
leave_lockLeave the server locked?
Return values
ptrNNTP server
NULLError

Automatically loads a newsrc into memory, if necessary. Checks the size/mtime of a newsrc file, if it doesn't match, load again. Hmm, if a system has broken mtimes, this might mean the file is reloaded every time, which we'd have to fix.

See also
$newsrc

Definition at line 1063 of file newsrc.c.

1064{
1065 char file[PATH_MAX] = { 0 };
1066 int rc;
1067 struct ConnAccount cac = { { 0 } };
1068 struct NntpAccountData *adata = NULL;
1069 struct Connection *conn = NULL;
1070
1071 if (!server || (*server == '\0'))
1072 {
1073 mutt_error(_("No news server defined"));
1074 return NULL;
1075 }
1076
1077 /* create account from news server url */
1078 cac.flags = 0;
1079 cac.port = NNTP_PORT;
1081 cac.service = "nntp";
1083
1084 snprintf(file, sizeof(file), "%s%s", strstr(server, "://") ? "" : "news://", server);
1085 struct Url *url = url_parse(file);
1086 if (!url || (url->path && *url->path) ||
1087 !((url->scheme == U_NNTP) || (url->scheme == U_NNTPS)) || !url->host ||
1088 (mutt_account_fromurl(&cac, url) < 0))
1089 {
1090 url_free(&url);
1091 mutt_error(_("%s is an invalid news server specification"), server);
1092 return NULL;
1093 }
1094 if (url->scheme == U_NNTPS)
1095 {
1096 cac.flags |= MUTT_ACCT_SSL;
1097 cac.port = NNTP_SSL_PORT;
1098 }
1099 url_free(&url);
1100
1101 // If nntp_user and nntp_pass are specified in the config, use them to find the connection
1102 const char *user = NULL;
1103 const char *pass = NULL;
1104 if ((user = cac.get_field(MUTT_CA_USER, NULL)))
1105 {
1106 mutt_str_copy(cac.user, user, sizeof(cac.user));
1107 cac.flags |= MUTT_ACCT_USER;
1108 }
1109 if ((pass = cac.get_field(MUTT_CA_PASS, NULL)))
1110 {
1111 mutt_str_copy(cac.pass, pass, sizeof(cac.pass));
1112 cac.flags |= MUTT_ACCT_PASS;
1113 }
1114
1115 /* find connection by account */
1116 conn = mutt_conn_find(&cac);
1117 if (!conn)
1118 return NULL;
1119 if (!(conn->account.flags & MUTT_ACCT_USER) && cac.flags & MUTT_ACCT_USER)
1120 {
1121 conn->account.flags |= MUTT_ACCT_USER;
1122 conn->account.user[0] = '\0';
1123 }
1124
1125 /* new news server */
1126 adata = nntp_adata_new(conn);
1127
1128 rc = nntp_open_connection(adata);
1129
1130 /* try to create cache directory and enable caching */
1131 adata->cacheable = false;
1132 const char *const c_news_cache_dir = cs_subset_path(NeoMutt->sub, "news_cache_dir");
1133 if ((rc >= 0) && c_news_cache_dir)
1134 {
1135 cache_expand(file, sizeof(file), &conn->account, NULL);
1136 if (mutt_file_mkdir(file, S_IRWXU) < 0)
1137 {
1138 mutt_error(_("Can't create %s: %s"), file, strerror(errno));
1139 }
1140 adata->cacheable = true;
1141 }
1142
1143 /* load .newsrc */
1144 if (rc >= 0)
1145 {
1146 const struct Expando *c_newsrc = cs_subset_expando(NeoMutt->sub, "newsrc");
1147 struct Buffer *buf = buf_pool_get();
1148 expando_filter(c_newsrc, NntpRenderData, adata, MUTT_FORMAT_NO_FLAGS, buf->dsize, buf);
1149 buf_expand_path(buf);
1150 adata->newsrc_file = buf_strdup(buf);
1151 buf_pool_release(&buf);
1152 rc = nntp_newsrc_parse(adata);
1153 }
1154 if (rc >= 0)
1155 {
1156 /* try to load list of newsgroups from cache */
1157 if (adata->cacheable && (active_get_cache(adata) == 0))
1158 {
1159 rc = nntp_check_new_groups(m, adata);
1160 }
1161 else
1162 {
1163 /* load list of newsgroups from server */
1164 rc = nntp_active_fetch(adata, false);
1165 }
1166 }
1167
1168 if (rc >= 0)
1169 nntp_clear_cache(adata);
1170
1171#ifdef USE_HCACHE
1172 /* check cache files */
1173 if ((rc >= 0) && adata->cacheable)
1174 {
1175 struct dirent *de = NULL;
1176 DIR *dir = mutt_file_opendir(file, MUTT_OPENDIR_NONE);
1177
1178 if (dir)
1179 {
1180 while ((de = readdir(dir)))
1181 {
1182 struct HeaderCache *hc = NULL;
1183 char *group = de->d_name;
1184
1185 char *p = group + strlen(group) - 7;
1186 if ((strlen(group) < 8) || !mutt_str_equal(p, ".hcache"))
1187 continue;
1188 *p = '\0';
1190 if (!mdata)
1191 continue;
1192
1193 hc = nntp_hcache_open(mdata);
1194 if (!hc)
1195 continue;
1196
1197 /* fetch previous values of first and last */
1198 char *hdata = hcache_fetch_raw_str(hc, "index", 5);
1199 if (hdata)
1200 {
1201 anum_t first = 0, last = 0;
1202
1203 if (sscanf(hdata, ANUM_FMT " " ANUM_FMT, &first, &last) == 2)
1204 {
1205 if (mdata->deleted)
1206 {
1207 mdata->first_message = first;
1208 mdata->last_message = last;
1209 }
1210 if ((last >= mdata->first_message) && (last <= mdata->last_message))
1211 {
1212 mdata->last_cached = last;
1213 mutt_debug(LL_DEBUG2, "%s last_cached=" ANUM_FMT "\n", mdata->group, last);
1214 }
1215 }
1216 FREE(&hdata);
1217 }
1218 hcache_close(&hc);
1219 }
1220 closedir(dir);
1221 }
1222 }
1223#endif
1224
1225 if ((rc < 0) || !leave_lock)
1227
1228 if (rc < 0)
1229 {
1234 FREE(&adata);
1235 mutt_socket_close(conn);
1236 FREE(&conn);
1237 return NULL;
1238 }
1239
1240 return adata;
1241}
char * buf_strdup(const struct Buffer *buf)
Copy a Buffer's string.
Definition: buffer.c:571
const char * cs_subset_path(const struct ConfigSubset *sub, const char *name)
Get a path config item by name.
Definition: helpers.c:168
const struct Expando * cs_subset_expando(const struct ConfigSubset *sub, const char *name)
Get an Expando config item by name.
Definition: config_type.c:357
@ MUTT_CA_USER
User name.
Definition: connaccount.h:36
@ MUTT_CA_PASS
Password.
Definition: connaccount.h:37
#define MUTT_ACCT_SSL
Account uses SSL/TLS.
Definition: connaccount.h:47
#define MUTT_ACCT_PASS
Password field has been set.
Definition: connaccount.h:46
#define MUTT_ACCT_USER
User field has been set.
Definition: connaccount.h:44
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.
Definition: filter.c:141
int mutt_file_mkdir(const char *path, mode_t mode)
Recursively create directories.
Definition: file.c:974
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:74
static const char * nntp_get_field(enum ConnAccountField field, void *gf_data)
Get connection login credentials - Implements ConnAccount::get_field() -.
Definition: newsrc.c:1032
#define mutt_error(...)
Definition: logging2.h:92
#define mutt_debug(LEVEL,...)
Definition: logging2.h:89
void * mutt_hash_find(const struct HashTable *table, const char *strkey)
Find the HashElem data in a Hash Table element using a key.
Definition: hash.c:362
void mutt_hash_free(struct HashTable **ptr)
Free a hash table.
Definition: hash.c:457
void hcache_close(struct HeaderCache **ptr)
Multiplexor for StoreOps::close.
Definition: hcache.c:545
char * hcache_fetch_raw_str(struct HeaderCache *hc, const char *key, size_t keylen)
Fetch a string from the cache.
Definition: hcache.c:655
@ LL_DEBUG2
Log at debug level 2.
Definition: logging2.h:44
#define FREE(x)
Definition: memory.h:45
#define _(a)
Definition: message.h:28
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:660
size_t mutt_str_copy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)
Definition: string.c:581
#define PATH_MAX
Definition: mutt.h:42
int mutt_account_fromurl(struct ConnAccount *cac, const struct Url *url)
Fill ConnAccount with information from url.
Definition: mutt_account.c:44
@ MUTT_ACCT_TYPE_NNTP
Nntp (Usenet) Account.
Definition: mutt_account.h:41
struct Connection * mutt_conn_find(const struct ConnAccount *cac)
Find a connection from a list.
Definition: mutt_socket.c:90
void buf_expand_path(struct Buffer *buf)
Create the canonical path.
Definition: muttlib.c:315
struct HeaderCache * nntp_hcache_open(struct NntpMboxData *mdata)
Open newsgroup hcache.
Definition: newsrc.c:709
void nntp_clear_cache(struct NntpAccountData *adata)
Clear the NNTP cache.
Definition: newsrc.c:843
const struct ExpandoRenderData NntpRenderData[]
Callbacks for Newsrc Expandos.
Definition: newsrc.c:67
int nntp_newsrc_parse(struct NntpAccountData *adata)
Parse .newsrc file.
Definition: newsrc.c:166
void nntp_newsrc_close(struct NntpAccountData *adata)
Unlock and close .newsrc file.
Definition: newsrc.c:122
static int active_get_cache(struct NntpAccountData *adata)
Load list of all newsgroups from cache.
Definition: newsrc.c:615
static void cache_expand(char *dst, size_t dstlen, struct ConnAccount *cac, const char *src)
Make fully qualified cache file name.
Definition: newsrc.c:526
struct NntpAccountData * nntp_adata_new(struct Connection *conn)
Allocate and initialise a new NntpAccountData structure.
Definition: adata.c:65
int nntp_active_fetch(struct NntpAccountData *adata, bool mark_new)
Fetch list of all newsgroups from server.
Definition: nntp.c:2037
#define ANUM_FMT
Definition: lib.h:61
#define anum_t
Definition: lib.h:60
#define NNTP_SSL_PORT
Definition: private.h:37
#define NNTP_PORT
Definition: private.h:36
int nntp_check_new_groups(struct Mailbox *m, struct NntpAccountData *adata)
Check for new groups/articles in subscribed groups.
Definition: nntp.c:2105
int nntp_open_connection(struct NntpAccountData *adata)
Connect to server, authenticate and get capabilities.
Definition: nntp.c:1766
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
#define MUTT_FORMAT_NO_FLAGS
No flags are set.
Definition: render.h:33
int mutt_socket_close(struct Connection *conn)
Close a socket.
Definition: socket.c:100
void * adata
Private data (for Mailbox backends)
Definition: account.h:42
String manipulation buffer.
Definition: buffer.h:36
size_t dsize
Length of data.
Definition: buffer.h:39
Login details for a remote server.
Definition: connaccount.h:53
char user[128]
Username.
Definition: connaccount.h:56
char pass[256]
Password.
Definition: connaccount.h:57
const char * service
Name of the service, e.g. "imap".
Definition: connaccount.h:61
const char *(* get_field)(enum ConnAccountField field, void *gf_data)
Definition: connaccount.h:70
unsigned char type
Connection type, e.g. MUTT_ACCT_TYPE_IMAP.
Definition: connaccount.h:59
MuttAccountFlags flags
Which fields are initialised, e.g. MUTT_ACCT_USER.
Definition: connaccount.h:60
unsigned short port
Port to connect to.
Definition: connaccount.h:58
struct ConnAccount account
Account details: username, password, etc.
Definition: connection.h:49
Parsed Expando trees.
Definition: expando.h:41
Header Cache.
Definition: lib.h:86
void * mdata
Driver specific data.
Definition: mailbox.h:132
Container for Accounts, Notifications.
Definition: neomutt.h:42
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:46
NNTP-specific Account data -.
Definition: adata.h:36
struct HashTable * groups_hash
Hash Table: "newsgroup" -> NntpMboxData.
Definition: adata.h:61
char * authenticators
Definition: adata.h:52
void ** groups_list
Definition: adata.h:60
bool cacheable
Definition: adata.h:48
char * newsrc_file
Definition: adata.h:51
NNTP-specific Mailbox data -.
Definition: mdata.h:34
anum_t last_message
Definition: mdata.h:38
char * group
Name of newsgroup.
Definition: mdata.h:35
struct NntpAccountData * adata
Definition: mdata.h:48
A parsed URL proto://user:password@host:port/path?a=1&b=2
Definition: url.h:69
char * user
Username.
Definition: url.h:71
char * host
Host.
Definition: url.h:73
char * pass
Password.
Definition: url.h:72
char * path
Path.
Definition: url.h:75
enum UrlScheme scheme
Scheme, e.g. U_SMTPS.
Definition: url.h:70
struct Url * url_parse(const char *src)
Fill in Url.
Definition: url.c:239
void url_free(struct Url **ptr)
Free the contents of a URL.
Definition: url.c:124
@ U_NNTPS
Url is nntps://.
Definition: url.h:42
@ U_NNTP
Url is nntp://.
Definition: url.h:41
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_newsgroup_subscribe()

struct NntpMboxData * mutt_newsgroup_subscribe ( struct NntpAccountData adata,
char *  group 
)

Subscribe newsgroup.

Parameters
adataNNTP server
groupNewsgroup
Return values
ptrNNTP data
NULLError

Definition at line 1292 of file newsrc.c.

1293{
1294 if (!adata || !adata->groups_hash || !group || (*group == '\0'))
1295 return NULL;
1296
1298 mdata->subscribed = true;
1299 if (!mdata->newsrc_ent)
1300 {
1301 mdata->newsrc_ent = mutt_mem_calloc(1, sizeof(struct NewsrcEntry));
1302 mdata->newsrc_len = 1;
1303 mdata->newsrc_ent[0].first = 1;
1304 mdata->newsrc_ent[0].last = 0;
1305 }
1306 return mdata;
1307}
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
Definition: memory.c:51
static struct NntpMboxData * mdata_find(struct NntpAccountData *adata, const char *group)
Find NntpMboxData for given newsgroup or add it.
Definition: newsrc.c:76
An entry in a .newsrc (subscribed newsgroups)
Definition: lib.h:76
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_newsgroup_unsubscribe()

struct NntpMboxData * mutt_newsgroup_unsubscribe ( struct NntpAccountData adata,
char *  group 
)

Unsubscribe newsgroup.

Parameters
adataNNTP server
groupNewsgroup
Return values
ptrNNTP data
NULLError

Definition at line 1316 of file newsrc.c.

1317{
1318 if (!adata || !adata->groups_hash || !group || (*group == '\0'))
1319 return NULL;
1320
1322 if (!mdata)
1323 return NULL;
1324
1325 mdata->subscribed = false;
1326 const bool c_save_unsubscribed = cs_subset_bool(NeoMutt->sub, "save_unsubscribed");
1327 if (!c_save_unsubscribed)
1328 {
1329 mdata->newsrc_len = 0;
1330 FREE(&mdata->newsrc_ent);
1331 }
1332 return mdata;
1333}
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition: helpers.c:47
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_newsgroup_catchup()

struct NntpMboxData * mutt_newsgroup_catchup ( struct Mailbox m,
struct NntpAccountData adata,
char *  group 
)

Catchup newsgroup.

Parameters
mMailbox
adataNNTP server
groupNewsgroup
Return values
ptrNNTP data
NULLError

Definition at line 1343 of file newsrc.c.

1345{
1346 if (!adata || !adata->groups_hash || !group || (*group == '\0'))
1347 return NULL;
1348
1350 if (!mdata)
1351 return NULL;
1352
1353 if (mdata->newsrc_ent)
1354 {
1355 mutt_mem_realloc(&mdata->newsrc_ent, sizeof(struct NewsrcEntry));
1356 mdata->newsrc_len = 1;
1357 mdata->newsrc_ent[0].first = 1;
1358 mdata->newsrc_ent[0].last = mdata->last_message;
1359 }
1360 mdata->unread = 0;
1361 if (m && (m->mdata == mdata))
1362 {
1363 for (unsigned int i = 0; i < m->msg_count; i++)
1364 {
1365 struct Email *e = m->emails[i];
1366 if (!e)
1367 break;
1368 mutt_set_flag(m, e, MUTT_READ, true, true);
1369 }
1370 }
1371 return mdata;
1372}
void mutt_set_flag(struct Mailbox *m, struct Email *e, enum MessageType flag, bool bf, bool upd_mbox)
Set a flag on an email.
Definition: flags.c:57
void mutt_mem_realloc(void *ptr, size_t size)
Resize a block of memory on the heap.
Definition: memory.c:115
@ MUTT_READ
Messages that have been read.
Definition: mutt.h:73
The envelope/body of an email.
Definition: email.h:39
int msg_count
Total number of messages.
Definition: mailbox.h:88
struct Email ** emails
Array of Emails.
Definition: mailbox.h:96
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_newsgroup_uncatchup()

struct NntpMboxData * mutt_newsgroup_uncatchup ( struct Mailbox m,
struct NntpAccountData adata,
char *  group 
)

Uncatchup newsgroup.

Parameters
mMailbox
adataNNTP server
groupNewsgroup
Return values
ptrNNTP data
NULLError

Definition at line 1382 of file newsrc.c.

1384{
1385 if (!adata || !adata->groups_hash || !group || (*group == '\0'))
1386 return NULL;
1387
1389 if (!mdata)
1390 return NULL;
1391
1392 if (mdata->newsrc_ent)
1393 {
1394 mutt_mem_realloc(&mdata->newsrc_ent, sizeof(struct NewsrcEntry));
1395 mdata->newsrc_len = 1;
1396 mdata->newsrc_ent[0].first = 1;
1397 mdata->newsrc_ent[0].last = mdata->first_message - 1;
1398 }
1399 if (m && (m->mdata == mdata))
1400 {
1401 mdata->unread = m->msg_count;
1402 for (unsigned int i = 0; i < m->msg_count; i++)
1403 {
1404 struct Email *e = m->emails[i];
1405 if (!e)
1406 break;
1407 mutt_set_flag(m, e, MUTT_READ, false, true);
1408 }
1409 }
1410 else
1411 {
1412 mdata->unread = mdata->last_message;
1413 if (mdata->newsrc_ent)
1414 mdata->unread -= mdata->newsrc_ent[0].last;
1415 }
1416 return mdata;
1417}
anum_t last
Last article number in run.
Definition: lib.h:78
struct NewsrcEntry * newsrc_ent
Definition: mdata.h:47
anum_t unread
Definition: mdata.h:41
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ nntp_active_fetch()

int nntp_active_fetch ( struct NntpAccountData adata,
bool  mark_new 
)

Fetch list of all newsgroups from server.

Parameters
adataNNTP server
mark_newMark the groups as new
Return values
0Success
-1Failure

Definition at line 2037 of file nntp.c.

2038{
2039 struct NntpMboxData tmp_mdata = { 0 };
2040 char msg[256] = { 0 };
2041 char buf[1024] = { 0 };
2042 unsigned int i;
2043 int rc;
2044
2045 snprintf(msg, sizeof(msg), _("Loading list of groups from server %s..."),
2047 mutt_message("%s", msg);
2048 if (nntp_date(adata, &adata->newgroups_time) < 0)
2049 return -1;
2050
2051 tmp_mdata.adata = adata;
2052 tmp_mdata.group = NULL;
2053 i = adata->groups_num;
2054 mutt_str_copy(buf, "LIST\r\n", sizeof(buf));
2055 rc = nntp_fetch_lines(&tmp_mdata, buf, sizeof(buf), msg, nntp_add_group, adata);
2056 if (rc)
2057 {
2058 if (rc > 0)
2059 {
2060 mutt_error("LIST: %s", buf);
2061 }
2062 return -1;
2063 }
2064
2065 if (mark_new)
2066 {
2067 for (; i < adata->groups_num; i++)
2068 {
2069 struct NntpMboxData *mdata = adata->groups_list[i];
2070 mdata->has_new_mail = true;
2071 }
2072 }
2073
2074 for (i = 0; i < adata->groups_num; i++)
2075 {
2076 struct NntpMboxData *mdata = adata->groups_list[i];
2077
2078 if (mdata && mdata->deleted && !mdata->newsrc_ent)
2079 {
2081 mutt_hash_delete(adata->groups_hash, mdata->group, NULL);
2082 adata->groups_list[i] = NULL;
2083 }
2084 }
2085
2086 const bool c_nntp_load_description = cs_subset_bool(NeoMutt->sub, "nntp_load_description");
2087 if (c_nntp_load_description)
2088 rc = get_description(&tmp_mdata, "*", _("Loading descriptions..."));
2089
2091 if (rc < 0)
2092 return -1;
2094 return 0;
2095}
#define mutt_message(...)
Definition: logging2.h:91
void mutt_hash_delete(struct HashTable *table, const char *strkey, const void *data)
Remove an element from a Hash Table.
Definition: hash.c:427
void mutt_clear_error(void)
Clear the message line (bottom line of screen)
Definition: mutt_logging.c:74
void nntp_delete_group_cache(struct NntpMboxData *mdata)
Remove hcache and bcache of newsgroup.
Definition: newsrc.c:810
int nntp_add_group(char *line, void *data)
Parse newsgroup.
Definition: newsrc.c:574
int nntp_active_save_cache(struct NntpAccountData *adata)
Save list of all newsgroups to cache.
Definition: newsrc.c:649
static int nntp_date(struct NntpAccountData *adata, time_t *now)
Get date and time from server.
Definition: nntp.c:1699
static int nntp_fetch_lines(struct NntpMboxData *mdata, char *query, size_t qlen, const char *msg, int(*func)(char *, void *), void *data)
Read lines, calling a callback function for each.
Definition: nntp.c:814
static int get_description(struct NntpMboxData *mdata, const char *wildmat, const char *msg)
Fetch newsgroups descriptions.
Definition: nntp.c:936
char host[128]
Server to login to.
Definition: connaccount.h:54
time_t newgroups_time
Definition: adata.h:56
struct Connection * conn
Connection to NNTP Server.
Definition: adata.h:62
unsigned int groups_num
Definition: adata.h:58
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ nntp_newsrc_update()

int nntp_newsrc_update ( struct NntpAccountData adata)

Update .newsrc file.

Parameters
adataNNTP server
Return values
0Success
-1Failure

Definition at line 445 of file newsrc.c.

446{
447 if (!adata)
448 return -1;
449
450 int rc = -1;
451
452 size_t buflen = 10240;
453 char *buf = mutt_mem_calloc(1, buflen);
454 size_t off = 0;
455
456 /* we will generate full newsrc here */
457 for (unsigned int i = 0; i < adata->groups_num; i++)
458 {
459 struct NntpMboxData *mdata = adata->groups_list[i];
460
461 if (!mdata || !mdata->newsrc_ent)
462 continue;
463
464 /* write newsgroup name */
465 if ((off + strlen(mdata->group) + 3) > buflen)
466 {
467 buflen *= 2;
468 mutt_mem_realloc(&buf, buflen);
469 }
470 snprintf(buf + off, buflen - off, "%s%c ", mdata->group, mdata->subscribed ? ':' : '!');
471 off += strlen(buf + off);
472
473 /* write entries */
474 for (unsigned int j = 0; j < mdata->newsrc_len; j++)
475 {
476 if ((off + 1024) > buflen)
477 {
478 buflen *= 2;
479 mutt_mem_realloc(&buf, buflen);
480 }
481 if (j)
482 buf[off++] = ',';
483 if (mdata->newsrc_ent[j].first == mdata->newsrc_ent[j].last)
484 {
485 snprintf(buf + off, buflen - off, ANUM_FMT, mdata->newsrc_ent[j].first);
486 }
487 else if (mdata->newsrc_ent[j].first < mdata->newsrc_ent[j].last)
488 {
489 snprintf(buf + off, buflen - off, ANUM_FMT "-" ANUM_FMT,
490 mdata->newsrc_ent[j].first, mdata->newsrc_ent[j].last);
491 }
492 off += strlen(buf + off);
493 }
494 buf[off++] = '\n';
495 }
496 buf[off] = '\0';
497
498 /* newrc being fully rewritten */
499 mutt_debug(LL_DEBUG1, "Updating %s\n", adata->newsrc_file);
500 if (adata->newsrc_file && (update_file(adata->newsrc_file, buf) == 0))
501 {
502 struct stat st = { 0 };
503
504 rc = stat(adata->newsrc_file, &st);
505 if (rc == 0)
506 {
507 adata->size = st.st_size;
508 adata->mtime = st.st_mtime;
509 }
510 else
511 {
512 mutt_perror("%s", adata->newsrc_file);
513 }
514 }
515 FREE(&buf);
516 return rc;
517}
#define mutt_perror(...)
Definition: logging2.h:93
@ LL_DEBUG1
Log at debug level 1.
Definition: logging2.h:43
static int update_file(char *filename, char *buf)
Update file with new contents.
Definition: newsrc.c:395
off_t size
Definition: adata.h:54
time_t mtime
Definition: adata.h:55
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ nntp_post()

int nntp_post ( struct Mailbox m,
const char *  msg 
)

Post article.

Parameters
mMailbox
msgMessage to post
Return values
0Success
-1Failure

Definition at line 1946 of file nntp.c.

1947{
1948 struct NntpMboxData *mdata = NULL;
1949 struct NntpMboxData tmp_mdata = { 0 };
1950 char buf[1024] = { 0 };
1951 int rc = -1;
1952
1953 if (m && (m->type == MUTT_NNTP))
1954 {
1955 mdata = m->mdata;
1956 }
1957 else
1958 {
1959 const char *const c_news_server = cs_subset_string(NeoMutt->sub, "news_server");
1960 CurrentNewsSrv = nntp_select_server(m, c_news_server, false);
1961 if (!CurrentNewsSrv)
1962 goto done;
1963
1964 mdata = &tmp_mdata;
1965 mdata->adata = CurrentNewsSrv;
1966 mdata->group = NULL;
1967 }
1968
1969 FILE *fp = mutt_file_fopen(msg, "r");
1970 if (!fp)
1971 {
1972 mutt_perror("%s", msg);
1973 goto done;
1974 }
1975
1976 mutt_str_copy(buf, "POST\r\n", sizeof(buf));
1977 if (nntp_query(mdata, buf, sizeof(buf)) < 0)
1978 {
1979 mutt_file_fclose(&fp);
1980 goto done;
1981 }
1982 if (buf[0] != '3')
1983 {
1984 mutt_error(_("Can't post article: %s"), buf);
1985 mutt_file_fclose(&fp);
1986 goto done;
1987 }
1988
1989 buf[0] = '.';
1990 buf[1] = '\0';
1991 while (fgets(buf + 1, sizeof(buf) - 2, fp))
1992 {
1993 size_t len = strlen(buf);
1994 if (buf[len - 1] == '\n')
1995 {
1996 buf[len - 1] = '\r';
1997 buf[len] = '\n';
1998 len++;
1999 buf[len] = '\0';
2000 }
2001 if (mutt_socket_send_d(mdata->adata->conn, (buf[1] == '.') ? buf : buf + 1,
2002 MUTT_SOCK_LOG_FULL) < 0)
2003 {
2004 mutt_file_fclose(&fp);
2005 nntp_connect_error(mdata->adata);
2006 goto done;
2007 }
2008 }
2009 mutt_file_fclose(&fp);
2010
2011 if (((buf[strlen(buf) - 1] != '\n') &&
2012 (mutt_socket_send_d(mdata->adata->conn, "\r\n", MUTT_SOCK_LOG_FULL) < 0)) ||
2013 (mutt_socket_send_d(mdata->adata->conn, ".\r\n", MUTT_SOCK_LOG_FULL) < 0) ||
2014 (mutt_socket_readln(buf, sizeof(buf), mdata->adata->conn) < 0))
2015 {
2016 nntp_connect_error(mdata->adata);
2017 goto done;
2018 }
2019 if (buf[0] != '2')
2020 {
2021 mutt_error(_("Can't post article: %s"), buf);
2022 goto done;
2023 }
2024 rc = 0;
2025
2026done:
2027 return rc;
2028}
const char * cs_subset_string(const struct ConfigSubset *sub, const char *name)
Get a string config item by name.
Definition: helpers.c:291
@ MUTT_NNTP
'NNTP' (Usenet) Mailbox type
Definition: mailbox.h:49
#define mutt_file_fclose(FP)
Definition: file.h:149
#define mutt_file_fopen(PATH, MODE)
Definition: file.h:148
struct NntpAccountData * nntp_select_server(struct Mailbox *m, const char *server, bool leave_lock)
Open a connection to an NNTP server.
Definition: newsrc.c:1063
static int nntp_connect_error(struct NntpAccountData *adata)
Signal a failed connection.
Definition: nntp.c:127
static int nntp_query(struct NntpMboxData *mdata, char *line, size_t linelen)
Send data from buffer and receive answer to same buffer.
Definition: nntp.c:730
struct NntpAccountData * CurrentNewsSrv
Current news server.
Definition: nntp.c:77
#define MUTT_SOCK_LOG_FULL
Definition: socket.h:54
#define mutt_socket_readln(buf, buflen, conn)
Definition: socket.h:56
#define mutt_socket_send_d(conn, buf, dbg)
Definition: socket.h:58
enum MailboxType type
Mailbox type.
Definition: mailbox.h:102
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ nntp_check_msgid()

int nntp_check_msgid ( struct Mailbox m,
const char *  msgid 
)

Fetch article by Message-ID.

Parameters
mMailbox
msgidMessage ID
Return values
0Success
1No such article
-1Error

Definition at line 2215 of file nntp.c.

2216{
2217 if (!m)
2218 return -1;
2219
2220 struct NntpMboxData *mdata = m->mdata;
2221 char buf[1024] = { 0 };
2222
2223 FILE *fp = mutt_file_mkstemp();
2224 if (!fp)
2225 {
2226 mutt_perror(_("Can't create temporary file"));
2227 return -1;
2228 }
2229
2230 snprintf(buf, sizeof(buf), "HEAD %s\r\n", msgid);
2231 int rc = nntp_fetch_lines(mdata, buf, sizeof(buf), NULL, fetch_tempfile, fp);
2232 if (rc)
2233 {
2234 mutt_file_fclose(&fp);
2235 if (rc < 0)
2236 return -1;
2237 if (mutt_str_startswith(buf, "430"))
2238 return 1;
2239 mutt_error("HEAD: %s", buf);
2240 return -1;
2241 }
2242
2243 /* parse header */
2245 m->emails[m->msg_count] = email_new();
2246 struct Email *e = m->emails[m->msg_count];
2247 e->edata = nntp_edata_new();
2249 e->env = mutt_rfc822_read_header(fp, e, false, false);
2250 mutt_file_fclose(&fp);
2251
2252 /* get article number */
2253 if (e->env->xref)
2254 {
2255 nntp_parse_xref(m, e);
2256 }
2257 else
2258 {
2259 snprintf(buf, sizeof(buf), "STAT %s\r\n", msgid);
2260 if (nntp_query(mdata, buf, sizeof(buf)) < 0)
2261 {
2262 email_free(&e);
2263 return -1;
2264 }
2265 sscanf(buf + 4, ANUM_FMT, &nntp_edata_get(e)->article_num);
2266 }
2267
2268 /* reset flags */
2269 e->read = false;
2270 e->old = false;
2271 e->deleted = false;
2272 e->changed = true;
2273 e->received = e->date_sent;
2274 e->index = m->msg_count++;
2276 return 0;
2277}
void mailbox_changed(struct Mailbox *m, enum NotifyMailbox action)
Notify observers of a change to a Mailbox.
Definition: mailbox.c:233
@ NT_MAILBOX_INVALID
Email list was changed.
Definition: mailbox.h:189
struct Email * email_new(void)
Create a new Email.
Definition: email.c:77
void email_free(struct Email **ptr)
Free an Email.
Definition: email.c:46
struct Envelope * mutt_rfc822_read_header(FILE *fp, struct Email *e, bool user_hdrs, bool weed)
Parses an RFC822 header.
Definition: parse.c:1200
void nntp_edata_free(void **ptr)
Free the private Email data - Implements Email::edata_free() -.
Definition: edata.c:38
size_t mutt_str_startswith(const char *str, const char *prefix)
Check whether a string starts with a prefix.
Definition: string.c:230
void mx_alloc_memory(struct Mailbox *m, int req_size)
Create storage for the emails.
Definition: mx.c:1206
struct NntpEmailData * nntp_edata_get(struct Email *e)
Get the private data for this Email.
Definition: edata.c:60
struct NntpEmailData * nntp_edata_new(void)
Create a new NntpEmailData for an Email.
Definition: edata.c:50
static int fetch_tempfile(char *line, void *data)
Write line to temporary file.
Definition: nntp.c:1009
static void nntp_parse_xref(struct Mailbox *m, struct Email *e)
Parse cross-reference.
Definition: nntp.c:968
bool read
Email is read.
Definition: email.h:50
struct Envelope * env
Envelope information.
Definition: email.h:68
void * edata
Driver-specific data.
Definition: email.h:74
bool old
Email is seen, but unread.
Definition: email.h:49
void(* edata_free)(void **ptr)
Definition: email.h:90
bool changed
Email has been edited.
Definition: email.h:77
time_t date_sent
Time when the message was sent (UTC)
Definition: email.h:60
bool deleted
Email is deleted.
Definition: email.h:78
int index
The absolute (unsorted) message number.
Definition: email.h:110
time_t received
Time when the message was placed in the mailbox.
Definition: email.h:61
char * xref
List of cross-references.
Definition: envelope.h:79
#define mutt_file_mkstemp()
Definition: tmp.h:36
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ nntp_check_children()

int nntp_check_children ( struct Mailbox m,
const char *  msgid 
)

Fetch children of article with the Message-ID.

Parameters
mMailbox
msgidMessage ID to find
Return values
0Success
-1Failure

Definition at line 2286 of file nntp.c.

2287{
2288 if (!m)
2289 return -1;
2290
2291 struct NntpMboxData *mdata = m->mdata;
2292 char buf[256] = { 0 };
2293 int rc;
2294 struct HeaderCache *hc = NULL;
2295
2296 if (!mdata || !mdata->adata)
2297 return -1;
2298 if (mdata->first_message > mdata->last_loaded)
2299 return 0;
2300
2301 /* init context */
2302 struct ChildCtx cc = { 0 };
2303 cc.mailbox = m;
2304 cc.num = 0;
2305 cc.max = 10;
2306 cc.child = mutt_mem_malloc(sizeof(anum_t) * cc.max);
2307
2308 /* fetch numbers of child messages */
2309 snprintf(buf, sizeof(buf), "XPAT References " ANUM_FMT "-" ANUM_FMT " *%s*\r\n",
2310 mdata->first_message, mdata->last_loaded, msgid);
2311 rc = nntp_fetch_lines(mdata, buf, sizeof(buf), NULL, fetch_children, &cc);
2312 if (rc)
2313 {
2314 FREE(&cc.child);
2315 if (rc > 0)
2316 {
2317 if (!mutt_str_startswith(buf, "500"))
2318 {
2319 mutt_error("XPAT: %s", buf);
2320 }
2321 else
2322 {
2323 mutt_error(_("Unable to find child articles because server does not support XPAT command"));
2324 }
2325 }
2326 return -1;
2327 }
2328
2329 /* fetch all found messages */
2330 bool verbose = m->verbose;
2331 m->verbose = false;
2332#ifdef USE_HCACHE
2333 hc = nntp_hcache_open(mdata);
2334#endif
2335 int old_msg_count = m->msg_count;
2336 for (int i = 0; i < cc.num; i++)
2337 {
2338 rc = nntp_fetch_headers(m, hc, cc.child[i], cc.child[i], true);
2339 if (rc < 0)
2340 break;
2341 }
2342 if (m->msg_count > old_msg_count)
2344
2345#ifdef USE_HCACHE
2346 hcache_close(&hc);
2347#endif
2348 m->verbose = verbose;
2349 FREE(&cc.child);
2350 return (rc < 0) ? -1 : 0;
2351}
void * mutt_mem_malloc(size_t size)
Allocate memory on the heap.
Definition: memory.c:91
static int fetch_children(char *line, void *data)
Parse XPAT line.
Definition: nntp.c:1736
static int nntp_fetch_headers(struct Mailbox *m, void *hc, anum_t first, anum_t last, bool restore)
Fetch headers.
Definition: nntp.c:1204
Keep track of the children of an article.
Definition: nntp.c:107
anum_t * child
Definition: nntp.c:111
struct Mailbox * mailbox
Definition: nntp.c:108
unsigned int max
Definition: nntp.c:110
unsigned int num
Definition: nntp.c:109
bool verbose
Display status messages?
Definition: mailbox.h:117
anum_t last_loaded
Definition: mdata.h:39
anum_t first_message
Definition: mdata.h:37
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ nntp_newsrc_parse()

int nntp_newsrc_parse ( struct NntpAccountData adata)

Parse .newsrc file.

Parameters
adataNNTP server
Return values
0Not changed
1Parsed
-1Error

Definition at line 166 of file newsrc.c.

167{
168 if (!adata)
169 return -1;
170
171 char *line = NULL;
172 struct stat st = { 0 };
173
174 if (adata->fp_newsrc)
175 {
176 /* if we already have a handle, close it and reopen */
178 }
179 else
180 {
181 /* if file doesn't exist, create it */
182 adata->fp_newsrc = mutt_file_fopen(adata->newsrc_file, "a");
184 }
185
186 /* open .newsrc */
187 adata->fp_newsrc = mutt_file_fopen(adata->newsrc_file, "r");
188 if (!adata->fp_newsrc)
189 {
190 mutt_perror("%s", adata->newsrc_file);
191 return -1;
192 }
193
194 /* lock it */
195 mutt_debug(LL_DEBUG1, "Locking %s\n", adata->newsrc_file);
196 if (mutt_file_lock(fileno(adata->fp_newsrc), false, true))
197 {
199 return -1;
200 }
201
202 if (stat(adata->newsrc_file, &st) != 0)
203 {
204 mutt_perror("%s", adata->newsrc_file);
205 nntp_newsrc_close(adata);
206 return -1;
207 }
208
209 if ((adata->size == st.st_size) && (adata->mtime == st.st_mtime))
210 return 0;
211
212 adata->size = st.st_size;
213 adata->mtime = st.st_mtime;
214 adata->newsrc_modified = true;
215 mutt_debug(LL_DEBUG1, "Parsing %s\n", adata->newsrc_file);
216
217 /* .newsrc has been externally modified or hasn't been loaded yet */
218 for (unsigned int i = 0; i < adata->groups_num; i++)
219 {
220 struct NntpMboxData *mdata = adata->groups_list[i];
221 if (!mdata)
222 continue;
223
224 mdata->subscribed = false;
225 mdata->newsrc_len = 0;
226 FREE(&mdata->newsrc_ent);
227 }
228
229 line = mutt_mem_malloc(st.st_size + 1);
230 while (st.st_size && fgets(line, st.st_size + 1, adata->fp_newsrc))
231 {
232 char *b = NULL, *h = NULL;
233 unsigned int j = 1;
234 bool subs = false;
235
236 /* find end of newsgroup name */
237 char *p = strpbrk(line, ":!");
238 if (!p)
239 continue;
240
241 /* ":" - subscribed, "!" - unsubscribed */
242 if (*p == ':')
243 subs = true;
244 *p++ = '\0';
245
246 /* get newsgroup data */
247 struct NntpMboxData *mdata = mdata_find(adata, line);
248 FREE(&mdata->newsrc_ent);
249
250 /* count number of entries */
251 b = p;
252 while (*b)
253 if (*b++ == ',')
254 j++;
255 mdata->newsrc_ent = mutt_mem_calloc(j, sizeof(struct NewsrcEntry));
256 mdata->subscribed = subs;
257
258 /* parse entries */
259 j = 0;
260 while (p)
261 {
262 b = p;
263
264 /* find end of entry */
265 p = strchr(p, ',');
266 if (p)
267 *p++ = '\0';
268
269 /* first-last or single number */
270 h = strchr(b, '-');
271 if (h)
272 *h++ = '\0';
273 else
274 h = b;
275
276 if ((sscanf(b, ANUM_FMT, &mdata->newsrc_ent[j].first) == 1) &&
277 (sscanf(h, ANUM_FMT, &mdata->newsrc_ent[j].last) == 1))
278 {
279 j++;
280 }
281 }
282 if (j == 0)
283 {
284 mdata->newsrc_ent[j].first = 1;
285 mdata->newsrc_ent[j].last = 0;
286 j++;
287 }
288 if (mdata->last_message == 0)
289 mdata->last_message = mdata->newsrc_ent[j - 1].last;
290 mdata->newsrc_len = j;
291 mutt_mem_realloc(&mdata->newsrc_ent, j * sizeof(struct NewsrcEntry));
293 mutt_debug(LL_DEBUG2, "%s\n", mdata->group);
294 }
295 FREE(&line);
296 return 1;
297}
int mutt_file_lock(int fd, bool excl, bool timeout)
(Try to) Lock a file using fcntl()
Definition: file.c:1202
void nntp_group_unread_stat(struct NntpMboxData *mdata)
Count number of unread articles using .newsrc data.
Definition: newsrc.c:136
bool newsrc_modified
Definition: adata.h:49
FILE * fp_newsrc
Definition: adata.h:50
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ nntp_newsrc_close()

void nntp_newsrc_close ( struct NntpAccountData adata)

Unlock and close .newsrc file.

Parameters
adataNNTP server

Definition at line 122 of file newsrc.c.

123{
124 if (!adata->fp_newsrc)
125 return;
126
127 mutt_debug(LL_DEBUG1, "Unlocking %s\n", adata->newsrc_file);
128 mutt_file_unlock(fileno(adata->fp_newsrc));
130}
int mutt_file_unlock(int fd)
Unlock a file previously locked by mutt_file_lock()
Definition: file.c:1249
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ nntp_mailbox()

void nntp_mailbox ( struct Mailbox m,
char *  buf,
size_t  buflen 
)

Get first newsgroup with new messages.

Parameters
mMailbox
bufBuffer for result
buflenLength of buffer

Definition at line 1425 of file newsrc.c.

1426{
1427 if (!m)
1428 return;
1429
1430 for (unsigned int i = 0; i < CurrentNewsSrv->groups_num; i++)
1431 {
1433
1434 if (!mdata || !mdata->subscribed || !mdata->unread)
1435 continue;
1436
1437 if ((m->type == MUTT_NNTP) &&
1438 mutt_str_equal(mdata->group, ((struct NntpMboxData *) m->mdata)->group))
1439 {
1440 unsigned int unread = 0;
1441
1442 for (unsigned int j = 0; j < m->msg_count; j++)
1443 {
1444 struct Email *e = m->emails[j];
1445 if (!e)
1446 break;
1447 if (!e->read && !e->deleted)
1448 unread++;
1449 }
1450 if (unread == 0)
1451 continue;
1452 }
1453 mutt_str_copy(buf, mdata->group, buflen);
1454 break;
1455 }
1456}
struct NntpAccountData * CurrentNewsSrv
Current NNTP news server.
Definition: nntp.c:77
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ nntp_expand_path()

void nntp_expand_path ( char *  buf,
size_t  buflen,
struct ConnAccount cac 
)

Make fully qualified url from newsgroup name.

Parameters
bufBuffer for the result
buflenLength of buffer
cacAccount to serialise

Definition at line 558 of file newsrc.c.

559{
560 struct Url url = { 0 };
561
562 mutt_account_tourl(cac, &url);
563 url.path = mutt_str_dup(buf);
564 url_tostring(&url, buf, buflen, U_NO_FLAGS);
565 FREE(&url.path);
566}
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:253
void mutt_account_tourl(struct ConnAccount *cac, struct Url *url)
Fill URL with info from account.
Definition: mutt_account.c:80
int url_tostring(const struct Url *url, char *dest, size_t len, uint8_t flags)
Output the URL string for a given Url object.
Definition: url.c:423
#define U_NO_FLAGS
Definition: url.h:49
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ nntp_clear_cache()

void nntp_clear_cache ( struct NntpAccountData adata)

Clear the NNTP cache.

Parameters
adataNNTP server

Remove hcache and bcache of all unexistent and unsubscribed newsgroups

Definition at line 843 of file newsrc.c.

844{
845 if (!adata || !adata->cacheable)
846 return;
847
848 struct dirent *de = NULL;
849 DIR *dir = NULL;
850 struct Buffer *cache = buf_pool_get();
851 struct Buffer *file = buf_pool_get();
852
853 cache_expand(cache->data, cache->dsize, &adata->conn->account, NULL);
855 if (!dir)
856 goto done;
857
858 buf_addch(cache, '/');
859 const bool c_save_unsubscribed = cs_subset_bool(NeoMutt->sub, "save_unsubscribed");
860
861 while ((de = readdir(dir)))
862 {
863 char *group = de->d_name;
864 if (mutt_str_equal(group, ".") || mutt_str_equal(group, ".."))
865 continue;
866
867 buf_printf(file, "%s%s", buf_string(cache), group);
868 struct stat st = { 0 };
869 if (stat(buf_string(file), &st) != 0)
870 continue;
871
872#ifdef USE_HCACHE
873 if (S_ISREG(st.st_mode))
874 {
875 char *ext = group + strlen(group) - 7;
876 if ((strlen(group) < 8) || !mutt_str_equal(ext, ".hcache"))
877 continue;
878 *ext = '\0';
879 }
880 else
881#endif
882 if (!S_ISDIR(st.st_mode))
883 continue;
884
885 struct NntpMboxData tmp_mdata = { 0 };
887 if (!mdata)
888 {
889 mdata = &tmp_mdata;
890 mdata->adata = adata;
891 mdata->group = group;
892 mdata->bcache = NULL;
893 }
894 else if (mdata->newsrc_ent || mdata->subscribed || c_save_unsubscribed)
895 {
896 continue;
897 }
898
900 if (S_ISDIR(st.st_mode))
901 {
902 rmdir(buf_string(file));
903 mutt_debug(LL_DEBUG2, "%s\n", buf_string(file));
904 }
905 }
906 closedir(dir);
907
908done:
909 buf_pool_release(&cache);
910 buf_pool_release(&file);
911}
int buf_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
Definition: buffer.c:161
size_t buf_addch(struct Buffer *buf, char c)
Add a single character to a Buffer.
Definition: buffer.c:241
static const char * buf_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition: buffer.h:96
char * data
Pointer to data.
Definition: buffer.h:37
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ nntp_complete()

int nntp_complete ( struct Buffer buf)

Auto-complete NNTP newsgroups.

Parameters
bufBuffer containing pathname
Return values
0Match found
-1No matches

XXX rules

Definition at line 46 of file complete.c.

47{
49 size_t n = 0;
50 struct Buffer *filepart = buf_new(buf_string(buf));
51 bool init = false;
52
53 /* special case to handle when there is no filepart yet
54 * find the first subscribed newsgroup */
55 int len = buf_len(filepart);
56 if (len == 0)
57 {
58 for (; n < adata->groups_num; n++)
59 {
60 struct NntpMboxData *mdata = adata->groups_list[n];
61
62 if (mdata && mdata->subscribed)
63 {
64 buf_strcpy(filepart, mdata->group);
65 init = true;
66 n++;
67 break;
68 }
69 }
70 }
71
72 for (; n < adata->groups_num; n++)
73 {
74 struct NntpMboxData *mdata = adata->groups_list[n];
75
76 if (mdata && mdata->subscribed &&
77 mutt_strn_equal(mdata->group, buf_string(filepart), len))
78 {
79 if (init)
80 {
81 char *str = filepart->data;
82 size_t i;
83 for (i = 0; (str[i] != '\0') && mdata->group[i]; i++)
84 {
85 if (str[i] != mdata->group[i])
86 break;
87 }
88 str[i] = '\0';
89 buf_fix_dptr(filepart);
90 }
91 else
92 {
93 buf_strcpy(filepart, mdata->group);
94 init = true;
95 }
96 }
97 }
98
99 buf_copy(buf, filepart);
100 buf_free(&filepart);
101 return init ? 0 : -1;
102}
size_t buf_len(const struct Buffer *buf)
Calculate the length of a Buffer.
Definition: buffer.c:491
void buf_fix_dptr(struct Buffer *buf)
Move the dptr to end of the Buffer.
Definition: buffer.c:182
void buf_free(struct Buffer **ptr)
Deallocates a buffer.
Definition: buffer.c:319
struct Buffer * buf_new(const char *str)
Allocate a new Buffer.
Definition: buffer.c:304
size_t buf_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition: buffer.c:395
size_t buf_copy(struct Buffer *dst, const struct Buffer *src)
Copy a Buffer's contents to another Buffer.
Definition: buffer.c:601
bool mutt_strn_equal(const char *a, const char *b, size_t num)
Check for equality of two strings (to a maximum), safely.
Definition: string.c:425
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Variable Documentation

◆ CurrentNewsSrv

struct NntpAccountData* CurrentNewsSrv
extern

Current NNTP news server.

Current NNTP news server.

Definition at line 77 of file nntp.c.

◆ NntpRenderData

const struct ExpandoRenderData NntpRenderData
extern
Initial value:
= {
{ -1, -1, NULL, NULL },
}
@ ED_NTP_SCHEMA
ConnAccount.account.
Definition: connaccount.h:85
@ ED_NTP_USERNAME
ConnAccount.user.
Definition: connaccount.h:87
@ ED_NTP_PORT_IF
ConnAccount.port.
Definition: connaccount.h:84
@ ED_NTP_SERVER
ConnAccount.account.
Definition: connaccount.h:86
@ ED_NTP_ACCOUNT
ConnAccount.account.
Definition: connaccount.h:82
@ ED_NTP_PORT
ConnAccount.port.
Definition: connaccount.h:83
@ ED_NNTP
Nntp ED_NTP_ ExpandoDataNntp.
Definition: domain.h:49
long nntp_p_num(const struct ExpandoNode *node, void *data, MuttFormatFlags flags)
Newsrc: Port - Implements ExpandoRenderData::get_number() -.
Definition: newsrc.c:939
long nntp_P_num(const struct ExpandoNode *node, void *data, MuttFormatFlags flags)
Newsrc: Port if specified - Implements ExpandoRenderData::get_number() -.
Definition: newsrc.c:950
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() -.
Definition: newsrc.c:979
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() -.
Definition: newsrc.c:964
void nntp_a(const struct ExpandoNode *node, void *data, MuttFormatFlags flags, int max_cols, struct Buffer *buf)
Newsrc: Account url - Implements ExpandoRenderData::get_string() -.
Definition: newsrc.c:916
void nntp_u(const struct ExpandoNode *node, void *data, MuttFormatFlags flags, int max_cols, struct Buffer *buf)
Newsrc: Username - Implements ExpandoRenderData::get_string() -.
Definition: newsrc.c:1019
void nntp_S(const struct ExpandoNode *node, void *data, MuttFormatFlags flags, int max_cols, struct Buffer *buf)
Newsrc: Url schema - Implements ExpandoRenderData::get_string() -.
Definition: newsrc.c:996

Callbacks for Newsrc Expandos.

See also
NntpFormatDef, ExpandoDataNntp

Definition at line 1463 of file newsrc.c.