X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ian/git?p=innduct.git;a=blobdiff_plain;f=backends%2Finnduct.c;h=acbae608ad4ecef16452814f886d56ef3a565d8d;hp=46d88bc65baf2a72eab1f9911f0ea5acc44708b3;hb=a89508cee0d8512cba067edff38c124c72b52bb6;hpb=aeb62f189a5d76b8ca0d23a46f7917679e081ea0 diff --git a/backends/innduct.c b/backends/innduct.c index 46d88bc..acbae60 100644 --- a/backends/innduct.c +++ b/backends/innduct.c @@ -1,4 +1,18 @@ /* + * bugs + * + + [740] info: processed feedfile(null) read=4(+0bl,+6err) offered=5(ch5,nc0) accepted=0(ch0+nc0) unwanted=0(0id+0bd+0nc) rejected=0(0id+0bd+0nc) deferred=0(0id+0bd+0nc) missing=2(0id+2bd+0nc) connretry=0(0id+0bd+0nc) + + (null) ?! + + also unwanted should be nonzero I think + + %d( is too hard to read + + [740] warning: corrupted file: /home/ian/things/Innfeed/inn2-2.4.5/fee, offset 349: line partially blanked: in ` @050000002D130000006A0000000000000000@ 8-/; print "\f" if m/-\^L-/' backends/innduct. #include #include #include +#include #include #include @@ -244,7 +259,7 @@ perl -ne 'print if m/-8\<-/..m/-\>8-/; print "\f" if m/-\^L-/' backends/innduct. #define LIST_REMHEAD(l) LIST_REMSOMEHOW((l),list_remhead) #define LIST_REMTAIL(l) LIST_REMSOMEHOW((l),list_remtail) -#define LIST_INIT(l) (list_new(&(l).u.li)) +#define LIST_INIT(l) ((l).count=0, list_new(&(l).u.li)) #define LIST_HEAD(l) ((typeof((l).u.for_type))(list_head((struct list*)&(l)))) #define LIST_NEXT(n) ((typeof(n))list_succ(NODE((n)))) #define LIST_BACK(n) ((typeof(n))list_pred(NODE((n)))) @@ -290,6 +305,8 @@ static void statemc_setstate(StateMachineState newsms, int periods, static void statemc_start_flush(const char *why); /* Normal => Flushing */ static void spawn_inndcomm_flush(const char *why); /* Moved => Flushing */ +static void article_done(Conn *conn, Article *art, int whichcount); + static void check_assign_articles(void); static void queue_check_input_done(void); @@ -358,7 +375,7 @@ typedef enum { /* in queue in conn->sent */ art_Unchecked, /* not checked, not sent checking */ art_Wanted, /* checked, wanted sent body as requested */ art_Unsolicited, /* - sent body without check */ - art_MaxState + art_MaxState, } ArtState; #define RESULT_COUNTS(RCS,RCN) \ @@ -367,9 +384,10 @@ typedef enum { /* in queue in conn->sent */ RCN(unwanted) \ RCN(rejected) \ RCN(deferred) \ + RCN(missing) \ RCN(connretry) -#define RCI_TRIPLE_FMT_BASE "%d(id%d+bd%d+nc%d)" +#define RCI_TRIPLE_FMT_BASE "%d(%did+%dbd+%dnc)" #define RCI_TRIPLE_VALS_BASE(counts,x) \ counts[art_Unchecked] x \ + counts[art_Wanted] x \ @@ -426,7 +444,7 @@ struct InputFile { struct Article { ISNODE(Article); ArtState state; - int midlen; + int midlen, missing; InputFile *ipf; TOKEN token; off_t offset; @@ -1038,6 +1056,7 @@ static void *conn_exception(oop_source *lp, int fd, static void vconnfail(Conn *conn, const char *fmt, va_list al) { int requeue[art_MaxState]; + memset(requeue,0,sizeof(requeue)); Article *art; while ((art= LIST_REMHEAD(conn->priority))) LIST_ADDTAIL(queue, art); @@ -1135,9 +1154,15 @@ static void connect_attempt_discard(void) { } #define PREP_DECL_MSG_CMSG(msg) \ + char msgbyte= 0; \ + struct iovec msgiov; \ + msgiov.iov_base= &msgbyte; \ + msgiov.iov_len= 1; \ struct msghdr msg; \ memset(&msg,0,sizeof(msg)); \ - char msg##cbuf[CMSG_SPACE(sizeof(fd))]; \ + char msg##cbuf[CMSG_SPACE(sizeof(int))]; \ + msg.msg_iov= &msgiov; \ + msg.msg_iovlen= 1; \ msg.msg_control= msg##cbuf; \ msg.msg_controllen= sizeof(msg##cbuf); @@ -1145,7 +1170,9 @@ static void *connchild_event(oop_source *lp, int fd, oop_event e, void *u) { Conn *conn= 0; assert(fd == connecting_fdpass_sock); + PREP_DECL_MSG_CMSG(msg); + ssize_t rs= recvmsg(fd, &msg, 0); if (rs<0) { if (isewouldblock(errno)) return OOP_CONTINUE; @@ -1155,6 +1182,9 @@ static void *connchild_event(oop_source *lp, int fd, oop_event e, void *u) { conn= xmalloc(sizeof(*conn)); memset(conn,0,sizeof(*conn)); + LIST_INIT(conn->waiting); + LIST_INIT(conn->priority); + LIST_INIT(conn->sent); struct cmsghdr *h= 0; if (rs >= 0) h= CMSG_FIRSTHDR(&msg); @@ -1215,9 +1245,6 @@ static void *connchild_event(oop_source *lp, int fd, oop_event e, void *u) { } /* Phew! */ - LIST_INIT(conn->waiting); - LIST_INIT(conn->priority); - LIST_INIT(conn->sent); conn->max_queue= conn->stream ? max_queue_per_conn : 1; loop->on_fd(loop, conn->fd, OOP_EXCEPTION, conn_exception, conn); @@ -1233,7 +1260,7 @@ static void *connchild_event(oop_source *lp, int fd, oop_event e, void *u) { connect_attempt_discard(); check_assign_articles(); - return 0; + return OOP_CONTINUE; x: conn_dispose(conn); @@ -1251,7 +1278,7 @@ static void connect_start(void) { assert(!connecting_child); assert(!connecting_fdpass_sock); - notice("starting connection attempt"); + info("starting connection attempt"); int socks[2]; int r= socketpair(AF_UNIX, SOCK_STREAM, 0, socks); @@ -1287,7 +1314,7 @@ static void connect_start(void) { if (NNTPsendpassword((char*)remote_host, cn_from, cn_to) < 0) sysfatal("connect: authentication failed"); if (try_stream) { - if (fputs("MODE STREAM\r\n", cn_to) || + if (fputs("MODE STREAM\r\n", cn_to)==EOF || fflush(cn_to)) sysfatal("connect: could not send MODE STREAM"); buf[sizeof(buf)-1]= 0; @@ -1299,7 +1326,7 @@ static void connect_start(void) { } int l= strlen(buf); assert(l>=1); - if (buf[-1]!='\n') + if (buf[l-1]!='\n') fatal("connect: response to MODE STREAM is too long: %.100s...", sanitise(buf)); l--; if (l>0 && buf[l-1]=='\r') l--; @@ -1334,7 +1361,8 @@ static void connect_start(void) { msg.msg_controllen= cmsg->cmsg_len; r= sendmsg(socks[1], &msg, 0); - if (r) sysdie("sendmsg failed for new connection"); + if (r<0) sysdie("sendmsg failed for new connection"); + if (r!=1) die("sendmsg for new connection gave wrong result %d",r); _exit(exitstatus); } @@ -1375,6 +1403,7 @@ static void check_assign_articles(void) { if (!inqueue) use->since_activity= 0; /* reset idle counter */ while (spare>0) { Article *art= LIST_REMHEAD(queue); + if (!art) break; LIST_ADDTAIL(use->waiting, art); spare--; } @@ -1499,12 +1528,23 @@ static void conn_make_some_xmits(Conn *conn) { ARTHANDLE *artdata= SMretrieve(art->token, RETR_ALL); + art->state= + art->state == art_Unchecked ? art_Unsolicited : + art->state == art_Wanted ? art_Wanted : + (abort(),-1); + + if (!artdata) art->missing= 1; + art->ipf->counts[art->state][ artdata ? RC_sent : RC_missing ]++; + if (conn->stream) { if (artdata) { XMIT_LITERAL("TAKETHIS "); xmit_noalloc(conn, art->messageid, art->midlen); XMIT_LITERAL("\r\n"); xmit_artbody(conn, artdata); + } else { + article_done(conn, art, -1); + continue; } } else { /* we got 235 from IHAVE */ @@ -1515,20 +1555,15 @@ static void conn_make_some_xmits(Conn *conn) { } } - art->state= - art->state == art_Unchecked ? art_Unsolicited : - art->state == art_Wanted ? art_Wanted : - (abort(),-1); - art->ipf->counts[art->state][RC_sent]++; LIST_ADDTAIL(conn->sent, art); } else { /* check it */ if (conn->stream) - XMIT_LITERAL("IHAVE "); - else XMIT_LITERAL("CHECK "); + else + XMIT_LITERAL("IHAVE "); xmit_noalloc(conn, art->messageid, art->midlen); XMIT_LITERAL("\r\n"); @@ -1630,7 +1665,8 @@ static void update_nocheck(int accepted) { } static void article_done(Conn *conn, Article *art, int whichcount) { - art->ipf->counts[art->state][whichcount]++; + if (!art->missing) art->ipf->counts[art->state][whichcount]++; + if (whichcount == RC_accepted) update_nocheck(1); else if (whichcount == RC_unwanted) update_nocheck(0); @@ -1702,7 +1738,7 @@ static void *peer_rd_ok(oop_source *lp, oop_read *oread, oop_rd_event ev, Article *art; #define GET_ARTICLE(musthavesent) \ - art= article_reply_check(conn, data, musthavesent, code_streaming, sani); \ + art= article_reply_check(conn, data, code_streaming, musthavesent, sani); \ if (art) ; else return OOP_CONTINUE /* reply_check has failed the conn */ #define ARTICLE_DEALTWITH(streaming,musthavesent,how) \ @@ -1776,7 +1812,7 @@ static void feedfile_eof(InputFile *ipf) { } static InputFile *open_input_file(const char *path) { - int fd= open(path, O_RDONLY); + int fd= open(path, O_RDWR); if (fd<0) { if (errno==ENOENT) return 0; sysfatal("unable to open input file %s", path);