NeoMutt  2021-02-05-666-ge300cd
Teaching an old dog new tricks
DOXYGEN
lib.h File Reference

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

#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include "core/lib.h"
#include "format_flags.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   uint32_t
 
#define ANUM   "%u"
 
#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. More...
 
struct NntpMboxDatamutt_newsgroup_subscribe (struct NntpAccountData *adata, char *group)
 Subscribe newsgroup. More...
 
struct NntpMboxDatamutt_newsgroup_unsubscribe (struct NntpAccountData *adata, char *group)
 Unsubscribe newsgroup. More...
 
struct NntpMboxDatamutt_newsgroup_catchup (struct Mailbox *m, struct NntpAccountData *adata, char *group)
 Catchup newsgroup. More...
 
struct NntpMboxDatamutt_newsgroup_uncatchup (struct Mailbox *m, struct NntpAccountData *adata, char *group)
 Uncatchup newsgroup. More...
 
int nntp_active_fetch (struct NntpAccountData *adata, bool mark_new)
 Fetch list of all newsgroups from server. More...
 
int nntp_newsrc_update (struct NntpAccountData *adata)
 Update .newsrc file. More...
 
int nntp_post (struct Mailbox *m, const char *msg)
 Post article. More...
 
int nntp_check_msgid (struct Mailbox *m, const char *msgid)
 Fetch article by Message-ID. More...
 
int nntp_check_children (struct Mailbox *m, const char *msgid)
 Fetch children of article with the Message-ID. More...
 
int nntp_newsrc_parse (struct NntpAccountData *adata)
 Parse .newsrc file. More...
 
void nntp_newsrc_close (struct NntpAccountData *adata)
 Unlock and close .newsrc file. More...
 
void nntp_mailbox (struct Mailbox *m, char *buf, size_t buflen)
 Get first newsgroup with new messages. More...
 
void nntp_expand_path (char *buf, size_t buflen, struct ConnAccount *acct)
 Make fully qualified url from newsgroup name. More...
 
void nntp_clear_cache (struct NntpAccountData *adata)
 Clear the NNTP cache. More...
 
const char * nntp_format_str (char *buf, size_t buflen, size_t col, int cols, char op, const char *src, const char *prec, const char *if_str, const char *else_str, intptr_t data, MuttFormatFlags flags)
 Expand the newsrc filename - Implements format_t -
Expando Description
%a Account url
%p Port
%P Port if specified
%s News server name
%S Url schema
%u Username
More...
 
int nntp_compare_order (const struct Email *a, const struct Email *b, bool reverse)
 Sort to mailbox order - Implements sort_mail_t. More...
 
enum MailboxType nntp_path_probe (const char *path, const struct stat *st)
 Is this an NNTP Mailbox? - Implements MxOps::path_probe() -. More...
 
const char * group_index_format_str (char *buf, size_t buflen, size_t col, int cols, char op, const char *src, const char *prec, const char *if_str, const char *else_str, intptr_t data, MuttFormatFlags flags)
 Format a string for the newsgroup menu - Implements format_t -
Expando Description
%C Current newsgroup number
%d Description of newsgroup (becomes from server)
%f Newsgroup name
%M - if newsgroup not allowed for direct post (moderated for example)
%N N if newsgroup is new, u if unsubscribed, blank otherwise
%n Number of new articles in newsgroup
%s Number of unread articles in newsgroup
More...
 
int nntp_complete (char *buf, size_t buflen)
 Auto-complete NNTP newsgroups. More...
 

Variables

struct NntpAccountDataCurrentNewsSrv
 Current NNTP news server. More...
 
struct MxOps MxNntpOps
 NNTP Mailbox - Implements MxOps -. More...
 

Detailed Description

Usenet network mailbox type; talk to an NNTP server.

Authors
  • Brandon Long
  • Andrej Gritsenko
  • Vsevolod Volkov

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   uint32_t

Definition at line 60 of file lib.h.

◆ ANUM

#define ANUM   "%u"

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.

Definition at line 1017 of file newsrc.c.

1018 {
1019  char file[PATH_MAX];
1020  int rc;
1021  struct ConnAccount cac = { { 0 } };
1022  struct NntpAccountData *adata = NULL;
1023  struct Connection *conn = NULL;
1024 
1025  if (!server || (*server == '\0'))
1026  {
1027  mutt_error(_("No news server defined"));
1028  return NULL;
1029  }
1030 
1031  /* create account from news server url */
1032  cac.flags = 0;
1033  cac.port = NNTP_PORT;
1034  cac.type = MUTT_ACCT_TYPE_NNTP;
1035  cac.service = "nntp";
1036  cac.get_field = nntp_get_field;
1037 
1038  snprintf(file, sizeof(file), "%s%s", strstr(server, "://") ? "" : "news://", server);
1039  struct Url *url = url_parse(file);
1040  if (!url || (url->path && *url->path) ||
1041  !((url->scheme == U_NNTP) || (url->scheme == U_NNTPS)) || !url->host ||
1042  (mutt_account_fromurl(&cac, url) < 0))
1043  {
1044  url_free(&url);
1045  mutt_error(_("%s is an invalid news server specification"), server);
1046  return NULL;
1047  }
1048  if (url->scheme == U_NNTPS)
1049  {
1050  cac.flags |= MUTT_ACCT_SSL;
1051  cac.port = NNTP_SSL_PORT;
1052  }
1053  url_free(&url);
1054 
1055  /* find connection by account */
1056  conn = mutt_conn_find(&cac);
1057  if (!conn)
1058  return NULL;
1059  if (!(conn->account.flags & MUTT_ACCT_USER) && cac.flags & MUTT_ACCT_USER)
1060  {
1061  conn->account.flags |= MUTT_ACCT_USER;
1062  conn->account.user[0] = '\0';
1063  }
1064 
1065  /* news server already exists */
1066  // adata = conn->data;
1067  if (adata)
1068  {
1069  if (adata->status == NNTP_BYE)
1070  adata->status = NNTP_NONE;
1071  if (nntp_open_connection(adata) < 0)
1072  return NULL;
1073 
1074  rc = nntp_newsrc_parse(adata);
1075  if (rc < 0)
1076  return NULL;
1077 
1078  /* check for new newsgroups */
1079  if (!leave_lock && (nntp_check_new_groups(m, adata) < 0))
1080  rc = -1;
1081 
1082  /* .newsrc has been externally modified */
1083  if (rc > 0)
1084  nntp_clear_cache(adata);
1085  if ((rc < 0) || !leave_lock)
1086  nntp_newsrc_close(adata);
1087  return (rc < 0) ? NULL : adata;
1088  }
1089 
1090  /* new news server */
1091  adata = nntp_adata_new(conn);
1092 
1093  rc = nntp_open_connection(adata);
1094 
1095  /* try to create cache directory and enable caching */
1096  adata->cacheable = false;
1097  const char *const c_news_cache_dir =
1098  cs_subset_path(NeoMutt->sub, "news_cache_dir");
1099  if ((rc >= 0) && c_news_cache_dir)
1100  {
1101  cache_expand(file, sizeof(file), &conn->account, NULL);
1102  if (mutt_file_mkdir(file, S_IRWXU) < 0)
1103  {
1104  mutt_error(_("Can't create %s: %s"), file, strerror(errno));
1105  }
1106  adata->cacheable = true;
1107  }
1108 
1109  /* load .newsrc */
1110  if (rc >= 0)
1111  {
1112  const char *const c_newsrc = cs_subset_path(NeoMutt->sub, "newsrc");
1113  mutt_expando_format(file, sizeof(file), 0, sizeof(file), NONULL(c_newsrc),
1114  nntp_format_str, (intptr_t) adata, MUTT_FORMAT_NO_FLAGS);
1115  mutt_expand_path(file, sizeof(file));
1116  adata->newsrc_file = mutt_str_dup(file);
1117  rc = nntp_newsrc_parse(adata);
1118  }
1119  if (rc >= 0)
1120  {
1121  /* try to load list of newsgroups from cache */
1122  if (adata->cacheable && (active_get_cache(adata) == 0))
1123  rc = nntp_check_new_groups(m, adata);
1124 
1125  /* load list of newsgroups from server */
1126  else
1127  rc = nntp_active_fetch(adata, false);
1128  }
1129 
1130  if (rc >= 0)
1131  nntp_clear_cache(adata);
1132 
1133 #ifdef USE_HCACHE
1134  /* check cache files */
1135  if ((rc >= 0) && adata->cacheable)
1136  {
1137  struct dirent *entry = NULL;
1138  DIR *dp = opendir(file);
1139 
1140  if (dp)
1141  {
1142  while ((entry = readdir(dp)))
1143  {
1144  struct HeaderCache *hc = NULL;
1145  void *hdata = NULL;
1146  char *group = entry->d_name;
1147 
1148  char *p = group + strlen(group) - 7;
1149  if ((strlen(group) < 8) || (strcmp(p, ".hcache") != 0))
1150  continue;
1151  *p = '\0';
1152  struct NntpMboxData *mdata = mutt_hash_find(adata->groups_hash, group);
1153  if (!mdata)
1154  continue;
1155 
1156  hc = nntp_hcache_open(mdata);
1157  if (!hc)
1158  continue;
1159 
1160  /* fetch previous values of first and last */
1161  size_t dlen = 0;
1162  hdata = mutt_hcache_fetch_raw(hc, "index", 5, &dlen);
1163  if (hdata)
1164  {
1165  anum_t first, last;
1166 
1167  if (sscanf(hdata, ANUM " " ANUM, &first, &last) == 2)
1168  {
1169  if (mdata->deleted)
1170  {
1171  mdata->first_message = first;
1172  mdata->last_message = last;
1173  }
1174  if ((last >= mdata->first_message) && (last <= mdata->last_message))
1175  {
1176  mdata->last_cached = last;
1177  mutt_debug(LL_DEBUG2, "%s last_cached=%u\n", mdata->group, last);
1178  }
1179  }
1180  mutt_hcache_free_raw(hc, &hdata);
1181  }
1182  mutt_hcache_close(hc);
1183  }
1184  closedir(dp);
1185  }
1186  }
1187 #endif
1188 
1189  if ((rc < 0) || !leave_lock)
1190  nntp_newsrc_close(adata);
1191 
1192  if (rc < 0)
1193  {
1194  mutt_hash_free(&adata->groups_hash);
1195  FREE(&adata->groups_list);
1196  FREE(&adata->newsrc_file);
1197  FREE(&adata->authenticators);
1198  FREE(&adata);
1199  mutt_socket_close(conn);
1200  FREE(&conn);
1201  return NULL;
1202  }
1203 
1204  return adata;
1205 }
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:354
int mutt_account_fromurl(struct ConnAccount *cac, const struct Url *url)
Fill ConnAccount with information from url.
Definition: mutt_account.c:43
void mutt_expando_format(char *buf, size_t buflen, size_t col, int cols, const char *src, format_t callback, intptr_t data, MuttFormatFlags flags)
Expand expandos (x) in a string -.
Definition: muttlib.c:780
#define NONULL(x)
Definition: string2.h:37
char * newsrc_file
Definition: adata.h:52
struct ConnAccount account
Account details: username, password, etc.
Definition: connection.h:40
#define mutt_error(...)
Definition: logging.h:88
void mutt_hash_free(struct HashTable **ptr)
Free a hash table.
Definition: hash.c:449
Disconnected from server.
Definition: private.h:46
A parsed URL proto://user:password@host:port/path?a=1&b=2
Definition: url.h:68
struct NntpAccountData * adata
Definition: mdata.h:47
enum UrlScheme scheme
Scheme, e.g. U_SMTPS.
Definition: url.h:70
header cache structure
Definition: lib.h:84
void nntp_clear_cache(struct NntpAccountData *adata)
Clear the NNTP cache.
Definition: newsrc.c:846
char user[128]
Username.
Definition: connaccount.h:55
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:370
#define _(a)
Definition: message.h:28
void url_free(struct Url **ptr)
Free the contents of a URL.
Definition: url.c:123
void mutt_hcache_free_raw(struct HeaderCache *hc, void **data)
Multiplexor for StoreOps::free.
Definition: hcache.c:541
Container for Accounts, Notifications.
Definition: neomutt.h:36
#define MUTT_ACCT_USER
User field has been set.
Definition: connaccount.h:43
struct HashTable * groups_hash
Definition: adata.h:62
NNTP-specific Account data -.
Definition: adata.h:36
#define MUTT_FORMAT_NO_FLAGS
No flags are set.
Definition: format_flags.h:30
anum_t last_cached
Definition: mdata.h:39
char * mutt_expand_path(char *buf, size_t buflen)
Create the canonical path.
Definition: muttlib.c:122
bool cacheable
Definition: adata.h:49
int nntp_active_fetch(struct NntpAccountData *adata, bool mark_new)
Fetch list of all newsgroups from server.
Definition: nntp.c:1963
const char * nntp_format_str(char *buf, size_t buflen, size_t col, int cols, char op, const char *src, const char *prec, const char *if_str, const char *else_str, intptr_t data, MuttFormatFlags flags)
Expand the newsrc filename - Implements format_t -Expando Description %a Account url %p Port %P Port...
Definition: newsrc.c:925
Log at debug level 2.
Definition: logging.h:41
int mutt_file_mkdir(const char *path, mode_t mode)
Recursively create directories.
Definition: file.c:877
char * group
Definition: mdata.h:34
void * mdata
Driver specific data.
Definition: mailbox.h:136
struct Connection * mutt_conn_find(const struct ConnAccount *cac)
Find a connection from a list.
Definition: mutt_socket.c:89
Url is nntps://.
Definition: url.h:42
unsigned short port
Port to connect to.
Definition: connaccount.h:57
const char *(* get_field)(enum ConnAccountField field, void *gf_data)
Function to get some login credentials.
Definition: connaccount.h:67
#define ANUM
Definition: lib.h:61
unsigned int status
Definition: adata.h:48
#define PATH_MAX
Definition: mutt.h:40
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
struct HeaderCache * nntp_hcache_open(struct NntpMboxData *mdata)
Open newsgroup hcache.
Definition: newsrc.c:709
No connection to server.
Definition: private.h:44
unsigned char type
Connection type, e.g. MUTT_ACCT_TYPE_IMAP.
Definition: connaccount.h:58
char * host
Host.
Definition: url.h:73
static void cache_expand(char *dst, size_t dstlen, struct ConnAccount *cac, const char *src)
Make fully qualified cache file name.
Definition: newsrc.c:518
const char * cs_subset_path(const struct ConfigSubset *sub, const char *name)
Get a path config item by name.
Definition: helpers.c:194
const char * service
Name of the service, e.g. "imap".
Definition: connaccount.h:60
#define mutt_debug(LEVEL,...)
Definition: logging.h:85
Login details for a remote server.
Definition: connaccount.h:51
int mutt_socket_close(struct Connection *conn)
Close a socket.
Definition: socket.c:97
NNTP-specific Mailbox data -.
Definition: mdata.h:32
int nntp_newsrc_parse(struct NntpAccountData *adata)
Parse .newsrc file.
Definition: newsrc.c:162
void nntp_newsrc_close(struct NntpAccountData *adata)
Unlock and close .newsrc file.
Definition: newsrc.c:118
char * path
Path.
Definition: url.h:75
Nntp (Usenet) Account.
Definition: mutt_account.h:40
void mutt_hcache_close(struct HeaderCache *hc)
Multiplexor for StoreOps::close.
Definition: hcache.c:435
char * authenticators
Definition: adata.h:53
bool deleted
Definition: mdata.h:44
anum_t first_message
Definition: mdata.h:36
Url is nntp://.
Definition: url.h:41
#define NNTP_SSL_PORT
Definition: private.h:37
void ** groups_list
Definition: adata.h:61
#define FREE(x)
Definition: memory.h:40
int nntp_check_new_groups(struct Mailbox *m, struct NntpAccountData *adata)
Check for new groups/articles in subscribed groups.
Definition: nntp.c:2032
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
void * mutt_hcache_fetch_raw(struct HeaderCache *hc, const char *key, size_t keylen, size_t *dlen)
Fetch a message&#39;s header from the cache.
Definition: hcache.c:521
#define anum_t
Definition: lib.h:60
static const char * nntp_get_field(enum ConnAccountField field, void *gf_data)
Get connection login credentials - Implements ConnAccount::get_field()
Definition: newsrc.c:988
static int active_get_cache(struct NntpAccountData *adata)
Load list of all newsgroups from cache.
Definition: newsrc.c:616
#define NNTP_PORT
Definition: private.h:36
#define MUTT_ACCT_SSL
Account uses SSL/TLS.
Definition: connaccount.h:46
struct NntpAccountData * nntp_adata_new(struct Connection *conn)
Allocate and initialise a new NntpAccountData structure.
Definition: adata.c:62
int nntp_open_connection(struct NntpAccountData *adata)
Connect to server, authenticate and get capabilities.
Definition: nntp.c:1712
MuttAccountFlags flags
Which fields are initialised, e.g. MUTT_ACCT_USER.
Definition: connaccount.h:59
struct Url * url_parse(const char *src)
Fill in Url.
Definition: url.c:234
anum_t last_message
Definition: mdata.h:37
+ 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 1256 of file newsrc.c.

1257 {
1258  if (!adata || !adata->groups_hash || !group || (*group == '\0'))
1259  return NULL;
1260 
1261  struct NntpMboxData *mdata = mdata_find(adata, group);
1262  mdata->subscribed = true;
1263  if (!mdata->newsrc_ent)
1264  {
1265  mdata->newsrc_ent = mutt_mem_calloc(1, sizeof(struct NewsrcEntry));
1266  mdata->newsrc_len = 1;
1267  mdata->newsrc_ent[0].first = 1;
1268  mdata->newsrc_ent[0].last = 0;
1269  }
1270  return mdata;
1271 }
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
Definition: memory.c:50
struct HashTable * groups_hash
Definition: adata.h:62
anum_t last
Definition: lib.h:78
bool subscribed
Definition: mdata.h:41
An entry in a .newsrc (subscribed newsgroups)
Definition: lib.h:75
char * group
Definition: mdata.h:34
void * mdata
Driver specific data.
Definition: mailbox.h:136
struct NewsrcEntry * newsrc_ent
Definition: mdata.h:46
NNTP-specific Mailbox data -.
Definition: mdata.h:32
unsigned int newsrc_len
Definition: mdata.h:45
static struct NntpMboxData * mdata_find(struct NntpAccountData *adata, const char *group)
Find NntpMboxData for given newsgroup or add it.
Definition: newsrc.c:72
anum_t first
Definition: lib.h:77
+ 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 1280 of file newsrc.c.

1281 {
1282  if (!adata || !adata->groups_hash || !group || (*group == '\0'))
1283  return NULL;
1284 
1285  struct NntpMboxData *mdata = mutt_hash_find(adata->groups_hash, group);
1286  if (!mdata)
1287  return NULL;
1288 
1289  mdata->subscribed = false;
1290  const bool c_save_unsubscribed =
1291  cs_subset_bool(NeoMutt->sub, "save_unsubscribed");
1292  if (!c_save_unsubscribed)
1293  {
1294  mdata->newsrc_len = 0;
1295  FREE(&mdata->newsrc_ent);
1296  }
1297  return mdata;
1298 }
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:354
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition: helpers.c:73
Container for Accounts, Notifications.
Definition: neomutt.h:36
struct HashTable * groups_hash
Definition: adata.h:62
bool subscribed
Definition: mdata.h:41
char * group
Definition: mdata.h:34
void * mdata
Driver specific data.
Definition: mailbox.h:136
struct NewsrcEntry * newsrc_ent
Definition: mdata.h:46
NNTP-specific Mailbox data -.
Definition: mdata.h:32
unsigned int newsrc_len
Definition: mdata.h:45
#define FREE(x)
Definition: memory.h:40
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
+ 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 1308 of file newsrc.c.

1310 {
1311  if (!adata || !adata->groups_hash || !group || (*group == '\0'))
1312  return NULL;
1313 
1314  struct NntpMboxData *mdata = mutt_hash_find(adata->groups_hash, group);
1315  if (!mdata)
1316  return NULL;
1317 
1318  if (mdata->newsrc_ent)
1319  {
1320  mutt_mem_realloc(&mdata->newsrc_ent, sizeof(struct NewsrcEntry));
1321  mdata->newsrc_len = 1;
1322  mdata->newsrc_ent[0].first = 1;
1323  mdata->newsrc_ent[0].last = mdata->last_message;
1324  }
1325  mdata->unread = 0;
1326  if (m && (m->mdata == mdata))
1327  {
1328  for (unsigned int i = 0; i < m->msg_count; i++)
1329  {
1330  struct Email *e = m->emails[i];
1331  if (!e)
1332  break;
1333  mutt_set_flag(m, e, MUTT_READ, true);
1334  }
1335  }
1336  return mdata;
1337 }
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:354
struct Email ** emails
Array of Emails.
Definition: mailbox.h:99
int msg_count
Total number of messages.
Definition: mailbox.h:91
#define mutt_set_flag(m, e, flag, bf)
Definition: protos.h:66
The envelope/body of an email.
Definition: email.h:37
struct HashTable * groups_hash
Definition: adata.h:62
anum_t last
Definition: lib.h:78
An entry in a .newsrc (subscribed newsgroups)
Definition: lib.h:75
char * group
Definition: mdata.h:34
void * mdata
Driver specific data.
Definition: mailbox.h:136
void mutt_mem_realloc(void *ptr, size_t size)
Resize a block of memory on the heap.
Definition: memory.c:114
Messages that have been read.
Definition: mutt.h:92
struct NewsrcEntry * newsrc_ent
Definition: mdata.h:46
NNTP-specific Mailbox data -.
Definition: mdata.h:32
unsigned int newsrc_len
Definition: mdata.h:45
anum_t unread
Definition: mdata.h:40
anum_t first
Definition: lib.h:77
anum_t last_message
Definition: mdata.h:37
+ 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 1347 of file newsrc.c.

1349 {
1350  if (!adata || !adata->groups_hash || !group || (*group == '\0'))
1351  return NULL;
1352 
1353  struct NntpMboxData *mdata = mutt_hash_find(adata->groups_hash, group);
1354  if (!mdata)
1355  return NULL;
1356 
1357  if (mdata->newsrc_ent)
1358  {
1359  mutt_mem_realloc(&mdata->newsrc_ent, sizeof(struct NewsrcEntry));
1360  mdata->newsrc_len = 1;
1361  mdata->newsrc_ent[0].first = 1;
1362  mdata->newsrc_ent[0].last = mdata->first_message - 1;
1363  }
1364  if (m && (m->mdata == mdata))
1365  {
1366  mdata->unread = m->msg_count;
1367  for (unsigned int i = 0; i < m->msg_count; i++)
1368  {
1369  struct Email *e = m->emails[i];
1370  if (!e)
1371  break;
1372  mutt_set_flag(m, e, MUTT_READ, false);
1373  }
1374  }
1375  else
1376  {
1377  mdata->unread = mdata->last_message;
1378  if (mdata->newsrc_ent)
1379  mdata->unread -= mdata->newsrc_ent[0].last;
1380  }
1381  return mdata;
1382 }
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:354
struct Email ** emails
Array of Emails.
Definition: mailbox.h:99
int msg_count
Total number of messages.
Definition: mailbox.h:91
#define mutt_set_flag(m, e, flag, bf)
Definition: protos.h:66
The envelope/body of an email.
Definition: email.h:37
struct HashTable * groups_hash
Definition: adata.h:62
anum_t last
Definition: lib.h:78
An entry in a .newsrc (subscribed newsgroups)
Definition: lib.h:75
char * group
Definition: mdata.h:34
void * mdata
Driver specific data.
Definition: mailbox.h:136
void mutt_mem_realloc(void *ptr, size_t size)
Resize a block of memory on the heap.
Definition: memory.c:114
Messages that have been read.
Definition: mutt.h:92
struct NewsrcEntry * newsrc_ent
Definition: mdata.h:46
NNTP-specific Mailbox data -.
Definition: mdata.h:32
unsigned int newsrc_len
Definition: mdata.h:45
anum_t first_message
Definition: mdata.h:36
anum_t unread
Definition: mdata.h:40
anum_t first
Definition: lib.h:77
anum_t last_message
Definition: mdata.h:37
+ 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 1963 of file nntp.c.

1964 {
1965  struct NntpMboxData tmp_mdata = { 0 };
1966  char msg[256];
1967  char buf[1024];
1968  unsigned int i;
1969  int rc;
1970 
1971  snprintf(msg, sizeof(msg), _("Loading list of groups from server %s..."),
1972  adata->conn->account.host);
1973  mutt_message(msg);
1974  if (nntp_date(adata, &adata->newgroups_time) < 0)
1975  return -1;
1976 
1977  tmp_mdata.adata = adata;
1978  tmp_mdata.group = NULL;
1979  i = adata->groups_num;
1980  mutt_str_copy(buf, "LIST\r\n", sizeof(buf));
1981  rc = nntp_fetch_lines(&tmp_mdata, buf, sizeof(buf), msg, nntp_add_group, adata);
1982  if (rc)
1983  {
1984  if (rc > 0)
1985  {
1986  mutt_error("LIST: %s", buf);
1987  }
1988  return -1;
1989  }
1990 
1991  if (mark_new)
1992  {
1993  for (; i < adata->groups_num; i++)
1994  {
1995  struct NntpMboxData *mdata = adata->groups_list[i];
1996  mdata->has_new_mail = true;
1997  }
1998  }
1999 
2000  for (i = 0; i < adata->groups_num; i++)
2001  {
2002  struct NntpMboxData *mdata = adata->groups_list[i];
2003 
2004  if (mdata && mdata->deleted && !mdata->newsrc_ent)
2005  {
2006  nntp_delete_group_cache(mdata);
2007  mutt_hash_delete(adata->groups_hash, mdata->group, NULL);
2008  adata->groups_list[i] = NULL;
2009  }
2010  }
2011 
2012  const bool c_nntp_load_description =
2013  cs_subset_bool(NeoMutt->sub, "nntp_load_description");
2014  if (c_nntp_load_description)
2015  rc = get_description(&tmp_mdata, "*", _("Loading descriptions..."));
2016 
2017  nntp_active_save_cache(adata);
2018  if (rc < 0)
2019  return -1;
2020  mutt_clear_error();
2021  return 0;
2022 }
bool has_new_mail
Definition: mdata.h:42
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition: helpers.c:73
struct ConnAccount account
Account details: username, password, etc.
Definition: connection.h:40
#define mutt_error(...)
Definition: logging.h:88
struct NntpAccountData * adata
Definition: mdata.h:47
static int nntp_date(struct NntpAccountData *adata, time_t *now)
Get date and time from server.
Definition: nntp.c:1645
#define _(a)
Definition: message.h:28
int nntp_active_save_cache(struct NntpAccountData *adata)
Save list of all newsgroups to cache.
Definition: newsrc.c:650
void nntp_delete_group_cache(struct NntpMboxData *mdata)
Remove hcache and bcache of newsgroup.
Definition: newsrc.c:812
Container for Accounts, Notifications.
Definition: neomutt.h:36
struct HashTable * groups_hash
Definition: adata.h:62
char host[128]
Server to login to.
Definition: connaccount.h:53
time_t newgroups_time
Definition: adata.h:57
char * group
Definition: mdata.h:34
void mutt_clear_error(void)
Clear the message line (bottom line of screen)
Definition: mutt_logging.c:112
void * mdata
Driver specific data.
Definition: mailbox.h:136
unsigned int groups_num
Definition: adata.h:59
int nntp_add_group(char *line, void *data)
Parse newsgroup.
Definition: newsrc.c:575
static int get_description(struct NntpMboxData *mdata, const char *wildmat, const char *msg)
Fetch newsgroups descriptions.
Definition: nntp.c:884
struct NewsrcEntry * newsrc_ent
Definition: mdata.h:46
NNTP-specific Mailbox data -.
Definition: mdata.h:32
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:768
struct Connection * conn
Definition: adata.h:63
bool deleted
Definition: mdata.h:44
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:749
void ** groups_list
Definition: adata.h:61
#define mutt_message(...)
Definition: logging.h:87
void mutt_hash_delete(struct HashTable *table, const char *strkey, const void *data)
Remove an element from a Hash Table.
Definition: hash.c:419
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
+ 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 439 of file newsrc.c.

440 {
441  if (!adata)
442  return -1;
443 
444  int rc = -1;
445 
446  size_t buflen = 10240;
447  char *buf = mutt_mem_calloc(1, buflen);
448  size_t off = 0;
449 
450  /* we will generate full newsrc here */
451  for (unsigned int i = 0; i < adata->groups_num; i++)
452  {
453  struct NntpMboxData *mdata = adata->groups_list[i];
454 
455  if (!mdata || !mdata->newsrc_ent)
456  continue;
457 
458  /* write newsgroup name */
459  if (off + strlen(mdata->group) + 3 > buflen)
460  {
461  buflen *= 2;
462  mutt_mem_realloc(&buf, buflen);
463  }
464  snprintf(buf + off, buflen - off, "%s%c ", mdata->group, mdata->subscribed ? ':' : '!');
465  off += strlen(buf + off);
466 
467  /* write entries */
468  for (unsigned int j = 0; j < mdata->newsrc_len; j++)
469  {
470  if (off + 1024 > buflen)
471  {
472  buflen *= 2;
473  mutt_mem_realloc(&buf, buflen);
474  }
475  if (j)
476  buf[off++] = ',';
477  if (mdata->newsrc_ent[j].first == mdata->newsrc_ent[j].last)
478  snprintf(buf + off, buflen - off, "%u", mdata->newsrc_ent[j].first);
479  else if (mdata->newsrc_ent[j].first < mdata->newsrc_ent[j].last)
480  {
481  snprintf(buf + off, buflen - off, "%u-%u", mdata->newsrc_ent[j].first,
482  mdata->newsrc_ent[j].last);
483  }
484  off += strlen(buf + off);
485  }
486  buf[off++] = '\n';
487  }
488  buf[off] = '\0';
489 
490  /* newrc being fully rewritten */
491  mutt_debug(LL_DEBUG1, "Updating %s\n", adata->newsrc_file);
492  if (adata->newsrc_file && (update_file(adata->newsrc_file, buf) == 0))
493  {
494  struct stat sb;
495 
496  rc = stat(adata->newsrc_file, &sb);
497  if (rc == 0)
498  {
499  adata->size = sb.st_size;
500  adata->mtime = sb.st_mtime;
501  }
502  else
503  {
504  mutt_perror(adata->newsrc_file);
505  }
506  }
507  FREE(&buf);
508  return rc;
509 }
char * newsrc_file
Definition: adata.h:52
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
Definition: memory.c:50
time_t mtime
Definition: adata.h:56
#define mutt_perror(...)
Definition: logging.h:89
anum_t last
Definition: lib.h:78
bool subscribed
Definition: mdata.h:41
static int update_file(char *filename, char *buf)
Update file with new contents.
Definition: newsrc.c:389
char * group
Definition: mdata.h:34
void * mdata
Driver specific data.
Definition: mailbox.h:136
off_t size
Definition: adata.h:55
void mutt_mem_realloc(void *ptr, size_t size)
Resize a block of memory on the heap.
Definition: memory.c:114
unsigned int groups_num
Definition: adata.h:59
#define mutt_debug(LEVEL,...)
Definition: logging.h:85
struct NewsrcEntry * newsrc_ent
Definition: mdata.h:46
NNTP-specific Mailbox data -.
Definition: mdata.h:32
unsigned int newsrc_len
Definition: mdata.h:45
Log at debug level 1.
Definition: logging.h:40
void ** groups_list
Definition: adata.h:61
#define FREE(x)
Definition: memory.h:40
anum_t first
Definition: lib.h:77
+ 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 1879 of file nntp.c.

1880 {
1881  struct NntpMboxData *mdata = NULL;
1882  struct NntpMboxData tmp_mdata = { 0 };
1883  char buf[1024];
1884 
1885  if (m && (m->type == MUTT_NNTP))
1886  mdata = m->mdata;
1887  else
1888  {
1889  const char *const c_news_server =
1890  cs_subset_string(NeoMutt->sub, "news_server");
1891  CurrentNewsSrv = nntp_select_server(m, c_news_server, false);
1892  if (!CurrentNewsSrv)
1893  return -1;
1894 
1895  mdata = &tmp_mdata;
1896  mdata->adata = CurrentNewsSrv;
1897  mdata->group = NULL;
1898  }
1899 
1900  FILE *fp = mutt_file_fopen(msg, "r");
1901  if (!fp)
1902  {
1903  mutt_perror(msg);
1904  return -1;
1905  }
1906 
1907  mutt_str_copy(buf, "POST\r\n", sizeof(buf));
1908  if (nntp_query(mdata, buf, sizeof(buf)) < 0)
1909  {
1910  mutt_file_fclose(&fp);
1911  return -1;
1912  }
1913  if (buf[0] != '3')
1914  {
1915  mutt_error(_("Can't post article: %s"), buf);
1916  mutt_file_fclose(&fp);
1917  return -1;
1918  }
1919 
1920  buf[0] = '.';
1921  buf[1] = '\0';
1922  while (fgets(buf + 1, sizeof(buf) - 2, fp))
1923  {
1924  size_t len = strlen(buf);
1925  if (buf[len - 1] == '\n')
1926  {
1927  buf[len - 1] = '\r';
1928  buf[len] = '\n';
1929  len++;
1930  buf[len] = '\0';
1931  }
1932  if (mutt_socket_send_d(mdata->adata->conn, (buf[1] == '.') ? buf : buf + 1,
1933  MUTT_SOCK_LOG_FULL) < 0)
1934  {
1935  mutt_file_fclose(&fp);
1936  return nntp_connect_error(mdata->adata);
1937  }
1938  }
1939  mutt_file_fclose(&fp);
1940 
1941  if (((buf[strlen(buf) - 1] != '\n') &&
1942  (mutt_socket_send_d(mdata->adata->conn, "\r\n", MUTT_SOCK_LOG_FULL) < 0)) ||
1943  (mutt_socket_send_d(mdata->adata->conn, ".\r\n", MUTT_SOCK_LOG_FULL) < 0) ||
1944  (mutt_socket_readln(buf, sizeof(buf), mdata->adata->conn) < 0))
1945  {
1946  return nntp_connect_error(mdata->adata);
1947  }
1948  if (buf[0] != '2')
1949  {
1950  mutt_error(_("Can't post article: %s"), buf);
1951  return -1;
1952  }
1953  return 0;
1954 }
enum MailboxType type
Mailbox type.
Definition: mailbox.h:105
&#39;NNTP&#39; (Usenet) Mailbox type
Definition: mailbox.h:52
#define mutt_error(...)
Definition: logging.h:88
struct NntpAccountData * adata
Definition: mdata.h:47
#define _(a)
Definition: message.h:28
static int nntp_connect_error(struct NntpAccountData *adata)
Signal a failed connection.
Definition: nntp.c:127
#define MUTT_SOCK_LOG_FULL
Definition: mutt_socket.h:31
#define mutt_perror(...)
Definition: logging.h:89
Container for Accounts, Notifications.
Definition: neomutt.h:36
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:153
#define mutt_socket_send_d(conn, buf, dbg)
Definition: mutt_socket.h:38
char * group
Definition: mdata.h:34
void * mdata
Driver specific data.
Definition: mailbox.h:136
struct NntpAccountData * nntp_select_server(struct Mailbox *m, const char *server, bool leave_lock)
Open a connection to an NNTP server.
Definition: newsrc.c:1017
const char * cs_subset_string(const struct ConfigSubset *sub, const char *name)
Get a string config item by name.
Definition: helpers.c:317
NNTP-specific Mailbox data -.
Definition: mdata.h:32
#define mutt_socket_readln(buf, buflen, conn)
Definition: mutt_socket.h:36
struct Connection * conn
Definition: adata.h:63
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:691
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:749
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
FILE * mutt_file_fopen(const char *path, const char *mode)
Call fopen() safely.
Definition: file.c:589
struct NntpAccountData * CurrentNewsSrv
Current NNTP news server.
Definition: nntp.c:78
+ 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 2141 of file nntp.c.

2142 {
2143  if (!m)
2144  return -1;
2145 
2146  struct NntpMboxData *mdata = m->mdata;
2147  char buf[1024];
2148 
2149  FILE *fp = mutt_file_mkstemp();
2150  if (!fp)
2151  {
2152  mutt_perror(_("Can't create temporary file"));
2153  return -1;
2154  }
2155 
2156  snprintf(buf, sizeof(buf), "HEAD %s\r\n", msgid);
2157  int rc = nntp_fetch_lines(mdata, buf, sizeof(buf), NULL, fetch_tempfile, fp);
2158  if (rc)
2159  {
2160  mutt_file_fclose(&fp);
2161  if (rc < 0)
2162  return -1;
2163  if (mutt_str_startswith(buf, "430"))
2164  return 1;
2165  mutt_error("HEAD: %s", buf);
2166  return -1;
2167  }
2168 
2169  /* parse header */
2170  if (m->msg_count == m->email_max)
2171  mx_alloc_memory(m);
2172  m->emails[m->msg_count] = email_new();
2173  struct Email *e = m->emails[m->msg_count];
2174  e->edata = nntp_edata_new();
2176  e->env = mutt_rfc822_read_header(fp, e, false, false);
2177  mutt_file_fclose(&fp);
2178 
2179  /* get article number */
2180  if (e->env->xref)
2181  nntp_parse_xref(m, e);
2182  else
2183  {
2184  snprintf(buf, sizeof(buf), "STAT %s\r\n", msgid);
2185  if (nntp_query(mdata, buf, sizeof(buf)) < 0)
2186  {
2187  email_free(&e);
2188  return -1;
2189  }
2190  sscanf(buf + 4, ANUM, &nntp_edata_get(e)->article_num);
2191  }
2192 
2193  /* reset flags */
2194  e->read = false;
2195  e->old = false;
2196  e->deleted = false;
2197  e->changed = true;
2198  e->received = e->date_sent;
2199  e->index = m->msg_count++;
2201  return 0;
2202 }
struct Email ** emails
Array of Emails.
Definition: mailbox.h:99
int msg_count
Total number of messages.
Definition: mailbox.h:91
The envelope/body of an email.
Definition: email.h:37
void email_free(struct Email **ptr)
Free an Email.
Definition: email.c:44
static void nntp_parse_xref(struct Mailbox *m, struct Email *e)
Parse cross-reference.
Definition: nntp.c:916
#define mutt_error(...)
Definition: logging.h:88
char * xref
List of cross-references.
Definition: envelope.h:76
static int fetch_tempfile(char *line, void *data)
Write line to temporary file.
Definition: nntp.c:957
void mx_alloc_memory(struct Mailbox *m)
Create storage for the emails.
Definition: mx.c:1212
#define _(a)
Definition: message.h:28
bool changed
Email has been edited.
Definition: email.h:48
Email list was changed.
Definition: mailbox.h:180
#define mutt_perror(...)
Definition: logging.h:89
struct Email * email_new(void)
Create a new Email.
Definition: email.c:78
bool read
Email is read.
Definition: email.h:51
bool old
Email is seen, but unread.
Definition: email.h:50
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:153
struct Envelope * env
Envelope information.
Definition: email.h:90
void * mdata
Driver specific data.
Definition: mailbox.h:136
time_t date_sent
Time when the message was sent (UTC)
Definition: email.h:82
#define ANUM
Definition: lib.h:61
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:160
int email_max
Number of pointers in emails.
Definition: mailbox.h:100
void(* edata_free)(void **ptr)
Free the private data attached to the Email.
Definition: email.h:121
struct NntpEmailData * nntp_edata_new(void)
Create a new NntpEmailData for an Email.
Definition: edata.c:48
#define mutt_file_mkstemp()
Definition: file.h:108
struct NntpEmailData * nntp_edata_get(struct Email *e)
Get the private data for this Email.
Definition: edata.c:58
NNTP-specific Mailbox data -.
Definition: mdata.h:32
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:768
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:691
bool deleted
Email is deleted.
Definition: email.h:45
void * edata
Driver-specific data.
Definition: email.h:111
int index
The absolute (unsorted) message number.
Definition: email.h:86
struct Envelope * mutt_rfc822_read_header(FILE *fp, struct Email *e, bool user_hdrs, bool weed)
parses an RFC822 header
Definition: parse.c:1124
void mailbox_changed(struct Mailbox *m, enum NotifyMailbox action)
Notify observers of a change to a Mailbox.
Definition: mailbox.c:208
time_t received
Time when the message was placed in the mailbox.
Definition: email.h:83
+ 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 2211 of file nntp.c.

2212 {
2213  if (!m)
2214  return -1;
2215 
2216  struct NntpMboxData *mdata = m->mdata;
2217  struct ChildCtx cc;
2218  char buf[256];
2219  int rc;
2220  void *hc = NULL;
2221 
2222  if (!mdata || !mdata->adata)
2223  return -1;
2224  if (mdata->first_message > mdata->last_loaded)
2225  return 0;
2226 
2227  /* init context */
2228  cc.mailbox = m;
2229  cc.num = 0;
2230  cc.max = 10;
2231  cc.child = mutt_mem_malloc(sizeof(anum_t) * cc.max);
2232 
2233  /* fetch numbers of child messages */
2234  snprintf(buf, sizeof(buf), "XPAT References %u-%u *%s*\r\n",
2235  mdata->first_message, mdata->last_loaded, msgid);
2236  rc = nntp_fetch_lines(mdata, buf, sizeof(buf), NULL, fetch_children, &cc);
2237  if (rc)
2238  {
2239  FREE(&cc.child);
2240  if (rc > 0)
2241  {
2242  if (!mutt_str_startswith(buf, "500"))
2243  mutt_error("XPAT: %s", buf);
2244  else
2245  {
2246  mutt_error(_("Unable to find child articles because server does not "
2247  "support XPAT command"));
2248  }
2249  }
2250  return -1;
2251  }
2252 
2253  /* fetch all found messages */
2254  bool verbose = m->verbose;
2255  m->verbose = false;
2256 #ifdef USE_HCACHE
2257  hc = nntp_hcache_open(mdata);
2258 #endif
2259  int old_msg_count = m->msg_count;
2260  for (int i = 0; i < cc.num; i++)
2261  {
2262  rc = nntp_fetch_headers(m, hc, cc.child[i], cc.child[i], true);
2263  if (rc < 0)
2264  break;
2265  }
2266  if (m->msg_count > old_msg_count)
2268 
2269 #ifdef USE_HCACHE
2270  mutt_hcache_close(hc);
2271 #endif
2272  m->verbose = verbose;
2273  FREE(&cc.child);
2274  return (rc < 0) ? -1 : 0;
2275 }
int msg_count
Total number of messages.
Definition: mailbox.h:91
#define mutt_error(...)
Definition: logging.h:88
static int nntp_fetch_headers(struct Mailbox *m, void *hc, anum_t first, anum_t last, bool restore)
Fetch headers.
Definition: nntp.c:1154
struct NntpAccountData * adata
Definition: mdata.h:47
#define _(a)
Definition: message.h:28
Keep track of the children of an article.
Definition: nntp.c:106
Email list was changed.
Definition: mailbox.h:180
anum_t last_loaded
Definition: mdata.h:38
void * mdata
Driver specific data.
Definition: mailbox.h:136
size_t mutt_str_startswith(const char *str, const char *prefix)
Check whether a string starts with a prefix.
Definition: string.c:160
void * mutt_mem_malloc(size_t size)
Allocate memory on the heap.
Definition: memory.c:90
struct HeaderCache * nntp_hcache_open(struct NntpMboxData *mdata)
Open newsgroup hcache.
Definition: newsrc.c:709
bool verbose
Display status messages?
Definition: mailbox.h:118
struct Mailbox * mailbox
Definition: nntp.c:108
NNTP-specific Mailbox data -.
Definition: mdata.h:32
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:768
static int fetch_children(char *line, void *data)
Parse XPAT line.
Definition: nntp.c:1682
void mutt_hcache_close(struct HeaderCache *hc)
Multiplexor for StoreOps::close.
Definition: hcache.c:435
anum_t first_message
Definition: mdata.h:36
#define FREE(x)
Definition: memory.h:40
#define anum_t
Definition: lib.h:60
void mailbox_changed(struct Mailbox *m, enum NotifyMailbox action)
Notify observers of a change to a Mailbox.
Definition: mailbox.c:208
+ 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 162 of file newsrc.c.

163 {
164  char *line = NULL;
165  struct stat sb;
166 
167  if (adata->fp_newsrc)
168  {
169  /* if we already have a handle, close it and reopen */
170  mutt_file_fclose(&adata->fp_newsrc);
171  }
172  else
173  {
174  /* if file doesn't exist, create it */
175  adata->fp_newsrc = mutt_file_fopen(adata->newsrc_file, "a");
176  mutt_file_fclose(&adata->fp_newsrc);
177  }
178 
179  /* open .newsrc */
180  adata->fp_newsrc = mutt_file_fopen(adata->newsrc_file, "r");
181  if (!adata->fp_newsrc)
182  {
183  mutt_perror(adata->newsrc_file);
184  return -1;
185  }
186 
187  /* lock it */
188  mutt_debug(LL_DEBUG1, "Locking %s\n", adata->newsrc_file);
189  if (mutt_file_lock(fileno(adata->fp_newsrc), false, true))
190  {
191  mutt_file_fclose(&adata->fp_newsrc);
192  return -1;
193  }
194 
195  if (stat(adata->newsrc_file, &sb) != 0)
196  {
197  mutt_perror(adata->newsrc_file);
198  nntp_newsrc_close(adata);
199  return -1;
200  }
201 
202  if ((adata->size == sb.st_size) && (adata->mtime == sb.st_mtime))
203  return 0;
204 
205  adata->size = sb.st_size;
206  adata->mtime = sb.st_mtime;
207  adata->newsrc_modified = true;
208  mutt_debug(LL_DEBUG1, "Parsing %s\n", adata->newsrc_file);
209 
210  /* .newsrc has been externally modified or hasn't been loaded yet */
211  for (unsigned int i = 0; i < adata->groups_num; i++)
212  {
213  struct NntpMboxData *mdata = adata->groups_list[i];
214  if (!mdata)
215  continue;
216 
217  mdata->subscribed = false;
218  mdata->newsrc_len = 0;
219  FREE(&mdata->newsrc_ent);
220  }
221 
222  line = mutt_mem_malloc(sb.st_size + 1);
223  while (sb.st_size && fgets(line, sb.st_size + 1, adata->fp_newsrc))
224  {
225  char *b = NULL, *h = NULL;
226  unsigned int j = 1;
227  bool subs = false;
228 
229  /* find end of newsgroup name */
230  char *p = strpbrk(line, ":!");
231  if (!p)
232  continue;
233 
234  /* ":" - subscribed, "!" - unsubscribed */
235  if (*p == ':')
236  subs = true;
237  *p++ = '\0';
238 
239  /* get newsgroup data */
240  struct NntpMboxData *mdata = mdata_find(adata, line);
241  FREE(&mdata->newsrc_ent);
242 
243  /* count number of entries */
244  b = p;
245  while (*b)
246  if (*b++ == ',')
247  j++;
248  mdata->newsrc_ent = mutt_mem_calloc(j, sizeof(struct NewsrcEntry));
249  mdata->subscribed = subs;
250 
251  /* parse entries */
252  j = 0;
253  while (p)
254  {
255  b = p;
256 
257  /* find end of entry */
258  p = strchr(p, ',');
259  if (p)
260  *p++ = '\0';
261 
262  /* first-last or single number */
263  h = strchr(b, '-');
264  if (h)
265  *h++ = '\0';
266  else
267  h = b;
268 
269  if ((sscanf(b, ANUM, &mdata->newsrc_ent[j].first) == 1) &&
270  (sscanf(h, ANUM, &mdata->newsrc_ent[j].last) == 1))
271  {
272  j++;
273  }
274  }
275  if (j == 0)
276  {
277  mdata->newsrc_ent[j].first = 1;
278  mdata->newsrc_ent[j].last = 0;
279  j++;
280  }
281  if (mdata->last_message == 0)
282  mdata->last_message = mdata->newsrc_ent[j - 1].last;
283  mdata->newsrc_len = j;
284  mutt_mem_realloc(&mdata->newsrc_ent, j * sizeof(struct NewsrcEntry));
285  nntp_group_unread_stat(mdata);
286  mutt_debug(LL_DEBUG2, "%s\n", mdata->group);
287  }
288  FREE(&line);
289  return 1;
290 }
char * newsrc_file
Definition: adata.h:52
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
Definition: memory.c:50
bool newsrc_modified
Definition: adata.h:50
time_t mtime
Definition: adata.h:56
#define mutt_perror(...)
Definition: logging.h:89
anum_t last
Definition: lib.h:78
bool subscribed
Definition: mdata.h:41
Log at debug level 2.
Definition: logging.h:41
int mutt_file_lock(int fd, bool excl, bool timeout)
(try to) lock a file using fcntl()
Definition: file.c:1178
An entry in a .newsrc (subscribed newsgroups)
Definition: lib.h:75
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:153
char * group
Definition: mdata.h:34
void * mdata
Driver specific data.
Definition: mailbox.h:136
off_t size
Definition: adata.h:55
void mutt_mem_realloc(void *ptr, size_t size)
Resize a block of memory on the heap.
Definition: memory.c:114
#define ANUM
Definition: lib.h:61
void * mutt_mem_malloc(size_t size)
Allocate memory on the heap.
Definition: memory.c:90
unsigned int groups_num
Definition: adata.h:59
#define mutt_debug(LEVEL,...)
Definition: logging.h:85
struct NewsrcEntry * newsrc_ent
Definition: mdata.h:46
NNTP-specific Mailbox data -.
Definition: mdata.h:32
unsigned int newsrc_len
Definition: mdata.h:45
void nntp_newsrc_close(struct NntpAccountData *adata)
Unlock and close .newsrc file.
Definition: newsrc.c:118
static struct NntpMboxData * mdata_find(struct NntpAccountData *adata, const char *group)
Find NntpMboxData for given newsgroup or add it.
Definition: newsrc.c:72
Log at debug level 1.
Definition: logging.h:40
void ** groups_list
Definition: adata.h:61
void nntp_group_unread_stat(struct NntpMboxData *mdata)
Count number of unread articles using .newsrc data.
Definition: newsrc.c:132
FILE * fp_newsrc
Definition: adata.h:51
#define FREE(x)
Definition: memory.h:40
FILE * mutt_file_fopen(const char *path, const char *mode)
Call fopen() safely.
Definition: file.c:589
anum_t first
Definition: lib.h:77
anum_t last_message
Definition: mdata.h:37
+ 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 118 of file newsrc.c.

119 {
120  if (!adata->fp_newsrc)
121  return;
122 
123  mutt_debug(LL_DEBUG1, "Unlocking %s\n", adata->newsrc_file);
124  mutt_file_unlock(fileno(adata->fp_newsrc));
125  mutt_file_fclose(&adata->fp_newsrc);
126 }
char * newsrc_file
Definition: adata.h:52
int mutt_file_unlock(int fd)
Unlock a file previously locked by mutt_file_lock()
Definition: file.c:1226
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:153
#define mutt_debug(LEVEL,...)
Definition: logging.h:85
Log at debug level 1.
Definition: logging.h:40
FILE * fp_newsrc
Definition: adata.h:51
+ 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 1390 of file newsrc.c.

1391 {
1392  if (!m)
1393  return;
1394 
1395  for (unsigned int i = 0; i < CurrentNewsSrv->groups_num; i++)
1396  {
1398 
1399  if (!mdata || !mdata->subscribed || !mdata->unread)
1400  continue;
1401 
1402  if ((m->type == MUTT_NNTP) &&
1403  mutt_str_equal(mdata->group, ((struct NntpMboxData *) m->mdata)->group))
1404  {
1405  unsigned int unread = 0;
1406 
1407  for (unsigned int j = 0; j < m->msg_count; j++)
1408  {
1409  struct Email *e = m->emails[j];
1410  if (!e)
1411  break;
1412  if (!e->read && !e->deleted)
1413  unread++;
1414  }
1415  if (unread == 0)
1416  continue;
1417  }
1418  mutt_str_copy(buf, mdata->group, buflen);
1419  break;
1420  }
1421 }
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:904
struct Email ** emails
Array of Emails.
Definition: mailbox.h:99
enum MailboxType type
Mailbox type.
Definition: mailbox.h:105
int msg_count
Total number of messages.
Definition: mailbox.h:91
The envelope/body of an email.
Definition: email.h:37
&#39;NNTP&#39; (Usenet) Mailbox type
Definition: mailbox.h:52
bool subscribed
Definition: mdata.h:41
bool read
Email is read.
Definition: email.h:51
char * group
Definition: mdata.h:34
void * mdata
Driver specific data.
Definition: mailbox.h:136
unsigned int groups_num
Definition: adata.h:59
NNTP-specific Mailbox data -.
Definition: mdata.h:32
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:749
bool deleted
Email is deleted.
Definition: email.h:45
anum_t unread
Definition: mdata.h:40
void ** groups_list
Definition: adata.h:61
struct NntpAccountData * CurrentNewsSrv
Current NNTP news server.
Definition: nntp.c:78
+ 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 559 of file newsrc.c.

560 {
561  struct Url url = { 0 };
562 
563  mutt_account_tourl(cac, &url);
564  url.path = mutt_str_dup(buf);
565  url_tostring(&url, buf, buflen, U_NO_FLAGS);
566  FREE(&url.path);
567 }
A parsed URL proto://user:password@host:port/path?a=1&b=2
Definition: url.h:68
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:370
#define U_NO_FLAGS
Definition: url.h:49
void mutt_account_tourl(struct ConnAccount *cac, struct Url *url)
Fill URL with info from account.
Definition: mutt_account.c:79
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:418
char * path
Path.
Definition: url.h:75
#define FREE(x)
Definition: memory.h:40
+ 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 846 of file newsrc.c.

847 {
848  char file[PATH_MAX];
849  char *fp = NULL;
850  struct dirent *entry = NULL;
851  DIR *dp = NULL;
852 
853  if (!adata || !adata->cacheable)
854  return;
855 
856  cache_expand(file, sizeof(file), &adata->conn->account, NULL);
857  dp = opendir(file);
858  if (dp)
859  {
860  mutt_strn_cat(file, sizeof(file), "/", 1);
861  fp = file + strlen(file);
862  while ((entry = readdir(dp)))
863  {
864  char *group = entry->d_name;
865  struct stat sb;
866  struct NntpMboxData *mdata = NULL;
867  struct NntpMboxData tmp_mdata;
868 
869  if (mutt_str_equal(group, ".") || mutt_str_equal(group, ".."))
870  continue;
871  *fp = '\0';
872  mutt_strn_cat(file, sizeof(file), group, strlen(group));
873  if (stat(file, &sb) != 0)
874  continue;
875 
876 #ifdef USE_HCACHE
877  if (S_ISREG(sb.st_mode))
878  {
879  char *ext = group + strlen(group) - 7;
880  if ((strlen(group) < 8) || !mutt_str_equal(ext, ".hcache"))
881  continue;
882  *ext = '\0';
883  }
884  else
885 #endif
886  if (!S_ISDIR(sb.st_mode))
887  continue;
888 
889  const bool c_save_unsubscribed =
890  cs_subset_bool(NeoMutt->sub, "save_unsubscribed");
891  mdata = mutt_hash_find(adata->groups_hash, group);
892  if (!mdata)
893  {
894  mdata = &tmp_mdata;
895  mdata->adata = adata;
896  mdata->group = group;
897  mdata->bcache = NULL;
898  }
899  else if (mdata->newsrc_ent || mdata->subscribed || c_save_unsubscribed)
900  continue;
901 
903  if (S_ISDIR(sb.st_mode))
904  {
905  rmdir(file);
906  mutt_debug(LL_DEBUG2, "%s\n", file);
907  }
908  }
909  closedir(dp);
910  }
911 }
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:354
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:904
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition: helpers.c:73
struct ConnAccount account
Account details: username, password, etc.
Definition: connection.h:40
char * mutt_strn_cat(char *d, size_t l, const char *s, size_t sl)
Concatenate two strings.
Definition: string.c:414
struct NntpAccountData * adata
Definition: mdata.h:47
void nntp_delete_group_cache(struct NntpMboxData *mdata)
Remove hcache and bcache of newsgroup.
Definition: newsrc.c:812
Container for Accounts, Notifications.
Definition: neomutt.h:36
struct HashTable * groups_hash
Definition: adata.h:62
bool subscribed
Definition: mdata.h:41
bool cacheable
Definition: adata.h:49
Log at debug level 2.
Definition: logging.h:41
char * group
Definition: mdata.h:34
void * mdata
Driver specific data.
Definition: mailbox.h:136
struct BodyCache * bcache
Definition: mdata.h:49
#define PATH_MAX
Definition: mutt.h:40
static void cache_expand(char *dst, size_t dstlen, struct ConnAccount *cac, const char *src)
Make fully qualified cache file name.
Definition: newsrc.c:518
#define mutt_debug(LEVEL,...)
Definition: logging.h:85
struct NewsrcEntry * newsrc_ent
Definition: mdata.h:46
NNTP-specific Mailbox data -.
Definition: mdata.h:32
struct Connection * conn
Definition: adata.h:63
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ nntp_compare_order()

int nntp_compare_order ( const struct Email a,
const struct Email b,
bool  reverse 
)

Sort to mailbox order - Implements sort_mail_t.

Definition at line 2280 of file nntp.c.

2281 {
2282  anum_t na = nntp_edata_get((struct Email *) a)->article_num;
2283  anum_t nb = nntp_edata_get((struct Email *) b)->article_num;
2284  int result = (na == nb) ? 0 : (na > nb) ? 1 : -1;
2285  return reverse ? -result : result;
2286 }
The envelope/body of an email.
Definition: email.h:37
anum_t article_num
Definition: edata.h:36
struct NntpEmailData * nntp_edata_get(struct Email *e)
Get the private data for this Email.
Definition: edata.c:58
#define anum_t
Definition: lib.h:60
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ nntp_complete()

int nntp_complete ( char *  buf,
size_t  buflen 
)

Auto-complete NNTP newsgroups.

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

XXX rules

Definition at line 47 of file complete.c.

48 {
50  size_t n = 0;
51  char filepart[PATH_MAX];
52  bool init = false;
53 
54  mutt_str_copy(filepart, buf, sizeof(filepart));
55 
56  /* special case to handle when there is no filepart yet
57  * find the first subscribed newsgroup */
58  int len = mutt_str_len(filepart);
59  if (len == 0)
60  {
61  for (; n < adata->groups_num; n++)
62  {
63  struct NntpMboxData *mdata = adata->groups_list[n];
64 
65  if (mdata && mdata->subscribed)
66  {
67  mutt_str_copy(filepart, mdata->group, sizeof(filepart));
68  init = true;
69  n++;
70  break;
71  }
72  }
73  }
74 
75  for (; n < adata->groups_num; n++)
76  {
77  struct NntpMboxData *mdata = adata->groups_list[n];
78 
79  if (mdata && mdata->subscribed && mutt_strn_equal(mdata->group, filepart, len))
80  {
81  if (init)
82  {
83  size_t i;
84  for (i = 0; filepart[i] && mdata->group[i]; i++)
85  {
86  if (filepart[i] != mdata->group[i])
87  break;
88  }
89  filepart[i] = '\0';
90  }
91  else
92  {
93  mutt_str_copy(filepart, mdata->group, sizeof(filepart));
94  init = true;
95  }
96  }
97  }
98 
99  mutt_str_copy(buf, filepart, buflen);
100  return init ? 0 : -1;
101 }
NNTP-specific Account data -.
Definition: adata.h:36
bool subscribed
Definition: mdata.h:41
char * group
Definition: mdata.h:34
void * mdata
Driver specific data.
Definition: mailbox.h:136
#define PATH_MAX
Definition: mutt.h:40
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
unsigned int groups_num
Definition: adata.h:59
NNTP-specific Mailbox data -.
Definition: mdata.h:32
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
Definition: string.c:664
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:749
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:593
void ** groups_list
Definition: adata.h:61
struct NntpAccountData * CurrentNewsSrv
Current NNTP news server.
Definition: nntp.c:78
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Variable Documentation

◆ CurrentNewsSrv

struct NntpAccountData* CurrentNewsSrv

Current NNTP news server.

Definition at line 78 of file nntp.c.