/* * cmd_goto() - goto a new room */ void cmd_goto(char *gargs) { struct ctdlroom QRscratch; int c; int ok = 0; int ra; char augmented_roomname[ROOMNAMELEN]; char towhere[ROOMNAMELEN]; char password[32]; int transiently = 0; if (CtdlAccessCheck(ac_logged_in_or_guest)) return; extract_token(towhere, gargs, 0, '|', sizeof towhere); extract_token(password, gargs, 1, '|', sizeof password); transiently = extract_int(gargs, 2); CtdlGetUser(&CC->user, CC->curr_user); /* * Handle some of the macro named rooms */ convert_room_name_macros(towhere, sizeof towhere); /* First try a regular match */ c = CtdlGetRoom(&QRscratch, towhere); /* Then try a mailbox name match */ if (c != 0) { CtdlMailboxName(augmented_roomname, sizeof augmented_roomname, &CC->user, towhere); c = CtdlGetRoom(&QRscratch, augmented_roomname); if (c == 0) safestrncpy(towhere, augmented_roomname, sizeof towhere); } /* And if the room was found... */ if (c == 0) { /* Let internal programs go directly to any room. */ if (CC->internal_pgm) { memcpy(&CC->room, &QRscratch, sizeof(struct ctdlroom)); CtdlUserGoto(NULL, 1, transiently, NULL, NULL, NULL, NULL); return; } /* See if there is an existing user/room relationship */ CtdlRoomAccess(&QRscratch, &CC->user, &ra, NULL); /* normal clients have to pass through security */ if (ra & UA_GOTOALLOWED) { ok = 1; } if (ok == 1) { if ((QRscratch.QRflags & QR_MAILBOX) && ((ra & UA_GOTOALLOWED))) { memcpy(&CC->room, &QRscratch, sizeof(struct ctdlroom)); CtdlUserGoto(NULL, 1, transiently, NULL, NULL, NULL, NULL); return; } else if ((QRscratch.QRflags & QR_PASSWORDED) && ((ra & UA_KNOWN) == 0) && (strcasecmp(QRscratch.QRpasswd, password)) && (CC->user.axlevel < AxAideU) ) { cprintf("%d wrong or missing passwd\n", ERROR + PASSWORD_REQUIRED); return; } else if ((QRscratch.QRflags & QR_PRIVATE) && ((QRscratch.QRflags & QR_PASSWORDED) == 0) && ((QRscratch.QRflags & QR_GUESSNAME) == 0) && ((ra & UA_KNOWN) == 0) && (CC->user.axlevel < AxAideU) ) { syslog(LOG_DEBUG, "Failed to acquire private room\n"); } else { memcpy(&CC->room, &QRscratch, sizeof(struct ctdlroom)); CtdlUserGoto(NULL, 1, transiently, NULL, NULL, NULL, NULL); return; } } } cprintf("%d room '%s' not found\n", ERROR + ROOM_NOT_FOUND, towhere); }
// // Implements the GROUP and LISTGROUP commands // 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]; char range_lo[256]; char range_hi[256]; char requested_room[ROOMNAMELEN]; char augmented_roomname[ROOMNAMELEN]; int c = 0; int ok = 0; int ra = 0; 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); 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 */ if (c != 0) { CtdlMailboxName(augmented_roomname, sizeof augmented_roomname, &CC->user, requested_room); c = CtdlGetRoom(&QRscratch, augmented_roomname); if (c == 0) { safestrncpy(requested_room, augmented_roomname, sizeof(requested_room)); } } /* If the room exists, check security/access */ if (c == 0) { /* See if there is an existing user/room relationship */ CtdlRoomAccess(&QRscratch, &CC->user, &ra, NULL); /* normal clients have to pass through security */ if (ra & UA_KNOWN) { ok = 1; } } /* Fail here if no such room */ if (!ok) { cprintf("411 no such newsgroup\r\n"); return; } /* * CtdlUserGoto() formally takes us to the desired room, happily returning * the number of messages and number of new messages. */ 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, set the "current article number" to zero, and then stop here. if (!strcasecmp(verb, "GROUP")) { nntpstate->current_article_number = oldest; 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"); }