From: Art Cancro Date: Thu, 22 Mar 2007 17:17:41 +0000 (+0000) Subject: Server-side changes to allow users to submit messages X-Git-Tag: v7.86~3491 X-Git-Url: https://code.citadel.org/?p=citadel.git;a=commitdiff_plain;h=d27e5ce95bd12d9c25a4e596655212253d50c5c9 Server-side changes to allow users to submit messages using any of their valid email addresses when using Citadel protocol. --- diff --git a/citadel/journaling.c b/citadel/journaling.c index ec158b43c..7febabd0a 100644 --- a/citadel/journaling.c +++ b/citadel/journaling.c @@ -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); } diff --git a/citadel/msgbase.c b/citadel/msgbase.c index b17e92040..f5a8da0e4 100644 --- a/citadel/msgbase.c +++ b/citadel/msgbase.c @@ -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; ics_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); diff --git a/citadel/msgbase.h b/citadel/msgbase.h index d8a3697ee..1e0616bbb 100644 --- a/citadel/msgbase.h +++ b/citadel/msgbase.h @@ -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 */ diff --git a/citadel/serv_calendar.c b/citadel/serv_calendar.c index aa859d025..a36926c30 100644 --- a/citadel/serv_calendar.c +++ b/citadel/serv_calendar.c @@ -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); diff --git a/citadel/serv_funambol.c b/citadel/serv_funambol.c index ba159173f..271dc102f 100644 --- a/citadel/serv_funambol.c +++ b/citadel/serv_funambol.c @@ -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; } diff --git a/citadel/serv_funambol.h b/citadel/serv_funambol.h index ecae2c7a6..209fb9b39 100644 --- a/citadel/serv_funambol.h +++ b/citadel/serv_funambol.h @@ -1 +1 @@ -int notify_funambol(long msgnum, void *userdata); +void notify_funambol(long msgnum, void *userdata); diff --git a/citadel/serv_vcard.c b/citadel/serv_vcard.c index 35f6efabb..a22d7c199 100644 --- a/citadel/serv_vcard.c +++ b/citadel/serv_vcard.c @@ -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; ics_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); diff --git a/citadel/serv_vcard.h b/citadel/serv_vcard.h index ad23cbb18..4e6f52758 100644 --- a/citadel/serv_vcard.h +++ b/citadel/serv_vcard.h @@ -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); diff --git a/citadel/server.h b/citadel/server.h index bdb7a7ebe..19eb12a2a 100644 --- a/citadel/server.h +++ b/citadel/server.h @@ -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 */