Move user privileges functions to user_ops.c, room access check functions to room_ops.c
[citadel.git] / citadel / msgbase.c
index 73d6bfe199af3f8bce5cc17d615ea9d48ec1a80a..052f06fcaf78ef88d830e5530cc742f020aaacda 100644 (file)
@@ -268,6 +268,90 @@ void CM_GetAsField(struct CtdlMessage *Msg, eMsgField which, char **ret, long *r
        }
 }
 
+/*
+ * Returns 1 if the supplied pointer points to a valid Citadel message.
+ * If the pointer is NULL or the magic number check fails, returns 0.
+ */
+int CM_IsValidMsg(struct CtdlMessage *msg) {
+       if (msg == NULL)
+               return 0;
+       if ((msg->cm_magic) != CTDLMESSAGE_MAGIC) {
+               struct CitContext *CCC = CC;
+               MSGM_syslog(LOG_WARNING, "CM_IsValidMsg() -- self-check failed\n");
+               return 0;
+       }
+       return 1;
+}
+
+void CM_FreeContents(struct CtdlMessage *msg)
+{
+       int i;
+
+       for (i = 0; i < 256; ++i)
+               if (msg->cm_fields[i] != NULL) {
+                       free(msg->cm_fields[i]);
+               }
+
+       msg->cm_magic = 0;      /* just in case */
+}
+/*
+ * 'Destructor' for struct CtdlMessage
+ */
+void CM_Free(struct CtdlMessage *msg)
+{
+       if (CM_IsValidMsg(msg) == 0) 
+       {
+               if (msg != NULL) free (msg);
+               return;
+       }
+       CM_FreeContents(msg);
+       free(msg);
+}
+
+int CM_DupField(eMsgField i, struct CtdlMessage *OrgMsg, struct CtdlMessage *NewMsg)
+{
+       long len;
+       len = strlen(OrgMsg->cm_fields[i]);
+       NewMsg->cm_fields[i] = malloc(len + 1);
+       if (NewMsg->cm_fields[i] == NULL)
+               return 0;
+       memcpy(NewMsg->cm_fields[i], OrgMsg->cm_fields[i], len);
+       NewMsg->cm_fields[i][len] = '\0';
+       return 1;
+}
+
+struct CtdlMessage * CM_Duplicate(struct CtdlMessage *OrgMsg)
+{
+       int i;
+       struct CtdlMessage *NewMsg;
+
+       if (CM_IsValidMsg(OrgMsg) == 0) 
+               return NULL;
+       NewMsg = (struct CtdlMessage *)malloc(sizeof(struct CtdlMessage));
+       if (NewMsg == NULL)
+               return NULL;
+
+       memcpy(NewMsg, OrgMsg, sizeof(struct CtdlMessage));
+
+       memset(&NewMsg->cm_fields, 0, sizeof(char*) * 256);
+       
+       for (i = 0; i < 256; ++i)
+       {
+               if (OrgMsg->cm_fields[i] != NULL)
+               {
+                       if (!CM_DupField(i, OrgMsg, NewMsg))
+                       {
+                               CM_Free(NewMsg);
+                               return NULL;
+                       }
+               }
+       }
+
+       return NewMsg;
+}
+
+
+
 /*
  * This function is self explanatory.
  * (What can I say, I'm in a weird mood today...)
@@ -438,7 +522,7 @@ void headers_listing(long msgnum, void *userdata)
                (!CM_IsEmpty(msg, erFc822Addr) ? msg->cm_fields[erFc822Addr] : ""),
                (!CM_IsEmpty(msg, eMsgSubject) ? msg->cm_fields[eMsgSubject] : "")
        );
-       CtdlFreeMessage(msg);
+       CM_Free(msg);
 }
 
 /*
@@ -458,7 +542,7 @@ void headers_euid(long msgnum, void *userdata)
                msgnum, 
                (!CM_IsEmpty(msg, eExclusiveID) ? msg->cm_fields[eExclusiveID] : ""),
                (!CM_IsEmpty(msg, eTimestamp) ? msg->cm_fields[eTimestamp] : "0"));
-       CtdlFreeMessage(msg);
+       CM_Free(msg);
 }
 
 
@@ -858,7 +942,7 @@ int CtdlForEachMessage(int mode, long ref, char *search_string,
                                        if (CtdlMsgCmp(msg, compare)) {
                                                msglist[a] = 0L;
                                        }
-                                       CtdlFreeMessage(msg);
+                                       CM_Free(msg);
                                }
                        }
                }
@@ -1068,48 +1152,11 @@ void cmd_msgs(char *cmdbuf)
                           template,
                           CallBack,
                           NULL);
-       if (template != NULL) CtdlFreeMessage(template);
+       if (template != NULL) CM_Free(template);
        cprintf("000\n");
 }
 
 
-
-
-/* 
- * help_subst()  -  support routine for help file viewer
- */
-void help_subst(char *strbuf, char *source, char *dest)
-{
-       char workbuf[SIZ];
-       int p;
-
-       while (p = pattern2(strbuf, source), (p >= 0)) {
-               strcpy(workbuf, &strbuf[p + strlen(source)]);
-               strcpy(&strbuf[p], dest);
-               strcat(strbuf, workbuf);
-       }
-}
-
-
-void do_help_subst(char *buffer)
-{
-       char buf2[16];
-
-       help_subst(buffer, "^nodename", config.c_nodename);
-       help_subst(buffer, "^humannode", config.c_humannode);
-       help_subst(buffer, "^fqdn", config.c_fqdn);
-       help_subst(buffer, "^username", CC->user.fullname);
-       snprintf(buf2, sizeof buf2, "%ld", CC->user.usernum);
-       help_subst(buffer, "^usernum", buf2);
-       help_subst(buffer, "^sysadm", config.c_sysadm);
-       help_subst(buffer, "^variantname", CITADEL);
-       snprintf(buf2, sizeof buf2, "%d", config.c_maxsessions);
-       help_subst(buffer, "^maxsessions", buf2);
-       help_subst(buffer, "^bbsdir", ctdl_message_dir);
-}
-
-
-
 /*
  * memfmout()  -  Citadel text formatter and paginator.
  *          Although the original purpose of this routine was to format
@@ -1418,7 +1465,7 @@ struct CtdlMessage *CtdlFetchMessage(long msgnum, int with_body)
 
        /* Perform "before read" hooks (aborting if any return nonzero) */
        if (PerformMessageHooks(ret, EVT_BEFOREREAD) > 0) {
-               CtdlFreeMessage(ret);
+               CM_Free(ret);
                return NULL;
        }
 
@@ -1426,89 +1473,6 @@ struct CtdlMessage *CtdlFetchMessage(long msgnum, int with_body)
 }
 
 
-/*
- * Returns 1 if the supplied pointer points to a valid Citadel message.
- * If the pointer is NULL or the magic number check fails, returns 0.
- */
-int is_valid_message(struct CtdlMessage *msg) {
-       if (msg == NULL)
-               return 0;
-       if ((msg->cm_magic) != CTDLMESSAGE_MAGIC) {
-               struct CitContext *CCC = CC;
-               MSGM_syslog(LOG_WARNING, "is_valid_message() -- self-check failed\n");
-               return 0;
-       }
-       return 1;
-}
-
-void CtdlFreeMessageContents(struct CtdlMessage *msg)
-{
-       int i;
-
-       for (i = 0; i < 256; ++i)
-               if (msg->cm_fields[i] != NULL) {
-                       free(msg->cm_fields[i]);
-               }
-
-       msg->cm_magic = 0;      /* just in case */
-}
-/*
- * 'Destructor' for struct CtdlMessage
- */
-void CtdlFreeMessage(struct CtdlMessage *msg)
-{
-       if (is_valid_message(msg) == 0) 
-       {
-               if (msg != NULL) free (msg);
-               return;
-       }
-       CtdlFreeMessageContents(msg);
-       free(msg);
-}
-
-int DupCMField(eMsgField i, struct CtdlMessage *OrgMsg, struct CtdlMessage *NewMsg)
-{
-       long len;
-       len = strlen(OrgMsg->cm_fields[i]);
-       NewMsg->cm_fields[i] = malloc(len + 1);
-       if (NewMsg->cm_fields[i] == NULL)
-               return 0;
-       memcpy(NewMsg->cm_fields[i], OrgMsg->cm_fields[i], len);
-       NewMsg->cm_fields[i][len] = '\0';
-       return 1;
-}
-
-struct CtdlMessage * CtdlDuplicateMessage(struct CtdlMessage *OrgMsg)
-{
-       int i;
-       struct CtdlMessage *NewMsg;
-
-       if (is_valid_message(OrgMsg) == 0) 
-               return NULL;
-       NewMsg = (struct CtdlMessage *)malloc(sizeof(struct CtdlMessage));
-       if (NewMsg == NULL)
-               return NULL;
-
-       memcpy(NewMsg, OrgMsg, sizeof(struct CtdlMessage));
-
-       memset(&NewMsg->cm_fields, 0, sizeof(char*) * 256);
-       
-       for (i = 0; i < 256; ++i)
-       {
-               if (OrgMsg->cm_fields[i] != NULL)
-               {
-                       if (!DupCMField(i, OrgMsg, NewMsg))
-                       {
-                               CtdlFreeMessage(NewMsg);
-                               return NULL;
-                       }
-               }
-       }
-
-       return NewMsg;
-}
-
-
 
 /*
  * Pre callback function for multipart/alternative
@@ -1831,20 +1795,6 @@ int check_cached_msglist(long msgnum) {
 }
 
 
-/* 
- * 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))
-               && (!config.c_guest_logins)
-       ) {
-               return(om_not_logged_in);
-       }
-       return(om_ok);
-}
-
 
 /*
  * Get a message off disk.  (returns om_* values found in msgbase.h)
@@ -1947,7 +1897,7 @@ int CtdlOutputMsg(long msg_num,           /* message number (local) to fetch */
                        *Address = TheMessage->cm_fields[erFc822Addr];
                        TheMessage->cm_fields[erFc822Addr] = NULL;
                }
-               CtdlFreeMessage(TheMessage);
+               CM_Free(TheMessage);
                TheMessage = NULL;
 
                if (encap.msg) {
@@ -1987,7 +1937,7 @@ int CtdlOutputMsg(long msg_num,           /* message number (local) to fetch */
                TheMessage->cm_fields[erFc822Addr] = NULL;
        }
 
-       CtdlFreeMessage(TheMessage);
+       CM_Free(TheMessage);
 
        return(retcode);
 }
@@ -2522,7 +2472,7 @@ int CtdlOutputPreLoadedMsg(
        strcpy(mid, "unknown");
        nl = (crlf ? "\r\n" : "\n");
 
-       if (!is_valid_message(TheMessage)) {
+       if (!CM_IsValidMsg(TheMessage)) {
                MSGM_syslog(LOG_ERR,
                            "ERROR: invalid preloaded message for output\n");
                cit_backtrace ();
@@ -2812,7 +2762,7 @@ void cmd_msg3(char *cmdbuf)
        }
 
        serialize_message(&smr, msg);
-       CtdlFreeMessage(msg);
+       CM_Free(msg);
 
        if (smr.len == 0) {
                cprintf("%d Unable to serialize message\n",
@@ -3026,7 +2976,7 @@ int CtdlSaveMsgPointersInRoom(char *roomname, long newmsgidlist[], int num_newms
 
                                /* Free up the memory we may have allocated */
                                if (msg != supplied_msg) {
-                                       CtdlFreeMessage(msg);
+                                       CM_Free(msg);
                                }
                        }
        
@@ -3172,7 +3122,7 @@ void serialize_message(struct ser_ret *ret,               /* return values */
        /*
         * Check for valid message format
         */
-       if (is_valid_message(msg) == 0) {
+       if (CM_IsValidMsg(msg) == 0) {
                MSGM_syslog(LOG_ERR, "serialize_message() aborting due to invalid message\n");
                ret->len = 0;
                ret->ser = NULL;
@@ -3289,7 +3239,7 @@ long CtdlSubmitMsg(struct CtdlMessage *msg,       /* message to save */
        int rv = 0;
 
        MSGM_syslog(LOG_DEBUG, "CtdlSubmitMsg() called\n");
-       if (is_valid_message(msg) == 0) return(-1);     /* self check */
+       if (CM_IsValidMsg(msg) == 0) return(-1);        /* self check */
 
        /* If this message has no timestamp, we take the liberty of
         * giving it one, right now.
@@ -3528,7 +3478,7 @@ long CtdlSubmitMsg(struct CtdlMessage *msg,       /* message to save */
                                        CM_SetAsField(imsg, eMesageText, &instr, instrlen);
                                        CM_SetField(imsg, eExtnotify, recipient, recipientlen);
                                        CtdlSubmitMsg(imsg, NULL, FNBL_QUEUE_ROOM, 0);
-                                       CtdlFreeMessage(imsg);
+                                       CM_Free(imsg);
                                }
                        }
                        else {
@@ -3646,7 +3596,7 @@ long CtdlSubmitMsg(struct CtdlMessage *msg,       /* message to save */
                imsg->cm_fields[eJournal] = strdup("do not journal");
                imsg->cm_fields[eMesageText] = SmashStrBuf(&SpoolMsg);  /* imsg owns this memory now */
                CtdlSubmitMsg(imsg, NULL, SMTP_SPOOLOUT_ROOM, QP_EADDR);
-               CtdlFreeMessage(imsg);
+               CM_Free(imsg);
        }
 
        /*
@@ -3752,7 +3702,7 @@ void quickie_message(const char *from,
        msg->cm_fields[eMesageText] = strdup(text);
 
        CtdlSubmitMsg(msg, recp, room, 0);
-       CtdlFreeMessage(msg);
+       CM_Free(msg);
        if (recp != NULL) free_recipients(recp);
 }
 
@@ -4089,7 +4039,7 @@ char *CtdlReadMessageBody(char *terminator,       /* token signalling EOT */
  * (NOTE: if you supply 'preformatted_text', the buffer you give it
  * will become part of the message.  This means you are no longer
  * responsible for managing that memory -- it will be freed along with
- * the rest of the fields when CtdlFreeMessage() is called.)
+ * the rest of the fields when CM_Free() is called.)
  */
 
 struct CtdlMessage *CtdlMakeMessage(
@@ -4218,102 +4168,6 @@ struct CtdlMessage *CtdlMakeMessage(
        return(msg);
 }
 
-/*
- * Check to see whether we have permission to post a message in the current
- * 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 is_reply
-       ) {
-       int ra;
-
-       if (!(CC->logged_in) && 
-           (PostPublic == POST_LOGGED_IN)) {
-               snprintf(errmsgbuf, n, "Not logged in.");
-               return (ERROR + NOT_LOGGED_IN);
-       }
-       else if (PostPublic == CHECK_EXISTANCE) {
-               return (0); // We're Evaling whether a recipient exists
-       }
-       else if (!(CC->logged_in)) {
-               
-               if ((CC->room.QRflags & QR_READONLY)) {
-                       snprintf(errmsgbuf, n, "Not logged in.");
-                       return (ERROR + NOT_LOGGED_IN);
-               }
-               if (CC->room.QRflags2 & QR2_MODERATED) {
-                       snprintf(errmsgbuf, n, "Not logged in Moderation feature not yet implemented!");
-                       return (ERROR + NOT_LOGGED_IN);
-               }
-               if ((PostPublic!=POST_LMTP) &&(CC->room.QRflags2 & QR2_SMTP_PUBLIC) == 0) {
-
-                       return CtdlNetconfigCheckRoomaccess(errmsgbuf, n, RemoteIdentifier);
-               }
-               return (0);
-
-       }
-
-       if ((CC->user.axlevel < AxProbU)
-           && ((CC->room.QRflags & QR_MAILBOX) == 0)) {
-               snprintf(errmsgbuf, n, "Need to be validated to enter (except in %s> to sysop)", MAILROOM);
-               return (ERROR + HIGHER_ACCESS_REQUIRED);
-       }
-
-       CtdlRoomAccess(&CC->room, &CC->user, &ra, NULL);
-
-       if (ra & UA_POSTALLOWED) {
-               strcpy(errmsgbuf, "OK to post or reply here");
-               return(0);
-       }
-
-       if ( (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.
-                */
-               strcpy(errmsgbuf, "OK to reply here");
-               return(0);
-       }
-
-       if ( (ra & UA_REPLYALLOWED) && (!is_reply) ) {
-               /* Clarify what happened with a better error message */
-               snprintf(errmsgbuf, n, "You may only reply to existing messages here.");
-               return (ERROR + HIGHER_ACCESS_REQUIRED);
-       }
-
-       snprintf(errmsgbuf, n, "Higher access is required to post in this room.");
-       return (ERROR + HIGHER_ACCESS_REQUIRED);
-
-}
-
-
-/*
- * Check to see if the specified user has Internet mail permission
- * (returns nonzero if permission is granted)
- */
-int CtdlCheckInternetMailPermission(struct ctdluser *who) {
-
-       /* Do not allow twits to send Internet mail */
-       if (who->axlevel <= AxProbU) return(0);
-
-       /* Globally enabled? */
-       if (config.c_restrict == 0) return(1);
-
-       /* User flagged ok? */
-       if (who->flags & US_INTERNET) return(2);
-
-       /* Admin level access? */
-       if (who->axlevel >= AxAideU) return(3);
-
-       /* No mail for you! */
-       return(0);
-}
 
 
 /*
@@ -4925,7 +4779,7 @@ void cmd_ent0(char *entargs)
                        cprintf("000\n");
                }
 
-               CtdlFreeMessage(msg);
+               CM_Free(msg);
        }
        if (valid != NULL) {
                free_recipients(valid);
@@ -5082,22 +4936,6 @@ int CtdlDeleteMessages(char *room_name,          /* which room */
        return (num_deleted);
 }
 
-
-
-/*
- * Check whether the current user has permission to delete messages from
- * the current room (returns 1 for yes, 0 for no)
- */
-int CtdlDoIHavePermissionToDeleteMessagesFromThisRoom(void) {
-       int ra;
-       CtdlRoomAccess(&CC->room, &CC->user, &ra, NULL);
-       if (ra & UA_DELETEALLOWED) return(1);
-       return(0);
-}
-
-
-
-
 /*
  * Delete message from current room
  */
@@ -5610,7 +5448,7 @@ void CtdlWriteObject(char *req_room,                      /* Room to stuff it in */
        }
        /* Now write the data */
        CtdlSubmitMsg(msg, NULL, roomname, 0);
-       CtdlFreeMessage(msg);
+       CM_Free(msg);
 }
 
 
@@ -5652,7 +5490,7 @@ char *CtdlGetSysConfig(char *sysconfname) {
                msg = CtdlFetchMessage(msgnum, 1);
                if (msg != NULL) {
                        conf = strdup(msg->cm_fields[eMesageText]);
-                       CtdlFreeMessage(msg);
+                       CM_Free(msg);
                }
                else {
                        conf = NULL;