static int nntp_get_cache_all (NNTP_SERVER *);
static int nntp_check_newgroups (NNTP_SERVER *, int);
-static void mutt_newsgroup_stat (nntp_data_t *);
static void nntp_delete_cache (nntp_data_t *);
/* newsrc {{{ */
+static void mutt_newsgroup_stat(nntp_data_t *data)
+{
+ data->unread = 0;
+ if (data->lastMessage == 0 || data->firstMessage > data->lastMessage)
+ return;
+
+ data->unread = data->lastMessage - data->firstMessage + 1;
+ for (int i = 0; i < data->num; i++) {
+ int first = MAX(data->entries[i].first, data->firstMessage);
+ int last = MIN(data->entries[i].last, data->lastMessage);
+ data->unread -= MAX(0, last - first + 1);
+ }
+}
+
static int nntp_parse_newsrc_line (NNTP_SERVER * news, char *line)
{
nntp_data_t *data;
* "skipped" in the newsrc, and new is anything not in the newsrc nor
* in the cache. By skipped, I mean before the last unread message
*/
-static void nntp_get_status(CONTEXT *ctx, HEADER *h, char *group, int article)
+static void
+nntp_get_status(CONTEXT *ctx, HEADER *h, const char *group, int article)
{
- nntp_data_t *data = (nntp_data_t *) ctx->data;
- int x;
-
- if (group)
- data = (nntp_data_t *) hash_find (data->nserv->newsgroups, group);
-
- if (!data) {
- return;
- }
-
- for (x = 0; x < data->num; x++) {
- if ((article >= data->entries[x].first) &&
- (article <= data->entries[x].last)) {
- /* we cannot use mutt_set_flag() because mx_update_context()
- didn't called yet */
- h->read = 1;
- return;
+ nntp_data_t *data = ctx->data;
+
+ if (group)
+ data = hash_find(data->nserv->newsgroups, group);
+ if (!data)
+ return;
+
+ for (int i = 0; i < data->num; i++) {
+ if ((article >= data->entries[i].first) &&
+ (article <= data->entries[i].last))
+ {
+ /* we cannot use mutt_set_flag() because mx_update_context()
+ didn't called yet */
+ h->read = 1;
+ return;
+ }
}
- }
- /* If article was not cached yet, it is new! :) */
- if (!data->cache || article > data->lastCached)
- return;
- /* Old articles are articles which aren't read but an article after them
- * has been cached */
- if (option (OPTMARKOLD))
- h->old = 1;
-}
-static void mutt_newsgroup_stat (nntp_data_t * data)
-{
- int i, first, last;
+ /* If article was not cached yet, it is new! :) */
+ if (!data->cache || article > data->lastCached)
+ return;
- data->unread = 0;
- if (data->lastMessage == 0 || data->firstMessage > data->lastMessage)
- return;
-
- data->unread = data->lastMessage - data->firstMessage + 1;
- for (i = 0; i < data->num; i++) {
- first = data->entries[i].first;
- if (first < data->firstMessage)
- first = data->firstMessage;
- last = data->entries[i].last;
- if (last > data->lastMessage)
- last = data->lastMessage;
- if (first <= last)
- data->unread -= last - first + 1;
- }
+ /* Old articles are articles which aren't read but an article after them
+ * has been cached */
+ if (option(OPTMARKOLD))
+ h->old = 1;
}
-static int puti (char *line, int num)
+static void nntp_create_newsrc_line(nntp_data_t *data, buffer_t *buf)
{
- char *p, s[32];
-
- for (p = s; num;) {
- *p++ = '0' + num % 10;
- num /= 10;
- }
- while (p > s)
- *line++ = *--p, num++;
- *line = '\0';
- return num;
-}
+ buffer_addstr(buf, data->group);
+ buffer_addch(buf, data->subscribed ? ':' : '!');
+ buffer_addch(buf, ' ');
-static void nntp_create_newsrc_line (nntp_data_t * data, char **buf,
- char **pline, ssize_t * buflen)
-{
- char *line = *pline;
- ssize_t len = *buflen - (*pline - *buf);
- int x, i;
-
- if (len < LONG_STRING * 10) {
- len += *buflen;
- *buflen *= 2;
- line = *buf;
- p_realloc(buf, *buflen);
- line = *buf + (*pline - line);
- }
- strcpy (line, data->group);
- len -= m_strlen(line) + 1;
- line += m_strlen(line);
- *line++ = data->subscribed ? ':' : '!';
- *line++ = ' ';
- *line = '\0';
-
- for (x = 0; x < data->num; x++) {
- if (len < LONG_STRING) {
- len += *buflen;
- *buflen *= 2;
- *pline = line;
- line = *buf;
- p_realloc(buf, *buflen);
- line = *buf + (*pline - line);
- }
- if (x) {
- *line++ = ',';
- len--;
- }
+ for (int x = 0; x < data->num; x++) {
+ if (x) {
+ buffer_addch(buf, ',');
+ }
- i = puti (line, data->entries[x].first);
- line += i;
- len -= i;
- if (data->entries[x].first != data->entries[x].last) {
- *line++ = '-';
- len--;
- i = puti (line, data->entries[x].last);
- line += i;
- len -= i;
+ buffer_addf(buf, "%d-%d", data->entries[x].first,
+ data->entries[x].last);
}
- }
- *line++ = '\n';
- *line = '\0';
- *pline = line;
+ buffer_addch(buf, '\n');
}
static void newsrc_gen_entries (CONTEXT * ctx)
}
static int mutt_update_list_file (char *filename, char *section,
- const char *key, char *line) {
+ const char *key, const char *line)
+{
FILE *ifp;
FILE *ofp;
char buf[HUGE_STRING];
int mutt_newsrc_update (NNTP_SERVER * news)
{
- char *buf, *line;
- nntp_data_t *data;
- int r = -1;
- ssize_t len, llen;
+ buffer_t buf;
+ nntp_data_t *data;
+ int r = -1;
- if (!news)
- return -1;
- llen = len = 10 * LONG_STRING;
- line = buf = p_new(char, len);
- /* we will generate full newsrc here */
- for (data = news->list; data; data = data->next) {
- if (!data || !data->rc)
- continue;
- nntp_create_newsrc_line (data, &buf, &line, &llen);
- line += m_strlen(line);
- }
- /* newrc being fully rewritten */
- if (news->newsrc &&
- (r = mutt_update_list_file(news->newsrc, NULL, "", buf)) == 0) {
- struct stat st;
+ if (!news)
+ return -1;
- stat (news->newsrc, &st);
- news->size = st.st_size;
- news->mtime = st.st_mtime;
- }
- p_delete(&buf);
- return r;
+ buffer_init(&buf);
+
+ /* we will generate full newsrc here */
+ for (data = news->list; data; data = data->next) {
+ if (!data || !data->rc)
+ continue;
+ nntp_create_newsrc_line(data, &buf);
+ }
+ /* newrc being fully rewritten */
+ if (news->newsrc
+ && (r = mutt_update_list_file(news->newsrc, NULL, "", buf.data)) == 0)
+ {
+ struct stat st;
+
+ stat (news->newsrc, &st);
+ news->size = st.st_size;
+ news->mtime = st.st_mtime;
+ }
+
+ buffer_wipe(&buf);
+ return r;
}
static FILE *mutt_mkname (char *s)
p++;
switch (x) {
case 0:
-
hdr->article_num = atoi (b);
nntp_get_status (ctx, hdr, NULL, hdr->article_num);
break;