]> code.citadel.org Git - citadel.git/blobdiff - citadel/modules/nntp/serv_nntp.c
current article number variable is now in place
[citadel.git] / citadel / modules / nntp / serv_nntp.c
index 6f6f41fa706f67317ea56006793bccf541860713..28edae8e642c9eb827c982e4866e364843c48c3a 100644 (file)
@@ -185,9 +185,9 @@ void nntp_greeting(void)
        strcpy(CC->cs_clientname, "NNTP session");
        CC->cs_flags |= CS_STEALTH;
 
-       /* CC->session_specific_data = malloc(sizeof(citnntp));
-       memset(NNTP, 0, sizeof(citnntp));
-       */
+       CC->session_specific_data = malloc(sizeof(citnntp));
+       citnntp *nntpstate = (citnntp *) CC->session_specific_data;
+       memset(nntpstate, 0, sizeof(citnntp));
 
        if (CC->nologin==1) {
                cprintf("451 Too many connections are already open; please try again later.\r\n");
@@ -586,6 +586,7 @@ void nntp_group(const char *cmd) {
        //
        if (CtdlAccessCheck(ac_logged_in_or_guest)) return;
 
+       citnntp *nntpstate = (citnntp *) CC->session_specific_data;
        char verb[16];
        char requested_group[1024];
        char message_range[256];
@@ -653,8 +654,9 @@ void nntp_group(const char *cmd) {
        CtdlUserGoto(NULL, 0, 0, &msgs, &new, &oldest, &newest);
        cprintf("211 %d %ld %ld %s\r\n", msgs, oldest, newest, requested_group);
 
-       // If this is a GROUP command, we can stop here.
+       // If this is a GROUP command, set the "current article number" to zero, and then stop here.
        if (!strcasecmp(verb, "GROUP")) {
+               nntpstate->current_article_number = 0;
                return;
        }
 
@@ -718,6 +720,12 @@ void nntp_article(const char *cmd) {
                return;
        }
 
+       // Which NNTP command was issued, determines whether we will fetch headers, body, or both.
+       int                     headers_only = HEADERS_ALL;
+       if (acmd == HEAD)       headers_only = HEADERS_FAST;
+       else if (acmd == BODY)  headers_only = HEADERS_NONE;
+       else if (acmd == STAT)  headers_only = HEADERS_FAST;
+
        // now figure out what the client is asking for.
        char requested_article[256];
        long requested_msgnum = 0;
@@ -747,15 +755,55 @@ void nntp_article(const char *cmd) {
        }
 
        // Anything else is noncompliant gobbledygook and should die in a car fire.
+       // Also, the weasel who is spreading untrue rumors about me at work should die in a slow and painful car fire.
        else {
                cprintf("500 syntax error\r\n");
                return;
        }
 
+       // At this point we know the message number of the "article" being requested.
+       // We have an awesome API call that does all the heavy lifting for us.
+       char *fetched_message_id = NULL;
+       CC->redirect_buffer = NewStrBufPlain(NULL, SIZ);
+       int fetch = CtdlOutputMsg(requested_msgnum,
+                       MT_RFC822,              // output in RFC822 format ... sort of
+                       headers_only,           // headers, body, or both?
+                       0,                      // don't do Citadel protocol responses
+                       1,                      // CRLF newlines
+                       NULL,                   // teh whole thing, not just a section
+                       0,                      // no flags yet ... maybe new ones for Path: etc ?
+                       NULL,
+                       NULL,
+                       &fetched_message_id     // extract the message ID from the message as we go...
+       );
+       StrBuf *msgtext = CC->redirect_buffer;
+       CC->redirect_buffer = NULL;
+
+       if (fetch != om_ok) {
+               cprintf("423 no article with that number\r\n");
+               FreeStrBuf(&msgtext);
+               return;
+       }
 
+       if (acmd == ARTICLE) {
+               cprintf("220 %ld <%s>\r\n", requested_msgnum, fetched_message_id);
+       }
+       if (acmd == HEAD) {
+               cprintf("221 %ld <%s>\r\n", requested_msgnum, fetched_message_id);
+       }
+       if (acmd == BODY) {
+               cprintf("222 %ld <%s>\r\n", requested_msgnum, fetched_message_id);
+       }
+       if (acmd == STAT) {
+               cprintf("223 %ld <%s>\r\n", requested_msgnum, fetched_message_id);
+               FreeStrBuf(&msgtext);
+               return;
+       }
 
-
-       cprintf("500 FIXME write the rest of cmd=%d msgnum=%ld\r\n", acmd, requested_msgnum);
+       client_write(SKEY(msgtext));
+       cprintf(".\r\n");                       // this protocol uses a dot terminator
+       FreeStrBuf(&msgtext);
+       if (fetched_message_id) free(fetched_message_id);
 }
 
 
@@ -851,6 +899,11 @@ void nntp_cleanup_function(void)
        if (CC->h_command_function != nntp_command_loop) return;
 
        syslog(LOG_DEBUG, "Performing NNTP cleanup hook\n");
+       citnntp *nntpstate = (citnntp *) CC->session_specific_data;
+       if (nntpstate != NULL) {
+               free(nntpstate);
+               nntpstate = NULL;
+       }
 }
 
 const char *CitadelServiceNNTP="NNTP";