NeoMutt  2021-02-05-89-gabe350
Teaching an old dog new tricks
DOXYGEN
lib.h File Reference
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <sys/types.h>
#include <time.h>
#include "core/lib.h"
#include "format_flags.h"
#include "mx.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. More...
 
int nntp_compare_order (const void *a, const void *b)
 Sort to mailbox order - Implements sort_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. More...
 
int nntp_complete (char *buf, size_t buflen)
 Auto-complete NNTP newsgroups. More...
 

Variables

unsigned char C_CatchupNewsgroup
 Config: (nntp) Mark all articles as read when leaving a newsgroup. More...
 
unsigned char C_FollowupToPoster
 Config: (nntp) Reply to the poster if 'poster' is in the 'Followup-To' header. More...
 
char * C_GroupIndexFormat
 Config: (nntp) printf-like format string for the browser's display of newsgroups. More...
 
char * C_NewsServer
 Config: (nntp) Url of the news server. More...
 
char * C_NewsgroupsCharset
 Config: (nntp) Character set of newsgroups' descriptions. More...
 
unsigned char C_PostModerated
 Config: (nntp) Allow posting to moderated newsgroups. More...
 
bool C_ShowOnlyUnread
 Config: (nntp) Only show subscribed newsgroups with unread articles. More...
 
bool C_XCommentTo
 Config: (nntp) Add 'X-Comment-To' header that contains article author. More...
 
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 72 of file lib.h.

◆ ANUM

#define ANUM   "%u"

Definition at line 73 of file lib.h.

◆ NNTP_ACACHE_LEN

#define NNTP_ACACHE_LEN   10

Definition at line 94 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 1012 of file newsrc.c.

1013 {
1014  char file[PATH_MAX];
1015  int rc;
1016  struct ConnAccount cac = { { 0 } };
1017  struct NntpAccountData *adata = NULL;
1018  struct Connection *conn = NULL;
1019 
1020  if (!server || (*server == '\0'))
1021  {
1022  mutt_error(_("No news server defined"));
1023  return NULL;
1024  }
1025 
1026  /* create account from news server url */
1027  cac.flags = 0;
1028  cac.port = NNTP_PORT;
1029  cac.type = MUTT_ACCT_TYPE_NNTP;
1030  cac.service = "nntp";
1031  cac.get_field = nntp_get_field;
1032 
1033  snprintf(file, sizeof(file), "%s%s", strstr(server, "://") ? "" : "news://", server);
1034  struct Url *url = url_parse(file);
1035  if (!url || (url->path && *url->path) ||
1036  !((url->scheme == U_NNTP) || (url->scheme == U_NNTPS)) || !url->host ||
1037  (mutt_account_fromurl(&cac, url) < 0))
1038  {
1039  url_free(&url);
1040  mutt_error(_("%s is an invalid news server specification"), server);
1041  return NULL;
1042  }
1043  if (url->scheme == U_NNTPS)
1044  {
1045  cac.flags |= MUTT_ACCT_SSL;
1046  cac.port = NNTP_SSL_PORT;
1047  }
1048  url_free(&url);
1049 
1050  /* find connection by account */
1051  conn = mutt_conn_find(&cac);
1052  if (!conn)
1053  return NULL;
1054  if (!(conn->account.flags & MUTT_ACCT_USER) && cac.flags & MUTT_ACCT_USER)
1055  {
1056  conn->account.flags |= MUTT_ACCT_USER;
1057  conn->account.user[0] = '\0';
1058  }
1059 
1060  /* news server already exists */
1061  // adata = conn->data;
1062  if (adata)
1063  {
1064  if (adata->status == NNTP_BYE)
1065  adata->status = NNTP_NONE;
1066  if (nntp_open_connection(adata) < 0)
1067  return NULL;
1068 
1069  rc = nntp_newsrc_parse(adata);
1070  if (rc < 0)
1071  return NULL;
1072 
1073  /* check for new newsgroups */
1074  if (!leave_lock && (nntp_check_new_groups(m, adata) < 0))
1075  rc = -1;
1076 
1077  /* .newsrc has been externally modified */
1078  if (rc > 0)
1079  nntp_clear_cache(adata);
1080  if ((rc < 0) || !leave_lock)
1081  nntp_newsrc_close(adata);
1082  return (rc < 0) ? NULL : adata;
1083  }
1084 
1085  /* new news server */
1086  adata = nntp_adata_new(conn);
1087 
1088  rc = nntp_open_connection(adata);
1089 
1090  /* try to create cache directory and enable caching */
1091  adata->cacheable = false;
1092  if ((rc >= 0) && C_NewsCacheDir)
1093  {
1094  cache_expand(file, sizeof(file), &conn->account, NULL);
1095  if (mutt_file_mkdir(file, S_IRWXU) < 0)
1096  {
1097  mutt_error(_("Can't create %s: %s"), file, strerror(errno));
1098  }
1099  adata->cacheable = true;
1100  }
1101 
1102  /* load .newsrc */
1103  if (rc >= 0)
1104  {
1105  mutt_expando_format(file, sizeof(file), 0, sizeof(file), NONULL(C_Newsrc),
1107  mutt_expand_path(file, sizeof(file));
1108  adata->newsrc_file = mutt_str_dup(file);
1109  rc = nntp_newsrc_parse(adata);
1110  }
1111  if (rc >= 0)
1112  {
1113  /* try to load list of newsgroups from cache */
1114  if (adata->cacheable && (active_get_cache(adata) == 0))
1115  rc = nntp_check_new_groups(m, adata);
1116 
1117  /* load list of newsgroups from server */
1118  else
1119  rc = nntp_active_fetch(adata, false);
1120  }
1121 
1122  if (rc >= 0)
1123  nntp_clear_cache(adata);
1124 
1125 #ifdef USE_HCACHE
1126  /* check cache files */
1127  if ((rc >= 0) && adata->cacheable)
1128  {
1129  struct dirent *entry = NULL;
1130  DIR *dp = opendir(file);
1131 
1132  if (dp)
1133  {
1134  while ((entry = readdir(dp)))
1135  {
1136  struct HeaderCache *hc = NULL;
1137  void *hdata = NULL;
1138  char *group = entry->d_name;
1139 
1140  char *p = group + strlen(group) - 7;
1141  if ((strlen(group) < 8) || (strcmp(p, ".hcache") != 0))
1142  continue;
1143  *p = '\0';
1145  if (!mdata)
1146  continue;
1147 
1148  hc = nntp_hcache_open(mdata);
1149  if (!hc)
1150  continue;
1151 
1152  /* fetch previous values of first and last */
1153  size_t dlen = 0;
1154  hdata = mutt_hcache_fetch_raw(hc, "index", 5, &dlen);
1155  if (hdata)
1156  {
1157  anum_t first, last;
1158 
1159  if (sscanf(hdata, ANUM " " ANUM, &first, &last) == 2)
1160  {
1161  if (mdata->deleted)
1162  {
1163  mdata->first_message = first;
1164  mdata->last_message = last;
1165  }
1166  if ((last >= mdata->first_message) && (last <= mdata->last_message))
1167  {
1168  mdata->last_cached = last;
1169  mutt_debug(LL_DEBUG2, "%s last_cached=%u\n", mdata->group, last);
1170  }
1171  }
1172  mutt_hcache_free_raw(hc, &hdata);
1173  }
1174  mutt_hcache_close(hc);
1175  }
1176  closedir(dp);
1177  }
1178  }
1179 #endif
1180 
1181  if ((rc < 0) || !leave_lock)
1183 
1184  if (rc < 0)
1185  {
1187  FREE(&adata->groups_list);
1188  FREE(&adata->newsrc_file);
1190  FREE(&adata);
1191  mutt_socket_close(conn);
1192  FREE(&conn);
1193  return NULL;
1194  }
1195 
1196  return adata;
1197 }
+ 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 1247 of file newsrc.c.

1248 {
1249  if (!adata || !adata->groups_hash || !group || (*group == '\0'))
1250  return NULL;
1251 
1252  struct NntpMboxData *mdata = mdata_find(adata, group);
1253  mdata->subscribed = true;
1254  if (!mdata->newsrc_ent)
1255  {
1256  mdata->newsrc_ent = mutt_mem_calloc(1, sizeof(struct NewsrcEntry));
1257  mdata->newsrc_len = 1;
1258  mdata->newsrc_ent[0].first = 1;
1259  mdata->newsrc_ent[0].last = 0;
1260  }
1261  return mdata;
1262 }
+ 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 1271 of file newsrc.c.

1272 {
1273  if (!adata || !adata->groups_hash || !group || (*group == '\0'))
1274  return NULL;
1275 
1277  if (!mdata)
1278  return NULL;
1279 
1280  mdata->subscribed = false;
1281  if (!C_SaveUnsubscribed)
1282  {
1283  mdata->newsrc_len = 0;
1284  FREE(&mdata->newsrc_ent);
1285  }
1286  return mdata;
1287 }
+ 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 1297 of file newsrc.c.

1299 {
1300  if (!adata || !adata->groups_hash || !group || (*group == '\0'))
1301  return NULL;
1302 
1304  if (!mdata)
1305  return NULL;
1306 
1307  if (mdata->newsrc_ent)
1308  {
1309  mutt_mem_realloc(&mdata->newsrc_ent, sizeof(struct NewsrcEntry));
1310  mdata->newsrc_len = 1;
1311  mdata->newsrc_ent[0].first = 1;
1312  mdata->newsrc_ent[0].last = mdata->last_message;
1313  }
1314  mdata->unread = 0;
1315  if (m && (m->mdata == mdata))
1316  {
1317  for (unsigned int i = 0; i < m->msg_count; i++)
1318  {
1319  struct Email *e = m->emails[i];
1320  if (!e)
1321  break;
1322  mutt_set_flag(m, e, MUTT_READ, true);
1323  }
1324  }
1325  return mdata;
1326 }
+ 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 1336 of file newsrc.c.

1338 {
1339  if (!adata || !adata->groups_hash || !group || (*group == '\0'))
1340  return NULL;
1341 
1343  if (!mdata)
1344  return NULL;
1345 
1346  if (mdata->newsrc_ent)
1347  {
1348  mutt_mem_realloc(&mdata->newsrc_ent, sizeof(struct NewsrcEntry));
1349  mdata->newsrc_len = 1;
1350  mdata->newsrc_ent[0].first = 1;
1351  mdata->newsrc_ent[0].last = mdata->first_message - 1;
1352  }
1353  if (m && (m->mdata == mdata))
1354  {
1355  mdata->unread = m->msg_count;
1356  for (unsigned int i = 0; i < m->msg_count; i++)
1357  {
1358  struct Email *e = m->emails[i];
1359  if (!e)
1360  break;
1361  mutt_set_flag(m, e, MUTT_READ, false);
1362  }
1363  }
1364  else
1365  {
1366  mdata->unread = mdata->last_message;
1367  if (mdata->newsrc_ent)
1368  mdata->unread -= mdata->newsrc_ent[0].last;
1369  }
1370  return mdata;
1371 }
+ 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 1948 of file nntp.c.

1949 {
1950  struct NntpMboxData tmp_mdata = { 0 };
1951  char msg[256];
1952  char buf[1024];
1953  unsigned int i;
1954  int rc;
1955 
1956  snprintf(msg, sizeof(msg), _("Loading list of groups from server %s..."),
1957  adata->conn->account.host);
1958  mutt_message(msg);
1959  if (nntp_date(adata, &adata->newgroups_time) < 0)
1960  return -1;
1961 
1962  tmp_mdata.adata = adata;
1963  tmp_mdata.group = NULL;
1964  i = adata->groups_num;
1965  mutt_str_copy(buf, "LIST\r\n", sizeof(buf));
1966  rc = nntp_fetch_lines(&tmp_mdata, buf, sizeof(buf), msg, nntp_add_group, adata);
1967  if (rc)
1968  {
1969  if (rc > 0)
1970  {
1971  mutt_error("LIST: %s", buf);
1972  }
1973  return -1;
1974  }
1975 
1976  if (mark_new)
1977  {
1978  for (; i < adata->groups_num; i++)
1979  {
1980  struct NntpMboxData *mdata = adata->groups_list[i];
1981  mdata->has_new_mail = true;
1982  }
1983  }
1984 
1985  for (i = 0; i < adata->groups_num; i++)
1986  {
1987  struct NntpMboxData *mdata = adata->groups_list[i];
1988 
1989  if (mdata && mdata->deleted && !mdata->newsrc_ent)
1990  {
1992  mutt_hash_delete(adata->groups_hash, mdata->group, NULL);
1993  adata->groups_list[i] = NULL;
1994  }
1995  }
1996 
1998  rc = get_description(&tmp_mdata, "*", _("Loading descriptions..."));
1999 
2001  if (rc < 0)
2002  return -1;
2003  mutt_clear_error();
2004  return 0;
2005 }
+ 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 442 of file newsrc.c.

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

1867 {
1868  struct NntpMboxData *mdata = NULL;
1869  struct NntpMboxData tmp_mdata = { 0 };
1870  char buf[1024];
1871 
1872  if (m && (m->type == MUTT_NNTP))
1873  mdata = m->mdata;
1874  else
1875  {
1877  if (!CurrentNewsSrv)
1878  return -1;
1879 
1880  mdata = &tmp_mdata;
1881  mdata->adata = CurrentNewsSrv;
1882  mdata->group = NULL;
1883  }
1884 
1885  FILE *fp = mutt_file_fopen(msg, "r");
1886  if (!fp)
1887  {
1888  mutt_perror(msg);
1889  return -1;
1890  }
1891 
1892  mutt_str_copy(buf, "POST\r\n", sizeof(buf));
1893  if (nntp_query(mdata, buf, sizeof(buf)) < 0)
1894  {
1895  mutt_file_fclose(&fp);
1896  return -1;
1897  }
1898  if (buf[0] != '3')
1899  {
1900  mutt_error(_("Can't post article: %s"), buf);
1901  mutt_file_fclose(&fp);
1902  return -1;
1903  }
1904 
1905  buf[0] = '.';
1906  buf[1] = '\0';
1907  while (fgets(buf + 1, sizeof(buf) - 2, fp))
1908  {
1909  size_t len = strlen(buf);
1910  if (buf[len - 1] == '\n')
1911  {
1912  buf[len - 1] = '\r';
1913  buf[len] = '\n';
1914  len++;
1915  buf[len] = '\0';
1916  }
1917  if (mutt_socket_send_d(mdata->adata->conn, (buf[1] == '.') ? buf : buf + 1,
1918  MUTT_SOCK_LOG_FULL) < 0)
1919  {
1920  mutt_file_fclose(&fp);
1921  return nntp_connect_error(mdata->adata);
1922  }
1923  }
1924  mutt_file_fclose(&fp);
1925 
1926  if (((buf[strlen(buf) - 1] != '\n') &&
1927  (mutt_socket_send_d(mdata->adata->conn, "\r\n", MUTT_SOCK_LOG_FULL) < 0)) ||
1928  (mutt_socket_send_d(mdata->adata->conn, ".\r\n", MUTT_SOCK_LOG_FULL) < 0) ||
1929  (mutt_socket_readln(buf, sizeof(buf), mdata->adata->conn) < 0))
1930  {
1931  return nntp_connect_error(mdata->adata);
1932  }
1933  if (buf[0] != '2')
1934  {
1935  mutt_error(_("Can't post article: %s"), buf);
1936  return -1;
1937  }
1938  return 0;
1939 }
+ 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 2118 of file nntp.c.

2119 {
2120  if (!m)
2121  return -1;
2122 
2123  struct NntpMboxData *mdata = m->mdata;
2124  char buf[1024];
2125 
2126  FILE *fp = mutt_file_mkstemp();
2127  if (!fp)
2128  {
2129  mutt_perror(_("Can't create temporary file"));
2130  return -1;
2131  }
2132 
2133  snprintf(buf, sizeof(buf), "HEAD %s\r\n", msgid);
2134  int rc = nntp_fetch_lines(mdata, buf, sizeof(buf), NULL, fetch_tempfile, fp);
2135  if (rc)
2136  {
2137  mutt_file_fclose(&fp);
2138  if (rc < 0)
2139  return -1;
2140  if (mutt_str_startswith(buf, "430"))
2141  return 1;
2142  mutt_error("HEAD: %s", buf);
2143  return -1;
2144  }
2145 
2146  /* parse header */
2147  if (m->msg_count == m->email_max)
2148  mx_alloc_memory(m);
2149  m->emails[m->msg_count] = email_new();
2150  struct Email *e = m->emails[m->msg_count];
2151  e->edata = nntp_edata_new();
2153  e->env = mutt_rfc822_read_header(fp, e, false, false);
2154  mutt_file_fclose(&fp);
2155 
2156  /* get article number */
2157  if (e->env->xref)
2158  nntp_parse_xref(m, e);
2159  else
2160  {
2161  snprintf(buf, sizeof(buf), "STAT %s\r\n", msgid);
2162  if (nntp_query(mdata, buf, sizeof(buf)) < 0)
2163  {
2164  email_free(&e);
2165  return -1;
2166  }
2167  sscanf(buf + 4, ANUM, &nntp_edata_get(e)->article_num);
2168  }
2169 
2170  /* reset flags */
2171  e->read = false;
2172  e->old = false;
2173  e->deleted = false;
2174  e->changed = true;
2175  e->received = e->date_sent;
2176  e->index = m->msg_count++;
2178  return 0;
2179 }
+ 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 2188 of file nntp.c.

2189 {
2190  if (!m)
2191  return -1;
2192 
2193  struct NntpMboxData *mdata = m->mdata;
2194  struct ChildCtx cc;
2195  char buf[256];
2196  int rc;
2197  void *hc = NULL;
2198 
2199  if (!mdata || !mdata->adata)
2200  return -1;
2201  if (mdata->first_message > mdata->last_loaded)
2202  return 0;
2203 
2204  /* init context */
2205  cc.mailbox = m;
2206  cc.num = 0;
2207  cc.max = 10;
2208  cc.child = mutt_mem_malloc(sizeof(anum_t) * cc.max);
2209 
2210  /* fetch numbers of child messages */
2211  snprintf(buf, sizeof(buf), "XPAT References %u-%u *%s*\r\n",
2212  mdata->first_message, mdata->last_loaded, msgid);
2213  rc = nntp_fetch_lines(mdata, buf, sizeof(buf), NULL, fetch_children, &cc);
2214  if (rc)
2215  {
2216  FREE(&cc.child);
2217  if (rc > 0)
2218  {
2219  if (!mutt_str_startswith(buf, "500"))
2220  mutt_error("XPAT: %s", buf);
2221  else
2222  {
2223  mutt_error(_("Unable to find child articles because server does not "
2224  "support XPAT command"));
2225  }
2226  }
2227  return -1;
2228  }
2229 
2230  /* fetch all found messages */
2231  bool verbose = m->verbose;
2232  m->verbose = false;
2233 #ifdef USE_HCACHE
2234  hc = nntp_hcache_open(mdata);
2235 #endif
2236  int old_msg_count = m->msg_count;
2237  for (int i = 0; i < cc.num; i++)
2238  {
2239  rc = nntp_fetch_headers(m, hc, cc.child[i], cc.child[i], true);
2240  if (rc < 0)
2241  break;
2242  }
2243  if (m->msg_count > old_msg_count)
2245 
2246 #ifdef USE_HCACHE
2247  mutt_hcache_close(hc);
2248 #endif
2249  m->verbose = verbose;
2250  FREE(&cc.child);
2251  return (rc < 0) ? -1 : 0;
2252 }
+ 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 164 of file newsrc.c.

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

121 {
122  if (!adata->fp_newsrc)
123  return;
124 
125  mutt_debug(LL_DEBUG1, "Unlocking %s\n", adata->newsrc_file);
126  mutt_file_unlock(fileno(adata->fp_newsrc));
128 }
+ 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 1379 of file newsrc.c.

1380 {
1381  if (!m)
1382  return;
1383 
1384  for (unsigned int i = 0; i < CurrentNewsSrv->groups_num; i++)
1385  {
1387 
1388  if (!mdata || !mdata->subscribed || !mdata->unread)
1389  continue;
1390 
1391  if ((m->type == MUTT_NNTP) &&
1392  mutt_str_equal(mdata->group, ((struct NntpMboxData *) m->mdata)->group))
1393  {
1394  unsigned int unread = 0;
1395 
1396  for (unsigned int j = 0; j < m->msg_count; j++)
1397  {
1398  struct Email *e = m->emails[j];
1399  if (!e)
1400  break;
1401  if (!e->read && !e->deleted)
1402  unread++;
1403  }
1404  if (unread == 0)
1405  continue;
1406  }
1407  mutt_str_copy(buf, mdata->group, buflen);
1408  break;
1409  }
1410 }
+ 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 560 of file newsrc.c.

561 {
562  struct Url url = { 0 };
563 
564  mutt_account_tourl(cac, &url);
565  url.path = mutt_str_dup(buf);
566  url_tostring(&url, buf, buflen, U_NO_FLAGS);
567  FREE(&url.path);
568 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ nntp_clear_cache()

void nntp_clear_cache ( struct NntpAccountData adata)

Clear the NNTP cache.

Parameters
adataNNTP server

Remove hcache and bcache of all unexistent and unsubscribed newsgroups

Definition at line 843 of file newsrc.c.

844 {
845  char file[PATH_MAX];
846  char *fp = NULL;
847  struct dirent *entry = NULL;
848  DIR *dp = NULL;
849 
850  if (!adata || !adata->cacheable)
851  return;
852 
853  cache_expand(file, sizeof(file), &adata->conn->account, NULL);
854  dp = opendir(file);
855  if (dp)
856  {
857  mutt_strn_cat(file, sizeof(file), "/", 1);
858  fp = file + strlen(file);
859  while ((entry = readdir(dp)))
860  {
861  char *group = entry->d_name;
862  struct stat sb;
863  struct NntpMboxData *mdata = NULL;
864  struct NntpMboxData tmp_mdata;
865 
866  if (mutt_str_equal(group, ".") || mutt_str_equal(group, ".."))
867  continue;
868  *fp = '\0';
869  mutt_strn_cat(file, sizeof(file), group, strlen(group));
870  if (stat(file, &sb) != 0)
871  continue;
872 
873 #ifdef USE_HCACHE
874  if (S_ISREG(sb.st_mode))
875  {
876  char *ext = group + strlen(group) - 7;
877  if ((strlen(group) < 8) || !mutt_str_equal(ext, ".hcache"))
878  continue;
879  *ext = '\0';
880  }
881  else
882 #endif
883  if (!S_ISDIR(sb.st_mode))
884  continue;
885 
887  if (!mdata)
888  {
889  mdata = &tmp_mdata;
890  mdata->adata = adata;
891  mdata->group = group;
892  mdata->bcache = NULL;
893  }
894  else if (mdata->newsrc_ent || mdata->subscribed || C_SaveUnsubscribed)
895  continue;
896 
898  if (S_ISDIR(sb.st_mode))
899  {
900  rmdir(file);
901  mutt_debug(LL_DEBUG2, "%s\n", file);
902  }
903  }
904  closedir(dp);
905  }
906 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ nntp_format_str()

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

Definition at line 920 of file newsrc.c.

923 {
924  struct NntpAccountData *adata = (struct NntpAccountData *) data;
925  struct ConnAccount *cac = &adata->conn->account;
926  char fn[128], fmt[128];
927 
928  switch (op)
929  {
930  case 'a':
931  {
932  struct Url url = { 0 };
933  mutt_account_tourl(cac, &url);
934  url_tostring(&url, fn, sizeof(fn), U_PATH);
935  char *p = strchr(fn, '/');
936  if (p)
937  *p = '\0';
938  snprintf(fmt, sizeof(fmt), "%%%ss", prec);
939  snprintf(buf, buflen, fmt, fn);
940  break;
941  }
942  case 'p':
943  snprintf(fmt, sizeof(fmt), "%%%su", prec);
944  snprintf(buf, buflen, fmt, cac->port);
945  break;
946  case 'P':
947  *buf = '\0';
948  if (cac->flags & MUTT_ACCT_PORT)
949  {
950  snprintf(fmt, sizeof(fmt), "%%%su", prec);
951  snprintf(buf, buflen, fmt, cac->port);
952  }
953  break;
954  case 's':
955  mutt_str_copy(fn, cac->host, sizeof(fn));
956  mutt_str_lower(fn);
957  snprintf(fmt, sizeof(fmt), "%%%ss", prec);
958  snprintf(buf, buflen, fmt, fn);
959  break;
960  case 'S':
961  {
962  struct Url url = { 0 };
963  mutt_account_tourl(cac, &url);
964  url_tostring(&url, fn, sizeof(fn), U_PATH);
965  char *p = strchr(fn, ':');
966  if (p)
967  *p = '\0';
968  snprintf(fmt, sizeof(fmt), "%%%ss", prec);
969  snprintf(buf, buflen, fmt, fn);
970  break;
971  }
972  case 'u':
973  snprintf(fmt, sizeof(fmt), "%%%ss", prec);
974  snprintf(buf, buflen, fmt, cac->user);
975  break;
976  }
977  return src;
978 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ nntp_compare_order()

int nntp_compare_order ( const void *  a,
const void *  b 
)

Sort to mailbox order - Implements sort_t.

Definition at line 2257 of file nntp.c.

2258 {
2259  const struct Email *ea = *(struct Email const *const *) a;
2260  const struct Email *eb = *(struct Email const *const *) b;
2261 
2262  anum_t na = nntp_edata_get((struct Email *) ea)->article_num;
2263  anum_t nb = nntp_edata_get((struct Email *) eb)->article_num;
2264  int result = (na == nb) ? 0 : (na > nb) ? 1 : -1;
2265  result = perform_auxsort(result, a, b);
2266  return SORT_CODE(result);
2267 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ nntp_path_probe()

enum MailboxType nntp_path_probe ( const char *  path,
const struct stat *  st 
)

Is this an NNTP Mailbox? - Implements MxOps::path_probe()

Definition at line 2685 of file nntp.c.

2686 {
2687  if (mutt_istr_startswith(path, "news://"))
2688  return MUTT_NNTP;
2689 
2690  if (mutt_istr_startswith(path, "snews://"))
2691  return MUTT_NNTP;
2692 
2693  return MUTT_UNKNOWN;
2694 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ group_index_format_str()

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

Definition at line 54 of file browse.c.

58 {
59  char fn[128], fmt[128];
60  struct Folder *folder = (struct Folder *) data;
61 
62  switch (op)
63  {
64  case 'C':
65  snprintf(fmt, sizeof(fmt), "%%%sd", prec);
66  snprintf(buf, buflen, fmt, folder->num + 1);
67  break;
68 
69  case 'd':
70  if (folder->ff->nd->desc)
71  {
72  char *desc = mutt_str_dup(folder->ff->nd->desc);
76 
77  snprintf(fmt, sizeof(fmt), "%%%ss", prec);
78  snprintf(buf, buflen, fmt, desc);
79  FREE(&desc);
80  }
81  else
82  {
83  snprintf(fmt, sizeof(fmt), "%%%ss", prec);
84  snprintf(buf, buflen, fmt, "");
85  }
86  break;
87 
88  case 'f':
89  mutt_str_copy(fn, folder->ff->name, sizeof(fn));
90  snprintf(fmt, sizeof(fmt), "%%%ss", prec);
91  snprintf(buf, buflen, fmt, fn);
92  break;
93 
94  case 'M':
95  snprintf(fmt, sizeof(fmt), "%%%sc", prec);
96  if (folder->ff->nd->deleted)
97  snprintf(buf, buflen, fmt, 'D');
98  else
99  snprintf(buf, buflen, fmt, folder->ff->nd->allowed ? ' ' : '-');
100  break;
101 
102  case 'N':
103  snprintf(fmt, sizeof(fmt), "%%%sc", prec);
104  if (folder->ff->nd->subscribed)
105  snprintf(buf, buflen, fmt, ' ');
106  else
107  snprintf(buf, buflen, fmt, folder->ff->has_new_mail ? 'N' : 'u');
108  break;
109 
110  case 'n':
111  if (C_MarkOld && (folder->ff->nd->last_cached >= folder->ff->nd->first_message) &&
112  (folder->ff->nd->last_cached <= folder->ff->nd->last_message))
113  {
114  snprintf(fmt, sizeof(fmt), "%%%sd", prec);
115  snprintf(buf, buflen, fmt, folder->ff->nd->last_message - folder->ff->nd->last_cached);
116  }
117  else
118  {
119  snprintf(fmt, sizeof(fmt), "%%%sd", prec);
120  snprintf(buf, buflen, fmt, folder->ff->nd->unread);
121  }
122  break;
123 
124  case 's':
125  if (flags & MUTT_FORMAT_OPTIONAL)
126  {
127  if (folder->ff->nd->unread != 0)
128  {
129  mutt_expando_format(buf, buflen, col, cols, if_str,
130  group_index_format_str, data, flags);
131  }
132  else
133  {
134  mutt_expando_format(buf, buflen, col, cols, else_str,
135  group_index_format_str, data, flags);
136  }
137  }
138  else
139  {
140  snprintf(fmt, sizeof(fmt), "%%%sd", prec);
141  snprintf(buf, buflen, fmt, folder->ff->nd->unread);
142  }
143  break;
144  }
145  return src;
146 }
+ 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 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Variable Documentation

◆ C_CatchupNewsgroup

unsigned char C_CatchupNewsgroup

Config: (nntp) Mark all articles as read when leaving a newsgroup.

Definition at line 37 of file config.c.

◆ C_FollowupToPoster

unsigned char C_FollowupToPoster

Config: (nntp) Reply to the poster if 'poster' is in the 'Followup-To' header.

Definition at line 38 of file config.c.

◆ C_GroupIndexFormat

char* C_GroupIndexFormat

Config: (nntp) printf-like format string for the browser's display of newsgroups.

Definition at line 39 of file config.c.

◆ C_NewsServer

char* C_NewsServer

Config: (nntp) Url of the news server.

Definition at line 41 of file config.c.

◆ C_NewsgroupsCharset

char* C_NewsgroupsCharset

Config: (nntp) Character set of newsgroups' descriptions.

Definition at line 42 of file config.c.

◆ C_PostModerated

unsigned char C_PostModerated

Config: (nntp) Allow posting to moderated newsgroups.

Definition at line 51 of file config.c.

◆ C_ShowOnlyUnread

bool C_ShowOnlyUnread

Config: (nntp) Only show subscribed newsgroups with unread articles.

Definition at line 54 of file config.c.

◆ C_XCommentTo

bool C_XCommentTo

Config: (nntp) Add 'X-Comment-To' header that contains article author.

Definition at line 55 of file config.c.

◆ CurrentNewsSrv

struct NntpAccountData* CurrentNewsSrv

Current NNTP news server.

Definition at line 79 of file nntp.c.

◆ MxNntpOps

struct MxOps MxNntpOps

NNTP Mailbox - Implements MxOps.

Definition at line 2726 of file nntp.c.

NntpAccountData::cacheable
bool cacheable
Definition: adata.h:46
Url::src
char * src
Raw URL string.
Definition: url.h:76
ChildCtx::mailbox
struct Mailbox * mailbox
Definition: nntp.c:109
nntp_check_new_groups
int nntp_check_new_groups(struct Mailbox *m, struct NntpAccountData *adata)
Check for new groups/articles in subscribed groups.
Definition: nntp.c:2015
IP
#define IP
Definition: set.h:54
NntpMboxData::unread
anum_t unread
Definition: mdata.h:39
Email::date_sent
time_t date_sent
Time when the message was sent (UTC)
Definition: email.h:82
NntpAccountData::size
off_t size
Definition: adata.h:52
NntpMboxData::group
char * group
Definition: mdata.h:33
mutt_file_lock
int mutt_file_lock(int fd, bool excl, bool timeout)
(try to) lock a file using fcntl()
Definition: file.c:1175
ConnAccount
Login details for a remote server.
Definition: connaccount.h:51
Connection
An open network connection (socket)
Definition: connection.h:34
mutt_mb_filter_unprintable
int mutt_mb_filter_unprintable(char **s)
Replace unprintable characters.
Definition: mbyte.c:424
C_NewsgroupsCharset
char * C_NewsgroupsCharset
Config: (nntp) Character set of newsgroups' descriptions.
Definition: config.c:42
nntp_connect_error
static int nntp_connect_error(struct NntpAccountData *adata)
Signal a failed connection.
Definition: nntp.c:128
ConnAccount::host
char host[128]
Server to login to.
Definition: connaccount.h:53
mdata_find
static struct NntpMboxData * mdata_find(struct NntpAccountData *adata, const char *group)
Find NntpMboxData for given newsgroup or add it.
Definition: newsrc.c:74
mutt_mem_calloc
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
Definition: memory.c:50
nntp_edata_free
void nntp_edata_free(void **ptr)
Free the private Email data - Implements Email::edata_free()
Definition: edata.c:37
mutt_account_fromurl
int mutt_account_fromurl(struct ConnAccount *cac, const struct Url *url)
Fill ConnAccount with information from url.
Definition: mutt_account.c:43
mutt_hash_delete
void mutt_hash_delete(struct HashTable *table, const char *strkey, const void *data)
Remove an element from a Hash Table.
Definition: hash.c:419
NntpAccountData::status
unsigned int status
Definition: adata.h:45
_
#define _(a)
Definition: message.h:28
NONULL
#define NONULL(x)
Definition: string2.h:37
NntpAccountData::authenticators
char * authenticators
Definition: adata.h:50
nntp_add_group
int nntp_add_group(char *line, void *data)
Parse newsgroup.
Definition: newsrc.c:576
U_NNTPS
@ U_NNTPS
Url is nntps://.
Definition: url.h:41
Mailbox::emails
struct Email ** emails
Array of Emails.
Definition: mailbox.h:99
mutt_strn_equal
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
MUTT_ACCT_PORT
#define MUTT_ACCT_PORT
Port field has been set.
Definition: connaccount.h:42
NT_MAILBOX_INVALID
@ NT_MAILBOX_INVALID
Email list was changed.
Definition: mailbox.h:173
NntpAccountData::groups_num
unsigned int groups_num
Definition: adata.h:56
nntp_open_connection
int nntp_open_connection(struct NntpAccountData *adata)
Connect to server, authenticate and get capabilities.
Definition: nntp.c:1702
FolderFile::has_new_mail
bool has_new_mail
true if mailbox has "new mail"
Definition: browser.h:70
Connection::account
struct ConnAccount account
Account details: username, password, etc.
Definition: connection.h:36
ConnAccount::get_field
const char *(* get_field)(enum ConnAccountField field, void *gf_data)
Function to get some login credentials.
Definition: connaccount.h:67
mutt_file_fclose
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:153
cache_expand
static void cache_expand(char *dst, size_t dstlen, struct ConnAccount *cac, const char *src)
Make fully qualified cache file name.
Definition: newsrc.c:521
nntp_edata_get
struct NntpEmailData * nntp_edata_get(struct Email *e)
Get the private data for this Email.
Definition: edata.c:57
mutt_account_tourl
void mutt_account_tourl(struct ConnAccount *cac, struct Url *url)
Fill URL with info from account.
Definition: mutt_account.c:79
ANUM
#define ANUM
Definition: lib.h:73
U_NO_FLAGS
#define U_NO_FLAGS
Definition: url.h:48
Folder::ff
struct FolderFile * ff
Definition: browser.h:51
update_file
static int update_file(char *filename, char *buf)
Update file with new contents.
Definition: newsrc.c:392
nntp_format_str
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.
Definition: newsrc.c:920
mutt_socket_close
int mutt_socket_close(struct Connection *conn)
Close a socket.
Definition: socket.c:96
Url::scheme
enum UrlScheme scheme
Scheme, e.g. U_SMTPS.
Definition: url.h:69
nntp_active_fetch
int nntp_active_fetch(struct NntpAccountData *adata, bool mark_new)
Fetch list of all newsgroups from server.
Definition: nntp.c:1948
NntpMboxData::desc
char * desc
Definition: mdata.h:34
mutt_str_dup
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:370
nntp_adata_new
struct NntpAccountData * nntp_adata_new(struct Connection *conn)
Allocate and initialise a new NntpAccountData structure.
Definition: adata.c:63
mutt_file_fopen
FILE * mutt_file_fopen(const char *path, const char *mode)
Call fopen() safely.
Definition: file.c:589
LL_DEBUG1
@ LL_DEBUG1
Log at debug level 1.
Definition: logging.h:40
NntpAccountData::groups_list
void ** groups_list
Definition: adata.h:58
FREE
#define FREE(x)
Definition: memory.h:40
mutt_perror
#define mutt_perror(...)
Definition: logging.h:85
get_description
static int get_description(struct NntpMboxData *mdata, const char *wildmat, const char *msg)
Fetch newsgroups descriptions.
Definition: nntp.c:880
mutt_socket_readln
#define mutt_socket_readln(buf, buflen, conn)
Definition: mutt_socket.h:36
Email::path
char * path
Path of Email (for local Mailboxes)
Definition: email.h:92
Email::edata_free
void(* edata_free)(void **ptr)
Free the private data attached to the Email.
Definition: email.h:117
NntpMboxData::first_message
anum_t first_message
Definition: mdata.h:35
PATH_MAX
#define PATH_MAX
Definition: mutt.h:44
mutt_ch_convert_string
int mutt_ch_convert_string(char **ps, const char *from, const char *to, uint8_t flags)
Convert a string between encodings.
Definition: charset.c:754
MUTT_FORMAT_NO_FLAGS
#define MUTT_FORMAT_NO_FLAGS
No flags are set.
Definition: format_flags.h:30
email_new
struct Email * email_new(void)
Create a new Email.
Definition: email.c:72
url_parse
struct Url * url_parse(const char *src)
Fill in Url.
Definition: url.c:234
Folder::num
int num
Definition: browser.h:52
NntpAccountData::fp_newsrc
FILE * fp_newsrc
Definition: adata.h:48
NntpMboxData::allowed
bool allowed
Definition: mdata.h:42
NntpAccountData::conn
struct Connection * conn
Definition: adata.h:60
nntp_parse_xref
static void nntp_parse_xref(struct Mailbox *m, struct Email *e)
Parse cross-reference.
Definition: nntp.c:912
NntpMboxData::adata
struct NntpAccountData * adata
Definition: mdata.h:46
MUTT_READ
@ MUTT_READ
Messages that have been read.
Definition: mutt.h:96
mutt_hash_find
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
CurrentNewsSrv
struct NntpAccountData * CurrentNewsSrv
Current NNTP news server.
Definition: nntp.c:79
mutt_str_equal
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:871
mutt_strn_cat
char * mutt_strn_cat(char *d, size_t l, const char *s, size_t sl)
Concatenate two strings.
Definition: string.c:414
NewsrcEntry::last
anum_t last
Definition: lib.h:90
active_get_cache
static int active_get_cache(struct NntpAccountData *adata)
Load list of all newsgroups from cache.
Definition: newsrc.c:617
Email::old
bool old
Email is seen, but unread.
Definition: email.h:50
Email::received
time_t received
Time when the message was placed in the mailbox.
Definition: email.h:83
ChildCtx
Keep track of the children of an article.
Definition: nntp.c:107
NntpAccountData::newsrc_file
char * newsrc_file
Definition: adata.h:49
MUTT_ICONV_HOOK_FROM
#define MUTT_ICONV_HOOK_FROM
apply charset-hooks to fromcode
Definition: charset.h:74
mx_alloc_memory
void mx_alloc_memory(struct Mailbox *m)
Create storage for the emails.
Definition: mx.c:1230
Envelope::xref
char * xref
List of cross-references.
Definition: envelope.h:76
NNTP_NONE
@ NNTP_NONE
No connection to server.
Definition: private.h:42
mutt_expand_path
char * mutt_expand_path(char *buf, size_t buflen)
Create the canonical path.
Definition: muttlib.c:128
MUTT_NNTP
@ MUTT_NNTP
'NNTP' (Usenet) Mailbox type
Definition: mailbox.h:52
Folder
A folder/dir in the browser.
Definition: browser.h:49
Mailbox::type
enum MailboxType type
Mailbox type.
Definition: mailbox.h:105
Mailbox::mdata
void * mdata
Driver specific data.
Definition: mailbox.h:136
url_tostring
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
U_PATH
#define U_PATH
Definition: url.h:49
perform_auxsort
int perform_auxsort(int retval, const void *a, const void *b)
Compare two emails using the auxiliary sort method.
Definition: sort.c:66
fetch_tempfile
static int fetch_tempfile(char *line, void *data)
Write line to temporary file.
Definition: nntp.c:953
nntp_delete_group_cache
void nntp_delete_group_cache(struct NntpMboxData *mdata)
Remove hcache and bcache of newsgroup.
Definition: newsrc.c:809
mutt_file_unlock
int mutt_file_unlock(int fd)
Unlock a file previously locked by mutt_file_lock()
Definition: file.c:1223
Url
A parsed URL proto://user:password@host:port/path?a=1&b=2
Definition: url.h:67
url_free
void url_free(struct Url **ptr)
Free the contents of a URL.
Definition: url.c:123
Mailbox::msg_count
int msg_count
Total number of messages.
Definition: mailbox.h:91
mutt_clear_error
void mutt_clear_error(void)
Clear the message line (bottom line of screen)
Definition: mutt_logging.c:113
MUTT_UNKNOWN
@ MUTT_UNKNOWN
Mailbox wasn't recognised.
Definition: mailbox.h:47
NntpMboxData::last_message
anum_t last_message
Definition: mdata.h:36
nntp_newsrc_parse
int nntp_newsrc_parse(struct NntpAccountData *adata)
Parse .newsrc file.
Definition: newsrc.c:164
mutt_hcache_free_raw
void mutt_hcache_free_raw(struct HeaderCache *hc, void **data)
Multiplexor for StoreOps::free.
Definition: hcache.c:514
C_SaveUnsubscribed
bool C_SaveUnsubscribed
Config: (nntp) Save a list of unsubscribed newsgroups to the 'newsrc'.
Definition: config.c:52
NntpMboxData::newsrc_ent
struct NewsrcEntry * newsrc_ent
Definition: mdata.h:45
nntp_fetch_lines
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:766
NntpAccountData::mtime
time_t mtime
Definition: adata.h:53
mutt_mem_realloc
void mutt_mem_realloc(void *ptr, size_t size)
Resize a block of memory on the heap.
Definition: memory.c:114
FolderFile::name
char * name
Definition: browser.h:67
ConnAccount::type
unsigned char type
Connection type, e.g. MUTT_ACCT_TYPE_IMAP.
Definition: connaccount.h:58
Email::env
struct Envelope * env
Envelope information.
Definition: email.h:90
mutt_debug
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
Mailbox::email_max
int email_max
Number of pointers in emails.
Definition: mailbox.h:100
anum_t
#define anum_t
Definition: lib.h:72
NewsrcEntry
An entry in a .newsrc (subscribed newsgroups)
Definition: lib.h:87
nntp_select_server
struct NntpAccountData * nntp_select_server(struct Mailbox *m, const char *server, bool leave_lock)
Open a connection to an NNTP server.
Definition: newsrc.c:1012
mutt_str_len
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
Definition: string.c:631
MUTT_ACCT_USER
#define MUTT_ACCT_USER
User field has been set.
Definition: connaccount.h:43
Mailbox::verbose
bool verbose
Display status messages?
Definition: mailbox.h:118
CurrentNewsSrv
struct NntpAccountData * CurrentNewsSrv
Current NNTP news server.
Definition: nntp.c:79
ConnAccount::flags
MuttAccountFlags flags
Which fields are initialised, e.g. MUTT_ACCT_USER.
Definition: connaccount.h:59
NntpMboxData::last_loaded
anum_t last_loaded
Definition: mdata.h:37
mutt_str_lower
char * mutt_str_lower(char *str)
Convert all characters in the string to lowercase.
Definition: string.c:504
group_index_format_str
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.
Definition: browse.c:54
nntp_group_unread_stat
void nntp_group_unread_stat(struct NntpMboxData *mdata)
Count number of unread articles using .newsrc data.
Definition: newsrc.c:134
MUTT_FORMAT_OPTIONAL
#define MUTT_FORMAT_OPTIONAL
Allow optional field processing.
Definition: format_flags.h:33
NNTP_BYE
@ NNTP_BYE
Disconnected from server.
Definition: private.h:44
NntpMboxData::subscribed
bool subscribed
Definition: mdata.h:40
Email::deleted
bool deleted
Email is deleted.
Definition: email.h:45
mutt_file_mkdir
int mutt_file_mkdir(const char *path, mode_t mode)
Recursively create directories.
Definition: file.c:875
nntp_get_field
static const char * nntp_get_field(enum ConnAccountField field, void *gf_data)
Get connection login credentials - Implements ConnAccount::get_field()
Definition: newsrc.c:983
MUTT_ACCT_SSL
#define MUTT_ACCT_SSL
Account uses SSL/TLS.
Definition: connaccount.h:46
C_Newsrc
char * C_Newsrc
Config: (nntp) File containing list of subscribed newsgroups.
Definition: config.c:43
NntpAccountData::newsrc_modified
bool newsrc_modified
Definition: adata.h:47
HeaderCache
header cache structure
Definition: lib.h:85
NntpAccountData
NNTP-specific Account data -.
Definition: adata.h:33
ConnAccount::port
unsigned short port
Port to connect to.
Definition: connaccount.h:57
C_NewsServer
char * C_NewsServer
Config: (nntp) Url of the news server.
Definition: config.c:41
mutt_expando_format
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:774
Email::edata
void * edata
Driver-specific data.
Definition: email.h:111
mutt_mem_malloc
void * mutt_mem_malloc(size_t size)
Allocate memory on the heap.
Definition: memory.c:90
nntp_hcache_open
struct HeaderCache * nntp_hcache_open(struct NntpMboxData *mdata)
Open newsgroup hcache.
Definition: newsrc.c:710
nntp_clear_cache
void nntp_clear_cache(struct NntpAccountData *adata)
Clear the NNTP cache.
Definition: newsrc.c:843
C_NntpLoadDescription
bool C_NntpLoadDescription
Config: (nntp) Load descriptions for newsgroups when adding to the list.
Definition: config.c:47
C_NewsCacheDir
char * C_NewsCacheDir
Config: (nntp) Directory for cached news articles.
Definition: config.c:40
U_NNTP
@ U_NNTP
Url is nntp://.
Definition: url.h:40
mutt_istr_startswith
size_t mutt_istr_startswith(const char *str, const char *prefix)
Check whether a string starts with a prefix, ignoring case.
Definition: string.c:172
Url::host
char * host
Host.
Definition: url.h:72
mailbox_changed
void mailbox_changed(struct Mailbox *m, enum NotifyMailbox action)
Notify observers of a change to a Mailbox.
Definition: mailbox.c:186
Account::adata
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
FolderFile::nd
struct NntpMboxData * nd
Definition: browser.h:85
NntpMboxData::deleted
bool deleted
Definition: mdata.h:43
NntpMboxData::last_cached
anum_t last_cached
Definition: mdata.h:38
C_MarkOld
bool C_MarkOld
Config: Mark new emails as old when leaving the mailbox.
Definition: globals.c:36
Email::index
int index
The absolute (unsorted) message number.
Definition: email.h:86
NntpEmailData::article_num
anum_t article_num
Definition: edata.h:33
mutt_rfc822_read_header
struct Envelope * mutt_rfc822_read_header(FILE *fp, struct Email *e, bool user_hdrs, bool weed)
parses an RFC822 header
Definition: parse.c:1112
email_free
void email_free(struct Email **ptr)
Free an Email.
Definition: email.c:43
MUTT_SOCK_LOG_FULL
#define MUTT_SOCK_LOG_FULL
Definition: mutt_socket.h:31
ConnAccount::service
const char * service
Name of the service, e.g. "imap".
Definition: connaccount.h:60
MUTT_ACCT_TYPE_NNTP
@ MUTT_ACCT_TYPE_NNTP
Nntp (Usenet) Account.
Definition: mutt_account.h:40
Url::path
char * path
Path.
Definition: url.h:74
mutt_hcache_fetch_raw
void * mutt_hcache_fetch_raw(struct HeaderCache *hc, const char *key, size_t keylen, size_t *dlen)
Fetch a message's header from the cache.
Definition: hcache.c:496
fetch_children
static int fetch_children(char *line, void *data)
Parse XPAT line.
Definition: nntp.c:1672
nntp_fetch_headers
static int nntp_fetch_headers(struct Mailbox *m, void *hc, anum_t first, anum_t last, bool restore)
Fetch headers.
Definition: nntp.c:1150
mutt_hcache_close
void mutt_hcache_close(struct HeaderCache *hc)
Multiplexor for StoreOps::close.
Definition: hcache.c:419
C_Charset
char * C_Charset
Config: Default character set for displaying text on screen.
Definition: charset.c:53
Email
The envelope/body of an email.
Definition: email.h:37
mutt_str_startswith
size_t mutt_str_startswith(const char *str, const char *prefix)
Check whether a string starts with a prefix.
Definition: string.c:160
nntp_edata_new
struct NntpEmailData * nntp_edata_new(void)
Create a new NntpEmailData for an Email.
Definition: edata.c:47
nntp_query
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:689
mutt_message
#define mutt_message(...)
Definition: logging.h:83
mutt_set_flag
#define mutt_set_flag(m, e, flag, bf)
Definition: protos.h:67
mutt_file_mkstemp
#define mutt_file_mkstemp()
Definition: file.h:109
mutt_conn_find
struct Connection * mutt_conn_find(const struct ConnAccount *cac)
Find a connection from a list.
Definition: mutt_socket.c:86
nntp_date
static int nntp_date(struct NntpAccountData *adata, time_t *now)
Get date and time from server.
Definition: nntp.c:1635
nntp_active_save_cache
int nntp_active_save_cache(struct NntpAccountData *adata)
Save list of all newsgroups to cache.
Definition: newsrc.c:651
Email::read
bool read
Email is read.
Definition: email.h:51
NNTP_SSL_PORT
#define NNTP_SSL_PORT
Definition: private.h:35
NntpAccountData::newgroups_time
time_t newgroups_time
Definition: adata.h:54
ConnAccount::user
char user[128]
Username.
Definition: connaccount.h:55
NntpAccountData::groups_hash
struct HashTable * groups_hash
Definition: adata.h:59
LL_DEBUG2
@ LL_DEBUG2
Log at debug level 2.
Definition: logging.h:41
nntp_newsrc_close
void nntp_newsrc_close(struct NntpAccountData *adata)
Unlock and close .newsrc file.
Definition: newsrc.c:120
mutt_hash_free
void mutt_hash_free(struct HashTable **ptr)
Free a hash table.
Definition: hash.c:447
mutt_socket_send_d
#define mutt_socket_send_d(conn, buf, dbg)
Definition: mutt_socket.h:38
Email::changed
bool changed
Email has been edited.
Definition: email.h:48
NntpMboxData
NNTP-specific Mailbox data -.
Definition: mdata.h:31
mutt_error
#define mutt_error(...)
Definition: logging.h:84
SORT_CODE
#define SORT_CODE(x)
Definition: sort.h:40
mutt_str_copy
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:716
NNTP_PORT
#define NNTP_PORT
Definition: private.h:34