📄 nnrp.c
字号:
/* * nnrp.c write by rexchen@ug.ee.tku.edu.tw */#include "nntp.h"intadd_cancel (options, data)struct nntp_opt *options;char *data;{ char fpath[PATHLEN] = { 0 }; FILE *fp; sprintf (fpath, "%s/%s", options->conf_dir, EXPIRE_LIST); if ((fp = fopen (fpath, "a")) != NULL) { fprintf (fp, data); fclose (fp); }}inthead_hack (msgbuf, head)char *msgbuf;struct dirhead *head;{ char *m = NULL, *n = NULL, *o = NULL; char *from = NULL; char nick[NIDLEN] = { 0 }; char owner[IDLEN] = { 0 }; char mail[MAILLEN] = { 0 }; char title[TITLELEN] = { 0 }; int n_num = 0; int o_num = 0; int m_num = 0; int state = 0; if (str_ncmp (msgbuf, "From: ", 6) == 0) { for (from = msgbuf; *from; from++) { switch (state) { case 0: if (*from == ':') state = 1; break; case 1: if (*from == '"') { n = from + 1; n_num = 0; state = 2; } else if (*from == '(') { n = from + 1; n_num = 0; state = 3; } else if (*from == '<') { o_num = m_num = 0; o = m = from + 1; state = 4; } else if (isalnum (*from)) { o_num = m_num = 0; o = m = from; state = 4; } break; case 2: n_num++; if (*from == '"') { n_num--; strncpy (nick, n, n_num); state = 1; } break; case 3: n_num++; if (*from == ')') { n_num--; strncpy (nick, n, n_num); state = 1; } break; case 4: o_num++; m_num++; if (*from == '@') { strncpy (owner, o, o_num); state = 5; } else if (*from == ' ' || *from == '\t') state = 1; else if (strchr (">,\r\n", *from)) { m_num--; strncpy (mail, m, m_num); state = 1; } /* everything else, including alphanumerics, just passes through */ break; case 5: m_num++; if (isspace (*from)) { strncpy (mail, m, m_num); state = 1; } else if (*from == '>' || *from == ',') { m_num--; strncpy (mail, m, m_num); state = 1; } break; } } if (o_num) { strtok (owner, ".@"); strcat (owner, "."); } strtok (owner, "\r\n"); strtok (nick, "\r\n"); strtok (mail, "\r\n"); strncpy (head->owner, owner, IDLEN); strncpy (head->nick, nick, NIDLEN); strncpy (head->mail, mail, MAILLEN); return (1); } if (str_ncmp (msgbuf, "Subject: ", 9) == 0) { strncpy (title, msgbuf + 9, TITLELEN); strtok (title, "\r\n"); strncpy (head->title, title, TITLELEN); return (1); }}intnnrp_article (sockfd, art, head, fpath)int sockfd;struct article *art;struct dirhead *head;char *fpath;{ char msgbuf[NEWS_BSIZE] = { 0 }; int lines = 0; int mfd = -1; int length = 0; int inheaders = 1; sockprintf (sockfd, "ARTICLE %d\r\n", art->num); if (get_reply (sockfd, msgbuf) == NNTP_ART_OK) { if ((mfd = openfile (fpath)) < 0) { return -2; } while (1) { if (sockgetline (sockfd, msgbuf, NEWS_BSIZE) < 0) { return -10; } if (inheaders && msgbuf[0] == '\0') inheaders = 0; if (msgbuf[0] == '.' && msgbuf[1] == 0) break; strcat (msgbuf, "\n");/* rexchen header hack */ if (inheaders) { if (!str_ncmp ("From: ", msgbuf, 6) || !str_ncmp ("Subject: ", msgbuf, 9)) { head_hack (msgbuf, head); } } length = strlen (msgbuf); if (write (mfd, msgbuf, length) < 0) { return (-1); } lines++; } closefile (mfd); return (lines); } else { return (-1); }}intget_article (sockfd, options, art)int sockfd;struct nntp_opt *options;struct article *art;{ char fname[PATHLEN] = { 0 }; char fpath[PATHLEN] = { 0 }; char artpath[PATHLEN] = { 0 }; struct dirhead head; sprintf (fpath, "%s/boards/%s", BBS_HOME, art->board); gen_fname (fpath, fname); sprintf (artpath, "%s/%s", fpath, fname); if (nnrp_article (sockfd, art, &head, artpath) != -1) { add_his (options->history, art->msgid, 0, artpath); } else { unlink (artpath); return (-1); } strncpy (head.bname, art->board, BNLEN); strncpy (head.fname, fname, PATHLEN); head.time = time (NULL); rtime (&head.time, head.date); sprintf (fpath, "%s/boards/%s/%s", BBS_HOME, art->board, DIR_FILE); add_record (fpath, &head, sizeof (struct dirhead));}intnnrp_group (sockfd, group)int sockfd;char *group;{ return (sockprintf (sockfd, "GROUP %s\r\n", group));}intnnrp_stat (sockfd, artno)int sockfd;int artno;{ return (sockprintf (sockfd, "STAT %d\r\n", artno));}intget_xhdr (sockfd, cancel, art)int sockfd;int cancel;struct article *art;{ int rpy = 0; char buf[NEWS_BSIZE] = { 0 }; char tmp[MSGIDLEN] = { 0 }; if (!sockgetline (sockfd, buf, NEWS_BSIZE)) { if (buf[0] == '.' && buf[1] == 0) { rpy = NNTP_XHDR_END; } else { strtok (buf, "\r\n"); if (cancel) sscanf (buf, "%d %s %s", &(art->num), tmp, art->msgid); else sscanf (buf, "%d %s", &(art->num), art->msgid); } } return (rpy);}intnnrp_xhdr (sockfd, options, pattern, cancel, low, high, art)int sockfd;struct nntp_opt *options;char *pattern;int cancel;ULONG low, high;struct article *art;{ int i = 0; int status = 0; struct article drop; char buf[NEWS_BSIZE] = { 0 }; char path[PATHLEN] = { 0 }; sockprintf (sockfd, "XHDR %s %d-%d\r\n", pattern, low, high); if (get_reply (sockfd, buf) == NNTP_XHDR_OK) { if (cancel) { while ((status = get_xhdr (sockfd, cancel, &drop)) != NNTP_XHDR_END) { if (query_his (options->history, drop.msgid, path) == 1) { add_cancel (options, path); } } } else { while ((status = get_xhdr (sockfd, cancel, &(art[i]))) != NNTP_XHDR_END && i < MAX_ARTS - 1) { if (query_his (options->history, art[i].msgid, path) == 0) i++; } if (status != NNTP_XHDR_END) { while (get_xhdr (sockfd, cancel, &drop) != NNTP_XHDR_END) { } } } } return (i);}intnnrp_get (sockfd, options, rcptr, nf, feeds_num)int sockfd;struct nntp_opt *options;struct active *rcptr;struct newsfeeds *nf;int feeds_num;{ char buf[NEWS_BSIZE] = { 0 }; char group[GROUPLEN] = { 0 }; struct article art[MAX_ARTS] = { 0 }; int i = 0, code = 0, size = 0, status = 0, max_stats = MAX_STATS; ULONG low = 0, high = 0, tmp = 0, maxartno = 0, maxget = 0; int xhdr = 0, nnrpstatus = 0; int cancel = 0; sprintf (group, "%-.*s", rcptr->namelen, rcptr->nameptr); nnrp_group (sockfd, group); status = get_reply (sockfd, buf); if (status == NNTP_GROUP_OK) { sscanf (buf, "%d %d %ld %ld", &code, &size, &low, &high); if (low > high) { tmp = low; low = high; high = tmp; } if (rcptr->low != low) { rcptr->low = low; updateactive (rcptr->lowptr, rcptr->lowlen, rcptr->low); } if (options->flag == NNTP_RESET) { if (rcptr->high != high) { rcptr->high = high; updateactive (rcptr->highptr, rcptr->highlen, rcptr->high); } return (0); } if (rcptr->high < low) { rcptr->high = low; updateactive (rcptr->highptr, rcptr->highlen, low); } maxget = high; if (high > rcptr->high + max_stats) { maxget = rcptr->high + max_stats; } if (strncmp (group, "control.cancel", GROUPLEN) == 0) { cancel = 1; xhdr = nnrp_xhdr (sockfd, options, "Control", cancel, rcptr->high + 1, maxget, art); } else { xhdr = nnrp_xhdr (sockfd, options, "Message-ID", cancel, rcptr->high + 1, maxget, art); } maxartno = maxget; if (xhdr > 0) maxartno = art[xhdr - 1].num; for (i = 0; i < xhdr; i++) {/* need stat ? *///nnrp_stat (sockfd, art[i].num); log_text (options->logfd, "** %d ** %d i have it %s", i, art[i].num, art[i].msgid); fill_board (&(art[i]), nf, group, feeds_num); nnrpstatus = get_article (sockfd, options, &(art[i])); if (nnrpstatus == -1) break; if (rcptr->high != art[i].num) { rcptr->high = art[i].num; updateactive (rcptr->highptr, rcptr->highlen, rcptr->high); } } if (rcptr->high != maxartno && nnrpstatus != -1 && xhdr >= 0) { rcptr->high = maxartno; updateactive (rcptr->highptr, rcptr->highlen, maxartno); } } else { return (-1); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -