]> code.citadel.org Git - citadel.git/blobdiff - citadel/serv_vcard.c
* Minor changes for global directory service
[citadel.git] / citadel / serv_vcard.c
index bc2f542788df4d66a733f1308616050d4b2691ec..36f4b2316cb2ad9a63af636df1b3fa86913bc25e 100644 (file)
@@ -3,12 +3,26 @@
  * 
  * A server-side module for Citadel which supports address book information
  * using the standard vCard format.
- *
+ * 
+ * Copyright (c) 1999-2001 / released under the GNU General Public License
  */
 
+/*
+ * Where we keep messages containing the vCards that source our directory.  It
+ * makes no sense to change this, because you'd have to change it on every
+ * system on the network.  That would be stupid.
+ */
 #define ADDRESS_BOOK_ROOM      "Global Address Book"
+
+/*
+ * Format of the "Extended ID" field of the message containing a user's
+ * vCard.  Doesn't matter what it really looks like as long as it's both
+ * unique and consistent (because we use it for replication checking to
+ * delete the old vCard network-wide when the user enters a new one).
+ */
 #define VCARD_EXT_FORMAT       "Citadel vCard: personal card for %s at %s"
 
+
 #include "sysdep.h"
 #include <stdlib.h>
 #include <unistd.h>
@@ -46,6 +60,7 @@
 #include "policy.h"
 #include "database.h"
 #include "msgbase.h"
+#include "internet_addressing.h"
 #include "tools.h"
 #include "vcard.h"
 
@@ -58,22 +73,35 @@ unsigned long SYM_VCARD;
 #define VC ((struct vcard_internal_info *)CtdlGetUserData(SYM_VCARD))
 
 
-
-
 /*
- * Extract Internet e-mail addresses from a message containing a vCard
- * FIXME give this a callback ability
+ * Extract Internet e-mail addresses from a message containing a vCard, and
+ * perform a callback for any found.
  */
-void vcard_extract_internet_addresses(struct CtdlMessage *msg) {
+void vcard_extract_internet_addresses(struct CtdlMessage *msg,
+                               void (*callback)(char *, char *) ) {
        struct vCard *v;
        char *s;
+       char *addr;
+       char citadel_address[SIZ];
+
+       if (msg->cm_fields['A'] == NULL) return;
+       if (msg->cm_fields['N'] == NULL) return;
+       sprintf(citadel_address, "%s @ %s",
+               msg->cm_fields['A'], msg->cm_fields['N']);
 
        v = vcard_load(msg->cm_fields['M']);
        if (v == NULL) return;
 
-       s = vcard_get_prop(v, "email;internet", 0);
+       s = vcard_get_prop(v, "email;internet", 0); /* FIXME handle multiples */
        if (s != NULL) {
-               lprintf(9, "extracted internet address <%s>\n", s);
+               addr = strdoop(s);
+               striplt(addr);
+               if (strlen(addr) > 0) {
+                       if (callback != NULL) {
+                               callback(addr, citadel_address);
+                       }
+               }
+               phree(addr);
        }
 
        vcard_free(v);
@@ -81,14 +109,14 @@ void vcard_extract_internet_addresses(struct CtdlMessage *msg) {
 
 /*
  * Back end function for cmd_igab()
- * FIXME actually write to the database, dumbass...
+ * FIXME use a callback that actually writes to the database, dumbass...
  */
-void vcard_igab_backend(long msgnum, void *data) {
+void vcard_add_to_directory(long msgnum, void *data) {
        struct CtdlMessage *msg;
 
        msg = CtdlFetchMessage(msgnum);
        if (msg != NULL) {
-               vcard_extract_internet_addresses(msg);
+               vcard_extract_internet_addresses(msg, CtdlDirectoryAddUser);
        }
 
        CtdlFreeMessage(msg);
@@ -117,14 +145,13 @@ void cmd_igab(char *argbuf) {
         * client when finished.
         */
        
-       cprintf("%d FIXME\n", LISTING_FOLLOWS);
+       cprintf("%d Directory will be rebuilt\n", OK);
 
         /* We want the last (and probably only) vcard in this room */
         CtdlForEachMessage(MSGS_ALL, 0, (-127), "text/x-vcard",
-               NULL, vcard_igab_backend, NULL);
+               NULL, vcard_add_to_directory, NULL);
 
         getroom(&CC->quickroom, hold_rm);      /* return to saved room */
-       cprintf("000\n");
 }
 
 
@@ -233,9 +260,13 @@ int vcard_upload_aftersave(struct CtdlMessage *msg) {
                        I = atol(msg->cm_fields['I']);
                        if (I < 0L) return(0);
 
+                       /* Put it in the Global Address Book room... */
                        CtdlSaveMsgPointerInRoom(ADDRESS_BOOK_ROOM, I,
                                (SM_VERIFY_GOODNESS | SM_DO_REPL_CHECK) );
 
+                       /* ...and also in the directory database. */
+                       vcard_add_to_directory(I, NULL);
+
                        return(0);
                }