]> code.citadel.org Git - citadel.git/blobdiff - citadel/serv_vcard.c
mk_module_init.sh now tests to see if echo supports -e and -E
[citadel.git] / citadel / serv_vcard.c
index ec8089d392d13f57e7bf279db95a10ca04af62b6..ba292dfebbfff248efae9d45c2ee31f8767401b9 100644 (file)
  */
 #define VCARD_EXT_FORMAT       "Citadel vCard: personal card for %s at %s"
 
+/*
+ * Citadel will accept either text/vcard or text/x-vcard as the MIME type
+ * for a vCard.  The following definition determines which one it *generates*
+ * when serializing.
+ */
+#define VCARD_MIME_TYPE                "text/x-vcard"
 
 #include "sysdep.h"
 #include <stdlib.h>
 #include <limits.h>
 #include "citadel.h"
 #include "server.h"
-#include "sysdep_decls.h"
 #include "citserver.h"
 #include "support.h"
 #include "config.h"
 #include "control.h"
-#include "serv_extensions.h"
 #include "room_ops.h"
 #include "user_ops.h"
 #include "policy.h"
 #include "serv_ldap.h"
 #include "serv_vcard.h"
 
+
+#include "ctdl_module.h"
+
+
+
 /*
  * set global flag calling for an aide to validate new users
  */
@@ -206,7 +215,7 @@ void cmd_igab(char *argbuf) {
  */
 void extract_inet_email_addrs(char *emailaddrbuf, size_t emailaddrbuf_len,
                                char *secemailaddrbuf, size_t secemailaddrbuf_len,
-                               struct vCard *v) {
+                               struct vCard *v, int local_addrs_only) {
        char *s, *addr;
        int instance = 0;
        int saved_instance = 0;
@@ -218,7 +227,8 @@ void extract_inet_email_addrs(char *emailaddrbuf, size_t emailaddrbuf_len,
                addr = strdup(s);
                striplt(addr);
                if (strlen(addr) > 0) {
-                       if (IsDirectory(addr)) {
+                       if ( (IsDirectory(addr, 1)) || 
+                            (!local_addrs_only) ) {
                                ++saved_instance;
                                if ((saved_instance == 1) && (emailaddrbuf != NULL)) {
                                        safestrncpy(emailaddrbuf, addr, emailaddrbuf_len);
@@ -445,7 +455,7 @@ int vcard_upload_beforesave(struct CtdlMessage *msg) {
        if (ser != NULL) {
                msg->cm_fields['M'] = realloc(msg->cm_fields['M'], strlen(ser) + 1024);
                sprintf(msg->cm_fields['M'],
-                       "Content-type: text/vcard"
+                       "Content-type: " VCARD_MIME_TYPE
                        "\r\n\r\n%s\r\n", ser);
                free(ser);
        }
@@ -499,7 +509,7 @@ int vcard_upload_aftersave(struct CtdlMessage *msg) {
                        v = vcard_load(msg->cm_fields['M']);
                        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);
+                                               v, 1);
                        extract_friendly_name(CC->cs_inet_fn, sizeof CC->cs_inet_fn, v);
                        vcard_free(v);
 
@@ -609,7 +619,7 @@ void vcard_write_user(struct ctdluser *u, struct vCard *v) {
         * is going to notice what we're trying to do, and delete the old vCard.
         */
        CtdlWriteObject(USERCONFIGROOM, /* which room */
-                       "text/vcard",   /* MIME type */
+                       VCARD_MIME_TYPE,/* MIME type */
                        temp,           /* temp file */
                        u,              /* which user */
                        0,              /* not binary */
@@ -759,6 +769,7 @@ void cmd_greg(char *argbuf)
        extract_token(buf, adr, 6, ';', sizeof buf);
        cprintf("%s\n", buf);                           /* country */
        cprintf("000\n");
+       vcard_free(v);
 }
 
 
@@ -944,6 +955,88 @@ void cmd_gvea(char *argbuf)
 }
 
 
+
+
+/*
+ * Callback function for cmd_dvca() that hunts for vCard content types
+ * and outputs any email addresses found within.
+ */
+void dvca_mime_callback(char *name, char *filename, char *partnum, char *disp,
+               void *content, char *cbtype, char *cbcharset, size_t length, char *encoding,
+               void *cbuserdata) {
+
+       struct vCard *v;
+       char displayname[256];
+       int displayname_len;
+       char emailaddr[256];
+       int i;
+       int has_commas = 0;
+
+       if ( (strcasecmp(cbtype, "text/vcard")) && (strcasecmp(cbtype, "text/x-vcard")) ) {
+               return;
+       }
+
+       v = vcard_load(content);
+       if (v == NULL) return;
+
+       extract_friendly_name(displayname, sizeof displayname, v);
+       extract_inet_email_addrs(emailaddr, sizeof emailaddr, NULL, 0, v, 0);
+
+       displayname_len = strlen(displayname);
+       for (i=0; i<displayname_len; ++i) {
+               if (displayname[i] == '\"') displayname[i] = ' ';
+               if (displayname[i] == ';') displayname[i] = ',';
+               if (displayname[i] == ',') has_commas = 1;
+       }
+       striplt(displayname);
+
+       cprintf("%s%s%s <%s>\n",
+               (has_commas ? "\"" : ""),
+               displayname,
+               (has_commas ? "\"" : ""),
+               emailaddr
+       );
+
+       vcard_free(v);
+}
+
+
+/*
+ * Back end callback function for cmd_dvca()
+ *
+ * It's basically just passed a list of message numbers, which we're going
+ * to fetch off the disk and then pass along to the MIME parser via another
+ * layer of callback...
+ */
+void dvca_callback(long msgnum, void *userdata) {
+       struct CtdlMessage *msg = NULL;
+
+       msg = CtdlFetchMessage(msgnum, 1);
+       if (msg == NULL) return;
+       mime_parser(msg->cm_fields['M'],
+               NULL,
+               *dvca_mime_callback,    /* callback function */
+               NULL, NULL,
+               NULL,                   /* user data */
+               0
+       );
+       CtdlFreeMessage(msg);
+}
+
+
+/*
+ * Dump VCard Addresses
+ */
+void cmd_dvca(char *argbuf)
+{
+       if (CtdlAccessCheck(ac_logged_in)) return;
+
+       cprintf("%d addresses:\n", LISTING_FOLLOWS);
+       CtdlForEachMessage(MSGS_ALL, 0, NULL, NULL, NULL, dvca_callback, NULL);
+       cprintf("000\n");
+}
+
+
 /*
  * Query Directory
  */
@@ -1054,7 +1147,7 @@ void vcard_session_login_hook(void) {
        v = vcard_get_user(&CC->user);
        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);
+                               v, 1);
        extract_friendly_name(CC->cs_inet_fn, sizeof CC->cs_inet_fn, v);
        vcard_free(v);
 
@@ -1170,7 +1263,7 @@ void store_this_ha(struct addresses_to_be_filed *aptr) {
                        if (ser != NULL) {
                                vmsg->cm_fields['M'] = malloc(strlen(ser) + 1024);
                                sprintf(vmsg->cm_fields['M'],
-                                       "Content-type: text/vcard"
+                                       "Content-type: " VCARD_MIME_TYPE
                                        "\r\n\r\n%s\r\n", ser);
                                free(ser);
                        }
@@ -1236,19 +1329,9 @@ void vcard_fixed_output(char *ptr, int len) {
 }
 
 
-char *serv_postfix_tcpdict(void)
-{
-       CtdlRegisterServiceHook(config.c_pftcpdict_port,        /* Postfix */
-                               NULL,
-                               check_get_greeting,
-                               check_get,
-                               NULL);
-       return "$Id$";
-}
-
 
 
-char *serv_vcard_init(void)
+CTDL_MODULE_INIT(vcard)
 {
        struct ctdlroom qr;
        char filename[256];
@@ -1265,6 +1348,7 @@ char *serv_vcard_init(void)
        CtdlRegisterProtoHook(cmd_qdir, "QDIR", "Query Directory");
        CtdlRegisterProtoHook(cmd_gvsn, "GVSN", "Get Valid Screen Names");
        CtdlRegisterProtoHook(cmd_gvea, "GVEA", "Get Valid Email Addresses");
+       CtdlRegisterProtoHook(cmd_dvca, "DVCA", "Dump VCard Addresses");
        CtdlRegisterUserHook(vcard_newuser, EVT_NEWUSER);
        CtdlRegisterUserHook(vcard_purge, EVT_PURGEUSER);
        CtdlRegisterNetprocHook(vcard_extract_from_network);
@@ -1293,5 +1377,13 @@ char *serv_vcard_init(void)
                chown(filename, CTDLUID, (-1));
        }
 
+       /* for postfix tcpdict */
+       CtdlRegisterServiceHook(config.c_pftcpdict_port,        /* Postfix */
+                               NULL,
+                               check_get_greeting,
+                               check_get,
+                               NULL);
+       
+       /* return our Subversion id for the Log */
        return "$Id$";
 }