LISTGROUP fully implemented.
authorArt Cancro <ajc@uncensored.citadel.org>
Wed, 5 Feb 2014 04:09:27 +0000 (23:09 -0500)
committerArt Cancro <ajc@uncensored.citadel.org>
Wed, 5 Feb 2014 04:09:27 +0000 (23:09 -0500)
citadel/modules/nntp/serv_nntp.c

index fe861374c88324b51502af74ef462f789dcd86b4..398e63dcc6ab14df66e837486a8142f65cee13a0 100644 (file)
@@ -551,8 +551,31 @@ void nntp_help(void) {
 }
 
 
+
+struct listgroup_range {
+       long lo;
+       long hi;
+};
+
+
+
+/*
+ * back end for the LISTGROUP command , called for each message number
+ */
+void nntp_listgroup_backend(long msgnum, void *userdata) {
+
+       struct listgroup_range *lr = (struct listgroup_range *)userdata;
+
+       // check range if supplied
+       if (msgnum < lr->lo) return;
+       if ((lr->hi != 0) && (msgnum > lr->hi)) return;
+
+       cprintf("%ld\r\n", msgnum);
+}
+
+
 /*
- * Implements the GROUP command
+ * Implements the GROUP and LISTGROUP commands
  */
 void nntp_group(const char *cmd) {
        /*
@@ -561,7 +584,11 @@ void nntp_group(const char *cmd) {
         */
        if (CtdlAccessCheck(ac_logged_in_or_guest)) return;
 
+       char verb[16];
        char requested_group[1024];
+       char message_range[256];
+       char range_lo[256];
+       char range_hi[256];
        char requested_room[ROOMNAMELEN];
        char augmented_roomname[ROOMNAMELEN];
        int c = 0;
@@ -570,11 +597,23 @@ void nntp_group(const char *cmd) {
        struct ctdlroom QRscratch;
        int msgs, new;
        long oldest,newest;
+       struct listgroup_range lr;
 
+       extract_token(verb, cmd, 0, ' ', sizeof verb);
        extract_token(requested_group, cmd, 1, ' ', sizeof requested_group);
-       newsgroup_to_room(requested_room, requested_group, sizeof requested_room);
+       extract_token(message_range, cmd, 2, ' ', sizeof message_range);
+       extract_token(range_lo, message_range, 0, '-', sizeof range_lo);
+       extract_token(range_hi, message_range, 1, '-', sizeof range_hi);
+       lr.lo = atoi(range_lo);
+       lr.hi = atoi(range_hi);
+
+       /* In LISTGROUP mode we can specify an empty name for 'currently selected' */
+       if ((!strcasecmp(verb, "LISTGROUP")) && (IsEmptyStr(requested_group))) {
+               room_to_newsgroup(requested_group, CC->room.QRname, sizeof requested_group);
+       }
 
        /* First try a regular match */
+       newsgroup_to_room(requested_room, requested_group, sizeof requested_room);
        c = CtdlGetRoom(&QRscratch, requested_room);
 
        /* Then try a mailbox name match */
@@ -611,6 +650,15 @@ void nntp_group(const char *cmd) {
        memcpy(&CC->room, &QRscratch, sizeof(struct ctdlroom));
        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 (!strcasecmp(verb, "GROUP")) {
+               return;
+       }
+
+       // If we get to this point we are running a LISTGROUP command.  Fetch those message numbers.
+       CtdlForEachMessage(MSGS_ALL, 0L, NULL, NULL, NULL, nntp_listgroup_backend, &lr);
+       cprintf(".\r\n");
 }
 
 
@@ -668,6 +716,10 @@ void nntp_command_loop(void)
                nntp_group(ChrPtr(Cmd));
        }
 
+       else if (!strcasecmp(cmdname, "listgroup")) {
+               nntp_group(ChrPtr(Cmd));
+       }
+
        else {
                cprintf("500 I'm afraid I can't do that.\r\n");
        }