/*
- * $Id$
- *
* Implements the message store.
*
* Copyright (c) 1987-2010 by the citadel.org team
* Retrieve the "seen" message list for the current room.
*/
void CtdlGetSeen(char *buf, int which_set) {
- struct visit vbuf;
+ visit vbuf;
/* Learn about the user and room in question */
CtdlGetRelationship(&vbuf, &CC->user, &CC->room);
int was_seen = 0;
long lo = (-1L);
long hi = (-1L);
- struct visit vbuf;
+ visit vbuf;
long *msglist;
int num_msgs = 0;
StrBuf *vset;
{
int a, i, j;
- struct visit vbuf;
+ visit vbuf;
struct cdbdata *cdbfr;
long *msglist = NULL;
int num_msgs = 0;
char search_string[1024];
ForEachMsgCallback CallBack;
+ if (CtdlAccessCheck(ac_logged_in_or_guest)) return;
+
extract_token(which, cmdbuf, 0, '|', sizeof which);
cm_ref = extract_int(cmdbuf, 1);
extract_token(search_string, cmdbuf, 1, '|', sizeof search_string);
else
mode = MSGS_ALL;
- if ((!(CC->logged_in)) && (!(CC->internal_pgm))) {
- cprintf("%d not logged in\n", ERROR + NOT_LOGGED_IN);
- return;
- }
-
if ( (mode == MSGS_SEARCH) && (!config.c_enable_fulltext) ) {
cprintf("%d Full text index is not enabled on this server.\n",
ERROR + CMD_NOT_SUPPORTED);
const char *nl /* string to terminate lines with */
) {
int column = 0;
- char ch = 0;
+ unsigned char ch = 0;
char outbuf[1024];
int len = 0;
int nllen = 0;
if (!mptr) return;
nllen = strlen(nl);
- while (ch=*(mptr++), ch > 0) {
+ while (ch=*(mptr++), ch != 0) {
if (ch == '\n') {
client_write(outbuf, len);
}
}
+#ifdef MESSAGE_IN_ROOM
+/*
+ * Check if a message is in the current room.
+ * This is used by CtdlFetchMessage to prevent random picking
+ * of messages from users private rooms
+ *
+ * The message list should probably be cached against the CC->room
+ */
+int CtdlMessageInRoom(long msgnum)
+{
+ visit vbuf;
+ struct cdbdata *cdbfr;
+
+ /* Learn about the user and room in question */
+ CtdlGetUser(&CC->user, CC->curr_user);
+ CtdlGetRelationship(&vbuf, &CC->user, &CC->room);
+ /* Load the message list */
+ cdbfr = cdb_fetch(CDB_MSGLISTS, &CC->room.QRnumber, sizeof(long));
+ if (cdbfr != NULL) {
+ long *msglist = NULL;
+ int num_msgs = 0;
+ int i;
+ int r = 0;
+
+ msglist = (long *) cdbfr->ptr;
+ num_msgs = cdbfr->len / sizeof(long);
+
+ /* search for message msgnum */
+ for (i=0; i<num_msgs; i++) {
+ if (msglist[i] == msgnum) {
+ r = 1;
+ break;
+ }
+ }
+
+ cdb_free(cdbfr);
+ return r;
+ } else {
+ return 0;
+ }
+}
+#endif
/*
* Load a message from disk into memory.
CtdlLogPrintf(CTDL_DEBUG, "CtdlFetchMessage(%ld, %d)\n", msgnum, with_body);
+#ifdef MESSAGE_IN_ROOM
+ if (!CtdlMessageInRoom(msgnum)) {
+ CtdlLogPrintf(CTDL_DEBUG, "Message %ld not in current room\n", msgnum);
+ return NULL;
+ }
+#endif
+
dmsgtext = cdb_fetch(CDB_MSGMAIN, &msgnum, sizeof(long));
if (dmsgtext == NULL) {
return NULL;
memcpy(encap->msg, content, length);
return;
}
-
}
-
-
-
-
+/*
+ * Determine whether the currently logged in session has permission to read
+ * messages in the current room.
+ */
int CtdlDoIHavePermissionToReadMessagesInThisRoom(void) {
- if ((!(CC->logged_in)) && (!(CC->internal_pgm))) {
+ if ( (!(CC->logged_in))
+ && (!(CC->internal_pgm))
+ && (!config.c_guest_logins)
+ ) {
return(om_not_logged_in);
}
return(om_ok);
return(r);
}
- /* FIXME: check message id against msglist for this room */
+#ifdef MESSAGE_IN_ROOM
+ if (!CtdlMessageInRoom(msg_num)) {
+ CtdlLogPrintf(CTDL_DEBUG, "Message %ld not in current room\n", msg_num);
+ if (do_proto) cprintf("%d Can't locate msg %ld in room\n",
+ ERROR + MESSAGE_NOT_FOUND, msg_num);
+ return(om_no_such_msg);
+ }
+#endif
/*
* Fetch the message from disk. If we're in HEADERS_FAST mode,
struct addresses_to_be_filed *aptr = NULL;
StrBuf *saved_rfc822_version = NULL;
int qualified_for_journaling = 0;
- CitContext *CCC = CC; /* CachedCitContext - performance boost */
+ CitContext *CCC = MyContext();
char bounce_to[1024] = "";
size_t tmp = 0;
int rv = 0;
* room. Returns a *CITADEL ERROR CODE* and puts a message in errmsgbuf, or
* returns 0 on success.
*/
-int CtdlDoIHavePermissionToPostInThisRoom(char *errmsgbuf,
- size_t n,
- const char* RemoteIdentifier,
- int PostPublic) {
+int CtdlDoIHavePermissionToPostInThisRoom(
+ char *errmsgbuf,
+ size_t n,
+ const char* RemoteIdentifier,
+ int PostPublic,
+ int is_reply
+) {
int ra;
if (!(CC->logged_in) &&
}
CtdlRoomAccess(&CC->room, &CC->user, &ra, NULL);
- if (!(ra & UA_POSTALLOWED)) {
+
+ if ( (!(ra & UA_POSTALLOWED)) && (ra & UA_REPLYALLOWED) && (!is_reply) ) {
+ /*
+ * To be thorough, we ought to check to see if the message they are
+ * replying to is actually a valid one in this room, but unless this
+ * actually becomes a problem we'll go with high performance instead.
+ */
+ snprintf(errmsgbuf, n, "You may only reply to existing messages here.");
+ return (ERROR + HIGHER_ACCESS_REQUIRED);
+ }
+
+ else if (!(ra & UA_POSTALLOWED)) {
snprintf(errmsgbuf, n, "Higher access is required to post in this room.");
return (ERROR + HIGHER_ACCESS_REQUIRED);
}
CC->room = tempQR;
/* Check permissions to send mail to this room */
- err = CtdlDoIHavePermissionToPostInThisRoom(errmsg,
- sizeof errmsg,
- RemoteIdentifier,
- Flags
+ err = CtdlDoIHavePermissionToPostInThisRoom(
+ errmsg,
+ sizeof errmsg,
+ RemoteIdentifier,
+ Flags,
+ 0 /* 0 = not a reply */
);
if (err)
{
/* first check to make sure the request is valid. */
- err = CtdlDoIHavePermissionToPostInThisRoom(errmsg, sizeof errmsg, NULL, POST_LOGGED_IN);
+ err = CtdlDoIHavePermissionToPostInThisRoom(
+ errmsg,
+ sizeof errmsg,
+ NULL,
+ POST_LOGGED_IN,
+ (!IsEmptyStr(references)) /* is this a reply? or a top-level post? */
+ );
if (err)
{
cprintf("%d %s\n", err, errmsg);
/* In mailbox rooms we have to behave a little differently --
* make sure the user has specified at least one recipient. Then
* validate the recipient(s). We do this for the Mail> room, as
- * well as any room which has the "Mailbox" view set.
+ * well as any room which has the "Mailbox" view set - unless it
+ * is the DRAFTS room which does not require recipients
*/
- if ( ( (CC->room.QRflags & QR_MAILBOX) && (!strcasecmp(&CC->room.QRname[11], MAILROOM)) )
- || ( (CC->room.QRflags & QR_MAILBOX) && (CC->curr_view == VIEW_MAILBOX) )
- ) {
+ if ( ( ( (CC->room.QRflags & QR_MAILBOX) && (!strcasecmp(&CC->room.QRname[11], MAILROOM)) )
+ || ( (CC->room.QRflags & QR_MAILBOX) && (CC->curr_view == VIEW_MAILBOX) )
+ ) && (strcasecmp(&CC->room.QRname[11], USERDRAFTROOM)) !=0 ) {
if (CC->user.axlevel < AxProbU) {
strcpy(recp, "sysop");
strcpy(cc, "");
}
/* return our Subversion id for the Log */
- return "$Id$";
+ return "msgbase";
}