Server-side changes to allow users to submit messages
authorArt Cancro <ajc@citadel.org>
Thu, 22 Mar 2007 17:17:41 +0000 (17:17 +0000)
committerArt Cancro <ajc@citadel.org>
Thu, 22 Mar 2007 17:17:41 +0000 (17:17 +0000)
using any of their valid email addresses when using Citadel protocol.

citadel/journaling.c
citadel/msgbase.c
citadel/msgbase.h
citadel/serv_calendar.c
citadel/serv_funambol.c
citadel/serv_funambol.h
citadel/serv_vcard.c
citadel/serv_vcard.h
citadel/server.h

index ec158b43c80999e120a1d02669002900aa6d3acb..7febabd0ae3b2cfbad2d886ad05ea85222636790 100644 (file)
@@ -107,7 +107,7 @@ void local_to_inetemail(char *inetemail, char *localuser, size_t inetemail_len)
                return;
        }
 
-       extract_primary_inet_email(inetemail, inetemail_len, v);
+       extract_inet_email_addrs(inetemail, inetemail_len, NULL, 0, v);
        vcard_free(v);
 }
 
index b17e920405879c5f78d47ee695e43f3130ce482b..f5a8da0e42d4b00a14c7e38816323793750de3a6 100644 (file)
@@ -2910,6 +2910,7 @@ struct CtdlMessage *CtdlMakeMessage(
        int type,                       /* see MES_ types in header file */
        int format_type,                /* variformat, plain text, MIME... */
        char *fake_name,                /* who we're masquerading as */
+       char *my_email,                 /* which of my email addresses to use (empty is ok) */
        char *subject,                  /* Subject (optional) */
        char *supplied_euid,            /* ...or NULL if this is irrelevant */
        char *preformatted_text         /* ...or NULL to read text from client */
@@ -2961,7 +2962,10 @@ struct CtdlMessage *CtdlMakeMessage(
                msg->cm_fields['D'] = strdup(dest_node);
        }
 
-       if ( (author == &CC->user) && (strlen(CC->cs_inet_email) > 0) ) {
+       if (strlen(my_email) > 0) {
+               msg->cm_fields['F'] = strdup(my_email);
+       }
+       else if ( (author == &CC->user) && (strlen(CC->cs_inet_email) > 0) ) {
                msg->cm_fields['F'] = strdup(CC->cs_inet_email);
        }
 
@@ -3265,6 +3269,7 @@ void cmd_ent0(char *entargs)
        int anon_flag = 0;
        int format_type = 0;
        char newusername[256];
+       char newuseremail[256];
        struct CtdlMessage *msg;
        int anonymous = 0;
        char errmsg[SIZ];
@@ -3276,6 +3281,9 @@ void cmd_ent0(char *entargs)
        char subject[SIZ];
        int do_confirm = 0;
        long msgnum;
+       int i, j;
+       char buf[256];
+       int newuseremail_ok = 0;
 
        unbuffer_output();
 
@@ -3297,6 +3305,7 @@ void cmd_ent0(char *entargs)
                        supplied_euid[0] = 0;
                        break;
        }
+       extract_token(newuseremail, entargs, 9, '|', sizeof newuseremail);
 
        /* first check to make sure the request is valid. */
 
@@ -3309,8 +3318,7 @@ void cmd_ent0(char *entargs)
 
        /* Check some other permission type things. */
 
-       if (strlen(newusername) == 0)
-       {
+       if (strlen(newusername) == 0) {
                strcpy(newusername, CC->user.fullname);
        }
        if (  (CC->user.axlevel < 6)
@@ -3324,6 +3332,34 @@ void cmd_ent0(char *entargs)
                return;
        }
 
+
+       if (strlen(newuseremail) == 0) {
+               newuseremail_ok = 1;
+       }
+
+       if (strlen(newuseremail) > 0) {
+               if (!strcasecmp(newuseremail, CC->cs_inet_email)) {
+                       newuseremail_ok = 1;
+               }
+               else if (strlen(CC->cs_inet_other_emails) > 0) {
+                       j = num_tokens(CC->cs_inet_other_emails, '|');
+                       for (i=0; i<j; ++i) {
+                               extract_token(buf, CC->cs_inet_other_emails, i, '|', sizeof buf);
+                               if (!strcasecmp(newuseremail, buf)) {
+                                       newuseremail_ok = 1;
+                               }
+                       }
+               }
+       }
+
+       if (!newuseremail_ok) {
+               cprintf("%d You don't have permission to author messages as '%s'.\n",
+                       ERROR + HIGHER_ACCESS_REQUIRED,
+                       newuseremail
+               );
+               return;
+       }
+
        CC->cs_flags |= CS_POSTING;
 
        /* In the Mail> room we have to behave a little differently --
@@ -3449,7 +3485,7 @@ void cmd_ent0(char *entargs)
 
        msg = CtdlMakeMessage(&CC->user, recp, cc,
                CC->room.QRname, anonymous, format_type,
-               newusername, subject,
+               newusername, newuseremail, subject,
                ((strlen(supplied_euid) > 0) ? supplied_euid : NULL),
                NULL);
 
index d8a3697ee5a865b3bc33d16bd505b7d2a64442dd..1e0616bbb1aeb4ec40d16093a6a1070bd8f6a70a 100644 (file)
@@ -163,6 +163,7 @@ struct CtdlMessage *CtdlMakeMessage(
         int type,                       /* see MES_ types in header file */
         int format_type,                /* variformat, plain text, MIME... */
         char *fake_name,                /* who we're masquerading as */
+       char *my_email,                 /* which of my email addresses to use (empty is ok) */
         char *subject,                  /* Subject (optional) */
        char *supplied_euid,            /* ...or NULL if this is irrelevant */
         char *preformatted_text         /* ...or NULL to read text from client */
index aa859d025abdd8b09fe31362196f7f14f0a57e75..a36926c3072215f47e8fbe780352c0abcd8ebf55 100644 (file)
@@ -314,6 +314,7 @@ void ical_send_a_reply(icalcomponent *request, char *action) {
                        "",                     /* cc */
                        CC->room.QRname, 0, FMT_RFC822,
                        "",
+                       "",
                        summary_string,         /* Use summary for subject */
                        NULL,
                        reply_message_text);
@@ -685,6 +686,7 @@ int ical_update_my_calendar_with_reply(icalcomponent *cal) {
                        roomname,
                        0, FMT_RFC822,
                        "",
+                       "",
                        "",             /* no subject */
                        NULL,
                        message_text);
@@ -1756,6 +1758,7 @@ void ical_send_out_invitations(icalcomponent *cal) {
                        "",                     /* No single recipient here */
                        CC->room.QRname, 0, FMT_RFC822,
                        "",
+                       "",
                        summary_string,         /* Use summary for subject */
                        NULL,
                        request_message_text);
index ba159173f48b420bde02814d6eea8c1f75c39d0d..271dc102f41bb49010feaa8103a41b224e563e99 100644 (file)
@@ -95,7 +95,7 @@ void do_notify_queue(void) {
 /*
  * Connect to the Funambol server and scan a message.
  */
-int notify_funambol(long msgnum, void *userdata) {
+void notify_funambol(long msgnum, void *userdata) {
        struct CtdlMessage *msg;
        int sock = (-1);
        char buf[SIZ];
@@ -121,7 +121,7 @@ int notify_funambol(long msgnum, void *userdata) {
 
        if (sock < 0) {
                /* If the service isn't running, pass for now */
-               return(0);
+               return;
        }
        
        /* Build a SOAP message, delicately, by hand */
@@ -215,7 +215,6 @@ int notify_funambol(long msgnum, void *userdata) {
        long todelete[1];
        todelete[0] = msgnum;
        CtdlDeleteMessages(FNBL_QUEUE_ROOM, todelete, 1, "");
-       return 0;
 }
 
 
index ecae2c7a66606432315790e63494fa7d26364be6..209fb9b390d572b9a1214749faa419629f0f0fd7 100644 (file)
@@ -1 +1 @@
-int notify_funambol(long msgnum, void *userdata);
+void notify_funambol(long msgnum, void *userdata);
index 35f6efabb50deec8b1bfdbdf8f6de60cac307683..a22d7c1997dd007149ac4b275d932164f154b5b7 100644 (file)
@@ -204,33 +204,39 @@ void cmd_igab(char *argbuf) {
  * See if there is a valid Internet address in a vCard to use for outbound
  * Internet messages.  If there is, stick it in the buffer.
  */
-void extract_primary_inet_email(char *emailaddrbuf, size_t emailaddrbuf_len, struct vCard *v) {
+void extract_inet_email_addrs(char *emailaddrbuf, size_t emailaddrbuf_len,
+                               char *secemailaddrbuf, size_t secemailaddrbuf_len,
+                               struct vCard *v) {
        char *s, *addr;
-       int continue_searching = 1;
        int instance = 0;
+       int saved_instance = 0;
 
        /* Go through the vCard searching for *all* instances of
         * the "email;internet" key
         */
-       do {
-               s = vcard_get_prop(v, "email;internet", 0, instance++, 0);
-               if (s != NULL) {
-                       continue_searching = 1;
-                       addr = strdup(s);
-                       striplt(addr);
-                       if (strlen(addr) > 0) {
-                               if (IsDirectory(addr)) {
-                                       continue_searching = 0;
-                                       safestrncpy(emailaddrbuf, addr,
-                                               emailaddrbuf_len);
+       while (s = vcard_get_prop(v, "email;internet", 0, instance++, 0),  s != NULL) {
+               addr = strdup(s);
+               striplt(addr);
+               if (strlen(addr) > 0) {
+                       if (IsDirectory(addr)) {
+                               ++saved_instance;
+                               if ((saved_instance == 1) && (emailaddrbuf != NULL)) {
+                                       safestrncpy(emailaddrbuf, addr, emailaddrbuf_len);
+                               }
+                               else if ((saved_instance == 2) && (secemailaddrbuf != NULL)) {
+                                       safestrncpy(secemailaddrbuf, addr, secemailaddrbuf_len);
+                               }
+                               else if ((saved_instance > 2) && (secemailaddrbuf != NULL)) {
+                                       if ( (strlen(addr) + strlen(secemailaddrbuf) + 2) 
+                                          < secemailaddrbuf_len ) {
+                                               strcat(secemailaddrbuf, "|");
+                                               strcat(secemailaddrbuf, addr);
+                                       }
                                }
                        }
-                       free(addr);
-               }
-               else {
-                       continue_searching = 0;
                }
-       } while(continue_searching);
+               free(addr);
+       }
 }
 
 
@@ -486,7 +492,9 @@ int vcard_upload_aftersave(struct CtdlMessage *msg) {
 
                        /* Store our Internet return address in memory */
                        v = vcard_load(msg->cm_fields['M']);
-                       extract_primary_inet_email(CC->cs_inet_email, sizeof CC->cs_inet_email, v);
+                       extract_inet_email_addrs(CC->cs_inet_email, sizeof CC->cs_inet_email,
+                                               CC->cs_inet_other_emails, sizeof CC->cs_inet_other_emails,
+                                               v);
                        extract_friendly_name(CC->cs_inet_fn, sizeof CC->cs_inet_fn, v);
                        vcard_free(v);
 
@@ -899,6 +907,32 @@ void cmd_gvsn(char *argbuf)
 }
 
 
+/*
+ * Get Valid Email Addresses
+ */
+void cmd_gvea(char *argbuf)
+{
+       int num_secondary_emails = 0;
+       int i;
+       char buf[256];
+
+       if (CtdlAccessCheck(ac_logged_in)) return;
+
+       cprintf("%d valid email addresses:\n", LISTING_FOLLOWS);
+       if (strlen(CC->cs_inet_email) > 0) {
+               cprintf("%s\n", CC->cs_inet_email);
+       }
+       if (strlen(CC->cs_inet_other_emails) > 0) {
+               num_secondary_emails = num_tokens(CC->cs_inet_other_emails, '|');
+               for (i=0; i<num_secondary_emails; ++i) {
+                       extract_token(buf, CC->cs_inet_other_emails,i,'|',sizeof CC->cs_inet_other_emails);
+                       cprintf("%s\n", buf);
+               }
+       }
+       cprintf("000\n");
+}
+
+
 /*
  * Query Directory
  */
@@ -1008,7 +1042,9 @@ void vcard_session_login_hook(void) {
        struct vCard *v = NULL;
 
        v = vcard_get_user(&CC->user);
-       extract_primary_inet_email(CC->cs_inet_email, sizeof CC->cs_inet_email, v);
+       extract_inet_email_addrs(CC->cs_inet_email, sizeof CC->cs_inet_email,
+                               CC->cs_inet_other_emails, sizeof CC->cs_inet_other_emails,
+                               v);
        extract_friendly_name(CC->cs_inet_fn, sizeof CC->cs_inet_fn, v);
        vcard_free(v);
 
@@ -1218,6 +1254,7 @@ char *serv_vcard_init(void)
                                        "Initialize Global Address Book");
        CtdlRegisterProtoHook(cmd_qdir, "QDIR", "Query Directory");
        CtdlRegisterProtoHook(cmd_gvsn, "GVSN", "Get Valid Screen Names");
+       CtdlRegisterProtoHook(cmd_gvea, "GVEA", "Get Valid Email Addresses");
        CtdlRegisterUserHook(vcard_newuser, EVT_NEWUSER);
        CtdlRegisterUserHook(vcard_purge, EVT_PURGEUSER);
        CtdlRegisterNetprocHook(vcard_extract_from_network);
index ad23cbb18c89b9afc5a1cf6c035886b04991b169..4e6f52758daa2e9132ff3fed112806bca34e8bf0 100644 (file)
@@ -1,5 +1,5 @@
 /*
  * $Id: $
  */
-void extract_primary_inet_email(char *emailaddrbuf, size_t emailaddrbuf_len, struct vCard *v);
+void extract_inet_email_addrs(char *, size_t, char *, size_t, struct vCard *v);
 struct vCard *vcard_get_user(struct ctdluser *u);
index bdb7a7ebeb5997643390311811d63b7b2199b046..19eb12a2a1b722a4e06a197fa134166207223a60 100644 (file)
@@ -52,8 +52,6 @@ struct CtdlMessage {
  * This structure keeps track of all information relating to a running 
  * session on the server.  We keep one of these for each session thread.
  *
- * Note that the first element is "*next" so that it may be used without
- * modification in a linked list.
  */
 struct CitContext {
        struct CitContext *prev;        /* Link to previous session in list */
@@ -83,7 +81,7 @@ struct CitContext {
        int async_waiting;      /* Nonzero if there are async msgs waiting */
        int input_waiting;      /* Nonzero if there is client input waiting */
 
-       /* feeping creaturisms... */
+       /* Client information */
        int cs_clientdev;       /* client developer ID */
        int cs_clienttyp;       /* client type code */
        int cs_clientver;       /* client version number */
@@ -92,8 +90,9 @@ struct CitContext {
        char cs_addr[64];       /* address logged in from */
 
        /* The Internet type of thing */
-       char cs_inet_email[128];/* Return address of outbound Internet mail */
-       char cs_inet_fn[128];   /* Friendly-name of outbound Internet mail */
+       char cs_inet_email[128];                /* Return address of outbound Internet mail */
+       char cs_inet_other_emails[1024];        /* User's other valid Internet email addresses */
+       char cs_inet_fn[128];                   /* Friendly-name of outbound Internet mail */
 
        FILE *download_fp;      /* Fields relating to file transfer */
        char download_desired_section[128];
@@ -428,7 +427,7 @@ enum {
 
 /*
  * ServiceFunctionHook extensions are used for hooks which implement various
- * non-Citadel services (on TCP protocols) directly in the Citadel server.
+ * protocols (either on TCP or on unix domain sockets) directly in the Citadel server.
  */
 struct ServiceFunctionHook {
        struct ServiceFunctionHook *next;
@@ -491,10 +490,10 @@ struct ser_ret {
 };
 
 
-/* Preferred field order */
-/*               **********                    Important fields */
-/*                         ***************     Semi-important fields */
-/*                                        *    Message text (MUST be last) */
+/* Preferred field order                                                       */
+/*               **********                    Important fields                */
+/*                         ***************     Semi-important fields           */
+/*                                        *    Message text (MUST be last)     */
 #define FORDER "IPTAFONHRDBCEJGKLQSVWXZYUM"
 
 #endif /* SERVER_H */