* 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) {
+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, "is_valid_message() -- self-check failed\n");
+ MSGM_syslog(LOG_WARNING, "CM_IsValidMsg() -- self-check failed\n");
return 0;
}
return 1;
}
-void CtdlFreeMessageContents(struct CtdlMessage *msg)
+void CM_FreeContents(struct CtdlMessage *msg)
{
int i;
/*
* 'Destructor' for struct CtdlMessage
*/
-void CtdlFreeMessage(struct CtdlMessage *msg)
+void CM_Free(struct CtdlMessage *msg)
{
- if (is_valid_message(msg) == 0)
+ if (CM_IsValidMsg(msg) == 0)
{
if (msg != NULL) free (msg);
return;
}
- CtdlFreeMessageContents(msg);
+ CM_FreeContents(msg);
free(msg);
}
-int DupCMField(eMsgField i, struct CtdlMessage *OrgMsg, struct CtdlMessage *NewMsg)
+int CM_DupField(eMsgField i, struct CtdlMessage *OrgMsg, struct CtdlMessage *NewMsg)
{
long len;
len = strlen(OrgMsg->cm_fields[i]);
return 1;
}
-struct CtdlMessage * CtdlDuplicateMessage(struct CtdlMessage *OrgMsg)
+struct CtdlMessage * CM_Duplicate(struct CtdlMessage *OrgMsg)
{
int i;
struct CtdlMessage *NewMsg;
- if (is_valid_message(OrgMsg) == 0)
+ if (CM_IsValidMsg(OrgMsg) == 0)
return NULL;
NewMsg = (struct CtdlMessage *)malloc(sizeof(struct CtdlMessage));
if (NewMsg == NULL)
{
if (OrgMsg->cm_fields[i] != NULL)
{
- if (!DupCMField(i, OrgMsg, NewMsg))
+ if (!CM_DupField(i, OrgMsg, NewMsg))
{
- CtdlFreeMessage(NewMsg);
+ CM_Free(NewMsg);
return NULL;
}
}
-/*
- * This function is self explanatory.
- * (What can I say, I'm in a weird mood today...)
- */
-void remove_any_whitespace_to_the_left_or_right_of_at_symbol(char *name)
-{
- int i;
-
- for (i = 0; i < strlen(name); ++i) {
- if (name[i] == '@') {
- while (isspace(name[i - 1]) && i > 0) {
- strcpy(&name[i - 1], &name[i]);
- --i;
- }
- while (isspace(name[i + 1])) {
- strcpy(&name[i + 1], &name[i + 2]);
- }
- }
- }
-}
-
-
-/*
- * Aliasing for network mail.
- * (Error messages have been commented out, because this is a server.)
- */
-int alias(char *name)
-{ /* process alias and routing info for mail */
- struct CitContext *CCC = CC;
- FILE *fp;
- int a, i;
- char aaa[SIZ], bbb[SIZ];
- char *ignetcfg = NULL;
- char *ignetmap = NULL;
- int at = 0;
- char node[64];
- char testnode[64];
- char buf[SIZ];
-
- char original_name[256];
- safestrncpy(original_name, name, sizeof original_name);
-
- striplt(name);
- remove_any_whitespace_to_the_left_or_right_of_at_symbol(name);
- stripallbut(name, '<', '>');
-
- fp = fopen(file_mail_aliases, "r");
- if (fp == NULL) {
- fp = fopen("/dev/null", "r");
- }
- if (fp == NULL) {
- return (MES_ERROR);
- }
- strcpy(aaa, "");
- strcpy(bbb, "");
- while (fgets(aaa, sizeof aaa, fp) != NULL) {
- while (isspace(name[0]))
- strcpy(name, &name[1]);
- aaa[strlen(aaa) - 1] = 0;
- strcpy(bbb, "");
- for (a = 0; a < strlen(aaa); ++a) {
- if (aaa[a] == ',') {
- strcpy(bbb, &aaa[a + 1]);
- aaa[a] = 0;
- }
- }
- if (!strcasecmp(name, aaa))
- strcpy(name, bbb);
- }
- fclose(fp);
-
- /* Hit the Global Address Book */
- if (CtdlDirectoryLookup(aaa, name, sizeof aaa) == 0) {
- strcpy(name, aaa);
- }
-
- if (strcasecmp(original_name, name)) {
- MSG_syslog(LOG_INFO, "%s is being forwarded to %s\n", original_name, name);
- }
-
- /* Change "user @ xxx" to "user" if xxx is an alias for this host */
- for (a=0; a<strlen(name); ++a) {
- if (name[a] == '@') {
- if (CtdlHostAlias(&name[a+1]) == hostalias_localhost) {
- name[a] = 0;
- MSG_syslog(LOG_INFO, "Changed to <%s>\n", name);
- }
- }
- }
-
- /* determine local or remote type, see citadel.h */
- at = haschar(name, '@');
- if (at == 0) return(MES_LOCAL); /* no @'s - local address */
- if (at > 1) return(MES_ERROR); /* >1 @'s - invalid address */
- remove_any_whitespace_to_the_left_or_right_of_at_symbol(name);
-
- /* figure out the delivery mode */
- extract_token(node, name, 1, '@', sizeof node);
-
- /* If there are one or more dots in the nodename, we assume that it
- * is an FQDN and will attempt SMTP delivery to the Internet.
- */
- if (haschar(node, '.') > 0) {
- return(MES_INTERNET);
- }
-
- /* Otherwise we look in the IGnet maps for a valid Citadel node.
- * Try directly-connected nodes first...
- */
- ignetcfg = CtdlGetSysConfig(IGNETCFG);
- for (i=0; i<num_tokens(ignetcfg, '\n'); ++i) {
- extract_token(buf, ignetcfg, i, '\n', sizeof buf);
- extract_token(testnode, buf, 0, '|', sizeof testnode);
- if (!strcasecmp(node, testnode)) {
- free(ignetcfg);
- return(MES_IGNET);
- }
- }
- free(ignetcfg);
-
- /*
- * Then try nodes that are two or more hops away.
- */
- ignetmap = CtdlGetSysConfig(IGNETMAP);
- for (i=0; i<num_tokens(ignetmap, '\n'); ++i) {
- extract_token(buf, ignetmap, i, '\n', sizeof buf);
- extract_token(testnode, buf, 0, '|', sizeof testnode);
- if (!strcasecmp(node, testnode)) {
- free(ignetmap);
- return(MES_IGNET);
- }
- }
- free(ignetmap);
-
- /* If we get to this point it's an invalid node name */
- return (MES_ERROR);
-}
-
-
/*
* Back end for the MSGS command: output message number only.
*/
(!CM_IsEmpty(msg, erFc822Addr) ? msg->cm_fields[erFc822Addr] : ""),
(!CM_IsEmpty(msg, eMsgSubject) ? msg->cm_fields[eMsgSubject] : "")
);
- CtdlFreeMessage(msg);
+ CM_Free(msg);
}
/*
msgnum,
(!CM_IsEmpty(msg, eExclusiveID) ? msg->cm_fields[eExclusiveID] : ""),
(!CM_IsEmpty(msg, eTimestamp) ? msg->cm_fields[eTimestamp] : "0"));
- CtdlFreeMessage(msg);
+ CM_Free(msg);
}
if (CtdlMsgCmp(msg, compare)) {
msglist[a] = 0L;
}
- CtdlFreeMessage(msg);
+ CM_Free(msg);
}
}
}
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
/* Perform "before read" hooks (aborting if any return nonzero) */
if (PerformMessageHooks(ret, EVT_BEFOREREAD) > 0) {
- CtdlFreeMessage(ret);
+ CM_Free(ret);
return NULL;
}
}
-/*
- * 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)
*Address = TheMessage->cm_fields[erFc822Addr];
TheMessage->cm_fields[erFc822Addr] = NULL;
}
- CtdlFreeMessage(TheMessage);
+ CM_Free(TheMessage);
TheMessage = NULL;
if (encap.msg) {
TheMessage->cm_fields[erFc822Addr] = NULL;
}
- CtdlFreeMessage(TheMessage);
+ CM_Free(TheMessage);
return(retcode);
}
-char *qp_encode_email_addrs(char *source)
-{
- struct CitContext *CCC = CC;
- char *user, *node, *name;
- const char headerStr[] = "=?UTF-8?Q?";
- char *Encoded;
- char *EncodedName;
- char *nPtr;
- int need_to_encode = 0;
- long SourceLen;
- long EncodedMaxLen;
- long nColons = 0;
- long *AddrPtr;
- long *AddrUtf8;
- long nAddrPtrMax = 50;
- long nmax;
- int InQuotes = 0;
- int i, n;
-
- if (source == NULL) return source;
- if (IsEmptyStr(source)) return source;
- if (MessageDebugEnabled != 0) cit_backtrace();
- MSG_syslog(LOG_DEBUG, "qp_encode_email_addrs: [%s]\n", source);
-
- AddrPtr = malloc (sizeof (long) * nAddrPtrMax);
- AddrUtf8 = malloc (sizeof (long) * nAddrPtrMax);
- memset(AddrUtf8, 0, sizeof (long) * nAddrPtrMax);
- *AddrPtr = 0;
- i = 0;
- while (!IsEmptyStr (&source[i])) {
- if (nColons >= nAddrPtrMax){
- long *ptr;
-
- ptr = (long *) malloc(sizeof (long) * nAddrPtrMax * 2);
- memcpy (ptr, AddrPtr, sizeof (long) * nAddrPtrMax);
- free (AddrPtr), AddrPtr = ptr;
-
- ptr = (long *) malloc(sizeof (long) * nAddrPtrMax * 2);
- memset(&ptr[nAddrPtrMax], 0,
- sizeof (long) * nAddrPtrMax);
-
- memcpy (ptr, AddrUtf8, sizeof (long) * nAddrPtrMax);
- free (AddrUtf8), AddrUtf8 = ptr;
- nAddrPtrMax *= 2;
- }
- if (((unsigned char) source[i] < 32) ||
- ((unsigned char) source[i] > 126)) {
- need_to_encode = 1;
- AddrUtf8[nColons] = 1;
- }
- if (source[i] == '"')
- InQuotes = !InQuotes;
- if (!InQuotes && source[i] == ',') {
- AddrPtr[nColons] = i;
- nColons++;
- }
- i++;
- }
- if (need_to_encode == 0) {
- free(AddrPtr);
- free(AddrUtf8);
- return source;
- }
-
- SourceLen = i;
- EncodedMaxLen = nColons * (sizeof(headerStr) + 3) + SourceLen * 3;
- Encoded = (char*) malloc (EncodedMaxLen);
-
- for (i = 0; i < nColons; i++)
- source[AddrPtr[i]++] = '\0';
- /* TODO: if libidn, this might get larger*/
- user = malloc(SourceLen + 1);
- node = malloc(SourceLen + 1);
- name = malloc(SourceLen + 1);
-
- nPtr = Encoded;
- *nPtr = '\0';
- for (i = 0; i < nColons && nPtr != NULL; i++) {
- nmax = EncodedMaxLen - (nPtr - Encoded);
- if (AddrUtf8[i]) {
- process_rfc822_addr(&source[AddrPtr[i]],
- user,
- node,
- name);
- /* TODO: libIDN here ! */
- if (IsEmptyStr(name)) {
- n = snprintf(nPtr, nmax,
- (i==0)?"%s@%s" : ",%s@%s",
- user, node);
- }
- else {
- EncodedName = rfc2047encode(name, strlen(name));
- n = snprintf(nPtr, nmax,
- (i==0)?"%s <%s@%s>" : ",%s <%s@%s>",
- EncodedName, user, node);
- free(EncodedName);
- }
- }
- else {
- n = snprintf(nPtr, nmax,
- (i==0)?"%s" : ",%s",
- &source[AddrPtr[i]]);
- }
- if (n > 0 )
- nPtr += n;
- else {
- char *ptr, *nnPtr;
- ptr = (char*) malloc(EncodedMaxLen * 2);
- memcpy(ptr, Encoded, EncodedMaxLen);
- nnPtr = ptr + (nPtr - Encoded), nPtr = nnPtr;
- free(Encoded), Encoded = ptr;
- EncodedMaxLen *= 2;
- i--; /* do it once more with properly lengthened buffer */
- }
- }
- for (i = 0; i < nColons; i++)
- source[--AddrPtr[i]] = ',';
-
- free(user);
- free(node);
- free(name);
- free(AddrUtf8);
- free(AddrPtr);
- return Encoded;
-}
-
-
-/* If the last item in a list of recipients was truncated to a partial address,
- * remove it completely in order to avoid choking libSieve
- */
-void sanitize_truncated_recipient(char *str)
-{
- if (!str) return;
- if (num_tokens(str, ',') < 2) return;
-
- int len = strlen(str);
- if (len < 900) return;
- if (len > 998) str[998] = 0;
-
- char *cptr = strrchr(str, ',');
- if (!cptr) return;
-
- char *lptr = strchr(cptr, '<');
- char *rptr = strchr(cptr, '>');
-
- if ( (lptr) && (rptr) && (rptr > lptr) ) return;
-
- *cptr = 0;
-}
-
void OutputCtdlMsgHeaders(
struct CtdlMessage *TheMessage,
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 ();
}
serialize_message(&smr, msg);
- CtdlFreeMessage(msg);
+ CM_Free(msg);
if (smr.len == 0) {
cprintf("%d Unable to serialize message\n",
/* Free up the memory we may have allocated */
if (msg != supplied_msg) {
- CtdlFreeMessage(msg);
+ CM_Free(msg);
}
}
/*
* 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;
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.
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 {
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);
}
/*
msg->cm_fields[eMesageText] = strdup(text);
CtdlSubmitMsg(msg, recp, room, 0);
- CtdlFreeMessage(msg);
+ CM_Free(msg);
if (recp != NULL) free_recipients(recp);
}
* (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(
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);
-}
-
-
-/*
- * Validate recipients, count delivery types and errors, and handle aliasing
- * FIXME check for dupes!!!!!
- *
- * Returns 0 if all addresses are ok, ret->num_error = -1 if no addresses
- * were specified, or the number of addresses found invalid.
- *
- * Caller needs to free the result using free_recipients()
- */
-struct recptypes *validate_recipients(const char *supplied_recipients,
- const char *RemoteIdentifier,
- int Flags) {
- struct CitContext *CCC = CC;
- struct recptypes *ret;
- char *recipients = NULL;
- char *org_recp;
- char this_recp[256];
- char this_recp_cooked[256];
- char append[SIZ];
- long len;
- int num_recps = 0;
- int i, j;
- int mailtype;
- int invalid;
- struct ctdluser tempUS;
- struct ctdlroom tempQR;
- struct ctdlroom tempQR2;
- int err = 0;
- char errmsg[SIZ];
- int in_quotes = 0;
-
- /* Initialize */
- ret = (struct recptypes *) malloc(sizeof(struct recptypes));
- if (ret == NULL) return(NULL);
-
- /* Set all strings to null and numeric values to zero */
- memset(ret, 0, sizeof(struct recptypes));
-
- if (supplied_recipients == NULL) {
- recipients = strdup("");
- }
- else {
- recipients = strdup(supplied_recipients);
- }
-
- /* Allocate some memory. Yes, this allocates 500% more memory than we will
- * actually need, but it's healthier for the heap than doing lots of tiny
- * realloc() calls instead.
- */
- len = strlen(recipients) + 1024;
- ret->errormsg = malloc(len);
- ret->recp_local = malloc(len);
- ret->recp_internet = malloc(len);
- ret->recp_ignet = malloc(len);
- ret->recp_room = malloc(len);
- ret->display_recp = malloc(len);
- ret->recp_orgroom = malloc(len);
- org_recp = malloc(len);
-
- ret->errormsg[0] = 0;
- ret->recp_local[0] = 0;
- ret->recp_internet[0] = 0;
- ret->recp_ignet[0] = 0;
- ret->recp_room[0] = 0;
- ret->recp_orgroom[0] = 0;
- ret->display_recp[0] = 0;
-
- ret->recptypes_magic = RECPTYPES_MAGIC;
-
- /* Change all valid separator characters to commas */
- for (i=0; !IsEmptyStr(&recipients[i]); ++i) {
- if ((recipients[i] == ';') || (recipients[i] == '|')) {
- recipients[i] = ',';
- }
- }
-
- /* Now start extracting recipients... */
-
- while (!IsEmptyStr(recipients)) {
- for (i=0; i<=strlen(recipients); ++i) {
- if (recipients[i] == '\"') in_quotes = 1 - in_quotes;
- if ( ( (recipients[i] == ',') && (!in_quotes) ) || (recipients[i] == 0) ) {
- safestrncpy(this_recp, recipients, i+1);
- this_recp[i] = 0;
- if (recipients[i] == ',') {
- strcpy(recipients, &recipients[i+1]);
- }
- else {
- strcpy(recipients, "");
- }
- break;
- }
- }
-
- striplt(this_recp);
- if (IsEmptyStr(this_recp))
- break;
- MSG_syslog(LOG_DEBUG, "Evaluating recipient #%d: %s\n", num_recps, this_recp);
- ++num_recps;
-
- strcpy(org_recp, this_recp);
- alias(this_recp);
- alias(this_recp);
- mailtype = alias(this_recp);
-
- for (j = 0; !IsEmptyStr(&this_recp[j]); ++j) {
- if (this_recp[j]=='_') {
- this_recp_cooked[j] = ' ';
- }
- else {
- this_recp_cooked[j] = this_recp[j];
- }
- }
- this_recp_cooked[j] = '\0';
- invalid = 0;
- errmsg[0] = 0;
- switch(mailtype) {
- case MES_LOCAL:
- if (!strcasecmp(this_recp, "sysop")) {
- ++ret->num_room;
- strcpy(this_recp, config.c_aideroom);
- if (!IsEmptyStr(ret->recp_room)) {
- strcat(ret->recp_room, "|");
- }
- strcat(ret->recp_room, this_recp);
- }
- else if ( (!strncasecmp(this_recp, "room_", 5))
- && (!CtdlGetRoom(&tempQR, &this_recp_cooked[5])) ) {
-
- /* Save room so we can restore it later */
- tempQR2 = CCC->room;
- CCC->room = tempQR;
-
- /* Check permissions to send mail to this room */
- err = CtdlDoIHavePermissionToPostInThisRoom(
- errmsg,
- sizeof errmsg,
- RemoteIdentifier,
- Flags,
- 0 /* 0 = not a reply */
- );
- if (err)
- {
- ++ret->num_error;
- invalid = 1;
- }
- else {
- ++ret->num_room;
- if (!IsEmptyStr(ret->recp_room)) {
- strcat(ret->recp_room, "|");
- }
- strcat(ret->recp_room, &this_recp_cooked[5]);
-
- if (!IsEmptyStr(ret->recp_orgroom)) {
- strcat(ret->recp_orgroom, "|");
- }
- strcat(ret->recp_orgroom, org_recp);
-
- }
-
- /* Restore room in case something needs it */
- CCC->room = tempQR2;
-
- }
- else if (CtdlGetUser(&tempUS, this_recp) == 0) {
- ++ret->num_local;
- strcpy(this_recp, tempUS.fullname);
- if (!IsEmptyStr(ret->recp_local)) {
- strcat(ret->recp_local, "|");
- }
- strcat(ret->recp_local, this_recp);
- }
- else if (CtdlGetUser(&tempUS, this_recp_cooked) == 0) {
- ++ret->num_local;
- strcpy(this_recp, tempUS.fullname);
- if (!IsEmptyStr(ret->recp_local)) {
- strcat(ret->recp_local, "|");
- }
- strcat(ret->recp_local, this_recp);
- }
- else {
- ++ret->num_error;
- invalid = 1;
- }
- break;
- case MES_INTERNET:
- /* Yes, you're reading this correctly: if the target
- * domain points back to the local system or an attached
- * Citadel directory, the address is invalid. That's
- * because if the address were valid, we would have
- * already translated it to a local address by now.
- */
- if (IsDirectory(this_recp, 0)) {
- ++ret->num_error;
- invalid = 1;
- }
- else {
- ++ret->num_internet;
- if (!IsEmptyStr(ret->recp_internet)) {
- strcat(ret->recp_internet, "|");
- }
- strcat(ret->recp_internet, this_recp);
- }
- break;
- case MES_IGNET:
- ++ret->num_ignet;
- if (!IsEmptyStr(ret->recp_ignet)) {
- strcat(ret->recp_ignet, "|");
- }
- strcat(ret->recp_ignet, this_recp);
- break;
- case MES_ERROR:
- ++ret->num_error;
- invalid = 1;
- break;
- }
- if (invalid) {
- if (IsEmptyStr(errmsg)) {
- snprintf(append, sizeof append, "Invalid recipient: %s", this_recp);
- }
- else {
- snprintf(append, sizeof append, "%s", errmsg);
- }
- if ( (strlen(ret->errormsg) + strlen(append) + 3) < SIZ) {
- if (!IsEmptyStr(ret->errormsg)) {
- strcat(ret->errormsg, "; ");
- }
- strcat(ret->errormsg, append);
- }
- }
- else {
- if (IsEmptyStr(ret->display_recp)) {
- strcpy(append, this_recp);
- }
- else {
- snprintf(append, sizeof append, ", %s", this_recp);
- }
- if ( (strlen(ret->display_recp)+strlen(append)) < SIZ) {
- strcat(ret->display_recp, append);
- }
- }
- }
- free(org_recp);
-
- if ((ret->num_local + ret->num_internet + ret->num_ignet +
- ret->num_room + ret->num_error) == 0) {
- ret->num_error = (-1);
- strcpy(ret->errormsg, "No recipients specified.");
- }
-
- MSGM_syslog(LOG_DEBUG, "validate_recipients()\n");
- MSG_syslog(LOG_DEBUG, " local: %d <%s>\n", ret->num_local, ret->recp_local);
- MSG_syslog(LOG_DEBUG, " room: %d <%s>\n", ret->num_room, ret->recp_room);
- MSG_syslog(LOG_DEBUG, " inet: %d <%s>\n", ret->num_internet, ret->recp_internet);
- MSG_syslog(LOG_DEBUG, " ignet: %d <%s>\n", ret->num_ignet, ret->recp_ignet);
- MSG_syslog(LOG_DEBUG, " error: %d <%s>\n", ret->num_error, ret->errormsg);
-
- free(recipients);
- return(ret);
-}
-
-
-/*
- * Destructor for struct recptypes
- */
-void free_recipients(struct recptypes *valid) {
-
- if (valid == NULL) {
- return;
- }
-
- if (valid->recptypes_magic != RECPTYPES_MAGIC) {
- struct CitContext *CCC = CC;
- MSGM_syslog(LOG_EMERG, "Attempt to call free_recipients() on some other data type!\n");
- abort();
- }
-
- if (valid->errormsg != NULL) free(valid->errormsg);
- if (valid->recp_local != NULL) free(valid->recp_local);
- if (valid->recp_internet != NULL) free(valid->recp_internet);
- if (valid->recp_ignet != NULL) free(valid->recp_ignet);
- if (valid->recp_room != NULL) free(valid->recp_room);
- if (valid->recp_orgroom != NULL) free(valid->recp_orgroom);
- if (valid->display_recp != NULL) free(valid->display_recp);
- if (valid->bounce_to != NULL) free(valid->bounce_to);
- if (valid->envelope_from != NULL) free(valid->envelope_from);
- if (valid->sending_room != NULL) free(valid->sending_room);
- free(valid);
-}
-
/*
cprintf("000\n");
}
- CtdlFreeMessage(msg);
+ CM_Free(msg);
}
if (valid != NULL) {
free_recipients(valid);
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
*/
}
/* Now write the data */
CtdlSubmitMsg(msg, NULL, roomname, 0);
- CtdlFreeMessage(msg);
+ CM_Free(msg);
}
msg = CtdlFetchMessage(msgnum, 1);
if (msg != NULL) {
conf = strdup(msg->cm_fields[eMesageText]);
- CtdlFreeMessage(msg);
+ CM_Free(msg);
}
else {
conf = NULL;
}
-/*
- * Determine whether a given Internet address belongs to the current user
- */
-int CtdlIsMe(char *addr, int addr_buf_len)
-{
- struct recptypes *recp;
- int i;
-
- recp = validate_recipients(addr, NULL, 0);
- if (recp == NULL) return(0);
-
- if (recp->num_local == 0) {
- free_recipients(recp);
- return(0);
- }
-
- for (i=0; i<recp->num_local; ++i) {
- extract_token(addr, recp->recp_local, i, '|', addr_buf_len);
- if (!strcasecmp(addr, CC->user.fullname)) {
- free_recipients(recp);
- return(1);
- }
- }
-
- free_recipients(recp);
- return(0);
-}
-
-
-/*
- * Citadel protocol command to do the same
- */
-void cmd_isme(char *argbuf) {
- char addr[256];
-
- if (CtdlAccessCheck(ac_logged_in)) return;
- extract_token(addr, argbuf, 0, '|', sizeof addr);
-
- if (CtdlIsMe(addr, sizeof addr)) {
- cprintf("%d %s\n", CIT_OK, addr);
- }
- else {
- cprintf("%d Not you.\n", ERROR + ILLEGAL_VALUE);
- }
-
-}
-
/*****************************************************************************/
/* MODULE INITIALIZATION STUFF */
CtdlRegisterProtoHook(cmd_ent0, "ENT0", "Enter a message");
CtdlRegisterProtoHook(cmd_dele, "DELE", "Delete a message");
CtdlRegisterProtoHook(cmd_move, "MOVE", "Move or copy a message to another room");
- CtdlRegisterProtoHook(cmd_isme, "ISME", "Determine whether an email address belongs to a user");
}
/* return our Subversion id for the Log */