NeoMutt  2024-03-23-142-g2b2e76
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 1070 of file newsrc.c.

1071{
1072 char file[PATH_MAX] = { 0 };
1073 int rc;
1074 struct ConnAccount cac = { { 0 } };
1075 struct NntpAccountData *adata = NULL;
1076 struct Connection *conn = NULL;
1077
1078 if (!server || (*server == '\0'))
1079 {
1080 mutt_error(_("No news server defined"));
1081 return NULL;
1082 }
1083
1084 /* create account from news server url */
1085 cac.flags = 0;
1086 cac.port = NNTP_PORT;
1088 cac.service = "nntp";
1090
1091 snprintf(file, sizeof(file), "%s%s", strstr(server, "://") ? "" : "news://", server);
1092 struct Url *url = url_parse(file);
1093 if (!url || (url->path && *url->path) ||
1094 !((url->scheme == U_NNTP) || (url->scheme == U_NNTPS)) || !url->host ||
1095 (mutt_account_fromurl(&cac, url) < 0))
1096 {
1097 url_free(&url);
1098 mutt_error(_("%s is an invalid news server specification"), server);
1099 return NULL;
1100 }
1101 if (url->scheme == U_NNTPS)
1102 {
1103 cac.flags |= MUTT_ACCT_SSL;
1104 cac.port = NNTP_SSL_PORT;
1105 }
1106 url_free(&url);
1107
1108 // If nntp_user and nntp_pass are specified in the config, use them to find the connection
1109 const char *user = NULL;
1110 const char *pass = NULL;
1111 if ((user = cac.get_field(MUTT_CA_USER, NULL)))
1112 {
1113 mutt_str_copy(cac.user, user, sizeof(cac.user));
1114 cac.flags |= MUTT_ACCT_USER;
1115 }
1116 if ((pass = cac.get_field(MUTT_CA_PASS, NULL)))
1117 {
1118 mutt_str_copy(cac.pass, pass, sizeof(cac.pass));
1119 cac.flags |= MUTT_ACCT_PASS;
1120 }
1121
1122 /* find connection by account */
1123 conn = mutt_conn_find(&cac);
1124 if (!conn)
1125 return NULL;
1126 if (!(conn->account.flags & MUTT_ACCT_USER) && cac.flags & MUTT_ACCT_USER)
1127 {
1128 conn->account.flags |= MUTT_ACCT_USER;
1129 conn->account.user[0] = '\0';
1130 }
1131
1132 /* new news server */
1133 adata = nntp_adata_new(conn);
1134
1135 rc = nntp_open_connection(adata);
1136
1137 /* try to create cache directory and enable caching */
1138 adata->cacheable = false;
1139 const char *const c_news_cache_dir = cs_subset_path(NeoMutt->sub, "news_cache_dir");
1140 if ((rc >= 0) && c_news_cache_dir)
1141 {
1142 cache_expand(file, sizeof(file), &conn->account, NULL);
1143 if (mutt_file_mkdir(file, S_IRWXU) < 0)
1144 {
1145 mutt_error(_("Can't create %s: %s"), file, strerror(errno));
1146 }
1147 adata->cacheable = true;
1148 }
1149
1150 /* load .newsrc */
1151 if (rc >= 0)
1152 {
1153 const struct Expando *c_newsrc = cs_subset_expando(NeoMutt->sub, "newsrc");
1154 struct Buffer *buf = buf_pool_get();
1155 expando_render(c_newsrc, NntpRenderData, adata, MUTT_FORMAT_NO_FLAGS, buf->dsize, buf);
1156 mutt_expand_path(buf->data, buf->dsize);
1157 adata->newsrc_file = buf_strdup(buf);
1158 buf_pool_release(&buf);
1159 rc = nntp_newsrc_parse(adata);
1160 }
1161 if (rc >= 0)
1162 {
1163 /* try to load list of newsgroups from cache */
1164 if (adata->cacheable && (active_get_cache(adata) == 0))
1165 {
1166 rc = nntp_check_new_groups(m, adata);
1167 }
1168 else
1169 {
1170 /* load list of newsgroups from server */
1171 rc = nntp_active_fetch(adata, false);
1172 }
1173 }
1174
1175 if (rc >= 0)
1176 nntp_clear_cache(adata);
1177
1178#ifdef USE_HCACHE
1179 /* check cache files */
1180 if ((rc >= 0) && adata->cacheable)
1181 {
1182 struct dirent *de = NULL;
1183 DIR *dir = mutt_file_opendir(file, MUTT_OPENDIR_NONE);
1184
1185 if (dir)
1186 {
1187 while ((de = readdir(dir)))
1188 {
1189 struct HeaderCache *hc = NULL;
1190 char *group = de->d_name;
1191
1192 char *p = group + strlen(group) - 7;
1193 if ((strlen(group) < 8) || !mutt_str_equal(p, ".hcache"))
1194 continue;
1195 *p = '\0';
1197 if (!mdata)
1198 continue;
1199
1200 hc = nntp_hcache_open(mdata);
1201 if (!hc)
1202 continue;
1203
1204 /* fetch previous values of first and last */
1205 char *hdata = hcache_fetch_raw_str(hc, "index", 5);
1206 if (hdata)
1207 {
1208 anum_t first, last;
1209
1210 if (sscanf(hdata, ANUM_FMT " " ANUM_FMT, &first, &last) == 2)
1211 {
1212 if (mdata->deleted)
1213 {
1214 mdata->first_message = first;
1215 mdata->last_message = last;
1216 }
1217 if ((last >= mdata->first_message) && (last <= mdata->last_message))
1218 {
1219 mdata->last_cached = last;
1220 mutt_debug(LL_DEBUG2, "%s last_cached=" ANUM_FMT "\n", mdata->group, last);
1221 }
1222 }
1223 FREE(&hdata);
1224 }
1225 hcache_close(&hc);
1226 }
1227 closedir(dir);
1228 }
1229 }
1230#endif
1231
1232 if ((rc < 0) || !leave_lock)
1234
1235 if (rc < 0)
1236 {
1241 FREE(&adata);
1242 mutt_socket_close(conn);
1243 FREE(&conn);
1244 return NULL;
1245 }
1246
1247 return adata;
1248}
char * buf_strdup(const struct Buffer *buf)
Copy a Buffer's string.
Definition: buffer.c:570
const char * cs_subset_path(const struct ConfigSubset *sub, const char *name)
Get a path config item by name.
Definition: helpers.c:169
const struct Expando * cs_subset_expando(const struct ConfigSubset *sub, const char *name)
Get an Expando config item by name.
Definition: config_type.c:358
@ 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_render(const struct Expando *exp, const struct ExpandoRenderData *rdata, void *data, MuttFormatFlags flags, int max_cols, struct Buffer *buf)
Render an Expando + data into a string.
Definition: expando.c:110
int mutt_file_mkdir(const char *path, mode_t mode)
Recursively create directories.
Definition: file.c:971
DIR * mutt_file_opendir(const char *path, enum MuttOpenDirMode mode)
Open a directory.
Definition: file.c:640
@ 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:1039
#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:540
char * hcache_fetch_raw_str(struct HeaderCache *hc, const char *key, size_t keylen)
Fetch a string from the cache.
Definition: hcache.c:650
@ 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:709
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:630
#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
char * mutt_expand_path(char *buf, size_t buflen)
Create the canonical path.
Definition: muttlib.c:123
struct HeaderCache * nntp_hcache_open(struct NntpMboxData *mdata)
Open newsgroup hcache.
Definition: newsrc.c:718
void nntp_clear_cache(struct NntpAccountData *adata)
Clear the NNTP cache.
Definition: newsrc.c:852
const struct ExpandoRenderData NntpRenderData[]
Callbacks for Newsrc Expandos.
Definition: newsrc.c:66
int nntp_newsrc_parse(struct NntpAccountData *adata)
Parse .newsrc file.
Definition: newsrc.c:165
void nntp_newsrc_close(struct NntpAccountData *adata)
Unlock and close .newsrc file.
Definition: newsrc.c:121
static int active_get_cache(struct NntpAccountData *adata)
Load list of all newsgroups from cache.
Definition: newsrc.c:624
static void cache_expand(char *dst, size_t dstlen, struct ConnAccount *cac, const char *src)
Make fully qualified cache file name.
Definition: newsrc.c:525
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:1989
#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:2057
int nntp_open_connection(struct NntpAccountData *adata)
Connect to server, authenticate and get capabilities.
Definition: nntp.c:1734
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
char * data
Pointer to data.
Definition: buffer.h:37
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:41
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:45
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 1299 of file newsrc.c.

1300{
1301 if (!adata || !adata->groups_hash || !group || (*group == '\0'))
1302 return NULL;
1303
1305 mdata->subscribed = true;
1306 if (!mdata->newsrc_ent)
1307 {
1308 mdata->newsrc_ent = mutt_mem_calloc(1, sizeof(struct NewsrcEntry));
1309 mdata->newsrc_len = 1;
1310 mdata->newsrc_ent[0].first = 1;
1311 mdata->newsrc_ent[0].last = 0;
1312 }
1313 return mdata;
1314}
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
Definition: memory.c:50
static struct NntpMboxData * mdata_find(struct NntpAccountData *adata, const char *group)
Find NntpMboxData for given newsgroup or add it.
Definition: newsrc.c:75
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 1323 of file newsrc.c.

1324{
1325 if (!adata || !adata->groups_hash || !group || (*group == '\0'))
1326 return NULL;
1327
1329 if (!mdata)
1330 return NULL;
1331
1332 mdata->subscribed = false;
1333 const bool c_save_unsubscribed = cs_subset_bool(NeoMutt->sub, "save_unsubscribed");
1334 if (!c_save_unsubscribed)
1335 {
1336 mdata->newsrc_len = 0;
1337 FREE(&mdata->newsrc_ent);
1338 }
1339 return mdata;
1340}
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition: helpers.c:48
+ 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 1350 of file newsrc.c.

1352{
1353 if (!adata || !adata->groups_hash || !group || (*group == '\0'))
1354 return NULL;
1355
1357 if (!mdata)
1358 return NULL;
1359
1360 if (mdata->newsrc_ent)
1361 {
1362 mutt_mem_realloc(&mdata->newsrc_ent, sizeof(struct NewsrcEntry));
1363 mdata->newsrc_len = 1;
1364 mdata->newsrc_ent[0].first = 1;
1365 mdata->newsrc_ent[0].last = mdata->last_message;
1366 }
1367 mdata->unread = 0;
1368 if (m && (m->mdata == mdata))
1369 {
1370 for (unsigned int i = 0; i < m->msg_count; i++)
1371 {
1372 struct Email *e = m->emails[i];
1373 if (!e)
1374 break;
1375 mutt_set_flag(m, e, MUTT_READ, true, true);
1376 }
1377 }
1378 return mdata;
1379}
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:114
@ 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 1389 of file newsrc.c.

1391{
1392 if (!adata || !adata->groups_hash || !group || (*group == '\0'))
1393 return NULL;
1394
1396 if (!mdata)
1397 return NULL;
1398
1399 if (mdata->newsrc_ent)
1400 {
1401 mutt_mem_realloc(&mdata->newsrc_ent, sizeof(struct NewsrcEntry));
1402 mdata->newsrc_len = 1;
1403 mdata->newsrc_ent[0].first = 1;
1404 mdata->newsrc_ent[0].last = mdata->first_message - 1;
1405 }
1406 if (m && (m->mdata == mdata))
1407 {
1408 mdata->unread = m->msg_count;
1409 for (unsigned int i = 0; i < m->msg_count; i++)
1410 {
1411 struct Email *e = m->emails[i];
1412 if (!e)
1413 break;
1414 mutt_set_flag(m, e, MUTT_READ, false, true);
1415 }
1416 }
1417 else
1418 {
1419 mdata->unread = mdata->last_message;
1420 if (mdata->newsrc_ent)
1421 mdata->unread -= mdata->newsrc_ent[0].last;
1422 }
1423 return mdata;
1424}
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 1989 of file nntp.c.

1990{
1991 struct NntpMboxData tmp_mdata = { 0 };
1992 char msg[256] = { 0 };
1993 char buf[1024] = { 0 };
1994 unsigned int i;
1995 int rc;
1996
1997 snprintf(msg, sizeof(msg), _("Loading list of groups from server %s..."),
1999 mutt_message("%s", msg);
2000 if (nntp_date(adata, &adata->newgroups_time) < 0)
2001 return -1;
2002
2003 tmp_mdata.adata = adata;
2004 tmp_mdata.group = NULL;
2005 i = adata->groups_num;
2006 mutt_str_copy(buf, "LIST\r\n", sizeof(buf));
2007 rc = nntp_fetch_lines(&tmp_mdata, buf, sizeof(buf), msg, nntp_add_group, adata);
2008 if (rc)
2009 {
2010 if (rc > 0)
2011 {
2012 mutt_error("LIST: %s", buf);
2013 }
2014 return -1;
2015 }
2016
2017 if (mark_new)
2018 {
2019 for (; i < adata->groups_num; i++)
2020 {
2021 struct NntpMboxData *mdata = adata->groups_list[i];
2022 mdata->has_new_mail = true;
2023 }
2024 }
2025
2026 for (i = 0; i < adata->groups_num; i++)
2027 {
2028 struct NntpMboxData *mdata = adata->groups_list[i];
2029
2030 if (mdata && mdata->deleted && !mdata->newsrc_ent)
2031 {
2033 mutt_hash_delete(adata->groups_hash, mdata->group, NULL);
2034 adata->groups_list[i] = NULL;
2035 }
2036 }
2037
2038 const bool c_nntp_load_description = cs_subset_bool(NeoMutt->sub, "nntp_load_description");
2039 if (c_nntp_load_description)
2040 rc = get_description(&tmp_mdata, "*", _("Loading descriptions..."));
2041
2043 if (rc < 0)
2044 return -1;
2046 return 0;
2047}
#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:819
int nntp_add_group(char *line, void *data)
Parse newsgroup.
Definition: newsrc.c:583
int nntp_active_save_cache(struct NntpAccountData *adata)
Save list of all newsgroups to cache.
Definition: newsrc.c:658
static int nntp_date(struct NntpAccountData *adata, time_t *now)
Get date and time from server.
Definition: nntp.c:1667
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:782
static int get_description(struct NntpMboxData *mdata, const char *wildmat, const char *msg)
Fetch newsgroups descriptions.
Definition: nntp.c:904
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 444 of file newsrc.c.

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

1905{
1906 struct NntpMboxData *mdata = NULL;
1907 struct NntpMboxData tmp_mdata = { 0 };
1908 char buf[1024] = { 0 };
1909
1910 if (m && (m->type == MUTT_NNTP))
1911 {
1912 mdata = m->mdata;
1913 }
1914 else
1915 {
1916 const char *const c_news_server = cs_subset_string(NeoMutt->sub, "news_server");
1917 CurrentNewsSrv = nntp_select_server(m, c_news_server, false);
1918 if (!CurrentNewsSrv)
1919 return -1;
1920
1921 mdata = &tmp_mdata;
1922 mdata->adata = CurrentNewsSrv;
1923 mdata->group = NULL;
1924 }
1925
1926 FILE *fp = mutt_file_fopen(msg, "r");
1927 if (!fp)
1928 {
1929 mutt_perror("%s", msg);
1930 return -1;
1931 }
1932
1933 mutt_str_copy(buf, "POST\r\n", sizeof(buf));
1934 if (nntp_query(mdata, buf, sizeof(buf)) < 0)
1935 {
1936 mutt_file_fclose(&fp);
1937 return -1;
1938 }
1939 if (buf[0] != '3')
1940 {
1941 mutt_error(_("Can't post article: %s"), buf);
1942 mutt_file_fclose(&fp);
1943 return -1;
1944 }
1945
1946 buf[0] = '.';
1947 buf[1] = '\0';
1948 while (fgets(buf + 1, sizeof(buf) - 2, fp))
1949 {
1950 size_t len = strlen(buf);
1951 if (buf[len - 1] == '\n')
1952 {
1953 buf[len - 1] = '\r';
1954 buf[len] = '\n';
1955 len++;
1956 buf[len] = '\0';
1957 }
1958 if (mutt_socket_send_d(mdata->adata->conn, (buf[1] == '.') ? buf : buf + 1,
1959 MUTT_SOCK_LOG_FULL) < 0)
1960 {
1961 mutt_file_fclose(&fp);
1962 return nntp_connect_error(mdata->adata);
1963 }
1964 }
1965 mutt_file_fclose(&fp);
1966
1967 if (((buf[strlen(buf) - 1] != '\n') &&
1968 (mutt_socket_send_d(mdata->adata->conn, "\r\n", MUTT_SOCK_LOG_FULL) < 0)) ||
1969 (mutt_socket_send_d(mdata->adata->conn, ".\r\n", MUTT_SOCK_LOG_FULL) < 0) ||
1970 (mutt_socket_readln(buf, sizeof(buf), mdata->adata->conn) < 0))
1971 {
1972 return nntp_connect_error(mdata->adata);
1973 }
1974 if (buf[0] != '2')
1975 {
1976 mutt_error(_("Can't post article: %s"), buf);
1977 return -1;
1978 }
1979 return 0;
1980}
const char * cs_subset_string(const struct ConfigSubset *sub, const char *name)
Get a string config item by name.
Definition: helpers.c:292
@ MUTT_NNTP
'NNTP' (Usenet) Mailbox type
Definition: mailbox.h:49
#define mutt_file_fclose(FP)
Definition: file.h:147
#define mutt_file_fopen(PATH, MODE)
Definition: file.h:146
struct NntpAccountData * nntp_select_server(struct Mailbox *m, const char *server, bool leave_lock)
Open a connection to an NNTP server.
Definition: newsrc.c:1070
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:703
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 2167 of file nntp.c.

2168{
2169 if (!m)
2170 return -1;
2171
2172 struct NntpMboxData *mdata = m->mdata;
2173 char buf[1024] = { 0 };
2174
2175 FILE *fp = mutt_file_mkstemp();
2176 if (!fp)
2177 {
2178 mutt_perror(_("Can't create temporary file"));
2179 return -1;
2180 }
2181
2182 snprintf(buf, sizeof(buf), "HEAD %s\r\n", msgid);
2183 int rc = nntp_fetch_lines(mdata, buf, sizeof(buf), NULL, fetch_tempfile, fp);
2184 if (rc)
2185 {
2186 mutt_file_fclose(&fp);
2187 if (rc < 0)
2188 return -1;
2189 if (mutt_str_startswith(buf, "430"))
2190 return 1;
2191 mutt_error("HEAD: %s", buf);
2192 return -1;
2193 }
2194
2195 /* parse header */
2197 m->emails[m->msg_count] = email_new();
2198 struct Email *e = m->emails[m->msg_count];
2199 e->edata = nntp_edata_new();
2201 e->env = mutt_rfc822_read_header(fp, e, false, false);
2202 mutt_file_fclose(&fp);
2203
2204 /* get article number */
2205 if (e->env->xref)
2206 {
2207 nntp_parse_xref(m, e);
2208 }
2209 else
2210 {
2211 snprintf(buf, sizeof(buf), "STAT %s\r\n", msgid);
2212 if (nntp_query(mdata, buf, sizeof(buf)) < 0)
2213 {
2214 email_free(&e);
2215 return -1;
2216 }
2217 sscanf(buf + 4, ANUM_FMT, &nntp_edata_get(e)->article_num);
2218 }
2219
2220 /* reset flags */
2221 e->read = false;
2222 e->old = false;
2223 e->deleted = false;
2224 e->changed = true;
2225 e->received = e->date_sent;
2226 e->index = m->msg_count++;
2228 return 0;
2229}
void mailbox_changed(struct Mailbox *m, enum NotifyMailbox action)
Notify observers of a change to a Mailbox.
Definition: mailbox.c:234
@ NT_MAILBOX_INVALID
Email list was changed.
Definition: mailbox.h:189
struct Email * email_new(void)
Create a new Email.
Definition: email.c:80
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:1204
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:977
static void nntp_parse_xref(struct Mailbox *m, struct Email *e)
Parse cross-reference.
Definition: nntp.c:936
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:113
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 2238 of file nntp.c.

2239{
2240 if (!m)
2241 return -1;
2242
2243 struct NntpMboxData *mdata = m->mdata;
2244 char buf[256] = { 0 };
2245 int rc;
2246 struct HeaderCache *hc = NULL;
2247
2248 if (!mdata || !mdata->adata)
2249 return -1;
2250 if (mdata->first_message > mdata->last_loaded)
2251 return 0;
2252
2253 /* init context */
2254 struct ChildCtx cc = { 0 };
2255 cc.mailbox = m;
2256 cc.num = 0;
2257 cc.max = 10;
2258 cc.child = mutt_mem_malloc(sizeof(anum_t) * cc.max);
2259
2260 /* fetch numbers of child messages */
2261 snprintf(buf, sizeof(buf), "XPAT References " ANUM_FMT "-" ANUM_FMT " *%s*\r\n",
2262 mdata->first_message, mdata->last_loaded, msgid);
2263 rc = nntp_fetch_lines(mdata, buf, sizeof(buf), NULL, fetch_children, &cc);
2264 if (rc)
2265 {
2266 FREE(&cc.child);
2267 if (rc > 0)
2268 {
2269 if (!mutt_str_startswith(buf, "500"))
2270 {
2271 mutt_error("XPAT: %s", buf);
2272 }
2273 else
2274 {
2275 mutt_error(_("Unable to find child articles because server does not support XPAT command"));
2276 }
2277 }
2278 return -1;
2279 }
2280
2281 /* fetch all found messages */
2282 bool verbose = m->verbose;
2283 m->verbose = false;
2284#ifdef USE_HCACHE
2285 hc = nntp_hcache_open(mdata);
2286#endif
2287 int old_msg_count = m->msg_count;
2288 for (int i = 0; i < cc.num; i++)
2289 {
2290 rc = nntp_fetch_headers(m, hc, cc.child[i], cc.child[i], true);
2291 if (rc < 0)
2292 break;
2293 }
2294 if (m->msg_count > old_msg_count)
2296
2297#ifdef USE_HCACHE
2298 hcache_close(&hc);
2299#endif
2300 m->verbose = verbose;
2301 FREE(&cc.child);
2302 return (rc < 0) ? -1 : 0;
2303}
void * mutt_mem_malloc(size_t size)
Allocate memory on the heap.
Definition: memory.c:90
static int fetch_children(char *line, void *data)
Parse XPAT line.
Definition: nntp.c:1704
static int nntp_fetch_headers(struct Mailbox *m, void *hc, anum_t first, anum_t last, bool restore)
Fetch headers.
Definition: nntp.c:1172
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 165 of file newsrc.c.

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

122{
123 if (!adata->fp_newsrc)
124 return;
125
126 mutt_debug(LL_DEBUG1, "Unlocking %s\n", adata->newsrc_file);
127 mutt_file_unlock(fileno(adata->fp_newsrc));
129}
int mutt_file_unlock(int fd)
Unlock a file previously locked by mutt_file_lock()
Definition: file.c:1246
+ 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 1432 of file newsrc.c.

1433{
1434 if (!m)
1435 return;
1436
1437 for (unsigned int i = 0; i < CurrentNewsSrv->groups_num; i++)
1438 {
1440
1441 if (!mdata || !mdata->subscribed || !mdata->unread)
1442 continue;
1443
1444 if ((m->type == MUTT_NNTP) &&
1445 mutt_str_equal(mdata->group, ((struct NntpMboxData *) m->mdata)->group))
1446 {
1447 unsigned int unread = 0;
1448
1449 for (unsigned int j = 0; j < m->msg_count; j++)
1450 {
1451 struct Email *e = m->emails[j];
1452 if (!e)
1453 break;
1454 if (!e->read && !e->deleted)
1455 unread++;
1456 }
1457 if (unread == 0)
1458 continue;
1459 }
1460 mutt_str_copy(buf, mdata->group, buflen);
1461 break;
1462 }
1463}
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 567 of file newsrc.c.

568{
569 struct Url url = { 0 };
570
571 mutt_account_tourl(cac, &url);
572 url.path = mutt_str_dup(buf);
573 url_tostring(&url, buf, buflen, U_NO_FLAGS);
574 FREE(&url.path);
575}
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(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 852 of file newsrc.c.

853{
854 char file[PATH_MAX] = { 0 };
855 char *fp = NULL;
856 struct dirent *de = NULL;
857 DIR *dir = NULL;
858
859 if (!adata || !adata->cacheable)
860 return;
861
862 cache_expand(file, sizeof(file), &adata->conn->account, NULL);
864 if (dir)
865 {
866 mutt_strn_cat(file, sizeof(file), "/", 1);
867 fp = file + strlen(file);
868 while ((de = readdir(dir)))
869 {
870 char *group = de->d_name;
871 struct stat st = { 0 };
872 struct NntpMboxData *mdata = NULL;
873 struct NntpMboxData tmp_mdata = { 0 };
874
875 if (mutt_str_equal(group, ".") || mutt_str_equal(group, ".."))
876 continue;
877 *fp = '\0';
878 mutt_strn_cat(file, sizeof(file), group, strlen(group));
879 if (stat(file, &st) != 0)
880 continue;
881
882#ifdef USE_HCACHE
883 if (S_ISREG(st.st_mode))
884 {
885 char *ext = group + strlen(group) - 7;
886 if ((strlen(group) < 8) || !mutt_str_equal(ext, ".hcache"))
887 continue;
888 *ext = '\0';
889 }
890 else
891#endif
892 if (!S_ISDIR(st.st_mode))
893 continue;
894
895 const bool c_save_unsubscribed = cs_subset_bool(NeoMutt->sub, "save_unsubscribed");
897 if (!mdata)
898 {
899 mdata = &tmp_mdata;
900 mdata->adata = adata;
901 mdata->group = group;
902 mdata->bcache = NULL;
903 }
904 else if (mdata->newsrc_ent || mdata->subscribed || c_save_unsubscribed)
905 {
906 continue;
907 }
908
910 if (S_ISDIR(st.st_mode))
911 {
912 rmdir(file);
913 mutt_debug(LL_DEBUG2, "%s\n", file);
914 }
915 }
916 closedir(dir);
917 }
918}
char * mutt_strn_cat(char *d, size_t l, const char *s, size_t sl)
Concatenate two strings.
Definition: string.c:297
+ 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:490
void buf_fix_dptr(struct Buffer *buf)
Move the dptr to end of the Buffer.
Definition: buffer.c:181
void buf_free(struct Buffer **ptr)
Deallocates a buffer.
Definition: buffer.c:318
struct Buffer * buf_new(const char *str)
Allocate a new Buffer.
Definition: buffer.c:303
size_t buf_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition: buffer.c:394
size_t buf_copy(struct Buffer *dst, const struct Buffer *src)
Copy a Buffer's contents to another Buffer.
Definition: buffer.c:600
static const char * buf_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition: buffer.h:96
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:474
+ 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:50
long nntp_p_num(const struct ExpandoNode *node, void *data, MuttFormatFlags flags)
Newsrc: Port - Implements ExpandoRenderData::get_number() -.
Definition: newsrc.c:946
long nntp_P_num(const struct ExpandoNode *node, void *data, MuttFormatFlags flags)
Newsrc: Port if specified - Implements ExpandoRenderData::get_number() -.
Definition: newsrc.c:957
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:986
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:971
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:923
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:1026
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:1003

Callbacks for Newsrc Expandos.

See also
NntpFormatDef, ExpandoDataNntp

Definition at line 1470 of file newsrc.c.