- if (!strcasecmp(v->prop[i].name, "org")) {
- (void) CtdlDoDirectoryServiceFunc("o", v->prop[i].value, &objectlist, "ldap", DIRECTORY_ATTRIB_ADD);
- }
-
- if ( (!strcasecmp(v->prop[i].name, "adr"))
- ||(!strncasecmp(v->prop[i].name, "adr;", 4)) ) {
- /* Unfortunately, we can only do a single address */
- if (!have_addr) {
- have_addr = 1;
- strcpy(street, "");
- extract_token(&street[strlen(street)],
- v->prop[i].value, 0, ';', (sizeof street - strlen(street))); /* po box */
- strcat(street, " ");
- extract_token(&street[strlen(street)],
- v->prop[i].value, 1, ';', (sizeof street - strlen(street))); /* extend addr */
- strcat(street, " ");
- extract_token(&street[strlen(street)],
- v->prop[i].value, 2, ';', (sizeof street - strlen(street))); /* street */
- striplt(street);
- extract_token(city, v->prop[i].value, 3, ';', sizeof city);
- extract_token(state, v->prop[i].value, 4, ';', sizeof state);
- extract_token(zipcode, v->prop[i].value, 5, ';', sizeof zipcode);
-
- (void) CtdlDoDirectoryServiceFunc("street", street, &objectlist, "ldap", DIRECTORY_ATTRIB_ADD);
- (void) CtdlDoDirectoryServiceFunc("l", city, &objectlist, "ldap", DIRECTORY_ATTRIB_ADD);
- (void) CtdlDoDirectoryServiceFunc("st", state, &objectlist, "ldap", DIRECTORY_ATTRIB_ADD);
- (void) CtdlDoDirectoryServiceFunc("postalcode", zipcode, &objectlist, "ldap", DIRECTORY_ATTRIB_ADD);
- }
- }
-
- if ( (!strcasecmp(v->prop[i].name, "tel"))
- ||(!strncasecmp(v->prop[i].name, "tel;", 4)) ) {
- ++num_phones;
- /* The first 'tel' property creates the 'telephoneNumber' attribute */
- if (num_phones == 1) {
- (void) CtdlDoDirectoryServiceFunc("telephoneNumber", v->prop[i].value, &objectlist, "ldap", DIRECTORY_ATTRIB_ADD);
- }
- /* Subsequent 'tel' properties *add to* the 'telephoneNumber' attribute */
- else {
- (void) CtdlDoDirectoryServiceFunc("telephoneNumber", v->prop[i].value, &objectlist, "ldap", DIRECTORY_ATTRIB_ADD);
- }
- }
-
-
- if ( (!strcasecmp(v->prop[i].name, "email"))
- ||(!strcasecmp(v->prop[i].name, "email;internet")) ) {
-
- ++num_emails;
- lprintf(CTDL_DEBUG, "email addr %d\n", num_emails);
-
- /* The first email address creates the 'mail' attribute */
- if (num_emails == 1) {
- (void) CtdlDoDirectoryServiceFunc("mail", v->prop[i].value, &objectlist, "ldap", DIRECTORY_ATTRIB_ADD);
- }
- /* The second and subsequent email address creates the 'alias' attribute */
- else if (num_emails >= 2) {
- (void) CtdlDoDirectoryServiceFunc("alias", v->prop[i].value, &objectlist, "ldap", DIRECTORY_ATTRIB_ADD);
- }
- }
-
- /* Calendar free/busy URL (take the first one we find, but if a subsequent
- * one contains the "pref" designation then we go with that instead.)
- */
- if ( (!strcasecmp(v->prop[i].name, "fburl"))
- ||(!strncasecmp(v->prop[i].name, "fburl;", 6)) ) {
- if ( (IsEmptyStr(calFBURL))
- || (!strncasecmp(v->prop[i].name, "fburl;pref", 10)) ) {
- safestrncpy(calFBURL, v->prop[i].value, sizeof calFBURL);
- }
- }
-
- }
- vcard_free(v); /* Don't need this anymore. */
-
- /* "sn" (surname) based on info in vCard */
- (void) CtdlDoDirectoryServiceFunc("sn", sn, &objectlist, "ldap", DIRECTORY_ATTRIB_ADD);
-
- /* "givenname" (first name) based on info in vCard */
- if (IsEmptyStr(givenname)) strcpy(givenname, "_");
- if (IsEmptyStr(sn)) strcpy(sn, "_");
- (void) CtdlDoDirectoryServiceFunc("givenname", givenname, &objectlist, "ldap", DIRECTORY_ATTRIB_ADD);
-
- /* "uid" is a Kolab compatibility thing. We just do cituser@citnode */
- (void) CtdlDoDirectoryServiceFunc("uid", uid, &objectlist, "ldap", DIRECTORY_ATTRIB_ADD);
-
- /* Add a "cn" (Common Name) attribute based on the user's screen name,
- * but only there was no 'fn' (full name) property in the vCard
- */
- if (!have_cn) {
- (void) CtdlDoDirectoryServiceFunc("cn", msg->cm_fields['A'], &objectlist, "ldap", DIRECTORY_ATTRIB_ADD);
- }
-
- /* Add a "calFBURL" attribute if a calendar free/busy URL exists */
- if (!IsEmptyStr(calFBURL)) {
- (void) CtdlDoDirectoryServiceFunc("calFBURL", calFBURL, &objectlist, "ldap", DIRECTORY_ATTRIB_ADD);
- }
-
- (void) CtdlDoDirectoryServiceFunc(msg->cm_fields['A'], msg->cm_fields['N'], &objectlist, "ldap", DIRECTORY_SAVE_OBJECT);
-
- (void) CtdlDoDirectoryServiceFunc(NULL, NULL, &objectlist, "ldap", DIRECTORY_FREE_OBJECT);
- lprintf(CTDL_DEBUG, "LDAP write operation complete.\n");
-}
-
-
-
-/*
- * Callback for vcard_add_to_directory()
- * (Lotsa ugly nested callbacks. Oh well.)
- */
-void vcard_directory_add_user(char *internet_addr, char *citadel_addr) {
- char buf[SIZ];
-
- /* We have to validate that we're not stepping on someone else's
- * email address ... but only if we're logged in. Otherwise it's
- * probably just the networker or something.
- */
- if (CC->logged_in) {
- lprintf(CTDL_DEBUG, "Checking for <%s>...\n", internet_addr);
- if (CtdlDirectoryLookup(buf, internet_addr, sizeof buf) == 0) {
- if (strcasecmp(buf, citadel_addr)) {
- /* This address belongs to someone else.
- * Bail out silently without saving.
- */
- lprintf(CTDL_DEBUG, "DOOP!\n");
- return;
- }
- }
- }
- lprintf(CTDL_INFO, "Adding %s (%s) to directory\n",
- citadel_addr, internet_addr);
- CtdlDirectoryAddUser(internet_addr, citadel_addr);
-}
-
-
-/*
- * Back end function for cmd_igab()
- */
-void vcard_add_to_directory(long msgnum, void *data) {
- struct CtdlMessage *msg;
-
- msg = CtdlFetchMessage(msgnum, 1);
- if (msg != NULL) {
- vcard_extract_internet_addresses(msg, vcard_directory_add_user);
- }
-
- ctdl_vcard_to_directory(msg, V2L_WRITE);
-
- CtdlFreeMessage(msg);
-}
-
-
-/*
- * Initialize Global Adress Book
- */
-void cmd_igab(char *argbuf) {
- char hold_rm[ROOMNAMELEN];
-
- if (CtdlAccessCheck(ac_aide)) return;
-
- strcpy(hold_rm, CC->room.QRname); /* save current room */
-
- if (getroom(&CC->room, ADDRESS_BOOK_ROOM) != 0) {
- getroom(&CC->room, hold_rm);
- cprintf("%d cannot get address book room\n", ERROR + ROOM_NOT_FOUND);
- return;
- }
-
- /* Empty the existing database first.
- */
- CtdlDirectoryInit();
-
- /* We want *all* vCards in this room */
- CtdlForEachMessage(MSGS_ALL, 0, NULL, "^[Tt][Ee][Xx][Tt]/.*[Vv][Cc][Aa][Rr][Dd]$",
- NULL, vcard_add_to_directory, NULL);
-
- getroom(&CC->room, hold_rm); /* return to saved room */
- cprintf("%d Directory has been rebuilt.\n", CIT_OK);
-}
-
-
-
-
-/*
- * 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_inet_email_addrs(char *emailaddrbuf, size_t emailaddrbuf_len,
- char *secemailaddrbuf, size_t secemailaddrbuf_len,
- struct vCard *v, int local_addrs_only) {
- char *s, *addr;
- int instance = 0;
- int saved_instance = 0;
-
- /* Go through the vCard searching for *all* instances of
- * the "email;internet" key
- */
- while (s = vcard_get_prop(v, "email;internet", 0, instance++, 0), s != NULL) {
- addr = strdup(s);
- striplt(addr);
- if (!IsEmptyStr(addr)) {
- if ( (IsDirectory(addr, 1)) ||
- (!local_addrs_only) ) {
- ++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);