-//
// NNTP server module (RFC 3977)
//
-// Copyright (c) 2014-2022 by the citadel.org team
-//
-// This program is open source software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License version 3.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
+// Copyright (c) 2014-2023 by the citadel.org team
//
+// This program is open source software. Use, duplication, or disclosure
+// are subject to the terms of the GNU General Public License version 3.
#include "../../sysdep.h"
#include <stdlib.h>
extern long timezone;
#endif
-//
// Tests whether the supplied string is a valid newsgroup name
// Returns true (nonzero) or false (0)
-//
int is_valid_newsgroup_name(char *name) {
char *ptr = name;
int has_a_letter = 0;
}
-//
// Convert a Citadel room name to a valid newsgroup name
-//
void room_to_newsgroup(char *target, char *source, size_t target_size) {
if (!target) return;
}
-//
// Convert a newsgroup name to a Citadel room name.
// This function recognizes names converted with room_to_newsgroup() and restores them with full fidelity.
-//
void newsgroup_to_room(char *target, char *source, size_t target_size) {
if (!target) return;
}
-//
// Here's where our NNTP session begins its happy day.
-//
void nntp_greeting(void) {
strcpy(CC->cs_clientname, "NNTP session");
CC->cs_flags |= CS_STEALTH;
}
-//
// NNTPS is just like NNTP, except it goes crypto right away.
-//
void nntps_greeting(void) {
CtdlModuleStartCryptoMsgs(NULL, NULL, NULL);
#ifdef HAVE_OPENSSL
- if (!CC->redirect_ssl) CC->kill_me = KILLME_NO_CRYPTO; /* kill session if no crypto */
+ if (!CC->redirect_ssl) CC->kill_me = KILLME_NO_CRYPTO; // kill session if no crypto
#endif
nntp_greeting();
}
-//
// implements the STARTTLS command
-//
void nntp_starttls(void) {
char ok_response[SIZ];
char nosup_response[SIZ];
}
-//
// Implements the CAPABILITY command
-//
void nntp_capabilities(void) {
cprintf("101 Capability list:\r\n");
cprintf("IMPLEMENTATION Citadel %d\r\n", REV_LEVEL);
}
-//
// Implements the QUIT command
-//
void nntp_quit(void) {
cprintf("221 Goodbye...\r\n");
CC->kill_me = KILLME_CLIENT_LOGGED_OUT;
}
-//
// Implements the AUTHINFO USER command (RFC 4643)
-//
void nntp_authinfo_user(const char *username) {
int a = CtdlLoginExistingUser(username);
switch (a) {
}
-//
// Implements the AUTHINFO PASS command (RFC 4643)
-//
void nntp_authinfo_pass(const char *buf) {
int a;
}
-//
// Implements the AUTHINFO extension (RFC 4643) in USER/PASS mode
-//
void nntp_authinfo(const char *cmd) {
if (!strncasecmp(cmd, "authinfo user ", 14)) {
}
-//
// Utility function to fetch the current list of message numbers in a room
-//
struct nntp_msglist nntp_fetch_msglist(struct ctdlroom *qrbuf) {
struct nntp_msglist nm;
struct cdbdata *cdbfr;
nm.num_msgs = cdbfr->len / sizeof(long);
cdbfr->len = 0;
cdb_free(cdbfr);
- } else {
+ }
+ else {
nm.num_msgs = 0;
nm.msgnums = NULL;
}
}
-//
// Output a room name (newsgroup name) in formats required for LIST and NEWGROUPS command
-//
void output_roomname_in_list_format(struct ctdlroom *qrbuf, int which_format, char *wildmat_pattern) {
char n_name[1024];
struct nntp_msglist nm;
}
-//
// Called once per room by nntp_newgroups() to qualify and possibly output a single room
-//
void nntp_newgroups_backend(struct ctdlroom *qrbuf, void *data) {
int ra;
int view;
CtdlRoomAccess(qrbuf, &CC->user, &ra, &view);
- /*
- * The "created after <date/time>" heuristics depend on the happy coincidence
- * that for a very long time we have used a unix timestamp as the room record's
- * generation number (QRgen). When this module is merged into the master
- * source tree we should rename QRgen to QR_create_time or something like that.
- */
-
+ // The "created after <date/time>" heuristics depend on the happy coincidence
+ // that for a very long time we have used a unix timestamp as the room record's
+ // generation number (QRgen). When this module is merged into the master
+ // source tree we should rename QRgen to QR_create_time or something like that.
if (ra & UA_KNOWN) {
if (qrbuf->QRgen >= thetime) {
output_roomname_in_list_format(qrbuf, NNTP_LIST_ACTIVE, NULL);
}
-//
// Implements the NEWGROUPS command
-//
void nntp_newgroups(const char *cmd) {
if (CtdlAccessCheck(ac_logged_in_or_guest)) return;
#endif
}
-
cprintf("231 list of new newsgroups follows\r\n");
CtdlGetUser(&CC->user, CC->curr_user);
CtdlForEachRoom(nntp_newgroups_backend, &thetime);
}
-//
// Called once per room by nntp_list() to qualify and possibly output a single room
-//
void nntp_list_backend(struct ctdlroom *qrbuf, void *data) {
int ra;
int view;
}
-//
// Implements the LIST commands
-//
void nntp_list(const char *cmd) {
if (CtdlAccessCheck(ac_logged_in_or_guest)) return;
}
-//
// Implement HELP command.
-//
void nntp_help(void) {
cprintf("100 This is the Citadel NNTP service.\r\n");
cprintf("RTFM http://www.ietf.org/rfc/rfc3977.txt\r\n");
}
-//
// Implement DATE command.
-//
void nntp_date(void) {
time_t now;
struct tm nowLocal;
}
-//
// 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;
}
-//
// Implements the GROUP and LISTGROUP commands
-//
void nntp_group(const char *cmd) {
if (CtdlAccessCheck(ac_logged_in_or_guest)) return;
lr.lo = atoi(range_lo);
lr.hi = atoi(range_hi);
- /* In LISTGROUP mode we can specify an empty name for 'currently selected' */
+ // 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 */
+ // 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 */
+ // 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 the room exists, check security/access */
+ // If the room exists, check security/access
if (c == 0) {
- /* See if there is an existing user/room relationship */
+ // See if there is an existing user/room relationship
CtdlRoomAccess(&QRscratch, &CC->user, &ra, NULL);
- /* normal clients have to pass through security */
+ // normal clients have to pass through security
if (ra & UA_KNOWN) {
ok = 1;
}
}
- /* Fail here if no such room */
+ // 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.
- */
+ // 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);
}
-//
// Implements the MODE command
-//
void nntp_mode(const char *cmd) {
char which_mode[16];
}
-//
// Implements the ARTICLE, HEAD, BODY, and STAT commands.
// (These commands all accept the same parameters; they differ only in how they output the retrieved message.)
-//
void nntp_article(const char *cmd) {
if (CtdlAccessCheck(ac_logged_in_or_guest)) return;
}
-//
// Utility function for nntp_last_next() that turns a msgnum into a message ID.
// The memory for the returned string is pwnz0red by the caller.
-//
char *message_id_from_msgnum(long msgnum) {
char *fetched_message_id = NULL;
CC->redirect_buffer = NewStrBufPlain(NULL, SIZ);
}
-//
// The LAST and NEXT commands are so similar that they are handled by a single function.
-//
void nntp_last_next(const char *cmd) {
if (CtdlAccessCheck(ac_logged_in_or_guest)) return;
}
-//
// back end for the XOVER command , called for each message number
-//
void nntp_xover_backend(long msgnum, void *userdata) {
struct listgroup_range *lr = (struct listgroup_range *)userdata;
}
-//
-//
// XOVER is used by some clients, even if we don't offer it
-//
void nntp_xover(const char *cmd) {
if (CtdlAccessCheck(ac_logged_in_or_guest)) return;
}
-//
// Main command loop for NNTP server sessions.
-//
void nntp_command_loop(void) {
StrBuf *Cmd = NewStrBuf();
char cmdname[16];
// ****************************************************************************
-//
-// This cleanup function blows away the temporary memory used by
-// the NNTP server.
-//
+// This cleanup function blows away the temporary memory used by the NNTP server.
void nntp_cleanup_function(void) {
- /* Don't do this stuff if this is not an NNTP session! */
+ // Don't do this stuff if this is not an NNTP session!
if (CC->h_command_function != nntp_command_loop) return;
syslog(LOG_DEBUG, "Performing NNTP cleanup hook\n");
CtdlRegisterSessionHook(nntp_cleanup_function, EVT_STOP, PRIO_STOP + 250);
}
- /* return our module name for the log */
+ // return our module name for the log
return "nntp";
}