diff options
This commit was manufactured by cvs2svn to create tag 'GDM2_2_4_4_0'.GDM2_2_4_4_0
svn path=/tags/GDM2_2_4_4_0/; revision=21592
Diffstat (limited to 'addressbook/backend')
86 files changed, 0 insertions, 32563 deletions
diff --git a/addressbook/backend/.cvsignore b/addressbook/backend/.cvsignore deleted file mode 100644 index 09980ae6ba..0000000000 --- a/addressbook/backend/.cvsignore +++ /dev/null @@ -1,6 +0,0 @@ -.deps -.libs -Makefile -Makefile.in -*.lo -*.la diff --git a/addressbook/backend/Makefile.am b/addressbook/backend/Makefile.am deleted file mode 100644 index b2807b2480..0000000000 --- a/addressbook/backend/Makefile.am +++ /dev/null @@ -1 +0,0 @@ -SUBDIRS = idl ebook pas diff --git a/addressbook/backend/ebook/.cvsignore b/addressbook/backend/ebook/.cvsignore deleted file mode 100644 index e3e9c805bb..0000000000 --- a/addressbook/backend/ebook/.cvsignore +++ /dev/null @@ -1,25 +0,0 @@ -.deps -.libs -.pure -Makefile -Makefile.in -*.lo -*.la -addressbook-stubs.c -addressbook-skels.c -addressbook-common.c -addressbook.h -test-card -test-client -test-client-list -load-pine-addressbook -load-gnomecard-addressbook -evolution-vcard-importer -evolution-gnomecard-importer -evolution-ldif-importer -GNOME_Evolution_Addressbook_VCard_Importer.server -GNOME_Evolution_Addressbook_LDIF_Importer.server -GNOME_Evolution_Addressbook_VCard_Importer.server.in -GNOME_Evolution_Addressbook_LDIF_Importer.server.in -e-book-marshal.c -e-book-marshal.h diff --git a/addressbook/backend/ebook/GNOME_Evolution_Addressbook_LDIF_Importer.server.in.in b/addressbook/backend/ebook/GNOME_Evolution_Addressbook_LDIF_Importer.server.in.in deleted file mode 100644 index 392220d119..0000000000 --- a/addressbook/backend/ebook/GNOME_Evolution_Addressbook_LDIF_Importer.server.in.in +++ /dev/null @@ -1,29 +0,0 @@ -<oaf_info> - -<oaf_server iid="OAFIID:GNOME_Evolution_Addressbook_LDIF_ImporterFactory" - type="exe" - location="@LIBEXECDIR@/evolution-ldif-importer"> - - <oaf_attribute name="repo_ids" type="stringv"> - <item value="IDL:GNOME/ObjectFactory:1.0"/> - </oaf_attribute> - - <oaf_attribute name="name" type="string" - _value="Evolution LDIF importer"/> -</oaf_server> - -<oaf_server iid="OAFIID:GNOME_Evolution_Addressbook_LDIF_Importer" - type="factory" - location="OAFIID:GNOME_Evolution_Addressbook_LDIF_ImporterFactory"> - - <oaf_attribute name="repo_ids" type="stringv"> - <item value="IDL:GNOME/Evolution/Importer:1.0"/> - </oaf_attribute> - - <oaf_attribute name="evolution:menu_name" type="string" - _value="LDAP Data Interchange Format (.ldif)"/> - <oaf_attribute name="name" type="string" - _value="Evolution LDIF importer"/> -</oaf_server> - -</oaf_info> diff --git a/addressbook/backend/ebook/GNOME_Evolution_Addressbook_VCard_Importer.server.in.in b/addressbook/backend/ebook/GNOME_Evolution_Addressbook_VCard_Importer.server.in.in deleted file mode 100644 index b630d31bec..0000000000 --- a/addressbook/backend/ebook/GNOME_Evolution_Addressbook_VCard_Importer.server.in.in +++ /dev/null @@ -1,29 +0,0 @@ -<oaf_info> - -<oaf_server iid="OAFIID:GNOME_Evolution_Addressbook_VCard_ImporterFactory" - type="exe" - location="@LIBEXECDIR@/evolution-vcard-importer"> - - <oaf_attribute name="repo_ids" type="stringv"> - <item value="IDL:GNOME/ObjectFactory:1.0"/> - </oaf_attribute> - - <oaf_attribute name="name" type="string" - _value="Evolution VCard importer"/> -</oaf_server> - -<oaf_server iid="OAFIID:GNOME_Evolution_Addressbook_VCard_Importer" - type="factory" - location="OAFIID:GNOME_Evolution_Addressbook_VCard_ImporterFactory"> - - <oaf_attribute name="repo_ids" type="stringv"> - <item value="IDL:GNOME/Evolution/Importer:1.0"/> - </oaf_attribute> - - <oaf_attribute name="evolution:menu_name" type="string" - _value="VCard (.vcf, .gcrd)"/> - <oaf_attribute name="name" type="string" - _value="Evolution VCard Importer"/> -</oaf_server> - -</oaf_info> diff --git a/addressbook/backend/ebook/Makefile.am b/addressbook/backend/ebook/Makefile.am deleted file mode 100644 index d79cd7abdc..0000000000 --- a/addressbook/backend/ebook/Makefile.am +++ /dev/null @@ -1,186 +0,0 @@ -noinst_PROGRAMS = test-card test-client test-client-list - -privlibexec_PROGRAMS = \ - evolution-vcard-importer \ - evolution-ldif-importer - -toolsdir = $(privlibexecdir)/ -tools_PROGRAMS = \ - load-pine-addressbook \ - load-gnomecard-addressbook - -# CORBA stuff - -CORBA_ADDRESSBOOK_SOURCE_H = \ - addressbook.h -CORBA_ADDRESSBOOK_SOURCE_C = \ - addressbook-common.c \ - addressbook-stubs.c \ - addressbook-skels.c -CORBA_ADDRESSBOOK_IDL = $(srcdir)/../idl/addressbook.idl - -$(CORBA_ADDRESSBOOK_SOURCE_H): $(CORBA_ADDRESSBOOK_IDL) - $(ORBIT_IDL) -I $(srcdir) $(IDL_INCLUDES) $(CORBA_ADDRESSBOOK_IDL) - -$(CORBA_ADDRESSBOOK_SOURCE_C): $(CORBA_ADDRESSBOOK_SOURCE_H) - -CORBA_SOURCE_H = $(CORBA_ADDRESSBOOK_SOURCE_H) -CORBA_SOURCE_C = $(CORBA_ADDRESSBOOK_SOURCE_C) -CORBA_SOURCE = $(CORBA_SOURCE_H) $(CORBA_SOURCE_C) - - -# The component - -INCLUDES = \ - -DPREFIX=\"$(prefix)\" \ - -DSYSCONFDIR=\"$(sysconfdir)\" \ - -DDATADIR=\"$(datadir)\" \ - -DLIBDIR=\"$(libdir)\" \ - -DG_LOG_DOMAIN=\"EBook\" \ - -I$(top_srcdir) \ - -I$(top_srcdir)/camel \ - -I$(top_srcdir)/addressbook/backend \ - -I$(top_srcdir)/addressbook/ename \ - -I$(top_builddir)/addressbook/backend \ - -I$(top_builddir)/addressbook/ename \ - -I$(top_builddir)/shell \ - -I$(top_srcdir)/shell \ - -DG_DISABLE_DEPRECATED \ - -DLIBGNOME_DISABLE_DEPRECATED \ - $(EVOLUTION_ADDRESSBOOK_CFLAGS) - -privlib_LTLIBRARIES = libebook.la libebook-static.la - -# Make sure the libraries are not built in parallel when using a parallel make; -# libtool can't handle that. -libebook_static_la_DEPENDENCIES = libebook.la - -libebook_la_SOURCES = \ - $(CORBA_SOURCE) \ - e-book-listener.c \ - e-book-marshal.c \ - e-book-view-listener.c \ - e-book-view.c \ - e-book.c \ - e-book-util.c \ - e-card-cursor.c \ - e-card-simple.c \ - e-card.c \ - e-card-compare.c \ - e-destination.c - -libebook_la_LIBADD = \ - $(top_builddir)/libversit/libversit.la \ - $(top_builddir)/camel/libcamel.la \ - $(top_builddir)/e-util/ename/libename.la \ - $(top_builddir)/e-util/libeutil.la - -libebookincludedir = $(privincludedir)/ebook - -libebookinclude_HEADERS = \ - e-book-listener.h \ - e-book-types.h \ - e-book-view-listener.h \ - e-book-view.h \ - e-book.h \ - e-book-util.h \ - e-card-cursor.h \ - e-card-simple.h \ - e-card-types.h \ - e-card.h \ - e-card-compare.h \ - e-destination.h \ - addressbook.h - - -# -# make a static library for use by addressbook's conduit's shared library -# -libebook_static_la_SOURCES = $(libebook_la_SOURCES) -libebook_static_la_LDFLAGS = -all-static - -# GLib marshalling cruft - -e-book-marshal.h: e-book-marshal.list - ( @GLIB_GENMARSHAL@ --prefix=e_book_marshal e-book-marshal.list --header > e-book-marshal.h.tmp \ - && mv e-book-marshal.h.tmp e-book-marshal.h ) \ - || ( rm -f e-book-marshal.h.tmp && exit 1 ) - -e-book-marshal.c: e-book-marshal.h - ( @GLIB_GENMARSHAL@ --prefix=e_book_marshal e-book-marshal.list --body > e-book-marshal.c.tmp \ - && mv e-book-marshal.c.tmp e-book-marshal.c ) \ - || ( rm -f e-book-marshal.c.tmp && exit 1 ) - -MARSHAL_GENERATED = e-book-marshal.c e-book-marshal.h - -test_client_SOURCES = \ - test-client.c - -test_client_LDADD = \ - libebook.la \ - $(EVOLUTION_ADDRESSBOOK_LIBS) - -test_client_list_SOURCES = \ - test-client-list.c - -test_client_list_LDADD = \ - libebook.la \ - $(EVOLUTION_ADDRESSBOOK_LIBS) - -test_card_SOURCES = \ - test-card.c - -test_card_LDADD = \ - libebook.la \ - $(EVOLUTION_ADDRESSBOOK_LIBS) - -evolution_vcard_importer_SOURCES = \ - evolution-vcard-importer.c - -evolution_vcard_importer_LDADD = \ - libebook.la \ - $(EVOLUTION_ADDRESSBOOK_LIBS) \ - $(top_builddir)/shell/importer/libevolution-importer.la \ - $(DB3_LDADD) - -evolution_ldif_importer_SOURCES = \ - evolution-ldif-importer.c - -evolution_ldif_importer_LDADD = \ - libebook.la \ - $(EVOLUTION_ADDRESSBOOK_LIBS) \ - $(top_builddir)/shell/importer/libevolution-importer.la \ - $(DB3_LDADD) - -load_pine_addressbook_SOURCES = \ - load-pine-addressbook.c - -load_pine_addressbook_LDADD = \ - libebook.la \ - $(EVOLUTION_ADDRESSBOOK_LIBS) - -load_gnomecard_addressbook_SOURCES = \ - load-gnomecard-addressbook.c - -load_gnomecard_addressbook_LDADD = \ - libebook.la \ - $(EVOLUTION_ADDRESSBOOK_LIBS) - - -BUILT_SOURCES = $(CORBA_SOURCE) $(MARSHAL_GENERATED) $(server_DATA) -CLEANFILES = $(BUILT_SOURCES) - -dist-hook: - cd $(distdir); rm -f $(BUILT_SOURCES) - -server_in_files = GNOME_Evolution_Addressbook_VCard_Importer.server.in.in \ - GNOME_Evolution_Addressbook_LDIF_Importer.server.in.in - -server_DATA = $(server_in_files:.server.in.in=.server) -%.server.in: %.server.in.in - sed -e "s|\@LIBEXECDIR\@|$(privlibexecdir)|" $< > $@ - - -@INTLTOOL_SERVER_RULE@ - -EXTRA_DIST = $(server_in_files) $(server_DATA) e-book-marshal.list diff --git a/addressbook/backend/ebook/TODO b/addressbook/backend/ebook/TODO deleted file mode 100644 index a69703cd92..0000000000 --- a/addressbook/backend/ebook/TODO +++ /dev/null @@ -1,2 +0,0 @@ -* Make sure open_book_progress does not use the EBook op queue; make - sure it works. diff --git a/addressbook/backend/ebook/docs/rfc2047.txt b/addressbook/backend/ebook/docs/rfc2047.txt deleted file mode 100644 index ff9a744bf3..0000000000 --- a/addressbook/backend/ebook/docs/rfc2047.txt +++ /dev/null @@ -1,843 +0,0 @@ - - - - - - -Network Working Group K. Moore -Request for Comments: 2047 University of Tennessee -Obsoletes: 1521, 1522, 1590 November 1996 -Category: Standards Track - - - MIME (Multipurpose Internet Mail Extensions) Part Three: - Message Header Extensions for Non-ASCII Text - -Status of this Memo - - This document specifies an Internet standards track protocol for the - Internet community, and requests discussion and suggestions for - improvements. Please refer to the current edition of the "Internet - Official Protocol Standards" (STD 1) for the standardization state - and status of this protocol. Distribution of this memo is unlimited. - -Abstract - - STD 11, RFC 822, defines a message representation protocol specifying - considerable detail about US-ASCII message headers, and leaves the - message content, or message body, as flat US-ASCII text. This set of - documents, collectively called the Multipurpose Internet Mail - Extensions, or MIME, redefines the format of messages to allow for - - (1) textual message bodies in character sets other than US-ASCII, - - (2) an extensible set of different formats for non-textual message - bodies, - - (3) multi-part message bodies, and - - (4) textual header information in character sets other than US-ASCII. - - These documents are based on earlier work documented in RFC 934, STD - 11, and RFC 1049, but extends and revises them. Because RFC 822 said - so little about message bodies, these documents are largely - orthogonal to (rather than a revision of) RFC 822. - - This particular document is the third document in the series. It - describes extensions to RFC 822 to allow non-US-ASCII text data in - Internet mail header fields. - - - - - - - - - -Moore Standards Track [Page 1] - -RFC 2047 Message Header Extensions November 1996 - - - Other documents in this series include: - - + RFC 2045, which specifies the various headers used to describe - the structure of MIME messages. - - + RFC 2046, which defines the general structure of the MIME media - typing system and defines an initial set of media types, - - + RFC 2048, which specifies various IANA registration procedures - for MIME-related facilities, and - - + RFC 2049, which describes MIME conformance criteria and - provides some illustrative examples of MIME message formats, - acknowledgements, and the bibliography. - - These documents are revisions of RFCs 1521, 1522, and 1590, which - themselves were revisions of RFCs 1341 and 1342. An appendix in RFC - 2049 describes differences and changes from previous versions. - -1. Introduction - - RFC 2045 describes a mechanism for denoting textual body parts which - are coded in various character sets, as well as methods for encoding - such body parts as sequences of printable US-ASCII characters. This - memo describes similar techniques to allow the encoding of non-ASCII - text in various portions of a RFC 822 [2] message header, in a manner - which is unlikely to confuse existing message handling software. - - Like the encoding techniques described in RFC 2045, the techniques - outlined here were designed to allow the use of non-ASCII characters - in message headers in a way which is unlikely to be disturbed by the - quirks of existing Internet mail handling programs. In particular, - some mail relaying programs are known to (a) delete some message - header fields while retaining others, (b) rearrange the order of - addresses in To or Cc fields, (c) rearrange the (vertical) order of - header fields, and/or (d) "wrap" message headers at different places - than those in the original message. In addition, some mail reading - programs are known to have difficulty correctly parsing message - headers which, while legal according to RFC 822, make use of - backslash-quoting to "hide" special characters such as "<", ",", or - ":", or which exploit other infrequently-used features of that - specification. - - While it is unfortunate that these programs do not correctly - interpret RFC 822 headers, to "break" these programs would cause - severe operational problems for the Internet mail system. The - extensions described in this memo therefore do not rely on little- - used features of RFC 822. - - - -Moore Standards Track [Page 2] - -RFC 2047 Message Header Extensions November 1996 - - - Instead, certain sequences of "ordinary" printable ASCII characters - (known as "encoded-words") are reserved for use as encoded data. The - syntax of encoded-words is such that they are unlikely to - "accidentally" appear as normal text in message headers. - Furthermore, the characters used in encoded-words are restricted to - those which do not have special meanings in the context in which the - encoded-word appears. - - Generally, an "encoded-word" is a sequence of printable ASCII - characters that begins with "=?", ends with "?=", and has two "?"s in - between. It specifies a character set and an encoding method, and - also includes the original text encoded as graphic ASCII characters, - according to the rules for that encoding method. - - A mail composer that implements this specification will provide a - means of inputting non-ASCII text in header fields, but will - translate these fields (or appropriate portions of these fields) into - encoded-words before inserting them into the message header. - - A mail reader that implements this specification will recognize - encoded-words when they appear in certain portions of the message - header. Instead of displaying the encoded-word "as is", it will - reverse the encoding and display the original text in the designated - character set. - -NOTES - - This memo relies heavily on notation and terms defined RFC 822 and - RFC 2045. In particular, the syntax for the ABNF used in this memo - is defined in RFC 822, as well as many of the terminal or nonterminal - symbols from RFC 822 are used in the grammar for the header - extensions defined here. Among the symbols defined in RFC 822 and - referenced in this memo are: 'addr-spec', 'atom', 'CHAR', 'comment', - 'CTLs', 'ctext', 'linear-white-space', 'phrase', 'quoted-pair'. - 'quoted-string', 'SPACE', and 'word'. Successful implementation of - this protocol extension requires careful attention to the RFC 822 - definitions of these terms. - - When the term "ASCII" appears in this memo, it refers to the "7-Bit - American Standard Code for Information Interchange", ANSI X3.4-1986. - The MIME charset name for this character set is "US-ASCII". When not - specifically referring to the MIME charset name, this document uses - the term "ASCII", both for brevity and for consistency with RFC 822. - However, implementors are warned that the character set name must be - spelled "US-ASCII" in MIME message and body part headers. - - - - - - -Moore Standards Track [Page 3] - -RFC 2047 Message Header Extensions November 1996 - - - This memo specifies a protocol for the representation of non-ASCII - text in message headers. It specifically DOES NOT define any - translation between "8-bit headers" and pure ASCII headers, nor is - any such translation assumed to be possible. - -2. Syntax of encoded-words - - An 'encoded-word' is defined by the following ABNF grammar. The - notation of RFC 822 is used, with the exception that white space - characters MUST NOT appear between components of an 'encoded-word'. - - encoded-word = "=?" charset "?" encoding "?" encoded-text "?=" - - charset = token ; see section 3 - - encoding = token ; see section 4 - - token = 1*<Any CHAR except SPACE, CTLs, and especials> - - especials = "(" / ")" / "<" / ">" / "@" / "," / ";" / ":" / " - <"> / "/" / "[" / "]" / "?" / "." / "=" - - encoded-text = 1*<Any printable ASCII character other than "?" - or SPACE> - ; (but see "Use of encoded-words in message - ; headers", section 5) - - Both 'encoding' and 'charset' names are case-independent. Thus the - charset name "ISO-8859-1" is equivalent to "iso-8859-1", and the - encoding named "Q" may be spelled either "Q" or "q". - - An 'encoded-word' may not be more than 75 characters long, including - 'charset', 'encoding', 'encoded-text', and delimiters. If it is - desirable to encode more text than will fit in an 'encoded-word' of - 75 characters, multiple 'encoded-word's (separated by CRLF SPACE) may - be used. - - While there is no limit to the length of a multiple-line header - field, each line of a header field that contains one or more - 'encoded-word's is limited to 76 characters. - - The length restrictions are included both to ease interoperability - through internetwork mail gateways, and to impose a limit on the - amount of lookahead a header parser must employ (while looking for a - final ?= delimiter) before it can decide whether a token is an - "encoded-word" or something else. - - - - - -Moore Standards Track [Page 4] - -RFC 2047 Message Header Extensions November 1996 - - - IMPORTANT: 'encoded-word's are designed to be recognized as 'atom's - by an RFC 822 parser. As a consequence, unencoded white space - characters (such as SPACE and HTAB) are FORBIDDEN within an - 'encoded-word'. For example, the character sequence - - =?iso-8859-1?q?this is some text?= - - would be parsed as four 'atom's, rather than as a single 'atom' (by - an RFC 822 parser) or 'encoded-word' (by a parser which understands - 'encoded-words'). The correct way to encode the string "this is some - text" is to encode the SPACE characters as well, e.g. - - =?iso-8859-1?q?this=20is=20some=20text?= - - The characters which may appear in 'encoded-text' are further - restricted by the rules in section 5. - -3. Character sets - - The 'charset' portion of an 'encoded-word' specifies the character - set associated with the unencoded text. A 'charset' can be any of - the character set names allowed in an MIME "charset" parameter of a - "text/plain" body part, or any character set name registered with - IANA for use with the MIME text/plain content-type. - - Some character sets use code-switching techniques to switch between - "ASCII mode" and other modes. If unencoded text in an 'encoded-word' - contains a sequence which causes the charset interpreter to switch - out of ASCII mode, it MUST contain additional control codes such that - ASCII mode is again selected at the end of the 'encoded-word'. (This - rule applies separately to each 'encoded-word', including adjacent - 'encoded-word's within a single header field.) - - When there is a possibility of using more than one character set to - represent the text in an 'encoded-word', and in the absence of - private agreements between sender and recipients of a message, it is - recommended that members of the ISO-8859-* series be used in - preference to other character sets. - -4. Encodings - - Initially, the legal values for "encoding" are "Q" and "B". These - encodings are described below. The "Q" encoding is recommended for - use when most of the characters to be encoded are in the ASCII - character set; otherwise, the "B" encoding should be used. - Nevertheless, a mail reader which claims to recognize 'encoded-word's - MUST be able to accept either encoding for any character set which it - supports. - - - -Moore Standards Track [Page 5] - -RFC 2047 Message Header Extensions November 1996 - - - Only a subset of the printable ASCII characters may be used in - 'encoded-text'. Space and tab characters are not allowed, so that - the beginning and end of an 'encoded-word' are obvious. The "?" - character is used within an 'encoded-word' to separate the various - portions of the 'encoded-word' from one another, and thus cannot - appear in the 'encoded-text' portion. Other characters are also - illegal in certain contexts. For example, an 'encoded-word' in a - 'phrase' preceding an address in a From header field may not contain - any of the "specials" defined in RFC 822. Finally, certain other - characters are disallowed in some contexts, to ensure reliability for - messages that pass through internetwork mail gateways. - - The "B" encoding automatically meets these requirements. The "Q" - encoding allows a wide range of printable characters to be used in - non-critical locations in the message header (e.g., Subject), with - fewer characters available for use in other locations. - -4.1. The "B" encoding - - The "B" encoding is identical to the "BASE64" encoding defined by RFC - 2045. - -4.2. The "Q" encoding - - The "Q" encoding is similar to the "Quoted-Printable" content- - transfer-encoding defined in RFC 2045. It is designed to allow text - containing mostly ASCII characters to be decipherable on an ASCII - terminal without decoding. - - (1) Any 8-bit value may be represented by a "=" followed by two - hexadecimal digits. For example, if the character set in use - were ISO-8859-1, the "=" character would thus be encoded as - "=3D", and a SPACE by "=20". (Upper case should be used for - hexadecimal digits "A" through "F".) - - (2) The 8-bit hexadecimal value 20 (e.g., ISO-8859-1 SPACE) may be - represented as "_" (underscore, ASCII 95.). (This character may - not pass through some internetwork mail gateways, but its use - will greatly enhance readability of "Q" encoded data with mail - readers that do not support this encoding.) Note that the "_" - always represents hexadecimal 20, even if the SPACE character - occupies a different code position in the character set in use. - - (3) 8-bit values which correspond to printable ASCII characters other - than "=", "?", and "_" (underscore), MAY be represented as those - characters. (But see section 5 for restrictions.) In - particular, SPACE and TAB MUST NOT be represented as themselves - within encoded words. - - - -Moore Standards Track [Page 6] - -RFC 2047 Message Header Extensions November 1996 - - -5. Use of encoded-words in message headers - - An 'encoded-word' may appear in a message header or body part header - according to the following rules: - -(1) An 'encoded-word' may replace a 'text' token (as defined by RFC 822) - in any Subject or Comments header field, any extension message - header field, or any MIME body part field for which the field body - is defined as '*text'. An 'encoded-word' may also appear in any - user-defined ("X-") message or body part header field. - - Ordinary ASCII text and 'encoded-word's may appear together in the - same header field. However, an 'encoded-word' that appears in a - header field defined as '*text' MUST be separated from any adjacent - 'encoded-word' or 'text' by 'linear-white-space'. - -(2) An 'encoded-word' may appear within a 'comment' delimited by "(" and - ")", i.e., wherever a 'ctext' is allowed. More precisely, the RFC - 822 ABNF definition for 'comment' is amended as follows: - - comment = "(" *(ctext / quoted-pair / comment / encoded-word) ")" - - A "Q"-encoded 'encoded-word' which appears in a 'comment' MUST NOT - contain the characters "(", ")" or " - 'encoded-word' that appears in a 'comment' MUST be separated from - any adjacent 'encoded-word' or 'ctext' by 'linear-white-space'. - - It is important to note that 'comment's are only recognized inside - "structured" field bodies. In fields whose bodies are defined as - '*text', "(" and ")" are treated as ordinary characters rather than - comment delimiters, and rule (1) of this section applies. (See RFC - 822, sections 3.1.2 and 3.1.3) - -(3) As a replacement for a 'word' entity within a 'phrase', for example, - one that precedes an address in a From, To, or Cc header. The ABNF - definition for 'phrase' from RFC 822 thus becomes: - - phrase = 1*( encoded-word / word ) - - In this case the set of characters that may be used in a "Q"-encoded - 'encoded-word' is restricted to: <upper and lower case ASCII - letters, decimal digits, "!", "*", "+", "-", "/", "=", and "_" - (underscore, ASCII 95.)>. An 'encoded-word' that appears within a - 'phrase' MUST be separated from any adjacent 'word', 'text' or - 'special' by 'linear-white-space'. - - - - - - -Moore Standards Track [Page 7] - -RFC 2047 Message Header Extensions November 1996 - - - These are the ONLY locations where an 'encoded-word' may appear. In - particular: - - + An 'encoded-word' MUST NOT appear in any portion of an 'addr-spec'. - - + An 'encoded-word' MUST NOT appear within a 'quoted-string'. - - + An 'encoded-word' MUST NOT be used in a Received header field. - - + An 'encoded-word' MUST NOT be used in parameter of a MIME - Content-Type or Content-Disposition field, or in any structured - field body except within a 'comment' or 'phrase'. - - The 'encoded-text' in an 'encoded-word' must be self-contained; - 'encoded-text' MUST NOT be continued from one 'encoded-word' to - another. This implies that the 'encoded-text' portion of a "B" - 'encoded-word' will be a multiple of 4 characters long; for a "Q" - 'encoded-word', any "=" character that appears in the 'encoded-text' - portion will be followed by two hexadecimal characters. - - Each 'encoded-word' MUST encode an integral number of octets. The - 'encoded-text' in each 'encoded-word' must be well-formed according - to the encoding specified; the 'encoded-text' may not be continued in - the next 'encoded-word'. (For example, "=?charset?Q?=?= - =?charset?Q?AB?=" would be illegal, because the two hex digits "AB" - must follow the "=" in the same 'encoded-word'.) - - Each 'encoded-word' MUST represent an integral number of characters. - A multi-octet character may not be split across adjacent 'encoded- - word's. - - Only printable and white space character data should be encoded using - this scheme. However, since these encoding schemes allow the - encoding of arbitrary octet values, mail readers that implement this - decoding should also ensure that display of the decoded data on the - recipient's terminal will not cause unwanted side-effects. - - Use of these methods to encode non-textual data (e.g., pictures or - sounds) is not defined by this memo. Use of 'encoded-word's to - represent strings of purely ASCII characters is allowed, but - discouraged. In rare cases it may be necessary to encode ordinary - text that looks like an 'encoded-word'. - - - - - - - - - -Moore Standards Track [Page 8] - -RFC 2047 Message Header Extensions November 1996 - - -6. Support of 'encoded-word's by mail readers - -6.1. Recognition of 'encoded-word's in message headers - - A mail reader must parse the message and body part headers according - to the rules in RFC 822 to correctly recognize 'encoded-word's. - - 'encoded-word's are to be recognized as follows: - - (1) Any message or body part header field defined as '*text', or any - user-defined header field, should be parsed as follows: Beginning - at the start of the field-body and immediately following each - occurrence of 'linear-white-space', each sequence of up to 75 - printable characters (not containing any 'linear-white-space') - should be examined to see if it is an 'encoded-word' according to - the syntax rules in section 2. Any other sequence of printable - characters should be treated as ordinary ASCII text. - - (2) Any header field not defined as '*text' should be parsed - according to the syntax rules for that header field. However, - any 'word' that appears within a 'phrase' should be treated as an - 'encoded-word' if it meets the syntax rules in section 2. - Otherwise it should be treated as an ordinary 'word'. - - (3) Within a 'comment', any sequence of up to 75 printable characters - (not containing 'linear-white-space'), that meets the syntax - rules in section 2, should be treated as an 'encoded-word'. - Otherwise it should be treated as normal comment text. - - (4) A MIME-Version header field is NOT required to be present for - 'encoded-word's to be interpreted according to this - specification. One reason for this is that the mail reader is - not expected to parse the entire message header before displaying - lines that may contain 'encoded-word's. - -6.2. Display of 'encoded-word's - - Any 'encoded-word's so recognized are decoded, and if possible, the - resulting unencoded text is displayed in the original character set. - - NOTE: Decoding and display of encoded-words occurs *after* a - structured field body is parsed into tokens. It is therefore - possible to hide 'special' characters in encoded-words which, when - displayed, will be indistinguishable from 'special' characters in the - surrounding text. For this and other reasons, it is NOT generally - possible to translate a message header containing 'encoded-word's to - an unencoded form which can be parsed by an RFC 822 mail reader. - - - - -Moore Standards Track [Page 9] - -RFC 2047 Message Header Extensions November 1996 - - - When displaying a particular header field that contains multiple - 'encoded-word's, any 'linear-white-space' that separates a pair of - adjacent 'encoded-word's is ignored. (This is to allow the use of - multiple 'encoded-word's to represent long strings of unencoded text, - without having to separate 'encoded-word's where spaces occur in the - unencoded text.) - - In the event other encodings are defined in the future, and the mail - reader does not support the encoding used, it may either (a) display - the 'encoded-word' as ordinary text, or (b) substitute an appropriate - message indicating that the text could not be decoded. - - If the mail reader does not support the character set used, it may - (a) display the 'encoded-word' as ordinary text (i.e., as it appears - in the header), (b) make a "best effort" to display using such - characters as are available, or (c) substitute an appropriate message - indicating that the decoded text could not be displayed. - - If the character set being used employs code-switching techniques, - display of the encoded text implicitly begins in "ASCII mode". In - addition, the mail reader must ensure that the output device is once - again in "ASCII mode" after the 'encoded-word' is displayed. - -6.3. Mail reader handling of incorrectly formed 'encoded-word's - - It is possible that an 'encoded-word' that is legal according to the - syntax defined in section 2, is incorrectly formed according to the - rules for the encoding being used. For example: - - (1) An 'encoded-word' which contains characters which are not legal - for a particular encoding (for example, a "-" in the "B" - encoding, or a SPACE or HTAB in either the "B" or "Q" encoding), - is incorrectly formed. - - (2) Any 'encoded-word' which encodes a non-integral number of - characters or octets is incorrectly formed. - - A mail reader need not attempt to display the text associated with an - 'encoded-word' that is incorrectly formed. However, a mail reader - MUST NOT prevent the display or handling of a message because an - 'encoded-word' is incorrectly formed. - -7. Conformance - - A mail composing program claiming compliance with this specification - MUST ensure that any string of non-white-space printable ASCII - characters within a '*text' or '*ctext' that begins with "=?" and - ends with "?=" be a valid 'encoded-word'. ("begins" means: at the - - - -Moore Standards Track [Page 10] - -RFC 2047 Message Header Extensions November 1996 - - - start of the field-body, immediately following 'linear-white-space', - or immediately following a "(" for an 'encoded-word' within '*ctext'; - "ends" means: at the end of the field-body, immediately preceding - 'linear-white-space', or immediately preceding a ")" for an - 'encoded-word' within '*ctext'.) In addition, any 'word' within a - 'phrase' that begins with "=?" and ends with "?=" must be a valid - 'encoded-word'. - - A mail reading program claiming compliance with this specification - must be able to distinguish 'encoded-word's from 'text', 'ctext', or - 'word's, according to the rules in section 6, anytime they appear in - appropriate places in message headers. It must support both the "B" - and "Q" encodings for any character set which it supports. The - program must be able to display the unencoded text if the character - set is "US-ASCII". For the ISO-8859-* character sets, the mail - reading program must at least be able to display the characters which - are also in the ASCII set. - -8. Examples - - The following are examples of message headers containing 'encoded- - word's: - - From: =?US-ASCII?Q?Keith_Moore?= <moore@cs.utk.edu> - To: =?ISO-8859-1?Q?Keld_J=F8rn_Simonsen?= <keld@dkuug.dk> - CC: =?ISO-8859-1?Q?Andr=E9?= Pirard <PIRARD@vm1.ulg.ac.be> - Subject: =?ISO-8859-1?B?SWYgeW91IGNhbiByZWFkIHRoaXMgeW8=?= - =?ISO-8859-2?B?dSB1bmRlcnN0YW5kIHRoZSBleGFtcGxlLg==?= - - Note: In the first 'encoded-word' of the Subject field above, the - last "=" at the end of the 'encoded-text' is necessary because each - 'encoded-word' must be self-contained (the "=" character completes a - group of 4 base64 characters representing 2 octets). An additional - octet could have been encoded in the first 'encoded-word' (so that - the encoded-word would contain an exact multiple of 3 encoded - octets), except that the second 'encoded-word' uses a different - 'charset' than the first one. - - From: =?ISO-8859-1?Q?Olle_J=E4rnefors?= <ojarnef@admin.kth.se> - To: ietf-822@dimacs.rutgers.edu, ojarnef@admin.kth.se - Subject: Time for ISO 10646? - - To: Dave Crocker <dcrocker@mordor.stanford.edu> - Cc: ietf-822@dimacs.rutgers.edu, paf@comsol.se - From: =?ISO-8859-1?Q?Patrik_F=E4ltstr=F6m?= <paf@nada.kth.se> - Subject: Re: RFC-HDR care and feeding - - - - - -Moore Standards Track [Page 11] - -RFC 2047 Message Header Extensions November 1996 - - - From: Nathaniel Borenstein <nsb@thumper.bellcore.com> - (=?iso-8859-8?b?7eXs+SDv4SDp7Oj08A==?=) - To: Greg Vaudreuil <gvaudre@NRI.Reston.VA.US>, Ned Freed - <ned@innosoft.com>, Keith Moore <moore@cs.utk.edu> - Subject: Test of new header generator - MIME-Version: 1.0 - Content-type: text/plain; charset=ISO-8859-1 - - The following examples illustrate how text containing 'encoded-word's - which appear in a structured field body. The rules are slightly - different for fields defined as '*text' because "(" and ")" are not - recognized as 'comment' delimiters. [Section 5, paragraph (1)]. - - In each of the following examples, if the same sequence were to occur - in a '*text' field, the "displayed as" form would NOT be treated as - encoded words, but be identical to the "encoded form". This is - because each of the encoded-words in the following examples is - adjacent to a "(" or ")" character. - - encoded form displayed as - --------------------------------------------------------------------- - (=?ISO-8859-1?Q?a?=) (a) - - (=?ISO-8859-1?Q?a?= b) (a b) - - Within a 'comment', white space MUST appear between an - 'encoded-word' and surrounding text. [Section 5, - paragraph (2)]. However, white space is not needed between - the initial "(" that begins the 'comment', and the - 'encoded-word'. - - - (=?ISO-8859-1?Q?a?= =?ISO-8859-1?Q?b?=) (ab) - - White space between adjacent 'encoded-word's is not - displayed. - - (=?ISO-8859-1?Q?a?= =?ISO-8859-1?Q?b?=) (ab) - - Even multiple SPACEs between 'encoded-word's are ignored - for the purpose of display. - - (=?ISO-8859-1?Q?a?= (ab) - =?ISO-8859-1?Q?b?=) - - Any amount of linear-space-white between 'encoded-word's, - even if it includes a CRLF followed by one or more SPACEs, - is ignored for the purposes of display. - - - -Moore Standards Track [Page 12] - -RFC 2047 Message Header Extensions November 1996 - - - (=?ISO-8859-1?Q?a_b?=) (a b) - - In order to cause a SPACE to be displayed within a portion - of encoded text, the SPACE MUST be encoded as part of the - 'encoded-word'. - - (=?ISO-8859-1?Q?a?= =?ISO-8859-2?Q?_b?=) (a b) - - In order to cause a SPACE to be displayed between two strings - of encoded text, the SPACE MAY be encoded as part of one of - the 'encoded-word's. - -9. References - - [RFC 822] Crocker, D., "Standard for the Format of ARPA Internet Text - Messages", STD 11, RFC 822, UDEL, August 1982. - - [RFC 2049] Borenstein, N., and N. Freed, "Multipurpose Internet Mail - Extensions (MIME) Part Five: Conformance Criteria and Examples", - RFC 2049, November 1996. - - [RFC 2045] Borenstein, N., and N. Freed, "Multipurpose Internet Mail - Extensions (MIME) Part One: Format of Internet Message Bodies", - RFC 2045, November 1996. - - [RFC 2046] Borenstein N., and N. Freed, "Multipurpose Internet Mail - Extensions (MIME) Part Two: Media Types", RFC 2046, - November 1996. - - [RFC 2048] Freed, N., Klensin, J., and J. Postel, "Multipurpose - Internet Mail Extensions (MIME) Part Four: Registration - Procedures", RFC 2048, November 1996. - - - - - - - - - - - - - - - - - - - -Moore Standards Track [Page 13] - -RFC 2047 Message Header Extensions November 1996 - - -10. Security Considerations - - Security issues are not discussed in this memo. - -11. Acknowledgements - - The author wishes to thank Nathaniel Borenstein, Issac Chan, Lutz - Donnerhacke, Paul Eggert, Ned Freed, Andreas M. Kirchwitz, Olle - Jarnefors, Mike Rosin, Yutaka Sato, Bart Schaefer, and Kazuhiko - Yamamoto, for their helpful advice, insightful comments, and - illuminating questions in response to earlier versions of this - specification. - -12. Author's Address - - Keith Moore - University of Tennessee - 107 Ayres Hall - Knoxville TN 37996-1301 - - EMail: moore@cs.utk.edu - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Moore Standards Track [Page 14] - -RFC 2047 Message Header Extensions November 1996 - - -Appendix - changes since RFC 1522 (in no particular order) - - + explicitly state that the MIME-Version is not requried to use - 'encoded-word's. - - + add explicit note that SPACEs and TABs are not allowed within - 'encoded-word's, explaining that an 'encoded-word' must look like an - 'atom' to an RFC822 parser.values, to be precise). - - + add examples from Olle Jarnefors (thanks!) which illustrate how - encoded-words with adjacent linear-white-space are displayed. - - + explicitly list terms defined in RFC822 and referenced in this memo - - + fix transcription typos that caused one or two lines and a couple of - characters to disappear in the resulting text, due to nroff quirks. - - + clarify that encoded-words are allowed in '*text' fields in both - RFC822 headers and MIME body part headers, but NOT as parameter - values. - - + clarify the requirement to switch back to ASCII within the encoded - portion of an 'encoded-word', for any charset that uses code switching - sequences. - - + add a note about 'encoded-word's being delimited by "(" and ")" - within a comment, but not in a *text (how bizarre!). - - + fix the Andre Pirard example to get rid of the trailing "_" after - the =E9. (no longer needed post-1342). - - + clarification: an 'encoded-word' may appear immediately following - the initial "(" or immediately before the final ")" that delimits a - comment, not just adjacent to "(" and ")" *within* *ctext. - - + add a note to explain that a "B" 'encoded-word' will always have a - multiple of 4 characters in the 'encoded-text' portion. - - + add note about the "=" in the examples - - + note that processing of 'encoded-word's occurs *after* parsing, and - some of the implications thereof. - - + explicitly state that you can't expect to translate between - 1522 and either vanilla 822 or so-called "8-bit headers". - - + explicitly state that 'encoded-word's are not valid within a - 'quoted-string'. - - - -Moore Standards Track [Page 15] - diff --git a/addressbook/backend/ebook/docs/rfc2425.txt b/addressbook/backend/ebook/docs/rfc2425.txt deleted file mode 100644 index 30fed9bc07..0000000000 --- a/addressbook/backend/ebook/docs/rfc2425.txt +++ /dev/null @@ -1,1851 +0,0 @@ - - - - - - -Network Working Group T. Howes -Request for Comments: 2425 M. Smith -Category: Standards Track Netscape Communications Corp. - F. Dawson - Lotus Development Corporation - September 1998 - - - A MIME Content-Type for Directory Information - -Status of this Memo - - This document specifies an Internet standards track protocol for the - Internet community, and requests discussion and suggestions for - improvements. Please refer to the current edition of the "Internet - Official Protocol Standards" (STD 1) for the standardization state - and status of this protocol. Distribution of this memo is unlimited. - -Copyright Notice - - Copyright (C) The Internet Society (1998). All Rights Reserved. - -1. Abstract - - This document defines a MIME Content-Type for holding directory - information. The definition is independent of any particular - directory service or protocol. The text/directory Content-Type is - defined for holding a variety of directory information, for example, - name, or email address, or logo. The text/directory Content-Type can - also be used as the root body part in a multipart/related Content- - Type for handling more complicated situations, especially those in - which non-textual information that already has a natural MIME - representation, for example, a photograph or sound, is to be - represented. - - The text/directory Content-Type defines a general framework and - format for holding directory information in a simple "type:value" - form. We refer to "type" in this context meaning a property or - attribute with which the value is associated. Mechanisms are defined - to specify alternate languages, encodings and other meta-information. - This document also defines the procedure by which particular formats, - called profiles, for carrying application-specific information within - a text/directory Content-Type can be defined and registered, and the - conventions such formats must follow. It is expected that other - documents will be produced that define such formats for various - applications (e.g., white pages). - - - - - -Howes, et. al. Standards Track [Page 1] - -RFC 2425 MIME Content-Type for Directory Information September 1998 - - - The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", - "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY" and "OPTIONAL" in this - document are to be interpreted as described in [RFC-2119]. - -2. Table of Contents - - Status of the Memo................................................ 1 - Copyright Notice.................................................. 1 - 1. Abstract...................................................... 1 - 2. Table of Contents............................................. 2 - 3. Need for a MIME Directory Type................................ 3 - 4. Overview...................................................... 4 - 5. The text/directory Content-Type............................... 4 - 5.1. MIME media type name........................................ 4 - 5.2. MIME subtype name........................................... 5 - 5.3. Required parameters......................................... 5 - 5.4. Optional parameters......................................... 5 - 5.5. Encoding considerations..................................... 5 - 5.6. Security considerations..................................... 6 - 5.7. Interoperability considerations............................. 6 - 5.8. Published specification..................................... 6 - 5.8.1. Line delimiting and folding............................... 6 - 5.8.2. ABNF content-type definition.............................. 7 - 5.8.3. Pre-defined Parameters.................................... 9 - 5.8.4. Pre-defined Value Types...................................11 - 5.9. Applications which use this media type......................14 - 5.10. Additional information.....................................14 - 5.11. Person & email address to contact for further information..14 - 5.12. Intended usage.............................................14 - 5.13. Author/Change controller...................................15 - 6. Predefined Types..............................................15 - 6.1. SOURCE Type Definition......................................15 - 6.2. NAME Type Definition........................................16 - 6.3. PROFILE Type Definition.....................................16 - 6.4. BEGIN Type Definition.......................................17 - 6.5. END Type Definition.........................................17 - 7. Use of the multipart/related Content-Type.....................18 - 8. Examples.......................................................18 - 8.1. Example 1...................................................19 - 8.2. Example 2...................................................19 - 8.3. Example 3...................................................20 - 8.4. Example 4...................................................21 - 9. Registration of new profiles..................................22 - 9.1. Define the profile..........................................22 - 9.2. Post the profile definition.................................23 - 9.3. Allow a comment period......................................23 - 9.4. Submit the profile for approval.............................23 - 10. Profile Change Control.......................................23 - - - -Howes, et. al. Standards Track [Page 2] - -RFC 2425 MIME Content-Type for Directory Information September 1998 - - - 11. Registration of new types....................................24 - 11.1. Define the type............................................24 - 11.2. Post the type definition...................................25 - 11.3. Allow a comment period.....................................25 - 11.4. Submit the type for approval...............................25 - 12. Type Change Control..........................................25 - 13. Registration of new parameters...............................26 - 13.1. Define the parameter.......................................26 - 13.2. Post the parameter definition..............................27 - 13.3. Allow a comment period.....................................27 - 13.4. Submit the parameter for approval..........................27 - 14. Parameter Change Control.....................................28 - 15. Registration of new value types..............................28 - 15.1. Define the value type......................................28 - 15.2. Post the value type definition.............................29 - 15.3. Allow a comment period.....................................29 - 15.4. Submit the value type for approval.........................29 - 16. Security Considerations......................................30 - 17. Acknowledgements..............................................30 - 18. References....................................................30 - 19. Authors' Addresses...........................................32 - 20. Full Copyright Statement......................................33 - -3. Need for a MIME Directory Type - - For purposes of this document, a directory is a special-purpose - database that contains typed information. A directory usually - supports both read and search of the information it contains, and can - support creation and modification of the information as well. - Directory information is usually accessed far more often than it is - updated. Directories can be local or global in scope. They can be - distributed or centralized. The information they contain can be - replicated, with weak or strong consistency requirements. - - There are several situations in which users of Internet mail might - wish to exchange directory information: the email analogy of a - "business card" exchange; the conveyance of directory information to - a user having only email access to the Internet; the provision of - machine-parseable address information when purchasing goods or - services over the Internet; etc. As MIME [RFC-2045, RFC-2046] is - used increasingly by other protocols, most notably HTTP, it can also - be useful for these protocols to carry directory information in MIME - format. Such a format, for example, could be used to represent URC - (uniform resource characteristics) information about resources on the - World Wide Web, or to provide a rudimentary directory service over - HTTP. - - - - - -Howes, et. al. Standards Track [Page 3] - -RFC 2425 MIME Content-Type for Directory Information September 1998 - - -4. Overview - - The scheme defined here for representing directory information in a - MIME Content-Type has two parts. First, the text/directory Content- - Type is defined for use in holding directory information within a - single body part, for example name, title, or email address. In its - simplest form, the format uses a "type:value" approach, which should - be easily parseable by existing MIME implementations and - understandable by users. More complicated situations can be - represented also. This document defines the general form the - information in the Content-Type should have, and the procedure by - which specific types and values (properties) for particular - applications can be defined. The framework is general enough to - handle information from any number of end directory services, - including LDAP [RFC-1777, RFC-1778], WHOIS++ [RFC-1835], and X.500 - [X500]. - - Directory entries can include far more than just textual information. - Some such information (e.g., an image or sound) overlaps with - predefined MIME Content-Types. In these cases it can be desirable to - include the information in its well-known MIME format. This situation - is handled by using a multipart/related Content-Type as defined in - [RFC-2112]. The root component of this type is a text/directory body - part specifying any in-line information, and for information - contained in other Content-Types, the Content-IDs (in URI form) of - those parts. - - In some applications, it can be useful to include a pointer (e.g, a - URI) to some directory information rather than the information - itself. This document defines a general mechanism for accomplishing - this. - -5. The text/directory Content-Type - - The text/directory Content-Type is used to hold basic directory - information and URIs referencing other information, including other - MIME body parts holding supplementary or non-textual directory - information, such as an image or sound. It is defined as follows, - using the MIME media type registration template from [RFC-2048]. - - To: ietf-types@uninett.no - Subject: Registration of MIME media type text/directory - -5.1. MIME media type name - - MIME media type name: text - - - - - -Howes, et. al. Standards Track [Page 4] - -RFC 2425 MIME Content-Type for Directory Information September 1998 - - -5.2. MIME subtype name - - MIME subtype name: directory - -5.3. Required parameters - - Required parameters: charset - - The "charset" parameter is as defined in [RFC-2046] for other body - parts. It is used to identify the default character set used within - the body part. - -5.4. Optional parameters - - Optional parameters: profile - - The "profile" parameter is used to convey the type(s) of entity(ies) - to which the directory information pertains and the likely set of - information associated with the entity(ies). It is intended only as a - guide to applications interpreting the information contained within - the body part. It SHOULD NOT be used to exclude or require particular - pieces of information unless a profile definition specifically calls - for this behavior. Unless specifically forbidden by a particular - profile definition, a text/directory content type can contain - arbitrary attribute/value pairs. - - The value of the "profile" parameter is defined as follows. Profile - names are case insensitive (i.e., the profile name "vCard" is the - same as "VCARD" and "vcard" and "vcArD"). - - profile = x-name / iana-token - - x-name = "x-" 1*(ALPHA / DIGIT / "-") - ; Names beginning with "x-" or "X-" are - ; reserved for experimental use not intended for released - ; products, or for use in bilateral agreements. - - iana-token = <a publicly-defined extension token, registered - with IANA, as specified in Section 9 of this - document> - -5.5. Encoding considerations - - The default encoding is 8bit. Otherwise, as specified by the - Content-Transfer-Encoding header field. - - - - - - -Howes, et. al. Standards Track [Page 5] - -RFC 2425 MIME Content-Type for Directory Information September 1998 - - -5.6. Security considerations - - Directory information can be public or it can be protected from - unauthorized access by the directory service in which it resides. - Once the information leaves its native service, there can be no - guarantee that the same care will be taken by all services handling - the information. Furthermore, this specification defines no access - control mechanism by which information can be protected, or by which - access control information can be conveyed. Note that the integrity - and privacy of a text/directory body part can be protected by - enclosing it within an appropriate MIME-based security mechanism. - -5.7. Interoperability considerations - - In order to make sense of directory information, applications must - share a common understanding of the types of information contained - within the Content-Type (the directory schema). This schema - information is not defined in this document, but rather in companion - documents (e.g., [MIME-VCARD]) that follow the requirements specified - in this document, or in bilateral agreements between communicating - parties. - -5.8. Published specification - - The text/directory Content-Type contains directory information, - typically pertaining to a single directory entity or group of - entities. The content consists of one or more lines in the format - given below. - -5.8.1. Line delimiting and folding - - Individual lines within the MIME text/directory Content Type body are - delimited by the [RFC-822] line break, which is a CRLF sequence - (ASCII decimal 13, followed by ASCII decimal 10). Long logical lines - of text can be split into a multiple-physical-line representation - using the following folding technique. - - A logical line MAY be continued on the next physical line anywhere - between two characters by inserting a CRLF immediately followed by a - single white space character (space, ASCII decimal 32, or horizontal - tab, ASCII decimal 9). At least one character must be present on the - folded line. Any sequence of CRLF followed immediately by a single - white space character is ignored (removed) when processing the - content type. For example the line: - - DESCRIPTION:This is a long description that exists on a long line. - - Can be represented as: - - - -Howes, et. al. Standards Track [Page 6] - -RFC 2425 MIME Content-Type for Directory Information September 1998 - - - DESCRIPTION:This is a long description - that exists on a long line. - - It could also be represented as: - - DESCRIPTION:This is a long descrip - tion that exists o - n a long line. - - The process of moving from this folded multiple-line representation - of a type definition to its single line representation is called - unfolding. Unfolding is accomplished by regarding CRLF immediately - followed by a white space character (namely HTAB ASCII decimal 9 or - SPACE ASCII decimal 32) as equivalent to no characters at all (i.e., - the CRLF and single white space character are removed). - -5.8.2. ABNF content-type definition - - The following ABNF uses the notation of RFC 2234, which also defines - CRLF, WSP, DQUOTE, VCHAR, ALPHA, and DIGIT. After the unfolding of - any folded lines as described above, the syntax for a line of this - content type is as follows: - - contentline = [group "."] name *(";" param) ":" value CRLF - ; When parsing a content line, folded lines MUST first - ; be unfolded according to the unfolding procedure - ; described above. - ; When generating a content line, lines longer than 75 - ; characters SHOULD be folded according to the folding - ; procedure described above. - - group = 1*(ALPHA / DIGIT / "-") - - name = x-name / iana-token - - iana-token = 1*(ALPHA / DIGIT / "-") - ; identifier registered with IANA - - x-name = "x-" 1*(ALPHA / DIGIT / "-") - ; Names that begin with "x-" or "X-" are - ; reserved for experimental use, not intended for released - ; products, or for use in bilateral agreements. - - param = param-name "=" param-value *("," param-value) - - param-name = x-name / iana-token - - param-value = ptext / quoted-string - - - -Howes, et. al. Standards Track [Page 7] - -RFC 2425 MIME Content-Type for Directory Information September 1998 - - - ptext = *SAFE-CHAR - - value = *VALUE-CHAR - / valuespec ; valuespec defined in section 5.8.4 - - quoted-string = DQUOTE *QSAFE-CHAR DQUOTE - - NON-ASCII = %x80-FF - ; use restricted by charset parameter - ; on outer MIME object (UTF-8 preferred) - - QSAFE-CHAR = WSP / %x21 / %x23-7E / NON-ASCII - ; Any character except CTLs, DQUOTE - - SAFE-CHAR = WSP / %x21 / %x23-2B / %x2D-39 / %x3C-7E / NON-ASCII - ; Any character except CTLs, DQUOTE, ";", ":", "," - - VALUE-CHAR = WSP / VCHAR / NON-ASCII - ; any textual character - - A line that begins with a white space character is a continuation of - the previous line, as described above. The white space character and - immediately preceeding CRLF should be discarded when reconstructing - the original line. Note that this line-folding convention differs - from that found in RFC 822, in that the sequence <CRLF><WSP> found - anywhere in the content indicates a continued line and should be - removed. - - Various type names and the format of the corresponding values are - defined as specified in Section 11. Specifications MAY impose - ordering on the type constructs within a body part, though none is - required by default. The various x-name constructs are used for - bilaterally-agreed upon type names, parameter names and parameter - values, or for use in experimental settings. - - Type names and parameter names are case insensitive (e.g., the type - name "fn" is the same as "FN" and "Fn"). Parameter values MAY be case - sensitive or case insensitive, depending on their definition. - - The group construct is used to group related attributes together. - The group name is a syntactic convention used to indicate that all - type names prefaced with the same group name SHOULD be grouped - together when displayed by an application. It has no other - significance. Implementations that do not understand or support - grouping MAY simply strip off any text before a "." to the left of - the type name and present the types and values as normal. - - - - - -Howes, et. al. Standards Track [Page 8] - -RFC 2425 MIME Content-Type for Directory Information September 1998 - - - Each attribute defined in the text/directory body MAY have multiple - values, if allowed in the definition of the profile in which the - attribute is used. The general rule for encoding multi-valued items - is to simply create a new content line for each value (including the - type name). However, it should be noted that some value types - support encoding multiple values in a single content line by - separating the values with a comma ",". This approach has been taken - for several of the content types defined below (date, time, integer, - float), for space-saving reasons. - -5.8.3. Pre-defined Parameters - - The following parameters and value types are defined for general use. - - predefined-param = encodingparm - / valuetypeparm - / languageparm - / contextparm - - encodingparm = "encoding" "=" encodingtype - - encodingtype = "b" ; from RFC 2047 - / iana-token ; registered as described in - ; section 15 of this document - - valuetypeparm = "value" "=" valuetype - - valuetype = "uri" ; genericurl from secion 5 of RFC 1738 - / "text" - / "date" - / "time" - / "date-time" ; date time - / "integer" - / "boolean" - / "float" - / x-name - / iana-token ; registered as described in - ; section 15 of this document - - languageparm = "language" "=" Language-Tag - ; Language-Tag is defined in section 2 of RFC 1766 - - contextparm = "context" "=" context - - context = x-name - / iana-token - - - - - -Howes, et. al. Standards Track [Page 9] - -RFC 2425 MIME Content-Type for Directory Information September 1998 - - - The "language" type parameter is used to identify data in multiple - languages. There is no concept of "default" language, except as - specified by any "Content-Language" MIME header parameter that is - present. The value of the "language" type parameter is a language - tag as defined in Section 2 of [RFC-1766]. - - The "context" type parameter is used to identify a context (e.g., a - protocol) used in interpreting the value. This is used, for example, - in the "source" type, defined below. - - The "encoding" type parameter is used to specify an alternate - encoding for a value. If the value contains a CRLF, it must be - encoded, since CRLF is used to separate lines in the content-type - itself. Currently, only the "b" encoding is supported. - - The "b" encoding can also be useful for binary values that are mixed - with other text information in the body part (e.g., a certificate). - Using a per-value "b" encoding in this case leaves the other - information in a more readable form. The encoded base 64 value can be - split across multiple physical lines in the content type by using the - line folding technique described above. - - The Content-Transfer-Encoding header field is used to specify the - encoding used for the body part as a whole. The "encoding" type - parameter is used to specify an encoding for a particular value - (e.g., a certificate). In this case, the Content-Transfer-Encoding - header might specify "8bit", while the one certificate value might - specify an encoding of "b" via an "encoding=b" type parameter. - - The Content-Transfer-Encoding and the encodings of individual types - given by the "encoding" type parameter are independent of one - another. When encoding a text/directory body part for transmission, - individual type encodings are performed first, then the entire body - part is encoded according to the Content-Transfer-Encoding. When - decoding a text/directory body part, the Content-Transfer-Encoding is - decoded first, and then any individual types with an "encoding" type - parameter are decoded. - - The "value" parameter is optional, and is used to identify the value - type (data type) and format of the value. The use of these - predefined formats is encouraged even if the value parameter is not - explicity used. By defining a standard set of value types and their - formats, existing parsing and processing code can be leveraged. - - Including the value type explicitly as part of each property provides - an extra hint to keep parsing simple and support more generalized - applications. For example a search engine would not have to know the - particular value types for all of the items for which it is - - - -Howes, et. al. Standards Track [Page 10] - -RFC 2425 MIME Content-Type for Directory Information September 1998 - - - searching. Because the value type is explicit in the definition, the - search engine could look for dates in any item type and provide - results that can still be interpreted. - -5.8.4. Pre-defined Value Types - - The format for values corresponding to the predefined valuetype - specifications given above are defined. - - valuespec = text-list - / genericurl ; from section 5 of RFC 1738 - / date-list - / time-list - / date-time-list - / boolean - / integer-list - / float-list - / iana-valuespec - - text-list = *TEXT-LIST-CHAR *("," *TEXT-LIST-CHAR) - - TEXT-LIST-CHAR = "\\" / "\," / "\n" - / <any VALUE-CHAR except , or \ or newline> - ; Backslashes, newlines, and commas must be encoded. - ; \n or \N can be used to encode a newline. - - date-list = date *("," date) - - time-list = time *("," time) - - date-time-list = date "T" time *("," date "T" time) - - boolean = "TRUE" / "FALSE" - - integer-list = integer *("," integer) - - integer = [sign] 1*DIGIT - - float-list = float *("," float) - - float = [sign] 1*DIGIT ["." 1*DIGIT] - - sign = "+" / "-" - - date = date-fullyear ["-"] date-month ["-"] date-mday - - date-fullyear = 4 DIGIT - - - - -Howes, et. al. Standards Track [Page 11] - -RFC 2425 MIME Content-Type for Directory Information September 1998 - - - date-month = 2 DIGIT ;01-12 - - date-mday = 2 DIGIT ;01-28, 01-29, 01-30, 01-31 - ;based on month/year - - time = time-hour [":"] time-minute [":"] time-second [time-secfrac] - [time-zone] - - time-hour = 2 DIGIT ;00-23 - - time-minute = 2 DIGIT ;00-59 - - time-second = 2 DIGIT ;00-60 (leap second) - - time-secfrac = "," 1*DIGIT - - time-zone = "Z" / time-numzone - - time-numzome = sign time-hour [":"] time-minute - - iana-valuespec = <a publicly-defined valuetype format, registered - with IANA, as defined in section 15 of this - document> - - Some specific notes on the value types and formats: - - "text": The "text" value type should be used to identify values that - contain human-readable text. The character set and language in which - the text is represented is controlled by the charset content-header - and the language type parameter and content-header. - - Examples for "text": - this is a text value - this is one value,this is another - this is a single value\, with a comma encoded - - A formatted text line break in a text value type MUST be represented - as the character sequence backslash (ASCII decimal 92) followed by a - Latin small letter n (ASCII decimal 110) or a Latin capital letter N - (ASCII decimal 78), that is "\n" or "\N". - - For example a multiple line DESCRIPTION value of: - - Mythical Manager - Hyjinx Software Division - BabsCo, Inc. - - could be represented as: - - - -Howes, et. al. Standards Track [Page 12] - -RFC 2425 MIME Content-Type for Directory Information September 1998 - - - DESCRIPTION:Mythical Manager\nHyjinx Software Division\n - BabsCo\, Inc.\n - - demonstrating the \n literal formatted line break technique, the - CRLF-followed-by-space line folding technique, and the backslash - escape technique. - - "uri": The "uri" value type should be used to identify values that - are referenced by a URI (including a Content-ID URI), instead of - encoded in-line. These value references might be used if the value is - too large, or otherwise undesirable to include directly. The format - for the URI is as defined in RFC 1738. - - Examples for "uri": - http://www.foobar.com/my/picture.jpg - ldap://ldap.foobar.com/cn=babs%20jensen - - "date", "time", and "date-time": Each of these value types is based - on a subset of the definitions in ISO 8601 standard. Profiles MAY - place further restrictions on "date" and "time" values. Multiple - "date" and "time" values can be specified using the comma-separated - notation, unless restricted by a profile. - - Examples for "date": - 1985-04-12 - 1996-08-05,1996-11-11 - 19850412 - - Examples for "time": - 10:22:00 - 102200 - 10:22:00.33 - 10:22:00.33Z - 10:22:33,11:22:00 - 10:22:00-08:00 - - Examples for "date-time": - 1996-10-22T14:00:00Z - 1996-08-11T12:34:56Z - 19960811T123456Z - 1996-10-22T14:00:00Z,1996-08-11T12:34:56Z - - "boolean": The "boolean" value type is used to express boolen values. - These values are case insensitive. - - Examples: TRUE - false - True - - - -Howes, et. al. Standards Track [Page 13] - -RFC 2425 MIME Content-Type for Directory Information September 1998 - - - "integer": The "integer" value type is used to express signed - integers in decimal format. If sign is not specified, the value is - assumed positive "+". Multiple "integer" values can be specified - using the comma-separated notation, unless restricted by a profile. - - Examples: 1234567890 - -1234556790 - +1234556790,432109876 - - "float": The "float" value type is used to express real numbers. If - sign is not specified, the value is assumed positive "+". Multiple - "float" values can be specified using the comma-separated notation, - unless restricted by a profile. - - Examples: 20.30 - 1000000.0000001 - 1.333,3.14 - -5.9. Applications which use this media type - - Applications which use this media type: Various - -5.10. Additional information - - Additional information: None - -5.11. Person & email address to contact for further information - - Tim Howes - Netscape Communications Corp. - 501 East Middlefield Rd. - Mountain View, CA 94041 - USA - howes@netscape.com - +1 415 937 3419 - -5.12. Intended usage - - Intended usage: COMMON - - - - - - - - - - - - -Howes, et. al. Standards Track [Page 14] - -RFC 2425 MIME Content-Type for Directory Information September 1998 - - -5.13. Author/Change controller - - Tim Howes - Netscape Communications Corp. - 501 East Middlefield Rd. - Mountain View, CA 94041 - USA - howes@netscape.com - +1 415 937 3419 - - Mark Smith - Netscape Communications Corp. - 501 East Middlefield Rd. - Mountain View, CA 94041 - USA - mcs@netscape.com - +1 415 937 3477 - - Frank Dawson - Lotus Development Corporation - 6544 Battleford Drive - Raleigh, NC 27613-3502 - USA - frank_dawson@lotus.com - +1-919-676-9515 - -6. Predefined Types - - The following types are generally useful regardless of the profile - being carried and are defined below using the text/directory MIME - type registration template defined in Section 11.1 of this document. - These types MAY be included in any profile, unless explicitly - forbidden in the profile definition. - -6.1. SOURCE Type Definition - - To: ietf-mime-direct@imc.org - Subject: Registration of text/directory MIME type SOURCE - - Type name: SOURCE - - Type purpose: To identify the source of directory information - contained in the content type. - - Type encoding: 8bit - - Type valuetype: uri - - - - -Howes, et. al. Standards Track [Page 15] - -RFC 2425 MIME Content-Type for Directory Information September 1998 - - - Type special notes: The SOURCE type is used to provide the means by - which applications knowledgable in the given directory service - protocol can obtain additional or more up-to-date information from - the directory service. It contains a URI as defined in [RFC-1738] - and/or other information referencing the directory entity or entities - to which the information pertains. When directory information is - available from more than one source, the sending entity can pick what - it considers to be the best source, or multiple SOURCE types can be - included. The interpretation of the value for a SOURCE type can - depend on the setting of the CONTEXT type parameter. The value of the - CONTEXT type parameter MUST be compatible with the value of the uri - prefix. - - Type example: - SOURCE;CONTEXT=LDAP:ldap://ldap.host/cn=Babs%20Jensen, - %20o=Babsco,%20c=US - -6.2. NAME Type Definition - - To: ietf-mime-direct@imc.org - Subject: Registration of text/directory MIME type NAME - - Type name: NAME - - Type purpose: To identify the displayable name of the directory - entity to which information in the content type pertains. - - Type encoding: 8bit - - Type valuetype: text - - Type special notes: The NAME type is used to convey the display name - of the entity to which the directory information pertains. - - Type example: - NAME:Babs Jensen's Contact Information - -6.3. PROFILE Type Definition - - To: ietf-mime-direct@imc.org - Subject: Registration of text/directory MIME type PROFILE - - Type name: PROFILE - - Type purpose: To identify the type of directory entity to which - information in the content type pertains. - - Type encoding: 8bit - - - -Howes, et. al. Standards Track [Page 16] - -RFC 2425 MIME Content-Type for Directory Information September 1998 - - - Type valuetype: A profile name, registered as described in Section 9 - of this document or bilaterally agreed upon as described in Section - 5. - - Type special notes: The PROFILE type is used to convey the type of - the entity to which the directory information in the rest of the body - part pertains. It should be the same as the "profile" header - parameter, if present. - - Type example: - PROFILE:vCard - -6.4. BEGIN Type Definition - - To: ietf-mime-direct@imc.org - Subject: Registration of text/directory MIME type BEGIN - - Type name: BEGIN - - Type purpose: To denote the beginning of a syntactic entity within a - text/directory content-type. - - Type encoding: 8bit - - Type valuetype: text, containing a profile name, registered as - described in Section 9 of this document or bilaterally-agreed upon as - described in Section 5. - - Type special notes: The BEGIN type is used in conjunction with the - END type to delimit a profile containing a related set of properties - within an text/directory content-type. This construct can be used - instead of or in addition to wrapping separate sets of information - inside additional MIME headers. It is provided for applications that - wish to define content that can contain multiple entities within the - same text/directory content-type or to define content that can be - identifiable outside of a MIME environment. - - Type example: - BEGIN:VCARD - -6.5. END Type Definition - - To: ietf-mime-direct@imc.org - Subject: Registration of text/directory MIME type END - - Type name: END - - - - - -Howes, et. al. Standards Track [Page 17] - -RFC 2425 MIME Content-Type for Directory Information September 1998 - - - Type purpose: To denote the end of a syntactic entity within a - text/directory content-type. - - Type encoding: 8bit - - Type valuetype: text, containing a profile name, registered as - described in Section 9 of this document or bilaterally-agreed upon as - described in Section 5. - - Type special notes: The END type is used in conjunction with the - BEGIN type to delimit a profile containing a related set of - properties within an text/directory content-type. This construct can - be used instead of or in addition to wrapping separate sets of - information inside additional MIME headers. It is provided for - applications that wish to define content that can contain multiple - entities within the same text/directory content-type or to define - content that can be identifiable outside of a MIME environment. - - Type example: - END: VCARD - -7. Use of the multipart/related Content-Type - - The multipart/related Content-Type can be used to hold directory - information comprised of both text and non-text information or - directory information that already has a natural MIME representation. - The root body part within the multipart/related body part is - specified as defined in [RFC-2112] by a "start" parameter, or it is - the first body part in the absence of such a parameter. The root - body part must have a Content-Type of "text/directory". This part - holds inline information and makes reference to subsequent body parts - holding additional text or non-text directory information via their - Content-ID URIs as explained in Section 5. - - The body parts referred to do not have to be in any particular order, - except as noted above for the root body part. - -8. Examples - - The following examples are for illustrative purposes only and are not - part of the definition. - - - - - - - - - - -Howes, et. al. Standards Track [Page 18] - -RFC 2425 MIME Content-Type for Directory Information September 1998 - - -8.1. Example 1 - - The first example illustrates simple use of the text/directory - Content-Type. Note that no "profile" parameter is given, so an - application may not know what kind of directory entity the - information applies to. Note also the use of both hypothetical - official and bilaterally agreed upon types. - - From: Whomever@wherever.com - To: Someone@somewhere.com - Subject: whatever - MIME-Version: 1.0 - Message-ID: <id1@host.net> - Content-Type: text/directory - Content-ID: <id2@host.com> - - cn:Babs Jensen - cn:Barbara J Jensen - sn:Jensen - email:babs@umich.edu - phone:+1 313 747-4454 - x-id:1234567890 - -8.2. Example 2 - - The next example illustrates the use of the Quoted-Printable transfer - encoding defined in [RFC 2045] to include non-ASCII character in some - of the information returned, and the use of the optional "name" and - "source" types. It also illustrates the use of an "encoding" type - parameter to encode a certificate value in "b". A "vCard" profile - [MIME- VCARD] is used for the example. - -Content-Type: text/directory; - charset="iso-8859-1"; - profile="vCard" -Content-ID: <id3@host.com> -Content-Transfer-Encoding: Quoted-Printable - -begin:VCARD -source:ldap://cn=3Dbjorn%20Jensen, o=3Duniversity%20of%20Michigan, c=3DUS -name:Bjorn Jensen -fn:Bj=F8rn Jensen -n:Jensen;Bj=F8rn -email;type=3Dinternet:bjorn@umich.edu -tel;type=3Dwork,voice,msg:+1 313 747-4454 -key;type=3Dx509;encoding=3DB:dGhpcyBjb3VsZCBiZSAKbXkgY2VydGlmaWNhdGUK -end:VCARD - - - - -Howes, et. al. Standards Track [Page 19] - -RFC 2425 MIME Content-Type for Directory Information September 1998 - - -8.3. Example 3 - - The next example illustrates the use of multi-valued type parameters, - the "language" type parameter, the "value" type parameter, folding of - long lines, the \n encoding for formatted lines, attribute grouping, - and the inline "b" encoding. A "vCard" profile [MIME-VCARD] is used - for the example. - -Content-Type: text/directory; profile="vcard"; charset=iso-8859-1 -Content-ID: <id3@host.com> -Content-Transfer-Encoding: Quoted-Printable - -begin:vcard -source:ldap://cn=3DMeister%20Berger,o=3DUniversitaet%20Goerlitz,c=3DDE -name:Meister Berger -fn:Meister Berger -n:Berger;Meister -bday;value=3Ddate:1963-09-21 -o:Universit=E6t G=F6rlitz -title:Mayor -title;language=3Dde;value=3Dtext:Burgermeister -note:The Mayor of the great city of - Goerlitz in the great country of Germany. -email;internet:mb@goerlitz.de -home.tel;type=3Dfax,voice,msg:+49 3581 123456 -home.label:Hufenshlagel 1234\n - 02828 Goerlitz\n - Deutschland -key;type=3DX509;encoding=3Db:MIICajCCAdOgAwIBAgICBEUwDQYJKoZIhvcNAQEEBQ - AwdzELMAkGA1UEBhMCVVMxLDAqBgNVBAoTI05ldHNjYXBlIENvbW11bmljYXRpb25zI - ENvcnBvcmF0aW9uMRwwGgYDVQQLExNJbmZvcm1hdGlvbiBTeXN0ZW1zMRwwGgYDVQQD - ExNyb290Y2EubmV0c2NhcGUuY29tMB4XDTk3MDYwNjE5NDc1OVoXDTk3MTIwMzE5NDc - 1OVowgYkxCzAJBgNVBAYTAlVTMSYwJAYDVQQKEx1OZXRzY2FwZSBDb21tdW5pY2F0aW - 9ucyBDb3JwLjEYMBYGA1UEAxMPVGltb3RoeSBBIEhvd2VzMSEwHwYJKoZIhvcNAQkBF - hJob3dlc0BuZXRzY2FwZS5jb20xFTATBgoJkiaJk/IsZAEBEwVob3dlczBcMA0GCSqG - SIb3DQEBAQUAA0sAMEgCQQC0JZf6wkg8pLMXHHCUvMfL5H6zjSk4vTTXZpYyrdN2dXc - oX49LKiOmgeJSzoiFKHtLOIboyludF90CgqcxtwKnAgMBAAGjNjA0MBEGCWCGSAGG+E - IBAQQEAwIAoDAfBgNVHSMEGDAWgBT84FToB/GV3jr3mcau+hUMbsQukjANBgkqhkiG9 - w0BAQQFAAOBgQBexv7o7mi3PLXadkmNP9LcIPmx93HGp0Kgyx1jIVMyNgsemeAwBM+M - SlhMfcpbTrONwNjZYW8vJDSoi//yrZlVt9bJbs7MNYZVsyF1unsqaln4/vy6Uawfg8V - UMk1U7jt8LYpo4YULU7UZHPYVUaSgVttImOHZIKi4hlPXBOhcUQ=3D=3D -end:vcard - - - - - - - - - -Howes, et. al. Standards Track [Page 20] - -RFC 2425 MIME Content-Type for Directory Information September 1998 - - -8.4. Example 4 - - The final example illustrates the use of the multipart/related - Content-Type to include non-textual directory data via the "uri" - encoding to refer to other body parts within the same message, or to - external values. Note that no "profile" parameter is given, so an - application may not know what kind of directory entity the - information applies to. Note also the use of both hypothetical - official and bilaterally agreed upon types. - -Content-Type: multipart/related; - boundary=woof; - type="text/directory"; - start="<id5@host.com>" -Content-ID: <id4@host.com> - ---woof -Content-Type: text/directory; charset="iso-8859-1" -Content-ID: <id5@host.com> -Content-Transfer-Encoding: Quoted-Printable - -source:ldap://cn=3DBjorn%20Jensen,o=3DUniversity%20of%20Michigan,c=3DUS -cn:Bj=F8rn Jensen -sn:Jensen -email:bjorn@umich.edu -image;value=3Duri:cid:id6@host.com -image;value=3Duri;format=3Djpeg:ftp://some.host/some/path.jpg -sound;value=3Duri:cid:id7@host.com -phone:+1 313 747-4454 - ---woof -Content-Type: image/jpeg -Content-ID: <id6@host.com> - -<...image data...> - ---woof -Content-Type: message/external-body; - name="myvoice.au"; - site="myhost.com"; - access-type=ANON-FTP; - directory="pub/myname"; - mode="image" - -Content-Type: audio/basic -Content-ID: <id7@host.com> - ---woof-- - - - -Howes, et. al. Standards Track [Page 21] - -RFC 2425 MIME Content-Type for Directory Information September 1998 - - -9. Registration of new profiles - - This section defines procedures by which new profiles are registered - with the IANA and made available to the Internet community. Note that - non-IANA profiles can be used by bilateral agreement, provided the - associated profile names follow the "X-" convention defined above. - - The procedures defined here are designed to allow public comment and - review of new profiles, while posing only a small impediment to the - definition of new profiles. - - Registration of a new profile is accomplished by the following steps. - -9.1. Define the profile - - A profile is defined by completing the following template. - - To: ietf-mime-direct@imc.org - Subject: Registration of text/directory MIME profile XXX - - Profile name: - - Profile purpose: - - Profile types: - - Profile special notes (optional): - - Intended usage: (one of COMMON, LIMITED USE or OBSOLETE) - - The explanation of what goes in each field in the template follows. - - Profile name: The name of the profile as it will appear in the - text/directory MIME Content-Type "profile" header parameter, or the - predefined "profile" type name. - - Profile purpose: The purpose of the profile (e.g., to represent - information about people, printers, documents, etc.). Give a short - but clear description. - - Profile types: The list of types associated with the profile. This - list of types is to be expected but not required in the profile, - unless otherwise noted in the profile definition. Other types not - mentioned in the profile definition MAY also be present. Note that - any new types referenced by the profile MUST be defined separately as - described in Section 10. - - - - - -Howes, et. al. Standards Track [Page 22] - -RFC 2425 MIME Content-Type for Directory Information September 1998 - - - Profile special notes: Any special notes about the profile, how it is - to be used, etc. This section of the template can also be used to - define an ordering on the types that appear in the Content-Type, if - such an ordering is required. - -9.2. Post the profile definition - - The profile description must be posted to the new profile discussion - list, ietf-mime-direct@imc.org - -9.3. Allow a comment period - - Discussion on the new profile must be allowed to take place on the - list for a minimum of two weeks. Consensus must be reached on the - profile before proceeding to step 4. - -9.4. Submit the profile for approval - - Once the two-week comment period has elapsed, and the proposer is - convinced consensus has been reached on the profile, the registration - application should be submitted to the Profile Reviewer for approval. - The Profile Reviewer is appointed by the Application Area Directors - and can either accept or reject the profile registration. An accepted - registration is passed on by the Profile Reviewer to the IANA for - inclusion in the official IANA profile registry. The registration may - be rejected for any of the following reasons. 1) Insufficient comment - period; 2) Consensus not reached; 3) Technical deficiencies raised on - the list or elsewhere have not been addressed. The Profile Reviewer's - decision to reject a profile can be appealed by the proposer to the - IESG, or the objections raised can be addressed by the proposer and - the profile resubmitted. - -10. Profile Change Control - - Existing profiles can be changed using the same process by which they - were registered. - - Define the change - - Post the change - - Allow a comment period - - Submit the changed profile for approval - - - - - - - -Howes, et. al. Standards Track [Page 23] - -RFC 2425 MIME Content-Type for Directory Information September 1998 - - - Note that the original author or any other interested party can - propose a change to an existing profile, but that such changes should - only be proposed when there are serious omissions or errors in the - published specification. The Profile Reviewer can object to a change - if it is not backwards compatible, but is not required to do so. - - Profile definitions can never be deleted from the IANA registry, but - profiles which are no longer believed to be useful can be declared - OBSOLETE by a change to their "intended use" field. - -11. Registration of new types - - This section defines procedures by which new types are registered - with the IANA. Note that non-IANA types can be used by bilateral - agreement, provided the associated types names follow the "X-" - convention defined above. - - The procedures defined here are designed to allow public comment and - review of new types, while posing only a small impediment to the - definition of new types. - - Registration of a new type is accomplished by the following steps. - -11.1. Define the type - - A type is defined by completing the following template. - - To: ietf-mime-direct@imc.org - Subject: Registration of text/directory MIME type XXX - - Type name: - - Type purpose: - - Type encoding: - - Type valuetype: - - Type special notes (optional): - - Intended usage: (one of COMMON, LIMITED USE or OBSOLETE) - - The meaning of each field in the template is as follows. - - Type name: The name of the type, as it will appear in the body of an - text/directory MIME Content-Type "type: value" line to the left of - the colon ":". - - - - -Howes, et. al. Standards Track [Page 24] - -RFC 2425 MIME Content-Type for Directory Information September 1998 - - - Type purpose: The purpose of the type (e.g., to represent a name, - postal address, IP address, etc.). Give a short but clear - description. - - Type encoding: The default encoding a value of the type must have in - the body of a text/directory MIME Content-Type. - - Type valuetype: The format a value of the type must have in the body - of a text/directory MIME Content-Type. This description must be - precise and must not violate the general encoding rules defined in - section 5 of this document. - - Type special notes: Any special notes about the type, how it is to be - used, etc. - -11.2. Post the type definition - - The type description must be posted to the new type discussion list, - ietf-mime-direct@imc.org - -11.3. Allow a comment period - - Discussion on the new type must be allowed to take place on the list - for a minimum of two weeks. Consensus must be reached on the type - before proceeding to step 4. - -11.4. Submit the type for approval - - Once the two-week comment period has elapsed, and the proposer is - convinced consensus has been reached on the type, the registration - application should be submitted to the Profile Reviewer for approval. - The Profile Reviewer is appointed by the Application Area Directors - and can either accept or reject the type registration. An accepted - registration is passed on by the Profile Reviewer to the IANA for - inclusion in the official IANA profile registry. The registration can - be rejected for any of the following reasons. 1) Insufficient comment - period; 2) Consensus not reached; 3) Technical deficiencies raised on - the list or elsewhere have not been addressed. The Profile - Reviewer's decision to reject a type can be appealed by the proposer - to the IESG, or the objections raised can be addressed by the - proposer and the type resubmitted. - - - - - - - - - - -Howes, et. al. Standards Track [Page 25] - -RFC 2425 MIME Content-Type for Directory Information September 1998 - - -12. Type Change Control - - Existing types can be changed using the same process by which they - were registered. - - Define the change - - Post the change - - Allow a comment period - - Submit the type for approval - - Note that the original author or any other interested party can - propose a change to an existing type, but that such changes should - only be proposed when there are serious omissions or errors in the - published specification. The Profile Reviewer can object to a change - if it is not backwards compatible, but is not required to do so. - - Type definitions can never be deleted from the IANA registry, but - types which are nolonger believed to be useful can be declared - OBSOLETE by a change to their "intended use" field. - -13. Registration of new parameters - - This section defines procedures by which new parameters are - registered with the IANA and made available to the Internet - community. Note that non-IANA parameters can be used by bilateral - agreement, provided the associated parameters names follow the "X-" - convention defined above. - - The procedures defined here are designed to allow public comment and - review of new parameters, while posing only a small impediment to the - definition of new parameters. - - Registration of a new parameter is accomplished by the following - steps. - -13.1. Define the parameter - - A parameter is defined by completing the following template. - - To: ietf-mime-direct@imc.org - Subject: Registration of text/directory MIME type parameter XXX - - Parameter name: - - Parameter purpose: - - - -Howes, et. al. Standards Track [Page 26] - -RFC 2425 MIME Content-Type for Directory Information September 1998 - - - Parameter values: - - Parameter special notes (optional): - - Intended usage: (one of COMMON, LIMITED USE or OBSOLETE) - - The explanation of what goes in each field in the template follows. - - Parameter name: The name of the parameter as it will appear in the - text/directory MIME Content-Type. - - Parameter purpose: The purpose of the parameter (e.g., to represent - the format of an image, type of a phone number, etc.). Give a short - but clear description. If defining a general paramemter like "format" - or "type" keep in mind that other applications might wish to extend - its use. - - Parameter values: The list or description of values associated with - the parameter. - - Parameter special notes: Any special notes about the parameter, how - it is to be used, etc. - -13.2. Post the parameter definition - - The parameter description must be posted to the new parameter - discussion list, ietf-mime-direct@imc.org - -13.3. Allow a comment period - - Discussion on the new parameter must be allowed to take place on the - list for a minimum of two weeks. Consensus must be reached on the - parameter before proceeding to step 4. - -13.4. Submit the parameter for approval - - Once the two-week comment period has elapsed, and the proposer is - convinced consensus has been reached on the parameter, the - registration application should be submitted to the Profile Reviewer - for approval. The Profile Reviewer is appointed by the Application - Area Directors and can either accept or reject the parameter - registration. An accepted registration is passed on by the Profile - Reviewer to the IANA for inclusion in the official IANA parameter - registry. The registration can be rejected for any of the following - reasons. 1) Insufficient comment period; 2) Consensus not reached; 3) - Technical deficiencies raised on the list or elsewhere have not been - addressed. The Profile Reviewer's decision to reject a profile can be - appealed by the proposer to the IESG, or the objections raised can be - - - -Howes, et. al. Standards Track [Page 27] - -RFC 2425 MIME Content-Type for Directory Information September 1998 - - - addressed by the proposer and the parameter registration resubmitted. - -14. Parameter Change Control - - Existing parameters can be changed using the same process by which - they were registered. - - Define the change - - Post the change - - Allow a comment period - - Submit the parameter for approval - - Note that the original author or any other interested party can - propose a change to an existing parameter, but that such changes - should only be proposed when there are serious omissions or errors in - the published specification. The Profile Reviewer can object to a - change if it is not backwards compatible, but is not required to do - so. - - Parameter definitions can never be deleted from the IANA registry, - but parameters which are nolonger believed to be useful can be - declared OBSOLETE by a change to their "intended use" field. - -15. Registration of new value types - - This section defines procedures by which new value types are - registered with the IANA and made available to the Internet - community. Note that non-IANA value types can be used by bilateral - agreement, provided the associated value types names follow the "X-" - convention defined above. - - The procedures defined here are designed to allow public comment and - review of new value types, while posing only a small impediment to - the definition of new value types. - - Registration of a new value types is accomplished by the following - steps. - -15.1. Define the value type - - A value type is defined by completing the following template. - - To: ietf-mime-direct@imc.org - Subject: Registration of text/directory MIME value type XXX - - - - -Howes, et. al. Standards Track [Page 28] - -RFC 2425 MIME Content-Type for Directory Information September 1998 - - - value type name: - - value type purpose: - - value type format: - - value type special notes (optional): - - Intended usage: (one of COMMON, LIMITED USE or OBSOLETE) - - The explanation of what goes in each field in the template follows. - - value type name: The name of the value type as it will appear in the - text/directory MIME Content-Type. - - value type purpose: The purpose of the value type. Give a short but - clear description. - - value type format: The definition of the format for the value, - usually using ABNF grammar. - - value type special notes: Any special notes about the value type, how - it is to be used, etc. - -15.2. Post the value type definition - - The value type description must be posted to the new value type - discussion list, ietf-mime-direct@imc.org - -15.3. Allow a comment period - - Discussion on the new value type must be allowed to take place on the - list for a minimum of two weeks. Consensus must be reached before - proceeding to step 4. - -15.4. Submit the value type for approval - - Once the two-week comment period has elapsed, and the proposer is - convinced consensus has been reached on the value type, the - registration application should be submitted to the Profile Reviewer - for approval. The Profile Reviewer is appointed by the Application - Area Directors and can either accept or reject the value type - registration. An accepted registration should be passed on by the - Profile Reviewer to the IANA for inclusion in the official IANA value - type registry. The registration can be rejected for any of the - following reasons. 1) Insufficient comment period; 2) Consensus not - reached; 3) Technical deficiencies raised on the list or elsewhere - have not been addressed. The Profile Reviewer's decision to reject a - - - -Howes, et. al. Standards Track [Page 29] - -RFC 2425 MIME Content-Type for Directory Information September 1998 - - - profile can be appealed by the proposer to the IESG, or the - objections raised can be addressed by the proposer and the value type - registration resubmitted. - -16. Security Considerations - - Internet mail is subject to many well known security attacks, - including monitoring, replay, and forgery. Care should be taken by - any directory service in allowing information to leave the scope of - the service itself, where any access controls can no longer be - guaranteed. Applications should also take care to display directory - data in a "safe" environment (e.g., PostScript-valued types). - -17. Acknowledgements - - The registration procedures defined here were shamelessly lifted from - the MIME registration RFC. - - The many valuable comments contributed by members of the IETF ASID - working group are gratefully acknowledged, as are the contributions - of the Versit Consortium. Chris Newman was especially helpful in - navigating the intricacies of ABNF lore. - -18. References - - [RFC-1777] Yeong, W., Howes, T., and S. Kille, "Lightweight - Directory Access Protocol", RFC 1777, March 1995. - - [RFC-1778] Howes, T., Kille, S., Yeong, W., and C. Robbins, "The - String Representation of Standard Attribute Syntaxes", - RFC 1778, March 1995. - - [RFC-822] Crocker, D., "Standard for the Format of ARPA Internet - Text Messages", STD 11, RFC 822, August 1982. - - [RFC-2045] Borenstein, N., and N. Freed, "Multipurpose Internet - Mail Extensions (MIME) Part One: Format of Internet - Message Bodies", RFC 2045, November 1996. - - [RFC-2046] Moore, K., "Multipurpose Internet Mail Extensions (MIME) - Part Two: Media Types", RFC 2046, November 1996. - - [RFC-2048] Freed, N., Klensin, J., and J. Postel, "Multipurpose - Internet Mail Extensions (MIME) Part Four: Registration - Procedures", RFC 2048, November 1996. - - [RFC-1766] Alvestrand, H., "Tags for the Identification of - Languages", RFC 1766, March 1995. - - - -Howes, et. al. Standards Track [Page 30] - -RFC 2425 MIME Content-Type for Directory Information September 1998 - - - [RFC-2112] Levinson, E., "The MIME Multipart/Related Content-type", - RFC 2112, March 1997. - - [X500] "Information Processing Systems - Open Systems - Interconnection - The Directory: Overview of Concepts, - Models and Services", ISO/IEC JTC 1/SC21, International - Standard 9594-1, 1988. - - [RFC-1835] Deutsch, P., Schoultz, R., Faltstrom, P., and C. Weider, - "Architecture of the WHOIS++ service", RFC 1835, August - 1995. - - [RFC-1738] Berners-Lee, T., Masinter, L., and M. McCahill, "Uniform - Resource Locators (URL)", RFC 1738, December 1994. - - [MIME-VCARD] Dawson, F., and T. Howes, "VCard MIME Directory - Profile", RFC 2426, September 1998. - - [VCARD] Internet Mail Consortium, "vCard - The Electronic - Business Card", Version 2.1, - http://www.imc.com/pdi/vcard-21.txt, September, 1996. - - [RFC-2119] Bradner, S., "Key words for use in RFCs to Indicate - Requirement Levels", BCP 14, RFC 2119, March 1997. - - [RFC-2234] Crocker, D., and P. Overell, "Augmented BNF for Syntax - Specifications: ABNF", RFC 2234, November 1997. - - - - - - - - - - - - - - - - - - - - - - - - -Howes, et. al. Standards Track [Page 31] - -RFC 2425 MIME Content-Type for Directory Information September 1998 - - -19. Authors' Addresses - - Tim Howes - Netscape Communications Corp. - 501 East Middlefield Rd. - Mountain View, CA 94041 - USA - - Phone: +1.415.937.3419 - EMail: howes@netscape.com - - - Mark Smith - Netscape Communications Corp. - 501 East Middlefield Rd. - Mountain View, CA 94041 - USA - - Phone: +1.415.937.3477 - EMail: mcs@netscape.com - - - Frank Dawson - Lotus Development Corporation - 6544 Battleford Drive - Raleigh, NC 27613 - USA - - Phone: +1-919-676-9515 - EMail: frank_dawson@lotus.com - - - - - - - - - - - - - - - - - - - - - -Howes, et. al. Standards Track [Page 32] - -RFC 2425 MIME Content-Type for Directory Information September 1998 - - -20. Full Copyright Statement - - Copyright (C) The Internet Society (1998). All Rights Reserved. - - This document and translations of it may be copied and furnished to - others, and derivative works that comment on or otherwise explain it - or assist in its implementation may be prepared, copied, published - and distributed, in whole or in part, without restriction of any - kind, provided that the above copyright notice and this paragraph are - included on all such copies and derivative works. However, this - document itself may not be modified in any way, such as by removing - the copyright notice or references to the Internet Society or other - Internet organizations, except as needed for the purpose of - developing Internet standards in which case the procedures for - copyrights defined in the Internet Standards process must be - followed, or as required to translate it into languages other than - English. - - The limited permissions granted above are perpetual and will not be - revoked by the Internet Society or its successors or assigns. - - This document and the information contained herein is provided on an - "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING - TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING - BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION - HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF - MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - - - - - - - - - - - - - - - - - - - - - - - - -Howes, et. al. Standards Track [Page 33] - diff --git a/addressbook/backend/ebook/docs/rfc2426.txt b/addressbook/backend/ebook/docs/rfc2426.txt deleted file mode 100644 index a393a67c98..0000000000 --- a/addressbook/backend/ebook/docs/rfc2426.txt +++ /dev/null @@ -1,2355 +0,0 @@ - - - - - - -Network Working Group F. Dawson -Request for Comments: 2426 Lotus Development Corporation -Category: Standards Track T. Howes - Netscape Communications - September 1998 - - - vCard MIME Directory Profile - -Status of this Memo - - This document specifies an Internet standards track protocol for the - Internet community, and requests discussion and suggestions for - improvements. Please refer to the current edition of the "Internet - Official Protocol Standards" (STD 1) for the standardization state - and status of this protocol. Distribution of this memo is unlimited. - -Copyright Notice - - Copyright (C) The Internet Society (1998). All Rights Reserved. - -Abstract - - This memo defines the profile of the MIME Content-Type [MIME-DIR] for - directory information for a white-pages person object, based on a - vCard electronic business card. The profile definition is independent - of any particular directory service or protocol. The profile is - defined for representing and exchanging a variety of information - about an individual (e.g., formatted and structured name and delivery - addresses, email address, multiple telephone numbers, photograph, - logo, audio clips, etc.). The directory information used by this - profile is based on the attributes for the person object defined in - the X.520 and X.521 directory services recommendations. The profile - also provides the method for including a [VCARD] representation of a - white-pages directory entry within the MIME Content-Type defined by - the [MIME-DIR] document. - - The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", - "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY" and "OPTIONAL" in this - document are to be interpreted as described in [RFC 2119]. - - - - - - - - - - - -Dawson & Howes Standards Track [Page 1] - -RFC 2426 vCard MIME Directory Profile September 1998 - - -Table of Contents - - Overview.........................................................3 - 1. THE VCARD MIME DIRECTORY PROFILE REGISTRATION.................4 - 2. MIME DIRECTORY FEATURES.......................................5 - 2.1 PREDEFINED TYPE USAGE ......................................5 - 2.1.1 BEGIN and END Type ......................................5 - 2.1.2 NAME Type ...............................................5 - 2.1.3 PROFILE Type ............................................5 - 2.1.4 SOURCE Type .............................................5 - 2.2 PREDEFINED TYPE PARAMETER USAGE ............................6 - 2.3 PREDEFINED VALUE TYPE USAGE ................................6 - 2.4 EXTENSIONS TO THE PREDEFINED VALUE TYPES ...................6 - 2.4.1 BINARY ..................................................6 - 2.4.2 VCARD ...................................................6 - 2.4.3 PHONE-NUMBER ............................................7 - 2.4.4 UTC-OFFSET ..............................................7 - 2.5 STRUCTURED TYPE VALUES .....................................7 - 2.6 LINE DELIMITING AND FOLDING ................................8 - 3. VCARD PROFILE FEATURES........................................8 - 3.1 IDENTIFICATION TYPES .......................................8 - 3.1.1 FN Type Definition ......................................8 - 3.1.2 N Type Definition .......................................9 - 3.1.3 NICKNAME Type Definition ................................9 - 3.1.4 PHOTO Type Definition ..................................10 - 3.1.5 BDAY Type Definition ...................................11 - 3.2 DELIVERY ADDRESSING TYPES .................................11 - 3.2.1 ADR Type Definition ....................................11 - 3.2.2 LABEL Type Definition ..................................13 - 3.3 TELECOMMUNICATIONS ADDRESSING TYPES .......................13 - 3.3.1 TEL Type Definition ....................................14 - 3.3.2 EMAIL Type Definition ..................................15 - 3.3.3 MAILER Type Definition .................................15 - 3.4 GEOGRAPHICAL TYPES ........................................16 - 3.4.1 TZ Type Definition .....................................16 - 3.4.2 GEO Type Definition ....................................16 - 3.5 ORGANIZATIONAL TYPES ......................................17 - 3.5.1 TITLE Type Definition ..................................17 - 3.5.2 ROLE Type Definition ...................................18 - 3.5.3 LOGO Type Definition ...................................18 - 3.5.4 AGENT Type Definition ..................................19 - 3.5.5 ORG Type Definition ....................................20 - 3.6 EXPLANATORY TYPES .........................................20 - 3.6.1 CATEGORIES Type Definition .............................20 - 3.6.2 NOTE Type Definition ...................................21 - 3.6.3 PRODID Type Definition .................................21 - 3.6.4 REV Type Definition ....................................22 - 3.6.5 SORT-STRING Type Definition ............................22 - - - -Dawson & Howes Standards Track [Page 2] - -RFC 2426 vCard MIME Directory Profile September 1998 - - - 3.6.6 SOUND Type Definition ..................................23 - 3.6.7 UID Type Definition ....................................24 - 3.6.8 URL Type Definition ....................................25 - 3.6.9 VERSION Type Definition ................................25 - 3.7 SECURITY TYPES ............................................25 - 3.7.1 CLASS Type Definition ..................................26 - 3.7.2 KEY Type Definition ....................................26 - 3.8 EXTENDED TYPES ............................................27 - 4. FORMAL GRAMMAR...............................................27 - 5. DIFFERENCES FROM VCARD V2.1..................................37 - 6. ACKNOWLEDGEMENTS.............................................39 - 7. AUTHORS' ADDRESSES...........................................39 - 8. SECURITY CONSIDERATIONS......................................39 - 9. REFERENCES...................................................40 - 10. FULL COPYRIGHT STATEMENT....................................42 - -Overview - - The [MIME-DIR] document defines a MIME Content-Type for holding - different kinds of directory information. The directory information - can be based on any of a number of directory schemas. This document - defines a [MIME-DIR] usage profile for conveying directory - information based on one such schema; that of the white-pages type of - person object. - - The schema is based on the attributes for the person object defined - in the X.520 and X.521 directory services recommendations. The schema - has augmented the basic attributes defined in the X.500 series - recommendation in order to provide for an electronic representation - of the information commonly found on a paper business card. This - schema was first defined in the [VCARD] document. Hence, this [MIME- - DIR] profile is referred to as the vCard MIME Directory Profile. - - A directory entry based on this usage profile can include traditional - directory, white-pages information such as the distinguished name - used to uniquely identify the entry, a formatted representation of - the name used for user-interface or presentation purposes, both the - structured and presentation form of the delivery address, various - telephone numbers and organizational information associated with the - entry. In addition, traditional paper business card information such - as an image of an organizational logo or identify photograph can be - included in this person object. - - The vCard MIME Directory Profile also provides support for - representing other important information about the person associated - with the directory entry. For instance, the date of birth of the - person; an audio clip describing the pronunciation of the name - associated with the directory entry, or some other application of the - - - -Dawson & Howes Standards Track [Page 3] - -RFC 2426 vCard MIME Directory Profile September 1998 - - - digital sound; longitude and latitude geo-positioning information - related to the person associated with the directory entry; date and - time that the directory information was last updated; annotations - often written on a business card; Uniform Resource Locators (URL) for - a website; public key information. The profile also provides support - for non-standard extensions to the schema. This provides the - flexibility for implementations to augment the current capabilities - of the profile in a standardized way. More information about this - electronic business card format can be found in [VCARD]. - -1. The vCard Mime Directory Profile Registration - - This profile is identified by the following [MIME-DIR] registration - template information. Subsequent sections define the profile - definition. - - To: ietf-mime-directory@imc.org - - Subject: Registration of text/directory MIME profile VCARD - - Profile name: VCARD - - Profile purpose: To hold person object or white-pages type of - directory information. The person schema captured in the directory - entries is that commonly found in an electronic business card. - - Predefined MIME Directory value specifications used: uri, date, - date-time, float - - New value specifications: This profile places further constraints on - the [MIME-DIR] text value specification. In addition, it adds a - binary, phone-number, utc-offset and vcard value specifications. - - Predefined MIME Directory types used: SOURCE, NAME, PROFILE, BEGIN, - END. - - Predefined MIME Directory parameters used: ENCODING, VALUE, CHARSET, - LANGUAGE, CONTEXT. - - New types: FN, N, NICKNAME, PHOTO, BDAY, ADR, LABEL, TEL, EMAIL, - MAILER, TZ, GEO, TITLE, ROLE, LOGO, AGENT, ORG, CATEGORIES, NOTE, - PRODID, REV, SORT-STRING, SOUND, URL, UID, VERSION, CLASS, KEY - - New parameters: TYPE - - Profile special notes: The vCard object MUST contain the FN, N and - VERSION types. The type-grouping feature of [MIME-DIR] is supported - by this profile to group related vCard properties about a directory - - - -Dawson & Howes Standards Track [Page 4] - -RFC 2426 vCard MIME Directory Profile September 1998 - - - entry. For example, vCard properties describing WORK or HOME related - characteristics can be grouped with a unique group label. - - The profile permits the use of non-standard types (i.e., those - identified with the prefix string "X-") as a flexible method for - implementations to extend the functionality currently defined within - this profile. - -2. MIME Directory Features - - The vCard MIME Directory Profile makes use of many of the features - defined by [MIME-DIR]. The following sections either clarify or - extend the content-type definition of [MIME-DIR]. - -2.1 Predefined Type Usage - - The vCard MIME Directory Profile uses the following predefined types - from [MIME-DIR]. - -2.1.1 BEGIN and END Type - - The content entity MUST begin with the BEGIN type with a value of - "VCARD". The content entity MUST end with the END type with a value - of "VCARD". - -2.1.2 NAME Type - - If the NAME type is present, then its value is the displayable, - presentation text associated with the source for the vCard, as - specified in the SOURCE type. - -2.1.3 PROFILE Type - - If the PROFILE type is present, then its value MUST be "VCARD". - -2.1.4 SOURCE Type - - If the SOURCE type is present, then its value provides information - how to find the source for the vCard. - - - - - - - - - - - - -Dawson & Howes Standards Track [Page 5] - -RFC 2426 vCard MIME Directory Profile September 1998 - - -2.2 Predefined Type Parameter Usage - - The vCard MIME Directory Profile uses the following predefined type - parameters as defined by [MIME-DIR]. - - - LANGUAGE - - - ENCODING - - - VALUE - -2.3 Predefined VALUE Type Usage - - The predefined data type values specified in [MIME-DIR] MUST NOT be - repeated in COMMA separated value lists except within the N, - NICKNAME, ADR and CATEGORIES value types. - - The text value type defined in [MIME-DIR] is further restricted such - that any SEMI-COLON character (ASCII decimal 59) in the value MUST be - escaped with the BACKSLASH character (ASCII decimal 92). - -2.4 Extensions To The Predefined VALUE Types - - The predefined data type values specified in [MIME-DIR] have been - extended by the vCard profile to include a number of value types that - are specific to this profile. - -2.4.1 BINARY - - The "binary" value type specifies that the type value is inline, - encoded binary data. This value type can be specified in the PHOTO, - LOGO, SOUND, and KEY types. - - If inline encoded binary data is specified, the ENCODING type - parameter MUST be used to specify the encoding format. The binary - data MUST be encoded using the "B" encoding format. Long lines of - encoded binary data SHOULD BE folded to 75 characters using the - folding method defined in [MIME-DIR]. - - The value type is defined by the following notation: - - binary = <A "B" binary encoded string as defined by [RFC 2047].> - -2.4.2 VCARD - - The "vcard" value type specifies that the type value is another - vCard. This value type can be specified in the AGENT type. The value - type is defined by this specification. Since each of the type - - - -Dawson & Howes Standards Track [Page 6] - -RFC 2426 vCard MIME Directory Profile September 1998 - - - declarations with in the vcard value type are being specified within - a text value themselves, they MUST be terminated with the backslash - escape sequence "\n" or "\N", instead of the normal newline character - sequence CRLF. In addition, any COMMA character (ASCII decimal 44), - SEMI-COLON character (ASCII decimal 59) and COLON character (ASCII - decimal 58) MUST be escaped with the BACKSLASH character (ASCII - decimal 92). For example, with the AGENT type a value would be - specified as: - - AGENT:BEGIN:VCARD\nFN:Joe Friday\nTEL:+1-919-555-7878\n - TITLE:Area Administrator\, Assistant\n EMAIL\;TYPE=INTERN\n - ET:jfriday@host.com\nEND:VCARD\n - -2.4.3 PHONE-NUMBER - - The "phone-number" value type specifies that the type value is a - telephone number. This value type can be specified in the TEL type. - The value type is a text value that has the special semantics of a - telephone number as defined in [CCITT E.163] and [CCITT X.121]. - -2.4.4 UTC-OFFSET - - The "utc-offset" value type specifies that the type value is a signed - offset from UTC. This value type can be specified in the TZ type. - - The value type is an offset from Coordinated Universal Time (UTC). It - is specified as a positive or negative difference in units of hours - and minutes (e.g., +hh:mm). The time is specified as a 24-hour clock. - Hour values are from 00 to 23, and minute values are from 00 to 59. - Hour and minutes are 2-digits with high order zeroes required to - maintain digit count. The extended format for ISO 8601 UTC offsets - MUST be used. The extended format makes use of a colon character as a - separator of the hour and minute text fields. - - The value is defined by the following notation: - - time-hour = 2DIGIT ;00-23 - time-minute = 2DIGIT ;00-59 - utc-offset = ("+" / "-") time-hour ":" time-minute - -2.5 Structured Type Values - - Compound type values are delimited by a field delimiter, specified by - the SEMI-COLON character (ASCII decimal 59). A SEMI-COLON in a - component of a compound property value MUST be escaped with a - BACKSLASH character (ASCII decimal 92). - - - - - -Dawson & Howes Standards Track [Page 7] - -RFC 2426 vCard MIME Directory Profile September 1998 - - - Lists of values are delimited by a list delimiter, specified by the - COMMA character (ASCII decimal 44). A COMMA character in a value MUST - be escaped with a BACKSLASH character (ASCII decimal 92). - - This profile supports the type grouping mechanism defined in [MIME- - DIR]. Grouping of related types is a useful technique to communicate - common semantics concerning the properties of a vCard. - -2.6 Line Delimiting and Folding - - This profile supports the same line delimiting and folding methods - defined in [MIME-DIR]. Specifically, when parsing a content line, - folded lines must first be unfolded according to the unfolding - procedure described in [MIME-DIR]. After generating a content line, - lines longer than 75 characters SHOULD be folded according to the - folding procedure described in [MIME DIR]. - - Folding is done after any content encoding of a type value. Unfolding - is done before any decoding of a type value in a content line. - -3. vCard Profile Features - - The vCard MIME Directory Profile Type contains directory information, - typically pertaining to a single directory entry. The information is - described using an attribute schema that is tailored for capturing - personal contact information. The vCard can include attributes that - describe identification, delivery addressing, telecommunications - addressing, geographical, organizational, general explanatory and - security and access information about the particular object - associated with the vCard. - -3.1 Identification Types - - These types are used in the vCard profile to capture information - associated with the identification and naming of the person or - resource associated with the vCard. - -3.1.1 FN Type Definition - - To: ietf-mime-directory@imc.org - - Subject: Registration of text/directory MIME type FN - - Type name:FN - - Type purpose: To specify the formatted text corresponding to the name - of the object the vCard represents. - - - - -Dawson & Howes Standards Track [Page 8] - -RFC 2426 vCard MIME Directory Profile September 1998 - - - Type encoding: 8bit - - Type value: A single text value. - - Type special notes: This type is based on the semantics of the X.520 - Common Name attribute. The property MUST be present in the vCard - object. - - Type example: - - FN:Mr. John Q. Public\, Esq. - -3.1.2 N Type Definition - - To: ietf-mime-directory@imc.org - - Subject: Registration of text/directory MIME type N - - Type name: N - - Type purpose: To specify the components of the name of the object the - vCard represents. - - Type encoding: 8bit - - Type value: A single structured text value. Each component can have - multiple values. - - Type special note: The structured type value corresponds, in - sequence, to the Family Name, Given Name, Additional Names, Honorific - Prefixes, and Honorific Suffixes. The text components are separated - by the SEMI-COLON character (ASCII decimal 59). Individual text - components can include multiple text values (e.g., multiple - Additional Names) separated by the COMMA character (ASCII decimal - 44). This type is based on the semantics of the X.520 individual name - attributes. The property MUST be present in the vCard object. - - Type example: - - N:Public;John;Quinlan;Mr.;Esq. - - N:Stevenson;John;Philip,Paul;Dr.;Jr.,M.D.,A.C.P. - -3.1.3 NICKNAME Type Definition - - To: ietf-mime-directory@imc.org - - Subject: Registration of text/directory MIME type NICKNAME - - - -Dawson & Howes Standards Track [Page 9] - -RFC 2426 vCard MIME Directory Profile September 1998 - - - Type name: NICKNAME - - Type purpose: To specify the text corresponding to the nickname of - the object the vCard represents. - - Type encoding: 8bit - - Type value: One or more text values separated by a COMMA character - (ASCII decimal 44). - - Type special note: The nickname is the descriptive name given instead - of or in addition to the one belonging to a person, place, or thing. - It can also be used to specify a familiar form of a proper name - specified by the FN or N types. - - Type example: - - NICKNAME:Robbie - - NICKNAME:Jim,Jimmie - -3.1.4 PHOTO Type Definition - - To: ietf-mime-directory@imc.org - - Subject: Registration of text/directory MIME type PHOTO - - Type name: PHOTO - - Type purpose: To specify an image or photograph information that - annotates some aspect of the object the vCard represents. - - Type encoding: The encoding MUST be reset to "b" using the ENCODING - parameter in order to specify inline, encoded binary data. If the - value is referenced by a URI value, then the default encoding of 8bit - is used and no explicit ENCODING parameter is needed. - - Type value: A single value. The default is binary value. It can also - be reset to uri value. The uri value can be used to specify a value - outside of this MIME entity. - - Type special notes: The type can include the type parameter "TYPE" to - specify the graphic image format type. The TYPE parameter values MUST - be one of the IANA registered image formats or a non-standard image - format. - - - - - - -Dawson & Howes Standards Track [Page 10] - -RFC 2426 vCard MIME Directory Profile September 1998 - - - Type example: - - PHOTO;VALUE=uri:http://www.abc.com/pub/photos - /jqpublic.gif - - - PHOTO;ENCODING=b;TYPE=JPEG:MIICajCCAdOgAwIBAgICBEUwDQYJKoZIhvcN - AQEEBQAwdzELMAkGA1UEBhMCVVMxLDAqBgNVBAoTI05ldHNjYXBlIENvbW11bm - ljYXRpb25zIENvcnBvcmF0aW9uMRwwGgYDVQQLExNJbmZvcm1hdGlvbiBTeXN0 - <...remainder of "B" encoded binary data...> - -3.1.5 BDAY Type Definition - - To: ietf-mime-directory@imc.org - - Subject: Registration of text/directory MIME type BDAY - - Type name: BDAY - - Type purpose: To specify the birth date of the object the vCard - represents. - - Type encoding: 8bit - - Type value: The default is a single date value. It can also be reset - to a single date-time value. - - Type examples: - - BDAY:1996-04-15 - - BDAY:1953-10-15T23:10:00Z - - BDAY:1987-09-27T08:30:00-06:00 - -3.2 Delivery Addressing Types - - These types are concerned with information related to the delivery - addressing or label for the vCard object. - -3.2.1 ADR Type Definition - - To: ietf-mime-directory@imc.org - - Subject: Registration of text/directory MIME type ADR - - Type name: ADR - - - - -Dawson & Howes Standards Track [Page 11] - -RFC 2426 vCard MIME Directory Profile September 1998 - - - Type purpose: To specify the components of the delivery address for - the vCard object. - - Type encoding: 8bit - - Type value: A single structured text value, separated by the - SEMI-COLON character (ASCII decimal 59). - - Type special notes: The structured type value consists of a sequence - of address components. The component values MUST be specified in - their corresponding position. The structured type value corresponds, - in sequence, to the post office box; the extended address; the street - address; the locality (e.g., city); the region (e.g., state or - province); the postal code; the country name. When a component value - is missing, the associated component separator MUST still be - specified. - - The text components are separated by the SEMI-COLON character (ASCII - decimal 59). Where it makes semantic sense, individual text - components can include multiple text values (e.g., a "street" - component with multiple lines) separated by the COMMA character - (ASCII decimal 44). - - The type can include the type parameter "TYPE" to specify the - delivery address type. The TYPE parameter values can include "dom" to - indicate a domestic delivery address; "intl" to indicate an - international delivery address; "postal" to indicate a postal - delivery address; "parcel" to indicate a parcel delivery address; - "home" to indicate a delivery address for a residence; "work" to - indicate delivery address for a place of work; and "pref" to indicate - the preferred delivery address when more than one address is - specified. These type parameter values can be specified as a - parameter list (i.e., "TYPE=dom;TYPE=postal") or as a value list - (i.e., "TYPE=dom,postal"). This type is based on semantics of the - X.520 geographical and postal addressing attributes. The default is - "TYPE=intl,postal,parcel,work". The default can be overridden to some - other set of values by specifying one or more alternate values. For - example, the default can be reset to "TYPE=dom,postal,work,home" to - specify a domestic delivery address for postal delivery to a - residence that is also used for work. - - Type example: In this example the post office box and the extended - address are absent. - - ADR;TYPE=dom,home,postal,parcel:;;123 Main - Street;Any Town;CA;91921-1234 - - - - - -Dawson & Howes Standards Track [Page 12] - -RFC 2426 vCard MIME Directory Profile September 1998 - - -3.2.2 LABEL Type Definition - - To: ietf-mime-directory@imc.org - - Subject: Registration of text/directory MIME type LABEL - - Type name: LABEL - - Type purpose: To specify the formatted text corresponding to delivery - address of the object the vCard represents. - - Type encoding: 8bit - - Type value: A single text value. - - Type special notes: The type value is formatted text that can be used - to present a delivery address label for the vCard object. The type - can include the type parameter "TYPE" to specify delivery label type. - The TYPE parameter values can include "dom" to indicate a domestic - delivery label; "intl" to indicate an international delivery label; - "postal" to indicate a postal delivery label; "parcel" to indicate a - parcel delivery label; "home" to indicate a delivery label for a - residence; "work" to indicate delivery label for a place of work; and - "pref" to indicate the preferred delivery label when more than one - label is specified. These type parameter values can be specified as a - parameter list (i.e., "TYPE=dom;TYPE=postal") or as a value list - (i.e., "TYPE=dom,postal"). This type is based on semantics of the - X.520 geographical and postal addressing attributes. The default is - "TYPE=intl,postal,parcel,work". The default can be overridden to some - other set of values by specifying one or more alternate values. For - example, the default can be reset to "TYPE=intl,post,parcel,home" to - specify an international delivery label for both postal and parcel - delivery to a residential location. - - Type example: A multi-line address label. - - LABEL;TYPE=dom,home,postal,parcel:Mr.John Q. Public\, Esq.\n - Mail Drop: TNE QB\n123 Main Street\nAny Town\, CA 91921-1234 - \nU.S.A. - -3.3 Telecommunications Addressing Types - - These types are concerned with information associated with the - telecommunications addressing of the object the vCard represents. - - - - - - - -Dawson & Howes Standards Track [Page 13] - -RFC 2426 vCard MIME Directory Profile September 1998 - - -3.3.1 TEL Type Definition - - To: ietf-mime-directory@imc.org - - Subject: Registration of text/directory MIME type TEL - - Type name: TEL - - Type purpose: To specify the telephone number for telephony - communication with the object the vCard represents. - - Type encoding: 8bit - - Type value: A single phone-number value. - - Type special notes: The value of this type is specified in a - canonical form in order to specify an unambiguous representation of - the globally unique telephone endpoint. This type is based on the - X.500 Telephone Number attribute. - - The type can include the type parameter "TYPE" to specify intended - use for the telephone number. The TYPE parameter values can include: - "home" to indicate a telephone number associated with a residence, - "msg" to indicate the telephone number has voice messaging support, - "work" to indicate a telephone number associated with a place of - work, "pref" to indicate a preferred-use telephone number, "voice" to - indicate a voice telephone number, "fax" to indicate a facsimile - telephone number, "cell" to indicate a cellular telephone number, - "video" to indicate a video conferencing telephone number, "pager" to - indicate a paging device telephone number, "bbs" to indicate a - bulletin board system telephone number, "modem" to indicate a MODEM - connected telephone number, "car" to indicate a car-phone telephone - number, "isdn" to indicate an ISDN service telephone number, "pcs" to - indicate a personal communication services telephone number. The - default type is "voice". These type parameter values can be specified - as a parameter list (i.e., "TYPE=work;TYPE=voice") or as a value list - (i.e., "TYPE=work,voice"). The default can be overridden to another - set of values by specifying one or more alternate values. For - example, the default TYPE of "voice" can be reset to a WORK and HOME, - VOICE and FAX telephone number by the value list - "TYPE=work,home,voice,fax". - - Type example: - - TEL;TYPE=work,voice,pref,msg:+1-213-555-1234 - - - - - - -Dawson & Howes Standards Track [Page 14] - -RFC 2426 vCard MIME Directory Profile September 1998 - - -3.3.2 EMAIL Type Definition - - To: ietf-mime-directory@imc.org - - Subject: Registration of text/directory MIME type EMAIL - - Type name: EMAIL - - Type purpose: To specify the electronic mail address for - communication with the object the vCard represents. - - Type encoding: 8bit - - Type value: A single text value. - - Type special notes: The type can include the type parameter "TYPE" to - specify the format or preference of the electronic mail address. The - TYPE parameter values can include: "internet" to indicate an Internet - addressing type, "x400" to indicate a X.400 addressing type or "pref" - to indicate a preferred-use email address when more than one is - specified. Another IANA registered address type can also be - specified. The default email type is "internet". A non-standard value - can also be specified. - - Type example: - - EMAIL;TYPE=internet:jqpublic@xyz.dom1.com - - EMAIL;TYPE=internet:jdoe@isp.net - - EMAIL;TYPE=internet,pref:jane_doe@abc.com - -3.3.3 MAILER Type Definition - - To: ietf-mime-directory@imc.org - - Subject: Registration of text/directory MIME type MAILER - - Type name: MAILER - - Type purpose: To specify the type of electronic mail software that is - used by the individual associated with the vCard. - - Type encoding: 8bit - - Type value: A single text value. - - - - - -Dawson & Howes Standards Track [Page 15] - -RFC 2426 vCard MIME Directory Profile September 1998 - - - Type special notes: This information can provide assistance to a - correspondent regarding the type of data representation which can be - used, and how they can be packaged. This property is based on the - private MIME type X-Mailer that is generally implemented by MIME user - agent products. - - Type example: - - MAILER:PigeonMail 2.1 - -3.4 Geographical Types - - These types are concerned with information associated with - geographical positions or regions associated with the object the - vCard represents. - -3.4.1 TZ Type Definition - - To: ietf-mime-directory@imc.org - - Subject: Registration of text/directory MIME type TZ - - Type name: TZ - - Type purpose: To specify information related to the time zone of the - object the vCard represents. - - Type encoding: 8bit - - Type value: The default is a single utc-offset value. It can also be - reset to a single text value. - - Type special notes: The type value consists of a single value. - - Type examples: - - TZ:-05:00 - - TZ;VALUE=text:-05:00; EST; Raleigh/North America - ;This example has a single value, not a structure text value. - -3.4.2 GEO Type Definition - - To: ietf-mime-directory@imc.org - - Subject: Registration of text/directory MIME type GEO - - Type name: GEO - - - -Dawson & Howes Standards Track [Page 16] - -RFC 2426 vCard MIME Directory Profile September 1998 - - - Type purpose: To specify information related to the global - positioning of the object the vCard represents. - - Type encoding: 8bit - - Type value: A single structured value consisting of two float values - separated by the SEMI-COLON character (ASCII decimal 59). - - Type special notes: This type specifies information related to the - global position of the object associated with the vCard. The value - specifies latitude and longitude, in that order (i.e., "LAT LON" - ordering). The longitude represents the location east and west of the - prime meridian as a positive or negative real number, respectively. - The latitude represents the location north and south of the equator - as a positive or negative real number, respectively. The longitude - and latitude values MUST be specified as decimal degrees and should - be specified to six decimal places. This will allow for granularity - within a meter of the geographical position. The text components are - separated by the SEMI-COLON character (ASCII decimal 59). The simple - formula for converting degrees-minutes-seconds into decimal degrees - is: - - decimal = degrees + minutes/60 + seconds/3600. - - Type example: - - GEO:37.386013;-122.082932 - -3.5 Organizational Types - - These types are concerned with information associated with - characteristics of the organization or organizational units of the - object the vCard represents. - -3.5.1 TITLE Type Definition - - To: ietf-mime-directory@imc.org - - Subject: Registration of text/directory MIME type TITLE - - Type name: TITLE - - Type purpose: To specify the job title, functional position or - function of the object the vCard represents. - - Type encoding: 8bit - - Type value: A single text value. - - - -Dawson & Howes Standards Track [Page 17] - -RFC 2426 vCard MIME Directory Profile September 1998 - - - Type special notes: This type is based on the X.520 Title attribute. - - Type example: - - TITLE:Director\, Research and Development - -3.5.2 ROLE Type Definition - - To: ietf-mime-directory@imc.org - - Subject: Registration of text/directory MIME type ROLE - - Type name: ROLE - - Type purpose: To specify information concerning the role, occupation, - or business category of the object the vCard represents. - - Type encoding: 8bit - - Type value: A single text value. - - Type special notes: This type is based on the X.520 Business Category - explanatory attribute. This property is included as an organizational - type to avoid confusion with the semantics of the TITLE type and - incorrect usage of that type when the semantics of this type is - intended. - - Type example: - - ROLE:Programmer - -3.5.3 LOGO Type Definition - - To: ietf-mime-directory@imc.org - - Subject: Registration of text/directory MIME type LOGO - - Type name: LOGO - - Type purpose: To specify a graphic image of a logo associated with - the object the vCard represents. - - Type encoding: The encoding MUST be reset to "b" using the ENCODING - parameter in order to specify inline, encoded binary data. If the - value is referenced by a URI value, then the default encoding of 8bit - is used and no explicit ENCODING parameter is needed. - - - - - -Dawson & Howes Standards Track [Page 18] - -RFC 2426 vCard MIME Directory Profile September 1998 - - - Type value: A single value. The default is binary value. It can also - be reset to uri value. The uri value can be used to specify a value - outside of this MIME entity. - - Type special notes: The type can include the type parameter "TYPE" to - specify the graphic image format type. The TYPE parameter values MUST - be one of the IANA registered image formats or a non-standard image - format. - - Type example: - - LOGO;VALUE=uri:http://www.abc.com/pub/logos/abccorp.jpg - - LOGO;ENCODING=b;TYPE=JPEG:MIICajCCAdOgAwIBAgICBEUwDQYJKoZIhvcN - AQEEBQAwdzELMAkGA1UEBhMCVVMxLDAqBgNVBAoTI05ldHNjYXBlIENvbW11bm - ljYXRpb25zIENvcnBvcmF0aW9uMRwwGgYDVQQLExNJbmZvcm1hdGlvbiBTeXN0 - <...the remainder of "B" encoded binary data...> - -3.5.4 AGENT Type Definition - - To: ietf-mime-directory@imc.org - - Subject: Registration of text/directory MIME type AGENT - - Type name: AGENT - - Type purpose: To specify information about another person who will - act on behalf of the individual or resource associated with the - vCard. - - Type encoding: 8-bit - - Type value: The default is a single vcard value. It can also be reset - to either a single text or uri value. The text value can be used to - specify textual information. The uri value can be used to specify - information outside of this MIME entity. - - Type special notes: This type typically is used to specify an area - administrator, assistant, or secretary for the individual associated - with the vCard. A key characteristic of the Agent type is that it - represents somebody or something that is separately addressable. - - Type example: - - AGENT;VALUE=uri: - CID:JQPUBLIC.part3.960129T083020.xyzMail@host3.com - - - - - -Dawson & Howes Standards Track [Page 19] - -RFC 2426 vCard MIME Directory Profile September 1998 - - - AGENT:BEGIN:VCARD\nFN:Susan Thomas\nTEL:+1-919-555- - 1234\nEMAIL\;INTERNET:sthomas@host.com\nEND:VCARD\n - -3.5.5 ORG Type Definition - - To: ietf-mime-directory@imc.org - - Subject: Registration of text/directory MIME type ORG - - Type name: ORG - - Type purpose: To specify the organizational name and units associated - with the vCard. - - Type encoding: 8bit - - Type value: A single structured text value consisting of components - separated the SEMI-COLON character (ASCII decimal 59). - - Type special notes: The type is based on the X.520 Organization Name - and Organization Unit attributes. The type value is a structured type - consisting of the organization name, followed by one or more levels - of organizational unit names. - - Type example: A type value consisting of an organizational name, - organizational unit #1 name and organizational unit #2 name. - - ORG:ABC\, Inc.;North American Division;Marketing - -3.6 Explanatory Types - - These types are concerned with additional explanations, such as that - related to informational notes or revisions specific to the vCard. - -3.6.1 CATEGORIES Type Definition - - To: ietf-mime-directory@imc.org - - Subject: Registration of text/directory MIME type CATEGORIES - - Type name: CATEGORIES - - Type purpose: To specify application category information about the - vCard. - - Type encoding: 8bit - - - - - -Dawson & Howes Standards Track [Page 20] - -RFC 2426 vCard MIME Directory Profile September 1998 - - - Type value: One or more text values separated by a COMMA character - (ASCII decimal 44). - - Type example: - - CATEGORIES:TRAVEL AGENT - - CATEGORIES:INTERNET,IETF,INDUSTRY,INFORMATION TECHNOLOGY - -3.6.2 NOTE Type Definition - - To: ietf-mime-directory@imc.org - - Subject: Registration of text/directory MIME type NOTE - - Type name: NOTE - - Type purpose: To specify supplemental information or a comment that - is associated with the vCard. - - Type encoding: 8bit - - Type value: A single text value. - - Type special notes: The type is based on the X.520 Description - attribute. - - Type example: - - NOTE:This fax number is operational 0800 to 1715 - EST\, Mon-Fri. - -3.6.3 PRODID Type Definition - - To: ietf-mime-directory@imc.org - - Subject: Registration of text/directory MIME type PRODID - - Type name: PRODID - - Type purpose: To specify the identifier for the product that created - the vCard object. - - Type encoding: 8-bit - - Type value: A single text value. - - - - - -Dawson & Howes Standards Track [Page 21] - -RFC 2426 vCard MIME Directory Profile September 1998 - - - Type special notes: Implementations SHOULD use a method such as that - specified for Formal Public Identifiers in ISO 9070 to assure that - the text value is unique. - - Type example: - - PRODID:-//ONLINE DIRECTORY//NONSGML Version 1//EN - -3.6.4 REV Type Definition - - To: ietf-mime-directory@imc.org - - Subject: Registration of text/directory MIME type REV - - Type name: REV - - Type purpose: To specify revision information about the current - vCard. - - Type encoding: 8-bit - - Type value: The default is a single date-time value. Can also be - reset to a single date value. - - Type special notes: The value distinguishes the current revision of - the information in this vCard for other renditions of the - information. - - Type example: - - REV:1995-10-31T22:27:10Z - - REV:1997-11-15 - -3.6.5 SORT-STRING Type Definition - - To: ietf-mime-directory@imc.org - - Subject: Registration of text/directory MIME type SORT-STRING - - Type Name: SORT-STRING - - Type purpose: To specify the family name or given name text to be - used for national-language-specific sorting of the FN and N types. - - Type encoding: 8bit - - Type value: A single text value. - - - -Dawson & Howes Standards Track [Page 22] - -RFC 2426 vCard MIME Directory Profile September 1998 - - - Type special notes: The sort string is used to provide family name or - given name text that is to be used in locale- or national-language- - specific sorting of the formatted name and structured name types. - Without this information, sorting algorithms could incorrectly sort - this vCard within a sequence of sorted vCards. When this type is - present in a vCard, then this family name or given name value is used - for sorting the vCard. - - Type examples: For the case of family name sorting, the following - examples define common sort string usage with the FN and N types. - - FN:Rene van der Harten - N:van der Harten;Rene;J.;Sir;R.D.O.N. - SORT-STRING:Harten - - FN:Robert Pau Shou Chang - N:Pau;Shou Chang;Robert - SORT-STRING:Pau - - FN:Osamu Koura - N:Koura;Osamu - SORT-STRING:Koura - - FN:Oscar del Pozo - N:del Pozo Triscon;Oscar - SORT-STRING:Pozo - - FN:Chistine d'Aboville - N:d'Aboville;Christine - SORT-STRING:Aboville - -3.6.6 SOUND Type Definition - - To: ietf-mime-directory@imc.org - - Subject: Registration of text/directory MIME type SOUND - - Type name: SOUND - - Type purpose: To specify a digital sound content information that - annotates some aspect of the vCard. By default this type is used to - specify the proper pronunciation of the name type value of the vCard. - - Type encoding: The encoding MUST be reset to "b" using the ENCODING - parameter in order to specify inline, encoded binary data. If the - value is referenced by a URI value, then the default encoding of 8bit - is used and no explicit ENCODING parameter is needed. - - - - -Dawson & Howes Standards Track [Page 23] - -RFC 2426 vCard MIME Directory Profile September 1998 - - - Type value: A single value. The default is binary value. It can also - be reset to uri value. The uri value can be used to specify a value - outside of this MIME entity. - - Type special notes: The type can include the type parameter "TYPE" to - specify the audio format type. The TYPE parameter values MUST be one - of the IANA registered audio formats or a non-standard audio format. - - Type example: - - SOUND;TYPE=BASIC;VALUE=uri:CID:JOHNQPUBLIC.part8. - 19960229T080000.xyzMail@host1.com - - SOUND;TYPE=BASIC;ENCODING=b:MIICajCCAdOgAwIBAgICBEUwDQYJKoZIhvcN - AQEEBQAwdzELMAkGA1UEBhMCVVMxLDAqBgNVBAoTI05ldHNjYXBlIENvbW11bm - ljYXRpb25zIENvcnBvcmF0aW9uMRwwGgYDVQQLExNJbmZvcm1hdGlvbiBTeXN0 - <...the remainder of "B" encoded binary data...> - -3.6.7 UID Type Definition - - To: ietf-mime-directory@imc.org - - Subject: Registration of text/directory MIME type UID - - Type name: UID - - Type purpose: To specify a value that represents a globally unique - identifier corresponding to the individual or resource associated - with the vCard. - - Type encoding: 8bit - - Type value: A single text value. - - Type special notes: The type is used to uniquely identify the object - that the vCard represents. - - The type can include the type parameter "TYPE" to specify the format - of the identifier. The TYPE parameter value should be an IANA - registered identifier format. The value can also be a non-standard - format. - - Type example: - - UID:19950401-080045-40000F192713-0052 - - - - - - -Dawson & Howes Standards Track [Page 24] - -RFC 2426 vCard MIME Directory Profile September 1998 - - -3.6.8 URL Type Definition - - To: ietf-mime-directory@imc.org - - Subject: Registration of text/directory MIME type URL - - Type name: URL - - Type purpose: To specify a uniform resource locator associated with - the object that the vCard refers to. - - Type encoding: 8bit - - Type value: A single uri value. - - Type example: - - URL:http://www.swbyps.restaurant.french/~chezchic.html - -3.6.9 VERSION Type Definition - - To: ietf-mime-directory@imc.org - - Subject: Registration of text/directory MIME type VERSION - - Type name: VERSION - - Type purpose: To specify the version of the vCard specification used - to format this vCard. - - Type encoding: 8bit - - Type value: A single text value. - - Type special notes: The property MUST be present in the vCard object. - The value MUST be "3.0" if the vCard corresponds to this - specification. - - Type example: - - VERSION:3.0 - -3.7 Security Types - - These types are concerned with the security of communication pathways - or access to the vCard. - - - - - -Dawson & Howes Standards Track [Page 25] - -RFC 2426 vCard MIME Directory Profile September 1998 - - -3.7.1 CLASS Type Definition - - To: ietf-mime-directory@imc.org - - Subject: Registration of text/directory MIME type CLASS - - Type name: CLASS - - Type purpose: To specify the access classification for a vCard - object. - - Type encoding: 8bit - - Type value: A single text value. - - Type special notes: An access classification is only one component of - the general security model for a directory service. The - classification attribute provides a method of capturing the intent of - the owner for general access to information described by the vCard - object. - - Type examples: - - CLASS:PUBLIC - - CLASS:PRIVATE - - CLASS:CONFIDENTIAL - -3.7.2 KEY Type Definition - - To: ietf-mime-directory@imc.org - - Subject: Registration of text/directory MIME type KEY - - Type name: KEY - - Type purpose: To specify a public key or authentication certificate - associated with the object that the vCard represents. - - Type encoding: The encoding MUST be reset to "b" using the ENCODING - parameter in order to specify inline, encoded binary data. If the - value is a text value, then the default encoding of 8bit is used and - no explicit ENCODING parameter is needed. - - Type value: A single value. The default is binary. It can also be - reset to text value. The text value can be used to specify a text - key. - - - -Dawson & Howes Standards Track [Page 26] - -RFC 2426 vCard MIME Directory Profile September 1998 - - - Type special notes: The type can also include the type parameter TYPE - to specify the public key or authentication certificate format. The - parameter type should specify an IANA registered public key or - authentication certificate format. The parameter type can also - specify a non-standard format. - - Type example: - - KEY;ENCODING=b:MIICajCCAdOgAwIBAgICBEUwDQYJKoZIhvcNAQEEBQA - wdzELMAkGA1UEBhMCVVMxLDAqBgNVBAoTI05ldHNjYXBlIENbW11bmljYX - Rpb25zIENvcnBvcmF0aW9uMRwwGgYDVQQLExNJbmZvcm1hdGlvbiBTeXN0 - ZW1zMRwwGgYDVQQDExNyb290Y2EubmV0c2NhcGUuY29tMB4XDTk3MDYwNj - E5NDc1OVoXDTk3MTIwMzE5NDc1OVowgYkxCzAJBgNVBAYTAlVTMSYwJAYD - VQQKEx1OZXRzY2FwZSBDb21tdW5pY2F0aW9ucyBDb3JwLjEYMBYGA1UEAx - MPVGltb3RoeSBBIEhvd2VzMSEwHwYJKoZIhvcNAQkBFhJob3dlc0BuZXRz - Y2FwZS5jb20xFTATBgoJkiaJk/IsZAEBEwVob3dlczBcMA0GCSqGSIb3DQ - EBAQUAA0sAMEgCQQC0JZf6wkg8pLMXHHCUvMfL5H6zjSk4vTTXZpYyrdN2 - dXcoX49LKiOmgeJSzoiFKHtLOIboyludF90CgqcxtwKnAgMBAAGjNjA0MB - EGCWCGSAGG+EIBAQQEAwIAoDAfBgNVHSMEGDAWgBT84FToB/GV3jr3mcau - +hUMbsQukjANBgkqhkiG9w0BAQQFAAOBgQBexv7o7mi3PLXadkmNP9LcIP - mx93HGp0Kgyx1jIVMyNgsemeAwBM+MSlhMfcpbTrONwNjZYW8vJDSoi//y - rZlVt9bJbs7MNYZVsyF1unsqaln4/vy6Uawfg8VUMk1U7jt8LYpo4YULU7 - UZHPYVUaSgVttImOHZIKi4hlPXBOhcUQ== - -3.8 Extended Types - - The types defined by this document can be extended with private types - using the non-standard, private values mechanism defined in [RFC - 2045]. Non-standard, private types with a name starting with "X-" may - be defined bilaterally between two cooperating agents without outside - registration or standardization. - -4. Formal Grammar - - The following formal grammar is provided to assist developers in - building parsers for the vCard. - - This syntax is written according to the form described in RFC 2234, - but it references just this small subset of RFC 2234 literals: - - ;******************************************* - ; Commonly Used Literal Definition - ;******************************************* - - ALPHA = %x41-5A / %x61-7A - ; Latin Capital Letter A-Latin Capital Letter Z / - ; Latin Small Letter a-Latin Small Letter z - - - - -Dawson & Howes Standards Track [Page 27] - -RFC 2426 vCard MIME Directory Profile September 1998 - - - CHAR = %x01-7F - ; Any C0 Controls and Basic Latin, excluding NULL from - ; Code Charts, pages 7-6 through 7-9 in [UNICODE] - - CR = %x0D - ; Carriage Return - - LF = %0A - ; Line Feed - - CRLF = CR LF - ; Internet standard newline - - ;CTL = %x00-1F / %x7F - ; Controls. Not used, but referenced in comments. - - DIGIT = %x30-39 - ; Digit Zero-Digit Nine - - DQUOTE = %x22 - ; Quotation Mark - - HTAB = %x09 - ; Horizontal Tabulation - - SP = %x20 - ; space - - VCHAR = %x21-7E - ; Visible (printing) characters - - WSP = SP / HTAB - ; White Space - - ;******************************************* - ; Basic vCard Definition - ;******************************************* - - vcard_entity = 1*(vcard) - - vcard = [group "."] "BEGIN" ":" "VCARD" 1*CRLF - 1*(contentline) - ;A vCard object MUST include the VERSION, FN and N types. - [group "."] "END" ":" "VCARD" 1*CRLF - - contentline = [group "."] name *(";" param ) ":" value CRLF - ; When parsing a content line, folded lines must first - ; be unfolded according to the unfolding procedure - - - -Dawson & Howes Standards Track [Page 28] - -RFC 2426 vCard MIME Directory Profile September 1998 - - - ; described above. When generating a content line, lines - ; longer than 75 characters SHOULD be folded according to - ; the folding procedure described in [MIME DIR]. - - group = 1*(ALPHA / DIGIT / "-") - - name = iana-token / x-name - ; Parsing of the param and value is - ; based on the "name" or type identifier - ; as defined in ABNF sections below - - iana-token = 1*(ALPHA / DIGIT / "-") - ; vCard type or parameter identifier registered with IANA - - x-name = "X-" 1*(ALPHA / DIGIT / "-") - ; Reserved for non-standard use - - param = param-name "=" param-value *("," param-value) - - param-name = iana-token / x-name - - param-value = ptext / quoted-string - - ptext = *SAFE-CHAR - - value = *VALUE-CHAR - - quoted-string = DQUOTE QSAFE-CHAR DQUOTE - - NON-ASCII = %x80-FF - ; Use is restricted by CHARSET parameter - ; on outer MIME object (UTF-8 preferred) - - QSAFE-CHAR = WSP / %x21 / %x23-7E / NON-ASCII - ; Any character except CTLs, DQUOTE - - SAFE-CHAR = WSP / %x21 / %x23-2B / %x2D-39 / %x3C-7E / NON-ASCII - ; Any character except CTLs, DQUOTE, ";", ":", "," - - VALUE-CHAR = WSP / VCHAR / NON-ASCII - ; Any textual character - - ;******************************************* - ; vCard Type Definition - ; - ; Provides type-specific definitions for how the - ; "value" and "param" are defined. - ;******************************************* - - - -Dawson & Howes Standards Track [Page 29] - -RFC 2426 vCard MIME Directory Profile September 1998 - - - ;For name="NAME" - param = "" - ; No parameters allowed - - value = text-value - - ;For name="PROFILE" - param = "" - ; No parameters allowed - - value = text-value - ; Value MUST be the case insensitive value "VCARD - - ;For name="SOURCE" - param = source-param - ; No parameters allowed - - value = uri - - source-param = ("VALUE" "=" "uri") - / ("CONTEXT" "=" "word") - ; Parameter value specifies the protocol context - ; for the uri value. - / (x-name "=" *SAFE-CHAR) - - ;For name="FN" - ;This type MUST be included in a vCard object. - param = text-param - ; Text parameters allowed - - value = text-value - - ;For name="N" - ;This type MUST be included in a vCard object. - - param = text-param - ; Text parameters allowed - - value = n-value - - n-value = 0*4(text-value *("," text-value) ";") - text-value *("," text-value) - ; Family; Given; Middle; Prefix; Suffix. - ; Example: Public;John;Quincy,Adams;Reverend Dr. III - - ;For name="NICKNAME" - param = text-param - ; Text parameters allowed - - - -Dawson & Howes Standards Track [Page 30] - -RFC 2426 vCard MIME Directory Profile September 1998 - - - value = text-list - - ;For name="PHOTO" - param = img-inline-param - ; Only image parameters allowed - - param =/ img-refer-param - ; Only image parameters allowed - - value = img-inline-value - ; Value and parameter MUST match - - value =/ img-refer-value - ; Value and parameter MUST match - - ;For name="BDAY" - param = ("VALUE" "=" "date") - ; Only value parameter allowed - - param =/ ("VALUE" "=" "date-time") - ; Only value parameter allowed - - value = date-value - ; Value MUST match value type - - value =/ date-time-value - ; Value MUST match value type - - ;For name="ADR" - param = adr-param / text-param - ; Only adr and text parameters allowed - - value = adr-value - - ;For name="LABEL" - param = adr-param / text-param - ; Only adr and text parameters allowed - - value = text-value - - ;For name="TEL" - param = tel-param - ; Only tel parameters allowed - - value = phone-number-value - - tel-param = "TYPE" "=" tel-type *("," tel-type) - - - - -Dawson & Howes Standards Track [Page 31] - -RFC 2426 vCard MIME Directory Profile September 1998 - - - tel-type = "HOME" / "WORK" / "PREF" / "VOICE" / "FAX" / "MSG" - / "CELL" / "PAGER" / "BBS" / "MODEM" / "CAR" / "ISDN" - / "VIDEO" / "PCS" / iana-token / x-name - ; Values are case insensitive - - ;For name="EMAIL" - param = email-param - ; Only email parameters allowed - - value = text-value - - email-param = "TYPE" "=" email-type ["," "PREF"] - ; Value is case insensitive - - email-type = "INTERNET" / "X400" / iana-token / "X-" word - ; Values are case insensitive - - ;For name="MAILER" - param = text-param - ; Only text parameters allowed - - value = text-value - - ;For name="TZ" - param = "" - ; No parameters allowed - - value = utc-offset-value - - ;For name="GEO" - param = "" - ; No parameters allowed - - value = float-value ";" float-value - - ;For name="TITLE" - param = text-param - ; Only text parameters allowed - - value = text-value - - ;For name="ROLE" - param = text-param - ; Only text parameters allowed - - value = text-value - - ;For name="LOGO" - - - -Dawson & Howes Standards Track [Page 32] - -RFC 2426 vCard MIME Directory Profile September 1998 - - - param = img-inline-param / img-refer-param - ; Only image parameters allowed - - value = img-inline-value / img-refer-value - ; Value and parameter MUST match - - ;For name="AGENT" - param = agent-inline-param - - param =/ agent-refer-param - - value = agent-inline-value - ; Value and parameter MUST match - - value =/ agent-refer-value - ; Value and parameter MUST match - - agent-inline-param = "" - ; No parameters allowed - - agent-refer-param = "VALUE" "=" "uri" - ; Only value parameter allowed - - agent-inline-value = text-value - ; Value MUST be a valid vCard object - - agent-refer-value = uri - ; URI MUST refer to image content of given type - - ;For name="ORG" - - param = text-param - ; Only text parameters allowed - - value = org-value - - org-value = *(text-value ";") text-value - ; First is Organization Name, remainder are Organization Units. - - ;For name="CATEGORIES" - param = text-param - ; Only text parameters allowed - - value = text-list - - ;For name="NOTE" - param = text-param - ; Only text parameters allowed - - - -Dawson & Howes Standards Track [Page 33] - -RFC 2426 vCard MIME Directory Profile September 1998 - - - value = text-value - - ;For name="PRODID" - param = "" - ; No parameters allowed - - value = text-value - - ;For name="REV" - param = ["VALUE" =" "date-time"] - ; Only value parameters allowed. Values are case insensitive. - - param =/ "VALUE" =" "date" - ; Only value parameters allowed. Values are case insensitive. - - value = date-time-value - - value =/ date-value - - ;For name="SORT-STRING" - param = text-param - ; Only text parameters allowed - - value = text-value - - ;For name="SOUND" - param = snd-inline-param - ; Only sound parameters allowed - - param =/ snd-refer-param - ; Only sound parameters allowed - - value = snd-line-value - ; Value MUST match value type - - value =/ snd-refer-value - ; Value MUST match value type - - snd-inline-value = binary-value CRLF - ; Value MUST be "b" encoded audio content - - snd-inline-param = ("VALUE" "=" "binary"]) - / ("ENCODING" "=" "b") - / ("TYPE" "=" *SAFE-CHAR) - ; Value MUST be an IANA registered audio type - - snd-refer-value = uri - ; URI MUST refer to audio content of given type - - - -Dawson & Howes Standards Track [Page 34] - -RFC 2426 vCard MIME Directory Profile September 1998 - - - snd-refer-param = ("VALUE" "=" "uri") - / ("TYPE" "=" word) - ; Value MUST be an IANA registered audio type - - ;For name="UID" - param = "" - ; No parameters allowed - - value = text-value - - ;For name="URL" - param = "" - ; No parameters allowed - - value = uri - - ;For name="VERSION" - ;This type MUST be included in a vCard object. - param = "" - ; No parameters allowed - - value = text-value - ; Value MUST be "3.0" - - ;For name="CLASS" - param = "" - ; No parameters allowed - - value = "PUBLIC" / "PRIVATE" / "CONFIDENTIAL" - / iana-token / x-name - ; Value are case insensitive - - ;For name="KEY" - param = key-txt-param - ; Only value and type parameters allowed - - param =/ key-bin-param - ; Only value and type parameters allowed - - value = text-value - - value =/ binary-value - - key-txt-param = "TYPE" "=" keytype - - key-bin-param = ("TYPE" "=" keytype) - / ("ENCODING" "=" "b") - ; Value MUST be a "b" encoded key or certificate - - - -Dawson & Howes Standards Track [Page 35] - -RFC 2426 vCard MIME Directory Profile September 1998 - - - keytype = "X509" / "PGP" / iana-token / x-name - ; Values are case insensitive - - ;For name="X-" non-standard type - param = text-param / (x-name "=" param-value) - ; Only text or non-standard parameters allowed - - value = text-value - - ;******************************************* - ; vCard Commonly Used Parameter Definition - ;******************************************* - - text-param = ("VALUE" "=" "ptext") - / ("LANGUAGE" "=" langval) - / (x-name "=" param-value) - - langval = <a language string as defined in RFC 1766> - - img-inline-value = binary-value - ;Value MUST be "b" encoded image content - - img-inline-param - - img-inline-param = ("VALUE" "=" "binary") - / ("ENCODING" "=" "b") - / ("TYPE" "=" param-value - ;TYPE value MUST be an IANA registered image type - - img-refer-value = uri - ;URI MUST refer to image content of given type - - img-refer-param = ("VALUE" "=" "uri") - / ("TYPE" "=" param-value) - ;TYPE value MUST be an IANA registered image type - - adr-param = ("TYPE" "=" adr-type *("," adr-type)) - / (text-param) - - adr-type = "dom" / "intl" / "postal" / "parcel" / "home" - / "work" / "pref" / iana-type / x-name - - adr-value = 0*6(text-value ";") text-value - ; PO Box, Extended Address, Street, Locality, Region, Postal - ; Code, Country Name - - - - - - -Dawson & Howes Standards Track [Page 36] - -RFC 2426 vCard MIME Directory Profile September 1998 - - - ;******************************************* - ; vCard Type Value Definition - ;******************************************* - - text-value-list = 1*text-value *("," 1*text-value) - - text-value = *(SAFE-CHAR / ":" / DQUOTE / ESCAPED-CHAR) - - ESCAPED-CHAR = "\\" / "\;" / "\," / "\n" / "\N") - ; \\ encodes \, \n or \N encodes newline - ; \; encodes ;, \, encodes , - - binary-value = <A "b" encoded text value as defined in [RFC 2047]> - - date-value = <A single date value as defined in [MIME-DIR]> - - time-value = <A single time value as defined in [MIME-DIR]> - - date-time-value = <A single date-time value as defined in [MIME-DIR] - - float-value = <A single float value as defined in [MIME-DIR]> - - phone-number-value = <A single text value as defined in [CCITT - E.163] and [CCITT X.121]> - - uri-value = <A uri value as defined in [MIME-DIR]> - - utc-offset-value = ("+" / "-") time-hour ":" time-minute - time-hour = 2DIGIT ;00-23 - time-minute = 2DIGIT ;00-59 - -5. Differences From vCard v2.1 - - This specification has been reviewed by the IETF community. The - review process introduced a number of differences from the [VCARD] - version 2.1. These differences require that vCard objects conforming - to this specification have a different version number than a vCard - conforming to [VCARD]. The differences include the following: - - . The QUOTED-PRINTABLE inline encoding has been eliminated. - Only the "B" encoding of [RFC 2047] is an allowed value for - the ENCODING parameter. - - . The method for specifying CRLF character sequences in text - type values has been changed. The CRLF character sequence in - a text type value is specified with the backslash character - sequence "\n" or "\N". - - - - -Dawson & Howes Standards Track [Page 37] - -RFC 2426 vCard MIME Directory Profile September 1998 - - - . Any COMMA or SEMICOLON in a text type value must be backslash - escaped. - - . VERSION value corresponding to this specification MUST be - "3.0". - - . The [MIME-DIR] predefined types of SOURCE, NAME and PROFILE - are allowed. - - . The [MIME-DIR] VALUE type parameter for value data typing is - allowed. In addition, there are extensions made to these type - values for additional value types used in this specification. - - . The [VCARD] CHARSET type parameter has been eliminated. - Character set can only be specified on the CHARSET parameter - on the Content-Type MIME header field. - - . The [VCARD] support for non-significant WSP character has - been eliminated. - - . The "TYPE=" prefix to parameter values is required. In - [VCARD] this was optional. - - . LOGO, PHOTO and SOUND multimedia formats MUST be either IANA - registered types or non-standard types. - - . Inline binary content must be "B" encoded and folded. A blank - line after the encoded binary content is no longer required. - - . TEL values can be identified as personal communication - services telephone numbers with the PCS type parameter value. - - . The CATEGORIES, CLASS, NICKNAME, PRODID and SORT-STRING types - have been added. - - . The VERSION, N and FN types MUST be specified in a vCard. - This identifies the version of the specification that the - object was formatted to. It also assures that every vCard - will include both a structured and formatted name that can be - used to identify the object. - - - - - - - - - - - -Dawson & Howes Standards Track [Page 38] - -RFC 2426 vCard MIME Directory Profile September 1998 - - -6. Acknowledgements - - The many valuable comments contributed by members of the IETF ASID - working group are gratefully acknowledged, as are the contributions - by Roland Alden, Stephen Bartlett, Alec Dun, Patrik Faltstrom, Daniel - Gurney, Bruce Johnston, Daniel Klaussen, Pete Miller, Keith Moore, - Vinod Seraphin, Michelle Watkins. Chris Newman was especially helpful - in navigating the intricacies of ABNF lore. - -7. Authors' Addresses - - BEGIN:vCard - VERSION:3.0 - FN:Frank Dawson - ORG:Lotus Development Corporation - ADR;TYPE=WORK,POSTAL,PARCEL:;;6544 Battleford Drive - ;Raleigh;NC;27613-3502;U.S.A. - TEL;TYPE=VOICE,MSG,WORK:+1-919-676-9515 - TEL;TYPE=FAX,WORK:+1-919-676-9564 - EMAIL;TYPE=INTERNET,PREF:Frank_Dawson@Lotus.com - EMAIL;TYPE=INTERNET:fdawson@earthlink.net - URL:http://home.earthlink.net/~fdawson - END:vCard - - - BEGIN:vCard - VERSION:3.0 - FN:Tim Howes - ORG:Netscape Communications Corp. - ADR;TYPE=WORK:;;501 E. Middlefield Rd.;Mountain View; - CA; 94043;U.S.A. - TEL;TYPE=VOICE,MSG,WORK:+1-415-937-3419 - TEL;TYPE=FAX,WORK:+1-415-528-4164 - EMAIL;TYPE=INTERNET:howes@netscape.com - END:vCard - -8. Security Considerations - - vCards can carry cryptographic keys or certificates, as described in - Section 3.7.2. - - Section 3.7.1 specifies a desired security classification policy for - a particular vCard. That policy is not enforced in any way. - - The vCard objects have no inherent authentication or privacy, but can - easily be carried by any security mechanism that transfers MIME - objects with authentication or privacy. In cases where threats of - "spoofed" vCard information is a concern, the vCard SHOULD BE - - - -Dawson & Howes Standards Track [Page 39] - -RFC 2426 vCard MIME Directory Profile September 1998 - - - transported using one of these secure mechanisms. - - The information in a vCard may become out of date. In cases where the - vitality of data is important to an originator of a vCard, the "URL" - type described in section 3.6.8 SHOULD BE specified. In addition, the - "REV" type described in section 3.6.4 can be specified to indicate - the last time that the vCard data was updated. - -9. References - - [ISO 8601] ISO 8601:1988 - Data elements and interchange formats - - Information interchange - Representation of dates and - times - The International Organization for - Standardization, June, 1988. - - [ISO 8601 TC] ISO 8601, Technical Corrigendum 1 - Data elements and - interchange formats - Information interchange - - Representation of dates and times - The International - Organization for Standardization, May, 1991. - - [ISO 9070] ISO 9070, Information Processing - SGML support - facilities - Registration Procedures for Public Text - Owner Identifiers, April, 1991. - - [CCITT E.163] Recommendation E.163 - Numbering Plan for The - International Telephone Service, CCITT Blue Book, - Fascicle II.2, pp. 128-134, November, 1988. - - [CCITT X.121] Recommendation X.121 - International Numbering Plan for - Public Data Networks, CCITT Blue Book, Fascicle VIII.3, - pp. 317-332, November, 1988. - - [CCITT X.520] Recommendation X.520 - The Directory - Selected - Attribute Types, November 1988. - - [CCITT X.521] Recommendation X.521 - The Directory - Selected Object - Classes, November 1988. - - [MIME-DIR] Howes, T., Smith, M., and F. Dawson, "A MIME Content- - Type for Directory Information", RFC 2425, September - 1998. - - [RFC 1738] Berners-Lee, T., Masinter, L., and M. McCahill, - "Uniform Resource Locators (URL)", RFC 1738, December - 1994. - - [RFC 1766] Alvestrand, H., "Tags for the Identification of - Languages", RFC 1766, March 1995. - - - -Dawson & Howes Standards Track [Page 40] - -RFC 2426 vCard MIME Directory Profile September 1998 - - - [RFC 1872] Levinson, E., "The MIME Multipart/Related Content- - type", RFC 1872, December 1995. - - [RFC 2045] Freed, N., and N. Borenstein, "Multipurpose Internet - Mail Extensions (MIME) - Part One: Format of Internet - Message Bodies", RFC 2045, November 1996. - - [RFC 2046] Freed, N., and N. Borenstein, "Multipurpose Internet - Mail Extensions (MIME) - Part Two: Media Types", RFC - 2046, November 1996. - - [RFC 2047] Moore, K., "Multipurpose Internet Mail Extensions - (MIME) - Part Three: Message Header Extensions for - Non-ASCII Text", RFC 2047, November 1996. - - [RFC 2048] Freed, N., Klensin, J., and J. Postel, "Multipurpose - Internet Mail Extensions (MIME) - Part Four: - Registration Procedures", RFC 2048, January 1997. - - [RFC 2119] Bradner, S., "Key words for use in RFCs to Indicate - Requirement Levels", BCP 14, RFC 2119, March 1997. - - [RFC 2234] Crocker, D., and P. Overell, "Augmented BNF for Syntax - Specifications: ABNF", RFC 2234, November 1997. - - [UNICODE] "The Unicode Standard - Version 2.0", The Unicode - Consortium, July 1996. - - [VCARD] Internet Mail Consortium, "vCard - The Electronic - Business Card Version 2.1", - http://www.imc.org/pdi/vcard-21.txt, September 18, - 1996. - - - - - - - - - - - - - - - - - - - -Dawson & Howes Standards Track [Page 41] - -RFC 2426 vCard MIME Directory Profile September 1998 - - -10. Full Copyright Statement - - Copyright (C) The Internet Society (1998). All Rights Reserved. - - This document and translations of it may be copied and furnished to - others, and derivative works that comment on or otherwise explain it - or assist in its implementation may be prepared, copied, published - and distributed, in whole or in part, without restriction of any - kind, provided that the above copyright notice and this paragraph are - included on all such copies and derivative works. However, this - document itself may not be modified in any way, such as by removing - the copyright notice or references to the Internet Society or other - Internet organizations, except as needed for the purpose of - developing Internet standards in which case the procedures for - copyrights defined in the Internet Standards process must be - followed, or as required to translate it into languages other than - English. - - The limited permissions granted above are perpetual and will not be - revoked by the Internet Society or its successors or assigns. - - This document and the information contained herein is provided on an - "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING - TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING - BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION - HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF - MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - - - - - - - - - - - - - - - - - - - - - - - - -Dawson & Howes Standards Track [Page 42] - diff --git a/addressbook/backend/ebook/docs/vcard-21.txt b/addressbook/backend/ebook/docs/vcard-21.txt deleted file mode 100644 index 64716ebf15..0000000000 --- a/addressbook/backend/ebook/docs/vcard-21.txt +++ /dev/null @@ -1,1544 +0,0 @@ -vCard -The Electronic Business Card -Version 2.1 - -A versit Consortium Specification -September 18, 1996 - - -Copyrights -© 1996, International Business Machines Corp., Lucent Technologies, Inc., and Siemens. All rights reserved. -Permission is granted to copy and distribute this publication provided that it is reproduced in its entirety without modification and includes the above copyright notice and this permission notice. -No licenses, express or implied, are granted with respect to any of the technology described in this publication. International Business Machines Corp., Lucent Technologies, Inc., and Siemens retain all their intellectual property rights in the technology described in this publication. -Even though International Business Machines Corp., Lucent Technologies, Inc., and Siemens have reviewed this specification, INTERNATIONAL BUSINESS MACHINES CORP., LUCENT TECHNOLOGIES, INC, AND SIEMENS, MAKE NO WARRANTY OR REPRESENTATION, EITHER EXPRESS OR IMPLIED, WITH RESPECT TO THIS PUBLICATION, ITS QUALITY OR ACCURACY, NONINFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. AS A RESULT, THIS SPECIFICATION IS DELIVERED "AS IS" AND THE READER ASSUMES THE ENTIRE RISK AS TO ITS QUALITY, ACCURACY OR SUITABILITY FOR ANY PARTICULAR PURPOSE.. -IN NO EVENT WILL INTERNATIONAL BUSINESS MACHINES CORP., LUCENT TECHNOLOGIES, INC, AND SIEMENS, BE LIABLE FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES RESULTING FROM ANY DEFECT OR INACCURACY IN THIS PUBLICATION, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. -This publication is provided with RESTRICTED RIGHTS. Use, duplication, or disclosure by the Government are subject to restrictions set forth in DFARS 252.227-7013 or 48 CFR 52.227-19, as applicable. - - -Trademarks -versit, the versit logo, versitcard, vCard, and vCalendar are trademarks of Apple Computer, Inc., AT&T Corp., International Business Machines Corp., and Siemens. -Apple, is a trademarks of Apple Computer, Inc. registered in the U.S. and other countries. -AT&T and ATTMail are registered trademarks of AT&T Corp. -IBM, IBM Mail, and OS/2 are registered trademarks of International Business Machines Corporation. -America Online is a registered trademark of America Online, Inc. -CompuServe, CompuServe Information Services are registered trademarks of Compuserve Incorporated. -MCIMail is a registered trademark of MCI Communications Corporation. -Microsoft is a registered trademark, and Microsoft Windows is a trademark of Microsoft Corporation. -Prodigy is a registered trademark of Prodigy Services Company. -Unicode is a registered trademark of Unicode, Inc. - - -Contributors -Roland Alden -Greg Ames, Ames & Associates -Masanari Arai, Puma Technologies -Stephen W. Bartlett -Donal Carroll -Liang-Jye Chang, Starfish Software -Frank Dawson, IBM Corporation -Ken Dobson, IntelliLink Inc. -Scott Feldstein, Nimble Software, Inc. -Anik Ganguly, OnTime/Division of FTP Software. -Beijing Goo, Microsoft -Arvind K. Goyal, Lotus Development Corporation -Gary Hand, IBM Corporation -Tim Howes, Netscape Communications Corporation -Mark Joseph, Attachmate Corporation -Kerry Kelly, Now Software, Inc. -Phac Letuan, Apple Computer, Inc. -Pat Megowan, Counterpoint Sytems Foundry Inc. -Tohri Mori, IBM Japan/Salutation Consortium -Ravi Pandya, NetManage, Inc. -Geoff Ralston, Four11 Corporation -Steven Rummel, Lucent Technologies -Michael Santullo, Four11 Corporation -Vinod Seraphin, Lotus Development Corporation -Dexter Seely, Corex Technologies, Inc. -Vlad Shmunis, Ring Zero Systems Inc. -Dean Stevens, Now Software, Inc. -Michelle Watkins, Netscape Communications Corporation -Horst Widlewski, Siemens - - -Reference Information -The cited references contain provisions which, through reference in this specification, constitute provisions of this specification. At the time of publication, the indicated versions in the following references were valid. Parties to agreements based on this specification are encouraged to research the possibility of revised standards. -* ANSI X3.4-1977, Code for Information Interchange, American National Standards Institute, 1977. -* CCITT (ITU) Recommendation E.163, Numbering Plan for The International Telephone Service, CCITT Blue Book, Fascicle II.2, pp. 128-134, November, 1988. -* CCITT (ITU) Recommendation G.721, 32 kbit/s Adaptive Differential Pulse Code Modulation (ADPCM), CCITT Red Book, Fascicle III.4, November, 1988. -* CCITT (ITU) Recommendation X.121, International Numbering Plan for Public Data Networks, CCITT Blue Book, Fascicle VIII.3, pp. 317-332, November, 1988. -* CCITT (ITU) Recommendations X.500-X.521, Data Communication Networks: Directory, CCITT Blue Book, Fascicle VIII.8, November, 1988. -* CCITT Recommendation X.520, The Directory-Selected Attribute Types, 1988. -* CCITT Recommendation X.521, The Directory-Selected Object Classes, 1988. -* IETF RFC 1738, Universal Resource Locator, December 1994. -* IETF Network Working Group RFC 1766, Tags for the Identification of Languages, March 1995. -* IETF Network Working Group Draft, A MIME Content-Type for Directory Information, January 1996. Available from the University of Michigan, 535 W. William St., Ann Arbor, MI 48103-4943, FTP://ds.internic.net/Internet-Drafts/draft-ietf-asid-mime-direct-01.txt. -* IETF Network Working Group Draft, An Application/Directory MIME Content-Type Electronic Business Card Profile, May 1996. Available FTP://ds.internic.net/Internet-Drafts/draft-ietf-asid-mime-vcard-00.txt. -* IETF Network Working Group Draft, UTF-8, A Transformation Format of UNICODE and ISO 10646, July 1996. Available from FTP://ds.internic.net/Internet-Drafts/draft-yergeau-utf8-01.txt. -* ISO 639, Code for The Representation of names of languages, International Organization for Standardization, April, 1988. -* ISO 3166, Codes for The Representation of names of countries, International Organization for Standardization, December, 1993. -* ISO 8601, Data elements and interchange formats-Information interchange-Representation of dates and times, International Organization for Standardization, June, 1988. -* ISO 8601, Technical Corrigendum 1, Data elements and interchange formats-Information interchange-Representation of dates and times, International Organization for Standardization, May, 1991. -* ISO 8859-1, Information Processing-8-Bit single-byte coded graphic character sets-Part 1: Latin Alphabet No. 1, International Organization for Standardization, February, 1987. -* ISO 9070, Information Processing-SGML support facilities-Registration Procedures for Public Text Owner Identifiers, 1990-02-01.[DS1] -ï ISO/IEC 9070, Information TechnologyóSGML Support FacilitiesóRegistration Procedures for Public Text Owner Identifiers, Second Edition, International Organization for Standardization, April, 1991. -ï ISO/IEC 11180, Postal addressing, International Organization for Standardization, 1993. -ï Appleís Representation of a Canonical Static DeviceID in The Telephony Suite, version 1.0, Apple Computer, Inc., 1993. -* Microsoft TAPI in Microsoft Windows 3.1 Telephony Programmers' Guide, version 1.0, Microsoft Corporation, 1993. -* RFC1521, MIME (Multipurpose Internet Mail Extensions) Part One: Mechanisms for Specifying and Describing the Format of Internet Message Bodies, Network Working Group, September, 1993. -* The Unicode Standard, Version 1.1: Version 1.0, Volume 1 (ISBN 0-201-56788-1), version 1.0, volume 2 (ISBN 0-20-60845-6) and Unicode Technical Report #4, The Unicode Standard, version 1.1, The Unicode Consortium, October, 1991. Both references to be published by Addison-Wesley. - - -versit Update -versit is a multivendor development initiative of the communication and computer industries, founded by Apple, AT&T, IBM and Siemens. The versit parties believe that great potential exists in improving the nature of communications in the business world-permitting companies to better manage their quality, productivity, customer satisfaction and cost of operations, while expanding the market opportunities for a variety of product and service vendors. versit parties will jointly define and support open specifications that facilitate and promote the interoperability of advanced personal information and communication devices, networks and services. -The versit vision is to enable diverse communication and computing devices, applications and services from competing vendors to interoperate in all environments. Through developing a series of specifications for interoperability among diverse communications and computing devices, applications, networks and services, versit 's vision will become a reality. -versit 's primary development areas are in: -* Personal Data Interchange (PDI) -* Computer Telephone Integration (CTI) -* Conferencing and Messaging (C&M) -* Wired and Wireless connectivity -versit specifications are directed at both the decision makers and the implementation teams of: -* Equipment Manufacturers -* Independent Software Vendors -* Information Service Providers -* Online Service Providers -* Software Houses -* Users -versit specifications are made available to any interested party. In turn, versit encourages the support of our goals by soliciting feedback on versit specifications. - -All comments relating to versit or the material within this specification should be submitted to: -versit -(800) 803-6240 -+1 (201) 327-2803 (Outside USA) -pdi@versit.com -http://www.versit.com/pdi - - -Contents -Section 1 : Introduction -1.1 Overview -1.2 Scope -1.3 Contents -1.4 Definitions and Abbreviations -Section 2 : vCard Specificiation -2.1 Encoding Characteristics -2.1.1 vCard Object -2.1.2 Property -2.1.3 Delimiters -2.1.4 Grouping -2.1.4.1 vCard Grouping -2.1.4.2 Property Grouping -2.1.5 Encodings -2.1.6 Character Set -2.1.7 Language -2.1.8 Value Location -2.1.9 Binary Values -2.2 Identification Properties -2.2.1 Formatted Name -2.2.2 Name -2.2.3 Photograph -2.2.3.1 Photo Format Type -2.2.4 Birthdate -2.3 Delivery Addressing Properties -2.3.1 Delivery Address -2.3.1.1 Delivery Address Type -2.3.2 Delivery Label -2.3.2.1 Delivery Label Type -2.4 Telecommunications Addressing Properties -2.4.1 Telephone Number -2.4.1.1 Telephone Type -2.4.2 Electronic Mail -2.4.2.1 Electronic Mail Type -2.4.3 Mailer -2.4.4 Geographical Properties -2.4.5 Time Zone -2.4.6 Geographic Position -2.5 Organizational Properties -2.5.1 Title -2.5.2 Business Category -2.5.3 Logo -2.5.3.1 Logo Format Type -2.5.4 Agent -2.5.5 Organization Name and Organizational Unit -2.6 Explanatory Properties -2.6.1 Comment -2.6.2 Last Revision -2.6.3 Sound -2.6.3.1 Sound Digital Audio Type -2.6.4 Uniform Resource Locator -2.6.5 Unique Identifier -2.6.6 Version -2.7 Security Properties -2.7.1 Public Key -2.7.2 Key Type -2.8 Miscellaneous Properties -2.8.1 Extensions -2.9 Formal Definition -Section 3 : Internet Recommendations -3.1 Recommended Practice with SMTP/MIME -3.1.1 Text/Plain Content Type -3.1.2 Text/X-vCard Content Type -3.1.3 Application/Directory Content Type -3.2 Recommended Practice with HTTP/HTML -3.2.1 Form Element Usage -3.2.2 Mapping To INPUT Element Attribute Names -3.2.3 Example HTML Code -Section 4 : UI Support Recommendations -4.1 File System -4.2 Clipboard -4.3 Drag/Drop -Section 5 : Conformance - - - -Section 1 : Introduction -[DS2] -Personal Data Interchange (PDI) occurs every time two or more individuals communicate, in either a business or personal context, face-to-face, or across space and time. Such interchanges frequently include the exchange of informal information, such as business cards, telephone numbers, addresses, dates and times of appointments, etc. Augmenting PDI with electronics and telecommunications can help ensure that information is quickly and reliably communicated, stored, organized and easily located when needed. -Personal information, by nature, is complex and diverse. Currently, proprietary standards exist to structure some types of PDI information, but no single, open specification comprehensively addresses the needs of collecting and communicating PDI information across many common communication channels such as telephones, voice-mail, e-mail, and face-to-face meetings. versit is developing a comprehensive family of PDI technologies based on open specifications and interoperability agreements to help meet this technology need. -Overview -This specification defines a format for an electronic business card, or vCard. The format is suitable as an interchange format between applications or systems. The format is defined independent of the particular method used to transport it. The transport for this exchange might be a file system, point-to-point asynchronous communication, wired-network transport, or some form of unwired transport. -A vCard is a data stream consisting of one or more vCard objects. The individual vCard definitions can be identified and parsed within the datastream. The vCard data stream may exist as a persistent form in a file system, document management system, network connection between two network endpoints, or in any other digital transport that has an abstraction of a stream of bytes. -Conceptually, a vCard Writer creates vCard data streams and a vCard Reader interprets vCard data streams. The vCard Reader and Writer may be implemented as a single application or as separate applications. It is not the intent of this specification to define the implementation of these processes beyond some fundamental capabilities related to the format of the vCard data stream and a common set of conformance requirements . -This specification provides for a clear-text encoding that is intended to be based on the syntax used by the MIME specification (RFC 1521). -The encoding of this specification can be used in environments which are constrained to 7-bit transfer encodings, short line lengths, and low bandwidth. In addition, the encoding is simple in order to facilitate the implementation of reader and writer applications on small platforms, such as Personal Digital Assistants (PDA), cellular telephones, or alphanumeric pagers. -Scope -The vCard is intended to be used for exchanging information about people and resources. In today's business environment, this information is typically exchanged on business cards. It is appropriate, then that this specification define this information in terms of a paradigm based on an electronic business card object. -The ultimate destination for this information is often a collection of business cards, Rolodex® file, or electronic contact manager. Prior to the introduction of the vCard specification, users of such applications typically had to re-key the original information, often transcribing it from paper business cards. With the advent of the vCard specification, this information can be exchanged in an automated fashion. -The basis for the data types supported by this specification have their origin in openly defined, international standards and in additional capabilities based on enhancements suggested by the demonstration of the exchange of prototypical vCards using the Internet based World-Wide-Web, Infra-red data transport, and simultaneous voice and data (SVD) modems. -The "person" object defined by the CCITT X.500 Series Recommendation for Directory Services was the primary reference for the properties that are defined by this specification. Every attempt was made to make it possible to map the X.520/X.521 attributes and objects into and out of an instance of a vCard. The vCard specification has extended the capabilities that have been defined within the CCITT X.500 Series Recommendation to allow the exchange of additional information often recorded on business cards and electronic contact managers. For example, this specification provides support for exchanging graphic images representing company logos, photographs of individuals, geo-positioning information, and other extensions to properties defined by the X.500 Recommendation. -The specification of all date and time values are defined in terms of the ISO 8601 standard for representation of dates and times. ISO 8601 supersedes all other international standards defined at the time this specification was drafted. -The paradigm of an electronic business card is related to the concepts of an entry in a LAN/WAN directory or an electronic mail address book or distribution list. However, the requirements of the electronic business card go beyond the definitions of a "person" object found in either the CCITT X.500 Series Recommendation, network directory services, or electronic mail address book products. The vCard specification is needed to address the requirements for an interchange format for the "person" personal data type or object. -Personal data applications such as Personal Information Managers (PIM) often provide an import/export capability using Comma Separated Value (CSV) or Tab Delimited Files (TDF) formats. However, these solutions do not preserve the intent of the originating application. When a CSV and TDF format is used by a PIM, the meta-data or semantics of the originating object are only apparent to a similar version of the originating application. Exchange of data between such applications is another important application of an industry-standard specification for an electronic business card interchange format, such as the vCard specification. -Contents -This specification is separated into eight sections: -* "Section 1 : Introduction" introduces PDI and the vCard specification with an overview, scope statement and section on definitions and abbreviations. -* "Section 2 : vCard Specification" defines the semantics and syntax for the vCard. -* "Section 3 : Internet Recommendations" specifies a set of guidelines to facilitate the exchange of vCard objects over Internet protocols such as HTTP using HTML and SMTP using MIME. -* "Section 4 : UI Support Recommendations" specifies a set of guidelines to facilitate the exchange of vCard objects at the desktop user interface using the file system, clipboard and drag/drop capabilities of the operating system. -* "Section 5 : Conformance" defines minimum conformance requirements to consider while developing support for this vCard specification. -Definitions and Abbreviations -Definitions and abbreviations used within this specification follow. -Electronic Business Card: Also known as vCard. -FPI: Formal Public Identifier. A string expression that represents a public identifier for an object. FPI syntax is defined by ISO 9070. -GUID: Globally Unique IDentifier -Internet: A WAN connecting thousands of disparate networks in industry, education, government, and research. The Internet uses TCP/IP as the standard for transmitting information. -ISO: Organization for International Standardization; a worldwide federation of national standards bodies (ISO Member bodies). -MIME: Multipurpose Internet Mail Extensions, as defined in RFC1521. -PDA: Personal Digital Assistant computing device -PDI: Personal Data Interchange, a collaborative application area which involves the communication of data between people who have a business or personal relationship, but do not necessarily share a common computing infrastructure. -PIM: Personal Information Manager -RFC#### documents: Internet "Request For Comment" documents (i.e., RFC822, RFC1521, etc.). -URL: Uniform Resource Locator; a string expression that can represent any resource on the Internet or local system. RFC 1738 defines the syntax for an URL. -UTC: Universal Time Coordinated; also known as UCT, for Universal Coordinated Time. -vCard: The generic term for an electronic, virtual information card that can be transferred between computers, PDAs, or other electronic devices through telephone lines, or e-mail networks, or infrared links. How, when, why, and where vCard are used depends on the applications developed utilizing a vCard. -versitcard: a vCard. -WAN: Wide-Area Network - - -Section 2 : vCard Specificiation -[DS3] -This section defines the semantics and syntax for the vCard. -A vCard is a collection of one or more properties. A property is a uniquely named value. A set of properties can be grouped within a vCard. For example, the properties for a telephone number and comment can be grouped in order to preserve the coupling of the annotation with the telephone number. In addition to property groupings, a vC. versit is developing a comprehensive family of PDI technologies based on open specifications and interoperability agreements to help meet this technology need. -Overview -This specification defines a format for an electronic business card, or vCard. The format is suitable as an interchange format between applications or systems. The format is defined independent of the particular method used to transport it. The transport for this exchange might be a file system, point-to-point asynchronous communication, wired-network transport, or some form of unwired transport. -A vCard is a data stream consisting of one or more vCard objects. The individual vCard definitions can be identified and parsed within the datastream. The vCard data stream may exist as a persistent form in a file system, document management system, network connection between two network endpoints, or in any other digital transport that has an abstraction of a stream of bytes. -Conceptually, a vCard Writer creates vCard data streams and a vCard Reader interprets vCard data streams. The vCard Reader and Writer may be implemented as a single application or as separate applications. It is not the intent of this specification to define the implementation of these processes beyond some fundamental capabilities related to the format of the vCard data stream and a common set of conformance requirements . -This specification provides for a clear-text encoding that is intended to be based on the syntax used by the MIME specification (RFC 1521). -The encoding of this specification can be used in environments which are constrained to 7-bit transfer encodings, short line lengths, and low bandwidth. In addition, the encoding is simple in order to facilitate the implementation of reader and writer applications on small platforms, such as Personal Digital Assistants (PDA), cellular telephones, or alphanumeric pagers. -Scope -The vCard is intended to be used for exchanging information about people and resources. In today's business environment, this information is typically exchanged on business cards. It is appropriate, then that this specification define this information in terms of a paradigm based on an electronic business card object. -The ultimate destination for this information is often a collection of business cards, Rolodex® file, or electronic contact manager. Prior to the introduction of the vCard specification, users of such applications typically had to re-key the original information, often transcribing it from paper business cards. With the advent of the vCard specification, this information can be exchanged in an automated fashion. -The basis for the data types supported by this specification have their origin in openly defined, international standards and in additional capabilities based on enhancements suggested by the demonstration of the exchange of prototypical vCards using the Internet based World-Wide-Web, Infra-red data transport, and simultaneous voice and data (SVD) modems. -The "person" object defined by the CCITT X.500 Series Recommendation for Directory Services was the primary reference for the properties that are defined by this specification. Every attempt was made to make it possible to map the X.520/X.521 attributes and objects into and out of an instance of a vCard. The vCard specification has extended the capabilities that have been defined within the CCITT X.500 Series Recommendation to allow the exchange of additional information often recorded on business cards and electronic contact managers. For example, this specification provides support for exchanging graphic images representing company logos, photographs of individuals, geo-positioning information, and other extensions to properties defined by the X.500 Recommendation. -The specification of all date and time values are defined in terms of the ISO 8601 standard for representation of dates and times. ISO 8601 supersedes all other international standards defined at the time this specification was drafted. -The paradigm of an electronic business card is related to the concepts of aQuoted-Printable lines of text must also be limited to less than 76 characters. The 76 characters does not include the CRLF (RFC 822) line break sequence. For example a multiple line LABEL property value of: -123 Winding Way -Any Town, CA 12345 -USA -Would be represented in a Quoted-Printable encoding as: -LABEL;ENCODING=QUOTED-PRINTABLE:123 Winding Way=0D=0A= - Any Town, CA 12345=0D=0A= - USA -Property parameter substrings are delimited by a field delimiter, specified by the Semi-colon character (ASCII decimal 59). A Semi-colon in a property parameter value must be escaped with a Backslash character (ASCII 92). -Compound property values are property values that also make use of the Semi-colon, field delimiter to separate positional components of the value. For example, the Name property is made up of the Family Name, Given Name, etc. components. A Semi-colon in a component of a compound property value must be escaped with a Backslash character (ASCII 92). -Grouping -There are two forms of grouping or collections supported within the vCard. A collection of vCard objects can be grouped and a collection of properties within an individual vCard can be grouped. -vCard Grouping -The vCard data stream can consist of multiple vCard objects. The vCard data stream can, sequentially, contain one or more vCard objects., In addition, the vCard data stream can contain a property whose value is a nested vCard. In both of these cases, each vCard object will be delimited by the vCard Delimiters. The vCard Reader conforming to this specification must be able to parse and process any of these combinations of vCard Groupings. The support for vCard Grouping is optional for a vCard Writer conforming to this specification. -Property Grouping -A Property Grouping is the definition of a method for specifying a collection of related properties within a vCard object. There is no requirement on a vCard reader that it preserve the property group name. However, the vCard reader is required to preserve the grouping of the properties. -The Property Grouping is identified by a character string prefix to the property name; separated by the Period character (ASCII decimal 46). -The grouping of a comment property with a telephone property is shown in the following example: -A.TEL;HOME:+1-213-555-1234 -A.NOTE:This is my vacation home. -The vCard Reader conforming to this specification must be able to parse and process the property grouping. The support for Property Grouping is optional for a vCard Writer conforming to this specification. -Encodings -The default encoding for the vCard object is 7-Bit. The default encoding can be overridden for an individual property value by using the "ENCODING" property parameter. This parameter value can be either "BASE64", "QUOTED-PRINTABLE", or "8BIT". This parameter may be used on any property. -Some transports (e.g., MIME based electronic mail) may also provide an encoding property at the transport wrapper level. This property can be used in these cases for transporting a vCard data stream that has been defined using a default encoding other than 7-bit (e.g., 8-bit). -Character Set -The default character set is ASCII. The default character set can be overridden for an individual property value by using the "CHARSET" property parameter. This property parameter may be used on any property. However, the use of this parameter on some properties may not make sense. -Any character set registered with the Internet Assigned Numbers Authority (IANA) can be specified by this property parameter. For example, ISO 8859-8 or the Latin/Hebrew character set is specified by: -ADR;CHARSET=ISO-8859-8:... -Some transports (e.g., MIME based electronic mail) may also provide a character set property at the transport wrapper level. This property can be used in these cases for transporting a vCard data stream that has been defined using a default character set other than ASCII (e.g., UTF-8). -Language -The default language is "en-US" (US English). The default language can be overridden for an individual property value by using the "LANGUAGE" property parameter. The values for this property are a string consistent with RFC 1766, Tags for the Identification of Languages. This property parameter may be used on any property. However, the use of this parameter on some properties, such as PHOTO, LOGO, SOUND, TEL, may not make sense. Canadian French would be specified by this parameter by the following: -ADR;LANGUAGE=fr-CA:... -Value Location -The default location of the property value is inline with the property. However, for some properties, such as those that specify multimedia values, it is efficient to organize the property value as a separate entity (e.g., a file out on the network). The property parameter "VALUE" can be specified to override the "INLINE" location of the property value. In the case of the vCard being transported within a MIME email message, the property value can be specified as being located in a separate MIME entity with the "Content-ID" value, or "CID" for short. In this case, the property value is the Content-ID for the MIME entity containing the property value. In addition, the property value can be specified as being located out on the network within some Internet resource with the "URL" value. In this case, the property value is the Uniform Resource Locator for the Internet resource containing the property value. This property parameter may be used on any property. However, the use of this parameter on some properties may not make sense; for example the Version, Time Zone, Comment, Unique Identifier, properties . The following specifies a value not located inline with the vCard but out in the Internet: -PHOTO;VALUE=URL;TYPE=GIF:http://www.abc.com/dir_photos/my_photo.gif -SOUND;VALUE=CONTENT-ID:<jsmith.part3.960817T083000.xyzMail@host1.com -Binary Values -The vCard format supports inclusion of binary information, such as computer graphic images, digital audio, or video graphic images. The binary information may either be referenced with a Uniform Reference Locator (URL) or placed inline in the vCard as the value of a property. Inline binary information is included as a property value after being encoded into clear-text with a Base 64 (default) or Quoted-Printable encoding -Identification Properties -These property types are concerned with information associated with the identification and naming of the individual or resource associated with the vCard object. -Formatted Name -This property specifies the formatted name string associated with the vCard object. This is the way that the name is to be displayed. It can contain desired honorific prefixes, suffixes, titles, etc. For example, "Mr. John Q. Public, Jr.", Dr. Ann Tyler, or Hon. Judge Blackwell. This property is based on the semantics of the X.520 Common Name attribute. -This property is identified by the property name FN. The following is an example of the Formatted Name property: -FN:Mr. John Q. Public, Esq. -Support for this property is optional for vCard Writers conforming to this specification. -Name -This property specifies a structured representation of the name of the person, place or thing associated with the vCard object. -This property is identified by the property name N. This property is defined to encapsulate the individual components of an object's name. The property value consists of the components of the name specified as positional fields separated by the Field Delimiter character (ASCII decimal 59). The property value is a concatenation of the Family Name (first field), Given Name (second field), Additional Names (third field), Name Prefix (fourth field), and Name Suffix (fifth field) strings. The following is an example of the Name property for a person: -N:Public;John;Quinlan;Mr.;Esq. -The following is an example of the Name property for a resource or place: -N:Veni, Vidi, Vici;The Restaurant. -Support for this property is mandatory for vCard Writers conforming to this specification. All vCard data streams should include this property to facilitate a common property for collating and sorting of vCard objects. -Photograph -This property specifies an image or photograph of the individual associated with the vCard. -The property is identified by the property name PHOTO. For example, the following syntax is an example of a referenced image file: -PHOTO;VALUE=URL:file:///jqpublic.gif - The following example is the syntax for including an inline GIF image file, using the Base 64 encoding: -PHOTO;ENCODING=BASE64;TYPE=GIF: - R0lGODdhfgA4AOYAAAAAAK+vr62trVIxa6WlpZ+fnzEpCEpzlAha/0Kc74+PjyGM - SuecKRhrtX9/fzExORBSjCEYCGtra2NjYyF7nDGE50JrhAg51qWtOTl7vee1MWu1 - 50o5e3PO/3sxcwAx/4R7GBgQOcDAwFoAQt61hJyMGHuUSpRKIf8A/wAY54yMjHtz -... -Support for this property is optional for vCard Writers conforming to this specification. -Photo Format Type -This property parameter is provided to specify the graphics format for the Photo property value. The property parameter includes the following values: - -Description -Property Parameter Value - -TYPE= - - -Indicates Graphics Interchange Format -GIF - -Indicates ISO Computer Graphics Metafile -CGM - -Indicates MS Windows Metafile -WMF - -Indicates MS Windows Bitmap -BMP - -Indicates IBM PM Metafile -MET - -Indicates IBM PM Bitmap -PMB - -Indicates MS Windows DIB -DIB - -Indicates an Apple Picture format -PICT - -Indicates a Tagged Image File Format -TIFF - -Indicates Adobe PostScript format -PS - -Indicates Adobe Page Description Format -PDF - -Indicates ISO JPEG format -JPEG - -Indicates ISO MPEG format -MPEG - -Indicates ISO MPEG version 2 format -MPEG2 - -Indicates Intel AVI format -AVI - -Indicates Apple QuickTime format -QTIME - - -Birthdate -This property specifies the date of birth of the individual associated with the vCard. The value for this property is a calendar date in a complete representation consistent with ISO 8601. -This property is identified by the property name BDAY. The property value is a string conforming to the ISO 8601 calendar date, complete representation, in either basic or extended format. The following example is in the basic format of ISO 8601: -BDAY:19950415 -The following example is in the extended format of ISO 8601: -BDAY:1995-04-15 -Support for this property is optional for vCard Writers conforming to this specification. -Delivery Addressing Properties -Delivery Address -This property specifies a structured representation of the physical delivery address for the vCard object. The property is made up of components that are based on the X.500 Post Office Box attribute, the X.520 Street Address geographical attribute, the X.520 Locality Name geographical attribute, the X.520 State or Province Name geographical attribute, the X.520 Postal Code attribute, and the X.520 Country Name geographical attribute. -This property is identified by the property name ADR. The property value consists of components of the address specified as positional fields separated by the Field Delimiter character (ASCII decimal 59). The property value is a concatenation of the Post Office Address (first field) Extended Address (second field), Street (third field), Locality (fourth field), Region (fifth field), Postal Code (six field), and Country (seventh field) strings. An example of this property follows: -ADR;DOM;HOME:P.O. Box 101;Suite 101;123 Main Street;Any Town;CA;91921-1234; -Support for this property is optional for vCard Writers conforming to this specification. -Delivery Address Type -This property parameter specifies the sub-types of physical delivery that is associated with the delivery address. For example, the label may need to be differentiated for Home, Work, Parcel, Postal, Domestic, and International physical delivery. One or more sub-types can be specified for a given delivery address. -The property parameter can have one or more of the following values: - -Description -Property Parameter Value - -TYPE= - - -Indicates a domestic address -DOM - -Indicates an international address (Default) -INTL - -Indicates a postal delivery address (Default) -POSTAL - -Indicates a parcel delivery address (Default) -PARCEL - -Indicates a home delivery address -HOME - -Indicates a work delivery address (Default) -WORK - - -The default property parameter is overridden to some other set of values by specifying one or more alternate values. For example, the default of a delivery for INTL, WORK, POSTAL and PARCEL can be reset to DOM, POSTAL, WORK and HOME in the following example: -ADR;DOM;WORK;HOME;POSTAL:P.O. Box 101;;;Any Town;CA;91921-1234; -Delivery Label -This property specifies the addressing label for physical delivery to the person/object associated with the vCard. The property is intended to include the information necessary to create a formatted delivery address label. Typical information includes the name, street address, possibly a Post Office or mail drop, city, state or province, zip or postal code. An international delivery label would also include the country name. -This property is based on the semantics of the X.520 Postal Address attribute. This specification has added semantics to those defined by the X.500 Series standard for differentiating Home, Work, Parcel, Postal, Domestic, and International delivery label types. -This property is identified by the property name LABEL. This property specifies the formatted delivery address label for the vCard object. An example of a domestic delivery label follows: -LABEL;DOM;POSTAL;ENCODING=QUOTED-PRINTABLE:P. O. Box 456=0D=0A= -123 Main Street=0D=0A= -Any Town, CA 91921-1234 -An example of an international delivery label follows: -LABEL;INTL;PARCEL,ENCODING=QUOTED-PRINTABLE:Suite 101=0D=0A= -123 Main Street=0D=0A= -Any Town, CA 91921-1234=0D=0A= -U.S.A. -Support for this property is optional for vCard Writers conforming to this specification. A vCard Reader supporting this property and conforming to this specification should support a minimum of four lines of text for this property. -Delivery Label Type -This property parameter specifies the sub-types of physical delivery that is associated with the delivery label. For example, the label may need to be differentiated for Home, Work, Parcel, Postal, Domestic, and International physical delivery. One or more sub-types can be specified for a given delivery label. -The property parameter can have one or more of the following values: - -Description -Property Parameter Value - -TYPE= - - -Indicates a domestic address -DOM - -Indicates an international address (Default) -INTL - -Indicates a postal delivery address (Default) -POSTAL - -Indicates a parcel delivery address (Default) -PARCEL - -Indicates a home delivery address -HOME - -Indicates a work delivery address (Default) -WORK - - -The default property parameter is overridden to some other set of values by specifying one or more alternate values. For example, the default of a delivery for INTL, WORK, POSTAL and PARCEL can be reset to DOM and HOME in the following example: -LABEL;DOM;HOME,ENCODING=QUOTED-PRINTABLE:Suite 101=0D=0A= -123 Main Street=0D=0A= -Any Town, CA 91921-1234 -Telecommunications Addressing Properties -These property types are concerned with information associated with the telecommunications addressing of the vCard object. -Telephone Number -This property specifies the canonical number string for a telephone number for telephony communication with the vCard object. The value of this property is specified in a canonical form in order to specify an unambiguous representation of the globally unique telephony endpoint. This property is based on the X.520 Telephone Number attribute. -The canonical form cannot be dialed without first being transformed by a dialing algorithm. The dialing algorithm combines the canonical number string with knowledge of the local dialing procedures, in effect at the time of call placement to produce actual dialing instructions. The actual dialing algorithm is outside the scope of this specification. -Two important canonical forms allowed by this specification are: -* Apple Computer's Representation of a Canonical Static DeviceID in The Telephony Suite, version 1.0, -* Microsoft TAPI in the Microsoft Windows 3.1 Telephony Programmer's Guide, version 1.0. -Software which creates this property can store a string in these allowed formats. Dialing software should be prepared to parse numbers from either of the supported formats; as neither format is considered to be technically costly to support. -This property is identified by the property name TEL. An example of this property follows: -TEL;PREF;WORK;MSG;FAX:+1-800-555-1234 -Support for this property is optional for vCard Writers conforming to this specification. -Telephone Type -This property parameter specifies the sub-type of telephone that is associated with the telephone number (e.g., Home, Work, Cellular, Facsimile, Video, Modem, Message Service, or Preferred). One or more sub-type values can be specified for a given telephone number. -The property parameter can have one or more of the following values: - -Description -Property Parameter Value - -TYPE= - - -Indicates preferred number -PREF - -Indicates a work number -WORK - -Indicates a home number -HOME - -Indicates a voice number (Default) -VOICE - -Indicates a facsimile number -FAX - -Indicates a messaging service on the number -MSG - -Indicates a cellular number -CELL - -Indicates a pager number -PAGER - -Indicates a bulletin board service number -BBS - -Indicates a MODEM number -MODEM - -Indicates a car-phone number -CAR - -Indicates an ISDN number -ISDN - -Indicates a video-phone number -VIDEO - -The default property parameter is overridden to some other set of values by specifying one or more alternate values. For example, the default of a VOICE telephone number can be reset to a WORK and HOME, VOICE and FAX telephone number in the following example: -TEL;WORK;HOME;VOICE;FAX:+1-800-555-1234 -Electronic Mail -This property specifies the address for electronic mail communication with the vCard object. The address is in the form of a specific addressing type. For example, the Internet mail address for John Public might be "John.Public@abc.com" or the CompuServe Information Service address might be "71234,5678".This property is identified by the property name EMAIL. -An example of this property follows: -EMAIL;INTERNET:john.public@abc.com -Support for this property is optional for vCard Writers conforming to this specification. -Electronic Mail Type -This property parameter specifies the type of electronic mail address. The following are some example values for this property parameter: - -Description -Property Parameter Value - -TYPE= - - -Indicates America On-Line -AOL - -Indicates AppleLink -AppleLink - -Indicates AT&T Mail -ATTMail - -Indicates CompuServe Information Service -CIS - -Indicates eWorld -eWorld - -Indicates Internet SMTP (default) -INTERNET - -Indicates IBM Mail -IBMMail - -Indicates MCI Mail -MCIMail - -Indicates PowerShare -POWERSHARE - -Indicates Prodigy information service -PRODIGY - -Indicates Telex number -TLX - -Indicates X.400 service -X400 - - -Mailer -This property parameter specifies the type of electronic mail software that is in use by the individual associated with the vCard object. This information may provide assistance to a correspondent regarding the type of data representation which can be used, and how they may be packaged. This property parameter is based on currently accepted practices within the Internet MIME community with the "X-Mailer" header field. -This property is identified by the property name MAILER. Support for this property is optional for vCard Writers conforming to this specification. An example of this property follows: -MAILER:ccMail 2.2 -Geographical Properties -These property types are concerned with geographical positions or region information associated with the vCard object. -Time Zone -This property specifies information related to the standard time zone of the vCard object. The time zone is a string as specified in a manner consistent with ISO 8601. It is an offset from Coordinated Universal Time (UTC). An ISO 8601 UTC offset, in basic format, is specified as a positive or negative difference in units of hours and minutes (e.g., +hhmm). If minutes are zero, then they may be omitted and the format would be specified in units of hours (e.g., +hh). The time is specified as a 24-hour clock. Hour valult property parameter is overridden to some other set of values by specifying one or more alternate values. For example, the default of a delivery for INTL, WORK, POSTAL and PARCEL can be reset to DOM, POSTAL, WORK and HOME in the following example: -ADR;DOM;WORK;HOME;POSTAL:P.O. Box 101;;;Any Town;CA;91921-1234; -Delivery Label -This property specifies the addressing label for physical delivery to the person/object associated with the vCard. The property is intended to include the information necessary to create a formatted delivery address label. Typical information includes the name, street address, possibly a Post Office or mail drop, city, state or province, zip or postal code. An international delivery label would also include the country name. -This property is based on the semantics of the X.520 Postal Address attribute. This specification has added semantics to those defined by the X.500 Series standard for differentiating Home, Work, Parcel, Postal, Domestic, and International delivery label types. -This property is identified by the property name LABEL. This property specifies the formatted delivery address label for the vCard object. An example of a domestic delivery label follows: -LABEL;DOM;POSTAL;ENCODING=QUOTED-PRINTABLE:P. O. Box 456=0D=0A= -123 Main Street=0D=0A= -Any Town, CA 91921-1234 -An example of an international delivery label follows: -LABEL;INTL;PARCEL,ENCODING=QUOTED-PRINTABLE:Suite 101=0D=0A= -123 Main Street=0D=0A= -Any Town, CA 91921-1234=0D=0A= -U.S.A. -Support for this property is optional for vCard Writers conforming to this specification. A vCard Reader supporting this property and conforming to this specification should support a minimum of four lines of text for this property. -Delivery Label Type -This property parameter specifies the sub-types of physical delivery that is associated with the delivery label. For example, the label may need to be differentiated for Home, Work, Parcel, Postal, Domestic, and International physical delivery. One or more sub-types can be specified for a given delivery label. -The property parameter can have one or more of the following values: - -Description -Property Parameter Value - -TYPE= - - -Indicates a domestic address -DOM - -Indicates an international address (Default) -INTL - -Indicates a postal delivery address (Default) -POSTAL - -Indicates a parcel delivery address (Default) -PARCEL - -Indicates a home delivery address -HOME - -Indicates a work delivery address (Default) -WORK - - -The default property parameter is overridden to some other set of values by specifying one or more alternate values. For example, the default of a delivery for INTL, WORK, POSTAL and PARCEL can be reset to DOM and HOME in the following example: -LABEL;DOM;HOME,ENCODING=QUOTED-PRINTABLE:Suite 101=0D=0A= -123 Main Street=0D=0A= -Any Town, CA 91921-1234 -Telecommunications Addressing Properties -These property types are concerned with information associated with the telecommunications addressing of the vCard object. -Telephone Number -This property specifies the canonical number string for a telephone number for telephony communication with the vCard object. The value of this property is specified in a canonical form in order to specify an unambiguous representation of the globally unique telephony endpoint. This property is based on the X.520 Telephone Number attribute. -The canonical form cannot be dialed without first being transformed by a dialing algorithm. The dialing algorithm combines the canonical number string with knowledge of the local dialing procedures, in effect at the time of call placement to produce actual dialing instructions. The actual dialing algorithm is outside the scope of this specification. -Two important canonical forms allowed by this specification are: -* Apple Computer's Representation of a Canonical Static DeviceID in The Telephony Suite, version 1.0, -* Microsoft TAPI in the Microsoft Windows 3.1 Telephony Programmer's Guide, version 1.0. -Software which creates this property can store a string in these allowed formats. Dialing s - -Description -Property Parameter Value - -TYPE= - - -Indicates Graphics Interchange Format -GIF - -Indicates ISO Computer Graphics Metafile -CGM - -Indicates MS Windows Metafile -WMF - -Indicates MS Windows Bitmap -BMP - -Indicates IBM PM Metafile -MET - -Indicates IBM PM Bitmap -PMB - -Indicates MS Windows DIB -DIB - -Indicates an Apple Picture format -PICT - -Indicates Tagged Image File Format -TIFF - -Indicates Adobe Page Description Format -PDF - -Indicates Adobe PostScript -PS - -Indicates ISO JPEG format -JPEG - -Indicates ISO MPEG format -MPEG - -Indicates ISO MPEG version 2 format -MPEG2 - -Indicates Intel AVI format -AVI - -Indicates Apple QuickTime format -QTIME - - -Agent -This property specifies information about another person who will act on behalf of the vCard object. Typically this would be an area administrator, assistant, or secretary for the individual. A key characteristic of the Agent property is that it represents somebody or something which is separately addressable. For example, if all phone calls or e-mail messages are normally screened by an agent, this property may not be needed. On the other hand, if an agent can act as a proxy, and may otherwise need to be contacted separately, then an Agent property is useful. -This property is equivalent to nesting another vCard with the specified vCard. -This property is identified by the property name AGENT. The value of this property is a string containing another vCard object. An example of this property follows: -AGENT: -BEGIN:VCARD -VERSION:2.1 -N:Friday;Fred -TEL;WORK;VOICE:+1-213-555-1234 -TEL;WORK;FAX:+1-213-555-5678 -END:VCARD -Support for this property is optional for vCard Writers conforming to this specification. -Organization Name and Organizational Unit -This property specifies the name and optionally the unit(s) of the organization associated with the vCard object. This property is based on the X.520 Organization Name attribute and the X.520 Organization Unit attribute. For example, "The AB Corporation" and the "North American Division". -This property is identified by the property name ORG. This property is defined to encapsulate the Organization Name and Organization Unit properties as sub-properties. The property value consists of the components of the organization specified as positional fields separated by the Field Delimiter (ASCII decimal 59). The property value is a concatenation of the Organization Name (first field), Organizational Unit (second field) strings. Additional positional fields, if specified, contain additional Organizational Units. The following is an example of the Organization property: -ORG:ABC, Inc.;North American Division;Marketing -Support for this property is optional for vCard Writers conforming to this specification. -Explanatory Properties -These property types are concerned with additional explanations, such as that related to national language support, annotation, or encoding of binary information about the vCard object. -Comment -This property specifies supplemental information or a comment that is associated with the vCard. With the use of property grouping, the association can be limited to a group of properties. The property is based on the X.520 Description attribute. -This property is identified by the property name NOTE. An example of this property follows: -NOTE;ENCODING=QUOTED-PRINTABLE:This facsimile machine if operational= - 0830 to 1715 hours=0D=0A= -Monday through Friday. Call +1-213-555-1234 if you have problems=0D=0A= -with access to the machine. -Support for this property is optional for vCard Writers conforming to this specification. -Last Revision -This property specifies the combination of the calendar date and time of day of the last update to the vCard object. The property value is a character string conforming to the basic or extended format of ISO 8601. The value can either be in terms of local time or UTC. -This property is identified by the property name REV. Valid values for this property are a character string representing a combination of the calendar date and time of day conforming to the basic or extended format of ISO 8601. The time of day can be either local time or UTC. The following example is in the basic format and local time of ISO 8601: -REV:19951031T222710 -The following example is in the extended format and UTC time of ISO 8601: -REV:1995-10-31T22:27:10Z -Support for this property is optional for vCard Writers conforming to this specification. -Sound -This property specifies a sound annotation for the vCard object. By default, if this property is not grouped with other properties it specifies the pronunciation of the Formatted Name property of the vCard object. Such information may be in the form of a string of characters representing a phonetic sound or in the form of a digitized sound, or both; subject to the limitations imposed by the encoding used to communicate the vCard. -This property is identified by the property name SOUND. Valid values for this property are either a string representation, a reference to a digital audio representation, or an inline digital audio representation of the phonetic pronunciation of the Formatted Name property. The following example shows the string based phonetic representation: -SOUND:JON Q PUBLIK -The following example shows the digtial sound representation and URL based value: -SOUND;VALUE=URL:file///multimed/audio/jqpublic.wav -The following example shows the digtial sound representation and INLINE value: -SOUND;WAVE;BASE64: - UklGRhAsAABXQVZFZm10IBAAAAABAAEAESsAABErAAABAAgAZGF0YesrAACAg4eC - eXR4e3uAhoiIiYmKjIiDfnx5eX6CgoKEhYWDenV5fH6BhISGiIiDfHZ2eXt/hIiK - jY2IhH12d3Vyc3uDiIiFf3l7fn18eXl+houFf319fnyAgHl5eoCIiISChIeAfnt2 -... -Support for this property is optional for vCard Writers conforming to this specification. -Sound Digital Audio Type -This property parameteris provided to specify the type of the digital audio Pronunciation for the vCard object. The property parameter can have the following values: - -Description -Property Parameter Value - -TYPE= - - -Indicates Wave format -WAVE - -Indicates MIME basic audio type -PCM - -Indicates AIFF format -AIFF - - -Uniform Resource Locator -This property specifies a value that represents a Uniform Resource Locator (URL). An URL is a representation of an Internet location that can be used to obtain real-time information about the vCard object. Application of this property might be to specify the location of a publicly accessible directory where up-to-date or additional information on the individual or resource associated with a vCard can be found. -This property is identified by the property name URL. Valid values for this property are a string conforming to the IETF RFC 1738, Uniform Resource Locators. The following is an example of this property: -URL:http://abc.com/pub/directory/northam/jpublic.ecd -Support for this property is optional for vCard Writers conforming to this specification. -Unique Identifier -This property specifies a value that represents a persistent, globally unique identifier associated with the object. The property can be used as a mechanism to relate different vCard objects. Some examples of valid forms of unique identifiers would include ISO 9070 formal public identifiers (FPI), X.500 distinguished names, machine-generated "random" numbers with a statistically high likelihood of being globally unique and Uniform Resource Locators (URL). If an URL is specified, it is suggested that the URL reference a service which will produce an updated version of the vCard. -This property is identified by the property name UID. This property is provided to enable a vCard Reader and Writer to uniquely identify either a vCard object instance or properties within a vCard object. Valid values for this property are a unique character string. The following is an example of this property: -UID:19950401-080045-40000F192713-0052 -Support for this property is optional for vCard Writers conforming to this specification. -Version -This property specifies the identifier corresponding to the highest version number of the vCard Specification supported by the implementation that created the vCard object. The value of this property must be 2.1 to correspond to this specification.. -This property is identified by the property name VERSION. The following is an example of this property: -VERSION:2.1 -Support for this property is mandatory for implementations conforming to this specification. This property must appear within the vCard data stream. -Security Properties -These property types are concerned with the security of the information in the vCard object. -Public Key -This property specifies the public encryption key associated with the vCard object. -This property is identified by the property name KEY. Valid values for this property are a public key that conforms to a bilaterally agreed to representation. If the representation is a binary format, then the public key must be further encoded. The default format is clear-text. If a binary format is used, then it is specified by the property parameter. Support for this property is optional for vCard Writers conforming to this specification. -Key Type -This property parameter is provided to specify the type of the public key for the vCard object. The property parameter can have the following values: - -Description -Property Parameter Value - -TYPE= - - -Indicates a X.509 public key certificate type of key -X509 - -Indicates an IETF PGP type of key -PGP - -Miscellaneous Properties -Extensions -The vCard provides a ìstandard mechanism for doing non-standard thingsî. This extension support is provided for implementers to "push the envelope" on the existing version of the specification. Extension properties are specified by property and/or property parameter names that have the initial sub-string of X- (the two character sequence: Capital X character followed by the Dash character. It is recommended that vendors concatenate onto this sentinel an added short sub-string to identify the vendor. This will facilitate readability of the extensions and minimize possible collision of names between different vendors. For example, the following might be the ABC vendor's extension for a video-clip form of identification property: -X-ABC-VIDEO;MPEG2:http://lonestar.bubbas.org/billibob.mpg -or, the following example might be an extension for grouping vCard objects into a distribution list for the Design Work Group. -BEGIN:VCARD -VERSION:2.1 -X-DL;Design Work Group:List Item 1;List Item 2;List Item 3 -BEGIN:VCARD -UID:List Item 1 -N:John Smith -TEL:+1-213-555-1111 -END:VCARD -BEGIN:VCARD -UID:List Item 2 -N:I. M. Big -TEL:+1-213-555-9999 -END:VCARD -BEGIN:VCARD -UID:List Item 3 -N:Jane Doe -TEL:+1-213-555-5555 -END:VCARD -END:VCARD -At present, there is no registration authority for names of extension properties. -Support for this property is mandatory for implementations conforming to this specification. However, an implementation may not be able to act on the extension property. Conformance only requires that an implementation be able to parse vCard data streams with extensions. The implementation need not act on them. -Formal Definition -The following modified Backus-Naur Notation (BNF) is provided to assist developers in building parsers for the vCard. -This syntax is written according to the form described in RFC 822, but it references just this small subset of RFC 822 literals: - CR = <ASCII CR, carriage return> ; ( 15, 13.) - LF = <ASCII LF, linefeed> ; ( 12, 10.) - CRLF = CR LF - SPACE = <ASCII SP, space> ; ( 40, 32.) - HTAB = <ASCII HT, horizontal-tab> ; ( 11, 9.) -All literal property names are valid as upper, lower, or mixed case. -ws = 1*(SPACE / HTAB) - ; "whitespace," one or more spaces or tabs -wsls = 1*(SPACE / HTAB / CRLF) - ; whitespace with line separators -word = <any printable 7bit us-ascii except []=:., > -groups = groups "." word - / word -vcard_file = [wsls] vcard [wsls] -vcard = "BEGIN" [ws] ":" [ws] "VCARD" [ws] 1*CRLF - items *CRLF "END" [ws] ":" [ws] "VCARD" -items = items *CRLF item - / item - ; these may be "folded" -item = [groups "."] name - [params] ":" value CRLF - / [groups "."] "ADR" - [params] ":" addressparts CRLF - / [groups "."] "ORG" - [params] ":" orgparts CRLF - / [groups "."] "N" - [params] ":" nameparts CRLF - / [groups "."] "AGENT" - [params] ":" vcard CRLF - ; these may be "folded" -name = "LOGO" / "PHOTO" / "LABEL" / "FN" / "TITLE" - / "SOUND" / "VERSION" / "TEL" / "EMAIL" / "TZ" / "GEO" / "NOTE" - / "URL" / "BDAY" / "ROLE" / "REV" / "UID" / "KEY" - / "MAILER" / "X-" word - ; these may be "folded" -value = 7bit / quoted-printable / base64 -7bit = <7bit us-ascii printable chars, excluding CR LF> -8bit = <MIME RFC 1521 8-bit text> -quoted-printable = <MIME RFC 1521 quoted-printable text> -base64 = <MIME RFC 1521 base64 text> - ; the end of the text is marked with two CRLF sequences - ; this results in one blank line before the start of the next property -params = ";" [ws] paramlist -paramlist = paramlist [ws] ";" [ws] param - / param -param = "TYPE" [ws] "=" [ws] ptypeval - / "VALUE" [ws] "=" [ws] pvalueval - / "ENCODING" [ws] "=" [ws] pencodingval - / "CHARSET" [ws] "=" [ws] charsetval - / "LANGUAGE" [ws] "=" [ws] langval - / "X-" word [ws] "=" [ws] word - / knowntype -ptypeval = knowntype / "X-" word -pvalueval = "INLINE" / "URL" / "CONTENT-ID" / "CID" / "X-" word -pencodingval = "7BIT" / "8BIT" / "QUOTED-PRINTABLE" / "BASE64" / "X-" word -charsetval = <a character set string as defined in Section 7.1 of - RFC 1521> -langval = <a language string as defined in RFC 1766> -addressparts = 0*6(strnosemi ";") strnosemi - ; PO Box, Extended Addr, Street, Locality, Region, Postal Code, - Country Name -orgparts = *(strnosemi ";") strnosemi - ; First is Organization Name, remainder are Organization Units. -nameparts = 0*4(strnosemi ";") strnosemi - ; Family, Given, Middle, Prefix, Suffix. - ; Example:Public;John;Q.;Reverend Dr.;III, Esq. -strnosemi = *(*nonsemi ("\;" / "\" CRLF)) *nonsemi - ; To include a semicolon in this string, it must be escaped - ; with a "\" character. -nonsemi = <any non-control ASCII except ";"> -knowntype = "DOM" / "INTL" / "POSTAL" / "PARCEL" / "HOME" / "WORK" - / "PREF" / "VOICE" / "FAX" / "MSG" / "CELL" / "PAGER" - / "BBS" / "MODEM" / "CAR" / "ISDN" / "VIDEO" - / "AOL" / "APPLELINK" / "ATTMAIL" / "CIS" / "EWORLD" - / "INTERNET" / "IBMMAIL" / "MCIMAIL" - / "POWERSHARE" / "PRODIGY" / "TLX" / "X400" - / "GIF" / "CGM" / "WMF" / "BMP" / "MET" / "PMB" / "DIB" - / "PICT" / "TIFF" / "PDF" / "PS" / "JPEG" / "QTIME" - / "MPEG" / "MPEG2" / "AVI" - / "WAVE" / "AIFF" / "PCM" - / "X509" / "PGP" - - -Section 3 : Internet Recommendations -[DS4] 1 -Recommended Practice with SMTP/MIME -The vCard information can be transported through SMTP/MIME based electronic mail services. Interoperability of vCard information over SMTP/MIME transports can be better assured by following a common set of recommended practices for encapsulation of the vCard. -Text/Plain Content Type -Without any change to existing SMTP or MIME compliant user agents, a vCard can be included within Internet email messages. This might be the case for an existing, simple user agent such as a legacy SMTP mail system. While this approach provides for transport of vCards over SMTP services, it does not allow for the end user to take advantage of the full capabilities of either the vCard or Internet email (i.e., MIME) functionality. -The following demonstrates how a vCard can be included as an epilog to a SMTP message made up of a RFC 822 message. This may be an initial method for incorporating vCard objects into SMTP messages. -Date: Thr, 25 Jan 96 0932 EDT -From: john.smith@host.com -Subject: Re: RFC822 vCard Example -Sender: john.smith@host.com -To: smartin@host2.com -Message-ID: <JOHNSMITH.960125T091020.xyzMail@host3.com> - -Steve: Thanks for the call earlier today. I am unable to -use your material at this time. Please feel free to contact -me in the future. -BEGIN:VCARD -VERSION:2.1 -N:Smith;John;M.;Mr.;Esq. -TEL;WORK;VOICE;MSG:+1 (919) 555-1234 -TEL;WORK;FAX:+1 (919) 555-9876 -ADR;WORK;PARCEL;POSTAL;DOM:Suite 101;1 Central St.;Any Town;NC;27654 -END:VCARD -The following example demonstrates how a vCard can be included as a separate text/plain content portion within current MIME user agents. -Date: Fri, 26 Jan 1996 07:53:00 -0500 -From: smartin@host2.com -Subject: RE: Text/Plain MIME vCard Example -To: fdawson@VNET.IBM.COM -Mime-Version: 1.0 -Content-Type: multipart/mixed; boundary=vcard -Message-ID: <ABC-1.00-Note-martin-steve-0824475754> - ---vcard -Content-Type:text/plain; charset=us-ascii -Content-Transfer-Encoding: 7bit -John: I have looked over my material and feel that you may -have over looked a couple of appropriate pieces. Please give -me a call so that we can discuss further. ---vcard -Content-Type:text/plain; charset=us-ascii; name="MARTIN.VCF" - -BEGIN:VCARD -VERSION:2.1 -N:Martin;Stephen -TEL;HOME;VOICE:+1 (210) 555-1357 -TEL;HOME;FAX:+1 (210) 555-0864 -ADR;WORK;PARCEL;POSTAL;DOM:123 Cliff Ave.;Big Town;CA;97531 -END:VCARD ---vcard-- -Text/X-vCard Content Type -A vCard object may also be transferred in a (RFC 1521) MIME entity as a non-standard "text/x-vCard" content-type. This (RFC 1521) MIME type maybe useful in those cases where the MIME compliant messaging service does not yet support the "application/directory" and "multipart/related" MIME content-types and yet the specificity of a calendaring and scheduling media type is required. -The following example demonstrates how a vCard can be included as a separate non-standard text/x-vCard content portion within current MIME user agents. -Date: Fri, 26 Jan 1996 07:53:00 +0000 -From: smartin@host2.com -Subject: RE: Text/x-vCard MIME vCard Example -To: fdawson@VNET.IBM.COM -Mime-Version: 1.0 -Content-Type: multipart/mixed; boundary=vcard -Message-ID: <ABC-1.00-Note-martin-steve-0824475754> - ---vcard -Content-Type:text/plain; charset=us-ascii -Content-Transfer-Encoding: 7bit -John: I have looked over my material and feel that you may -have over looked a couple of appropriate pieces. Please give -me a call so that we can discuss further. ---vcard -Content-Type:text/x-vCard; charset=us-ascii; name="MARTIN.VCF" - -BEGIN:VCARD -VERSION:2.1N:Martin;Stephen -TEL;HOME;VOICE:+1 (210) 555-1357 -TEL;HOME;FAX:+1 (210) 555-0864 -ADR;WORK;PARCEL;POSTAL;DOM:123 Cliff Ave.;Big Town;CA;97531 -END:VCARD ---vcard-- -Application/Directory Content Type -The Internet Engineering Task Force (IETF) Access and Searching of Internet Directories (ASID) working group has produced an Internet Draft defining the "application/directory" MIME content type. The current draft name is draft-ietf-asid-mime-direct-01.txt. This specification is intended to be aligned with this work. Internet Drafts are working documents of an IETF working group, valid for at most six months, and should be considered "works in progress". -This MIME content type was designed to be used to transport directory information across MIME based electronic mail services. The internet draft is directly applicable to the exchange of business card data, such as that defined by the vCard specification. -The versit PDI Team has worked within the IETF ASID Working Group to draft an application/directory profile that registers the method for transporting a vCard as an application/directory Content-Type. The current draft name is draft-ietf-asid-mime-vcard-00.txt. This work is expected to be progressed to a Request For Comment after the publication of this version of the vCard specification. In the interim, the following guidelines are provided to describe how a vCard might be conveyed using the application/directory draft specification. -A vCard should be included in a MIME message that has a Content-Type header field value of "multipart/related". The vCard is included in the message as the primary body part. The position of the body part entity can also be specified with the "start=" parameter. This MIME body part entity has a Content-Type body part header field value of "application/directory" with a "profile" parameter value of "vcard". Any vCard binary information, such as a logo, picture, or digital audio pronunciation can be included inline within the vCard, as is specified by the vCard specification. Preferably, the binary information should be extracted from the vCard object and contained in the MIME message as secondary body part entities. The binary content in the secondary body part entities can be referenced from within the vCard object through the use of the "VALUE=" property parameter. In this latter case, the binary information should be transformed into a content type nominally supported by MIME user agents. For image content, this would be the Graphics Image Format (GIF) or Joint Picture Encoding Group (JPEG) formats. For audio content, this would be the 8-bit mu-law (PCM) format specified by the MIME specification. -The following example defines how this might be specified: -Date: Mon, 29 Jan 96 0830 EDT -From: john.smith@host.com -Subject: Re: MIME application/directory vCard Example -Sender: john.smith@host.com -To: smartin@host2.com -Message-ID: <JOHNSMITH.960129T083020.xyzMail@host3.com> -Content-Type: multipart/related; boundary="vcard"; - type=application/directory; - start=<JOHNSMITH.part1.960129T083020.xyzMail@host3.com> ---vcard -Content-Type: application/directory; charset=us-ascii; - source="file://versit.or2"; profile="vcard" -Content-ID: <<JOHNSMITH.part1.960129T083020.xyzMail@host3.com> -BEGIN:VCARD -VERSION:2.1 -N:Smith;John;M.;Mr.;Esq. -TEL;WORK;VOICE;MSG:+1 (919) 555-1234 -TEL;CELL:+1 (919) 554-6758 -TEL;WORK;FAX:+1 (919) 555-9876 -PHOTO;GIF;MIME:<<JOHNSMITH.part3.960129T083020.xyzMail@host3.com> -ADR;WORK;PARCEL;POSTAL;DOM:Suite 101;1 Central St.;Any Town;NC;27654 -END:VCARD ---vcard -Content-Type: text/plain; charset=us-ascii -Content-ID: <<JOHNSMITH.part2.960129T083020.xyzMail@host3.com> -Steve: -I am not in the office today. You may want to try -reaching me either on my cellular telephone or fax your -new ideas to my office. -Let's setup a face-to-face meeting later this week, after I review -your updated material. I am including a picture in my business card -data, since we have not met yet. --- John ---vcard -Content-Type: image/gif -Content-ID: <<JOHNSMITH.part3.960129T083020.xyzMail@host3.com> -...image data would go here... ---vcard-- -Recommended Practice with HTTP/HTML -A vCard object should be transferred over HTTP with the non-standard MIME type/subtype value of "text/x-vCard". The non-standard subtype should be used because the vCard has not been registered as a MIME media type with the IANA. -The vCard information can be captured with a FORM type of HTML document. Interoperability of of vCard information can be better assured by following a common set of recommended practices for mapping vCard information into and out of HTML documents. -Form Element Usage -The HTML FORM element is a useful method for capturing data intended for input into individual vCard property values. The following recommended practices are provided for such use. -Mapping To INPUT Element Attribute Names -An HTML form data set is a useful mechanism for capturing vCard data within the Internet WWW. The use of a consistent naming scheme for the name attributes within a form element will permit implementations to support automatic fill-in of forms with existing vCard data. In addition, such a consistent naming scheme will provide a greater assurance of interoperability between HTML based applications that use vCard data. -The following table provides a recommended mapping of vCard properties and name attributes within a form element. -Identification Properties -Description -Attribute Name -Comment - -Formatted Name -FN - - -Name -N -Individual components of name property are captured as separate input elements with the names N.Family, N.First, N.Middle, N.Prefix, N.Suffix. - -Photograph -PHOTO -Only the URL based specification is supported by this mapping. Value is the URL for the graphic. - -Photograph Format Type -PHOTO.Type -Where the value is one of the enumerated strings defined by the vCard specification. - -Birthdate -BDAY - - - -Delivery Addressing Properties -Description -Attribute Name -Comment - -Delivery Address -ADR -TYPE=TEXTAREA - -Address Type -ADR.x -TYPE=CHECKBOX. Separate input elements are used to capture the possible delivery types. The elements are named ADR.x, where x is one of the enumerated strings defined by the vCard specification. - -Delivery Label -LABEL - - -Label Type -LABEL.x -TYPE=CHECKBOX. Separate input elements are used to capture the possible delivery types. The elements are named LABEL.x, where x is one of the enumerated strings defined by the vCard specification. - - -Telecommunications Addressing Properties -Description -Attribute Name -Comment - -Telephone Number -TEL - - -Telephone Type -TEL.x -TYPE=CHECKBOX. Separate input elements are used to capture the possible telephone types. The elements are named TEL.x, where x is one of the enumerated strings defined by the vCard specification. - -Electronic Mail Address -EMAIL - - -Electronic Mail Address Type -EMAIL.Type -Selection option from a list of alternatives. - -Mailer -MAILER - - - -Geographical Properties -Description -Attribute Name -Comment - -Time Zone -TZ - - -Geographic Position -GEO - - - -Organizational Properties -Description -Attribute Name -Comment - -Title -TITLE - - -Business Category -ROLE - - -Logo -LOGO -Only the URL based specification is supported by this mapping. Value is the URL for the graphic. - -Logo Format Type -LOGO.Type -Where the value is one of the enumerated strings defined by the vCard specification. - -Agent - -Captured through a separate form element using the mapping defined in these tables. - -Organization -ORG -TYPE=TEXT. Separate input elements for the organizational name and unit. The name ORG.Name is used to capture the organizational name. The name ORG.UNIT is used to capture the organizational unit. If there are multiple organizational units, it is captured in a form with name attributes ORG.UNIT1, ORG.UNIT2, etc. - - -Explanatory Properties -Description -Attribute Name -Comment - -Comment -NOTE -TYPE=TEXT - -Last Revision -REV -A hidden field. - -Version -VERSION -A hidden field with the value set to the string ì2.1î. - -Language -LANG -A hidden field with the value set to the string associated with the default language used in the form (e.g., US-eng). - -Sound -SOUND -TYPE=TEXT - -Sound Type -N/A - - -Uniform Resource Locator -URL -TYPE=TEXT - -Unique Identifier -UID -TYPE=TEXT - -Binary Encoding -BE.x -Where x is one of the enumerated encoding types defined by the vCard specification. - - -Security Properties -Description -Attribute Name -Comment - -Public Key -KEY - - -Key Type -KEY.Type.x -Where x is one of the enumerated encoding types defined by the vCard specification. - -MISCELLANEOUS PROPERTIES - - - -Extensions -X-x -Where x is a string defined by the extension author. - - -Where multiple properties (e.g., telephone numbers) appear, a label prefix should be used. For example, telephone #1 might have a name attribute of ìA.TELî, telephone #2 might have a name attribute of ìB.TELî, etc. -Example HTML Code -The following HTML code is an example of the use of the mapping of INPUT element attributes names to vCard property names. The code can be used to capture input data for creating a vCard on a Web homepage. -<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN"> -<head> -<title>Create Your Own Versitcard</title> -</head> -<IMG src="versit.gif"> -<h1>Create Your Own Versitcard</h1> -<P> Fill out this form and we'll -create a <b>Versitcard</b> for you and send it to the email address of your choice, -along with more information on the Versitcard format.</P> -<hr><!-- Identification And Organizational Properties --> -<FORM METHOD="POST" ACTION="/cgi-bin/vcard-maker"> -Formatted Name:<INPUT name="FN" type=text size=32 maxlength=64 -value=""><br> -Phoenetic Pronunciation:<INPUT name="SOUND" type=text size=32 maxlength=128 value=""><br> -Company Name:<INPUT name="ORG.Name" type=text size=32 maxlength=64 -value=""><br> -Company Unit:<INPUT name="ORG.Unit" type=text size=32 -maxlength=64 value=""><br> -Title:<INPUT name="TITLE" type=text size=32 maxlength=64 -value=""> -<hr><!-- Name Property Component Values --> -Family Name:<INPUT name="N.Family" type=text size=32 maxlength=64 -value=""><br> -Given Name:<INPUT name="N.Given" type=text size=32 -maxlength=64 value=""><br> -Middle Name:<INPUT name="N.Middle" type=type size=32 -maxlength=64 value=""><br> -Name Prefix:<INPUT name="N.Prefix" type=type size=32 -maxlength=64 value=""><br> -Name Suffix:<INPUT name="N.Suffix" type=type size=32 -maxlength=64 value=""><br> -<hr><!-- Delivery Addressing Properties --> -Delivery Label:<TEXTAREA name="LABEL" cols=64 ROWS=5> -</TEXTAREA><br><br> -Post Office Address:<INPUT name="ADR.POAddr" type=text size=32 -maxlength=64 value=""><br> -Extended Address:<INPUT name="ADR.ExtAddr" type=text size=32 -maxlength=64 value=""><br> -Street Address:<INPUT name="ADR.Street" type=text size=62 -maxlength=128 value=""><br> -City:<INPUT name="ADR.Locality" type=text size=16 maxlength=32 -value=""> -Region:<INPUT name="ADR.Region" type=text size=16 maxlength=32 -value=""> -Postal Code:<INPUT name="ADR.PostalCode" type=text size=16 maxlength=32 -value=""><br> -Country Name:<INPUT name="ADR.CountryName" type=text size=16 maxlength=32 value="USA"> -<INPUT type=checkbox name="ADR.Work" value=WORK checked>Work -<INPUT type=checkbox name="ADR.Home" value=HOME>Home -<INPUT type=checkbox name="ADR.Parcel" value=PARCEL checked>Parcel <INPUT type=checkbox name="ADR.Postal" value=POSTAL checked>Postal<br> -<hr><!-- Geographical Properties --> -TimeZone:<INPUT name="TZ" type=text size=3 maxlength=8 -value="-06"> -Location:<INPUT name="GEO" type=text size=16 maxlength=32 value=""><br> -<hr><!-- Telephony Addressing Properties --> -<!-- Telephone #1 --> -Telephone #1:<INPUT type=text name="A.TEL" size=20 maxlength=40 value="+1 (000) 000-0000"><br> -<INPUT type=checkbox name="A.TEL.Work" value=WORK checked>Work -<INPUT type=checkbox name="A.TEL.Home" value=HOME>Home -<INPUT type=checkbox name="A.TEL.Voice" value=VOICE checked>Voice -<INPUT type=checkbox name="A.TEL.Msg" value=MSG checked>Msg <INPUT type=checkbox name="A.TEL.Fax" value=FAX>Fax <INPUT type=checkbox name="A.TEL.Prefer" value=PREFER checked>Preferred<br> -<hr><!-- Telephone #2 --> -Telephone #2:<INPUT type=text name="B.TEL" size=20 maxlength=40 value="+1 (000) 000-0000"><br> -<INPUT type=checkbox name="B.TEL.Work" value=WORK checked>Work <INPUT type=checkbox name="B.TEL.Home" value=HOME>Home -<INPUT type=checkbox name="B.TEL.Voice" value=VOICE>Voice <INPUT type=checkbox name="B.TEL.Msg" value=MSG>Msg -<INPUT type=checkbox name="B.TEL.Fax" value=FAX checked>Fax -<INPUT type=checkbox name="B.TEL.Prefer" value=PREFER>Preferred<br> -<hr><!-- Telephone #3 --> -Telephone #3:<INPUT type=text name= "C.TEL" size=20 maxlength=40 value="+1 (000) 000-0000"><br> -<INPUT type=checkbox name="C.TEL.Work" value=WORK>Work -<INPUT type=checkbox name="C.TEL.Home" value=HOME checked>Home <INPUT type=checkbox name="C.TEL.Voice" value=VOICE checked>Voice <INPUT type=checkbox name="C.TEL.Msg" value=MSG checked>Msg -<INPUT type=checkbox name="C.TEL.Fax" value=FAX checked>Fax <INPUT type=checkbox name="D.Prefer" value=PREFER>Preferred<br> -<hr><!-- Email D --> -EmailAddress: <select name="D.EMAILTYPE"> -<option selected>INTERNET: -<option>CompuServe: -<option>AOL: -<option>Prodigy: -<option>eWorld: -<option>AppleLink: -<option>AppleTalk: -<option>PowerShare: -<option>IBMMail: -<option>ATTMail: -<option>MCIMail: -<option>X.400: -<option>TLX: -</select><INPUT type=text name="D.EMAIL" size=32 maxlength=64 value=""> -<INPUT type=checkbox name="D.EMAIL.Work" value=WORK checked>Work <INPUT type=checkbox name="D.EMAIL.Home" value=HOME checked>Home<br> -<hr><!-- End of vCard Input --> -Send my Versitcard to this <b>internet</b> email address: -<INPUT type=text name="SENDTOADDR" size=32 maxlength=64 value=""><br> Press <INPUT TYPE=SUBMIT value="Send"> to send the form now. Or, press <INPUT TYPE=RESET value="Reset"> to reset values to the form defaults. -</form> -</body> - - -Section 4 : UI Support Recommendations -[DS5] -When integrating vCard support into an application, an implementor needs to consider a number of user interface (UI) implications. Most appliss Type -ADR.x -TYPE=CHECKBOX. Separate input elements are used to capture the possible delivery types. The elements are named ADR.x, where x is one of the enumerated strings defined by the vCard specification. - -Delivery Label -LABEL - - -Label Type -LABEL.x -TYPE=CHECKBOX. Separate input elements are used to capture the possible delivery types. The elements are named LABEL.x, where x is one of the enumerated strings defined by the vCard specification. - - -Telecommunications Addressing Properties -Description -Attribute Name -Comment - -Telephone Number -TEL - - -Telephone Type -TEL.x -TYPE=CHECKBOX. Separate input elements are used to capture the possible telephone types. The elements are named TEL.x, where x is one of the enumerated strings defined by the vCard specification. - -Electronic Mail Address -EMAIL - - -Electronic Mail Address Type -EMAIL.Type -Selection option from a list of alternatives. - -Mailer -MAILER - - - -Geographical Properties -Description -Attribute Name -Comment - -Time Zone -TZ - - -Geographic Position -GEO - - - -Organizational Properties -Description -Attribute Name -Comment - -Title -TITLE - - -Business Category -ROLE - - -Logo -LOGO -Only the URL based specification is supported by this mapping. Value is the URL for the graphic. - -Logo Format Type -LOGO.Type -Where the value is one of the enumerated strings defined by the vCard specification. - -Agent - -Captured through a separate form element using the mapping defined in these tables. - -Organization -ORG -TYPE=TEXT. Separate input elements for the organizational name and unit. The name ORG.Name is used to capture the organizational name. The name ORG.UNIT is used to capture the organizational unit. If there are multiple organizational units, it is captured in a form with name attributes ORG.UNIT1, ORG.UNIT2, etc. - - -Explanatory Properties -Description -Attribute Name -Comment - -Comment -NOTE -TYPE=TEXT - -Last Revision -REV -A hidden field. - -Version -VERSION -A hidden field with the value set to the string ì2.1î. - -Language -LANG -A hidden field with the value set to the string associated with the default language used in the form (e.g., US-eng). - -Sound -SOUND -TYPE=TEXT - -Sound Type -N/A - - -Uniform Resource Locator -URL -TYPE=TEXT - -Unique Identifier -UID -TYPE=TEXT - -Binary Encoding -BE.x -Where x is one of the enumerated encoding types defined by the vCard specification. - - -Security Properties -Description -Attribute Name -Comment - -Public Key -KEY - - -Key Type -KEY.Type.x -Where x is one of the enumerated encoding types defined by the vCard specification. - -MISCELLANEOUS PROPERTIES - - - -Extensions -X-x -Where x is a string defined by the extension author. - - -Where multiple properties (e.g., telephone numbers) appear, a label prefix should be used. For example, telephone #1 might have a name attribute of ìA.TELî, telephone #2 might have a name attribute of ìB.TELî, etc. -Example HTML Code -The following HTML code is an example of the use of the mapping of INPUT element attributes names to vCard property names. The code can be used to capture input data for creating a vCard on a Web homepage. -<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN"> -<head> -<title>Create Your Own Versitcard</title> -</head> -<IMG src="versit.gif"> -<h1>Create Your Own Versitcard</h1> -<P> Fill out this form and we'll -create a <b>Versitcard</b> for you and send it to the email address of your choice, -along with more information on the Versitcard format.</P> -<hr><!-- Identification And Organizational Properties --> -<FORM METHOD="POST" ACTION="/cgi-bin/vcard-maker"> -Formatted Name:<INPUT name="FN" type=text size=32 maxlength=64 -value=""><br> -Phoenetic Pronunciation:<INPUT name="SOUND" type=text size=32 maxlength=128 value=""><br> -Company Name:<INPUT name="ORG.Name" type=text size=32 maxlength=64 -value=""><br> -Company Unit:<INPUT name="ORG.Unit" type=text size=32 -maxlength=64 value=""><br> -Title:<INPUT name="TITLE" type=text size=32 maxlength=64 -value=""> -<hr><!-- Name Property Component Values --> -Family Name:<INPUT nies. -All forms of vCard Grouping must be able to be parsed and processed. -Property Grouping must be able to be parsed and processed. -Additionally, in order for a vCard Writer to conform to this specification it must meet the following additional criteria: -Must be able to send at least the Version, Formatted Name, Name, Address, Telephone, Email, and Mailer properties. - - -[DS1]This entry (merged from the ìTRIAL USE (TU)î document) appears to be a duplicate of the already-existing entry that follows, except for the publicaton/edition date. I would assume that itís OK to delete this item, but, Ö -[DS2]This entry/line in the section is assigned the style for the level 1 heading. This is done so that a section number can be given in the chapter title (style "chptr_title") and so that "heading 1" (more specifically, the format/heading numbering of the form "1. Overview") can be "skipped," and the appropriate form for the next-level of heading can be properly displayed (eg., "1.1 Overview"). It is, and must be, formatted as "hidden text" prior to pagination and/or printing. -[DS3]This entry/line in the section is assigned the style for the level 1 heading. This is done so that a section number can be given in the chapter title (style "chptr_title") and so that "heading 1" (more specifically, the format/heading numbering of the form "1. Overview") can be "skipped," and the appropriate form for the next-level of heading can be properly displayed (eg., "1.1 Overview"). It is, and must be, formatted as "hidden text" prior to pagination and/or printing. -[DS4]This entry/line in the section is assigned the style for the level 1 heading. This is done so that a section number can be given in the chapter title (style "chptr_title") and so that "heading 1" (more specifically, the format/heading numbering of the form "1. Overview") can be "skipped," and the appropriate form for the next-level of heading can be properly displayed (eg., "1.1 Overview"). It is, and must be, formatted as "hidden text" prior to pagination and/or printing. -[DS5]This entry/line in the section is assigned the style for the level 1 heading. This is done so that a section number can be given in the chapter title (style ìchptr_title") and so that "heading 1" (more specifically, the format/heading numbering of the form "1. Overview") can be "skipped," and the appropriate form for the next-level of heading can be properly displayed (eg., "1.1 Overview"). It is, and must be, formatted as "hidden text" prior to pagination and/or printing. -[DS6]This entry/line in the section is assigned the style for the level 1 heading. This is done so that a section number can be given in the chapter title (style ìchptr_title") and so that "heading 1" (more specifically, the format/heading numbering of the form "1. Overview") can be "skipped," and the appropriate form for the next-level of heading can be properly displayed (eg., "1.1 Overview"). It is, and must be, formatted as "hidden text" prior to pagination and/or printing. - - - - - - - -$paratext[Pr.Preface] - - - - - - - - -vi vCard Specification, Version 2.1 - - v - -versit Update vii - - - - - - - -36 vCard Specification, Version 2.1 - - xi - - - - - 39 - - diff --git a/addressbook/backend/ebook/e-book-listener.c b/addressbook/backend/ebook/e-book-listener.c deleted file mode 100644 index 9d6d876045..0000000000 --- a/addressbook/backend/ebook/e-book-listener.c +++ /dev/null @@ -1,797 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * Exports the BookListener interface. Maintains a queue of messages - * which come in on the interface. - * - * Author: - * Nat Friedman (nat@ximian.com) - * - * Copyright 2000, Ximian, Inc. - */ - -#include <config.h> -#include <bonobo/bonobo-main.h> -#include "e-book-listener.h" -#include "e-book-marshal.h" - -static EBookStatus e_book_listener_convert_status (GNOME_Evolution_Addressbook_BookListener_CallStatus status); - -enum { - RESPONSES_QUEUED, - LAST_SIGNAL -}; - -static guint e_book_listener_signals [LAST_SIGNAL]; - -static BonoboObjectClass *parent_class; - -struct _EBookListenerPrivate { - GList *response_queue; - gint timeout_id; - - guint timeout_lock : 1; - guint stopped : 1; -}; - -static void -response_free (EBookListenerResponse *resp) -{ - if (resp == NULL) - return; - - g_free (resp->msg); - g_free (resp->id); - - if (resp->book != CORBA_OBJECT_NIL) { - CORBA_Environment ev; - - CORBA_exception_init (&ev); - - bonobo_object_release_unref (resp->book, &ev); - - if (ev._major != CORBA_NO_EXCEPTION) { - g_warning ("e_book_listener_destroy: " - "Exception destroying book " - "in response queue!\n"); - } - - CORBA_exception_free (&ev); - } - - if (resp->cursor != CORBA_OBJECT_NIL) { - CORBA_Environment ev; - - CORBA_exception_init (&ev); - - bonobo_object_release_unref (resp->cursor, &ev); - - if (ev._major != CORBA_NO_EXCEPTION) { - g_warning ("e_book_listener_destroy: " - "Exception destroying cursor " - "in response queue!\n"); - } - - CORBA_exception_free (&ev); - } - - if (resp->book_view != CORBA_OBJECT_NIL) { - CORBA_Environment ev; - - CORBA_exception_init (&ev); - - bonobo_object_release_unref (resp->book_view, &ev); - - if (ev._major != CORBA_NO_EXCEPTION) { - g_warning ("e_book_listener_destroy: " - "Exception destroying book_view " - "in response queue!\n"); - } - - CORBA_exception_free (&ev); - } - - g_free (resp); -} - -static gboolean -e_book_listener_check_queue (EBookListener *listener) -{ - if (listener->priv->timeout_lock) - return TRUE; - - listener->priv->timeout_lock = TRUE; - - if (listener->priv->response_queue != NULL && !listener->priv->stopped) { - g_signal_emit (listener, e_book_listener_signals [RESPONSES_QUEUED], 0); - } - - if (listener->priv->response_queue == NULL || listener->priv->stopped) { - listener->priv->timeout_id = 0; - listener->priv->timeout_lock = FALSE; - bonobo_object_unref (BONOBO_OBJECT (listener)); /* release the timeout's reference */ - return FALSE; - } - - listener->priv->timeout_lock = FALSE; - return TRUE; -} - -static void -e_book_listener_queue_response (EBookListener *listener, - EBookListenerResponse *response) -{ - if (response == NULL) - return; - - if (listener->priv->stopped) { - response_free (response); - return; - } - - listener->priv->response_queue = g_list_append (listener->priv->response_queue, response); - - if (listener->priv->timeout_id == 0) { - - /* 20 == an arbitrary small integer */ - listener->priv->timeout_id = g_timeout_add (20, (GSourceFunc) e_book_listener_check_queue, listener); - - /* Hold a reference on behalf of the timeout */ - bonobo_object_ref (BONOBO_OBJECT (listener)); - - } -} - -/* Add, Remove, Modify */ -static void -e_book_listener_queue_generic_response (EBookListener *listener, - EBookListenerOperation op, - EBookStatus status) -{ - EBookListenerResponse *resp; - - if (listener->priv->stopped) - return; - - resp = g_new0 (EBookListenerResponse, 1); - - resp->op = op; - resp->status = status; - - e_book_listener_queue_response (listener, resp); -} - -static void -e_book_listener_queue_open_response (EBookListener *listener, - EBookStatus status, - GNOME_Evolution_Addressbook_Book book) -{ - EBookListenerResponse *resp; - - if (listener->priv->stopped) - return; - - resp = g_new0 (EBookListenerResponse, 1); - - resp->op = OpenBookResponse; - resp->status = status; - resp->book = book; - - e_book_listener_queue_response (listener, resp); -} - -static void -e_book_listener_queue_open_progress (EBookListener *listener, - const char *msg, - short percent) -{ - EBookListenerResponse *resp; - - if (listener->priv->stopped) - return; - - resp = g_new0 (EBookListenerResponse, 1); - - resp->op = OpenProgressEvent; - resp->msg = g_strdup (msg); - resp->percent = percent; - - e_book_listener_queue_response (listener, resp); -} - - -static void -e_book_listener_queue_create_card_response (EBookListener *listener, - EBookStatus status, - const char *id) -{ - EBookListenerResponse *resp; - - if (listener->priv->stopped) - return; - - resp = g_new0 (EBookListenerResponse, 1); - - resp->op = CreateCardResponse; - resp->status = status; - resp->id = g_strdup (id); - - e_book_listener_queue_response (listener, resp); -} - -static void -e_book_listener_queue_get_vcard_response (EBookListener *listener, - EBookStatus status, - const char *vcard) -{ - EBookListenerResponse *resp; - - if (listener->priv->stopped) - return; - - resp = g_new0 (EBookListenerResponse, 1); - - resp->op = GetCardResponse; - resp->status = status; - resp->vcard = g_strdup (vcard); - - e_book_listener_queue_response (listener, resp); -} - -static void -e_book_listener_queue_get_cursor_response (EBookListener *listener, - EBookStatus status, - GNOME_Evolution_Addressbook_CardCursor cursor) -{ - EBookListenerResponse *resp; - - if (listener->priv->stopped) - return; - - resp = g_new0 (EBookListenerResponse, 1); - - resp->op = GetCursorResponse; - resp->status = status; - resp->cursor = cursor; - - e_book_listener_queue_response (listener, resp); -} - -static void -e_book_listener_queue_get_view_response (EBookListener *listener, - EBookStatus status, - GNOME_Evolution_Addressbook_BookView book_view) -{ - EBookListenerResponse *resp; - - if (listener->priv->stopped) - return; - - resp = g_new0 (EBookListenerResponse, 1); - - resp->op = GetBookViewResponse; - resp->status = status; - resp->book_view = book_view; - - e_book_listener_queue_response (listener, resp); -} - -static void -e_book_listener_queue_get_changes_response (EBookListener *listener, - EBookStatus status, - GNOME_Evolution_Addressbook_BookView book_view) -{ - EBookListenerResponse *resp; - - if (listener->priv->stopped) - return; - - resp = g_new0 (EBookListenerResponse, 1); - - resp->op = GetChangesResponse; - resp->status = status; - resp->book_view = book_view; - - e_book_listener_queue_response (listener, resp); -} - -static void -e_book_listener_queue_link_status (EBookListener *listener, - gboolean connected) -{ - EBookListenerResponse *resp; - - if (listener->priv->stopped) - return; - - resp = g_new0 (EBookListenerResponse, 1); - - resp->op = LinkStatusEvent; - resp->connected = connected; - - e_book_listener_queue_response (listener, resp); -} - -static void -e_book_listener_queue_writable_status (EBookListener *listener, - gboolean writable) -{ - EBookListenerResponse *resp; - - if (listener->priv->stopped) - return; - - resp = g_new0 (EBookListenerResponse, 1); - - resp->op = WritableStatusEvent; - resp->writable = writable; - - e_book_listener_queue_response (listener, resp); -} - -static void -e_book_listener_queue_authentication_response (EBookListener *listener, - EBookStatus status) -{ - EBookListenerResponse *resp; - - if (listener->priv->stopped) - return; - - resp = g_new0 (EBookListenerResponse, 1); - - resp->op = AuthenticationResponse; - resp->status = status; - - e_book_listener_queue_response (listener, resp); -} - -static void -e_book_listener_queue_get_supported_fields_response (EBookListener *listener, - EBookStatus status, - const GNOME_Evolution_Addressbook_stringlist *fields) -{ - EBookListenerResponse *resp; - int i; - - if (listener->priv->stopped) - return; - - resp = g_new0 (EBookListenerResponse, 1); - - resp->op = GetSupportedFieldsResponse; - resp->status = status; - resp->list = e_list_new ((EListCopyFunc)g_strdup, (EListFreeFunc)g_free, NULL); - - for (i = 0; i < fields->_length; i ++) { - e_list_append (resp->list, fields->_buffer[i]); - } - - e_book_listener_queue_response (listener, resp); -} - -static void -e_book_listener_queue_get_supported_auth_methods_response (EBookListener *listener, - EBookStatus status, - const GNOME_Evolution_Addressbook_stringlist *auth_methods) -{ - EBookListenerResponse *resp; - int i; - - if (listener->priv->stopped) - return; - - resp = g_new0 (EBookListenerResponse, 1); - - resp->op = GetSupportedAuthMethodsResponse; - resp->status = status; - resp->list = e_list_new ((EListCopyFunc)g_strdup, (EListFreeFunc)g_free, NULL); - - for (i = 0; i < auth_methods->_length; i ++) { - e_list_append (resp->list, auth_methods->_buffer[i]); - } - - e_book_listener_queue_response (listener, resp); -} - -static void -impl_BookListener_respond_create_card (PortableServer_Servant servant, - const GNOME_Evolution_Addressbook_BookListener_CallStatus status, - const CORBA_char* id, - CORBA_Environment *ev) -{ - EBookListener *listener = E_BOOK_LISTENER (bonobo_object (servant)); - - e_book_listener_queue_create_card_response ( - listener, - e_book_listener_convert_status (status), - id); -} - -static void -impl_BookListener_respond_remove_cards (PortableServer_Servant servant, - const GNOME_Evolution_Addressbook_BookListener_CallStatus status, - CORBA_Environment *ev) -{ - EBookListener *listener = E_BOOK_LISTENER (bonobo_object (servant)); - - e_book_listener_queue_generic_response ( - listener, RemoveCardResponse, - e_book_listener_convert_status (status)); -} - -static void -impl_BookListener_respond_modify_card (PortableServer_Servant servant, - const GNOME_Evolution_Addressbook_BookListener_CallStatus status, - CORBA_Environment *ev) -{ - EBookListener *listener = E_BOOK_LISTENER (bonobo_object (servant)); - - e_book_listener_queue_generic_response ( - listener, ModifyCardResponse, - e_book_listener_convert_status (status)); -} - -static void -impl_BookListener_respond_get_vcard (PortableServer_Servant servant, - const GNOME_Evolution_Addressbook_BookListener_CallStatus status, - const CORBA_char* card, - CORBA_Environment *ev) -{ - EBookListener *listener = E_BOOK_LISTENER (bonobo_object (servant)); - - e_book_listener_queue_get_vcard_response ( - listener, - e_book_listener_convert_status (status), - g_strdup (card)); -} - -static void -impl_BookListener_respond_get_cursor (PortableServer_Servant servant, - const GNOME_Evolution_Addressbook_BookListener_CallStatus status, - const GNOME_Evolution_Addressbook_CardCursor cursor, - CORBA_Environment *ev) -{ - EBookListener *listener = E_BOOK_LISTENER (bonobo_object (servant)); - GNOME_Evolution_Addressbook_CardCursor cursor_copy; - - cursor_copy = bonobo_object_dup_ref (cursor, ev); - - if (ev->_major != CORBA_NO_EXCEPTION) { - g_warning ("EBookListener: Exception while duplicating CardCursor!\n"); - return; - } - - e_book_listener_queue_get_cursor_response ( - listener, - e_book_listener_convert_status (status), - cursor_copy); -} - -static void -impl_BookListener_respond_get_view (PortableServer_Servant servant, - const GNOME_Evolution_Addressbook_BookListener_CallStatus status, - const GNOME_Evolution_Addressbook_BookView book_view, - CORBA_Environment *ev) -{ - EBookListener *listener = E_BOOK_LISTENER (bonobo_object (servant)); - GNOME_Evolution_Addressbook_BookView book_view_copy; - - book_view_copy = bonobo_object_dup_ref (book_view, ev); - - if (ev->_major != CORBA_NO_EXCEPTION) { - g_warning ("EBookListener: Exception while duplicating BookView.\n"); - return; - } - - e_book_listener_queue_get_view_response ( - listener, - e_book_listener_convert_status (status), - book_view_copy); -} - -static void -impl_BookListener_respond_get_changes (PortableServer_Servant servant, - const GNOME_Evolution_Addressbook_BookListener_CallStatus status, - const GNOME_Evolution_Addressbook_BookView book_view, - CORBA_Environment *ev) -{ - EBookListener *listener = E_BOOK_LISTENER (bonobo_object (servant)); - GNOME_Evolution_Addressbook_BookView book_view_copy; - - book_view_copy = bonobo_object_dup_ref (book_view, ev); - - if (ev->_major != CORBA_NO_EXCEPTION) { - g_warning ("EBookListener: Exception while duplicating BookView.\n"); - return; - } - - e_book_listener_queue_get_changes_response ( - listener, - e_book_listener_convert_status (status), - book_view_copy); -} - -static void -impl_BookListener_respond_open_book (PortableServer_Servant servant, - const GNOME_Evolution_Addressbook_BookListener_CallStatus status, - const GNOME_Evolution_Addressbook_Book book, - CORBA_Environment *ev) -{ - EBookListener *listener = E_BOOK_LISTENER (bonobo_object (servant)); - GNOME_Evolution_Addressbook_Book book_copy; - - book_copy = bonobo_object_dup_ref (book, ev); - - if (ev->_major != CORBA_NO_EXCEPTION) { - g_warning ("EBookListener: Exception while duplicating Book!\n"); - return; - } - - e_book_listener_queue_open_response ( - listener, - e_book_listener_convert_status (status), - book_copy); -} - -static void -impl_BookListener_report_open_book_progress (PortableServer_Servant servant, - const CORBA_char *status_message, - const CORBA_short percent, - CORBA_Environment *ev) -{ - EBookListener *listener = E_BOOK_LISTENER (bonobo_object (servant)); - - e_book_listener_queue_open_progress ( - listener, status_message, percent); -} - -static void -impl_BookListener_respond_authentication_result (PortableServer_Servant servant, - const GNOME_Evolution_Addressbook_BookListener_CallStatus status, - CORBA_Environment *ev) -{ - EBookListener *listener = E_BOOK_LISTENER (bonobo_object (servant)); - - e_book_listener_queue_authentication_response ( - listener, status); -} - -static void -impl_BookListener_response_get_supported_fields (PortableServer_Servant servant, - const GNOME_Evolution_Addressbook_BookListener_CallStatus status, - const GNOME_Evolution_Addressbook_stringlist *fields, - CORBA_Environment *ev) -{ - EBookListener *listener = E_BOOK_LISTENER (bonobo_object (servant)); - - e_book_listener_queue_get_supported_fields_response ( - listener, status, fields); -} - -static void -impl_BookListener_response_get_supported_auth_methods (PortableServer_Servant servant, - const GNOME_Evolution_Addressbook_BookListener_CallStatus status, - const GNOME_Evolution_Addressbook_stringlist *auth_methods, - CORBA_Environment *ev) -{ - EBookListener *listener = E_BOOK_LISTENER (bonobo_object (servant)); - - e_book_listener_queue_get_supported_auth_methods_response ( - listener, status, auth_methods); -} - -static void -impl_BookListener_report_connection_status (PortableServer_Servant servant, - const CORBA_boolean connected, - CORBA_Environment *ev) -{ - EBookListener *listener = E_BOOK_LISTENER (bonobo_object (servant)); - - e_book_listener_queue_link_status ( - listener, connected); -} - -static void -impl_BookListener_report_writable (PortableServer_Servant servant, - const CORBA_boolean writable, - CORBA_Environment *ev) -{ - EBookListener *listener = E_BOOK_LISTENER (bonobo_object (servant)); - - e_book_listener_queue_writable_status (listener, writable); -} - -/** - * e_book_listener_check_pending: - * @listener: the #EBookListener - * - * Returns: the number of items on the response queue, - * or -1 if the @listener is isn't an #EBookListener. - */ -int -e_book_listener_check_pending (EBookListener *listener) -{ - g_return_val_if_fail (listener != NULL, -1); - g_return_val_if_fail (E_IS_BOOK_LISTENER (listener), -1); - - return g_list_length (listener->priv->response_queue); -} - -/** - * e_book_listener_pop_response: - * @listener: the #EBookListener for which a request is to be popped - * - * Returns: an #EBookListenerResponse if there are responses on the - * queue to be returned; %NULL if there aren't, or if the @listener - * isn't an EBookListener. - */ -EBookListenerResponse * -e_book_listener_pop_response (EBookListener *listener) -{ - EBookListenerResponse *resp; - GList *popped; - - g_return_val_if_fail (listener != NULL, NULL); - g_return_val_if_fail (E_IS_BOOK_LISTENER (listener), NULL); - - if (listener->priv->response_queue == NULL) - return NULL; - - resp = listener->priv->response_queue->data; - - popped = listener->priv->response_queue; - listener->priv->response_queue = - g_list_remove_link (listener->priv->response_queue, - listener->priv->response_queue); - g_list_free_1 (popped); - - return resp; -} - -static EBookStatus -e_book_listener_convert_status (const GNOME_Evolution_Addressbook_BookListener_CallStatus status) -{ - switch (status) { - case GNOME_Evolution_Addressbook_BookListener_Success: - return E_BOOK_STATUS_SUCCESS; - case GNOME_Evolution_Addressbook_BookListener_RepositoryOffline: - return E_BOOK_STATUS_REPOSITORY_OFFLINE; - case GNOME_Evolution_Addressbook_BookListener_PermissionDenied: - return E_BOOK_STATUS_PERMISSION_DENIED; - case GNOME_Evolution_Addressbook_BookListener_CardNotFound: - return E_BOOK_STATUS_CARD_NOT_FOUND; - case GNOME_Evolution_Addressbook_BookListener_CardIdAlreadyExists: - return E_BOOK_STATUS_CARD_ID_ALREADY_EXISTS; - case GNOME_Evolution_Addressbook_BookListener_ProtocolNotSupported: - return E_BOOK_STATUS_PROTOCOL_NOT_SUPPORTED; - case GNOME_Evolution_Addressbook_BookListener_AuthenticationFailed: - return E_BOOK_STATUS_AUTHENTICATION_FAILED; - case GNOME_Evolution_Addressbook_BookListener_AuthenticationRequired: - return E_BOOK_STATUS_AUTHENTICATION_REQUIRED; - case GNOME_Evolution_Addressbook_BookListener_TLSNotAvailable: - return E_BOOK_STATUS_TLS_NOT_AVAILABLE; - case GNOME_Evolution_Addressbook_BookListener_NoSuchBook: - return E_BOOK_STATUS_NO_SUCH_BOOK; - case GNOME_Evolution_Addressbook_BookListener_OtherError: - return E_BOOK_STATUS_OTHER_ERROR; - default: - g_warning ("e_book_listener_convert_status: Unknown status " - "from card server: %d\n", (int) status); - return E_BOOK_STATUS_UNKNOWN; - - } -} - -static void -e_book_listener_construct (EBookListener *listener) -{ - /* nothing to do here */ -} - -/** - * e_book_listener_new: - * @book: the #EBook for which the listener is to be bound - * - * Creates and returns a new #EBookListener for the book. - * - * Returns: a new #EBookListener - */ -EBookListener * -e_book_listener_new () -{ - EBookListener *listener; - - listener = g_object_new (E_TYPE_BOOK_LISTENER, NULL); - - e_book_listener_construct (listener); - - return listener; -} - -static void -e_book_listener_init (EBookListener *listener) -{ - listener->priv = g_new0 (EBookListenerPrivate, 1); -} - -void -e_book_listener_stop (EBookListener *listener) -{ - g_return_if_fail (E_IS_BOOK_LISTENER (listener)); - - listener->priv->stopped = TRUE; -} - -static void -e_book_listener_dispose (GObject *object) -{ - EBookListener *listener = E_BOOK_LISTENER (object); - - if (listener->priv) { - GList *l; - - /* Remove our response queue handler: In theory, this - can never happen since we always hold a reference - to the listener while the timeout is running. */ - if (listener->priv->timeout_id) { - g_source_remove (listener->priv->timeout_id); - } - - /* Clean up anything still sitting in response_queue */ - for (l = listener->priv->response_queue; l != NULL; l = l->next) { - EBookListenerResponse *resp = l->data; - - response_free (resp); - } - g_list_free (listener->priv->response_queue); - - g_free (listener->priv); - - listener->priv = NULL; - } - - if (G_OBJECT_CLASS (parent_class)->dispose) - G_OBJECT_CLASS (parent_class)->dispose (object); -} - -static void -e_book_listener_class_init (EBookListenerClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - POA_GNOME_Evolution_Addressbook_BookListener__epv *epv; - - parent_class = g_type_class_ref (BONOBO_TYPE_OBJECT); - - e_book_listener_signals [RESPONSES_QUEUED] = - g_signal_new ("responses_queued", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (EBookListenerClass, responses_queued), - NULL, NULL, - e_book_marshal_NONE__NONE, - G_TYPE_NONE, 0); - - object_class->dispose = e_book_listener_dispose; - - epv = &klass->epv; - epv->notifyOpenBookProgress = impl_BookListener_report_open_book_progress; - epv->notifyBookOpened = impl_BookListener_respond_open_book; - epv->notifyCardCreated = impl_BookListener_respond_create_card; - epv->notifyCardsRemoved = impl_BookListener_respond_remove_cards; - epv->notifyCardModified = impl_BookListener_respond_modify_card; - epv->notifyAuthenticationResult = impl_BookListener_respond_authentication_result; - epv->notifySupportedFields = impl_BookListener_response_get_supported_fields; - epv->notifySupportedAuthMethods = impl_BookListener_response_get_supported_auth_methods; - epv->notifyCardRequested = impl_BookListener_respond_get_vcard; - epv->notifyCursorRequested = impl_BookListener_respond_get_cursor; - epv->notifyViewRequested = impl_BookListener_respond_get_view; - epv->notifyChangesRequested = impl_BookListener_respond_get_changes; - epv->notifyConnectionStatus = impl_BookListener_report_connection_status; - epv->notifyWritable = impl_BookListener_report_writable; -} - -BONOBO_TYPE_FUNC_FULL ( - EBookListener, - GNOME_Evolution_Addressbook_BookListener, - BONOBO_TYPE_OBJECT, - e_book_listener); diff --git a/addressbook/backend/ebook/e-book-listener.h b/addressbook/backend/ebook/e-book-listener.h deleted file mode 100644 index 1b02dd4bb6..0000000000 --- a/addressbook/backend/ebook/e-book-listener.h +++ /dev/null @@ -1,110 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * A client-side GObject which exposes the - * Evolution:BookListener interface. - * - * Author: - * Nat Friedman (nat@ximian.com) - * - * Copyright 2000, Ximian, Inc. - */ - -#ifndef __E_BOOK_LISTENER_H__ -#define __E_BOOK_LISTENER_H__ - -#include <bonobo/bonobo-object.h> -#include <ebook/addressbook.h> -#include <ebook/e-book-types.h> -#include <e-util/e-list.h> - -#define E_TYPE_BOOK_LISTENER (e_book_listener_get_type ()) -#define E_BOOK_LISTENER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), E_TYPE_BOOK_LISTENER, EBookListener)) -#define E_BOOK_LISTENER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), E_TYPE_BOOK_LISTENER, EBookListenerClass)) -#define E_IS_BOOK_LISTENER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), E_TYPE_BOOK_LISTENER)) -#define E_IS_BOOK_LISTENER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), E_TYPE_BOOK_LISTENER)) -#define E_BOOK_LISTENER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), E_TYPE_BOOK_LISTENER, EBookListenerClass)) - -G_BEGIN_DECLS - -typedef struct _EBookListener EBookListener; -typedef struct _EBookListenerClass EBookListenerClass; -typedef struct _EBookListenerPrivate EBookListenerPrivate; - -struct _EBookListener { - BonoboObject parent; - EBookListenerPrivate *priv; -}; - -struct _EBookListenerClass { - BonoboObjectClass parent; - - POA_GNOME_Evolution_Addressbook_BookListener__epv epv; - /* - * Signals - */ - void (*responses_queued) (void); -}; - -typedef enum { - /* Async responses */ - OpenBookResponse, - CreateCardResponse, - RemoveCardResponse, - ModifyCardResponse, - GetCardResponse, - GetCursorResponse, - GetBookViewResponse, - GetChangesResponse, - AuthenticationResponse, - GetSupportedFieldsResponse, - GetSupportedAuthMethodsResponse, - - /* Async events */ - LinkStatusEvent, - WritableStatusEvent, - OpenProgressEvent, -} EBookListenerOperation; - -typedef struct { - EBookListenerOperation op; - - /* For most Response notifications */ - EBookStatus status; - - /* For OpenBookResponse */ - GNOME_Evolution_Addressbook_Book book; - - /* For GetCursorResponse */ - GNOME_Evolution_Addressbook_CardCursor cursor; - - /* For GetBookViewReponse */ - GNOME_Evolution_Addressbook_BookView book_view; - - /* For GetSupportedFields/GetSupportedAuthMethods */ - EList *list; - - /* For OpenProgressEvent */ - char *msg; - short percent; - - /* For LinkStatusEvent */ - gboolean connected; - - /* For WritableStatusEvent */ - gboolean writable; - - /* For Card[Added|Removed|Modified]Event */ - char *id; - char *vcard; -} EBookListenerResponse; - - -EBookListener *e_book_listener_new (void); -int e_book_listener_check_pending (EBookListener *listener); -EBookListenerResponse *e_book_listener_pop_response (EBookListener *listener); -GType e_book_listener_get_type (void); -void e_book_listener_stop (EBookListener *listener); - -G_END_DECLS - -#endif /* ! __E_BOOK_LISTENER_H__ */ diff --git a/addressbook/backend/ebook/e-book-marshal.list b/addressbook/backend/ebook/e-book-marshal.list deleted file mode 100644 index 680ea039a3..0000000000 --- a/addressbook/backend/ebook/e-book-marshal.list +++ /dev/null @@ -1,5 +0,0 @@ -NONE:NONE -NONE:BOOL -NONE:POINTER -NONE:STRING -NONE:INT diff --git a/addressbook/backend/ebook/e-book-types.h b/addressbook/backend/ebook/e-book-types.h deleted file mode 100644 index b1900e77ed..0000000000 --- a/addressbook/backend/ebook/e-book-types.h +++ /dev/null @@ -1,53 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * A client-side GObject which exposes the - * Evolution:BookListener interface. - * - * Author: - * Nat Friedman (nat@ximian.com) - * - * Copyright 2000, Ximian, Inc. - */ - -#ifndef __E_BOOK_TYPES_H__ -#define __E_BOOK_TYPES_H__ - -#include <glib.h> - -G_BEGIN_DECLS - -typedef enum { - E_BOOK_STATUS_SUCCESS, - E_BOOK_STATUS_UNKNOWN, - E_BOOK_STATUS_REPOSITORY_OFFLINE, - E_BOOK_STATUS_PERMISSION_DENIED, - E_BOOK_STATUS_CARD_NOT_FOUND, - E_BOOK_STATUS_CARD_ID_ALREADY_EXISTS, - E_BOOK_STATUS_PROTOCOL_NOT_SUPPORTED, - E_BOOK_STATUS_CANCELLED, - E_BOOK_STATUS_AUTHENTICATION_FAILED, - E_BOOK_STATUS_AUTHENTICATION_REQUIRED, - E_BOOK_STATUS_TLS_NOT_AVAILABLE, - E_BOOK_STATUS_NO_SUCH_BOOK, - E_BOOK_STATUS_OTHER_ERROR -} EBookStatus; - -typedef enum { - E_BOOK_VIEW_STATUS_SUCCESS, - E_BOOK_VIEW_STATUS_TIME_LIMIT_EXCEEDED, - E_BOOK_VIEW_STATUS_SIZE_LIMIT_EXCEEDED, - E_BOOK_VIEW_STATUS_INVALID_QUERY, - E_BOOK_VIEW_STATUS_QUERY_REFUSED, - E_BOOK_VIEW_STATUS_OTHER_ERROR, - E_BOOK_VIEW_STATUS_UNKNOWN -} EBookViewStatus; - -typedef enum { - E_BOOK_SIMPLE_QUERY_STATUS_SUCCESS, - E_BOOK_SIMPLE_QUERY_STATUS_CANCELLED, - E_BOOK_SIMPLE_QUERY_STATUS_OTHER_ERROR -} EBookSimpleQueryStatus; - -G_END_DECLS - -#endif /* ! __E_BOOK_TYPES_H__ */ diff --git a/addressbook/backend/ebook/e-book-util.c b/addressbook/backend/ebook/e-book-util.c deleted file mode 100644 index cc00d045f4..0000000000 --- a/addressbook/backend/ebook/e-book-util.c +++ /dev/null @@ -1,808 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -/* - * e-book-util.c - * - * Copyright (C) 2001 Ximian, Inc. - * - * Developed by Jon Trowbridge <trow@ximian.com> - */ - -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA. - */ - -#include <config.h> -#include "e-book-util.h" - -#include <string.h> -#include <glib.h> -#include <glib-object.h> -#include <e-util/e-config-listener.h> -#include "e-card-compare.h" - -typedef struct _CommonBookInfo CommonBookInfo; -struct _CommonBookInfo { - EBookCommonCallback cb; - gpointer closure; -}; - -char * -e_book_expand_uri (const char *uri) -{ - if (!strncmp (uri, "file:", 5)) { - int length = strlen (uri); - int offset = 5; - - if (!strncmp (uri, "file://", 7)) - offset = 7; - - if (length < 3 || strcmp (uri + length - 3, ".db")) { - /* we assume it's a dir and glom addressbook.db onto the end. */ - - char *ret_val; - char *file_name; - - file_name = g_build_filename(uri + offset, "addressbook.db", NULL); - ret_val = g_strdup_printf("file://%s", file_name); - g_free(file_name); - return ret_val; - } - } - - return g_strdup (uri); -} - -static void -got_uri_book_cb (EBook *book, EBookStatus status, gpointer closure) -{ - CommonBookInfo *info = (CommonBookInfo *) closure; - - if (status == E_BOOK_STATUS_SUCCESS) { - info->cb (book, info->closure); - } else { - if (book) - g_object_unref (book); - info->cb (NULL, info->closure); - } - g_free (info); -} - -void -e_book_load_address_book_by_uri (EBook *book, const char *uri, EBookCallback open_response, gpointer closure) -{ - char *real_uri; - - g_return_if_fail (book != NULL); - g_return_if_fail (E_IS_BOOK (book)); - g_return_if_fail (open_response != NULL); - - real_uri = e_book_expand_uri (uri); - - e_book_load_uri (book, real_uri, open_response, closure); - - g_free (real_uri); -} - -void -e_book_use_address_book_by_uri (const char *uri, EBookCommonCallback cb, gpointer closure) -{ - EBook *book; - CommonBookInfo *info; - - g_return_if_fail (cb != NULL); - - info = g_new0 (CommonBookInfo, 1); - info->cb = cb; - info->closure = closure; - - book = e_book_new (); - e_book_load_address_book_by_uri (book, uri, got_uri_book_cb, info); -} - -EConfigListener * -e_book_get_config_database () -{ - static EConfigListener *config_db; - - if (config_db == NULL) - config_db = e_config_listener_new (); - - return config_db; -} - -static EBook *common_default_book = NULL; - -static void -got_default_book_cb (EBook *book, EBookStatus status, gpointer closure) -{ - CommonBookInfo *info = (CommonBookInfo *) closure; - - if (status == E_BOOK_STATUS_SUCCESS) { - - /* We try not to leak in a race condition where the - default book got loaded twice. */ - - if (common_default_book) { - g_object_unref (book); - book = common_default_book; - } - - info->cb (book, info->closure); - - if (common_default_book == NULL) { - common_default_book = book; - } - - } else { - if (book) - g_object_unref (book); - info->cb (NULL, info->closure); - - } - g_free (info); -} - -void -e_book_use_default_book (EBookCommonCallback cb, gpointer closure) -{ - EBook *book; - CommonBookInfo *info; - - g_return_if_fail (cb != NULL); - - if (common_default_book != NULL) { - cb (common_default_book, closure); - return; - } - - info = g_new0 (CommonBookInfo, 1); - info->cb = cb; - info->closure = closure; - - book = e_book_new (); - e_book_load_default_book (book, got_default_book_cb, info); -} - -static char *default_book_uri; - -static char* -get_local_book_uri (void) -{ - char *filename; - char *uri; - - filename = g_build_filename (g_get_home_dir(), - "evolution/local/Contacts/addressbook.db", - NULL); - uri = g_strdup_printf ("file://%s", filename); - - g_free (filename); - - return uri; -} - -static void -set_default_book_uri_local (void) -{ - g_free (default_book_uri); - - default_book_uri = get_local_book_uri (); -} - -static void -set_default_book_uri (char *val) -{ - if (default_book_uri) - g_free (default_book_uri); - - if (val) { - default_book_uri = e_book_expand_uri (val); - g_free (val); - } - else { - set_default_book_uri_local (); - } -} - -#define DEFAULT_CONTACTS_URI_PATH "/apps/evolution/shell/default_folders/contacts_uri" -static void -default_folder_listener (EConfigListener *cl, const char *key, gpointer data) -{ - char *val; - - if (strcmp (key, DEFAULT_CONTACTS_URI_PATH)) - return; - - val = e_config_listener_get_string (cl, DEFAULT_CONTACTS_URI_PATH); - - set_default_book_uri (val); -} - -static void -set_default_book_uri_from_config_db (void) -{ - char *val; - EConfigListener* config_db; - - config_db = e_book_get_config_database (); - val = e_config_listener_get_string_with_default (config_db, DEFAULT_CONTACTS_URI_PATH, NULL, NULL); - - g_signal_connect (config_db, - "key_changed", - G_CALLBACK (default_folder_listener), NULL); - - set_default_book_uri (val); -} - -typedef struct { - gpointer closure; - EBookCallback open_response; -} DefaultBookClosure; - -static void -e_book_default_book_open (EBook *book, EBookStatus status, gpointer closure) -{ - DefaultBookClosure *default_book_closure = closure; - gpointer user_closure = default_book_closure->closure; - EBookCallback user_response = default_book_closure->open_response; - - g_free (default_book_closure); - - /* If there's a transient error, report it to the caller, but - * if the old default folder has disappeared, fall back to the - * local contacts folder instead, except when the default - * folder is also the local folder. - */ - if (status == E_BOOK_STATUS_PROTOCOL_NOT_SUPPORTED || - status == E_BOOK_STATUS_NO_SUCH_BOOK) { - char *local_uri = get_local_book_uri(); - if (strcmp (local_uri, default_book_uri)) { - set_default_book_uri_local (); - e_book_load_default_book (book, user_response, user_closure); - } - else - user_response (book, status, user_closure); - g_free (local_uri); - } else { - user_response (book, status, user_closure); - } -} - -void -e_book_load_default_book (EBook *book, EBookCallback open_response, gpointer closure) -{ - const char *uri; - DefaultBookClosure *default_book_closure; - - g_return_if_fail (book != NULL); - g_return_if_fail (E_IS_BOOK (book)); - g_return_if_fail (open_response != NULL); - - uri = e_book_get_default_book_uri (); - - default_book_closure = g_new (DefaultBookClosure, 1); - - default_book_closure->closure = closure; - default_book_closure->open_response = open_response; - - e_book_load_uri (book, uri, - e_book_default_book_open, default_book_closure); - -} - -const char * -e_book_get_default_book_uri () -{ - if (!default_book_uri) - set_default_book_uri_from_config_db (); - - return default_book_uri; -} - -/* - * - * Simple Query Stuff - * - */ - -typedef struct _SimpleQueryInfo SimpleQueryInfo; -struct _SimpleQueryInfo { - guint tag; - EBook *book; - gchar *query; - EBookSimpleQueryCallback cb; - gpointer closure; - EBookView *view; - guint add_tag; - guint seq_complete_tag; - GList *cards; - gboolean cancelled; -}; - -static void -book_add_simple_query (EBook *book, SimpleQueryInfo *info) -{ - GList *pending = g_object_get_data (G_OBJECT(book), "sq_pending"); - pending = g_list_prepend (pending, info); - g_object_set_data (G_OBJECT (book), "sq_pending", pending); -} - -static SimpleQueryInfo * -book_lookup_simple_query (EBook *book, guint tag) -{ - GList *pending = g_object_get_data (G_OBJECT (book), "sq_pending"); - while (pending) { - SimpleQueryInfo *sq = pending->data; - if (sq->tag == tag) - return sq; - pending = g_list_next (pending); - } - return NULL; -} - -static void -book_remove_simple_query (EBook *book, SimpleQueryInfo *info) -{ - GList *pending = g_object_get_data (G_OBJECT (book), "sq_pending"); - GList *i; - - for (i=pending; i != NULL; i = g_list_next (i)) { - if (i->data == info) { - pending = g_list_remove_link (pending, i); - g_list_free_1 (i); - break; - } - } - g_object_set_data (G_OBJECT (book), "sq_pending", pending); -} - -static guint -book_issue_tag (EBook *book) -{ - gpointer ptr = g_object_get_data (G_OBJECT (book), "sq_tag"); - guint tag = GPOINTER_TO_UINT (ptr); - if (tag == 0) - tag = 1; - g_object_set_data (G_OBJECT (book), "sq_tag", GUINT_TO_POINTER (tag+1)); - return tag; -} - -static SimpleQueryInfo * -simple_query_new (EBook *book, const char *query, EBookSimpleQueryCallback cb, gpointer closure) -{ - SimpleQueryInfo *sq = g_new0 (SimpleQueryInfo, 1); - - sq->tag = book_issue_tag (book); - sq->book = book; - g_object_ref (book); - sq->query = g_strdup (query); - sq->cb = cb; - sq->closure = closure; - sq->cancelled = FALSE; - - /* Automatically add ourselves to the EBook's pending list. */ - book_add_simple_query (book, sq); - - return sq; -} - -static void -simple_query_disconnect (SimpleQueryInfo *sq) -{ - if (sq->add_tag) { - g_signal_handler_disconnect (sq->view, sq->add_tag); - sq->add_tag = 0; - } - - if (sq->seq_complete_tag) { - g_signal_handler_disconnect (sq->view, sq->seq_complete_tag); - sq->seq_complete_tag = 0; - } - - if (sq->view) { - g_object_unref (sq->view); - sq->view = NULL; - } -} - -static void -simple_query_free (SimpleQueryInfo *sq) -{ - simple_query_disconnect (sq); - - /* Remove ourselves from the EBook's pending list. */ - book_remove_simple_query (sq->book, sq); - - g_free (sq->query); - - if (sq->book) - g_object_unref (sq->book); - - g_list_foreach (sq->cards, (GFunc) g_object_unref, NULL); - g_list_free (sq->cards); - - g_free (sq); -} - -static void -simple_query_card_added_cb (EBookView *view, const GList *cards, gpointer closure) -{ - SimpleQueryInfo *sq = closure; - - if (sq->cancelled) - return; - - sq->cards = g_list_concat (sq->cards, g_list_copy ((GList *) cards)); - g_list_foreach ((GList *) cards, (GFunc) g_object_ref, NULL); -} - -static void -simple_query_sequence_complete_cb (EBookView *view, EBookViewStatus status, gpointer closure) -{ - SimpleQueryInfo *sq = closure; - - /* Disconnect signals, so that we don't pick up any changes to the book that occur - in our callback */ - simple_query_disconnect (sq); - if (! sq->cancelled) - sq->cb (sq->book, E_BOOK_SIMPLE_QUERY_STATUS_SUCCESS, sq->cards, sq->closure); - simple_query_free (sq); -} - -static void -simple_query_book_view_cb (EBook *book, EBookStatus status, EBookView *book_view, gpointer closure) -{ - SimpleQueryInfo *sq = closure; - - if (sq->cancelled) { - simple_query_free (sq); - return; - } - - if (status != E_BOOK_STATUS_SUCCESS) { - simple_query_disconnect (sq); - sq->cb (sq->book, E_BOOK_SIMPLE_QUERY_STATUS_OTHER_ERROR, NULL, sq->closure); - simple_query_free (sq); - return; - } - - sq->view = book_view; - g_object_ref (book_view); - - sq->add_tag = g_signal_connect (sq->view, "card_added", - G_CALLBACK (simple_query_card_added_cb), sq); - sq->seq_complete_tag = g_signal_connect (sq->view, "sequence_complete", - G_CALLBACK (simple_query_sequence_complete_cb), sq); -} - -guint -e_book_simple_query (EBook *book, const char *query, EBookSimpleQueryCallback cb, gpointer closure) -{ - SimpleQueryInfo *sq; - - g_return_val_if_fail (book && E_IS_BOOK (book), 0); - g_return_val_if_fail (query, 0); - g_return_val_if_fail (cb, 0); - - sq = simple_query_new (book, query, cb, closure); - e_book_get_book_view (book, (gchar *) query, simple_query_book_view_cb, sq); - - return sq->tag; -} - -void -e_book_simple_query_cancel (EBook *book, guint tag) -{ - SimpleQueryInfo *sq; - - g_return_if_fail (book && E_IS_BOOK (book)); - - sq = book_lookup_simple_query (book, tag); - - if (sq) { - sq->cancelled = TRUE; - sq->cb (sq->book, E_BOOK_SIMPLE_QUERY_STATUS_CANCELLED, NULL, sq->closure); - } else { - g_warning ("Simple query tag %d is unknown", tag); - } -} - -/* - * - * Specialized Queries - * - */ - -typedef struct _NameEmailQueryInfo NameEmailQueryInfo; -struct _NameEmailQueryInfo { - gchar *name; - gchar *email; - EBookSimpleQueryCallback cb; - gpointer closure; -}; - -static void -name_email_query_info_free (NameEmailQueryInfo *info) -{ - if (info) { - g_free (info->name); - g_free (info->email); - g_free (info); - } -} - -static void -name_and_email_cb (EBook *book, EBookSimpleQueryStatus status, const GList *cards, gpointer closure) -{ - NameEmailQueryInfo *info = closure; - GList *filtered_cards = NULL; - - while (cards) { - ECard *card = E_CARD (cards->data); - if ((info->name == NULL || e_card_compare_name_to_string (card, info->name) >= E_CARD_MATCH_VAGUE) - && (info->email == NULL || e_card_email_match_string (card, info->email))) { - filtered_cards = g_list_append (filtered_cards, card); - } - cards = g_list_next (cards); - } - - info->cb (book, status, filtered_cards, info->closure); - - g_list_free (filtered_cards); - - name_email_query_info_free (info); -} - -guint -e_book_name_and_email_query (EBook *book, - const gchar *name, - const gchar *email, - EBookSimpleQueryCallback cb, - gpointer closure) -{ - NameEmailQueryInfo *info; - gchar *email_query=NULL, *name_query=NULL, *query; - guint tag; - - g_return_val_if_fail (book && E_IS_BOOK (book), 0); - g_return_val_if_fail (cb != NULL, 0); - - if (name && !*name) - name = NULL; - if (email && !*email) - email = NULL; - - if (name == NULL && email == NULL) - return 0; - - /* Build our e-mail query. - * We only query against the username part of the address, to avoid not matching - * fred@foo.com and fred@mail.foo.com. While their may be namespace collisions - * in the usernames of everyone out there, it shouldn't be that bad. (Famous last words.) - */ - if (email) { - const gchar *t = email; - while (*t && *t != '@') - ++t; - if (*t == '@') { - email_query = g_strdup_printf ("(beginswith \"email\" \"%.*s@\")", t-email, email); - - } else { - email_query = g_strdup_printf ("(beginswith \"email\" \"%s\")", email); - } - } - - /* Build our name query. - * We only do name-query stuff if we don't have an e-mail address. Our basic assumption - * is that the username part of the email is good enough to keep the amount of stuff returned - * in the query relatively small. - */ - if (name && !email) { - gchar *name_cpy = g_strdup (name), *qjoined; - gchar **namev; - gint i, count=0; - - g_strstrip (name_cpy); - namev = g_strsplit (name_cpy, " ", 0); - for (i=0; namev[i]; ++i) { - if (*namev[i]) { - char *str = namev[i]; - - namev[i] = g_strdup_printf ("(contains \"file_as\" \"%s\")", namev[i]); - ++count; - - g_free (str); - } - } - - qjoined = g_strjoinv (" ", namev); - if (count > 1) { - name_query = g_strdup_printf ("(or %s)", qjoined); - } else { - name_query = qjoined; - qjoined = NULL; - } - - g_free (name_cpy); - g_strfreev (namev); - g_free (qjoined); - } - - /* Assemble our e-mail & name queries */ - if (email_query && name_query) { - query = g_strdup_printf ("(and %s %s)", email_query, name_query); - } else if (email_query) { - query = email_query; - email_query = NULL; - } else if (name_query) { - query = name_query; - name_query = NULL; - } else - return 0; - - info = g_new0 (NameEmailQueryInfo, 1); - info->name = g_strdup (name); - info->email = g_strdup (email); - info->cb = cb; - info->closure = closure; - - tag = e_book_simple_query (book, query, name_and_email_cb, info); - - g_free (email_query); - g_free (name_query); - g_free (query); - - return tag; -} - -/* - * Simple nickname query - */ - -typedef struct _NicknameQueryInfo NicknameQueryInfo; -struct _NicknameQueryInfo { - gchar *nickname; - EBookSimpleQueryCallback cb; - gpointer closure; -}; - -static void -nickname_cb (EBook *book, EBookSimpleQueryStatus status, const GList *cards, gpointer closure) -{ - NicknameQueryInfo *info = closure; - - if (info->cb) - info->cb (book, status, cards, info->closure); - - g_free (info->nickname); - g_free (info); -} - -guint -e_book_nickname_query (EBook *book, - const char *nickname, - EBookSimpleQueryCallback cb, - gpointer closure) -{ - NicknameQueryInfo *info; - gchar *query; - guint retval; - - g_return_val_if_fail (E_IS_BOOK (book), 0); - g_return_val_if_fail (nickname != NULL, 0); - - /* The empty-string case shouldn't generate a warning. */ - if (! *nickname) - return 0; - - info = g_new0 (NicknameQueryInfo, 1); - info->nickname = g_strdup (nickname); - info->cb = cb; - info->closure = closure; - - query = g_strdup_printf ("(is \"nickname\" \"%s\")", info->nickname); - - retval = e_book_simple_query (book, query, nickname_cb, info); - - g_free (query); - - return retval; -} - -/* - * Convenience routine to check for addresses in the local address book. - */ - -typedef struct _HaveAddressInfo HaveAddressInfo; -struct _HaveAddressInfo { - gchar *email; - EBookHaveAddressCallback cb; - gpointer closure; -}; - -static void -have_address_query_cb (EBook *book, EBookSimpleQueryStatus status, const GList *cards, gpointer closure) -{ - HaveAddressInfo *info = (HaveAddressInfo *) closure; - - info->cb (book, - info->email, - cards && (status == E_BOOK_SIMPLE_QUERY_STATUS_SUCCESS) ? E_CARD (cards->data) : NULL, - info->closure); - - g_free (info->email); - g_free (info); -} - -static void -have_address_book_open_cb (EBook *book, gpointer closure) -{ - HaveAddressInfo *info = (HaveAddressInfo *) closure; - - if (book) { - - e_book_name_and_email_query (book, NULL, info->email, have_address_query_cb, info); - - } else { - - info->cb (NULL, info->email, NULL, info->closure); - - g_free (info->email); - g_free (info); - - } -} - -void -e_book_query_address_default (const gchar *email, - EBookHaveAddressCallback cb, - gpointer closure) -{ - HaveAddressInfo *info; - - g_return_if_fail (email != NULL); - g_return_if_fail (cb != NULL); - - info = g_new0 (HaveAddressInfo, 1); - info->email = g_strdup (email); - info->cb = cb; - info->closure = closure; - - e_book_use_default_book (have_address_book_open_cb, info); -} - -/* bad place for this i know. */ -int -e_utf8_casefold_collate_len (const gchar *str1, const gchar *str2, int len) -{ - gchar *s1 = g_utf8_casefold(str1, len); - gchar *s2 = g_utf8_casefold(str2, len); - int rv; - - rv = g_utf8_collate (s1, s2); - - g_free (s1); - g_free (s2); - - return rv; -} - -int -e_utf8_casefold_collate (const gchar *str1, const gchar *str2) -{ - return e_utf8_casefold_collate_len (str1, str2, -1); -} - diff --git a/addressbook/backend/ebook/e-book-util.h b/addressbook/backend/ebook/e-book-util.h deleted file mode 100644 index 39eb135332..0000000000 --- a/addressbook/backend/ebook/e-book-util.h +++ /dev/null @@ -1,94 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -/* - * e-book-util.h - * - * Copyright (C) 2001 Ximian, Inc. - * - * Developed by Jon Trowbridge <trow@ximian.com> - */ - -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA. - */ - -#ifndef __E_BOOK_UTIL_H__ -#define __E_BOOK_UTIL_H__ - -#include "e-book.h" -#include "e-util/e-config-listener.h" -#include <bonobo/bonobo-object.h> -#include <bonobo/bonobo-moniker-util.h> - -G_BEGIN_DECLS - -/* Callbacks for asynchronous functions. */ -typedef void (*EBookCommonCallback) (EBook *book, gpointer closure); -typedef void (*EBookSimpleQueryCallback) (EBook *book, EBookSimpleQueryStatus status, const GList *cards, gpointer closure); -typedef void (*EBookHaveAddressCallback) (EBook *book, const gchar *addr, ECard *card, gpointer closure); - -/* expand file:///foo/foo/ to file:///foo/foo/addressbook.db */ -char *e_book_expand_uri (const char *uri); - -void e_book_load_address_book_by_uri (EBook *book, - const char *uri, - EBookCallback open_response, - gpointer closure); -void e_book_use_address_book_by_uri (const char *uri, - EBookCommonCallback cb, - gpointer closure); - -void e_book_use_default_book (EBookCommonCallback cb, - gpointer closure); -void e_book_load_default_book (EBook *book, - EBookCallback open_response, - gpointer closure); -const char *e_book_get_default_book_uri (void); - -/* config database interface. */ -EConfigListener *e_book_get_config_database (void); - -/* Simple Query Interface. */ -guint e_book_simple_query (EBook *book, - const char *query, - EBookSimpleQueryCallback cb, - gpointer closure); -void e_book_simple_query_cancel (EBook *book, - guint tag); - -/* Specialized Name/Email Queries */ -guint e_book_name_and_email_query (EBook *book, - const char *name, - const char *email, - EBookSimpleQueryCallback cb, - gpointer closure); -guint e_book_nickname_query (EBook *book, - const char *nickname, - EBookSimpleQueryCallback cb, - gpointer closure); - -/* Returns the ECard associated to email in the callback, - or NULL if no match is found in the default address book. */ -void e_book_query_address_default (const gchar *email, - EBookHaveAddressCallback cb, - gpointer closure); - -int e_utf8_casefold_collate_len (const gchar *str1, const gchar *str2, int len); -int e_utf8_casefold_collate (const gchar *str1, const gchar *str2); - -G_END_DECLS - -#endif /* __E_BOOK_UTIL_H__ */ - diff --git a/addressbook/backend/ebook/e-book-view-listener.c b/addressbook/backend/ebook/e-book-view-listener.c deleted file mode 100644 index 668c442a9a..0000000000 --- a/addressbook/backend/ebook/e-book-view-listener.c +++ /dev/null @@ -1,449 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * Exports the BookViewListener interface. Maintains a queue of messages - * which come in on the interface. - * - * Author: - * Nat Friedman (nat@ximian.com) - * - * Copyright 2000, Ximian, Inc. - */ - -#include <config.h> -#include <bonobo/bonobo-main.h> -#include "e-book-view-listener.h" -#include "e-book-view.h" -#include "e-card.h" -#include "e-book-marshal.h" - -static EBookViewStatus e_book_view_listener_convert_status (GNOME_Evolution_Addressbook_BookViewListener_CallStatus status); - -enum { - RESPONSES_QUEUED, - LAST_SIGNAL -}; - -static guint e_book_view_listener_signals [LAST_SIGNAL]; - -static BonoboObjectClass *parent_class; - -struct _EBookViewListenerPrivate { - GList *response_queue; - gint timeout_id; - - guint timeout_lock : 1; - guint stopped : 1; -}; - -static gboolean -e_book_view_listener_check_queue (EBookViewListener *listener) -{ - if (listener->priv->timeout_lock) - return TRUE; - - listener->priv->timeout_lock = TRUE; - - if (listener->priv->response_queue != NULL && !listener->priv->stopped) { - g_signal_emit (listener, e_book_view_listener_signals [RESPONSES_QUEUED], 0); - } - - if (listener->priv->response_queue == NULL || listener->priv->stopped) { - listener->priv->timeout_id = 0; - listener->priv->timeout_lock = FALSE; - bonobo_object_unref (BONOBO_OBJECT (listener)); - return FALSE; - } - - listener->priv->timeout_lock = FALSE; - return TRUE; -} - -static void -e_book_view_listener_queue_response (EBookViewListener *listener, - EBookViewListenerResponse *response) -{ - if (response == NULL) - return; - - if (listener->priv->stopped) { - /* Free response and return */ - g_list_foreach (response->ids, (GFunc)g_free, NULL); - g_list_free (response->ids); - g_list_foreach (response->cards, (GFunc) g_object_unref, NULL); - g_list_free (response->cards); - g_free (response->message); - g_free (response); - return; - } - - /* a slight optimization for huge ldap queries. if there's an - existing Add response on the end of the queue, and we're an - Add response, we just glom the two lists of cards - together */ - if (response->op == CardAddedEvent) { - GList *last = g_list_last (listener->priv->response_queue); - EBookViewListenerResponse *last_resp = NULL; - - if (last) last_resp = last->data; - - if (last_resp && last_resp->op == CardAddedEvent ) { - response->cards = g_list_concat (last_resp->cards, response->cards); - g_free (response); - /* there should already be a timeout since the - queue isn't empty, so we'll just return - here */ - return; - } - else - listener->priv->response_queue = g_list_append (last, response); - } - else - listener->priv->response_queue = g_list_append (listener->priv->response_queue, response); - - if (listener->priv->timeout_id == 0) { - - /* Here, 20 == an arbitrary small number */ - listener->priv->timeout_id = g_timeout_add (20, (GSourceFunc) e_book_view_listener_check_queue, listener); - - /* Hold a reference to the listener on behalf of the timeout */ - bonobo_object_ref (BONOBO_OBJECT (listener)); - } -} - -/* Add, Remove, Modify */ -static void -e_book_view_listener_queue_status_event (EBookViewListener *listener, - EBookViewListenerOperation op, - EBookViewStatus status) -{ - EBookViewListenerResponse *resp; - - if (listener->priv->stopped) - return; - - resp = g_new0 (EBookViewListenerResponse, 1); - - resp->op = op; - resp->status = status; - resp->ids = NULL; - resp->cards = NULL; - resp->message = NULL; - - e_book_view_listener_queue_response (listener, resp); -} - -/* Add, Remove, Modify */ -static void -e_book_view_listener_queue_idlist_event (EBookViewListener *listener, - EBookViewListenerOperation op, - const GNOME_Evolution_Addressbook_CardIdList *ids) -{ - EBookViewListenerResponse *resp; - int i; - - if (listener->priv->stopped) - return; - - resp = g_new0 (EBookViewListenerResponse, 1); - - resp->op = op; - resp->status = E_BOOK_VIEW_STATUS_SUCCESS; - resp->ids = NULL; - resp->cards = NULL; - resp->message = NULL; - - for (i = 0; i < ids->_length; i ++) { - resp->ids = g_list_prepend (resp->ids, g_strdup (ids->_buffer[i])); - } - - e_book_view_listener_queue_response (listener, resp); -} - -/* Add, Remove, Modify */ -static void -e_book_view_listener_queue_sequence_event (EBookViewListener *listener, - EBookViewListenerOperation op, - const GNOME_Evolution_Addressbook_VCardList *cards) -{ - EBookViewListenerResponse *resp; - int i; - - if (listener->priv->stopped) - return; - - resp = g_new0 (EBookViewListenerResponse, 1); - - resp->op = op; - resp->status = E_BOOK_VIEW_STATUS_SUCCESS; - resp->ids = NULL; - resp->cards = NULL; - resp->message = NULL; - - for ( i = 0; i < cards->_length; i++ ) { - resp->cards = g_list_append(resp->cards, e_card_new(cards->_buffer[i])); - } - - e_book_view_listener_queue_response (listener, resp); -} - -/* Status Message */ -static void -e_book_view_listener_queue_message_event (EBookViewListener *listener, - EBookViewListenerOperation op, - const char *message) -{ - EBookViewListenerResponse *resp; - - if (listener->priv->stopped) - return; - - resp = g_new0 (EBookViewListenerResponse, 1); - - resp->op = op; - resp->status = E_BOOK_VIEW_STATUS_SUCCESS; - resp->ids = NULL; - resp->cards = NULL; - resp->message = g_strdup(message); - - e_book_view_listener_queue_response (listener, resp); -} - -static void -impl_BookViewListener_notify_card_added (PortableServer_Servant servant, - const GNOME_Evolution_Addressbook_VCardList *cards, - CORBA_Environment *ev) -{ - EBookViewListener *listener = E_BOOK_VIEW_LISTENER (bonobo_object (servant)); - - e_book_view_listener_queue_sequence_event ( - listener, CardAddedEvent, cards); -} - -static void -impl_BookViewListener_notify_cards_removed (PortableServer_Servant servant, - const GNOME_Evolution_Addressbook_CardIdList *ids, - CORBA_Environment *ev) -{ - EBookViewListener *listener = E_BOOK_VIEW_LISTENER (bonobo_object (servant)); - - e_book_view_listener_queue_idlist_event (listener, CardsRemovedEvent, ids); -} - -static void -impl_BookViewListener_notify_card_changed (PortableServer_Servant servant, - const GNOME_Evolution_Addressbook_VCardList *cards, - CORBA_Environment *ev) -{ - EBookViewListener *listener = E_BOOK_VIEW_LISTENER (bonobo_object (servant)); - - e_book_view_listener_queue_sequence_event ( - listener, CardModifiedEvent, cards); -} - -static void -impl_BookViewListener_notify_sequence_complete (PortableServer_Servant servant, - const GNOME_Evolution_Addressbook_BookViewListener_CallStatus status, - CORBA_Environment *ev) -{ - EBookViewListener *listener = E_BOOK_VIEW_LISTENER (bonobo_object (servant)); - - e_book_view_listener_queue_status_event (listener, SequenceCompleteEvent, - e_book_view_listener_convert_status (status)); -} - -static void -impl_BookViewListener_notify_status_message (PortableServer_Servant servant, - const char *message, - CORBA_Environment *ev) -{ - EBookViewListener *listener = E_BOOK_VIEW_LISTENER (bonobo_object (servant)); - - e_book_view_listener_queue_message_event (listener, StatusMessageEvent, message); -} - -/** - * e_book_view_listener_check_pending: - * @listener: the #EBookViewListener - * - * Returns: the number of items on the response queue, - * or -1 if the @listener is isn't an #EBookViewListener. - */ -int -e_book_view_listener_check_pending (EBookViewListener *listener) -{ - g_return_val_if_fail (listener != NULL, -1); - g_return_val_if_fail (E_IS_BOOK_VIEW_LISTENER (listener), -1); - - return g_list_length (listener->priv->response_queue); -} - -/** - * e_book_view_listener_pop_response: - * @listener: the #EBookViewListener for which a request is to be popped - * - * Returns: an #EBookViewListenerResponse if there are responses on the - * queue to be returned; %NULL if there aren't, or if the @listener - * isn't an EBookViewListener. - */ -EBookViewListenerResponse * -e_book_view_listener_pop_response (EBookViewListener *listener) -{ - EBookViewListenerResponse *resp; - GList *popped; - - g_return_val_if_fail (listener != NULL, NULL); - g_return_val_if_fail (E_IS_BOOK_VIEW_LISTENER (listener), NULL); - - if (listener->priv->response_queue == NULL) - return NULL; - - resp = listener->priv->response_queue->data; - - popped = listener->priv->response_queue; - listener->priv->response_queue = - g_list_remove_link (listener->priv->response_queue, - listener->priv->response_queue); - g_list_free_1 (popped); - - return resp; -} - -static EBookViewStatus -e_book_view_listener_convert_status (const GNOME_Evolution_Addressbook_BookViewListener_CallStatus status) -{ - switch (status) { - case GNOME_Evolution_Addressbook_BookViewListener_Success: - return E_BOOK_VIEW_STATUS_SUCCESS; - case GNOME_Evolution_Addressbook_BookViewListener_SearchTimeLimitExceeded: - return E_BOOK_VIEW_STATUS_TIME_LIMIT_EXCEEDED; - case GNOME_Evolution_Addressbook_BookViewListener_SearchSizeLimitExceeded: - return E_BOOK_VIEW_STATUS_SIZE_LIMIT_EXCEEDED; - case GNOME_Evolution_Addressbook_BookViewListener_InvalidQuery: - return E_BOOK_VIEW_STATUS_INVALID_QUERY; - case GNOME_Evolution_Addressbook_BookViewListener_QueryRefused: - return E_BOOK_VIEW_STATUS_QUERY_REFUSED; - case GNOME_Evolution_Addressbook_BookViewListener_OtherError: - return E_BOOK_VIEW_STATUS_OTHER_ERROR; - default: - g_warning ("e_book_view_listener_convert_status: Unknown status " - "from card server: %d\n", (int) status); - return E_BOOK_VIEW_STATUS_UNKNOWN; - - } -} - -static void -e_book_view_listener_construct (EBookViewListener *listener) -{ - /* nothing needed here */ -} - -/** - * e_book_view_listener_new: - * @book: the #EBookView for which the listener is to be bound - * - * Creates and returns a new #EBookViewListener for the book. - * - * Returns: a new #EBookViewListener - */ -EBookViewListener * -e_book_view_listener_new () -{ - EBookViewListener *listener; - - listener = g_object_new (E_TYPE_BOOK_VIEW_LISTENER, NULL); - - e_book_view_listener_construct (listener); - - return listener; -} - -static void -e_book_view_listener_init (EBookViewListener *listener) -{ - listener->priv = g_new0 (EBookViewListenerPrivate, 1); - listener->priv->response_queue = NULL; - listener->priv->timeout_id = 0; - listener->priv->timeout_lock = FALSE; - listener->priv->stopped = FALSE; -} - -void -e_book_view_listener_stop (EBookViewListener *listener) -{ - g_return_if_fail (E_IS_BOOK_VIEW_LISTENER (listener)); - listener->priv->stopped = TRUE; -} - -static void -e_book_view_listener_dispose (GObject *object) -{ - EBookViewListener *listener = E_BOOK_VIEW_LISTENER (object); - - if (listener->priv) { - GList *l; - /* Remove our response queue handler: In theory, this - can never happen since we always hold a reference - to the listener while the timeout is running. */ - if (listener->priv->timeout_id) { - g_source_remove (listener->priv->timeout_id); - } - - /* Clear out the queue */ - for (l = listener->priv->response_queue; l != NULL; l = l->next) { - EBookViewListenerResponse *resp = l->data; - - g_list_foreach (resp->ids, (GFunc)g_free, NULL); - g_list_free (resp->ids); - - g_list_foreach(resp->cards, (GFunc) g_object_unref, NULL); - g_list_free(resp->cards); - resp->cards = NULL; - - g_free (resp->message); - resp->message = NULL; - - g_free (resp); - } - g_list_free (listener->priv->response_queue); - - g_free (listener->priv); - listener->priv = NULL; - } - - if (G_OBJECT_CLASS (parent_class)->dispose) - G_OBJECT_CLASS (parent_class)->dispose (object); -} - -static void -e_book_view_listener_class_init (EBookViewListenerClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - POA_GNOME_Evolution_Addressbook_BookViewListener__epv *epv; - - parent_class = g_type_class_ref (BONOBO_TYPE_OBJECT); - - e_book_view_listener_signals [RESPONSES_QUEUED] = - g_signal_new ("responses_queued", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (EBookViewListenerClass, responses_queued), - NULL, NULL, - e_book_marshal_NONE__NONE, - G_TYPE_NONE, 0); - - object_class->dispose = e_book_view_listener_dispose; - - epv = &klass->epv; - epv->notifyCardChanged = impl_BookViewListener_notify_card_changed; - epv->notifyCardsRemoved = impl_BookViewListener_notify_cards_removed; - epv->notifyCardAdded = impl_BookViewListener_notify_card_added; - epv->notifySequenceComplete = impl_BookViewListener_notify_sequence_complete; - epv->notifyStatusMessage = impl_BookViewListener_notify_status_message; -} - -BONOBO_TYPE_FUNC_FULL ( - EBookViewListener, - GNOME_Evolution_Addressbook_BookViewListener, - BONOBO_TYPE_OBJECT, - e_book_view_listener); diff --git a/addressbook/backend/ebook/e-book-view-listener.h b/addressbook/backend/ebook/e-book-view-listener.h deleted file mode 100644 index fd1c1395a7..0000000000 --- a/addressbook/backend/ebook/e-book-view-listener.h +++ /dev/null @@ -1,82 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * A client-side GObject which exposes the - * Evolution:BookViewListener interface. - * - * Author: - * Nat Friedman (nat@ximian.com) - * - * Copyright 2000, Ximian, Inc. - */ - -#ifndef __E_BOOK_VIEW_LISTENER_H__ -#define __E_BOOK_VIEW_LISTENER_H__ - -#include <bonobo/bonobo-object.h> -#include <ebook/e-book-types.h> -#include <ebook/addressbook.h> - -#define E_TYPE_BOOK_VIEW_LISTENER (e_book_view_listener_get_type ()) -#define E_BOOK_VIEW_LISTENER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), E_TYPE_BOOK_VIEW_LISTENER, EBookViewListener)) -#define E_BOOK_VIEW_LISTENER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), E_TYPE_BOOK_VIEW_LISTENER, EBookViewListenerClass)) -#define E_IS_BOOK_VIEW_LISTENER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), E_TYPE_BOOK_VIEW_LISTENER)) -#define E_IS_BOOK_VIEW_LISTENER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), E_TYPE_BOOK_VIEW_LISTENER)) -#define E_BOOK_VIEW_LISTENER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), E_TYPE_BOOK_VIEW_LISTENER, EBookViewListenerClass)) - -G_BEGIN_DECLS - -typedef struct _EBookViewListener EBookViewListener; -typedef struct _EBookViewListenerClass EBookViewListenerClass; -typedef struct _EBookViewListenerPrivate EBookViewListenerPrivate; - -struct _EBookViewListener { - BonoboObject parent; - EBookViewListenerPrivate *priv; -}; - -struct _EBookViewListenerClass { - BonoboObjectClass parent; - - POA_GNOME_Evolution_Addressbook_BookViewListener__epv epv; - - /* - * Signals - */ - void (*responses_queued) (void); -}; - -typedef enum { - /* Async events */ - CardAddedEvent, - CardsRemovedEvent, - CardModifiedEvent, - SequenceCompleteEvent, - StatusMessageEvent, -} EBookViewListenerOperation; - -typedef struct { - EBookViewListenerOperation op; - - /* For SequenceComplete */ - EBookViewStatus status; - - /* For CardsRemovedEvent */ - GList *ids; - - /* For Card[Added|Modified]Event */ - GList *cards; /* Of type ECard. */ - - /* For StatusMessageEvent */ - char *message; - -} EBookViewListenerResponse; - -EBookViewListener *e_book_view_listener_new (void); -int e_book_view_listener_check_pending (EBookViewListener *listener); -EBookViewListenerResponse *e_book_view_listener_pop_response (EBookViewListener *listener); -GType e_book_view_listener_get_type (void); -void e_book_view_listener_stop (EBookViewListener *listener); - -G_END_DECLS - -#endif /* ! __E_BOOK_VIEW_LISTENER_H__ */ diff --git a/addressbook/backend/ebook/e-book-view.c b/addressbook/backend/ebook/e-book-view.c deleted file mode 100644 index e1f4b1623c..0000000000 --- a/addressbook/backend/ebook/e-book-view.c +++ /dev/null @@ -1,352 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * The Evolution addressbook client object. - * - * Author: - * Nat Friedman (nat@ximian.com) - * - * Copyright 1999, 2000, Ximian, Inc. - */ - -#include <config.h> - -#include "addressbook.h" -#include "e-card-cursor.h" -#include "e-book-view-listener.h" -#include "e-book-view.h" -#include "e-book.h" -#include "e-book-marshal.h" - -static GObjectClass *parent_class; - -struct _EBookViewPrivate { - GNOME_Evolution_Addressbook_BookView corba_book_view; - - EBook *book; - - EBookViewListener *listener; - - int responses_queued_id; -}; - -enum { - CARD_CHANGED, - CARD_REMOVED, - CARD_ADDED, - SEQUENCE_COMPLETE, - STATUS_MESSAGE, - LAST_SIGNAL -}; - -static guint e_book_view_signals [LAST_SIGNAL]; - -static void -add_book_iterator (gpointer data, gpointer closure) -{ - ECard *card = E_CARD (data); - EBook *book = E_BOOK (closure); - - e_card_set_book (card, book); -} - -static void -e_book_view_do_added_event (EBookView *book_view, - EBookViewListenerResponse *resp) -{ - if (book_view->priv->book) - g_list_foreach (resp->cards, add_book_iterator, book_view->priv->book); - - g_signal_emit (book_view, e_book_view_signals [CARD_ADDED], 0, - resp->cards); - - g_list_foreach (resp->cards, (GFunc) g_object_unref, NULL); - g_list_free (resp->cards); -} - -static void -e_book_view_do_modified_event (EBookView *book_view, - EBookViewListenerResponse *resp) -{ - if (book_view->priv->book) - g_list_foreach (resp->cards, add_book_iterator, book_view->priv->book); - - g_signal_emit (book_view, e_book_view_signals [CARD_CHANGED], 0, - resp->cards); - - g_list_foreach (resp->cards, (GFunc) g_object_unref, NULL); - g_list_free (resp->cards); -} - -static void -e_book_view_do_removed_event (EBookView *book_view, - EBookViewListenerResponse *resp) -{ - g_signal_emit (book_view, e_book_view_signals [CARD_REMOVED], 0, - resp->ids); - - g_list_foreach (resp->ids, (GFunc) g_free, NULL); - g_list_free (resp->ids); -} - -static void -e_book_view_do_complete_event (EBookView *book_view, - EBookViewListenerResponse *resp) -{ - g_signal_emit (book_view, e_book_view_signals [SEQUENCE_COMPLETE], 0, - resp->status); -} - -static void -e_book_view_do_status_message_event (EBookView *book_view, - EBookViewListenerResponse *resp) -{ - g_signal_emit (book_view, e_book_view_signals [STATUS_MESSAGE], 0, - resp->message); - g_free(resp->message); -} - - -/* - * Reading notices out of the EBookViewListener's queue. - */ -static void -e_book_view_check_listener_queue (EBookViewListener *listener, EBookView *book_view) -{ - EBookViewListenerResponse *resp; - - resp = e_book_view_listener_pop_response (listener); - - if (resp == NULL) - return; - - switch (resp->op) { - case CardAddedEvent: - e_book_view_do_added_event (book_view, resp); - break; - case CardModifiedEvent: - e_book_view_do_modified_event (book_view, resp); - break; - case CardsRemovedEvent: - e_book_view_do_removed_event (book_view, resp); - break; - case SequenceCompleteEvent: - e_book_view_do_complete_event (book_view, resp); - break; - case StatusMessageEvent: - e_book_view_do_status_message_event (book_view, resp); - break; - default: - g_error ("EBookView: Unknown operation %d in listener queue!\n", - resp->op); - break; - } - - g_free (resp); -} - -static gboolean -e_book_view_construct (EBookView *book_view, GNOME_Evolution_Addressbook_BookView corba_book_view, EBookViewListener *listener) -{ - CORBA_Environment ev; - g_return_val_if_fail (book_view != NULL, FALSE); - g_return_val_if_fail (E_IS_BOOK_VIEW (book_view), FALSE); - - /* - * Copy in the corba_book_view. - */ - CORBA_exception_init (&ev); - - book_view->priv->corba_book_view = bonobo_object_dup_ref(corba_book_view, &ev); - - if (ev._major != CORBA_NO_EXCEPTION) { - g_warning ("e_book_view_construct: Exception duplicating corba_book_view.\n"); - CORBA_exception_free (&ev); - book_view->priv->corba_book_view = NULL; - return FALSE; - } - - CORBA_exception_free (&ev); - - /* - * Create our local BookListener interface. - */ - book_view->priv->listener = listener; - book_view->priv->responses_queued_id = g_signal_connect (book_view->priv->listener, "responses_queued", - G_CALLBACK (e_book_view_check_listener_queue), book_view); - - bonobo_object_ref(BONOBO_OBJECT(book_view->priv->listener)); - - return TRUE; -} - -/** - * e_book_view_new: - */ -EBookView * -e_book_view_new (GNOME_Evolution_Addressbook_BookView corba_book_view, EBookViewListener *listener) -{ - EBookView *book_view; - - book_view = g_object_new (E_TYPE_BOOK_VIEW, NULL); - - if (! e_book_view_construct (book_view, corba_book_view, listener)) { - g_object_unref (book_view); - return NULL; - } - - return book_view; -} - -void -e_book_view_set_book (EBookView *book_view, EBook *book) -{ - g_return_if_fail (book_view && E_IS_BOOK_VIEW (book_view)); - g_return_if_fail (book && E_IS_BOOK (book)); - g_return_if_fail (book_view->priv->book == NULL); - - book_view->priv->book = book; - g_object_ref (book); -} - -void -e_book_view_stop (EBookView *book_view) -{ - g_return_if_fail (book_view && E_IS_BOOK_VIEW (book_view)); - if (book_view->priv->listener) - e_book_view_listener_stop (book_view->priv->listener); -} - -static void -e_book_view_init (EBookView *book_view) -{ - book_view->priv = g_new0 (EBookViewPrivate, 1); - book_view->priv->book = NULL; - book_view->priv->corba_book_view = CORBA_OBJECT_NIL; - book_view->priv->listener = NULL; - book_view->priv->responses_queued_id = 0; -} - -static void -e_book_view_dispose (GObject *object) -{ - EBookView *book_view = E_BOOK_VIEW (object); - CORBA_Environment ev; - - if (book_view->priv) { - if (book_view->priv->book) { - g_object_unref (book_view->priv->book); - } - - if (book_view->priv->corba_book_view) { - CORBA_exception_init (&ev); - - bonobo_object_release_unref (book_view->priv->corba_book_view, &ev); - - if (ev._major != CORBA_NO_EXCEPTION) { - g_warning ("EBookView: Exception while releasing BookView\n"); - } - - CORBA_exception_free (&ev); - } - - if (book_view->priv->listener) { - if (book_view->priv->responses_queued_id) - g_signal_handler_disconnect(book_view->priv->listener, - book_view->priv->responses_queued_id); - e_book_view_listener_stop (book_view->priv->listener); - bonobo_object_unref (BONOBO_OBJECT(book_view->priv->listener)); - } - - g_free (book_view->priv); - book_view->priv = NULL; - } - - G_OBJECT_CLASS(parent_class)->dispose (object); -} - -static void -e_book_view_class_init (EBookViewClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - parent_class = g_type_class_ref (G_TYPE_OBJECT); - - e_book_view_signals [CARD_CHANGED] = - g_signal_new ("card_changed", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (EBookViewClass, card_changed), - NULL, NULL, - e_book_marshal_NONE__POINTER, - G_TYPE_NONE, 1, - G_TYPE_POINTER); - - e_book_view_signals [CARD_ADDED] = - g_signal_new ("card_added", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (EBookViewClass, card_added), - NULL, NULL, - e_book_marshal_NONE__POINTER, - G_TYPE_NONE, 1, - G_TYPE_POINTER); - - e_book_view_signals [CARD_REMOVED] = - g_signal_new ("card_removed", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (EBookViewClass, card_removed), - NULL, NULL, - e_book_marshal_NONE__POINTER, - G_TYPE_NONE, 1, - G_TYPE_POINTER); - - e_book_view_signals [SEQUENCE_COMPLETE] = - g_signal_new ("sequence_complete", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (EBookViewClass, sequence_complete), - NULL, NULL, - e_book_marshal_NONE__INT, - G_TYPE_NONE, 1, - G_TYPE_INT); - - e_book_view_signals [STATUS_MESSAGE] = - g_signal_new ("status_message", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (EBookViewClass, status_message), - NULL, NULL, - e_book_marshal_NONE__STRING, - G_TYPE_NONE, 1, - G_TYPE_STRING); - - object_class->dispose = e_book_view_dispose; -} - -/** - * e_book_view_get_type: - */ -GType -e_book_view_get_type (void) -{ - static GType type = 0; - - if (! type) { - GTypeInfo info = { - sizeof (EBookViewClass), - NULL, /* base_class_init */ - NULL, /* base_class_finalize */ - (GClassInitFunc) e_book_view_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (EBookView), - 0, /* n_preallocs */ - (GInstanceInitFunc) e_book_view_init - }; - - type = g_type_register_static (G_TYPE_OBJECT, "EBookView", &info, 0); - } - - return type; -} diff --git a/addressbook/backend/ebook/e-book-view.h b/addressbook/backend/ebook/e-book-view.h deleted file mode 100644 index bd7a97d1d5..0000000000 --- a/addressbook/backend/ebook/e-book-view.h +++ /dev/null @@ -1,63 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * The Evolution addressbook client object. - * - * Author: - * Nat Friedman (nat@ximian.com) - * - * Copyright 1999, 2000, Ximian, Inc. - */ - -#ifndef __E_BOOK_VIEW_H__ -#define __E_BOOK_VIEW_H__ - -#include <glib.h> -#include <glib-object.h> -#include <ebook/e-card.h> -#include <ebook/e-book-view-listener.h> - -#define E_TYPE_BOOK_VIEW (e_book_view_get_type ()) -#define E_BOOK_VIEW(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), E_TYPE_BOOK_VIEW, EBookView)) -#define E_BOOK_VIEW_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), E_TYPE_BOOK_VIEW, EBookViewClass)) -#define E_IS_BOOK_VIEW(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), E_TYPE_BOOK_VIEW)) -#define E_IS_BOOK_VIEW_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), E_TYPE_BOOK_VIEW)) -#define E_BOOK_VIEW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), E_TYPE_BOOK_VIEW, EBookViewClass)) - -G_BEGIN_DECLS - -typedef struct _EBookView EBookView; -typedef struct _EBookViewClass EBookViewClass; -typedef struct _EBookViewPrivate EBookViewPrivate; - -struct _EBook; /* Forward reference */ - -struct _EBookView { - GObject parent; - EBookViewPrivate *priv; -}; - -struct _EBookViewClass { - GObjectClass parent; - - /* - * Signals. - */ - void (* card_changed) (EBookView *book_view, const GList *cards); - void (* card_removed) (EBookView *book_view, const GList *ids); - void (* card_added) (EBookView *book_view, const GList *cards); - void (* sequence_complete) (EBookView *book_view, EBookViewStatus status); - void (* status_message) (EBookView *book_view, const char *message); -}; - -/* Creating a new addressbook. */ -EBookView *e_book_view_new (GNOME_Evolution_Addressbook_BookView corba_book_view, EBookViewListener *listener); - -GType e_book_view_get_type (void); - -void e_book_view_set_book (EBookView *book_view, struct _EBook *book); - -void e_book_view_stop (EBookView *book_view); - -G_END_DECLS - -#endif /* ! __E_BOOK_VIEW_H__ */ diff --git a/addressbook/backend/ebook/e-book.c b/addressbook/backend/ebook/e-book.c deleted file mode 100644 index 9e1250bd0e..0000000000 --- a/addressbook/backend/ebook/e-book.c +++ /dev/null @@ -1,1700 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * The Evolution addressbook client object. - * - * Author: - * Nat Friedman (nat@ximian.com) - * - * Copyright 1999, 2000, Ximian, Inc. - */ - -#include <config.h> -#include <glib.h> -#include <glib-object.h> -#include <string.h> -#include <bonobo-activation/bonobo-activation.h> - -#include "addressbook.h" -#include "e-card-cursor.h" -#include "e-book-listener.h" -#include "e-book.h" -#include "e-book-marshal.h" -#include "e-util/e-component-listener.h" - -static GObjectClass *parent_class; - -#define CARDSERVER_OAF_ID "OAFIID:GNOME_Evolution_Wombat_ServerFactory" - -typedef enum { - URINotLoaded, - URILoading, - URILoaded -} EBookLoadState; - -struct _EBookPrivate { - GList *book_factories; - GList *iter; - - /* cached capabilites */ - char *cap; - gboolean cap_queried; - - EBookListener *listener; - EComponentListener *comp_listener; - - GNOME_Evolution_Addressbook_Book corba_book; - - EBookLoadState load_state; - - /* - * The operation queue. New operations are appended to the - * end of the queue. When responses come back from the PAS, - * the op structures are popped off the front of the queue. - */ - GList *pending_ops; - - guint op_tag; - - gchar *uri; - - gulong listener_signal; - gulong died_signal; -}; - -enum { - OPEN_PROGRESS, - WRITABLE_STATUS, - LINK_STATUS, - BACKEND_DIED, - LAST_SIGNAL -}; - -static guint e_book_signals [LAST_SIGNAL]; - -typedef struct { - guint tag; - gboolean active; - gpointer cb; - gpointer closure; - EBookViewListener *listener; -} EBookOp; - -/* - * Local response queue management. - */ - -static void -e_book_op_free (EBookOp *op) -{ - if (op->listener) { - bonobo_object_unref (BONOBO_OBJECT (op->listener)); - op->listener = NULL; - } - g_free (op); -} - -static guint -e_book_queue_op (EBook *book, - gpointer cb, - gpointer closure, - EBookViewListener *listener) -{ - EBookOp *op; - - op = g_new0 (EBookOp, 1); - op->tag = book->priv->op_tag++; - op->active = TRUE; - op->cb = cb; - op->closure = closure; - op->listener = listener; - - if (op->listener) - bonobo_object_ref (BONOBO_OBJECT (op->listener)); - - book->priv->pending_ops = - g_list_append (book->priv->pending_ops, op); - - return op->tag; -} - -/* - * Local response queue management. - */ -static void -e_book_unqueue_op (EBook *book) -{ - EBookOp *op; - GList *removed; - - removed = g_list_last (book->priv->pending_ops); - - if (removed) { - book->priv->pending_ops = g_list_remove_link (book->priv->pending_ops, - removed); - op = removed->data; - e_book_op_free (op); - g_list_free_1 (removed); - book->priv->op_tag--; - } -} - -static EBookOp * -e_book_pop_op (EBook *book) -{ - GList *popped; - EBookOp *op; - - if (book->priv->pending_ops == NULL) - return NULL; - - op = book->priv->pending_ops->data; - - popped = book->priv->pending_ops; - book->priv->pending_ops = - g_list_remove_link (book->priv->pending_ops, - book->priv->pending_ops); - - g_list_free_1 (popped); - - return op; -} - -static gboolean -e_book_cancel_op (EBook *book, guint tag) -{ - GList *iter; - gboolean cancelled = FALSE; - - for (iter = book->priv->pending_ops; iter != NULL && !cancelled; iter = g_list_next (iter)) { - EBookOp *op = iter->data; - if (op->tag == tag) { - op->active = FALSE; - cancelled = TRUE; - } - } - - return cancelled; -} - -static void -e_book_do_response_create_card (EBook *book, - EBookListenerResponse *resp) -{ - EBookOp *op; - - op = e_book_pop_op (book); - - if (op == NULL) { - g_warning ("e_book_do_response_create_card: Cannot find operation " - "in local op queue!\n"); - return; - } - - if (op->cb) - ((EBookIdCallback) op->cb) (book, resp->status, resp->id, op->closure); - g_free (resp->id); - e_book_op_free (op); -} - -static void -e_book_do_response_generic (EBook *book, - EBookListenerResponse *resp) -{ - EBookOp *op; - - op = e_book_pop_op (book); - - if (op == NULL) { - g_warning ("e_book_do_response_generic: Cannot find operation " - "in local op queue!\n"); - } - - if (op->cb) - ((EBookCallback) op->cb) (book, resp->status, op->closure); - - e_book_op_free (op); -} - -static void -e_book_do_response_get_vcard (EBook *book, - EBookListenerResponse *resp) -{ - EBookOp *op; - ECard *card; - - op = e_book_pop_op (book); - - if (op == NULL) { - g_warning ("e_book_do_response_get_vcard: Cannot find operation " - "in local op queue!\n"); - return; - } - if (resp->vcard != NULL) { - - card = e_card_new(resp->vcard); - - if (card != NULL) { - e_card_set_book (card, book); - if (op->cb) { - if (op->active) - ((EBookCardCallback) op->cb) (book, resp->status, card, op->closure); - else - ((EBookCardCallback) op->cb) (book, E_BOOK_STATUS_CANCELLED, NULL, op->closure); - } - - g_object_unref(card); - } else { - ((EBookCursorCallback) op->cb) (book, resp->status, NULL, op->closure); - } - } else { - ((EBookCardCallback) op->cb) (book, resp->status, NULL, op->closure); - } - - g_free (resp->vcard); - e_book_op_free (op); -} - -static void -e_book_do_response_get_cursor (EBook *book, - EBookListenerResponse *resp) -{ - CORBA_Environment ev; - EBookOp *op; - ECardCursor *cursor; - - op = e_book_pop_op (book); - - if (op == NULL) { - g_warning ("e_book_do_response_get_cursor: Cannot find operation " - "in local op queue!\n"); - return; - } - - cursor = e_card_cursor_new(resp->cursor); - - if (cursor != NULL) { - if (op->cb) { - if (op->active) - ((EBookCursorCallback) op->cb) (book, resp->status, cursor, op->closure); - else - ((EBookCursorCallback) op->cb) (book, E_BOOK_STATUS_CANCELLED, NULL, op->closure); - } - - /* - * Release the remote GNOME_Evolution_Addressbook_Book in the PAS. - */ - CORBA_exception_init (&ev); - - bonobo_object_release_unref (resp->cursor, &ev); - - if (ev._major != CORBA_NO_EXCEPTION) { - g_warning ("e_book_do_response_get_cursor: Exception releasing " - "remote GNOME_Evolution_Addressbook_CardCursor interface!\n"); - } - - CORBA_exception_free (&ev); - - g_object_unref(cursor); - } else { - ((EBookCursorCallback) op->cb) (book, E_BOOK_STATUS_CANCELLED, NULL, op->closure); - } - - e_book_op_free (op); -} - -static void -e_book_do_response_get_view (EBook *book, - EBookListenerResponse *resp) -{ - CORBA_Environment ev; - EBookOp *op; - EBookView *book_view; - - op = e_book_pop_op (book); - - if (op == NULL) { - g_warning ("e_book_do_response_get_view: Cannot find operation " - "in local op queue!\n"); - return; - } - - book_view = e_book_view_new (resp->book_view, op->listener); - - if (book_view != NULL) { - e_book_view_set_book (book_view, book); - - /* Only execute the callback if the operation is still flagged as active (i.e. hasn't - been cancelled. This is mildly wasteful since we unnecessaryily create the - book_view, etc... but I'm leery of tinkering with the CORBA magic. */ - if (op->cb) { - if (op->active) - ((EBookBookViewCallback) op->cb) (book, resp->status, book_view, op->closure); - else - ((EBookBookViewCallback) op->cb) (book, E_BOOK_STATUS_CANCELLED, NULL, op->closure); - } - - /* - * Release the remote GNOME_Evolution_Addressbook_Book in the PAS. - */ - CORBA_exception_init (&ev); - - bonobo_object_release_unref (resp->book_view, &ev); - - if (ev._major != CORBA_NO_EXCEPTION) { - g_warning ("e_book_do_response_get_view: Exception releasing " - "remote GNOME_Evolution_Addressbook_BookView interface!\n"); - } - - CORBA_exception_free (&ev); - - g_object_unref(book_view); - } else { - e_book_view_listener_stop (op->listener); - ((EBookBookViewCallback) op->cb) (book, E_BOOK_STATUS_CANCELLED, NULL, op->closure); - } - - e_book_op_free (op); -} - -static void -e_book_do_response_get_changes (EBook *book, - EBookListenerResponse *resp) -{ - CORBA_Environment ev; - EBookOp *op; - EBookView *book_view; - - op = e_book_pop_op (book); - - if (op == NULL) { - g_warning ("e_book_do_response_get_changes: Cannot find operation " - "in local op queue!\n"); - return; - } - - book_view = e_book_view_new (resp->book_view, op->listener); - - if (book_view != NULL) { - e_book_view_set_book (book_view, book); - - if (op->cb) { - if (op->active) - ((EBookBookViewCallback) op->cb) (book, resp->status, book_view, op->closure); - else - ((EBookBookViewCallback) op->cb) (book, E_BOOK_STATUS_CANCELLED, NULL, op->closure); - } - - /* - * Release the remote GNOME_Evolution_Addressbook_BookView in the PAS. - */ - CORBA_exception_init (&ev); - - bonobo_object_release_unref (resp->book_view, &ev); - - if (ev._major != CORBA_NO_EXCEPTION) { - g_warning ("e_book_do_response_get_changes: Exception releasing " - "remote GNOME_Evolution_Addressbook_BookView interface!\n"); - } - - CORBA_exception_free (&ev); - - g_object_unref(book_view); - } else { - e_book_view_listener_stop (op->listener); - ((EBookBookViewCallback) op->cb) (book, E_BOOK_STATUS_CANCELLED, NULL, op->closure); - } - - e_book_op_free (op); -} - -static void -backend_died_cb (EComponentListener *cl, gpointer user_data) -{ - EBook *book = user_data; - - book->priv->load_state = URINotLoaded; - g_signal_emit (book, e_book_signals [BACKEND_DIED], 0); -} - -static void -e_book_do_response_open (EBook *book, - EBookListenerResponse *resp) -{ - EBookOp *op; - - if (resp->status == E_BOOK_STATUS_SUCCESS) { - book->priv->corba_book = resp->book; - book->priv->load_state = URILoaded; - - book->priv->comp_listener = e_component_listener_new (book->priv->corba_book); - book->priv->died_signal = g_signal_connect (book->priv->comp_listener, "component_died", - G_CALLBACK (backend_died_cb), book); - } - - op = e_book_pop_op (book); - - if (op == NULL) { - g_warning ("e_book_do_response_open: Cannot find operation " - "in local op queue!\n"); - return; - } - - if (op->cb) - ((EBookCallback) op->cb) (book, resp->status, op->closure); - e_book_op_free (op); -} - -static void -e_book_do_progress_event (EBook *book, - EBookListenerResponse *resp) -{ - g_signal_emit (book, e_book_signals [OPEN_PROGRESS], 0, - resp->msg, resp->percent); - - g_free (resp->msg); -} - -static void -e_book_do_link_event (EBook *book, - EBookListenerResponse *resp) -{ - g_signal_emit (book, e_book_signals [LINK_STATUS], 0, - resp->connected); -} - -static void -e_book_do_writable_event (EBook *book, - EBookListenerResponse *resp) -{ - g_signal_emit (book, e_book_signals [WRITABLE_STATUS], 0, - resp->writable); -} - -static void -e_book_do_response_get_supported_fields (EBook *book, - EBookListenerResponse *resp) -{ - EBookOp *op; - - op = e_book_pop_op (book); - - if (op == NULL) { - g_warning ("e_book_do_response_get_supported_fields: Cannot find operation " - "in local op queue!\n"); - return; - } - - if (op->cb) { - if (op->active) - ((EBookFieldsCallback) op->cb) (book, resp->status, resp->list, op->closure); - else - ((EBookFieldsCallback) op->cb) (book, E_BOOK_STATUS_CANCELLED, NULL, op->closure); - } - - g_object_unref(resp->list); - - e_book_op_free (op); -} - -static void -e_book_do_response_get_supported_auth_methods (EBook *book, - EBookListenerResponse *resp) -{ - EBookOp *op; - - op = e_book_pop_op (book); - - if (op == NULL) { - g_warning ("e_book_do_response_get_supported_auth_methods: Cannot find operation " - "in local op queue!\n"); - return; - } - - if (op->cb) { - if (op->active) - ((EBookAuthMethodsCallback) op->cb) (book, resp->status, resp->list, op->closure); - else - ((EBookAuthMethodsCallback) op->cb) (book, E_BOOK_STATUS_CANCELLED, NULL, op->closure); - } - - g_object_unref(resp->list); - - e_book_op_free (op); -} - -/* - * Reading notices out of the EBookListener's queue. - */ -static void -e_book_check_listener_queue (EBookListener *listener, EBook *book) -{ - EBookListenerResponse *resp; - - resp = e_book_listener_pop_response (listener); - - if (resp == NULL) - return; - - switch (resp->op) { - case CreateCardResponse: - e_book_do_response_create_card (book, resp); - break; - case RemoveCardResponse: - case ModifyCardResponse: - case AuthenticationResponse: - e_book_do_response_generic (book, resp); - break; - case GetCardResponse: - e_book_do_response_get_vcard (book, resp); - break; - case GetCursorResponse: - e_book_do_response_get_cursor (book, resp); - break; - case GetBookViewResponse: - e_book_do_response_get_view(book, resp); - break; - case GetChangesResponse: - e_book_do_response_get_changes(book, resp); - break; - case OpenBookResponse: - e_book_do_response_open (book, resp); - break; - case GetSupportedFieldsResponse: - e_book_do_response_get_supported_fields (book, resp); - break; - case GetSupportedAuthMethodsResponse: - e_book_do_response_get_supported_auth_methods (book, resp); - break; - - case OpenProgressEvent: - e_book_do_progress_event (book, resp); - break; - case LinkStatusEvent: - e_book_do_link_event (book, resp); - break; - case WritableStatusEvent: - e_book_do_writable_event (book, resp); - break; - default: - g_error ("EBook: Unknown operation %d in listener queue!\n", - resp->op); - } - - g_free (resp); -} - -/** - * e_book_load_uri: - */ - -typedef struct { - char *uri; - EBookCallback open_response; - gpointer closure; -} EBookLoadURIData; - -static void e_book_load_uri_from_factory (EBook *book, - GNOME_Evolution_Addressbook_BookFactory factory, - EBookLoadURIData *load_uri_data); - -static void -e_book_load_uri_step (EBook *book, EBookStatus status, EBookLoadURIData *data) -{ - /* iterate to the next possible CardFactory, or fail - if it's the last one */ - book->priv->iter = book->priv->iter->next; - if (book->priv->iter) { - GNOME_Evolution_Addressbook_BookFactory factory = book->priv->iter->data; - e_book_load_uri_from_factory (book, factory, data); - } - else { - EBookCallback cb = data->open_response; - gpointer closure = data->closure; - - /* reset the load_state to NotLoaded so people can - attempt another load_uri on the book. */ - book->priv->load_state = URINotLoaded; - - g_free (data); - - cb (book, status, closure); - } -} - -static void -e_book_load_uri_open_cb (EBook *book, EBookStatus status, EBookLoadURIData *data) -{ - if (status == E_BOOK_STATUS_SUCCESS) { - EBookCallback cb = data->open_response; - gpointer closure = data->closure; - - g_free (data); - - cb (book, status, closure); - } - else { - e_book_load_uri_step (book, status, data); - } -} - -static void -e_book_load_uri_from_factory (EBook *book, - GNOME_Evolution_Addressbook_BookFactory factory, - EBookLoadURIData *load_uri_data) -{ - CORBA_Environment ev; - - CORBA_exception_init (&ev); - - e_book_queue_op (book, e_book_load_uri_open_cb, load_uri_data, NULL); - - GNOME_Evolution_Addressbook_BookFactory_openBook ( - factory, book->priv->uri, - bonobo_object_corba_objref (BONOBO_OBJECT (book->priv->listener)), - &ev); - - if (ev._major != CORBA_NO_EXCEPTION) { - g_warning ("e_book_load_uri: CORBA exception while opening addressbook!\n"); - e_book_unqueue_op (book); - CORBA_exception_free (&ev); - e_book_load_uri_step (book, E_BOOK_STATUS_OTHER_ERROR, load_uri_data); - } - - CORBA_exception_free (&ev); - -} - -static gboolean -activate_factories_for_uri (EBook *book, const char *uri) -{ - CORBA_Environment ev; - Bonobo_ServerInfoList *info_list = NULL; - int i; - char *protocol, *query, *colon; - gboolean retval = FALSE; - - colon = strchr (uri, ':'); - if (!colon) { - g_warning ("e_book_load_uri: Unable to determine protocol in the URI\n"); - return FALSE; - } - - protocol = g_strndup (uri, colon-uri); - query = g_strdup_printf ("repo_ids.has ('IDL:GNOME/Evolution/BookFactory:1.0')" - " AND addressbook:supported_protocols.has ('%s')", protocol - ); - - CORBA_exception_init (&ev); - - info_list = bonobo_activation_query (query, NULL, &ev); - - if (ev._major != CORBA_NO_EXCEPTION) { - g_warning ("Eeek! Cannot perform bonobo-activation query for book factories."); - CORBA_exception_free (&ev); - goto shutdown; - } - - if (info_list->_length == 0) { - g_warning ("Can't find installed BookFactory that handles protocol '%s'.", protocol); - CORBA_exception_free (&ev); - goto shutdown; - } - - CORBA_exception_free (&ev); - - for (i = 0; i < info_list->_length; i ++) { - const Bonobo_ServerInfo *info; - GNOME_Evolution_Addressbook_BookFactory factory; - - info = info_list->_buffer + i; - - factory = bonobo_activation_activate_from_id (info->iid, 0, NULL, NULL); - - if (factory == CORBA_OBJECT_NIL) - g_warning ("e_book_construct: Could not obtain a handle " - "to the Personal Addressbook Server with IID `%s'\n", info->iid); - else - book->priv->book_factories = g_list_append (book->priv->book_factories, - factory); - } - - if (!book->priv->book_factories) { - g_warning ("Couldn't activate any book factories."); - goto shutdown; - } - - retval = TRUE; - - shutdown: - if (info_list) - CORBA_free (info_list); - g_free (query); - g_free (protocol); - - return retval; -} - -void -e_book_load_uri (EBook *book, - const char *uri, - EBookCallback open_response, - gpointer closure) -{ - EBookLoadURIData *load_uri_data; - GNOME_Evolution_Addressbook_BookFactory factory; - - g_return_if_fail (book != NULL); - g_return_if_fail (E_IS_BOOK (book)); - g_return_if_fail (uri != NULL); - g_return_if_fail (open_response != NULL); - - if (book->priv->load_state != URINotLoaded) { - g_warning ("e_book_load_uri: Attempted to load a URI " - "on a book which already has a URI loaded!\n"); - open_response (book, E_BOOK_STATUS_OTHER_ERROR, closure); /* XXX need a new status code here */ - return; - } - - /* try to find a list of factories that can handle the protocol */ - if (!activate_factories_for_uri (book, uri)) { - open_response (book, E_BOOK_STATUS_PROTOCOL_NOT_SUPPORTED, closure); - return; - } - - g_free (book->priv->uri); - book->priv->uri = g_strdup (uri); - - /* - * Create our local BookListener interface. - */ - book->priv->listener = e_book_listener_new (); - if (book->priv->listener == NULL) { - g_warning ("e_book_load_uri: Could not create EBookListener!\n"); - open_response (NULL, E_BOOK_STATUS_OTHER_ERROR, closure); /* XXX need a new status code here */ - return; - } - - book->priv->listener_signal = g_signal_connect (book->priv->listener, "responses_queued", - G_CALLBACK (e_book_check_listener_queue), book); - - load_uri_data = g_new (EBookLoadURIData, 1); - load_uri_data->open_response = open_response; - load_uri_data->closure = closure; - - /* initialize the iterator, and load from the first one*/ - book->priv->iter = book->priv->book_factories; - - factory = book->priv->iter->data; - - e_book_load_uri_from_factory (book, factory, load_uri_data); - - book->priv->load_state = URILoading; -} - -/** - * e_book_unload_uri: - */ -void -e_book_unload_uri (EBook *book) -{ - CORBA_Environment ev; - - g_return_if_fail (book != NULL); - g_return_if_fail (E_IS_BOOK (book)); - - /* - * FIXME: Make sure this works if the URI is still being - * loaded. - */ - if (book->priv->load_state != URILoaded) { - g_warning ("e_book_unload_uri: No URI is loaded!\n"); - return; - } - - /* - * Release the remote GNOME_Evolution_Addressbook_Book in the PAS. - */ - CORBA_exception_init (&ev); - - bonobo_object_release_unref (book->priv->corba_book, &ev); - if (ev._major != CORBA_NO_EXCEPTION) { - g_warning ("e_book_unload_uri: Exception releasing " - "remote book interface!\n"); - } - - CORBA_exception_free (&ev); - - e_book_listener_stop (book->priv->listener); - bonobo_object_unref (BONOBO_OBJECT (book->priv->listener)); - - book->priv->listener = NULL; - book->priv->load_state = URINotLoaded; -} - -const char * -e_book_get_uri (EBook *book) -{ - g_return_val_if_fail (book && E_IS_BOOK (book), NULL); - - return book->priv->uri; -} - -char * -e_book_get_static_capabilities (EBook *book) -{ - if (!book->priv->cap_queried) { - CORBA_Environment ev; - char *temp; - - CORBA_exception_init (&ev); - - if (book->priv->load_state != URILoaded) { - g_warning ("e_book_unload_uri: No URI is loaded!\n"); - return g_strdup(""); - } - - temp = GNOME_Evolution_Addressbook_Book_getStaticCapabilities(book->priv->corba_book, &ev); - - if (ev._major != CORBA_NO_EXCEPTION) { - g_warning ("e_book_get_static_capabilities: Exception " - "during get_static_capabilities!\n"); - CORBA_exception_free (&ev); - return g_strdup(""); - } - - book->priv->cap = g_strdup(temp); - book->priv->cap_queried = TRUE; - - CORBA_free(temp); - - CORBA_exception_free (&ev); - } - - return g_strdup (book->priv->cap); -} - -gboolean -e_book_check_static_capability (EBook *book, const char *cap) -{ - gboolean rv = FALSE; - char *caps = e_book_get_static_capabilities (book); - if (!caps) - return FALSE; - - /* XXX this is an inexact test but it works for our use */ - if (strstr (caps, cap)) - rv = TRUE; - - g_free (caps); - - return rv; -} - -guint -e_book_get_supported_fields (EBook *book, - EBookFieldsCallback cb, - gpointer closure) -{ - CORBA_Environment ev; - guint tag; - - CORBA_exception_init (&ev); - - if (book->priv->load_state != URILoaded) { - g_warning ("e_book_unload_uri: No URI is loaded!\n"); - return 0; - } - - tag = e_book_queue_op (book, cb, closure, NULL); - - GNOME_Evolution_Addressbook_Book_getSupportedFields(book->priv->corba_book, &ev); - - if (ev._major != CORBA_NO_EXCEPTION) { - g_warning ("e_book_get_supported_fields: Exception " - "during get_supported_fields!\n"); - CORBA_exception_free (&ev); - e_book_unqueue_op (book); - return 0; - } - - CORBA_exception_free (&ev); - - return tag; -} - -guint -e_book_get_supported_auth_methods (EBook *book, - EBookAuthMethodsCallback cb, - gpointer closure) -{ - CORBA_Environment ev; - guint tag; - - CORBA_exception_init (&ev); - - if (book->priv->load_state != URILoaded) { - g_warning ("e_book_unload_uri: No URI is loaded!\n"); - return 0; - } - - tag = e_book_queue_op (book, cb, closure, NULL); - - GNOME_Evolution_Addressbook_Book_getSupportedAuthMethods(book->priv->corba_book, &ev); - - if (ev._major != CORBA_NO_EXCEPTION) { - g_warning ("e_book_get_supported_auth_methods: Exception " - "during get_supported_auth_methods!\n"); - CORBA_exception_free (&ev); - e_book_unqueue_op (book); - return 0; - } - - CORBA_exception_free (&ev); - - return tag; -} - -static gboolean -e_book_construct (EBook *book) -{ - g_return_val_if_fail (book != NULL, FALSE); - g_return_val_if_fail (E_IS_BOOK (book), FALSE); - - book->priv->book_factories = NULL; - - return TRUE; -} - -/** - * e_book_new: - */ -EBook * -e_book_new (void) -{ - EBook *book; - - book = g_object_new (E_TYPE_BOOK, NULL); - - if (! e_book_construct (book)) { - g_object_unref (book); - return NULL; - } - - return book; -} - -/* User authentication. */ - -void -e_book_authenticate_user (EBook *book, - const char *user, - const char *passwd, - const char *auth_method, - EBookCallback cb, - gpointer closure) -{ - CORBA_Environment ev; - - g_return_if_fail (book != NULL); - g_return_if_fail (E_IS_BOOK (book)); - - if (book->priv->load_state != URILoaded) { - g_warning ("e_book_authenticate_user: No URI loaded!\n"); - return; - } - - CORBA_exception_init (&ev); - - e_book_queue_op (book, cb, closure, NULL); - - GNOME_Evolution_Addressbook_Book_authenticateUser (book->priv->corba_book, - user, - passwd, - auth_method, - &ev); - - if (ev._major != CORBA_NO_EXCEPTION) { - g_warning ("e_book_authenticate_user: Exception authenticating user with the PAS!\n"); - CORBA_exception_free (&ev); - e_book_unqueue_op (book); - return; - } - - CORBA_exception_free (&ev); -} - -/* Fetching cards */ - -/** - * e_book_get_card: - */ -guint -e_book_get_card (EBook *book, - const char *id, - EBookCardCallback cb, - gpointer closure) -{ - CORBA_Environment ev; - guint tag; - - g_return_val_if_fail (book != NULL, 0); - g_return_val_if_fail (E_IS_BOOK (book), 0); - - if (book->priv->load_state != URILoaded) { - g_warning ("e_book_get_card: No URI loaded!\n"); - return 0; - } - - CORBA_exception_init (&ev); - - tag = e_book_queue_op (book, cb, closure, NULL); - - GNOME_Evolution_Addressbook_Book_getVCard (book->priv->corba_book, (const GNOME_Evolution_Addressbook_VCard) id, &ev); - - if (ev._major != CORBA_NO_EXCEPTION) { - g_warning ("e_book_get_card: Exception " - "getting card!\n"); - CORBA_exception_free (&ev); - e_book_unqueue_op (book); - return 0; - } - - CORBA_exception_free (&ev); - - return tag; -} - -/* Deleting cards. */ - -/** - * e_book_remove_card: - */ -gboolean -e_book_remove_card (EBook *book, - ECard *card, - EBookCallback cb, - gpointer closure) -{ - const char *id; - - g_return_val_if_fail (book != NULL, FALSE); - g_return_val_if_fail (E_IS_BOOK (book), FALSE); - g_return_val_if_fail (card != NULL, FALSE); - g_return_val_if_fail (E_IS_CARD (card), FALSE); - - if (book->priv->load_state != URILoaded) { - g_warning ("e_book_remove_card: No URI loaded!\n"); - return FALSE; - } - - id = e_card_get_id (card); - g_assert (id != NULL); - - return e_book_remove_card_by_id (book, id, cb, closure); -} - -/** - * e_book_remove_card_by_id: - */ -gboolean -e_book_remove_card_by_id (EBook *book, - const char *id, - EBookCallback cb, - gpointer closure) - -{ - GList *list = NULL; - gboolean rv; - - list = g_list_prepend (list, (char*)id); - - rv = e_book_remove_cards (book, list, cb, closure); - - g_list_free (list); - - return rv; -} - -gboolean -e_book_remove_cards (EBook *book, - GList *ids, - EBookCallback cb, - gpointer closure) -{ - GNOME_Evolution_Addressbook_CardIdList idlist; - CORBA_Environment ev; - GList *l; - int num_ids, i; - - g_return_val_if_fail (book != NULL, FALSE); - g_return_val_if_fail (E_IS_BOOK (book), FALSE); - g_return_val_if_fail (ids != NULL, FALSE); - - if (book->priv->load_state != URILoaded) { - g_warning ("e_book_remove_card_by_id: No URI loaded!\n"); - return FALSE; - } - - CORBA_exception_init (&ev); - - e_book_queue_op (book, cb, closure, NULL); - - num_ids = g_list_length (ids); - idlist._buffer = CORBA_sequence_GNOME_Evolution_Addressbook_CardId_allocbuf (num_ids); - idlist._maximum = num_ids; - idlist._length = num_ids; - - for (l = ids, i = 0; l; l=l->next, i ++) { - idlist._buffer[i] = CORBA_string_dup (l->data); - } - - GNOME_Evolution_Addressbook_Book_removeCards (book->priv->corba_book, &idlist, &ev); - - if (ev._major != CORBA_NO_EXCEPTION) { - g_warning ("e_book_remove_card_by_id: CORBA exception " - "talking to PAS!\n"); - CORBA_exception_free (&ev); - e_book_unqueue_op (book); - return FALSE; - } - - CORBA_exception_free (&ev); - - CORBA_free(idlist._buffer); - - return TRUE; -} - - -/* Adding cards. */ - -/** - * e_book_add_card: - */ -gboolean -e_book_add_card (EBook *book, - ECard *card, - EBookIdCallback cb, - gpointer closure) - -{ - char *vcard; - gboolean retval; - - g_return_val_if_fail (book != NULL, FALSE); - g_return_val_if_fail (E_IS_BOOK (book), FALSE); - g_return_val_if_fail (card != NULL, FALSE); - g_return_val_if_fail (E_IS_CARD (card), FALSE); - - if (book->priv->load_state != URILoaded) { - g_warning ("e_book_add_card: No URI loaded!\n"); - return FALSE; - } - - vcard = e_card_get_vcard_assume_utf8 (card); - - if (vcard == NULL) { - g_warning ("e_book_add_card: Cannot convert card to VCard string!\n"); - return FALSE; - } - - retval = e_book_add_vcard (book, vcard, cb, closure); - - g_free (vcard); - - e_card_set_book (card, book); - - return retval; -} - -/** - * e_book_add_vcard: - */ -gboolean -e_book_add_vcard (EBook *book, - const char *vcard, - EBookIdCallback cb, - gpointer closure) -{ - CORBA_Environment ev; - - g_return_val_if_fail (book != NULL, FALSE); - g_return_val_if_fail (E_IS_BOOK (book), FALSE); - g_return_val_if_fail (vcard != NULL, FALSE); - - if (book->priv->load_state != URILoaded) { - g_warning ("e_book_add_vcard: No URI loaded!\n"); - return FALSE; - } - - CORBA_exception_init (&ev); - - e_book_queue_op (book, (EBookCallback) cb, closure, NULL); - - GNOME_Evolution_Addressbook_Book_addCard ( - book->priv->corba_book, (const GNOME_Evolution_Addressbook_VCard) vcard, &ev); - - if (ev._major != CORBA_NO_EXCEPTION) { - g_warning ("e_book_add_vcard: Exception adding card to PAS!\n"); - CORBA_exception_free (&ev); - e_book_unqueue_op (book); - return FALSE; - } - - CORBA_exception_free (&ev); - - return TRUE; -} - -/* Modifying cards. */ - -/** - * e_book_commit_card: - */ -gboolean -e_book_commit_card (EBook *book, - ECard *card, - EBookCallback cb, - gpointer closure) -{ - char *vcard; - gboolean retval; - - g_return_val_if_fail (book != NULL, FALSE); - g_return_val_if_fail (E_IS_BOOK (book), FALSE); - g_return_val_if_fail (card != NULL, FALSE); - g_return_val_if_fail (E_IS_CARD (card), FALSE); - - if (book->priv->load_state != URILoaded) { - g_warning ("e_book_commit_card: No URI loaded!\n"); - return FALSE; - } - - vcard = e_card_get_vcard_assume_utf8 (card); - - if (vcard == NULL) { - g_warning ("e_book_commit_card: Error " - "getting VCard for card!\n"); - return FALSE; - } - - retval = e_book_commit_vcard (book, vcard, cb, closure); - - g_free (vcard); - - e_card_set_book (card, book); - - return retval; -} - -/** - * e_book_commit_vcard: - */ -gboolean -e_book_commit_vcard (EBook *book, - const char *vcard, - EBookCallback cb, - gpointer closure) -{ - CORBA_Environment ev; - - g_return_val_if_fail (book != NULL, FALSE); - g_return_val_if_fail (E_IS_BOOK (book), FALSE); - g_return_val_if_fail (vcard != NULL, FALSE); - - if (book->priv->load_state != URILoaded) { - g_warning ("e_book_commit_vcard: No URI loaded!\n"); - return FALSE; - } - - CORBA_exception_init (&ev); - - e_book_queue_op (book, cb, closure, NULL); - - GNOME_Evolution_Addressbook_Book_modifyCard ( - book->priv->corba_book, (const GNOME_Evolution_Addressbook_VCard) vcard, &ev); - - if (ev._major != CORBA_NO_EXCEPTION) { - g_warning ("e_book_commit_vcard: Exception " - "modifying card in PAS!\n"); - CORBA_exception_free (&ev); - e_book_unqueue_op (book); - return FALSE; - } - - CORBA_exception_free (&ev); - - return TRUE; -} - -/** - * e_book_check_connection: - */ -gboolean -e_book_check_connection (EBook *book) -{ - CORBA_Environment ev; - - g_return_val_if_fail (book != NULL, FALSE); - g_return_val_if_fail (E_IS_BOOK (book), FALSE); - - if (book->priv->load_state != URILoaded) { - g_warning ("e_book_check_connection: No URI loaded!\n"); - return FALSE; - } - - CORBA_exception_init (&ev); - - GNOME_Evolution_Addressbook_Book_checkConnection (book->priv->corba_book, &ev); - - if (ev._major != CORBA_NO_EXCEPTION) { - g_warning ("e_book_check_connection: Exception " - "querying the PAS!\n"); - CORBA_exception_free (&ev); - return FALSE; - } - - CORBA_exception_free (&ev); - - return TRUE; -} - -guint -e_book_get_cursor (EBook *book, - gchar *query, - EBookCursorCallback cb, - gpointer closure) -{ - CORBA_Environment ev; - guint tag; - - g_return_val_if_fail (book != NULL, 0); - g_return_val_if_fail (E_IS_BOOK (book), 0); - - if (book->priv->load_state != URILoaded) { - g_warning ("e_book_check_connection: No URI loaded!\n"); - return 0; - } - - CORBA_exception_init (&ev); - - tag = e_book_queue_op (book, cb, closure, NULL); - - GNOME_Evolution_Addressbook_Book_getCursor (book->priv->corba_book, query, &ev); - - if (ev._major != CORBA_NO_EXCEPTION) { - g_warning ("e_book_get_all_cards: Exception " - "querying list of cards!\n"); - CORBA_exception_free (&ev); - e_book_unqueue_op (book); - return 0; - } - - CORBA_exception_free (&ev); - - return tag; -} - -guint -e_book_get_book_view (EBook *book, - const gchar *query, - EBookBookViewCallback cb, - gpointer closure) -{ - CORBA_Environment ev; - EBookViewListener *listener; - guint tag; - - g_return_val_if_fail (book != NULL, 0); - g_return_val_if_fail (E_IS_BOOK (book), 0); - - if (book->priv->load_state != URILoaded) { - g_warning ("e_book_get_book_view: No URI loaded!\n"); - return 0; - } - - listener = e_book_view_listener_new(); - - CORBA_exception_init (&ev); - - tag = e_book_queue_op (book, cb, closure, listener); - - GNOME_Evolution_Addressbook_Book_getBookView (book->priv->corba_book, bonobo_object_corba_objref(BONOBO_OBJECT(listener)), query, &ev); - - if (ev._major != CORBA_NO_EXCEPTION) { - g_warning ("e_book_get_book_view: Exception " - "getting book_view!\n"); - CORBA_exception_free (&ev); - e_book_unqueue_op (book); - return 0; - } - - CORBA_exception_free (&ev); - - return tag; -} - -guint -e_book_get_completion_view (EBook *book, - const gchar *query, - EBookBookViewCallback cb, - gpointer closure) -{ - CORBA_Environment ev; - EBookViewListener *listener; - guint tag; - - g_return_val_if_fail (book != NULL, 0); - g_return_val_if_fail (E_IS_BOOK (book), 0); - - if (book->priv->load_state != URILoaded) { - g_warning ("e_book_get_completion_view: No URI loaded!\n"); - return 0; - } - - listener = e_book_view_listener_new(); - - CORBA_exception_init (&ev); - - tag = e_book_queue_op (book, cb, closure, listener); - - GNOME_Evolution_Addressbook_Book_getCompletionView (book->priv->corba_book, - bonobo_object_corba_objref(BONOBO_OBJECT(listener)), - query, &ev); - - if (ev._major != CORBA_NO_EXCEPTION) { - g_warning ("e_book_get_completion_view: Exception " - "getting completion_view!\n"); - CORBA_exception_free (&ev); - e_book_unqueue_op (book); - return 0; - } - - CORBA_exception_free (&ev); - - return tag; -} - -guint -e_book_get_changes (EBook *book, - gchar *changeid, - EBookBookViewCallback cb, - gpointer closure) -{ - CORBA_Environment ev; - EBookViewListener *listener; - guint tag; - - g_return_val_if_fail (book != NULL, 0); - g_return_val_if_fail (E_IS_BOOK (book), 0); - - if (book->priv->load_state != URILoaded) { - g_warning ("e_book_get_changes: No URI loaded!\n"); - return FALSE; - } - - listener = e_book_view_listener_new(); - - CORBA_exception_init (&ev); - - tag = e_book_queue_op (book, cb, closure, listener); - - GNOME_Evolution_Addressbook_Book_getChanges (book->priv->corba_book, bonobo_object_corba_objref(BONOBO_OBJECT(listener)), changeid, &ev); - - if (ev._major != CORBA_NO_EXCEPTION) { - g_warning ("e_book_changes: Exception " - "getting changes!\n"); - CORBA_exception_free (&ev); - e_book_unqueue_op (book); - return 0; - } - - CORBA_exception_free (&ev); - - return tag; -} - -/** - * e_book_cancel - */ - -void -e_book_cancel (EBook *book, guint tag) -{ - g_return_if_fail (book != NULL); - g_return_if_fail (E_IS_BOOK (book)); - g_return_if_fail (tag != 0); - - /* In an attempt to be useful, we take a bit of extra care in reporting - errors. This might come in handy someday. */ - if (tag >= book->priv->op_tag) - g_warning ("Attempt to cancel unassigned operation (%u)", tag); - else if (! e_book_cancel_op (book, tag)) - g_warning ("Attempt to cancel unknown operation (%u)", tag); -} - -/** - * e_book_get_name: - */ -char * -e_book_get_name (EBook *book) -{ - CORBA_Environment ev; - char *retval; - char *name; - - g_return_val_if_fail (book != NULL, NULL); - g_return_val_if_fail (E_IS_BOOK (book), NULL); - - if (book->priv->load_state != URILoaded) { - g_warning ("e_book_get_name: No URI loaded!\n"); - return NULL; - } - - CORBA_exception_init (&ev); - - name = GNOME_Evolution_Addressbook_Book_getName (book->priv->corba_book, &ev); - - if (ev._major != CORBA_NO_EXCEPTION) { - g_warning ("e_book_get_name: Exception getting name from PAS!\n"); - CORBA_exception_free (&ev); - return NULL; - } - - CORBA_exception_free (&ev); - - if (name == NULL) { - g_warning ("e_book_get_name: Got NULL name from PAS!\n"); - return NULL; - } - - retval = g_strdup (name); - CORBA_free (name); - - return retval; -} - -static void -e_book_init (EBook *book) -{ - book->priv = g_new0 (EBookPrivate, 1); - book->priv->load_state = URINotLoaded; - book->priv->op_tag = 1; - book->priv->uri = NULL; -} - -static void -e_book_dispose (GObject *object) -{ - EBook *book = E_BOOK (object); - - if (book->priv) { - CORBA_Environment ev; - GList *l; - - if (book->priv->load_state == URILoaded) - e_book_unload_uri (book); - - CORBA_exception_init (&ev); - - for (l = book->priv->book_factories; l; l = l->next) { - CORBA_Object_release ((CORBA_Object)l->data, &ev); - if (ev._major != CORBA_NO_EXCEPTION) { - g_warning ("EBook: Exception while releasing BookFactory\n"); - - CORBA_exception_free (&ev); - CORBA_exception_init (&ev); - } - } - - CORBA_exception_free (&ev); - - if (book->priv->listener) { - g_signal_handler_disconnect (book->priv->comp_listener, book->priv->listener_signal); - bonobo_object_unref (book->priv->listener); - book->priv->listener = NULL; - } - - if (book->priv->comp_listener) { - g_signal_handler_disconnect (book->priv->comp_listener, book->priv->died_signal); - g_object_unref (book->priv->comp_listener); - book->priv->comp_listener = NULL; - } - - g_free (book->priv->cap); - - g_free (book->priv->uri); - - g_free (book->priv); - book->priv = NULL; - } - - if (G_OBJECT_CLASS (parent_class)->dispose) - G_OBJECT_CLASS (parent_class)->dispose (object); -} - -static void -e_book_class_init (EBookClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - parent_class = g_type_class_ref (G_TYPE_OBJECT); - - e_book_signals [LINK_STATUS] = - g_signal_new ("link_status", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (EBookClass, link_status), - NULL, NULL, - e_book_marshal_NONE__BOOL, - G_TYPE_NONE, 1, - G_TYPE_BOOLEAN); - - e_book_signals [WRITABLE_STATUS] = - g_signal_new ("writable_status", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (EBookClass, writable_status), - NULL, NULL, - e_book_marshal_NONE__BOOL, - G_TYPE_NONE, 1, - G_TYPE_BOOLEAN); - - e_book_signals [BACKEND_DIED] = - g_signal_new ("backend_died", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (EBookClass, backend_died), - NULL, NULL, - e_book_marshal_NONE__NONE, - G_TYPE_NONE, 0); - - object_class->dispose = e_book_dispose; -} - -/** - * e_book_get_type: - */ -GType -e_book_get_type (void) -{ - static GType type = 0; - - if (! type) { - GTypeInfo info = { - sizeof (EBookClass), - NULL, /* base_class_init */ - NULL, /* base_class_finalize */ - (GClassInitFunc) e_book_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (EBook), - 0, /* n_preallocs */ - (GInstanceInitFunc) e_book_init - }; - - type = g_type_register_static (G_TYPE_OBJECT, "EBook", &info, 0); - } - - return type; -} diff --git a/addressbook/backend/ebook/e-book.h b/addressbook/backend/ebook/e-book.h deleted file mode 100644 index d2c5a7bce4..0000000000 --- a/addressbook/backend/ebook/e-book.h +++ /dev/null @@ -1,170 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * The Evolution addressbook client object. - * - * Author: - * Nat Friedman (nat@ximian.com) - * - * Copyright 1999, 2000, Ximian, Inc. - */ - -#ifndef __E_BOOK_H__ -#define __E_BOOK_H__ - -#include <glib.h> -#include <glib-object.h> - -#include <ebook/e-card.h> -#include <ebook/e-card-cursor.h> -#include <ebook/e-book-view.h> -#include <ebook/e-book-types.h> - -#define E_TYPE_BOOK (e_book_get_type ()) -#define E_BOOK(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), E_TYPE_BOOK, EBook)) -#define E_BOOK_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), E_TYPE_BOOK, EBookClass)) -#define E_IS_BOOK(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), E_TYPE_BOOK)) -#define E_IS_BOOK_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), E_TYPE_BOOK)) -#define E_BOOK_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), E_TYPE_BOOK, EBookClass)) - -G_BEGIN_DECLS - -typedef struct _EBook EBook; -typedef struct _EBookClass EBookClass; -typedef struct _EBookPrivate EBookPrivate; - -struct _EBook { - GObject parent; - EBookPrivate *priv; -}; - -struct _EBookClass { - GObjectClass parent; - - /* - * Signals. - */ - void (* open_progress) (EBook *book, const char *msg, short percent); - void (* link_status) (EBook *book, gboolean connected); - void (* writable_status) (EBook *book, gboolean writable); - void (* backend_died) (EBook *book); -}; - -/* Callbacks for asynchronous functions. */ -typedef void (*EBookCallback) (EBook *book, EBookStatus status, gpointer closure); -typedef void (*EBookOpenProgressCallback) (EBook *book, - const char *status_message, - short percent, - gpointer closure); -typedef void (*EBookIdCallback) (EBook *book, EBookStatus status, const char *id, gpointer closure); -typedef void (*EBookCardCallback) (EBook *book, EBookStatus status, ECard *card, gpointer closure); -typedef void (*EBookCursorCallback) (EBook *book, EBookStatus status, ECardCursor *cursor, gpointer closure); -typedef void (*EBookBookViewCallback) (EBook *book, EBookStatus status, EBookView *book_view, gpointer closure); -typedef void (*EBookFieldsCallback) (EBook *book, EBookStatus status, EList *fields, gpointer closure); -typedef void (*EBookAuthMethodsCallback) (EBook *book, EBookStatus status, EList *auth_methods, gpointer closure); - -/* Creating a new addressbook. */ -EBook *e_book_new (void); - -void e_book_load_uri (EBook *book, - const char *uri, - EBookCallback open_response, - gpointer closure); -void e_book_unload_uri (EBook *book); - -const char *e_book_get_uri (EBook *book); - -char *e_book_get_static_capabilities (EBook *book); -gboolean e_book_check_static_capability (EBook *book, const char *cap); - -guint e_book_get_supported_fields (EBook *book, - EBookFieldsCallback cb, - gpointer closure); - -guint e_book_get_supported_auth_methods (EBook *book, - EBookAuthMethodsCallback cb, - gpointer closure); - -/* User authentication. */ -void e_book_authenticate_user (EBook *book, - const char *user, - const char *passwd, - const char *auth_method, - EBookCallback cb, - gpointer closure); - -/* Fetching cards. */ -guint e_book_get_card (EBook *book, - const char *id, - EBookCardCallback cb, - gpointer closure); - -/* Deleting cards. */ -gboolean e_book_remove_card (EBook *book, - ECard *card, - EBookCallback cb, - gpointer closure); -gboolean e_book_remove_card_by_id (EBook *book, - const char *id, - EBookCallback cb, - gpointer closure); - -gboolean e_book_remove_cards (EBook *book, - GList *id_list, - EBookCallback cb, - gpointer closure); - -/* Adding cards. */ -gboolean e_book_add_card (EBook *book, - ECard *card, - EBookIdCallback cb, - gpointer closure); -gboolean e_book_add_vcard (EBook *book, - const char *vcard, - EBookIdCallback cb, - gpointer closure); - -/* Modifying cards. */ -gboolean e_book_commit_card (EBook *book, - ECard *card, - EBookCallback cb, - gpointer closure); -gboolean e_book_commit_vcard (EBook *book, - const char *vcard, - EBookCallback cb, - gpointer closure); - -/* Checking to see if we're connected to the card repository. */ -gboolean e_book_check_connection (EBook *book); -guint e_book_get_cursor (EBook *book, - char *query, - EBookCursorCallback cb, - gpointer closure); - -guint e_book_get_book_view (EBook *book, - const gchar *query, - EBookBookViewCallback cb, - gpointer closure); - -guint e_book_get_completion_view (EBook *book, - const gchar *query, - EBookBookViewCallback cb, - gpointer closure); - -guint e_book_get_changes (EBook *book, - char *changeid, - EBookBookViewCallback cb, - gpointer closure); - -/* Cancel a pending operation. */ -void e_book_cancel (EBook *book, - guint tag); - - -/* Getting the name of the repository. */ -char *e_book_get_name (EBook *book); - -GType e_book_get_type (void); - -G_END_DECLS - -#endif /* ! __E_BOOK_H__ */ diff --git a/addressbook/backend/ebook/e-card-compare.c b/addressbook/backend/ebook/e-card-compare.c deleted file mode 100644 index 2413d987e5..0000000000 --- a/addressbook/backend/ebook/e-card-compare.c +++ /dev/null @@ -1,706 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -/* - * e-card-compare.c - * - * Copyright (C) 2001 Ximian, Inc. - * - * Developed by Jon Trowbridge <trow@ximian.com> - */ - -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA. - */ - -#include <config.h> -#include <ctype.h> -#include <string.h> -#include "e-book-util.h" -#include "e-card-compare.h" - -/* This is an "optimistic" combiner: the best of the two outcomes is - selected. */ -static ECardMatchType -combine_comparisons (ECardMatchType prev, - ECardMatchType new_info) -{ - if (new_info == E_CARD_MATCH_NOT_APPLICABLE) - return prev; - return (ECardMatchType) MAX ((gint) prev, (gint) new_info); -} - - -/*** Name comparisons ***/ - -/* This *so* doesn't belong here... at least not implemented in a - sucky way like this. But it can be fixed later. */ - -/* This is very Anglocentric. */ -static gchar *name_synonyms[][2] = { - { "jon", "john" }, /* Ah, the hacker's perogative */ - { "joseph", "joe" }, - { "robert", "bob" }, - { "gene", "jean" }, - { "jesse", "jessie" }, - { "ian", "iain" }, - { "richard", "dick" }, - { "william", "bill" }, - { "william", "will" }, - { "anthony", "tony" }, - { "michael", "mike" }, - { "eric", "erik" }, - { "elizabeth", "liz" }, - { "jeff", "geoff" }, - { "jeff", "geoffrey" }, - { "tom", "thomas" }, - { "dave", "david" }, - { "jim", "james" }, - { "abigal", "abby" }, - { "amanda", "amy" }, - { "amanda", "manda" }, - { "jennifer", "jenny" }, - { "christopher", "chris" }, - { "rebecca", "becca" }, - { "rebecca", "becky" }, - { "anderson", "andersen" }, - { "johnson", "johnsen" }, - /* We could go on and on... */ - /* We should add soundex here. */ - { NULL, NULL } -}; - -static gboolean -name_fragment_match (const gchar *a, const gchar *b, gboolean strict) -{ - gint len; - - if (!(a && b && *a && *b)) - return FALSE; - - /* If we are in 'strict' mode, b must match the beginning of a. - So "Robert", "Rob" would match, but "Robert", "Robbie" wouldn't. - - If strict is FALSE, it is sufficient for the strings to share - some leading characters. In this case, "Robert" and "Robbie" - would match, as would "Dave" and "Dan". */ - - if (strict) { - len = g_utf8_strlen (b, -1); - } else { - len = MIN (g_utf8_strlen (a, -1), g_utf8_strlen (b, -1)); - } - - return !e_utf8_casefold_collate_len (a, b, len); -} - -static gboolean -name_fragment_match_with_synonyms (const gchar *a, const gchar *b, gboolean strict) -{ - gint i; - - if (!(a && b && *a && *b)) - return FALSE; - - if (name_fragment_match (a, b, strict)) - return TRUE; - - /* Check for nicknames. Yes, the linear search blows. */ - for (i=0; name_synonyms[i][0]; ++i) { - - if (!e_utf8_casefold_collate (name_synonyms[i][0], a) - && !e_utf8_casefold_collate (name_synonyms[i][1], b)) - return TRUE; - - if (!e_utf8_casefold_collate (name_synonyms[i][0], b) - && !e_utf8_casefold_collate (name_synonyms[i][1], a)) - return TRUE; - } - - return FALSE; -} - -ECardMatchType -e_card_compare_name_to_string (ECard *card, const gchar *str) -{ - return e_card_compare_name_to_string_full (card, str, FALSE, NULL, NULL, NULL); -} - -ECardMatchType -e_card_compare_name_to_string_full (ECard *card, const gchar *str, gboolean allow_partial_matches, - gint *matched_parts_out, ECardMatchPart *first_matched_part_out, gint *matched_character_count_out) -{ - gchar **namev, **givenv = NULL, **addv = NULL, **familyv = NULL; - - gint matched_parts = E_CARD_MATCH_PART_NONE; - ECardMatchPart first_matched_part = E_CARD_MATCH_PART_NONE; - ECardMatchPart this_part_match = E_CARD_MATCH_PART_NOT_APPLICABLE; - ECardMatchType match_type; - - gint match_count = 0, matched_character_count = 0, fragment_count; - gint i, j; - gchar *str_cpy, *s; - - g_return_val_if_fail (E_IS_CARD (card), E_CARD_MATCH_NOT_APPLICABLE); - g_return_val_if_fail (card->name != NULL, E_CARD_MATCH_NOT_APPLICABLE); - g_return_val_if_fail (str != NULL, E_CARD_MATCH_NOT_APPLICABLE); - - str_cpy = s = g_strdup (str); - while (*s) { - if (*s == ',' || *s == '"') - *s = ' '; - ++s; - } - namev = g_strsplit (str_cpy, " ", 0); - g_free (str_cpy); - - if (card->name->given) - givenv = g_strsplit (card->name->given, " ", 0); - if (card->name->additional) - addv = g_strsplit (card->name->additional, " ", 0); - if (card->name->family) - familyv = g_strsplit (card->name->family, " ", 0); - - fragment_count = 0; - for (i = 0; givenv && givenv[i]; ++i) - ++fragment_count; - for (i = 0; addv && addv[i]; ++i) - ++fragment_count; - for (i = 0; familyv && familyv[i]; ++i) - ++fragment_count; - - for (i = 0; namev[i] && this_part_match != E_CARD_MATCH_PART_NONE; ++i) { - - if (*namev[i]) { - - this_part_match = E_CARD_MATCH_PART_NONE; - - /* When we are allowing partials, we are strict about the matches we allow. - Does this make sense? Not really, but it does the right thing for the purposes - of completion. */ - - if (givenv && this_part_match == E_CARD_MATCH_PART_NONE) { - for (j = 0; givenv[j]; ++j) { - if (name_fragment_match_with_synonyms (givenv[j], namev[i], allow_partial_matches)) { - - this_part_match = E_CARD_MATCH_PART_GIVEN_NAME; - - /* We remove a piece of a name once it has been matched against, so - that "john john" won't match "john doe". */ - g_free (givenv[j]); - givenv[j] = g_strdup (""); - break; - } - } - } - - if (addv && this_part_match == E_CARD_MATCH_PART_NONE) { - for (j = 0; addv[j]; ++j) { - if (name_fragment_match_with_synonyms (addv[j], namev[i], allow_partial_matches)) { - - this_part_match = E_CARD_MATCH_PART_ADDITIONAL_NAME; - - g_free (addv[j]); - addv[j] = g_strdup (""); - break; - } - } - } - - if (familyv && this_part_match == E_CARD_MATCH_PART_NONE) { - for (j = 0; familyv[j]; ++j) { - if (allow_partial_matches ? name_fragment_match_with_synonyms (familyv[j], namev[i], allow_partial_matches) - : !e_utf8_casefold_collate (familyv[j], namev[i])) { - - this_part_match = E_CARD_MATCH_PART_FAMILY_NAME; - - g_free (familyv[j]); - familyv[j] = g_strdup (""); - break; - } - } - } - - if (this_part_match != E_CARD_MATCH_PART_NONE) { - ++match_count; - matched_character_count += g_utf8_strlen (namev[i], -1); - matched_parts |= this_part_match; - if (first_matched_part == E_CARD_MATCH_PART_NONE) - first_matched_part = this_part_match; - } - } - } - - match_type = E_CARD_MATCH_NONE; - - if (this_part_match != E_CARD_MATCH_PART_NONE) { - - if (match_count > 0) - match_type = E_CARD_MATCH_VAGUE; - - if (fragment_count == match_count) { - - match_type = E_CARD_MATCH_EXACT; - - } else if (fragment_count == match_count + 1) { - - match_type = E_CARD_MATCH_PARTIAL; - - } - } - - if (matched_parts_out) - *matched_parts_out = matched_parts; - if (first_matched_part_out) - *first_matched_part_out = first_matched_part; - if (matched_character_count_out) - *matched_character_count_out = matched_character_count; - - g_strfreev (namev); - g_strfreev (givenv); - g_strfreev (addv); - g_strfreev (familyv); - - return match_type; -} - -ECardMatchType -e_card_compare_name (ECard *card1, ECard *card2) -{ - ECardName *a, *b; - gint matches=0, possible=0; - gboolean given_match = FALSE, additional_match = FALSE, family_match = FALSE; - - g_return_val_if_fail (E_IS_CARD (card1), E_CARD_MATCH_NOT_APPLICABLE); - g_return_val_if_fail (E_IS_CARD (card2), E_CARD_MATCH_NOT_APPLICABLE); - - a = card1->name; - b = card2->name; - - if (a == NULL || b == NULL) - return E_CARD_MATCH_NOT_APPLICABLE; - - if (a->given && b->given) { - ++possible; - if (name_fragment_match_with_synonyms (a->given, b->given, FALSE /* both inputs are complete */)) { - ++matches; - given_match = TRUE; - } - } - - if (a->additional && b->additional) { - ++possible; - if (name_fragment_match_with_synonyms (a->additional, b->additional, FALSE /* both inputs are complete */)) { - ++matches; - additional_match = TRUE; - } - } - - if (a->family && b->family) { - ++possible; - /* We don't allow "loose matching" (i.e. John vs. Jon) on family names */ - if (! e_utf8_casefold_collate (a->family, b->family)) { - ++matches; - family_match = TRUE; - } - } - - /* Now look at the # of matches and try to intelligently map - an E_CARD_MATCH_* type to it. Special consideration is given - to family-name matches. */ - - if (possible == 0) - return E_CARD_MATCH_NOT_APPLICABLE; - - if (possible == 1) - return family_match ? E_CARD_MATCH_VAGUE : E_CARD_MATCH_NONE; - - if (possible == matches) - return family_match ? E_CARD_MATCH_EXACT : E_CARD_MATCH_PARTIAL; - - if (possible == matches+1) - return family_match ? E_CARD_MATCH_VAGUE : E_CARD_MATCH_NONE; - - return E_CARD_MATCH_NONE; -} - - -/*** Nickname Comparisons ***/ - -ECardMatchType -e_card_compare_nickname (ECard *card1, ECard *card2) -{ - g_return_val_if_fail (card1 && E_IS_CARD (card1), E_CARD_MATCH_NOT_APPLICABLE); - g_return_val_if_fail (card2 && E_IS_CARD (card2), E_CARD_MATCH_NOT_APPLICABLE); - - return E_CARD_MATCH_NOT_APPLICABLE; -} - - - -/*** E-mail Comparisons ***/ - -static gboolean -match_email_username (const gchar *addr1, const gchar *addr2) -{ - gint c1, c2; - if (addr1 == NULL || addr2 == NULL) - return FALSE; - - while (*addr1 && *addr2 && *addr1 != '@' && *addr2 != '@') { - c1 = isupper (*addr1) ? tolower (*addr1) : *addr1; - c2 = isupper (*addr2) ? tolower (*addr2) : *addr2; - if (c1 != c2) - return FALSE; - ++addr1; - ++addr2; - } - - return *addr1 == *addr2; -} - -static gboolean -match_email_hostname (const gchar *addr1, const gchar *addr2) -{ - gint c1, c2; - gboolean seen_at1, seen_at2; - if (addr1 == NULL || addr2 == NULL) - return FALSE; - - /* Walk to the end of each string. */ - seen_at1 = FALSE; - if (*addr1) { - while (*addr1) { - if (*addr1 == '@') - seen_at1 = TRUE; - ++addr1; - } - --addr1; - } - - seen_at2 = FALSE; - if (*addr2) { - while (*addr2) { - if (*addr2 == '@') - seen_at2 = TRUE; - ++addr2; - } - --addr2; - } - - if (!seen_at1 && !seen_at2) - return TRUE; - if (!seen_at1 || !seen_at2) - return FALSE; - - while (*addr1 != '@' && *addr2 != '@') { - c1 = isupper (*addr1) ? tolower (*addr1) : *addr1; - c2 = isupper (*addr2) ? tolower (*addr2) : *addr2; - if (c1 != c2) - return FALSE; - --addr1; - --addr2; - } - - /* This will match bob@foo.ximian.com and bob@ximian.com */ - return *addr1 == '.' || *addr2 == '.'; -} - -static ECardMatchType -compare_email_addresses (const gchar *addr1, const gchar *addr2) -{ - if (addr1 == NULL || *addr1 == 0 || - addr2 == NULL || *addr2 == 0) - return E_CARD_MATCH_NOT_APPLICABLE; - - if (match_email_username (addr1, addr2)) - return match_email_hostname (addr1, addr2) ? E_CARD_MATCH_EXACT : E_CARD_MATCH_VAGUE; - - return E_CARD_MATCH_NONE; -} - -ECardMatchType -e_card_compare_email (ECard *card1, ECard *card2) -{ - EIterator *i1, *i2; - ECardMatchType match = E_CARD_MATCH_NOT_APPLICABLE; - - g_return_val_if_fail (card1 && E_IS_CARD (card1), E_CARD_MATCH_NOT_APPLICABLE); - g_return_val_if_fail (card2 && E_IS_CARD (card2), E_CARD_MATCH_NOT_APPLICABLE); - - if (card1->email == NULL || card2->email == NULL) - return E_CARD_MATCH_NOT_APPLICABLE; - - i1 = e_list_get_iterator (card1->email); - i2 = e_list_get_iterator (card2->email); - - /* Do pairwise-comparisons on all of the e-mail addresses. If - we find an exact match, there is no reason to keep - checking. */ - e_iterator_reset (i1); - while (e_iterator_is_valid (i1) && match != E_CARD_MATCH_EXACT) { - const gchar *addr1 = (const gchar *) e_iterator_get (i1); - - e_iterator_reset (i2); - while (e_iterator_is_valid (i2) && match != E_CARD_MATCH_EXACT) { - const gchar *addr2 = (const gchar *) e_iterator_get (i2); - - match = combine_comparisons (match, compare_email_addresses (addr1, addr2)); - - e_iterator_next (i2); - } - - e_iterator_next (i1); - } - - g_object_unref (i1); - g_object_unref (i2); - - return match; -} - -ECardMatchType -e_card_compare_address (ECard *card1, ECard *card2) -{ - g_return_val_if_fail (card1 && E_IS_CARD (card1), E_CARD_MATCH_NOT_APPLICABLE); - g_return_val_if_fail (card2 && E_IS_CARD (card2), E_CARD_MATCH_NOT_APPLICABLE); - - /* Unimplemented */ - - return E_CARD_MATCH_NOT_APPLICABLE; -} - -ECardMatchType -e_card_compare_telephone (ECard *card1, ECard *card2) -{ - g_return_val_if_fail (card1 && E_IS_CARD (card1), E_CARD_MATCH_NOT_APPLICABLE); - g_return_val_if_fail (card2 && E_IS_CARD (card2), E_CARD_MATCH_NOT_APPLICABLE); - - /* Unimplemented */ - - return E_CARD_MATCH_NOT_APPLICABLE; -} - -ECardMatchType -e_card_compare (ECard *card1, ECard *card2) -{ - ECardMatchType result; - - g_return_val_if_fail (card1 && E_IS_CARD (card1), E_CARD_MATCH_NOT_APPLICABLE); - g_return_val_if_fail (card2 && E_IS_CARD (card2), E_CARD_MATCH_NOT_APPLICABLE); - - result = E_CARD_MATCH_NONE; - result = combine_comparisons (result, e_card_compare_name (card1, card2)); - result = combine_comparisons (result, e_card_compare_nickname (card1, card2)); - result = combine_comparisons (result, e_card_compare_email (card1, card2)); - result = combine_comparisons (result, e_card_compare_address (card1, card2)); - result = combine_comparisons (result, e_card_compare_telephone (card1, card2)); - - return result; -} - -typedef struct _MatchSearchInfo MatchSearchInfo; -struct _MatchSearchInfo { - ECard *card; - GList *avoid; - ECardMatchQueryCallback cb; - gpointer closure; -}; - -static void -match_search_info_free (MatchSearchInfo *info) -{ - if (info) { - g_object_unref (info->card); - - /* This should already have been deallocated, but just in case... */ - if (info->avoid) { - g_list_foreach (info->avoid, (GFunc) g_object_unref, NULL); - g_list_free (info->avoid); - info->avoid = NULL; - } - - g_free (info); - } -} - -static void -simple_query_cb (EBook *book, EBookSimpleQueryStatus status, const GList *cards, gpointer closure) -{ - MatchSearchInfo *info = (MatchSearchInfo *) closure; - ECardMatchType best_match = E_CARD_MATCH_NONE; - ECard *best_card = NULL; - GList *remaining_cards = NULL; - const GList *i; - - if (status != E_BOOK_SIMPLE_QUERY_STATUS_SUCCESS) { - info->cb (info->card, NULL, E_CARD_MATCH_NONE, info->closure); - match_search_info_free (info); - return; - } - - /* remove the cards we're to avoid from the list, if they're present */ - for (i = cards; i != NULL; i = g_list_next (i)) { - ECard *this_card = E_CARD (i->data); - GList *iterator; - gboolean avoid = FALSE; - for (iterator = info->avoid; iterator; iterator = iterator->next) { - if (!strcmp (e_card_get_id (iterator->data), e_card_get_id (this_card))) { - avoid = TRUE; - break; - } - } - if (!avoid) - remaining_cards = g_list_prepend (remaining_cards, this_card); - } - - remaining_cards = g_list_reverse (remaining_cards); - - for (i = remaining_cards; i != NULL; i = g_list_next (i)) { - ECard *this_card = E_CARD (i->data); - ECardMatchType this_match = e_card_compare (info->card, this_card); - if ((gint)this_match > (gint)best_match) { - best_match = this_match; - best_card = this_card; - } - } - - g_list_free (remaining_cards); - - info->cb (info->card, best_card, best_match, info->closure); - match_search_info_free (info); -} - -#define MAX_QUERY_PARTS 10 -static void -use_common_book_cb (EBook *book, gpointer closure) -{ - MatchSearchInfo *info = (MatchSearchInfo *) closure; - ECard *card = info->card; - gchar *query_parts[MAX_QUERY_PARTS]; - gint p=0; - gchar *query, *qj; - int i; - - if (book == NULL) { - info->cb (info->card, NULL, E_CARD_MATCH_NONE, info->closure); - match_search_info_free (info); - return; - } - -#if 0 - if (card->nickname && *card->nickname) - query_parts[p++] = g_strdup_printf ("(beginswith \"nickname\" \"%s\")", card->nickname); -#endif - - if (card->name->given && strlen (card->name->given) > 1) - query_parts[p++] = g_strdup_printf ("(contains \"full_name\" \"%s\")", card->name->given); - - if (card->name->additional && strlen (card->name->additional) > 1) - query_parts[p++] = g_strdup_printf ("(contains \"full_name\" \"%s\")", card->name->additional); - - if (card->name->family && strlen (card->name->family) > 1) - query_parts[p++] = g_strdup_printf ("(contains \"full_name\" \"%s\")", card->name->family); - - - if (card->email) { - EIterator *iter = e_list_get_iterator (card->email); - while (e_iterator_is_valid (iter) && p < MAX_QUERY_PARTS) { - gchar *addr = g_strdup (e_iterator_get (iter)); - if (addr && *addr) { - gchar *s = addr; - while (*s) { - if (*s == '@') { - *s = '\0'; - break; - } - ++s; - } - query_parts[p++] = g_strdup_printf ("(beginswith \"email\" \"%s\")", addr); - g_free (addr); - } - e_iterator_next (iter); - } - } - - - - /* Build up our full query from the parts. */ - query_parts[p] = NULL; - qj = g_strjoinv (" ", query_parts); - for(i = 0; query_parts[i] != NULL; i++) - g_free(query_parts[i]); - if (p > 0) { - query = g_strdup_printf ("(or %s)", qj); - g_free (qj); - } else { - query = qj; - } - - e_book_simple_query (book, query, simple_query_cb, info); - - g_free (query); -} - -void -e_card_locate_match (ECard *card, ECardMatchQueryCallback cb, gpointer closure) -{ - MatchSearchInfo *info; - - g_return_if_fail (card && E_IS_CARD (card)); - g_return_if_fail (cb != NULL); - - info = g_new (MatchSearchInfo, 1); - info->card = card; - g_object_ref (card); - info->cb = cb; - info->closure = closure; - info->avoid = NULL; - - e_book_use_default_book (use_common_book_cb, info); -} - -/** - * e_card_locate_match_full: - * @book: The book to look in. If this is NULL, use the default - * addressbook. - * @card: The card to compare to. - * @avoid: A list of cards to not match. These will not show up in the search. - * @cb: The function to call. - * @closure: The closure to add to the call. - * - * Look for the best match and return it using the ECardMatchQueryCallback. - **/ -void -e_card_locate_match_full (EBook *book, ECard *card, GList *avoid, ECardMatchQueryCallback cb, gpointer closure) -{ - MatchSearchInfo *info; - - g_return_if_fail (card && E_IS_CARD (card)); - g_return_if_fail (cb != NULL); - - info = g_new (MatchSearchInfo, 1); - info->card = card; - g_object_ref (card); - info->cb = cb; - info->closure = closure; - info->avoid = g_list_copy (avoid); - g_list_foreach (info->avoid, (GFunc) g_object_ref, NULL); - - if (book) - use_common_book_cb (book, info); - else - e_book_use_default_book (use_common_book_cb, info); -} - diff --git a/addressbook/backend/ebook/e-card-compare.h b/addressbook/backend/ebook/e-card-compare.h deleted file mode 100644 index 07ccb54e89..0000000000 --- a/addressbook/backend/ebook/e-card-compare.h +++ /dev/null @@ -1,72 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -/* - * e-card-compare.h - * - * Copyright (C) 2001 Ximian, Inc. - * - * Developed by Jon Trowbridge <trow@ximian.com> - */ - -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA. - */ - -#ifndef __E_CARD_COMPARE_H__ -#define __E_CARD_COMPARE_H__ - -#include "e-book.h" -#include "e-card.h" - -typedef enum { - E_CARD_MATCH_NOT_APPLICABLE = 0, - E_CARD_MATCH_NONE = 1, - E_CARD_MATCH_VAGUE = 2, - E_CARD_MATCH_PARTIAL = 3, - E_CARD_MATCH_EXACT = 4 -} ECardMatchType; - -typedef enum { - E_CARD_MATCH_PART_NOT_APPLICABLE = -1, - E_CARD_MATCH_PART_NONE = 0, - E_CARD_MATCH_PART_GIVEN_NAME = 1<<0, - E_CARD_MATCH_PART_ADDITIONAL_NAME = 1<<2, - E_CARD_MATCH_PART_FAMILY_NAME = 1<<3 -} ECardMatchPart; - -typedef void (*ECardMatchQueryCallback) (ECard *card, ECard *match, ECardMatchType type, gpointer closure); - -ECardMatchType e_card_compare_name_to_string (ECard *card, const gchar *str); - -ECardMatchType e_card_compare_name_to_string_full (ECard *card, const gchar *str, - gboolean allow_partial_matches, - gint *matched_parts, ECardMatchPart *first_matched_part, - gint *matched_character_count); - -ECardMatchType e_card_compare_name (ECard *card1, ECard *card2); -ECardMatchType e_card_compare_nickname (ECard *card1, ECard *card2); -ECardMatchType e_card_compare_email (ECard *card1, ECard *card2); -ECardMatchType e_card_compare_address (ECard *card1, ECard *card2); -ECardMatchType e_card_compare_telephone (ECard *card1, ECard *card2); - -ECardMatchType e_card_compare (ECard *card1, ECard *card2); - -void e_card_locate_match (ECard *card, ECardMatchQueryCallback cb, gpointer closure); -void e_card_locate_match_full (EBook *book, ECard *card, GList *avoid, ECardMatchQueryCallback cb, gpointer closure); - - - -#endif /* __E_CARD_COMPARE_H__ */ - diff --git a/addressbook/backend/ebook/e-card-cursor.c b/addressbook/backend/ebook/e-card-cursor.c deleted file mode 100644 index 0aa9c8c1e0..0000000000 --- a/addressbook/backend/ebook/e-card-cursor.c +++ /dev/null @@ -1,239 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * e-card-cursor.c: Implements card cursors. - * - * Author: - * Christopher James Lahey <clahey@ximian.com. - */ - -#include <config.h> -#include "addressbook.h" -#include "e-card-cursor.h" - -struct _ECardCursorPrivate { - GNOME_Evolution_Addressbook_CardCursor corba_cursor; -}; - -/* - * A pointer to our parent object class - */ -static GObjectClass *parent_class; - -/* - * Implemented GObject::dispose - */ -static void -e_card_cursor_dispose (GObject *object) -{ - ECardCursor *cursor = E_CARD_CURSOR (object); - - if (cursor->priv) { - CORBA_Environment ev; - - CORBA_exception_init (&ev); - - GNOME_Evolution_Addressbook_CardCursor_unref( cursor->priv->corba_cursor, &ev ); - - if (ev._major != CORBA_NO_EXCEPTION) { - g_warning("e_card_cursor_destroy: Exception unreffing " - "corba cursor.\n"); - CORBA_exception_free (&ev); - CORBA_exception_init (&ev); - } - - CORBA_Object_release (cursor->priv->corba_cursor, &ev); - - if (ev._major != CORBA_NO_EXCEPTION) { - g_warning("e_card_cursor_destroy: Exception releasing " - "corba cursor.\n"); - } - - CORBA_exception_free (&ev); - - g_free ( cursor->priv ); - cursor->priv = NULL; - } - - if (G_OBJECT_CLASS (parent_class)->dispose) - G_OBJECT_CLASS (parent_class)->dispose (object); -} - -/** - * e_card_cursor_get_length: - * @cursor: the #ECardCursor whose length is being queried - * - * Returns: the number of items the cursor references, or -1 there's - * an error. - */ -long -e_card_cursor_get_length (ECardCursor *cursor) -{ - if ( cursor->priv->corba_cursor != CORBA_OBJECT_NIL ) { - CORBA_Environment ev; - long ret_val; - - CORBA_exception_init (&ev); - - ret_val = GNOME_Evolution_Addressbook_CardCursor_count (cursor->priv->corba_cursor, &ev); - - if (ev._major != CORBA_NO_EXCEPTION) { - g_warning("e_card_cursor_get_length: Exception during " - "get_length corba call.\n"); - ret_val = -1; - } - - CORBA_exception_free (&ev); - - return ret_val; - } - else - return -1; -} - -/** - * e_card_cursor_get_nth: - * @cursor: an #ECardCursor object - * @n: the index of the item requested - * - * Gets an #ECard based on an index. - * - * Returns: a new #ECard on success, or %NULL on failure. - */ -ECard * -e_card_cursor_get_nth (ECardCursor *cursor, - const long n) -{ - if ( cursor->priv->corba_cursor != CORBA_OBJECT_NIL ) { - CORBA_Environment en; - CORBA_char *vcard; - ECard *card; - - CORBA_exception_init (&en); - - vcard = GNOME_Evolution_Addressbook_CardCursor_getNth(cursor->priv->corba_cursor, n, &en); - - if (en._major != CORBA_NO_EXCEPTION) { - g_warning("e_card_cursor_get_nth: Exception during " - "get_nth corba call.\n"); - } - - CORBA_exception_free (&en); - - card = e_card_new (vcard); - - CORBA_free(vcard); - - return card; - } - else - return e_card_new(""); -} - -static void -e_card_cursor_class_init (ECardCursorClass *klass) -{ - GObjectClass *object_class = (GObjectClass *) klass; - - parent_class = g_type_class_ref (G_TYPE_OBJECT); - - object_class->dispose = e_card_cursor_dispose; -} - -static void -e_card_cursor_init (ECardCursor *cursor) -{ - cursor->priv = g_new(ECardCursorPrivate, 1); - cursor->priv->corba_cursor = CORBA_OBJECT_NIL; -} - -GType -e_card_cursor_get_type (void) -{ - static GType type = 0; - - if (!type){ - static const GTypeInfo info = { - sizeof (ECardCursorClass), - NULL, /* base_init */ - NULL, /* base_finalize */ - (GClassInitFunc) e_card_cursor_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (ECardCursor), - 0, /* n_preallocs */ - (GInstanceInitFunc) e_card_cursor_init, - }; - - type = g_type_register_static (G_TYPE_OBJECT, "ECardCursor", &info, 0); - } - - return type; -} - -/** - * e_card_cursor_construct: - * @cursor: an #ECardCursor object - * @corba_cursor: an #GNOME_Evolution_Addressbook_CardCursor - * - * Wraps an #GNOME_Evolution_Addressbook_CardCursor object inside the #ECardCursor - * @cursor object. - * - * Returns: a new #ECardCursor on success, or %NULL on failure. - */ -ECardCursor * -e_card_cursor_construct (ECardCursor *cursor, - GNOME_Evolution_Addressbook_CardCursor corba_cursor) -{ - CORBA_Environment ev; - g_return_val_if_fail (cursor != NULL, NULL); - g_return_val_if_fail (E_IS_CARD_CURSOR (cursor), NULL); - g_return_val_if_fail (corba_cursor != CORBA_OBJECT_NIL, NULL); - - CORBA_exception_init (&ev); - - /* - * Initialize cursor - */ - cursor->priv->corba_cursor = CORBA_Object_duplicate(corba_cursor, &ev); - - if (ev._major != CORBA_NO_EXCEPTION) { - g_warning("e_card_cursor_construct: Exception duplicating " - "corba cursor.\n"); - CORBA_exception_free (&ev); - CORBA_exception_init (&ev); - } - - GNOME_Evolution_Addressbook_CardCursor_ref(cursor->priv->corba_cursor, &ev); - - if (ev._major != CORBA_NO_EXCEPTION) { - g_warning("e_card_cursor_construct: Exception reffing " - "corba cursor.\n"); - } - - CORBA_exception_free (&ev); - - /* - * Success: return the GType we were given - */ - return cursor; -} - -/** - * e_card_cursor_new: - * @cursor: the #GNOME_Evolution_Addressbook_CardCursor to be wrapped - * - * Creates a new #ECardCursor, which wraps an #GNOME_Evolution_Addressbook_CardCursor - * object. - * - * Returns: a new #ECardCursor on success, or %NULL on failure. - */ -ECardCursor * -e_card_cursor_new (GNOME_Evolution_Addressbook_CardCursor corba_cursor) -{ - ECardCursor *cursor; - - cursor = g_object_new (E_TYPE_CARD_CURSOR, NULL); - - return e_card_cursor_construct (cursor, - corba_cursor); -} diff --git a/addressbook/backend/ebook/e-card-cursor.h b/addressbook/backend/ebook/e-card-cursor.h deleted file mode 100644 index b8da39f023..0000000000 --- a/addressbook/backend/ebook/e-card-cursor.h +++ /dev/null @@ -1,53 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * - * Author: - * Nat Friedman (nat@ximian.com) - * - * Copyright 2000, Ximian, Inc. - */ - -#ifndef __E_CARD_CURSOR_H__ -#define __E_CARD_CURSOR_H__ - -#include <glib.h> -#include <glib-object.h> -#include <ebook/addressbook.h> -#include <ebook/e-card.h> - -#define E_TYPE_CARD_CURSOR (e_card_cursor_get_type ()) -#define E_CARD_CURSOR(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), E_TYPE_CARD_CURSOR, ECardCursor)) -#define E_CARD_CURSOR_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), E_TYPE_CARD_CURSOR, ECardCursorClass)) -#define E_IS_CARD_CURSOR(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), E_TYPE_CARD_CURSOR)) -#define E_IS_CARD_CURSOR_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), E_TYPE_CARD_CURSOR)) -#define E_CARD_CURSOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), E_TYPE_CARD_CURSOR, ECardCursorClass)) - -G_BEGIN_DECLS - -typedef struct _ECardCursor ECardCursor; -typedef struct _ECardCursorPrivate ECardCursorPrivate; -typedef struct _ECardCursorClass ECardCursorClass; - -struct _ECardCursor { - GObject parent; - ECardCursorPrivate *priv; -}; - -struct _ECardCursorClass { - GObjectClass parent; -}; - -/* Creating a new addressbook. */ -ECardCursor *e_card_cursor_new (GNOME_Evolution_Addressbook_CardCursor corba_cursor); -ECardCursor *e_card_cursor_construct (ECardCursor *cursor, - GNOME_Evolution_Addressbook_CardCursor corba_cursor); - -GType e_card_cursor_get_type (void); - -/* Fetching cards. */ -long e_card_cursor_get_length (ECardCursor *cursor); -ECard *e_card_cursor_get_nth (ECardCursor *cursor, - const long nth); -G_END_DECLS - -#endif /* ! __E_CARD_CURSOR_H__ */ diff --git a/addressbook/backend/ebook/e-card-pairs.h b/addressbook/backend/ebook/e-card-pairs.h deleted file mode 100644 index f82f948ebb..0000000000 --- a/addressbook/backend/ebook/e-card-pairs.h +++ /dev/null @@ -1,118 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* GnomeCard - a graphical contact manager. - * - * pairs.h: This file is part of GnomeCard. - * - * Copyright (C) 1999 The Free Software Foundation - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef __E_CARD_PAIRS_H__ -#define __E_CARD_PAIRS_H__ - -#include <libversit/vcc.h> -#include <ebook/e-card.h> - - -#if 0 -struct pair -{ - char *str; - ECardPropertyType i ; -}; - -struct pair prop_lookup[] = { - { VCFullNameProp, PROP_FNAME }, - { VCNameProp, PROP_NAME }, - { VCPhotoProp, PROP_PHOTO }, - { VCBirthDateProp, PROP_BDAY }, - { VCAdrProp, PROP_DELADDR }, - { VCDeliveryLabelProp, PROP_DELLABEL }, - { VCTelephoneProp, PROP_PHONE }, - { VCEmailAddressProp, PROP_EMAIL }, - { VCMailerProp, PROP_MAILER }, - { VCTimeZoneProp, PROP_TIMEZN }, - { VCGeoProp, PROP_GEOPOS }, - { VCTitleProp, PROP_TITLE }, - { VCBusinessRoleProp, PROP_ROLE }, - { VCLogoProp, PROP_LOGO }, - { VCAgentProp, PROP_AGENT }, - { VCOrgProp, PROP_ORG }, - { VCCategoriesProp, PROP_CATEGORIES }, - { VCCommentProp, PROP_COMMENT }, - { VCLastRevisedProp, PROP_REV }, - { VCPronunciationProp, PROP_SOUND }, - { VCURLProp, PROP_URL }, - { VCUniqueStringProp, PROP_UID }, - { VCVersionProp, PROP_VERSION }, - { VCPublicKeyProp, PROP_KEY }, - { VCValueProp, PROP_VALUE }, - { VCEncodingProp, PROP_ENCODING }, - { VCQuotedPrintableProp, PROP_QUOTED_PRINTABLE }, - { VC8bitProp, PROP_8BIT }, - { VCBase64Prop, PROP_BASE64 }, - { VCLanguageProp, PROP_LANG }, - { VCCharSetProp, PROP_CHARSET }, - { NULL, PROP_NONE} }; - -struct pair photo_pairs[] = { - { VCGIFProp, PHOTO_GIF }, - { VCCGMProp, PHOTO_CGM }, - { VCWMFProp, PHOTO_WMF }, - { VCBMPProp, PHOTO_BMP }, - { VCMETProp, PHOTO_MET }, - { VCPMBProp, PHOTO_PMB }, - { VCDIBProp, PHOTO_DIB }, - { VCPICTProp, PHOTO_PICT }, - { VCTIFFProp, PHOTO_TIFF }, - { VCPDFProp, PHOTO_PDF }, - { VCPSProp, PHOTO_PS }, - { VCJPEGProp, PHOTO_JPEG }, - { VCMPEGProp, PHOTO_MPEG }, - { VCMPEG2Prop, PHOTO_MPEG2 }, - { VCAVIProp, PHOTO_AVI }, - { VCQuickTimeProp, PHOTO_QTIME }, - { NULL, 0 } }; - -struct pair email_pairs[] = { - { VCAOLProp, EMAIL_AOL }, - { VCAppleLinkProp, EMAIL_APPLE_LINK }, - { VCATTMailProp, EMAIL_ATT }, - { VCCISProp, EMAIL_CIS }, - { VCEWorldProp, EMAIL_EWORLD }, - { VCInternetProp, EMAIL_INET }, - { VCIBMMailProp, EMAIL_IBM }, - { VCMCIMailProp, EMAIL_MCI }, - { VCPowerShareProp, EMAIL_POWERSHARE }, - { VCProdigyProp, EMAIL_PRODIGY }, - { VCTLXProp, EMAIL_TLX }, - { VCX400Prop, EMAIL_X400 }, - { NULL, 0 } }; - -struct pair sound_pairs[] = { - { VCAIFFProp, SOUND_AIFF }, - { VCPCMProp, SOUND_PCM }, - { VCWAVEProp, SOUND_WAVE }, - { NULL, 0 } }; - -struct pair key_pairs[] = { - { VCX509Prop, KEY_X509 }, - { VCPGPProp, KEY_PGP }, - { NULL, 0 } }; - - -#endif -#endif /* ! __E_CARD_PAIRS_H__ */ diff --git a/addressbook/backend/ebook/e-card-simple.c b/addressbook/backend/ebook/e-card-simple.c deleted file mode 100644 index b9e32762fe..0000000000 --- a/addressbook/backend/ebook/e-card-simple.c +++ /dev/null @@ -1,1344 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * Authors: - * Chris Lahey <clahey@ximian.com> - * Arturo Espinosa (arturo@nuclecu.unam.mx) - * Nat Friedman (nat@ximian.com) - * - * Copyright (C) 2000 Ximian, Inc. - * Copyright (C) 1999 The Free Software Foundation - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <bonobo/bonobo-i18n.h> -#include <gal/util/e-util.h> - -#include <libversit/vcc.h> -#include "e-card-simple.h" - -/* Object property IDs */ -enum { - PROP_0, - PROP_CARD, -}; - -static GObjectClass *parent_class; - -typedef enum _ECardSimpleInternalType ECardSimpleInternalType; -typedef struct _ECardSimpleFieldData ECardSimpleFieldData; - -enum _ECardSimpleInternalType { - E_CARD_SIMPLE_INTERNAL_TYPE_STRING, - E_CARD_SIMPLE_INTERNAL_TYPE_DATE, - E_CARD_SIMPLE_INTERNAL_TYPE_ADDRESS, - E_CARD_SIMPLE_INTERNAL_TYPE_PHONE, - E_CARD_SIMPLE_INTERNAL_TYPE_EMAIL, - E_CARD_SIMPLE_INTERNAL_TYPE_SPECIAL, - E_CARD_SIMPLE_INTERNAL_TYPE_BOOL, -}; - -struct _ECardSimpleFieldData { - ECardSimpleField field; - char *ecard_field; - char *name; - char *short_name; - int list_type_index; - ECardSimpleInternalType type; -}; - -/* This order must match the order in the .h. */ - -/* the ecard_field data below should only be used for TYPE_STRING, - TYPE_DATE, and TYPE_SPECIAL fields. that is, it's only valid for - e-cards for those types. it is used as a unique name for fields - for the get_supported functionality. */ -static ECardSimpleFieldData field_data[] = -{ - { E_CARD_SIMPLE_FIELD_FILE_AS, "file_as", N_("File As"), "", 0, E_CARD_SIMPLE_INTERNAL_TYPE_STRING }, - { E_CARD_SIMPLE_FIELD_FULL_NAME, "full_name", N_("Name"), N_("Name"), 0, E_CARD_SIMPLE_INTERNAL_TYPE_STRING }, - { E_CARD_SIMPLE_FIELD_EMAIL, "email", N_("Email"), N_("Email"), E_CARD_SIMPLE_EMAIL_ID_EMAIL, E_CARD_SIMPLE_INTERNAL_TYPE_EMAIL }, - { E_CARD_SIMPLE_FIELD_PHONE_PRIMARY, "primary_phone", N_("Primary"), N_("Prim"), E_CARD_SIMPLE_PHONE_ID_PRIMARY, E_CARD_SIMPLE_INTERNAL_TYPE_PHONE }, - { E_CARD_SIMPLE_FIELD_PHONE_ASSISTANT, "assistant_phone", N_("Assistant"), N_("Assistant"),E_CARD_SIMPLE_PHONE_ID_ASSISTANT, E_CARD_SIMPLE_INTERNAL_TYPE_PHONE }, - { E_CARD_SIMPLE_FIELD_PHONE_BUSINESS, "business_phone", N_("Business"), N_("Bus"), E_CARD_SIMPLE_PHONE_ID_BUSINESS, E_CARD_SIMPLE_INTERNAL_TYPE_PHONE }, - { E_CARD_SIMPLE_FIELD_PHONE_CALLBACK, "callback_phone", N_("Callback"), N_("Callback"), E_CARD_SIMPLE_PHONE_ID_CALLBACK, E_CARD_SIMPLE_INTERNAL_TYPE_PHONE }, - { E_CARD_SIMPLE_FIELD_PHONE_COMPANY, "company_phone", N_("Company"), N_("Comp"), E_CARD_SIMPLE_PHONE_ID_COMPANY, E_CARD_SIMPLE_INTERNAL_TYPE_PHONE }, - { E_CARD_SIMPLE_FIELD_PHONE_HOME, "home_phone", N_("Home"), N_("Home"), E_CARD_SIMPLE_PHONE_ID_HOME, E_CARD_SIMPLE_INTERNAL_TYPE_PHONE }, - { E_CARD_SIMPLE_FIELD_ORG, "org", N_("Organization"), N_("Org"), 0, E_CARD_SIMPLE_INTERNAL_TYPE_STRING }, - { E_CARD_SIMPLE_FIELD_ADDRESS_BUSINESS, "business_address",N_("Business"), N_("Bus"), E_CARD_SIMPLE_ADDRESS_ID_BUSINESS, E_CARD_SIMPLE_INTERNAL_TYPE_ADDRESS }, - { E_CARD_SIMPLE_FIELD_ADDRESS_HOME, "home_address", N_("Home"), N_("Home"), E_CARD_SIMPLE_ADDRESS_ID_HOME, E_CARD_SIMPLE_INTERNAL_TYPE_ADDRESS }, - { E_CARD_SIMPLE_FIELD_PHONE_MOBILE, "mobile_phone", N_("Mobile"), N_("Mobile"), E_CARD_SIMPLE_PHONE_ID_MOBILE, E_CARD_SIMPLE_INTERNAL_TYPE_PHONE }, - { E_CARD_SIMPLE_FIELD_PHONE_CAR, "car_phone", N_("Car"), N_("Car"), E_CARD_SIMPLE_PHONE_ID_CAR, E_CARD_SIMPLE_INTERNAL_TYPE_PHONE }, - { E_CARD_SIMPLE_FIELD_PHONE_BUSINESS_FAX, "business_fax", N_("Business Fax"), N_("Bus Fax"), E_CARD_SIMPLE_PHONE_ID_BUSINESS_FAX, E_CARD_SIMPLE_INTERNAL_TYPE_PHONE }, - { E_CARD_SIMPLE_FIELD_PHONE_HOME_FAX, "home_fax", N_("Home Fax"), N_("Home Fax"), E_CARD_SIMPLE_PHONE_ID_HOME_FAX, E_CARD_SIMPLE_INTERNAL_TYPE_PHONE }, - { E_CARD_SIMPLE_FIELD_PHONE_BUSINESS_2, "business_phone_2",N_("Business 2"), N_("Bus 2"), E_CARD_SIMPLE_PHONE_ID_BUSINESS_2, E_CARD_SIMPLE_INTERNAL_TYPE_PHONE }, - { E_CARD_SIMPLE_FIELD_PHONE_HOME_2, "home_phone_2", N_("Home 2"), N_("Home 2"), E_CARD_SIMPLE_PHONE_ID_HOME_2, E_CARD_SIMPLE_INTERNAL_TYPE_PHONE }, - { E_CARD_SIMPLE_FIELD_PHONE_ISDN, "isdn", N_("ISDN"), N_("ISDN"), E_CARD_SIMPLE_PHONE_ID_ISDN, E_CARD_SIMPLE_INTERNAL_TYPE_PHONE }, - { E_CARD_SIMPLE_FIELD_PHONE_OTHER, "other_phone", N_("Other"), N_("Other"), E_CARD_SIMPLE_PHONE_ID_OTHER, E_CARD_SIMPLE_INTERNAL_TYPE_PHONE }, - { E_CARD_SIMPLE_FIELD_PHONE_OTHER_FAX, "other_fax", N_("Other Fax"), N_("Other Fax"), E_CARD_SIMPLE_PHONE_ID_OTHER_FAX, E_CARD_SIMPLE_INTERNAL_TYPE_PHONE }, - { E_CARD_SIMPLE_FIELD_PHONE_PAGER, "pager", N_("Pager"), N_("Pager"), E_CARD_SIMPLE_PHONE_ID_PAGER, E_CARD_SIMPLE_INTERNAL_TYPE_PHONE }, - { E_CARD_SIMPLE_FIELD_PHONE_RADIO, "radio", N_("Radio"), N_("Radio"), E_CARD_SIMPLE_PHONE_ID_RADIO, E_CARD_SIMPLE_INTERNAL_TYPE_PHONE }, - { E_CARD_SIMPLE_FIELD_PHONE_TELEX, "telex", N_("Telex"), N_("Telex"), E_CARD_SIMPLE_PHONE_ID_TELEX, E_CARD_SIMPLE_INTERNAL_TYPE_PHONE }, - { E_CARD_SIMPLE_FIELD_PHONE_TTYTDD, "tty", N_("TTY"), N_("TTY"), E_CARD_SIMPLE_PHONE_ID_TTYTDD, E_CARD_SIMPLE_INTERNAL_TYPE_PHONE }, - { E_CARD_SIMPLE_FIELD_ADDRESS_OTHER, "other_address", N_("Other"), N_("Other"), E_CARD_SIMPLE_ADDRESS_ID_OTHER, E_CARD_SIMPLE_INTERNAL_TYPE_ADDRESS }, - { E_CARD_SIMPLE_FIELD_EMAIL_2, "email_2", N_("Email 2"), N_("Email 2"), E_CARD_SIMPLE_EMAIL_ID_EMAIL_2, E_CARD_SIMPLE_INTERNAL_TYPE_EMAIL }, - { E_CARD_SIMPLE_FIELD_EMAIL_3, "email_3", N_("Email 3"), N_("Email 3"), E_CARD_SIMPLE_EMAIL_ID_EMAIL_3, E_CARD_SIMPLE_INTERNAL_TYPE_EMAIL }, - { E_CARD_SIMPLE_FIELD_URL, "url", N_("Web Site"), N_("Url"), 0, E_CARD_SIMPLE_INTERNAL_TYPE_STRING }, - { E_CARD_SIMPLE_FIELD_ORG_UNIT, "org_unit", N_("Department"), N_("Dep"), 0, E_CARD_SIMPLE_INTERNAL_TYPE_STRING }, - { E_CARD_SIMPLE_FIELD_OFFICE, "office", N_("Office"), N_("Off"), 0, E_CARD_SIMPLE_INTERNAL_TYPE_STRING }, - { E_CARD_SIMPLE_FIELD_TITLE, "title", N_("Title"), N_("Title"), 0, E_CARD_SIMPLE_INTERNAL_TYPE_STRING }, - { E_CARD_SIMPLE_FIELD_ROLE, "role", N_("Profession"), N_("Prof"), 0, E_CARD_SIMPLE_INTERNAL_TYPE_STRING }, - { E_CARD_SIMPLE_FIELD_MANAGER, "manager", N_("Manager"), N_("Man"), 0, E_CARD_SIMPLE_INTERNAL_TYPE_STRING }, - { E_CARD_SIMPLE_FIELD_ASSISTANT, "assistant", N_("Assistant"), N_("Ass"), 0, E_CARD_SIMPLE_INTERNAL_TYPE_STRING }, - { E_CARD_SIMPLE_FIELD_NICKNAME, "nickname", N_("Nickname"), N_("Nick"), 0, E_CARD_SIMPLE_INTERNAL_TYPE_STRING }, - { E_CARD_SIMPLE_FIELD_SPOUSE, "spouse", N_("Spouse"), N_("Spouse"), 0, E_CARD_SIMPLE_INTERNAL_TYPE_STRING }, - { E_CARD_SIMPLE_FIELD_NOTE, "note", N_("Note"), N_("Note"), 0, E_CARD_SIMPLE_INTERNAL_TYPE_STRING }, - { E_CARD_SIMPLE_FIELD_CALURI, "caluri", N_("Calendar URI"), N_("CALUri"), 0, E_CARD_SIMPLE_INTERNAL_TYPE_STRING }, - { E_CARD_SIMPLE_FIELD_FBURL, "fburl", N_("Free-busy URL"), N_("FBUrl"), 0, E_CARD_SIMPLE_INTERNAL_TYPE_STRING }, - { E_CARD_SIMPLE_FIELD_ICSCALENDAR, "icscalendar", N_("Default server calendar"), N_("icsCalendar"), 0, E_CARD_SIMPLE_INTERNAL_TYPE_STRING }, - { E_CARD_SIMPLE_FIELD_ANNIVERSARY, "anniversary", N_("Anniversary"), N_("Anniv"), 0, E_CARD_SIMPLE_INTERNAL_TYPE_DATE }, - { E_CARD_SIMPLE_FIELD_BIRTH_DATE, "birth_date", N_("Birth Date"), "", 0, E_CARD_SIMPLE_INTERNAL_TYPE_DATE }, - { E_CARD_SIMPLE_FIELD_MAILER, "mailer", "", "", 0, E_CARD_SIMPLE_INTERNAL_TYPE_STRING }, - { E_CARD_SIMPLE_FIELD_NAME_OR_ORG, "nameororg", "", "", 0, E_CARD_SIMPLE_INTERNAL_TYPE_SPECIAL }, - { E_CARD_SIMPLE_FIELD_CATEGORIES, "categories", N_("Categories"), N_("Categories"), 0, E_CARD_SIMPLE_INTERNAL_TYPE_STRING }, - { E_CARD_SIMPLE_FIELD_FAMILY_NAME, "family_name", N_("Family Name"), N_("Family Name"), 0, E_CARD_SIMPLE_INTERNAL_TYPE_SPECIAL }, - { E_CARD_SIMPLE_FIELD_GIVEN_NAME, "given_name", "Given Name", "Given Name", 0, E_CARD_SIMPLE_INTERNAL_TYPE_SPECIAL }, - { E_CARD_SIMPLE_FIELD_ADDITIONAL_NAME, "additional_name", "Additional Name", "Additional Name", 0, E_CARD_SIMPLE_INTERNAL_TYPE_SPECIAL }, - { E_CARD_SIMPLE_FIELD_NAME_SUFFIX, "name_suffix", "Name Suffix", "Name Suffix", 0, E_CARD_SIMPLE_INTERNAL_TYPE_SPECIAL }, - { E_CARD_SIMPLE_FIELD_WANTS_HTML, "wants_html", "Wants HTML", "Wants HTML", 0, E_CARD_SIMPLE_INTERNAL_TYPE_BOOL }, - { E_CARD_SIMPLE_FIELD_IS_LIST, "list", "Is List", "Is List", 0, E_CARD_SIMPLE_INTERNAL_TYPE_BOOL }, -}; -static int field_data_count = sizeof (field_data) / sizeof (field_data[0]); - -static void e_card_simple_init (ECardSimple *simple); -static void e_card_simple_class_init (ECardSimpleClass *klass); - -static void e_card_simple_dispose (GObject *object); -static void e_card_simple_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec); -static void e_card_simple_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec); - -static void fill_in_info(ECardSimple *simple); - -ECardPhoneFlags phone_correspondences[] = { - E_CARD_PHONE_ASSISTANT, /* E_CARD_SIMPLE_PHONE_ID_ASSISTANT, */ - E_CARD_PHONE_WORK | E_CARD_PHONE_VOICE, /* E_CARD_SIMPLE_PHONE_ID_BUSINESS, */ - E_CARD_PHONE_WORK | E_CARD_PHONE_VOICE, /* E_CARD_SIMPLE_PHONE_ID_BUSINESS_2, */ - E_CARD_PHONE_WORK | E_CARD_PHONE_FAX, /* E_CARD_SIMPLE_PHONE_ID_BUSINESS_FAX, */ - E_CARD_PHONE_CALLBACK, /* E_CARD_SIMPLE_PHONE_ID_CALLBACK, */ - E_CARD_PHONE_CAR, /* E_CARD_SIMPLE_PHONE_ID_CAR, */ - E_CARD_PHONE_WORK, /* E_CARD_SIMPLE_PHONE_ID_COMPANY, */ - E_CARD_PHONE_HOME, /* E_CARD_SIMPLE_PHONE_ID_HOME, */ - E_CARD_PHONE_HOME, /* E_CARD_SIMPLE_PHONE_ID_HOME_2, */ - E_CARD_PHONE_HOME | E_CARD_PHONE_FAX, /* E_CARD_SIMPLE_PHONE_ID_HOME_FAX, */ - E_CARD_PHONE_ISDN, /* E_CARD_SIMPLE_PHONE_ID_ISDN, */ - E_CARD_PHONE_CELL, /* E_CARD_SIMPLE_PHONE_ID_MOBILE, */ - E_CARD_PHONE_VOICE, /* E_CARD_SIMPLE_PHONE_ID_OTHER, */ - E_CARD_PHONE_FAX, /* E_CARD_SIMPLE_PHONE_ID_OTHER_FAX, */ - E_CARD_PHONE_PAGER, /* E_CARD_SIMPLE_PHONE_ID_PAGER, */ - E_CARD_PHONE_PREF, /* E_CARD_SIMPLE_PHONE_ID_PRIMARY, */ - E_CARD_PHONE_RADIO, /* E_CARD_SIMPLE_PHONE_ID_RADIO, */ - E_CARD_PHONE_TELEX, /* E_CARD_SIMPLE_PHONE_ID_TELEX, */ - E_CARD_PHONE_TTYTDD, /* E_CARD_SIMPLE_PHONE_ID_TTYTDD, */ -}; - -char *phone_names[] = { - NULL, /* E_CARD_SIMPLE_PHONE_ID_ASSISTANT, */ - "Business", - "Business 2", - "Business Fax", - NULL, /* E_CARD_SIMPLE_PHONE_ID_CALLBACK, */ - "Car", - NULL, /* E_CARD_SIMPLE_PHONE_ID_COMPANY, */ - "Home", - "Home 2", - "Home Fax", - "ISDN", - "Mobile", - "Other", - NULL, /* E_CARD_SIMPLE_PHONE_ID_OTHER_FAX, */ - "Pager", - "Primary", - NULL, /* E_CARD_SIMPLE_PHONE_ID_RADIO, */ - NULL, /* E_CARD_SIMPLE_PHONE_ID_TELEX, */ - NULL, /* E_CARD_SIMPLE_PHONE_ID_TTYTDD, */ -}; - -char *phone_short_names[] = { - NULL, /* E_CARD_SIMPLE_PHONE_ID_ASSISTANT, */ - "Bus", - "Bus 2", - "Bus Fax", - NULL, /* E_CARD_SIMPLE_PHONE_ID_CALLBACK, */ - "Car", - NULL, /* E_CARD_SIMPLE_PHONE_ID_COMPANY, */ - "Home", - "Home 2", - "Home Fax", - "ISDN", - "Mob", - "Other", - NULL, /* E_CARD_SIMPLE_PHONE_ID_OTHER_FAX, */ - "Pag", - "Prim", - NULL, /* E_CARD_SIMPLE_PHONE_ID_RADIO, */ - NULL, /* E_CARD_SIMPLE_PHONE_ID_TELEX, */ - NULL, /* E_CARD_SIMPLE_PHONE_ID_TTYTDD, */ -}; - -ECardAddressFlags addr_correspondences[] = { - E_CARD_ADDR_WORK, /* E_CARD_SIMPLE_ADDRESS_ID_BUSINESS, */ - E_CARD_ADDR_HOME, /* E_CARD_SIMPLE_ADDRESS_ID_HOME, */ - E_CARD_ADDR_POSTAL, /* E_CARD_SIMPLE_ADDRESS_ID_OTHER, */ -}; - -char *address_names[] = { - "Business", - "Home", - "Other", -}; - -/** - * e_card_simple_get_type: - * @void: - * - * Registers the &ECardSimple class if necessary, and returns the type ID - * associated to it. - * - * Return value: The type ID of the &ECardSimple class. - **/ -GType -e_card_simple_get_type (void) -{ - static GType simple_type = 0; - - if (!simple_type) { - static const GTypeInfo simple_info = { - sizeof (ECardSimpleClass), - NULL, /* base_init */ - NULL, /* base_finalize */ - (GClassInitFunc) e_card_simple_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (ECardSimple), - 0, /* n_preallocs */ - (GInstanceInitFunc) e_card_simple_init, - }; - - simple_type = g_type_register_static (G_TYPE_OBJECT, "ECardSimple", &simple_info, 0); - } - - return simple_type; -} - -/** - * e_card_simple_new: - * @VCard: a string in vCard format - * - * Returns: a new #ECardSimple that wraps the @VCard. - */ -ECardSimple * -e_card_simple_new (ECard *card) -{ - ECardSimple *simple = g_object_new (E_TYPE_CARD_SIMPLE, NULL); - g_object_set(simple, - "card", card, - NULL); - return simple; -} - -ECardSimple * -e_card_simple_duplicate(ECardSimple *simple) -{ - ECard *card = simple->card ? e_card_duplicate (simple->card) : e_card_new (""); - ECardSimple *new_simple = e_card_simple_new(card); - return new_simple; -} - -/** - * e_card_simple_get_id: - * @simple: an #ECardSimple - * - * Returns: a string representing the id of the simple, which is unique - * within its book. - */ -const char * -e_card_simple_get_id (ECardSimple *simple) -{ - if (simple->card) - return e_card_get_id(simple->card); - else - return ""; -} - -/** - * e_card_simple_get_id: - * @simple: an #ECardSimple - * @id: a id in string format - * - * Sets the identifier of a simple, which should be unique within its - * book. - */ -void -e_card_simple_set_id (ECardSimple *simple, const char *id) -{ - if ( simple->card ) - e_card_set_id(simple->card, id); -} - -/** - * e_card_simple_get_vcard: - * @simple: an #ECardSimple - * - * Returns: a string in vcard format, which is wrapped by the @simple. - */ -char * -e_card_simple_get_vcard (ECardSimple *simple) -{ - if (simple->card) - return e_card_get_vcard(simple->card); - else - return g_strdup(""); -} - -/** - * e_card_simple_get_vcard_assume_utf8: - * @simple: an #ECardSimple - * - * Returns: a string in vcard format, which is wrapped by the @simple. - */ -char * -e_card_simple_get_vcard_assume_utf8 (ECardSimple *simple) -{ - if (simple->card) - return e_card_get_vcard_assume_utf8(simple->card); - else - return g_strdup(""); -} - -static void -e_card_simple_class_init (ECardSimpleClass *klass) -{ - GObjectClass *object_class; - - object_class = G_OBJECT_CLASS(klass); - - parent_class = g_type_class_ref (G_TYPE_OBJECT); - - object_class->dispose = e_card_simple_dispose; - object_class->get_property = e_card_simple_get_property; - object_class->set_property = e_card_simple_set_property; - - g_object_class_install_property (object_class, PROP_CARD, - g_param_spec_object ("card", - _("ECard"), - /*_( */"XXX blurb" /*)*/, - E_TYPE_CARD, - G_PARAM_READWRITE)); -} - -/* - * ECardSimple lifecycle management and vcard loading/saving. - */ - -static void -e_card_simple_dispose (GObject *object) -{ - ECardSimple *simple; - int i; - - simple = E_CARD_SIMPLE (object); - - if (simple->card) { - g_object_unref(simple->card); - simple->card = NULL; - } - if (simple->temp_fields) { - g_list_foreach(simple->temp_fields, (GFunc) g_free, NULL); - g_list_free(simple->temp_fields); - simple->temp_fields = NULL; - } - - for(i = 0; i < E_CARD_SIMPLE_PHONE_ID_LAST; i++) { - if (simple->phone[i]) { - e_card_phone_unref (simple->phone[i]); - simple->phone[i] = NULL; - } - } - for(i = 0; i < E_CARD_SIMPLE_EMAIL_ID_LAST; i++) { - if (simple->email[i]) { - g_free(simple->email[i]); - simple->email[i] = NULL; - } - } - for(i = 0; i < E_CARD_SIMPLE_ADDRESS_ID_LAST; i++) { - if (simple->address[i]) { - e_card_address_label_unref(simple->address[i]); - simple->address[i] = NULL; - } - } - for(i = 0; i < E_CARD_SIMPLE_ADDRESS_ID_LAST; i++) { - if (simple->delivery[i]) { - e_card_delivery_address_unref(simple->delivery[i]); - simple->delivery[i] = NULL; - } - } - - if (G_OBJECT_CLASS (parent_class)->dispose) - G_OBJECT_CLASS (parent_class)->dispose (object); -} - - -/* Set_arg handler for the simple */ -static void -e_card_simple_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - ECardSimple *simple; - - simple = E_CARD_SIMPLE (object); - - switch (prop_id) { - case PROP_CARD: - if (simple->card) - g_object_unref(simple->card); - g_list_foreach(simple->temp_fields, (GFunc) g_free, NULL); - g_list_free(simple->temp_fields); - simple->temp_fields = NULL; - if (g_value_get_object (value)) - simple->card = E_CARD(g_value_get_object (value)); - else - simple->card = NULL; - if(simple->card) - g_object_ref(simple->card); - fill_in_info(simple); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -/* Get_arg handler for the simple */ -static void -e_card_simple_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - ECardSimple *simple; - - simple = E_CARD_SIMPLE (object); - - switch (prop_id) { - case PROP_CARD: - e_card_simple_sync_card(simple); - g_value_set_object (value, simple->card); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - - -/** - * e_card_simple_init: - */ -static void -e_card_simple_init (ECardSimple *simple) -{ - int i; - simple->card = NULL; - for(i = 0; i < E_CARD_SIMPLE_PHONE_ID_LAST; i++) - simple->phone[i] = NULL; - for(i = 0; i < E_CARD_SIMPLE_EMAIL_ID_LAST; i++) - simple->email[i] = NULL; - for(i = 0; i < E_CARD_SIMPLE_ADDRESS_ID_LAST; i++) - simple->address[i] = NULL; - simple->temp_fields = NULL; - - simple->changed = TRUE; -} - -static void -fill_in_info(ECardSimple *simple) -{ - ECard *card = simple->card; - if (card) { - EList *address_list; - EList *phone_list; - EList *email_list; - EList *delivery_list; - const ECardPhone *phone; - const char *email; - const ECardAddrLabel *address; - const ECardDeliveryAddress *delivery; - int i; - - EIterator *iterator; - - g_object_get(card, - "address_label", &address_list, - "address", &delivery_list, - "phone", &phone_list, - "email", &email_list, - NULL); - for (i = 0; i < E_CARD_SIMPLE_PHONE_ID_LAST; i++) { - e_card_phone_unref(simple->phone[i]); - simple->phone[i] = NULL; - } - for (iterator = e_list_get_iterator(phone_list); e_iterator_is_valid(iterator); e_iterator_next(iterator)) { - gboolean found = FALSE; - phone = e_iterator_get(iterator); - for (i = 0; i < E_CARD_SIMPLE_PHONE_ID_LAST; i ++) { - if ((phone->flags == phone_correspondences[i]) && (simple->phone[i] == NULL)) { - simple->phone[i] = e_card_phone_ref(phone); - found = TRUE; - break; - } - } - if (found) - continue; - for (i = 0; i < E_CARD_SIMPLE_PHONE_ID_LAST; i ++) { - if (((phone->flags & phone_correspondences[i]) == phone_correspondences[i]) && (simple->phone[i] == NULL)) { - simple->phone[i] = e_card_phone_ref(phone); - break; - } - } - } - g_object_unref(iterator); - - for (i = 0; i < E_CARD_SIMPLE_EMAIL_ID_LAST; i++) { - g_free(simple->email[i]); - simple->email[i] = NULL; - } - for (iterator = e_list_get_iterator(email_list); e_iterator_is_valid(iterator); e_iterator_next(iterator)) { - email = e_iterator_get(iterator); - for (i = 0; i < E_CARD_SIMPLE_EMAIL_ID_LAST; i ++) { - if ((simple->email[i] == NULL)) { - simple->email[i] = g_strdup(email); - break; - } - } - } - g_object_unref(iterator); - - for (i = 0; i < E_CARD_SIMPLE_ADDRESS_ID_LAST; i++) { - e_card_address_label_unref(simple->address[i]); - simple->address[i] = NULL; - } - for (iterator = e_list_get_iterator(address_list); e_iterator_is_valid(iterator); e_iterator_next(iterator)) { - address = e_iterator_get(iterator); - for (i = 0; i < E_CARD_SIMPLE_ADDRESS_ID_LAST; i ++) { - if (((address->flags & addr_correspondences[i]) == addr_correspondences[i]) && (simple->address[i] == NULL)) { - simple->address[i] = e_card_address_label_ref(address); - break; - } - } - } - g_object_unref(iterator); - - for (i = 0; i < E_CARD_SIMPLE_ADDRESS_ID_LAST; i++) { - e_card_delivery_address_unref(simple->delivery[i]); - simple->delivery[i] = NULL; - } - for (iterator = e_list_get_iterator(delivery_list); e_iterator_is_valid(iterator); e_iterator_next(iterator)) { - delivery = e_iterator_get(iterator); - for (i = 0; i < E_CARD_SIMPLE_ADDRESS_ID_LAST; i ++) { - if (((delivery->flags & addr_correspondences[i]) == addr_correspondences[i]) && (simple->delivery[i] == NULL)) { - simple->delivery[i] = e_card_delivery_address_ref(delivery); - break; - } - } - } - g_object_unref(iterator); - - g_object_unref(phone_list); - g_object_unref(email_list); - g_object_unref(address_list); - g_object_unref(delivery_list); - e_card_free_empty_lists (card); - } -} - -void -e_card_simple_sync_card(ECardSimple *simple) -{ - ECard *card = simple->card; - if (card && simple->changed) { - EList *address_list; - EList *phone_list; - EList *email_list; - EList *delivery_list; - const ECardPhone *phone; - const ECardAddrLabel *address; - const ECardDeliveryAddress *delivery; - const char *email; - int i; - - EIterator *iterator; - - g_object_get(card, - "address_label", &address_list, - "address", &delivery_list, - "phone", &phone_list, - "email", &email_list, - NULL); - - for (iterator = e_list_get_iterator(phone_list); e_iterator_is_valid(iterator); e_iterator_next(iterator) ) { - int i; - gboolean found = FALSE; - phone = e_iterator_get(iterator); - for (i = 0; i < E_CARD_SIMPLE_PHONE_ID_LAST; i ++) { - if (phone->flags == phone_correspondences[i]) { - if (simple->phone[i]) { - simple->phone[i]->flags = phone_correspondences[i]; - if (simple->phone[i]->number && *simple->phone[i]->number) { - e_iterator_set(iterator, simple->phone[i]); - } else { - e_iterator_delete(iterator); - } - e_card_phone_unref(simple->phone[i]); - simple->phone[i] = NULL; - found = TRUE; - break; - } - } - } - if (found) - continue; - for (i = 0; i < E_CARD_SIMPLE_PHONE_ID_LAST; i ++) { - if ((phone->flags & phone_correspondences[i]) == phone_correspondences[i]) { - if (simple->phone[i]) { - simple->phone[i]->flags = phone_correspondences[i]; - if (simple->phone[i]->number && *simple->phone[i]->number) { - e_iterator_set(iterator, simple->phone[i]); - } else { - e_iterator_delete(iterator); - } - e_card_phone_unref(simple->phone[i]); - simple->phone[i] = NULL; - break; - } - } - } - } - g_object_unref(iterator); - for (i = 0; i < E_CARD_SIMPLE_PHONE_ID_LAST; i ++) { - if (simple->phone[i]) { - simple->phone[i]->flags = phone_correspondences[i]; - e_list_append(phone_list, simple->phone[i]); - e_card_phone_unref(simple->phone[i]); - simple->phone[i] = NULL; - } - } - - for (iterator = e_list_get_iterator(email_list); e_iterator_is_valid(iterator); e_iterator_next(iterator) ) { - int i; - email = e_iterator_get(iterator); - for (i = 0; i < E_CARD_SIMPLE_EMAIL_ID_LAST; i ++) { - if (simple->email[i]) { - if (*simple->email[i]) { - e_iterator_set(iterator, simple->email[i]); - } else { - e_iterator_delete(iterator); - } - g_free(simple->email[i]); - simple->email[i] = NULL; - break; - } - } - } - g_object_unref(iterator); - for (i = 0; i < E_CARD_SIMPLE_EMAIL_ID_LAST; i ++) { - if (simple->email[i]) { - e_list_append(email_list, simple->email[i]); - g_free(simple->email[i]); - simple->email[i] = NULL; - } - } - - for (iterator = e_list_get_iterator(address_list); e_iterator_is_valid(iterator); e_iterator_next(iterator) ) { - int i; - address = e_iterator_get(iterator); - for (i = 0; i < E_CARD_SIMPLE_ADDRESS_ID_LAST; i ++) { - if ((address->flags & addr_correspondences[i]) == addr_correspondences[i]) { - if (simple->address[i]) { - simple->address[i]->flags &= ~E_CARD_ADDR_MASK; - simple->address[i]->flags |= addr_correspondences[i]; - if (simple->address[i]->data && *simple->address[i]->data) { - e_iterator_set(iterator, simple->address[i]); - } else { - e_iterator_delete(iterator); - } - e_card_address_label_unref(simple->address[i]); - simple->address[i] = NULL; - break; - } - } - } - } - g_object_unref(iterator); - for (i = 0; i < E_CARD_SIMPLE_ADDRESS_ID_LAST; i ++) { - if (simple->address[i]) { - simple->address[i]->flags &= ~E_CARD_ADDR_MASK; - simple->address[i]->flags |= addr_correspondences[i]; - e_list_append(address_list, simple->address[i]); - e_card_address_label_unref(simple->address[i]); - simple->address[i] = NULL; - } - } - - for (iterator = e_list_get_iterator(delivery_list); e_iterator_is_valid(iterator); e_iterator_next(iterator) ) { - int i; - delivery = e_iterator_get(iterator); - for (i = 0; i < E_CARD_SIMPLE_ADDRESS_ID_LAST; i ++) { - if ((delivery->flags & addr_correspondences[i]) == addr_correspondences[i]) { - if (simple->delivery[i]) { - simple->delivery[i]->flags &= ~E_CARD_ADDR_MASK; - simple->delivery[i]->flags |= addr_correspondences[i]; - if (!e_card_delivery_address_is_empty(simple->delivery[i])) { - e_iterator_set(iterator, simple->delivery[i]); - } else { - e_iterator_delete(iterator); - } - e_card_delivery_address_unref(simple->delivery[i]); - simple->delivery[i] = NULL; - break; - } - } - } - } - g_object_unref(iterator); - for (i = 0; i < E_CARD_SIMPLE_ADDRESS_ID_LAST; i ++) { - if (simple->delivery[i]) { - simple->delivery[i]->flags &= ~E_CARD_ADDR_MASK; - simple->delivery[i]->flags |= addr_correspondences[i]; - e_list_append(delivery_list, simple->delivery[i]); - e_card_delivery_address_unref(simple->delivery[i]); - simple->delivery[i] = NULL; - } - } - fill_in_info(simple); - - g_object_unref(phone_list); - g_object_unref(email_list); - g_object_unref(address_list); - g_object_unref(delivery_list); - e_card_free_empty_lists (card); - } - - simple->changed = FALSE; -} - -const ECardPhone *e_card_simple_get_phone (ECardSimple *simple, - ECardSimplePhoneId id) -{ - return simple->phone[id]; -} - -const char *e_card_simple_get_email (ECardSimple *simple, - ECardSimpleEmailId id) -{ - return simple->email[id]; -} - -const ECardAddrLabel *e_card_simple_get_address (ECardSimple *simple, - ECardSimpleAddressId id) -{ - return simple->address[id]; -} - -const ECardDeliveryAddress *e_card_simple_get_delivery_address (ECardSimple *simple, - ECardSimpleAddressId id) -{ - return simple->delivery[id]; -} - -void e_card_simple_set_phone (ECardSimple *simple, - ECardSimplePhoneId id, - const ECardPhone *phone) -{ - e_card_phone_unref(simple->phone[id]); - simple->phone[id] = e_card_phone_ref(phone); - simple->changed = TRUE; -} - -void e_card_simple_set_email (ECardSimple *simple, - ECardSimpleEmailId id, - const char *email) -{ - g_free(simple->email[id]); - simple->email[id] = g_strdup(email); - simple->changed = TRUE; -} - -void -e_card_simple_set_address (ECardSimple *simple, ECardSimpleAddressId id, const ECardAddrLabel *address) -{ - e_card_address_label_unref(simple->address[id]); - simple->address[id] = e_card_address_label_ref(address); - e_card_delivery_address_unref(simple->delivery[id]); - simple->delivery[id] = e_card_delivery_address_from_label(simple->address[id]); - simple->changed = TRUE; -} - -void e_card_simple_set_delivery_address (ECardSimple *simple, - ECardSimpleAddressId id, - const ECardDeliveryAddress *delivery) -{ - e_card_delivery_address_unref(simple->delivery[id]); - simple->delivery[id] = e_card_delivery_address_ref(delivery); - e_card_address_label_unref(simple->address[id]); - simple->address[id] = e_card_delivery_address_to_label(simple->delivery[id]); - simple->changed = TRUE; -} - -const char *e_card_simple_get_const (ECardSimple *simple, - ECardSimpleField field) -{ - char *ret_val = e_card_simple_get(simple, field); - if (ret_val) - simple->temp_fields = g_list_prepend(simple->temp_fields, ret_val); - return ret_val; -} - -char *e_card_simple_get (ECardSimple *simple, - ECardSimpleField field) -{ - ECardSimpleInternalType type = field_data[field].type; - const ECardAddrLabel *addr; - const ECardPhone *phone; - char *string; - ECardDate *date; - ECardName *name; - switch(type) { - case E_CARD_SIMPLE_INTERNAL_TYPE_STRING: - if (simple->card) { - g_object_get(simple->card, - field_data[field].ecard_field, &string, - NULL); - return string; - } else - return NULL; - case E_CARD_SIMPLE_INTERNAL_TYPE_DATE: - if (simple->card) { - g_object_get(simple->card, - field_data[field].ecard_field, &date, - NULL); - if (date != NULL) { - char buf[26]; - struct tm then; - then.tm_year = date->year; - then.tm_mon = date->month - 1; - then.tm_mday = date->day; - then.tm_hour = 12; - then.tm_min = 0; - then.tm_sec = 0; - e_strftime_fix_am_pm (buf, 26, _("%x"), &then); - return g_strdup (buf); - } else { - return NULL; - } - } else - return NULL; - case E_CARD_SIMPLE_INTERNAL_TYPE_ADDRESS: - addr = e_card_simple_get_address(simple, - field_data[field].list_type_index); - if (addr) - return g_strdup(addr->data); - else - return NULL; - case E_CARD_SIMPLE_INTERNAL_TYPE_PHONE: - phone = e_card_simple_get_phone(simple, - field_data[field].list_type_index); - if (phone) - return g_strdup(phone->number); - else - return NULL; - case E_CARD_SIMPLE_INTERNAL_TYPE_EMAIL: - string = e_card_simple_get_email(simple, - field_data[field].list_type_index); - return g_strdup(string); - case E_CARD_SIMPLE_INTERNAL_TYPE_BOOL: - if (simple->card) { - gboolean boole; - g_object_get (simple->card, - field_data[field].ecard_field, &boole, - NULL); - if (boole) - return g_strdup("true"); - else - return NULL; - } else { - return NULL; - } - case E_CARD_SIMPLE_INTERNAL_TYPE_SPECIAL: - switch (field) { - case E_CARD_SIMPLE_FIELD_NAME_OR_ORG: - if (simple->card) { - gboolean is_list; - - g_object_get(simple->card, - "file_as", &string, - NULL); - if (string && *string) - return string -; else - g_free (string); - - g_object_get(simple->card, - "full_name", &string, - NULL); - if (string && *string) - return g_strdup(string); - else - g_free (string); - - g_object_get(simple->card, - "org", &string, - NULL); - if (string && *string) - return g_strdup(string); - else - g_free (string); - - is_list = e_card_evolution_list (simple->card); - if (is_list) - string = _("Unnamed List"); - else - string = e_card_simple_get_email(simple, - E_CARD_SIMPLE_EMAIL_ID_EMAIL); - return g_strdup(string); - } else - return NULL; - case E_CARD_SIMPLE_FIELD_FAMILY_NAME: - if (simple->card) { - g_object_get (simple->card, - "name", &name, - NULL); - return g_strdup (name->family); - } else - return NULL; - case E_CARD_SIMPLE_FIELD_GIVEN_NAME: - if (simple->card) { - g_object_get (simple->card, - "name", &name, - NULL); - return g_strdup (name->given); - } else - return NULL; - case E_CARD_SIMPLE_FIELD_ADDITIONAL_NAME: - if (simple->card) { - g_object_get (simple->card, - "name", &name, - NULL); - return g_strdup (name->additional); - } else - return NULL; - case E_CARD_SIMPLE_FIELD_NAME_SUFFIX: - if (simple->card) { - g_object_get (simple->card, - "name", &name, - NULL); - return g_strdup (name->suffix); - } else - return NULL; - default: - return NULL; - } - default: - return NULL; - } -} - -static char * -name_to_style(const ECardName *name, char *company, int style) -{ - char *string; - char *strings[4], **stringptr; - char *substring; - switch (style) { - case 0: - stringptr = strings; - if (name->family && *name->family) - *(stringptr++) = name->family; - if (name->given && *name->given) - *(stringptr++) = name->given; - *stringptr = NULL; - string = g_strjoinv(", ", strings); - break; - case 1: - stringptr = strings; - if (name->given && *name->given) - *(stringptr++) = name->given; - if (name->family && *name->family) - *(stringptr++) = name->family; - *stringptr = NULL; - string = g_strjoinv(" ", strings); - break; - case 2: - string = g_strdup(company); - break; - case 3: /* Fall Through */ - case 4: - stringptr = strings; - if (name->family && *name->family) - *(stringptr++) = name->family; - if (name->given && *name->given) - *(stringptr++) = name->given; - *stringptr = NULL; - substring = g_strjoinv(", ", strings); - if (!(company && *company)) - company = ""; - if (style == 3) - string = g_strdup_printf("%s (%s)", substring, company); - else - string = g_strdup_printf("%s (%s)", company, substring); - g_free(substring); - break; - default: - string = g_strdup(""); - } - return string; -} - -static int -file_as_get_style (ECardSimple *simple) -{ - char *filestring = e_card_simple_get(simple, E_CARD_SIMPLE_FIELD_FILE_AS); - char *trystring; - char *company = e_card_simple_get(simple, E_CARD_SIMPLE_FIELD_ORG); - ECardName *name = NULL; - int i; - int style; - style = 0; - if (!company) - company = g_strdup(""); - if (filestring) { - g_object_get (simple->card, - "name", &name, - NULL); - - if (!name) { - goto end; - } - - style = -1; - - for (i = 0; i < 5; i++) { - trystring = name_to_style(name, company, i); - if (!strcmp(trystring, filestring)) { - g_free(trystring); - style = i; - goto end; - } - g_free(trystring); - } - } - end: - - g_free(filestring); - g_free(company); - - return style; -} - -static void -file_as_set_style(ECardSimple *simple, int style) -{ - if (style != -1) { - char *string; - char *company = e_card_simple_get(simple, E_CARD_SIMPLE_FIELD_ORG); - ECardName *name; - - if (!company) - company = g_strdup(""); - g_object_get (simple->card, - "name", &name, - NULL); - if (name) { - string = name_to_style(name, company, style); - e_card_simple_set(simple, E_CARD_SIMPLE_FIELD_FILE_AS, string); - g_free(string); - } - g_free(company); - } -} - -void e_card_simple_set (ECardSimple *simple, - ECardSimpleField field, - const char *data) -{ - ECardSimpleInternalType type = field_data[field].type; - ECardAddrLabel *address; - ECardPhone *phone; - int style; - simple->changed = TRUE; - switch (field) { - case E_CARD_SIMPLE_FIELD_FULL_NAME: - case E_CARD_SIMPLE_FIELD_ORG: - style = file_as_get_style(simple); - g_object_set(simple->card, - field_data[field].ecard_field, data, - NULL); - file_as_set_style(simple, style); - break; - default: - switch(type) { - case E_CARD_SIMPLE_INTERNAL_TYPE_STRING: - g_object_set(simple->card, - field_data[field].ecard_field, data, - NULL); - break; - case E_CARD_SIMPLE_INTERNAL_TYPE_DATE: - break; /* FIXME!!!! */ - case E_CARD_SIMPLE_INTERNAL_TYPE_ADDRESS: - address = e_card_address_label_new(); - address->data = g_strdup (data); - e_card_simple_set_address(simple, - field_data[field].list_type_index, - address); - e_card_address_label_unref(address); - break; - case E_CARD_SIMPLE_INTERNAL_TYPE_PHONE: - phone = e_card_phone_new(); - phone->number = g_strdup (data); - e_card_simple_set_phone(simple, - field_data[field].list_type_index, - phone); - e_card_phone_unref(phone); - break; - case E_CARD_SIMPLE_INTERNAL_TYPE_EMAIL: - e_card_simple_set_email(simple, - field_data[field].list_type_index, - data); - break; - case E_CARD_SIMPLE_INTERNAL_TYPE_SPECIAL: - break; - case E_CARD_SIMPLE_INTERNAL_TYPE_BOOL: - if (simple->card) { - gboolean boole = TRUE; - if (data == NULL) - boole = FALSE; - else if (!strcasecmp (data, "false")) - boole = FALSE; - g_object_set (simple->card, - field_data[field].ecard_field, boole, - NULL); - } - break; - } - break; - } -} - -ECardSimpleType e_card_simple_type (ECardSimple *simple, - ECardSimpleField field) -{ - ECardSimpleInternalType type = field_data[field].type; - switch(type) { - case E_CARD_SIMPLE_INTERNAL_TYPE_STRING: - case E_CARD_SIMPLE_INTERNAL_TYPE_ADDRESS: - case E_CARD_SIMPLE_INTERNAL_TYPE_PHONE: - case E_CARD_SIMPLE_INTERNAL_TYPE_EMAIL: - default: - return E_CARD_SIMPLE_TYPE_STRING; - - case E_CARD_SIMPLE_INTERNAL_TYPE_BOOL: - return E_CARD_SIMPLE_TYPE_BOOL; - - case E_CARD_SIMPLE_INTERNAL_TYPE_DATE: - return E_CARD_SIMPLE_TYPE_DATE; - - case E_CARD_SIMPLE_INTERNAL_TYPE_SPECIAL: - return E_CARD_SIMPLE_TYPE_STRING; - } -} - -const char *e_card_simple_get_ecard_field (ECardSimple *simple, - ECardSimpleField field) -{ - return field_data[field].ecard_field; -} - -const char *e_card_simple_get_name (ECardSimple *simple, - ECardSimpleField field) -{ - return _(field_data[field].name); -} - -gboolean -e_card_simple_get_allow_newlines (ECardSimple *simple, - ECardSimpleField field) -{ - ECardSimpleInternalType type = field_data[field].type; - switch(type) { - case E_CARD_SIMPLE_INTERNAL_TYPE_STRING: - case E_CARD_SIMPLE_INTERNAL_TYPE_PHONE: - case E_CARD_SIMPLE_INTERNAL_TYPE_EMAIL: - case E_CARD_SIMPLE_INTERNAL_TYPE_BOOL: - case E_CARD_SIMPLE_INTERNAL_TYPE_DATE: - case E_CARD_SIMPLE_INTERNAL_TYPE_SPECIAL: - default: - switch (field) { - case E_CARD_SIMPLE_FIELD_NOTE: - return TRUE; - default: - return FALSE; - } - - case E_CARD_SIMPLE_INTERNAL_TYPE_ADDRESS: - return TRUE; - } -} - -const char *e_card_simple_get_short_name (ECardSimple *simple, - ECardSimpleField field) -{ - return _(field_data[field].short_name); -} - -void e_card_simple_arbitrary_foreach (ECardSimple *simple, - ECardSimpleArbitraryCallback *callback, - gpointer closure) -{ - if (simple->card) { - EList *list; - EIterator *iterator; - g_object_get(simple->card, - "arbitrary", &list, - NULL); - for (iterator = e_list_get_iterator(list); e_iterator_is_valid(iterator); e_iterator_next(iterator)) { - const ECardArbitrary *arbitrary = e_iterator_get(iterator); - if (callback) - (*callback) (arbitrary, closure); - } - - g_object_unref (list); - e_card_free_empty_lists (simple->card); - } -} - -const ECardArbitrary *e_card_simple_get_arbitrary (ECardSimple *simple, - const char *key) -{ - if (simple->card) { - EList *list; - EIterator *iterator; - g_object_get(simple->card, - "arbitrary", &list, - NULL); - for (iterator = e_list_get_iterator(list); e_iterator_is_valid(iterator); e_iterator_next(iterator)) { - const ECardArbitrary *arbitrary = e_iterator_get(iterator); - if (!strcasecmp(arbitrary->key, key)) - return arbitrary; - } - - g_object_unref (list); - e_card_free_empty_lists (simple->card); - } - return NULL; -} - -/* Any of these except key can be NULL */ -void e_card_simple_set_arbitrary (ECardSimple *simple, - const char *key, - const char *type, - const char *value) -{ - if (simple->card) { - ECardArbitrary *new_arb; - EList *list; - EIterator *iterator; - - simple->changed = TRUE; - g_object_get(simple->card, - "arbitrary", &list, - NULL); - for (iterator = e_list_get_iterator(list); e_iterator_is_valid(iterator); e_iterator_next(iterator)) { - const ECardArbitrary *arbitrary = e_iterator_get(iterator); - if (!strcasecmp(arbitrary->key, key)) { - new_arb = e_card_arbitrary_new(); - new_arb->key = g_strdup(key); - new_arb->type = g_strdup(type); - new_arb->value = g_strdup(value); - e_iterator_set(iterator, new_arb); - e_card_arbitrary_unref(new_arb); - return; - } - } - new_arb = e_card_arbitrary_new(); - new_arb->key = g_strdup(key); - new_arb->type = g_strdup(type); - new_arb->value = g_strdup(value); - e_list_append(list, new_arb); - g_object_unref(list); - e_card_arbitrary_unref(new_arb); - } -} - -void -e_card_simple_set_name (ECardSimple *simple, ECardName *name) -{ - int style; - style = file_as_get_style(simple); - g_object_set (simple->card, - "name", name, - NULL); - file_as_set_style(simple, style); -} - -/* These map between the individual list types and ECardSimpleField */ -ECardSimpleField -e_card_simple_map_phone_to_field (ECardSimplePhoneId phone_id) -{ - int i; - - g_return_val_if_fail (phone_id < E_CARD_SIMPLE_PHONE_ID_LAST, 0); - - for (i = 0; i < field_data_count; i ++) - if (field_data[i].list_type_index == phone_id - && field_data[i].type == E_CARD_SIMPLE_INTERNAL_TYPE_PHONE) - return i; - - g_warning ("couldn't find phone id %d, returning 0 (which is almost assuredly incorrect)\n", phone_id); - - return 0; -} - -ECardSimpleField -e_card_simple_map_email_to_field (ECardSimpleEmailId email_id) -{ - int i; - - g_return_val_if_fail (email_id < E_CARD_SIMPLE_EMAIL_ID_LAST, 0); - - for (i = 0; i < field_data_count; i ++) - if (field_data[i].list_type_index == email_id - && field_data[i].type == E_CARD_SIMPLE_INTERNAL_TYPE_EMAIL) - return i; - - g_warning ("couldn't find email id %d, returning 0 (which is almost assuredly incorrect)\n", email_id); - return 0; -} - -ECardSimpleField -e_card_simple_map_address_to_field (ECardSimpleAddressId address_id) -{ - int i; - - g_return_val_if_fail (address_id < E_CARD_SIMPLE_ADDRESS_ID_LAST, 0); - - for (i = 0; i < field_data_count; i ++) - if (field_data[i].list_type_index == address_id - && field_data[i].type == E_CARD_SIMPLE_INTERNAL_TYPE_ADDRESS) - return i; - - g_warning ("couldn't find address id %d, returning 0 (which is almost assuredly incorrect)\n", address_id); - return 0; -} diff --git a/addressbook/backend/ebook/e-card-simple.h b/addressbook/backend/ebook/e-card-simple.h deleted file mode 100644 index 868d4e1573..0000000000 --- a/addressbook/backend/ebook/e-card-simple.h +++ /dev/null @@ -1,234 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * Authors: - * Chris Lahey <clahey@ximian.com> - * Arturo Espinosa - * Nat Friedman (nat@ximian.com) - * - * Copyright (C) 2000 Ximian, Inc. - * Copyright (C) 1999 The Free Software Foundation - */ - -#ifndef __E_CARD_SIMPLE_H__ -#define __E_CARD_SIMPLE_H__ - -#include <time.h> -#include <glib-object.h> -#include <stdio.h> -#include <ebook/e-card.h> -#include <ebook/e-card-types.h> -#include <e-util/e-list.h> - -#define E_TYPE_CARD_SIMPLE (e_card_simple_get_type ()) -#define E_CARD_SIMPLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_TYPE_CARD_SIMPLE, ECardSimple)) -#define E_CARD_SIMPLE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), E_TYPE_CARD_SIMPLE, ECardSimpleClass)) -#define E_IS_CARD_SIMPLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), E_TYPE_CARD_SIMPLE)) -#define E_IS_CARD_SIMPLE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), E_TYPE_CARD_SIMPLE)) -#define E_CARD_SIMPLE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), E_TYPE_CARD_SIMPLE, ECardSimpleClass)) - -typedef enum _ECardSimplePhoneId ECardSimplePhoneId; -typedef enum _ECardSimpleEmailId ECardSimpleEmailId; -typedef enum _ECardSimpleAddressId ECardSimpleAddressId; -typedef enum _ECardSimpleType ECardSimpleType; -typedef enum _ECardSimpleField ECardSimpleField; - -enum _ECardSimplePhoneId { - E_CARD_SIMPLE_PHONE_ID_ASSISTANT, - E_CARD_SIMPLE_PHONE_ID_BUSINESS, - E_CARD_SIMPLE_PHONE_ID_BUSINESS_2, - E_CARD_SIMPLE_PHONE_ID_BUSINESS_FAX, - E_CARD_SIMPLE_PHONE_ID_CALLBACK, - E_CARD_SIMPLE_PHONE_ID_CAR, - E_CARD_SIMPLE_PHONE_ID_COMPANY, - E_CARD_SIMPLE_PHONE_ID_HOME, - E_CARD_SIMPLE_PHONE_ID_HOME_2, - E_CARD_SIMPLE_PHONE_ID_HOME_FAX, - E_CARD_SIMPLE_PHONE_ID_ISDN, - E_CARD_SIMPLE_PHONE_ID_MOBILE, - E_CARD_SIMPLE_PHONE_ID_OTHER, - E_CARD_SIMPLE_PHONE_ID_OTHER_FAX, - E_CARD_SIMPLE_PHONE_ID_PAGER, - E_CARD_SIMPLE_PHONE_ID_PRIMARY, - E_CARD_SIMPLE_PHONE_ID_RADIO, - E_CARD_SIMPLE_PHONE_ID_TELEX, - E_CARD_SIMPLE_PHONE_ID_TTYTDD, - E_CARD_SIMPLE_PHONE_ID_LAST -}; - -/* We need HOME and WORK email addresses here. */ -enum _ECardSimpleEmailId { - E_CARD_SIMPLE_EMAIL_ID_EMAIL, - E_CARD_SIMPLE_EMAIL_ID_EMAIL_2, - E_CARD_SIMPLE_EMAIL_ID_EMAIL_3, - E_CARD_SIMPLE_EMAIL_ID_LAST -}; - -/* Should this include (BILLING/SHIPPING)? */ -enum _ECardSimpleAddressId { - E_CARD_SIMPLE_ADDRESS_ID_BUSINESS, - E_CARD_SIMPLE_ADDRESS_ID_HOME, - E_CARD_SIMPLE_ADDRESS_ID_OTHER, - E_CARD_SIMPLE_ADDRESS_ID_LAST -}; - -enum _ECardSimpleType { - E_CARD_SIMPLE_TYPE_STRING, - E_CARD_SIMPLE_TYPE_DATE, - E_CARD_SIMPLE_TYPE_BOOL, -}; - -enum _ECardSimpleField { - E_CARD_SIMPLE_FIELD_FILE_AS, - E_CARD_SIMPLE_FIELD_FULL_NAME, - E_CARD_SIMPLE_FIELD_EMAIL, - E_CARD_SIMPLE_FIELD_PHONE_PRIMARY, - E_CARD_SIMPLE_FIELD_PHONE_ASSISTANT, - E_CARD_SIMPLE_FIELD_PHONE_BUSINESS, - E_CARD_SIMPLE_FIELD_PHONE_CALLBACK, - E_CARD_SIMPLE_FIELD_PHONE_COMPANY, - E_CARD_SIMPLE_FIELD_PHONE_HOME, - E_CARD_SIMPLE_FIELD_ORG, - E_CARD_SIMPLE_FIELD_ADDRESS_BUSINESS, - E_CARD_SIMPLE_FIELD_ADDRESS_HOME, - E_CARD_SIMPLE_FIELD_PHONE_MOBILE, - E_CARD_SIMPLE_FIELD_PHONE_CAR, - E_CARD_SIMPLE_FIELD_PHONE_BUSINESS_FAX, - E_CARD_SIMPLE_FIELD_PHONE_HOME_FAX, - E_CARD_SIMPLE_FIELD_PHONE_BUSINESS_2, - E_CARD_SIMPLE_FIELD_PHONE_HOME_2, - E_CARD_SIMPLE_FIELD_PHONE_ISDN, - E_CARD_SIMPLE_FIELD_PHONE_OTHER, - E_CARD_SIMPLE_FIELD_PHONE_OTHER_FAX, - E_CARD_SIMPLE_FIELD_PHONE_PAGER, - E_CARD_SIMPLE_FIELD_PHONE_RADIO, - E_CARD_SIMPLE_FIELD_PHONE_TELEX, - E_CARD_SIMPLE_FIELD_PHONE_TTYTDD, - E_CARD_SIMPLE_FIELD_ADDRESS_OTHER, - E_CARD_SIMPLE_FIELD_EMAIL_2, - E_CARD_SIMPLE_FIELD_EMAIL_3, - E_CARD_SIMPLE_FIELD_URL, - E_CARD_SIMPLE_FIELD_ORG_UNIT, - E_CARD_SIMPLE_FIELD_OFFICE, - E_CARD_SIMPLE_FIELD_TITLE, - E_CARD_SIMPLE_FIELD_ROLE, - E_CARD_SIMPLE_FIELD_MANAGER, - E_CARD_SIMPLE_FIELD_ASSISTANT, - E_CARD_SIMPLE_FIELD_NICKNAME, - E_CARD_SIMPLE_FIELD_SPOUSE, - E_CARD_SIMPLE_FIELD_NOTE, - E_CARD_SIMPLE_FIELD_CALURI, - E_CARD_SIMPLE_FIELD_FBURL, - E_CARD_SIMPLE_FIELD_ICSCALENDAR, - /* If you add after icscalendar, make sure to move LAST_SIMPLE_STRING */ - E_CARD_SIMPLE_FIELD_LAST_SIMPLE_STRING = E_CARD_SIMPLE_FIELD_ICSCALENDAR, - E_CARD_SIMPLE_FIELD_ANNIVERSARY, - E_CARD_SIMPLE_FIELD_BIRTH_DATE, - E_CARD_SIMPLE_FIELD_MAILER, - E_CARD_SIMPLE_FIELD_NAME_OR_ORG, - E_CARD_SIMPLE_FIELD_CATEGORIES, - E_CARD_SIMPLE_FIELD_FAMILY_NAME, - E_CARD_SIMPLE_FIELD_GIVEN_NAME, - E_CARD_SIMPLE_FIELD_ADDITIONAL_NAME, - E_CARD_SIMPLE_FIELD_NAME_SUFFIX, - E_CARD_SIMPLE_FIELD_WANTS_HTML, - E_CARD_SIMPLE_FIELD_IS_LIST, - E_CARD_SIMPLE_FIELD_LAST -}; - -typedef struct _ECardSimple ECardSimple; -typedef struct _ECardSimpleClass ECardSimpleClass; - -struct _ECardSimple { - GObject object; - ECard *card; - - GList *temp_fields; - - ECardPhone *phone[E_CARD_SIMPLE_PHONE_ID_LAST]; - char *email[E_CARD_SIMPLE_EMAIL_ID_LAST]; - ECardAddrLabel *address[E_CARD_SIMPLE_ADDRESS_ID_LAST]; - ECardDeliveryAddress *delivery[E_CARD_SIMPLE_ADDRESS_ID_LAST]; - - gboolean changed; -}; - -struct _ECardSimpleClass { - GObjectClass parent_class; -}; - -typedef void (*ECardSimpleArbitraryCallback) (const ECardArbitrary *arbitrary, gpointer closure); -ECardSimple *e_card_simple_new (ECard *card); -const char *e_card_simple_get_id (ECardSimple *simple); -void e_card_simple_set_id (ECardSimple *simple, - const gchar *character); -char *e_card_simple_get_vcard (ECardSimple *simple); -char *e_card_simple_get_vcard_assume_utf8 (ECardSimple *simple); -ECardSimple *e_card_simple_duplicate (ECardSimple *simple); -char *e_card_simple_get (ECardSimple *simple, - ECardSimpleField field); -const char *e_card_simple_get_const (ECardSimple *simple, - ECardSimpleField field); -void e_card_simple_set (ECardSimple *simple, - ECardSimpleField field, - const char *data); -ECardSimpleType e_card_simple_type (ECardSimple *simple, - ECardSimpleField field); - -const char *e_card_simple_get_ecard_field (ECardSimple *simple, - ECardSimpleField field); -const char *e_card_simple_get_name (ECardSimple *simple, - ECardSimpleField field); -const char *e_card_simple_get_short_name (ECardSimple *simple, - ECardSimpleField field); -gboolean e_card_simple_get_allow_newlines (ECardSimple *simple, - ECardSimpleField field); - - -/* Use these only if building lists of specific types. It should be - * easier to use the above if you consider a phone field to be the - * same as any other field. - */ -const ECardPhone *e_card_simple_get_phone (ECardSimple *simple, - ECardSimplePhoneId id); -const char *e_card_simple_get_email (ECardSimple *simple, - ECardSimpleEmailId id); -const ECardAddrLabel *e_card_simple_get_address (ECardSimple *simple, - ECardSimpleAddressId id); -const ECardDeliveryAddress *e_card_simple_get_delivery_address (ECardSimple *simple, - ECardSimpleAddressId id); -void e_card_simple_set_phone (ECardSimple *simple, - ECardSimplePhoneId id, - const ECardPhone *phone); -void e_card_simple_set_email (ECardSimple *simple, - ECardSimpleEmailId id, - const char *email); -void e_card_simple_set_address (ECardSimple *simple, - ECardSimpleAddressId id, - const ECardAddrLabel *address); -void e_card_simple_set_delivery_address (ECardSimple *simple, - ECardSimpleAddressId id, - const ECardDeliveryAddress *delivery); -void e_card_simple_arbitrary_foreach (ECardSimple *simple, - ECardSimpleArbitraryCallback *callback, - gpointer closure); -const ECardArbitrary *e_card_simple_get_arbitrary (ECardSimple *simple, - const char *key); -/* Any of these except key can be NULL */ -void e_card_simple_set_arbitrary (ECardSimple *simple, - const char *key, - const char *type, - const char *value); -void e_card_simple_set_name (ECardSimple *simple, - ECardName *name); -void e_card_simple_sync_card (ECardSimple *simple); - -/* These map between the individual list types and ECardSimpleField */ -ECardSimpleField e_card_simple_map_phone_to_field (ECardSimplePhoneId phone_id); -ECardSimpleField e_card_simple_map_email_to_field (ECardSimpleEmailId email_id); -ECardSimpleField e_card_simple_map_address_to_field (ECardSimpleAddressId address_id); - -GType e_card_simple_get_type (void); - -#endif /* ! __E_CARD_SIMPLE_H__ */ - - diff --git a/addressbook/backend/ebook/e-card-types.h b/addressbook/backend/ebook/e-card-types.h deleted file mode 100644 index 8d35c54924..0000000000 --- a/addressbook/backend/ebook/e-card-types.h +++ /dev/null @@ -1,101 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * Authors: - * Arturo Espinosa - * Nat Friedman (nat@ximian.com) - * - * Copyright (C) 2000 Ximian, Inc. - * Copyright (C) 1999 The Free Software Foundation - */ - -#ifndef __E_CARD_TYPES_H__ -#define __E_CARD_TYPES_H__ - -/* IDENTIFICATION PROPERTIES */ - -typedef struct { - gint ref_count; - char *prefix; /* Mr. */ - char *given; /* John */ - char *additional; /* Quinlan */ - char *family; /* Public */ - char *suffix; /* Esq. */ -} ECardName; - -typedef struct { - int year; - int month; - int day; -} ECardDate; - -/* TELECOMMUNICATIONS ADDRESSING PROPERTIES */ - -typedef enum { - E_CARD_PHONE_PREF = 1 << 0, - E_CARD_PHONE_WORK = 1 << 1, - E_CARD_PHONE_HOME = 1 << 2, - E_CARD_PHONE_VOICE = 1 << 3, - E_CARD_PHONE_FAX = 1 << 4, - E_CARD_PHONE_MSG = 1 << 5, - E_CARD_PHONE_CELL = 1 << 6, - E_CARD_PHONE_PAGER = 1 << 7, - E_CARD_PHONE_BBS = 1 << 8, - E_CARD_PHONE_MODEM = 1 << 9, - E_CARD_PHONE_CAR = 1 << 10, - E_CARD_PHONE_ISDN = 1 << 11, - E_CARD_PHONE_VIDEO = 1 << 12, - E_CARD_PHONE_ASSISTANT = 1 << 13, - E_CARD_PHONE_CALLBACK = 1 << 14, - E_CARD_PHONE_RADIO = 1 << 15, - E_CARD_PHONE_TELEX = 1 << 16, - E_CARD_PHONE_TTYTDD = 1 << 17, -} ECardPhoneFlags; - -typedef struct { - gint ref_count; - ECardPhoneFlags flags; - char *number; -} ECardPhone; - -/* DELIVERY ADDRESSING PROPERTIES */ - -typedef enum { - E_CARD_ADDR_HOME = 1 << 0, - E_CARD_ADDR_WORK = 1 << 1, - E_CARD_ADDR_POSTAL = 1 << 2, - E_CARD_ADDR_MASK = 7, - E_CARD_ADDR_PARCEL = 1 << 3, - E_CARD_ADDR_DOM = 1 << 4, - E_CARD_ADDR_INTL = 1 << 5, - E_CARD_ADDR_DEFAULT = 1 << 6 -} ECardAddressFlags; - -typedef struct { - gint ref_count; - ECardAddressFlags flags; - - char *po; - char *ext; - char *street; - char *city; - char *region; - char *code; - char *country; -} ECardDeliveryAddress; - -typedef struct { - gint ref_count; - ECardAddressFlags flags; - char *data; -} ECardAddrLabel; - -/* ARBITRARY PROPERTIES */ - -typedef struct { - gint ref_count; - char *key; - char *type; - char *value; -} ECardArbitrary; - -#endif /* __E_CARD_TYPES_H__ */ diff --git a/addressbook/backend/ebook/e-card.c b/addressbook/backend/ebook/e-card.c deleted file mode 100644 index ff2ecc9287..0000000000 --- a/addressbook/backend/ebook/e-card.c +++ /dev/null @@ -1,2807 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * Authors: - * Arturo Espinosa (arturo@nuclecu.unam.mx) - * Nat Friedman (nat@ximian.com) - * - * Copyright (C) 2000 Ximian, Inc. - * Copyright (C) 1999 The Free Software Foundation - */ - -#include <config.h> - -#include "e-card.h" - -#include <gal/widgets/e-unicode.h> - -#include <ctype.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <time.h> -#include <math.h> - -#include <bonobo/bonobo-i18n.h> -#include <gal/util/e-util.h> - -#include <libversit/vcc.h> -#include "e-util/ename/e-name-western.h" -#include "e-util/ename/e-address-western.h" -#include "e-book.h" - -#define is_a_prop_of(obj,prop) (isAPropertyOf ((obj),(prop))) -#define str_val(obj) (the_str = (vObjectValueType (obj))? fakeCString (vObjectUStringZValue (obj)) : calloc (1, 1)) -#define has(obj,prop) (vo = isAPropertyOf ((obj), (prop))) - -#define XEV_WANTS_HTML "X-MOZILLA-HTML" -#define XEV_ARBITRARY "X-EVOLUTION-ARBITRARY" -#define XEV_LIST "X-EVOLUTION-LIST" -#define XEV_LIST_SHOW_ADDRESSES "X-EVOLUTION-LIST-SHOW_ADDRESSES" -#define XEV_RELATED_CONTACTS "X-EVOLUTION-RELATED_CONTACTS" - -/* Object property IDs */ -enum { - PROP_0, - PROP_FILE_AS, - PROP_FULL_NAME, - PROP_NAME, - PROP_ADDRESS, - PROP_ADDRESS_LABEL, - PROP_PHONE, - PROP_EMAIL, - PROP_BIRTH_DATE, - PROP_URL, - PROP_ORG, - PROP_ORG_UNIT, - PROP_OFFICE, - PROP_TITLE, - PROP_ROLE, - PROP_MANAGER, - PROP_ASSISTANT, - PROP_NICKNAME, - PROP_SPOUSE, - PROP_ANNIVERSARY, - PROP_MAILER, - PROP_CALURI, - PROP_FBURL, - PROP_ICSCALENDAR, - PROP_NOTE, - PROP_RELATED_CONTACTS, - PROP_CATEGORIES, - PROP_CATEGORY_LIST, - PROP_WANTS_HTML, - PROP_WANTS_HTML_SET, - PROP_EVOLUTION_LIST, - PROP_EVOLUTION_LIST_SHOW_ADDRESSES, - PROP_ARBITRARY, - PROP_ID, - PROP_LAST_USE, - PROP_USE_SCORE, -}; - -static GObjectClass *parent_class; - -static void parse(ECard *card, VObject *vobj, char *default_charset); -static void e_card_init (ECard *card); -static void e_card_class_init (ECardClass *klass); - -static void e_card_dispose (GObject *object); -static void e_card_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec); -static void e_card_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec); - -static void assign_string(VObject *vobj, char *default_charset, char **string); - -char *e_v_object_get_child_value(VObject *vobj, char *name, char *default_charset); - -static void parse_bday(ECard *card, VObject *object, char *default_charset); -static void parse_full_name(ECard *card, VObject *object, char *default_charset); -static void parse_file_as(ECard *card, VObject *object, char *default_charset); -static void parse_name(ECard *card, VObject *object, char *default_charset); -static void parse_email(ECard *card, VObject *object, char *default_charset); -static void parse_phone(ECard *card, VObject *object, char *default_charset); -static void parse_address(ECard *card, VObject *object, char *default_charset); -static void parse_address_label(ECard *card, VObject *object, char *default_charset); -static void parse_url(ECard *card, VObject *object, char *default_charset); -static void parse_org(ECard *card, VObject *object, char *default_charset); -static void parse_office(ECard *card, VObject *object, char *default_charset); -static void parse_title(ECard *card, VObject *object, char *default_charset); -static void parse_role(ECard *card, VObject *object, char *default_charset); -static void parse_manager(ECard *card, VObject *object, char *default_charset); -static void parse_assistant(ECard *card, VObject *object, char *default_charset); -static void parse_nickname(ECard *card, VObject *object, char *default_charset); -static void parse_spouse(ECard *card, VObject *object, char *default_charset); -static void parse_anniversary(ECard *card, VObject *object, char *default_charset); -static void parse_mailer(ECard *card, VObject *object, char *default_charset); -static void parse_caluri(ECard *card, VObject *object, char *default_charset); -static void parse_fburl(ECard *card, VObject *object, char *default_charset); -static void parse_icscalendar(ECard *card, VObject *object, char *default_charset); -static void parse_note(ECard *card, VObject *object, char *default_charset); -static void parse_related_contacts(ECard *card, VObject *object, char *default_charset); -static void parse_categories(ECard *card, VObject *object, char *default_charset); -static void parse_wants_html(ECard *card, VObject *object, char *default_charset); -static void parse_list(ECard *card, VObject *object, char *default_charset); -static void parse_list_show_addresses(ECard *card, VObject *object, char *default_charset); -static void parse_arbitrary(ECard *card, VObject *object, char *default_charset); -static void parse_id(ECard *card, VObject *object, char *default_charset); -static void parse_last_use(ECard *card, VObject *object, char *default_charset); -static void parse_use_score(ECard *card, VObject *object, char *default_charset); - -static ECardPhoneFlags get_phone_flags (VObject *vobj); -static void set_phone_flags (VObject *vobj, ECardPhoneFlags flags); -static ECardAddressFlags get_address_flags (VObject *vobj); -static void set_address_flags (VObject *vobj, ECardAddressFlags flags); - -typedef void (* ParsePropertyFunc) (ECard *card, VObject *object, char *default_charset); - -struct { - char *key; - ParsePropertyFunc function; -} attribute_jump_array[] = -{ - { VCFullNameProp, parse_full_name }, - { "X-EVOLUTION-FILE-AS", parse_file_as }, - { VCNameProp, parse_name }, - { VCBirthDateProp, parse_bday }, - { VCEmailAddressProp, parse_email }, - { VCTelephoneProp, parse_phone }, - { VCAdrProp, parse_address }, - { VCDeliveryLabelProp, parse_address_label }, - { VCURLProp, parse_url }, - { VCOrgProp, parse_org }, - { "X-EVOLUTION-OFFICE", parse_office }, - { VCTitleProp, parse_title }, - { VCBusinessRoleProp, parse_role }, - { "X-EVOLUTION-MANAGER", parse_manager }, - { "X-EVOLUTION-ASSISTANT", parse_assistant }, - { "NICKNAME", parse_nickname }, - { "X-EVOLUTION-SPOUSE", parse_spouse }, - { "X-EVOLUTION-ANNIVERSARY", parse_anniversary }, - { VCMailerProp, parse_mailer }, - { "CALURI", parse_caluri }, - { "FBURL", parse_fburl }, - { "ICSCALENDAR", parse_icscalendar }, - { VCNoteProp, parse_note }, - { XEV_RELATED_CONTACTS, parse_related_contacts }, - { "CATEGORIES", parse_categories }, - { XEV_WANTS_HTML, parse_wants_html }, - { XEV_ARBITRARY, parse_arbitrary }, - { VCUniqueStringProp, parse_id }, - { "X-EVOLUTION-LAST-USE", parse_last_use }, - { "X-EVOLUTION-USE-SCORE", parse_use_score }, - { XEV_LIST, parse_list }, - { XEV_LIST_SHOW_ADDRESSES, parse_list_show_addresses }, - { VCUniqueStringProp, parse_id } -}; - -/** - * e_card_get_type: - * @void: - * - * Registers the &ECard class if necessary, and returns the type ID - * associated to it. - * - * Return value: The type ID of the &ECard class. - **/ -GType -e_card_get_type (void) -{ - static GType card_type = 0; - - if (!card_type) { - static const GTypeInfo card_info = { - sizeof (ECardClass), - NULL, /* base_init */ - NULL, /* base_finalize */ - (GClassInitFunc) e_card_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (ECard), - 0, /* n_preallocs */ - (GInstanceInitFunc) e_card_init, - }; - - card_type = g_type_register_static (G_TYPE_OBJECT, "ECard", &card_info, 0); - } - - return card_type; -} - -ECard * -e_card_new_with_default_charset (char *vcard, char *default_charset) -{ - ECard *card = g_object_new (E_TYPE_CARD, NULL); - VObject *vobj = Parse_MIME(vcard, strlen(vcard)); - while(vobj) { - VObject *next; - parse(card, vobj, default_charset); - next = nextVObjectInList(vobj); - cleanVObject(vobj); - vobj = next; - } - if (card->name == NULL) - card->name = e_card_name_new(); - if (card->file_as == NULL) - card->file_as = g_strdup(""); - if (card->fname == NULL) - card->fname = g_strdup(""); - return card; -} - -/** - * e_card_new: - * @vcard: a string in vCard format - * - * Returns: a new #ECard that wraps the @vcard. - */ -ECard * -e_card_new (char *vcard) -{ - return e_card_new_with_default_charset (vcard, "UTF-8"); -} - -ECard * -e_card_duplicate(ECard *card) -{ - char *vcard = e_card_get_vcard_assume_utf8(card); - ECard *new_card = e_card_new(vcard); - g_free (vcard); - - if (card->book) { - new_card->book = card->book; - g_object_ref (new_card->book); - } - - return new_card; -} - -static void -e_card_get_today (GDate *dt) -{ - time_t now; - struct tm *now_tm; - if (dt == NULL) - return; - - time (&now); - now_tm = localtime (&now); - - g_date_set_dmy (dt, now_tm->tm_mday, now_tm->tm_mon + 1, now_tm->tm_year + 1900); -} - -float -e_card_get_use_score(ECard *card) -{ - GDate today, last_use; - gint days_since_last_use; - - g_return_val_if_fail (card != NULL && E_IS_CARD (card), 0); - - if (card->last_use == NULL) - return 0.0; - - e_card_get_today (&today); - g_date_set_dmy (&last_use, card->last_use->day, card->last_use->month, card->last_use->year); - - days_since_last_use = g_date_get_julian (&today) - g_date_get_julian (&last_use); - - /* Apply a seven-day "grace period" to the use score decay. */ - days_since_last_use -= 7; - if (days_since_last_use < 0) - days_since_last_use = 0; - - return MAX (card->raw_use_score, 0) * exp (- days_since_last_use / 30.0); -} - -void -e_card_touch(ECard *card) -{ - GDate today; - double use_score; - - g_return_if_fail (card != NULL && E_IS_CARD (card)); - - e_card_get_today (&today); - use_score = e_card_get_use_score (card); - - if (card->last_use == NULL) - card->last_use = g_new (ECardDate, 1); - - card->last_use->day = g_date_get_day (&today); - card->last_use->month = g_date_get_month (&today); - card->last_use->year = g_date_get_year (&today); - - card->raw_use_score = use_score + 1.0; -} - -/** - * e_card_get_id: - * @card: an #ECard - * - * Returns: a string representing the id of the card, which is unique - * within its book. - */ -const char * -e_card_get_id (ECard *card) -{ - g_return_val_if_fail (card && E_IS_CARD (card), NULL); - - return card->id ? card->id : ""; -} - -/** - * e_card_get_id: - * @card: an #ECard - * @id: a id in string format - * - * Sets the identifier of a card, which should be unique within its - * book. - */ -void -e_card_set_id (ECard *card, const char *id) -{ - g_return_if_fail (card && E_IS_CARD (card)); - - if ( card->id ) - g_free(card->id); - card->id = g_strdup(id ? id : ""); -} - -EBook * -e_card_get_book (ECard *card) -{ - g_return_val_if_fail (card && E_IS_CARD (card), NULL); - - return card->book; -} - -void -e_card_set_book (ECard *card, EBook *book) -{ - g_return_if_fail (card && E_IS_CARD (card)); - - if (card->book) - g_object_unref (card->book); - card->book = book; - if (card->book) - g_object_ref (card->book); -} - -gchar * -e_card_date_to_string (ECardDate *dt) -{ - if (dt) - return g_strdup_printf ("%04d-%02d-%02d", - CLAMP(dt->year, 1000, 9999), - CLAMP(dt->month, 1, 12), - CLAMP(dt->day, 1, 31)); - else - return NULL; -} - -static VObject * -addPropValueUTF8(VObject *o, const char *p, const char *v) -{ - VObject *prop = addPropValue (o, p, v); - for (; *v; v++) { - if ((*v) & 0x80) { - addPropValue (prop, "CHARSET", "UTF-8"); - addProp(prop, VCQuotedPrintableProp); - - return prop; - } - if (*v == '\n') { - addProp(prop, VCQuotedPrintableProp); - for (; *v; v++) { - if ((*v) & 0x80) { - addPropValue (prop, "CHARSET", "UTF-8"); - return prop; - } - } - return prop; - } - } - return prop; -} - -static VObject * -addPropValueQP(VObject *o, const char *p, const char *v) -{ - VObject *prop = addPropValue (o, p, v); - for (; *v; v++) { - if (*v == '\n') { - addProp(prop, VCQuotedPrintableProp); - break; - } - } - return prop; -} - -static void -addPropValueSets (VObject *o, const char *p, const char *v, gboolean assumeUTF8, gboolean *is_ascii, gboolean *has_return) -{ - addPropValue (o, p, v); - if (*has_return && (assumeUTF8 || !*is_ascii)) - return; - if (*has_return) { - for (; *v; v++) { - if (*v & 0x80) { - *is_ascii = FALSE; - return; - } - } - return; - } - if (assumeUTF8 || !*is_ascii) { - for (; *v; v++) { - if (*v == '\n') { - *has_return = TRUE; - return; - } - } - return; - } - for (; *v; v++) { - if (*v & 0x80) { - *is_ascii = FALSE; - for (; *v; v++) { - if (*v == '\n') { - *has_return = TRUE; - return; - } - } - return; - } - if (*v == '\n') { - *has_return = TRUE; - for (; *v; v++) { - if (*v & 0x80) { - *is_ascii = FALSE; - return; - } - } - return; - } - } - return; -} - -#define ADD_PROP_VALUE(o, p, v) (assumeUTF8 ? (addPropValueQP ((o), (p), (v))) : addPropValueUTF8 ((o), (p), (v))) -#define ADD_PROP_VALUE_SET_IS_ASCII(o, p, v) (addPropValueSets ((o), (p), (v), assumeUTF8, &is_ascii, &has_return)) - - -static VObject * -e_card_get_vobject (const ECard *card, gboolean assumeUTF8) -{ - VObject *vobj; - - vobj = newVObject (VCCardProp); - - ADD_PROP_VALUE(vobj, VCVersionProp, "2.1"); - - if (card->file_as && *card->file_as) - ADD_PROP_VALUE(vobj, "X-EVOLUTION-FILE-AS", card->file_as); - else if (card->file_as) - addProp(vobj, "X-EVOLUTION-FILE_AS"); - - if (card->fname && *card->fname) - ADD_PROP_VALUE(vobj, VCFullNameProp, card->fname); - else if (card->fname) - addProp(vobj, VCFullNameProp); - - if ( card->name && (card->name->prefix || card->name->given || card->name->additional || card->name->family || card->name->suffix) ) { - VObject *nameprop; - gboolean is_ascii = TRUE; - gboolean has_return = FALSE; - nameprop = addProp(vobj, VCNameProp); - if ( card->name->prefix ) - ADD_PROP_VALUE_SET_IS_ASCII(nameprop, VCNamePrefixesProp, card->name->prefix); - if ( card->name->given ) - ADD_PROP_VALUE_SET_IS_ASCII(nameprop, VCGivenNameProp, card->name->given); - if ( card->name->additional ) - ADD_PROP_VALUE_SET_IS_ASCII(nameprop, VCAdditionalNamesProp, card->name->additional); - if ( card->name->family ) - ADD_PROP_VALUE_SET_IS_ASCII(nameprop, VCFamilyNameProp, card->name->family); - if ( card->name->suffix ) - ADD_PROP_VALUE_SET_IS_ASCII(nameprop, VCNameSuffixesProp, card->name->suffix); - if (has_return) - addProp(nameprop, VCQuotedPrintableProp); - if (!(is_ascii || assumeUTF8)) - addPropValue (nameprop, "CHARSET", "UTF-8"); - } - else if (card->name) - addProp(vobj, VCNameProp); - - - if ( card->address ) { - EIterator *iterator = e_list_get_iterator(card->address); - for ( ; e_iterator_is_valid(iterator) ;e_iterator_next(iterator) ) { - VObject *addressprop; - ECardDeliveryAddress *address = (ECardDeliveryAddress *) e_iterator_get(iterator); - gboolean is_ascii = TRUE; - gboolean has_return = FALSE; - - addressprop = addProp(vobj, VCAdrProp); - - set_address_flags (addressprop, address->flags); - if (address->po) - ADD_PROP_VALUE_SET_IS_ASCII(addressprop, VCPostalBoxProp, address->po); - if (address->ext) - ADD_PROP_VALUE_SET_IS_ASCII(addressprop, VCExtAddressProp, address->ext); - if (address->street) - ADD_PROP_VALUE_SET_IS_ASCII(addressprop, VCStreetAddressProp, address->street); - if (address->city) - ADD_PROP_VALUE_SET_IS_ASCII(addressprop, VCCityProp, address->city); - if (address->region) - ADD_PROP_VALUE_SET_IS_ASCII(addressprop, VCRegionProp, address->region); - if (address->code) - ADD_PROP_VALUE_SET_IS_ASCII(addressprop, VCPostalCodeProp, address->code); - if (address->country) - ADD_PROP_VALUE_SET_IS_ASCII(addressprop, VCCountryNameProp, address->country); - - if (has_return) - addProp(addressprop, VCQuotedPrintableProp); - if (!(is_ascii || assumeUTF8)) - addPropValue (addressprop, "CHARSET", "UTF-8"); - } - g_object_unref(iterator); - } - - if ( card->address_label ) { - EIterator *iterator = e_list_get_iterator(card->address_label); - for ( ; e_iterator_is_valid(iterator) ;e_iterator_next(iterator) ) { - VObject *labelprop; - ECardAddrLabel *address_label = (ECardAddrLabel *) e_iterator_get(iterator); - if (address_label->data) - labelprop = ADD_PROP_VALUE(vobj, VCDeliveryLabelProp, address_label->data); - else - labelprop = addProp(vobj, VCDeliveryLabelProp); - - set_address_flags (labelprop, address_label->flags); - } - g_object_unref(iterator); - } - - if ( card->phone ) { - EIterator *iterator = e_list_get_iterator(card->phone); - for ( ; e_iterator_is_valid(iterator) ;e_iterator_next(iterator) ) { - VObject *phoneprop; - ECardPhone *phone = (ECardPhone *) e_iterator_get(iterator); - phoneprop = ADD_PROP_VALUE(vobj, VCTelephoneProp, phone->number); - - set_phone_flags (phoneprop, phone->flags); - } - g_object_unref(iterator); - } - - if ( card->email ) { - EIterator *iterator = e_list_get_iterator(card->email); - for ( ; e_iterator_is_valid(iterator) ;e_iterator_next(iterator) ) { - VObject *emailprop; - emailprop = ADD_PROP_VALUE(vobj, VCEmailAddressProp, (char *) e_iterator_get(iterator)); - addProp (emailprop, VCInternetProp); - } - g_object_unref(iterator); - } - - if ( card->bday ) { - char *value; - value = e_card_date_to_string (card->bday); - ADD_PROP_VALUE(vobj, VCBirthDateProp, value); - g_free(value); - } - - if (card->url) - ADD_PROP_VALUE(vobj, VCURLProp, card->url); - - if (card->org || card->org_unit) { - VObject *orgprop; - gboolean is_ascii = TRUE; - gboolean has_return = FALSE; - orgprop = addProp(vobj, VCOrgProp); - - if (card->org) - ADD_PROP_VALUE_SET_IS_ASCII(orgprop, VCOrgNameProp, card->org); - if (card->org_unit) - ADD_PROP_VALUE_SET_IS_ASCII(orgprop, VCOrgUnitProp, card->org_unit); - - if (has_return) - addProp(orgprop, VCQuotedPrintableProp); - if (!(is_ascii || assumeUTF8)) - addPropValue (orgprop, "CHARSET", "UTF-8"); - } - - if (card->office) - ADD_PROP_VALUE(vobj, "X-EVOLUTION-OFFICE", card->office); - - if (card->title) - ADD_PROP_VALUE(vobj, VCTitleProp, card->title); - - if (card->role) - ADD_PROP_VALUE(vobj, VCBusinessRoleProp, card->role); - - if (card->manager) - ADD_PROP_VALUE(vobj, "X-EVOLUTION-MANAGER", card->manager); - - if (card->assistant) - ADD_PROP_VALUE(vobj, "X-EVOLUTION-ASSISTANT", card->assistant); - - if (card->nickname) - ADD_PROP_VALUE(vobj, "NICKNAME", card->nickname); - - if (card->spouse) - ADD_PROP_VALUE(vobj, "X-EVOLUTION-SPOUSE", card->spouse); - - if ( card->anniversary ) { - char *value; - value = e_card_date_to_string (card->anniversary); - ADD_PROP_VALUE(vobj, "X-EVOLUTION-ANNIVERSARY", value); - g_free(value); - } - - if (card->mailer) { - ADD_PROP_VALUE(vobj, VCMailerProp, card->mailer); - } - - if (card->caluri) - addPropValueQP(vobj, "CALURI", card->caluri); - - if (card->fburl) - ADD_PROP_VALUE(vobj, "FBURL", card->fburl); - - if (card->icscalendar) - ADD_PROP_VALUE(vobj, "ICSCALENDAR", card->icscalendar); - - if (card->note) { - VObject *noteprop; - - noteprop = ADD_PROP_VALUE(vobj, VCNoteProp, card->note); - } - - if (card->last_use) { - char *value; - value = e_card_date_to_string (card->last_use); - ADD_PROP_VALUE (vobj, "X-EVOLUTION-LAST-USE", value); - g_free (value); - } - - if (card->raw_use_score > 0) { - char *value; - value = g_strdup_printf ("%f", card->raw_use_score); - ADD_PROP_VALUE (vobj, "X-EVOLUTION-USE-SCORE", value); - g_free (value); - } - - if (card->related_contacts && *card->related_contacts) { - ADD_PROP_VALUE(vobj, XEV_RELATED_CONTACTS, card->related_contacts); - } - - if (card->categories) { - EIterator *iterator; - int length = 0; - char *string; - char *stringptr; - for (iterator = e_list_get_iterator(card->categories); e_iterator_is_valid(iterator); e_iterator_next(iterator)) { - length += strlen(e_iterator_get(iterator)) + 1; - } - string = g_new(char, length + 1); - stringptr = string; - *stringptr = 0; - for (e_iterator_reset(iterator); e_iterator_is_valid(iterator); e_iterator_next(iterator)) { - strcpy(stringptr, e_iterator_get(iterator)); - stringptr += strlen(stringptr); - *stringptr = ','; - stringptr++; - *stringptr = 0; - } - if (stringptr > string) { - stringptr --; - *stringptr = 0; - } - ADD_PROP_VALUE (vobj, "CATEGORIES", string); - g_free(string); - } - - if (card->wants_html_set) { - ADD_PROP_VALUE (vobj, XEV_WANTS_HTML, card->wants_html ? "TRUE" : "FALSE"); - } - - if (card->list) { - ADD_PROP_VALUE (vobj, XEV_LIST, "TRUE"); - ADD_PROP_VALUE (vobj, XEV_LIST_SHOW_ADDRESSES, card->list_show_addresses ? "TRUE" : "FALSE"); - } - - if (card->arbitrary) { - EIterator *iterator; - for (iterator = e_list_get_iterator(card->arbitrary); e_iterator_is_valid(iterator); e_iterator_next(iterator)) { - const ECardArbitrary *arbitrary = e_iterator_get(iterator); - VObject *arb_object; - if (arbitrary->value) { - arb_object = ADD_PROP_VALUE (vobj, XEV_ARBITRARY, arbitrary->value); - } else { - arb_object = addProp (vobj, XEV_ARBITRARY); - } - if (arbitrary->type) { - ADD_PROP_VALUE (arb_object, "TYPE", arbitrary->type); - } - if (arbitrary->key) { - addProp (arb_object, arbitrary->key); - } - } - } - - addPropValueQP (vobj, VCUniqueStringProp, (card->id ? card->id : "")); - - return vobj; -} - -/** - * e_card_get_vcard: - * @card: an #ECard - * - * Returns: a string in vCard format, which is wrapped by the @card. - */ -char * -e_card_get_vcard (ECard *card) -{ - VObject *vobj; - char *temp, *ret_val; - - vobj = e_card_get_vobject (card, FALSE); - temp = writeMemVObject(NULL, NULL, vobj); - ret_val = g_strdup(temp); - free(temp); - cleanVObject(vobj); - return ret_val; -} - -char * -e_card_get_vcard_assume_utf8 (ECard *card) -{ - VObject *vobj; - char *temp, *ret_val; - - vobj = e_card_get_vobject (card, TRUE); - temp = writeMemVObject(NULL, NULL, vobj); - ret_val = g_strdup(temp); - free(temp); - cleanVObject(vobj); - return ret_val; -} - -/** - * e_card_list_get_vcard: - * @list: a list of #ECards - * - * Returns: a string in vCard format. - */ -char * -e_card_list_get_vcard (const GList *list) -{ - VObject *vobj; - - char *temp, *ret_val; - - vobj = NULL; - - for (; list; list = list->next) { - VObject *tempvobj; - ECard *card = list->data; - - tempvobj = e_card_get_vobject (card, FALSE); - addList (&vobj, tempvobj); - } - temp = writeMemVObjects(NULL, NULL, vobj); - ret_val = g_strdup(temp); - free(temp); - cleanVObjects(vobj); - return ret_val; -} - -static void -parse_file_as(ECard *card, VObject *vobj, char *default_charset) -{ - if ( card->file_as ) - g_free(card->file_as); - assign_string(vobj, default_charset, &(card->file_as)); -} - -static void -parse_name(ECard *card, VObject *vobj, char *default_charset) -{ - e_card_name_unref(card->name); - - card->name = e_card_name_new(); - - card->name->family = e_v_object_get_child_value (vobj, VCFamilyNameProp, default_charset); - card->name->given = e_v_object_get_child_value (vobj, VCGivenNameProp, default_charset); - card->name->additional = e_v_object_get_child_value (vobj, VCAdditionalNamesProp, default_charset); - card->name->prefix = e_v_object_get_child_value (vobj, VCNamePrefixesProp, default_charset); - card->name->suffix = e_v_object_get_child_value (vobj, VCNameSuffixesProp, default_charset); -} - -static void -parse_full_name(ECard *card, VObject *vobj, char *default_charset) -{ - if ( card->fname ) - g_free(card->fname); - assign_string(vobj, default_charset, &(card->fname)); -} - -static void -parse_email(ECard *card, VObject *vobj, char *default_charset) -{ - char *next_email; - EList *list; - - assign_string(vobj, default_charset, &next_email); - g_object_get(card, - "email", &list, - NULL); - e_list_append(list, next_email); - g_free (next_email); - g_object_unref(list); -} - -/* Deal with charset */ -static void -parse_bday(ECard *card, VObject *vobj, char *default_charset) -{ - if ( vObjectValueType (vobj) ) { - char *str = fakeCString (vObjectUStringZValue (vobj)); - if ( card->bday ) - g_free(card->bday); - card->bday = g_new(ECardDate, 1); - *(card->bday) = e_card_date_from_string(str); - free(str); - } -} - -static void -parse_phone(ECard *card, VObject *vobj, char *default_charset) -{ - ECardPhone *next_phone = e_card_phone_new (); - EList *list; - - assign_string(vobj, default_charset, &(next_phone->number)); - next_phone->flags = get_phone_flags(vobj); - - g_object_get(card, - "phone", &list, - NULL); - e_list_append(list, next_phone); - e_card_phone_unref (next_phone); - g_object_unref(list); -} - -static void -parse_address(ECard *card, VObject *vobj, char *default_charset) -{ - ECardDeliveryAddress *next_addr = e_card_delivery_address_new (); - EList *list; - - next_addr->flags = get_address_flags (vobj); - next_addr->po = e_v_object_get_child_value (vobj, VCPostalBoxProp, default_charset); - next_addr->ext = e_v_object_get_child_value (vobj, VCExtAddressProp, default_charset); - next_addr->street = e_v_object_get_child_value (vobj, VCStreetAddressProp, default_charset); - next_addr->city = e_v_object_get_child_value (vobj, VCCityProp, default_charset); - next_addr->region = e_v_object_get_child_value (vobj, VCRegionProp, default_charset); - next_addr->code = e_v_object_get_child_value (vobj, VCPostalCodeProp, default_charset); - next_addr->country = e_v_object_get_child_value (vobj, VCCountryNameProp, default_charset); - - g_object_get(card, - "address", &list, - NULL); - e_list_append(list, next_addr); - e_card_delivery_address_unref (next_addr); - g_object_unref(list); -} - -static void -parse_address_label(ECard *card, VObject *vobj, char *default_charset) -{ - ECardAddrLabel *next_addr = e_card_address_label_new (); - EList *list; - - next_addr->flags = get_address_flags (vobj); - assign_string(vobj, default_charset, &next_addr->data); - - g_object_get(card, - "address_label", &list, - NULL); - e_list_append(list, next_addr); - e_card_address_label_unref (next_addr); - g_object_unref(list); -} - -static void -parse_url(ECard *card, VObject *vobj, char *default_charset) -{ - if (card->url) - g_free(card->url); - assign_string(vobj, default_charset, &(card->url)); -} - -static void -parse_org(ECard *card, VObject *vobj, char *default_charset) -{ - char *temp; - - temp = e_v_object_get_child_value(vobj, VCOrgNameProp, default_charset); - g_free(card->org); - card->org = temp; - - temp = e_v_object_get_child_value(vobj, VCOrgUnitProp, default_charset); - g_free(card->org_unit); - card->org_unit = temp; -} - -static void -parse_office(ECard *card, VObject *vobj, char *default_charset) -{ - if ( card->office ) - g_free(card->office); - assign_string(vobj, default_charset, &(card->office)); -} - -static void -parse_title(ECard *card, VObject *vobj, char *default_charset) -{ - if ( card->title ) - g_free(card->title); - assign_string(vobj, default_charset, &(card->title)); -} - -static void -parse_role(ECard *card, VObject *vobj, char *default_charset) -{ - if (card->role) - g_free(card->role); - assign_string(vobj, default_charset, &(card->role)); -} - -static void -parse_manager(ECard *card, VObject *vobj, char *default_charset) -{ - if ( card->manager ) - g_free(card->manager); - assign_string(vobj, default_charset, &(card->manager)); -} - -static void -parse_assistant(ECard *card, VObject *vobj, char *default_charset) -{ - if ( card->assistant ) - g_free(card->assistant); - assign_string(vobj, default_charset, &(card->assistant)); -} - -static void -parse_nickname(ECard *card, VObject *vobj, char *default_charset) -{ - if (card->nickname) - g_free(card->nickname); - assign_string(vobj, default_charset, &(card->nickname)); -} - -static void -parse_spouse(ECard *card, VObject *vobj, char *default_charset) -{ - if ( card->spouse ) - g_free(card->spouse); - assign_string(vobj, default_charset, &(card->spouse)); -} - -/* Deal with charset */ -static void -parse_anniversary(ECard *card, VObject *vobj, char *default_charset) -{ - if ( vObjectValueType (vobj) ) { - char *str = fakeCString (vObjectUStringZValue (vobj)); - if (card->anniversary) - g_free(card->anniversary); - card->anniversary = g_new(ECardDate, 1); - *(card->anniversary) = e_card_date_from_string(str); - free(str); - } -} - -static void -parse_mailer(ECard *card, VObject *vobj, char *default_charset) -{ - if ( card->mailer ) - g_free(card->mailer); - assign_string(vobj, default_charset, &(card->mailer)); -} - -static void -parse_caluri(ECard *card, VObject *vobj, char *default_charset) -{ - g_free(card->caluri); - assign_string(vobj, default_charset, &(card->caluri)); -} - -static void -parse_fburl(ECard *card, VObject *vobj, char *default_charset) -{ - g_free(card->fburl); - assign_string(vobj, default_charset, &(card->fburl)); -} - -static void -parse_icscalendar(ECard *card, VObject *vobj, char *default_charset) -{ - g_free(card->icscalendar); - assign_string(vobj, default_charset, &(card->icscalendar)); -} - -static void -parse_note(ECard *card, VObject *vobj, char *default_charset) -{ - g_free(card->note); - assign_string(vobj, default_charset, &(card->note)); -} - -static void -parse_related_contacts(ECard *card, VObject *vobj, char *default_charset) -{ - g_free(card->related_contacts); - assign_string(vobj, default_charset, &(card->related_contacts)); -} - -static void -add_list_unique(ECard *card, EList *list, char *string) -{ - char *temp = e_strdup_strip(string); - EIterator *iterator; - - if (!*temp) { - g_free(temp); - return; - } - for ( iterator = e_list_get_iterator(list); e_iterator_is_valid(iterator); e_iterator_next(iterator)) { - if (!strcmp(e_iterator_get(iterator), temp)) { - break; - } - } - if (!e_iterator_is_valid(iterator)) { - e_list_append(list, temp); - } - g_free(temp); - g_object_unref(iterator); -} - -static void -do_parse_categories(ECard *card, char *str) -{ - int length = strlen(str); - char *copy = g_new(char, length + 1); - int i, j; - EList *list; - g_object_get(card, - "category_list", &list, - NULL); - for (i = 0, j = 0; str[i]; i++, j++) { - switch (str[i]) { - case '\\': - i++; - if (str[i]) { - copy[j] = str[i]; - } else - i--; - break; - case ',': - copy[j] = 0; - add_list_unique(card, list, copy); - j = -1; - break; - default: - copy[j] = str[i]; - break; - } - } - copy[j] = 0; - add_list_unique(card, list, copy); - g_object_unref(list); - g_free(copy); -} - -/* Deal with charset */ -static void -parse_categories(ECard *card, VObject *vobj, char *default_charset) -{ - if ( vObjectValueType (vobj) ) { - char *str = fakeCString (vObjectUStringZValue (vobj)); - do_parse_categories(card, str); - free(str); - } -} - -/* Deal with charset */ -static void -parse_wants_html(ECard *card, VObject *vobj, char *default_charset) -{ - if ( vObjectValueType (vobj) ) { - char *str = fakeCString (vObjectUStringZValue (vobj)); - if (!strcasecmp(str, "true")) { - card->wants_html = TRUE; - card->wants_html_set = TRUE; - } - if (!strcasecmp(str, "false")) { - card->wants_html = FALSE; - card->wants_html_set = TRUE; - } - free(str); - } -} - -/* Deal with charset */ -static void -parse_list(ECard *card, VObject *vobj, char *default_charset) -{ - if ( vObjectValueType (vobj) ) { - char *str = fakeCString (vObjectUStringZValue (vobj)); - if (!strcasecmp(str, "true")) { - card->list = TRUE; - } - if (!strcasecmp(str, "false")) { - card->list = FALSE; - } - free(str); - } -} - -/* Deal with charset */ -static void -parse_list_show_addresses(ECard *card, VObject *vobj, char *default_charset) -{ - if ( vObjectValueType (vobj) ) { - char *str = fakeCString (vObjectUStringZValue (vobj)); - if (!strcasecmp(str, "true")) { - card->list_show_addresses = TRUE; - } - if (!strcasecmp(str, "false")) { - card->list_show_addresses = FALSE; - } - free(str); - } -} - -typedef union ValueItem { - const char *strs; - const wchar_t *ustrs; - unsigned int i; - unsigned long l; - void *any; - VObject *vobj; -} ValueItem; - -struct VObject { - VObject *next; - const char *id; - VObject *prop; - unsigned short valType; - ValueItem val; -}; - -static void -parse_arbitrary(ECard *card, VObject *vobj, char *default_charset) -{ - ECardArbitrary *arbitrary = e_card_arbitrary_new(); - VObjectIterator iterator; - EList *list; - for ( initPropIterator (&iterator, vobj); moreIteration(&iterator); ) { - VObject *temp = nextVObject(&iterator); - const char *name = vObjectName(temp); - if (name && !strcmp(name, "TYPE")) { - g_free(arbitrary->type); - assign_string(temp, default_charset, &(arbitrary->type)); - } else { - g_free(arbitrary->key); - arbitrary->key = g_strdup(name); - } - } - - assign_string(vobj, default_charset, &(arbitrary->value)); - - g_object_get(card, - "arbitrary", &list, - NULL); - e_list_append(list, arbitrary); - e_card_arbitrary_unref(arbitrary); - g_object_unref(list); -} - -static void -parse_id(ECard *card, VObject *vobj, char *default_charset) -{ - g_free(card->id); - assign_string(vobj, default_charset, &(card->id)); -} - -/* Deal with charset */ -static void -parse_last_use(ECard *card, VObject *vobj, char *default_charset) -{ - if ( vObjectValueType (vobj) ) { - char *str = fakeCString (vObjectUStringZValue (vobj)); - g_free(card->last_use); - card->last_use = g_new(ECardDate, 1); - *(card->last_use) = e_card_date_from_string(str); - free(str); - } -} - -/* Deal with charset */ -static void -parse_use_score(ECard *card, VObject *vobj, char *default_charset) -{ - card->raw_use_score = 0; - - if ( vObjectValueType (vobj) ) { - char *str = fakeCString (vObjectUStringZValue (vobj)); - card->raw_use_score = MAX(0, atof (str)); - free (str); - } -} - -static void -parse_attribute(ECard *card, VObject *vobj, char *default_charset) -{ - ParsePropertyFunc function = g_hash_table_lookup(E_CARD_GET_CLASS(card)->attribute_jump_table, vObjectName(vobj)); - if ( function ) - function(card, vobj, default_charset); -} - -static void -parse(ECard *card, VObject *vobj, char *default_charset) -{ - VObjectIterator iterator; - initPropIterator(&iterator, vobj); - while(moreIteration (&iterator)) { - parse_attribute(card, nextVObject(&iterator), default_charset); - } - if (!card->fname) { - card->fname = g_strdup(""); - } - if (!card->name) { - card->name = e_card_name_from_string(card->fname); - } - if (!card->file_as) { - ECardName *name = card->name; - char *strings[3], **stringptr; - char *string; - stringptr = strings; - if (name->family && *name->family) - *(stringptr++) = name->family; - if (name->given && *name->given) - *(stringptr++) = name->given; - *stringptr = NULL; - string = g_strjoinv(", ", strings); - card->file_as = string; - } -} - -static void -e_card_class_init (ECardClass *klass) -{ - int i; - GObjectClass *object_class; - - object_class = G_OBJECT_CLASS(klass); - - parent_class = g_type_class_ref (G_TYPE_OBJECT); - - klass->attribute_jump_table = g_hash_table_new(g_str_hash, g_str_equal); - - for ( i = 0; i < sizeof(attribute_jump_array) / sizeof(attribute_jump_array[0]); i++ ) { - g_hash_table_insert(klass->attribute_jump_table, attribute_jump_array[i].key, attribute_jump_array[i].function); - } - - object_class->dispose = e_card_dispose; - object_class->get_property = e_card_get_property; - object_class->set_property = e_card_set_property; - - g_object_class_install_property (object_class, PROP_FILE_AS, - g_param_spec_string ("file_as", - _("File As"), - /*_( */"XXX blurb" /*)*/, - NULL, - G_PARAM_READWRITE)); - - g_object_class_install_property (object_class, PROP_FULL_NAME, - g_param_spec_string ("full_name", - _("Full Name"), - /*_( */"XXX blurb" /*)*/, - NULL, - G_PARAM_READWRITE)); - - g_object_class_install_property (object_class, PROP_NAME, - g_param_spec_pointer ("name", - _("Name"), - /*_( */"XXX blurb" /*)*/, - G_PARAM_READWRITE)); - - g_object_class_install_property (object_class, PROP_ADDRESS, - g_param_spec_object ("address", - _("Address"), - /*_( */"XXX blurb" /*)*/, - E_TYPE_LIST, - G_PARAM_READABLE)); - - g_object_class_install_property (object_class, PROP_ADDRESS_LABEL, - g_param_spec_object ("address_label", - _("Address Label"), - /*_( */"XXX blurb" /*)*/, - E_TYPE_LIST, - G_PARAM_READABLE)); - - g_object_class_install_property (object_class, PROP_PHONE, - g_param_spec_object ("phone", - _("Phone"), - /*_( */"XXX blurb" /*)*/, - E_TYPE_LIST, - G_PARAM_READABLE)); - - g_object_class_install_property (object_class, PROP_EMAIL, - g_param_spec_object ("email", - _("Email"), - /*_( */"XXX blurb" /*)*/, - E_TYPE_LIST, - G_PARAM_READABLE)); - - g_object_class_install_property (object_class, PROP_BIRTH_DATE, - g_param_spec_pointer ("birth_date", - _("Birth date"), - /*_( */"XXX blurb" /*)*/, - G_PARAM_READWRITE)); - - g_object_class_install_property (object_class, PROP_URL, - g_param_spec_string ("url", - _("URL"), - /*_( */"XXX blurb" /*)*/, - NULL, - G_PARAM_READWRITE)); - - g_object_class_install_property (object_class, PROP_ORG, - g_param_spec_string ("org", - _("Organization"), - /*_( */"XXX blurb" /*)*/, - NULL, - G_PARAM_READWRITE)); - - g_object_class_install_property (object_class, PROP_ORG_UNIT, - g_param_spec_string ("org_unit", - _("Organizational Unit"), - /*_( */"XXX blurb" /*)*/, - NULL, - G_PARAM_READWRITE)); - - g_object_class_install_property (object_class, PROP_OFFICE, - g_param_spec_string ("office", - _("Office"), - /*_( */"XXX blurb" /*)*/, - NULL, - G_PARAM_READWRITE)); - - g_object_class_install_property (object_class, PROP_TITLE, - g_param_spec_string ("title", - _("Title"), - /*_( */"XXX blurb" /*)*/, - NULL, - G_PARAM_READWRITE)); - - g_object_class_install_property (object_class, PROP_ROLE, - g_param_spec_string ("role", - _("Role"), - /*_( */"XXX blurb" /*)*/, - NULL, - G_PARAM_READWRITE)); - - g_object_class_install_property (object_class, PROP_MANAGER, - g_param_spec_string ("manager", - _("Manager"), - /*_( */"XXX blurb" /*)*/, - NULL, - G_PARAM_READWRITE)); - - g_object_class_install_property (object_class, PROP_ASSISTANT, - g_param_spec_string ("assistant", - _("Assistant"), - /*_( */"XXX blurb" /*)*/, - NULL, - G_PARAM_READWRITE)); - - g_object_class_install_property (object_class, PROP_NICKNAME, - g_param_spec_string ("nickname", - _("Nickname"), - /*_( */"XXX blurb" /*)*/, - NULL, - G_PARAM_READWRITE)); - - g_object_class_install_property (object_class, PROP_SPOUSE, - g_param_spec_string ("spouse", - _("Spouse"), - /*_( */"XXX blurb" /*)*/, - NULL, - G_PARAM_READWRITE)); - - g_object_class_install_property (object_class, PROP_ANNIVERSARY, - g_param_spec_pointer ("anniversary", - _("Anniversary"), - /*_( */"XXX blurb" /*)*/, - G_PARAM_READWRITE)); - - g_object_class_install_property (object_class, PROP_MAILER, - g_param_spec_string ("mailer", - _("Mailer"), - /*_( */"XXX blurb" /*)*/, - NULL, - G_PARAM_READWRITE)); - - g_object_class_install_property (object_class, PROP_CALURI, - g_param_spec_string ("caluri", - _("Calendar URI"), - /*_( */"XXX blurb" /*)*/, - NULL, - G_PARAM_READWRITE)); - - g_object_class_install_property (object_class, PROP_FBURL, - g_param_spec_string ("fburl", - _("Free/Busy URL"), - /*_( */"XXX blurb" /*)*/, - NULL, - G_PARAM_READWRITE)); - - g_object_class_install_property (object_class, PROP_ICSCALENDAR, - g_param_spec_string ("icscalendar", - _("ICS Calendar"), - /*_( */"XXX blurb" /*)*/, - NULL, - G_PARAM_READWRITE)); - - g_object_class_install_property (object_class, PROP_NOTE, - g_param_spec_string ("note", - _("Note"), - /*_( */"XXX blurb" /*)*/, - NULL, - G_PARAM_READWRITE)); - - g_object_class_install_property (object_class, PROP_RELATED_CONTACTS, - g_param_spec_string ("related_contacts", - _("Related Contacts"), - /*_( */"XXX blurb" /*)*/, - NULL, - G_PARAM_READWRITE)); - - g_object_class_install_property (object_class, PROP_CATEGORIES, - g_param_spec_string ("categories", - _("Categories"), - /*_( */"XXX blurb" /*)*/, - NULL, - G_PARAM_READWRITE)); - - g_object_class_install_property (object_class, PROP_CATEGORY_LIST, - g_param_spec_object ("category list", - _("Category List"), - /*_( */"XXX blurb" /*)*/, - E_TYPE_LIST, - G_PARAM_READWRITE)); - - g_object_class_install_property (object_class, PROP_WANTS_HTML, - g_param_spec_boolean ("wants_html", - _("Wants HTML"), - /*_( */"XXX blurb" /*)*/, - FALSE, - G_PARAM_READWRITE)); - - g_object_class_install_property (object_class, PROP_WANTS_HTML_SET, - g_param_spec_boolean ("wants_html_set", - _("Wants HTML set"), - /*_( */"XXX blurb" /*)*/, - FALSE, - G_PARAM_READABLE)); - - g_object_class_install_property (object_class, PROP_EVOLUTION_LIST, - g_param_spec_boolean ("list", - _("List"), - /*_( */"XXX blurb" /*)*/, - FALSE, - G_PARAM_READWRITE)); - - g_object_class_install_property (object_class, PROP_EVOLUTION_LIST_SHOW_ADDRESSES, - g_param_spec_boolean ("list_show_addresses", - _("List Show Addresses"), - /*_( */"XXX blurb" /*)*/, - FALSE, - G_PARAM_READWRITE)); - - g_object_class_install_property (object_class, PROP_ARBITRARY, - g_param_spec_object ("arbitrary", - _("Arbitrary"), - /*_( */"XXX blurb" /*)*/, - E_TYPE_LIST, - G_PARAM_READWRITE)); - - g_object_class_install_property (object_class, PROP_ID, - g_param_spec_string ("id", - _("ID"), - /*_( */"XXX blurb" /*)*/, - NULL, - G_PARAM_READWRITE)); - - g_object_class_install_property (object_class, PROP_LAST_USE, - g_param_spec_pointer ("last_use", - _("Last Use"), - /*_( */"XXX blurb" /*)*/, - G_PARAM_READWRITE)); - - g_object_class_install_property (object_class, PROP_USE_SCORE, - /* XXX at some point we - should remove - LAX_VALIDATION and figure - out some hard min & max - scores. */ - g_param_spec_float ("use_score", - _("Use Score"), - /*_( */"XXX blurb" /*)*/, - 0.0, - 0.0, - 0.0, - G_PARAM_READWRITE | G_PARAM_LAX_VALIDATION)); -} - -ECardPhone * -e_card_phone_new (void) -{ - ECardPhone *newphone = g_new(ECardPhone, 1); - - newphone->ref_count = 1; - newphone->number = NULL; - newphone->flags = 0; - - return newphone; -} - -void -e_card_phone_unref (ECardPhone *phone) -{ - if (phone) { - phone->ref_count --; - if (phone->ref_count == 0) { - g_free(phone->number); - g_free(phone); - } - } -} - -ECardPhone * -e_card_phone_ref (const ECardPhone *phone) -{ - ECardPhone *phone_mutable = (ECardPhone *) phone; - if (phone_mutable) - phone_mutable->ref_count ++; - return phone_mutable; -} - -ECardPhone * -e_card_phone_copy (const ECardPhone *phone) -{ - if ( phone ) { - ECardPhone *phone_copy = e_card_phone_new(); - phone_copy->number = g_strdup(phone->number); - phone_copy->flags = phone->flags; - return phone_copy; - } else - return NULL; -} - -ECardDeliveryAddress * -e_card_delivery_address_new (void) -{ - ECardDeliveryAddress *newaddr = g_new(ECardDeliveryAddress, 1); - - newaddr->ref_count = 1; - newaddr->po = NULL; - newaddr->ext = NULL; - newaddr->street = NULL; - newaddr->city = NULL; - newaddr->region = NULL; - newaddr->code = NULL; - newaddr->country = NULL; - newaddr->flags = 0; - - return newaddr; -} - -void -e_card_delivery_address_unref (ECardDeliveryAddress *addr) -{ - if ( addr ) { - addr->ref_count --; - if (addr->ref_count == 0) { - g_free(addr->po); - g_free(addr->ext); - g_free(addr->street); - g_free(addr->city); - g_free(addr->region); - g_free(addr->code); - g_free(addr->country); - g_free(addr); - } - } -} - -ECardDeliveryAddress * -e_card_delivery_address_ref (const ECardDeliveryAddress *addr) -{ - ECardDeliveryAddress *addr_mutable = (ECardDeliveryAddress *) addr; - if (addr_mutable) - addr_mutable->ref_count ++; - return addr_mutable; -} - -ECardDeliveryAddress * -e_card_delivery_address_copy (const ECardDeliveryAddress *addr) -{ - if ( addr ) { - ECardDeliveryAddress *addr_copy = e_card_delivery_address_new (); - addr_copy->po = g_strdup(addr->po ); - addr_copy->ext = g_strdup(addr->ext ); - addr_copy->street = g_strdup(addr->street ); - addr_copy->city = g_strdup(addr->city ); - addr_copy->region = g_strdup(addr->region ); - addr_copy->code = g_strdup(addr->code ); - addr_copy->country = g_strdup(addr->country); - addr_copy->flags = addr->flags; - return addr_copy; - } else - return NULL; -} - -gboolean -e_card_delivery_address_is_empty (const ECardDeliveryAddress *addr) -{ - return (((addr->po == NULL) || (*addr->po == 0)) && - ((addr->ext == NULL) || (*addr->ext == 0)) && - ((addr->street == NULL) || (*addr->street == 0)) && - ((addr->city == NULL) || (*addr->city == 0)) && - ((addr->region == NULL) || (*addr->region == 0)) && - ((addr->code == NULL) || (*addr->code == 0)) && - ((addr->country == NULL) || (*addr->country == 0))); -} - -ECardDeliveryAddress * -e_card_delivery_address_from_label(const ECardAddrLabel *label) -{ - ECardDeliveryAddress *addr = e_card_delivery_address_new (); - EAddressWestern *western = e_address_western_parse (label->data); - - addr->po = g_strdup (western->po_box ); - addr->ext = g_strdup (western->extended ); - addr->street = g_strdup (western->street ); - addr->city = g_strdup (western->locality ); - addr->region = g_strdup (western->region ); - addr->code = g_strdup (western->postal_code); - addr->country = g_strdup (western->country ); - addr->flags = label->flags; - - e_address_western_free(western); - - return addr; -} - -char * -e_card_delivery_address_to_string(const ECardDeliveryAddress *addr) -{ - char *strings[5], **stringptr = strings; - char *line1, *line22, *line2; - char *final; - if (addr->po && *addr->po) - *(stringptr++) = addr->po; - if (addr->street && *addr->street) - *(stringptr++) = addr->street; - *stringptr = NULL; - line1 = g_strjoinv(" ", strings); - stringptr = strings; - if (addr->region && *addr->region) - *(stringptr++) = addr->region; - if (addr->code && *addr->code) - *(stringptr++) = addr->code; - *stringptr = NULL; - line22 = g_strjoinv(" ", strings); - stringptr = strings; - if (addr->city && *addr->city) - *(stringptr++) = addr->city; - if (line22 && *line22) - *(stringptr++) = line22; - *stringptr = NULL; - line2 = g_strjoinv(", ", strings); - stringptr = strings; - if (line1 && *line1) - *(stringptr++) = line1; - if (addr->ext && *addr->ext) - *(stringptr++) = addr->ext; - if (line2 && *line2) - *(stringptr++) = line2; - if (addr->country && *addr->country) - *(stringptr++) = addr->country; - *stringptr = NULL; - final = g_strjoinv("\n", strings); - g_free(line1); - g_free(line22); - g_free(line2); - return final; -} - -ECardAddrLabel * -e_card_delivery_address_to_label (const ECardDeliveryAddress *addr) -{ - ECardAddrLabel *label; - label = e_card_address_label_new(); - label->flags = addr->flags; - label->data = e_card_delivery_address_to_string(addr); - - return label; -} - -ECardAddrLabel * -e_card_address_label_new (void) -{ - ECardAddrLabel *newaddr = g_new(ECardAddrLabel, 1); - - newaddr->ref_count = 1; - newaddr->data = NULL; - newaddr->flags = 0; - - return newaddr; -} - -void -e_card_address_label_unref (ECardAddrLabel *addr) -{ - if (addr) { - addr->ref_count --; - if (addr->ref_count == 0) { - g_free(addr->data); - g_free(addr); - } - } -} - -ECardAddrLabel * -e_card_address_label_ref (const ECardAddrLabel *addr) -{ - ECardAddrLabel *addr_mutable = (ECardAddrLabel *) addr; - if (addr_mutable) - addr_mutable->ref_count ++; - return addr_mutable; -} - -ECardAddrLabel * -e_card_address_label_copy (const ECardAddrLabel *addr) -{ - if ( addr ) { - ECardAddrLabel *addr_copy = e_card_address_label_new (); - addr_copy->data = g_strdup(addr->data); - addr_copy->flags = addr->flags; - return addr_copy; - } else - return NULL; -} - -ECardName *e_card_name_new(void) -{ - ECardName *newname = g_new(ECardName, 1); - - newname->ref_count = 1; - newname->prefix = NULL; - newname->given = NULL; - newname->additional = NULL; - newname->family = NULL; - newname->suffix = NULL; - - return newname; -} - -void -e_card_name_unref(ECardName *name) -{ - if (name) { - name->ref_count --; - if (name->ref_count == 0) { - g_free (name->prefix); - g_free (name->given); - g_free (name->additional); - g_free (name->family); - g_free (name->suffix); - g_free (name); - } - } -} - -ECardName * -e_card_name_ref(const ECardName *name) -{ - ECardName *name_mutable = (ECardName *) name; - if (name_mutable) - name_mutable->ref_count ++; - return name_mutable; -} - -ECardName * -e_card_name_copy(const ECardName *name) -{ - if (name) { - ECardName *newname = e_card_name_new (); - - newname->prefix = g_strdup(name->prefix); - newname->given = g_strdup(name->given); - newname->additional = g_strdup(name->additional); - newname->family = g_strdup(name->family); - newname->suffix = g_strdup(name->suffix); - - return newname; - } else - return NULL; -} - - -char * -e_card_name_to_string(const ECardName *name) -{ - char *strings[6], **stringptr = strings; - - g_return_val_if_fail (name != NULL, NULL); - - if (name->prefix && *name->prefix) - *(stringptr++) = name->prefix; - if (name->given && *name->given) - *(stringptr++) = name->given; - if (name->additional && *name->additional) - *(stringptr++) = name->additional; - if (name->family && *name->family) - *(stringptr++) = name->family; - if (name->suffix && *name->suffix) - *(stringptr++) = name->suffix; - *stringptr = NULL; - return g_strjoinv(" ", strings); -} - -ECardName * -e_card_name_from_string(const char *full_name) -{ - ECardName *name = e_card_name_new (); - ENameWestern *western = e_name_western_parse (full_name); - - name->prefix = g_strdup (western->prefix); - name->given = g_strdup (western->first ); - name->additional = g_strdup (western->middle); - name->family = g_strdup (western->last ); - name->suffix = g_strdup (western->suffix); - - e_name_western_free(western); - - return name; -} - -ECardArbitrary * -e_card_arbitrary_new(void) -{ - ECardArbitrary *arbitrary = g_new(ECardArbitrary, 1); - arbitrary->ref_count = 1; - arbitrary->key = NULL; - arbitrary->type = NULL; - arbitrary->value = NULL; - return arbitrary; -} - -void -e_card_arbitrary_unref(ECardArbitrary *arbitrary) -{ - if (arbitrary) { - arbitrary->ref_count --; - if (arbitrary->ref_count == 0) { - g_free(arbitrary->key); - g_free(arbitrary->type); - g_free(arbitrary->value); - g_free(arbitrary); - } - } -} - -ECardArbitrary * -e_card_arbitrary_copy(const ECardArbitrary *arbitrary) -{ - if (arbitrary) { - ECardArbitrary *arb_copy = e_card_arbitrary_new (); - arb_copy->key = g_strdup(arbitrary->key); - arb_copy->type = g_strdup(arbitrary->type); - arb_copy->value = g_strdup(arbitrary->value); - return arb_copy; - } else - return NULL; -} - -ECardArbitrary * -e_card_arbitrary_ref(const ECardArbitrary *arbitrary) -{ - ECardArbitrary *arbitrary_mutable = (ECardArbitrary *) arbitrary; - if (arbitrary_mutable) - arbitrary_mutable->ref_count ++; - return arbitrary_mutable; -} - -/* EMail matching */ -static gboolean -e_card_email_match_single_string (const gchar *a, const gchar *b) -{ - const gchar *xa = NULL, *xb = NULL; - gboolean match = TRUE; - - for (xa=a; *xa && *xa != '@'; ++xa); - for (xb=b; *xb && *xb != '@'; ++xb); - - if (xa-a != xb-b || *xa != *xb || g_ascii_strncasecmp (a, b, xa-a)) - return FALSE; - - if (*xa == '\0') - return TRUE; - - /* Find the end of the string, then walk through backwards comparing. - This is so that we'll match joe@foobar.com and joe@mail.foobar.com. - */ - while (*xa) - ++xa; - while (*xb) - ++xb; - - while (match && *xa != '@' && *xb != '@') { - match = (tolower (*xa) == tolower (*xb)); - --xa; - --xb; - } - - match = match && ((tolower (*xa) == tolower (*xb)) || (*xa == '.') || (*xb == '.')); - - return match; -} - -gboolean -e_card_email_match_string (const ECard *card, const gchar *str) -{ - EIterator *iter; - - g_return_val_if_fail (card && E_IS_CARD (card), FALSE); - g_return_val_if_fail (str != NULL, FALSE); - - if (!card->email) - return FALSE; - - iter = e_list_get_iterator (card->email); - for (e_iterator_reset (iter); e_iterator_is_valid (iter); e_iterator_next (iter)) { - if (e_card_email_match_single_string (e_iterator_get (iter), str)) - return TRUE; - } - g_object_unref (iter); - - return FALSE; -} - -gint -e_card_email_find_number (const ECard *card, const gchar *email) -{ - EIterator *iter; - gint count = 0; - - g_return_val_if_fail (E_IS_CARD (card), -1); - g_return_val_if_fail (email != NULL, -1); - - if (!card->email) - return -1; - - iter = e_list_get_iterator (card->email); - for (e_iterator_reset (iter); e_iterator_is_valid (iter); e_iterator_next (iter)) { - if (!g_ascii_strcasecmp (e_iterator_get (iter), email)) - goto finished; - ++count; - } - count = -1; - - finished: - g_object_unref (iter); - - return count; -} - -/* - * ECard lifecycle management and vCard loading/saving. - */ - -static void -e_card_dispose (GObject *object) -{ - ECard *card = E_CARD(object); - -#define FREE_IF(x) do { if ((x)) { g_free (x); x = NULL; } } while (0) -#define UNREF_IF(x) do { if ((x)) { g_object_unref (x); x = NULL; } } while (0) - - FREE_IF (card->id); - UNREF_IF (card->book); - FREE_IF(card->file_as); - FREE_IF(card->fname); - if (card->name) { - e_card_name_unref(card->name); - card->name = NULL; - } - FREE_IF(card->bday); - - FREE_IF(card->url); - FREE_IF(card->org); - FREE_IF(card->org_unit); - FREE_IF(card->office); - FREE_IF(card->title); - FREE_IF(card->role); - FREE_IF(card->manager); - FREE_IF(card->assistant); - FREE_IF(card->nickname); - FREE_IF(card->spouse); - FREE_IF(card->anniversary); - FREE_IF(card->caluri); - FREE_IF(card->fburl); - FREE_IF(card->icscalendar); - FREE_IF(card->last_use); - FREE_IF(card->note); - FREE_IF(card->related_contacts); - - UNREF_IF (card->categories); - UNREF_IF (card->email); - UNREF_IF (card->phone); - UNREF_IF (card->address); - UNREF_IF (card->address_label); - - if (G_OBJECT_CLASS (parent_class)->dispose) - G_OBJECT_CLASS (parent_class)->dispose (object); -} - - -/* Set_arg handler for the card */ -static void -e_card_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - ECard *card; - - card = E_CARD (object); - - switch (prop_id) { - case PROP_FILE_AS: - g_free(card->file_as); - card->file_as = g_strdup(g_value_get_string (value)); - if (card->file_as == NULL) - card->file_as = g_strdup(""); - break; - - case PROP_FULL_NAME: - g_free(card->fname); - card->fname = g_strdup(g_value_get_string (value)); - if (card->fname == NULL) - card->fname = g_strdup(""); - - e_card_name_unref (card->name); - card->name = e_card_name_from_string (card->fname); - break; - case PROP_NAME: - e_card_name_unref (card->name); - card->name = e_card_name_ref(g_value_get_pointer (value)); - if (card->name == NULL) - card->name = e_card_name_new(); - if (card->fname == NULL) { - card->fname = e_card_name_to_string(card->name); - } - if (card->file_as == NULL) { - ECardName *name = card->name; - char *strings[3], **stringptr; - char *string; - stringptr = strings; - if (name->family && *name->family) - *(stringptr++) = name->family; - if (name->given && *name->given) - *(stringptr++) = name->given; - *stringptr = NULL; - string = g_strjoinv(", ", strings); - card->file_as = string; - } - break; - case PROP_CATEGORIES: - if (card->categories) - g_object_unref(card->categories); - card->categories = NULL; - if (g_value_get_string (value)) - do_parse_categories(card, (char*)g_value_get_string (value)); - break; - case PROP_CATEGORY_LIST: - if (card->categories) - g_object_unref(card->categories); - card->categories = E_LIST(g_value_get_object(value)); - if (card->categories) - g_object_ref(card->categories); - break; - case PROP_BIRTH_DATE: - g_free(card->bday); - if (g_value_get_pointer (value)) { - card->bday = g_new (ECardDate, 1); - memcpy (card->bday, g_value_get_pointer (value), sizeof (ECardDate)); - } else { - card->bday = NULL; - } - break; - case PROP_URL: - g_free(card->url); - card->url = g_strdup(g_value_get_string(value)); - break; - case PROP_ORG: - g_free(card->org); - card->org = g_strdup(g_value_get_string(value)); - break; - case PROP_ORG_UNIT: - g_free(card->org_unit); - card->org_unit = g_strdup(g_value_get_string(value)); - break; - case PROP_OFFICE: - g_free(card->office); - card->office = g_strdup(g_value_get_string(value)); - break; - case PROP_TITLE: - g_free(card->title); - card->title = g_strdup(g_value_get_string(value)); - break; - case PROP_ROLE: - g_free(card->role); - card->role = g_strdup(g_value_get_string(value)); - break; - case PROP_MANAGER: - g_free(card->manager); - card->manager = g_strdup(g_value_get_string(value)); - break; - case PROP_ASSISTANT: - g_free(card->assistant); - card->assistant = g_strdup(g_value_get_string(value)); - break; - case PROP_NICKNAME: - g_free(card->nickname); - card->nickname = g_strdup(g_value_get_string(value)); - break; - case PROP_SPOUSE: - g_free(card->spouse); - card->spouse = g_strdup(g_value_get_string(value)); - break; - case PROP_ANNIVERSARY: - g_free(card->anniversary); - if (g_value_get_pointer (value)) { - card->anniversary = g_new (ECardDate, 1); - memcpy (card->anniversary, g_value_get_pointer (value), sizeof (ECardDate)); - } else { - card->anniversary = NULL; - } - break; - case PROP_MAILER: - g_free(card->mailer); - card->mailer = g_strdup(g_value_get_string(value)); - break; - case PROP_CALURI: - g_free(card->caluri); - card->caluri = g_strdup(g_value_get_string(value)); - break; - case PROP_FBURL: - g_free(card->fburl); - card->fburl = g_strdup(g_value_get_string(value)); - break; - case PROP_ICSCALENDAR: - g_free(card->icscalendar); - card->icscalendar = g_strdup(g_value_get_string(value)); - break; - case PROP_NOTE: - g_free (card->note); - card->note = g_strdup(g_value_get_string(value)); - break; - case PROP_RELATED_CONTACTS: - g_free (card->related_contacts); - card->related_contacts = g_strdup(g_value_get_string(value)); - break; - case PROP_WANTS_HTML: - card->wants_html = g_value_get_boolean (value); - card->wants_html_set = TRUE; - break; - case PROP_ARBITRARY: - if (card->arbitrary) - g_object_unref(card->arbitrary); - card->arbitrary = E_LIST(g_value_get_pointer(value)); - if (card->arbitrary) - g_object_ref(card->arbitrary); - break; - case PROP_ID: - g_free(card->id); - card->id = g_strdup(g_value_get_string(value)); - if (card->id == NULL) - card->id = g_strdup (""); - break; - case PROP_LAST_USE: - g_free(card->last_use); - if (g_value_get_pointer (value)) { - card->last_use = g_new (ECardDate, 1); - memcpy (card->last_use, g_value_get_pointer (value), sizeof (ECardDate)); - } else { - card->last_use = NULL; - } - break; - case PROP_USE_SCORE: - card->raw_use_score = g_value_get_float (value); - break; - case PROP_EVOLUTION_LIST: - card->list = g_value_get_boolean (value); - break; - case PROP_EVOLUTION_LIST_SHOW_ADDRESSES: - card->list_show_addresses = g_value_get_boolean (value); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -/* Get_arg handler for the card */ -static void -e_card_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - ECard *card; - - card = E_CARD (object); - - switch (prop_id) { - case PROP_FILE_AS: - g_value_set_string (value, card->file_as); - break; - case PROP_FULL_NAME: - g_value_set_string (value, card->fname); - break; - case PROP_NAME: - g_value_set_pointer (value, card->name); - break; - case PROP_ADDRESS: - if (!card->address) - card->address = e_list_new((EListCopyFunc) e_card_delivery_address_ref, - (EListFreeFunc) e_card_delivery_address_unref, - NULL); - g_value_set_object (value, card->address); - break; - case PROP_ADDRESS_LABEL: - if (!card->address_label) - card->address_label = e_list_new((EListCopyFunc) e_card_address_label_ref, - (EListFreeFunc) e_card_address_label_unref, - NULL); - g_value_set_object (value, card->address_label); - break; - case PROP_PHONE: - if (!card->phone) - card->phone = e_list_new((EListCopyFunc) e_card_phone_ref, - (EListFreeFunc) e_card_phone_unref, - NULL); - g_value_set_object (value, card->phone); - break; - case PROP_EMAIL: - if (!card->email) - card->email = e_list_new((EListCopyFunc) g_strdup, - (EListFreeFunc) g_free, - NULL); - g_value_set_object (value, card->email); - break; - case PROP_CATEGORIES: - { - int i; - char ** strs; - int length; - EIterator *iterator; - if (!card->categories) - card->categories = e_list_new((EListCopyFunc) g_strdup, - (EListFreeFunc) g_free, - NULL); - length = e_list_length(card->categories); - strs = g_new(char *, length + 1); - for (iterator = e_list_get_iterator(card->categories), i = 0; e_iterator_is_valid(iterator); e_iterator_next(iterator), i++) { - strs[i] = (char *)e_iterator_get(iterator); - } - strs[i] = 0; - g_value_set_string_take_ownership(value, g_strjoinv(", ", strs)); - g_free(strs); - } - break; - case PROP_CATEGORY_LIST: - if (!card->categories) - card->categories = e_list_new((EListCopyFunc) g_strdup, - (EListFreeFunc) g_free, - NULL); - g_value_set_object (value, card->categories); - break; - case PROP_BIRTH_DATE: - g_value_set_pointer (value, card->bday); - break; - case PROP_URL: - g_value_set_string (value, card->url); - break; - case PROP_ORG: - g_value_set_string (value, card->org); - break; - case PROP_ORG_UNIT: - g_value_set_string (value, card->org_unit); - break; - case PROP_OFFICE: - g_value_set_string (value, card->office); - break; - case PROP_TITLE: - g_value_set_string (value, card->title); - break; - case PROP_ROLE: - g_value_set_string (value, card->role); - break; - case PROP_MANAGER: - g_value_set_string (value, card->manager); - break; - case PROP_ASSISTANT: - g_value_set_string (value, card->assistant); - break; - case PROP_NICKNAME: - g_value_set_string (value, card->nickname); - break; - case PROP_SPOUSE: - g_value_set_string (value, card->spouse); - break; - case PROP_ANNIVERSARY: - g_value_set_pointer (value, card->anniversary); - break; - case PROP_MAILER: - g_value_set_string (value, card->mailer); - break; - case PROP_CALURI: - g_value_set_string (value, card->caluri); - break; - case PROP_FBURL: - g_value_set_string (value, card->fburl); - break; - case PROP_ICSCALENDAR: - g_value_set_string (value, card->icscalendar); - break; - case PROP_NOTE: - g_value_set_string (value, card->note); - break; - case PROP_RELATED_CONTACTS: - g_value_set_string (value, card->related_contacts); - break; - case PROP_WANTS_HTML: - g_value_set_boolean (value, card->wants_html); - break; - case PROP_WANTS_HTML_SET: - g_value_set_boolean (value, card->wants_html_set); - break; - case PROP_ARBITRARY: - if (!card->arbitrary) - card->arbitrary = e_list_new((EListCopyFunc) e_card_arbitrary_ref, - (EListFreeFunc) e_card_arbitrary_unref, - NULL); - - g_value_set_object (value, card->arbitrary); - break; - case PROP_ID: - g_value_set_string (value, card->id); - break; - case PROP_LAST_USE: - g_value_set_pointer (value, card->last_use); - break; - case PROP_USE_SCORE: - g_value_set_float (value, e_card_get_use_score (card)); - break; - case PROP_EVOLUTION_LIST: - g_value_set_boolean (value, card->list); - break; - case PROP_EVOLUTION_LIST_SHOW_ADDRESSES: - g_value_set_boolean (value, card->list_show_addresses); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - - -/** - * e_card_init: - */ -static void -e_card_init (ECard *card) -{ - card->id = g_strdup(""); - - card->file_as = NULL; - card->fname = NULL; - card->name = NULL; - card->bday = NULL; - card->email = NULL; - card->phone = NULL; - card->address = NULL; - card->address_label = NULL; - card->url = NULL; - card->org = NULL; - card->org_unit = NULL; - card->office = NULL; - card->title = NULL; - card->role = NULL; - card->manager = NULL; - card->assistant = NULL; - card->nickname = NULL; - card->spouse = NULL; - card->anniversary = NULL; - card->mailer = NULL; - card->caluri = NULL; - card->fburl = NULL; - card->icscalendar = NULL; - card->note = NULL; - card->related_contacts = NULL; - card->categories = NULL; - card->wants_html = FALSE; - card->wants_html_set = FALSE; - card->list = FALSE; - card->list_show_addresses = FALSE; - card->arbitrary = NULL; - card->last_use = NULL; - card->raw_use_score = 0; -} - -GList * -e_card_load_cards_from_file_with_default_charset(const char *filename, char *default_charset) -{ - VObject *vobj = Parse_MIME_FromFileName((char *) filename); - GList *list = NULL; - while(vobj) { - VObject *next; - ECard *card = g_object_new (E_TYPE_CARD, NULL); - parse(card, vobj, default_charset); - next = nextVObjectInList(vobj); - cleanVObject(vobj); - vobj = next; - list = g_list_prepend(list, card); - } - list = g_list_reverse(list); - return list; -} - -GList * -e_card_load_cards_from_file(const char *filename) -{ - return e_card_load_cards_from_file_with_default_charset (filename, "UTF-8"); -} - -GList * -e_card_load_cards_from_string_with_default_charset(const char *str, char *default_charset) -{ - VObject *vobj = Parse_MIME(str, strlen (str)); - GList *list = NULL; - while(vobj) { - VObject *next; - ECard *card = g_object_new (E_TYPE_CARD, NULL); - parse(card, vobj, default_charset); - next = nextVObjectInList(vobj); - cleanVObject(vobj); - vobj = next; - list = g_list_prepend(list, card); - } - list = g_list_reverse(list); - return list; -} - -GList * -e_card_load_cards_from_string(const char *str) -{ - return e_card_load_cards_from_string_with_default_charset (str, "UTF-8"); -} - -void -e_card_free_empty_lists (ECard *card) -{ - if (card->address && e_list_length (card->address) == 0) { - g_object_unref (card->address); - card->address = NULL; - } - - if (card->address_label && e_list_length (card->address_label) == 0) { - g_object_unref (card->address_label); - card->address_label = NULL; - } - - if (card->phone && e_list_length (card->phone) == 0) { - g_object_unref (card->phone); - card->phone = NULL; - } - - if (card->email && e_list_length (card->email) == 0) { - g_object_unref (card->email); - card->email = NULL; - } - - if (card->categories && e_list_length (card->categories) == 0) { - g_object_unref (card->categories); - card->categories = NULL; - } - - if (card->arbitrary && e_list_length (card->arbitrary) == 0) { - g_object_unref (card->arbitrary); - card->arbitrary = NULL; - } -} - -static void -assign_string(VObject *vobj, char *default_charset, char **string) -{ - int type = vObjectValueType(vobj); - char *str; - char *charset = default_charset; - gboolean free_charset = FALSE; - VObject *charset_obj; - - if ((charset_obj = isAPropertyOf (vobj, "CHARSET"))) { - switch (vObjectValueType (charset_obj)) { - case VCVT_STRINGZ: - charset = (char *) vObjectStringZValue(charset_obj); - break; - case VCVT_USTRINGZ: - charset = fakeCString (vObjectUStringZValue (charset_obj)); - free_charset = TRUE; - break; - } - } - - switch(type) { - case VCVT_STRINGZ: - if (strcmp (charset, "UTF-8")) - *string = e_utf8_from_charset_string (charset, vObjectStringZValue(vobj)); - else - *string = g_strdup(vObjectStringZValue(vobj)); - break; - case VCVT_USTRINGZ: - str = fakeCString (vObjectUStringZValue (vobj)); - if (strcmp (charset, "UTF-8")) - *string = e_utf8_from_charset_string (charset, str); - else - *string = g_strdup(str); - free(str); - break; - default: - *string = g_strdup(""); - break; - } - - if (free_charset) { - free (charset); - } -} - - -ECardDate -e_card_date_from_string (const char *str) -{ - ECardDate date; - int length; - - date.year = 0; - date.month = 0; - date.day = 0; - - length = strlen(str); - - if (length == 10 ) { - date.year = str[0] * 1000 + str[1] * 100 + str[2] * 10 + str[3] - '0' * 1111; - date.month = str[5] * 10 + str[6] - '0' * 11; - date.day = str[8] * 10 + str[9] - '0' * 11; - } else if ( length == 8 ) { - date.year = str[0] * 1000 + str[1] * 100 + str[2] * 10 + str[3] - '0' * 1111; - date.month = str[4] * 10 + str[5] - '0' * 11; - date.day = str[6] * 10 + str[7] - '0' * 11; - } - - return date; -} - -char * -e_v_object_get_child_value(VObject *vobj, char *name, char *default_charset) -{ - char *ret_val; - VObjectIterator iterator; - gboolean free_charset = FALSE; - VObject *charset_obj; - - if ((charset_obj = isAPropertyOf (vobj, "CHARSET"))) { - switch (vObjectValueType (charset_obj)) { - case VCVT_STRINGZ: - default_charset = (char *) vObjectStringZValue(charset_obj); - break; - case VCVT_USTRINGZ: - default_charset = fakeCString (vObjectUStringZValue (charset_obj)); - free_charset = TRUE; - break; - } - } - - initPropIterator(&iterator, vobj); - while(moreIteration (&iterator)) { - VObject *attribute = nextVObject(&iterator); - const char *id = vObjectName(attribute); - if ( ! strcmp(id, name) ) { - assign_string(attribute, default_charset, &ret_val); - return ret_val; - } - } - if (free_charset) - free (default_charset); - - return NULL; -} - -static struct { - char *id; - ECardPhoneFlags flag; -} phone_pairs[] = { - { VCPreferredProp, E_CARD_PHONE_PREF }, - { VCWorkProp, E_CARD_PHONE_WORK }, - { VCHomeProp, E_CARD_PHONE_HOME }, - { VCVoiceProp, E_CARD_PHONE_VOICE }, - { VCFaxProp, E_CARD_PHONE_FAX }, - { VCMessageProp, E_CARD_PHONE_MSG }, - { VCCellularProp, E_CARD_PHONE_CELL }, - { VCPagerProp, E_CARD_PHONE_PAGER }, - { VCBBSProp, E_CARD_PHONE_BBS }, - { VCModemProp, E_CARD_PHONE_MODEM }, - { VCCarProp, E_CARD_PHONE_CAR }, - { VCISDNProp, E_CARD_PHONE_ISDN }, - { VCVideoProp, E_CARD_PHONE_VIDEO }, - { "X-EVOLUTION-ASSISTANT", E_CARD_PHONE_ASSISTANT }, - { "X-EVOLUTION-CALLBACK", E_CARD_PHONE_CALLBACK }, - { "X-EVOLUTION-RADIO", E_CARD_PHONE_RADIO }, - { "X-EVOLUTION-TELEX", E_CARD_PHONE_TELEX }, - { "X-EVOLUTION-TTYTDD", E_CARD_PHONE_TTYTDD }, -}; - -static ECardPhoneFlags -get_phone_flags (VObject *vobj) -{ - ECardPhoneFlags ret = 0; - int i; - - for (i = 0; i < sizeof(phone_pairs) / sizeof(phone_pairs[0]); i++) { - if (isAPropertyOf (vobj, phone_pairs[i].id)) { - ret |= phone_pairs[i].flag; - } - } - - return ret; -} - -static void -set_phone_flags (VObject *vobj, ECardPhoneFlags flags) -{ - int i; - - for (i = 0; i < sizeof(phone_pairs) / sizeof(phone_pairs[0]); i++) { - if (flags & phone_pairs[i].flag) { - addProp (vobj, phone_pairs[i].id); - } - } -} - -static struct { - char *id; - ECardAddressFlags flag; -} addr_pairs[] = { - { VCDomesticProp, E_CARD_ADDR_DOM }, - { VCInternationalProp, E_CARD_ADDR_INTL }, - { VCPostalProp, E_CARD_ADDR_POSTAL }, - { VCParcelProp, E_CARD_ADDR_PARCEL }, - { VCHomeProp, E_CARD_ADDR_HOME }, - { VCWorkProp, E_CARD_ADDR_WORK }, - { "PREF", E_CARD_ADDR_DEFAULT }, -}; - -static ECardAddressFlags -get_address_flags (VObject *vobj) -{ - ECardAddressFlags ret = 0; - int i; - - for (i = 0; i < sizeof(addr_pairs) / sizeof(addr_pairs[0]); i++) { - if (isAPropertyOf (vobj, addr_pairs[i].id)) { - ret |= addr_pairs[i].flag; - } - } - - return ret; -} - -static void -set_address_flags (VObject *vobj, ECardAddressFlags flags) -{ - int i; - - for (i = 0; i < sizeof(addr_pairs) / sizeof(addr_pairs[0]); i++) { - if (flags & addr_pairs[i].flag) { - addProp (vobj, addr_pairs[i].id); - } - } -} - -gboolean -e_card_evolution_list (ECard *card) -{ - g_return_val_if_fail (card && E_IS_CARD (card), FALSE); - return card->list; -} - -gboolean -e_card_evolution_list_show_addresses (ECard *card) -{ - g_return_val_if_fail (card && E_IS_CARD (card), FALSE); - return card->list_show_addresses; -} - -typedef struct _CardLoadData CardLoadData; -struct _CardLoadData { - gchar *card_id; - ECardCallback cb; - gpointer closure; -}; - -static void -get_card_cb (EBook *book, EBookStatus status, ECard *card, gpointer closure) -{ - CardLoadData *data = (CardLoadData *) closure; - - if (data->cb != NULL) { - if (status == E_BOOK_STATUS_SUCCESS) - data->cb (card, data->closure); - else - data->cb (NULL, data->closure); - } - - g_free (data->card_id); - g_free (data); -} - -static void -card_load_cb (EBook *book, EBookStatus status, gpointer closure) -{ - CardLoadData *data = (CardLoadData *) closure; - - if (status == E_BOOK_STATUS_SUCCESS) - e_book_get_card (book, data->card_id, get_card_cb, closure); - else { - data->cb (NULL, data->closure); - g_free (data->card_id); - g_free (data); - } -} - -void -e_card_load_uri (const gchar *book_uri, const gchar *uid, ECardCallback cb, gpointer closure) -{ - CardLoadData *data; - EBook *book; - - data = g_new (CardLoadData, 1); - data->card_id = g_strdup (uid); - data->cb = cb; - data->closure = closure; - - book = e_book_new (); - e_book_load_uri (book, book_uri, card_load_cb, data); -} diff --git a/addressbook/backend/ebook/e-card.h b/addressbook/backend/ebook/e-card.h deleted file mode 100644 index d82d5f4cb6..0000000000 --- a/addressbook/backend/ebook/e-card.h +++ /dev/null @@ -1,209 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * Authors: - * Chris Lahey <clahey@ximian.com> - * Arturo Espinosa - * Nat Friedman (nat@ximian.com) - * - * Copyright (C) 2000 Ximian, Inc. - * Copyright (C) 1999 The Free Software Foundation - */ - -#ifndef __E_CARD_H__ -#define __E_CARD_H__ - -#include <time.h> -#include <glib-object.h> -#include <stdio.h> -#include <ebook/e-card-types.h> -#include <e-util/e-list.h> - -#define E_TYPE_CARD (e_card_get_type ()) -#define E_CARD(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_TYPE_CARD, ECard)) -#define E_CARD_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), E_TYPE_CARD, ECardClass)) -#define E_IS_CARD(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), E_TYPE_CARD)) -#define E_IS_CARD_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), E_TYPE_CARD)) -#define E_CARD_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), E_TYPE_CARD, ECardClass)) - -typedef struct _ECard ECard; -typedef struct _ECardClass ECardClass; - -struct _EBook; /* Forward reference */ - -struct _ECard { - GObject object; - char *id; - - struct _EBook *book; /* The EBook this card is from. */ - - char *file_as; /* The File As field. */ - char *fname; /* The full name. */ - ECardName *name; /* The structured name. */ - EList *address; /* Delivery addresses (ECardDeliveryAddress *) */ - EList *address_label; /* Delivery address labels - * (ECardAddrLabel *) */ - - EList *phone; /* Phone numbers (ECardPhone *) */ - EList *email; /* Email addresses (char *) */ - char *url; /* The person's web page. */ - - ECardDate *bday; /* The person's birthday. */ - - char *note; - - - char *org; /* The person's organization. */ - char *org_unit; /* The person's organization unit. */ - char *office; /* The person's office. */ - char *role; /* The person's role w/in his org */ - char *title; /* The person's title w/in his org */ - - char *manager; - char *assistant; - - char *nickname; /* The person's nickname */ - - char *spouse; /* The person's spouse. */ - ECardDate *anniversary; /* The person's anniversary. */ - - char *mailer; /* Mailer */ - - char *caluri; /* Calendar URI */ - char *fburl; /* Free Busy URL */ - char *icscalendar; /* Default server calendar */ - - gint timezone; /* number of minutes from UTC as an int */ - - ECardDate *last_use; - float raw_use_score; - - char *related_contacts; /* EDestinationV (serialized) of related contacts. */ - - EList *categories; /* Categories. */ - - EList *arbitrary; /* Arbitrary fields. */ - - - - guint32 wants_html : 1; /* Wants html mail. */ - guint32 wants_html_set : 1; /* Wants html mail. */ - guint32 list : 1; /* If the card corresponds to a contact list */ - guint32 list_show_addresses : 1; /* Whether to show the addresses - in the To: or Bcc: field */ - -#if 0 - ECardPhoto *logo; /* This person's org's logo. */ - - ECardPhoto *photo; /* A photo of the person. */ - - ECard *agent; /* A person who sereves as this - guy's agent/secretary/etc. */ - - ECardSound *sound; - - ECardKey *key; /* The person's public key. */ - ECardTimeZone *timezn; /* The person's time zone. */ - ECardGeoPos *geopos; /* The person's long/lat. */ - - ECardRev *rev; /* The time this card was last - modified. */ - - EList xtension; -#endif -}; - -struct _ECardClass { - GObjectClass parent_class; - GHashTable *attribute_jump_table; -}; - - -/* Simple functions */ -ECard *e_card_new (char *vcard); /* Assumes utf8 */ -ECard *e_card_new_with_default_charset (char *vcard, - char *default_charset); -const char *e_card_get_id (ECard *card); -void e_card_set_id (ECard *card, - const char *character); - -struct _EBook *e_card_get_book (ECard *card); -void e_card_set_book (ECard *card, - struct _EBook *book); -char *e_card_get_vcard (ECard *card); -char *e_card_get_vcard_assume_utf8 (ECard *card); -char *e_card_list_get_vcard (const GList *list); -ECard *e_card_duplicate (ECard *card); -float e_card_get_use_score (ECard *card); -void e_card_touch (ECard *card); - -/* Evolution List convenience functions */ -/* used for encoding uids in email addresses */ -gboolean e_card_evolution_list (ECard *card); -gboolean e_card_evolution_list_show_addresses (ECard *card); - -/* ECardPhone manipulation */ -ECardPhone *e_card_phone_new (void); -ECardPhone *e_card_phone_copy (const ECardPhone *phone); -ECardPhone *e_card_phone_ref (const ECardPhone *phone); -void e_card_phone_unref (ECardPhone *phone); - -/* ECardDeliveryAddress manipulation */ -ECardDeliveryAddress *e_card_delivery_address_new (void); -ECardDeliveryAddress *e_card_delivery_address_copy (const ECardDeliveryAddress *addr); -ECardDeliveryAddress *e_card_delivery_address_ref (const ECardDeliveryAddress *addr); -void e_card_delivery_address_unref (ECardDeliveryAddress *addr); -gboolean e_card_delivery_address_is_empty (const ECardDeliveryAddress *addr); -char *e_card_delivery_address_to_string (const ECardDeliveryAddress *addr); -ECardDeliveryAddress *e_card_delivery_address_from_label (const ECardAddrLabel *label); -ECardAddrLabel *e_card_delivery_address_to_label (const ECardDeliveryAddress *addr); - -/* ECardAddrLabel manipulation */ -ECardAddrLabel *e_card_address_label_new (void); -ECardAddrLabel *e_card_address_label_copy (const ECardAddrLabel *addr); -ECardAddrLabel *e_card_address_label_ref (const ECardAddrLabel *addr); -void e_card_address_label_unref (ECardAddrLabel *addr); - -/* ECardName manipulation */ -ECardName *e_card_name_new (void); -ECardName *e_card_name_copy (const ECardName *name); -ECardName *e_card_name_ref (const ECardName *name); -void e_card_name_unref (ECardName *name); -char *e_card_name_to_string (const ECardName *name); -ECardName *e_card_name_from_string (const char *full_name); - -/* ECardDate */ -ECardDate e_card_date_from_string (const gchar *str); -gchar *e_card_date_to_string (ECardDate *dt); - -/* ECardArbitrary manipulation */ -ECardArbitrary *e_card_arbitrary_new (void); -ECardArbitrary *e_card_arbitrary_copy (const ECardArbitrary *arbitrary); -ECardArbitrary *e_card_arbitrary_ref (const ECardArbitrary *arbitrary); -void e_card_arbitrary_unref (ECardArbitrary *arbitrary); - -/* ECard email manipulation */ -gboolean e_card_email_match_string (const ECard *card, - const gchar *str); -gint e_card_email_find_number (const ECard *card, - const gchar *email); - -/* Specialized functionality */ -GList *e_card_load_cards_from_file (const char *filename); -GList *e_card_load_cards_from_file_with_default_charset (const char *filename, - char *default_charset); -GList *e_card_load_cards_from_string (const char *str); -GList *e_card_load_cards_from_string_with_default_charset (const char *str, - char *default_charset); -void e_card_free_empty_lists (ECard *card); - -/* Getting ECards via their URIs */ -typedef void (*ECardCallback) (ECard *card, gpointer closure); -void e_card_load_uri (const gchar *book_uri, - const gchar *uid, - ECardCallback cb, - gpointer closure); - - -GType e_card_get_type (void); - -#endif /* ! __E_CARD_H__ */ diff --git a/addressbook/backend/ebook/e-destination.c b/addressbook/backend/ebook/e-destination.c deleted file mode 100644 index 7ddae75b48..0000000000 --- a/addressbook/backend/ebook/e-destination.c +++ /dev/null @@ -1,1695 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -/* - * e-destination.c - * - * Copyright (C) 2001 Ximian, Inc. - * - * Developed by Jon Trowbridge <trow@ximian.com> - */ - -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA. - */ - -#include <config.h> -#include "e-destination.h" - -#include <stdlib.h> -#include <ctype.h> -#include <string.h> -#include "e-book.h" -#include "e-book-marshal.h" -#include "e-book-util.h" -#include <gal/widgets/e-unicode.h> - -#include <glib.h> -#include <libxml/xmlmemory.h> -#include <camel/camel-internet-address.h> - -#define d(x) - -enum { - CHANGED, - CARDIFIED, - LAST_SIGNAL -}; - -guint e_destination_signals[LAST_SIGNAL] = { 0 }; - -struct _EDestinationPrivate { - gchar *raw; - - gchar *book_uri; - gchar *card_uid; - ECard *card; - gint card_email_num; - - ECard *old_card; - gint old_card_email_num; - gchar *old_textrep; - - gchar *name; - gchar *email; - gchar *addr; - gchar *textrep; - - GList *list_dests; - - guint html_mail_override : 1; - guint wants_html_mail : 1; - - guint show_addresses : 1; - - guint has_been_cardified : 1; - guint allow_cardify : 1; - guint cannot_cardify : 1; - guint auto_recipient : 1; - guint pending_cardification; - - guint pending_change : 1; - - EBook *cardify_book; - - gint freeze_count; -}; - -static void e_destination_clear_card (EDestination *); -static void e_destination_clear_strings (EDestination *); - -static GObjectClass *parent_class; - -static void -e_destination_dispose (GObject *obj) -{ - EDestination *dest = E_DESTINATION (obj); - - if (dest->priv) { - e_destination_clear (dest); - - if (dest->priv->old_card) - g_object_unref (dest->priv->old_card); - - if (dest->priv->cardify_book) - g_object_unref (dest->priv->cardify_book); - - g_free (dest->priv->old_textrep); - - g_free (dest->priv); - dest->priv = NULL; - } -} - -static void -e_destination_class_init (EDestinationClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - parent_class = g_type_class_ref (G_TYPE_OBJECT); - - object_class->dispose = e_destination_dispose; - - e_destination_signals[CHANGED] = - g_signal_new ("changed", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (EDestinationClass, changed), - NULL, NULL, - e_book_marshal_NONE__NONE, - G_TYPE_NONE, 0); - - e_destination_signals[CARDIFIED] = - g_signal_new ("cardified", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (EDestinationClass, cardified), - NULL, NULL, - e_book_marshal_NONE__NONE, - G_TYPE_NONE, 0); -} - -static void -e_destination_init (EDestination *dest) -{ - dest->priv = g_new0 (struct _EDestinationPrivate, 1); - - dest->priv->allow_cardify = TRUE; - dest->priv->cannot_cardify = FALSE; - dest->priv->auto_recipient = FALSE; - dest->priv->pending_cardification = 0; -} - -GType -e_destination_get_type (void) -{ - static GType dest_type = 0; - - if (!dest_type) { - GTypeInfo dest_info = { - sizeof (EDestinationClass), - NULL, /* base_class_init */ - NULL, /* base_class_finalize */ - (GClassInitFunc) e_destination_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (EDestination), - 0, /* n_preallocs */ - (GInstanceInitFunc) e_destination_init - }; - - dest_type = g_type_register_static (G_TYPE_OBJECT, "EDestination", &dest_info, 0); - } - - return dest_type; -} - -EDestination * -e_destination_new (void) -{ - return g_object_new (E_TYPE_DESTINATION, NULL); -} - -static void -e_destination_freeze (EDestination *dest) -{ - g_return_if_fail (E_IS_DESTINATION (dest)); - g_return_if_fail (dest->priv->freeze_count >= 0); - - dest->priv->freeze_count++; -} - -static void -e_destination_thaw (EDestination *dest) -{ - g_return_if_fail (E_IS_DESTINATION (dest)); - g_return_if_fail (dest->priv->freeze_count > 0); - - dest->priv->freeze_count--; - if (dest->priv->freeze_count == 0 && dest->priv->pending_change) - e_destination_changed (dest); -} - -void -e_destination_changed (EDestination *dest) -{ - if (dest->priv->freeze_count == 0) { - g_signal_emit (dest, e_destination_signals[CHANGED], 0); - dest->priv->pending_change = FALSE; - dest->priv->cannot_cardify = FALSE; - - } else { - dest->priv->pending_change = TRUE; - } -} - -EDestination * -e_destination_copy (const EDestination *dest) -{ - EDestination *new_dest; - GList *iter; - - g_return_val_if_fail (dest && E_IS_DESTINATION (dest), NULL); - - new_dest = e_destination_new (); - - new_dest->priv->book_uri = g_strdup (dest->priv->book_uri); - new_dest->priv->card_uid = g_strdup (dest->priv->card_uid); - new_dest->priv->name = g_strdup (dest->priv->name); - new_dest->priv->email = g_strdup (dest->priv->email); - new_dest->priv->addr = g_strdup (dest->priv->addr); - new_dest->priv->card_email_num = dest->priv->card_email_num; - new_dest->priv->old_card_email_num = dest->priv->old_card_email_num; - new_dest->priv->old_textrep = g_strdup (dest->priv->old_textrep); - - new_dest->priv->card = dest->priv->card; - if (new_dest->priv->card) - g_object_ref (new_dest->priv->card); - - new_dest->priv->old_card = dest->priv->old_card; - if (new_dest->priv->old_card) - g_object_ref (new_dest->priv->old_card); - - new_dest->priv->html_mail_override = dest->priv->html_mail_override; - new_dest->priv->wants_html_mail = dest->priv->wants_html_mail; - - for (iter = dest->priv->list_dests; iter != NULL; iter = g_list_next (iter)) { - new_dest->priv->list_dests = g_list_append (new_dest->priv->list_dests, - e_destination_copy (E_DESTINATION (iter->data))); - } - - return new_dest; -} - -static void -e_destination_clear_card (EDestination *dest) -{ - if (dest->priv->card) { - if (dest->priv->old_card) - g_object_unref (dest->priv->old_card); - - dest->priv->old_card = dest->priv->card; - dest->priv->old_card_email_num = dest->priv->card_email_num; - - g_free (dest->priv->old_textrep); - dest->priv->old_textrep = g_strdup (e_destination_get_textrep (dest, FALSE)); - } - - g_free (dest->priv->book_uri); - dest->priv->book_uri = NULL; - g_free (dest->priv->card_uid); - dest->priv->card_uid = NULL; - - dest->priv->card = NULL; - dest->priv->card_email_num = -1; - - g_list_foreach (dest->priv->list_dests, (GFunc) g_object_unref, NULL); - g_list_free (dest->priv->list_dests); - dest->priv->list_dests = NULL; - - dest->priv->allow_cardify = TRUE; - dest->priv->cannot_cardify = FALSE; - - e_destination_cancel_cardify (dest); - - e_destination_changed (dest); -} - -static void -e_destination_clear_strings (EDestination *dest) -{ - g_free (dest->priv->raw); - dest->priv->raw = NULL; - - g_free (dest->priv->name); - dest->priv->name = NULL; - - g_free (dest->priv->email); - dest->priv->email = NULL; - - g_free (dest->priv->addr); - dest->priv->addr = NULL; - - g_free (dest->priv->textrep); - dest->priv->textrep = NULL; - - e_destination_changed (dest); -} - -void -e_destination_clear (EDestination *dest) -{ - g_return_if_fail (dest && E_IS_DESTINATION (dest)); - - e_destination_freeze (dest); - - e_destination_clear_card (dest); - e_destination_clear_strings (dest); - - e_destination_thaw (dest); -} - -static gboolean -nonempty (const gchar *s) -{ - gunichar c; - while (*s) { - c = g_utf8_get_char (s); - if (!g_unichar_isspace (c)) - return TRUE; - s = g_utf8_next_char (s); - } - return FALSE; -} - -gboolean -e_destination_is_empty (const EDestination *dest) - -{ - struct _EDestinationPrivate *p; - - g_return_val_if_fail (E_IS_DESTINATION (dest), TRUE); - - p = dest->priv; - - return !(p->card != NULL - || (p->book_uri && *p->book_uri) - || (p->card_uid && *p->card_uid) - || (p->raw && nonempty (p->raw)) - || (p->name && nonempty (p->name)) - || (p->email && nonempty (p->email)) - || (p->addr && nonempty (p->addr)) - || (p->list_dests != NULL)); -} - -gboolean -e_destination_is_valid (const EDestination *dest) -{ - const char *email; - - g_return_val_if_fail (E_IS_DESTINATION (dest), FALSE); - - if (e_destination_from_card (dest)) - return TRUE; - - email = e_destination_get_email (dest); - - /* FIXME: if we really wanted to get fancy here, we could - check to make sure that the address was valid according to - rfc822's addr-spec grammar. */ - - return email && *email && strchr (email, '@'); -} - -gboolean -e_destination_equal (const EDestination *a, const EDestination *b) -{ - const struct _EDestinationPrivate *pa, *pb; - const char *na, *nb; - - g_return_val_if_fail (E_IS_DESTINATION (a), FALSE); - g_return_val_if_fail (E_IS_DESTINATION (b), FALSE); - - if (a == b) - return TRUE; - - pa = a->priv; - pb = b->priv; - - /* Check equality of cards. */ - if (pa->card || pb->card) { - if (! (pa->card && pb->card)) - return FALSE; - - if (pa->card == pb->card || !strcmp (e_card_get_id (pa->card), e_card_get_id (pb->card))) - return TRUE; - - return FALSE; - } - - /* Just in case name returns NULL */ - na = e_destination_get_name (a); - nb = e_destination_get_name (b); - if ((na || nb) && !(na && nb && ! e_utf8_casefold_collate (na, nb))) - return FALSE; - - if (!g_ascii_strcasecmp (e_destination_get_email (a), e_destination_get_email (b))) - return TRUE; - else - return FALSE; -} - -void -e_destination_set_card (EDestination *dest, ECard *card, gint email_num) -{ - g_return_if_fail (dest && E_IS_DESTINATION (dest)); - g_return_if_fail (card && E_IS_CARD (card)); - - if (dest->priv->card != card || dest->priv->card_email_num != email_num) { - /* We have to freeze/thaw around these operations so that the 'changed' - signals don't cause the EDestination's internal state to be altered - before we can finish setting ->card && ->card_email_num. */ - e_destination_freeze (dest); - e_destination_clear (dest); - - dest->priv->card = card; - g_object_ref (dest->priv->card); - - dest->priv->card_email_num = email_num; - - e_destination_changed (dest); - e_destination_thaw (dest); - } -} - -void -e_destination_set_book_uri (EDestination *dest, const gchar *uri) -{ - g_return_if_fail (dest && E_IS_DESTINATION (dest)); - g_return_if_fail (uri != NULL); - - if (dest->priv->book_uri == NULL || strcmp (dest->priv->book_uri, uri)) { - g_free (dest->priv->book_uri); - dest->priv->book_uri = g_strdup (uri); - - /* If we already have a card, remove it unless it's uri matches the one - we just set. */ - if (dest->priv->card) { - EBook *book = e_card_get_book (dest->priv->card); - if ((!book) || strcmp (uri, e_book_get_uri (book))) { - g_object_unref (dest->priv->card); - dest->priv->card = NULL; - } - } - - e_destination_changed (dest); - } -} - -void -e_destination_set_card_uid (EDestination *dest, const gchar *uid, gint email_num) -{ - g_return_if_fail (dest && E_IS_DESTINATION (dest)); - g_return_if_fail (uid != NULL); - - if (dest->priv->card_uid == NULL - || strcmp (dest->priv->card_uid, uid) - || dest->priv->card_email_num != email_num) { - - g_free (dest->priv->card_uid); - dest->priv->card_uid = g_strdup (uid); - dest->priv->card_email_num = email_num; - - /* If we already have a card, remove it unless it's uri matches the one - we just set. */ - if (dest->priv->card && strcmp (uid, e_card_get_id (dest->priv->card))) { - g_object_unref (dest->priv->card); - dest->priv->card = NULL; - } - - e_destination_changed (dest); - } -} - -void -e_destination_set_name (EDestination *dest, const gchar *name) -{ - gboolean changed = FALSE; - - g_return_if_fail (E_IS_DESTINATION (dest)); - - if (name == NULL) { - if (dest->priv->name != NULL) { - g_free (dest->priv->name); - dest->priv->name = NULL; - changed = TRUE; - } - } else if (dest->priv->name == NULL || strcmp (dest->priv->name, name)) { - g_free (dest->priv->name); - dest->priv->name = g_strdup (name); - changed = TRUE; - } - - if (changed) { - g_free (dest->priv->addr); - dest->priv->addr = NULL; - g_free (dest->priv->textrep); - dest->priv->textrep = NULL; - e_destination_changed (dest); - } -} - -void -e_destination_set_email (EDestination *dest, const gchar *email) -{ - gboolean changed = FALSE; - - g_return_if_fail (E_IS_DESTINATION (dest)); - - if (email == NULL) { - if (dest->priv->email != NULL) { - g_free (dest->priv->addr); - dest->priv->addr = NULL; - changed = TRUE; - } - } else if (dest->priv->email == NULL || strcmp (dest->priv->email, email)) { - g_free (dest->priv->email); - dest->priv->email = g_strdup (email); - changed = TRUE; - } - - if (changed) { - g_free (dest->priv->addr); - dest->priv->addr = NULL; - g_free (dest->priv->textrep); - dest->priv->textrep = NULL; - e_destination_changed (dest); - } -} - -void -e_destination_set_html_mail_pref (EDestination *dest, gboolean x) -{ - g_return_if_fail (dest && E_IS_DESTINATION (dest)); - - dest->priv->html_mail_override = TRUE; - if (dest->priv->wants_html_mail != x) { - dest->priv->wants_html_mail = x; - e_destination_changed (dest); - } -} - -gboolean -e_destination_contains_card (const EDestination *dest) -{ - g_return_val_if_fail (dest && E_IS_DESTINATION (dest), FALSE); - return dest->priv->card != NULL; -} - -gboolean -e_destination_from_card (const EDestination *dest) -{ - g_return_val_if_fail (dest && E_IS_DESTINATION (dest), FALSE); - return dest->priv->card != NULL || dest->priv->book_uri != NULL || dest->priv->card_uid != NULL; -} - -gboolean -e_destination_is_auto_recipient (const EDestination *dest) -{ - g_return_val_if_fail (dest && E_IS_DESTINATION (dest), FALSE); - - return dest->priv->auto_recipient; -} - -void -e_destination_set_auto_recipient (EDestination *dest, gboolean value) -{ - g_return_if_fail (dest && E_IS_DESTINATION (dest)); - - dest->priv->auto_recipient = value; -} - -typedef struct _UseCard UseCard; -struct _UseCard { - EDestination *dest; - EDestinationCardCallback cb; - gpointer closure; -}; - -static void -use_card_cb (ECard *card, gpointer closure) -{ - UseCard *uc = (UseCard *) closure; - - if (card != NULL && uc->dest->priv->card == NULL) { - uc->dest->priv->card = card; - g_object_ref (uc->dest->priv->card); - e_destination_changed (uc->dest); - } - - if (uc->cb) { - uc->cb (uc->dest, uc->dest->priv->card, uc->closure); - } - - /* We held a copy of the destination during the callback. */ - g_object_unref (uc->dest); - g_free (uc); -} - -void -e_destination_use_card (EDestination *dest, EDestinationCardCallback cb, gpointer closure) -{ - g_return_if_fail (dest && E_IS_DESTINATION (dest)); - - if (dest->priv->card != NULL) { - if (cb) - cb (dest, dest->priv->card, closure); - } else if (dest->priv->book_uri != NULL && dest->priv->card_uid != NULL) { - UseCard *uc = g_new (UseCard, 1); - - uc->dest = dest; - /* Hold a reference to the destination during the callback. */ - g_object_ref (uc->dest); - uc->cb = cb; - uc->closure = closure; - e_card_load_uri (dest->priv->book_uri, dest->priv->card_uid, use_card_cb, uc); - } else { - if (cb) - cb (dest, NULL, closure); - } -} - -ECard * -e_destination_get_card (const EDestination *dest) -{ - g_return_val_if_fail (dest && E_IS_DESTINATION (dest), NULL); - - return dest->priv->card; -} - -const gchar * -e_destination_get_card_uid (const EDestination *dest) -{ - g_return_val_if_fail (dest && E_IS_DESTINATION (dest), NULL); - - if (dest->priv->card_uid) - return dest->priv->card_uid; - - if (dest->priv->card) - return e_card_get_id (dest->priv->card); - - return NULL; -} - -const gchar * -e_destination_get_book_uri (const EDestination *dest) -{ - g_return_val_if_fail (dest && E_IS_DESTINATION (dest), NULL); - - if (dest->priv->book_uri) - return dest->priv->book_uri; - - if (dest->priv->card) { - EBook *book = e_card_get_book (dest->priv->card); - - if (book) { - return e_book_get_uri (book); - } - } - - return NULL; -} - -gint -e_destination_get_email_num (const EDestination *dest) -{ - g_return_val_if_fail (dest && E_IS_DESTINATION (dest), -1); - - if (dest->priv->card == NULL && (dest->priv->book_uri == NULL || dest->priv->card_uid == NULL)) - return -1; - - return dest->priv->card_email_num; -} - -const gchar * -e_destination_get_name (const EDestination *dest) -{ - struct _EDestinationPrivate *priv; - - g_return_val_if_fail (dest && E_IS_DESTINATION (dest), NULL); - - priv = (struct _EDestinationPrivate *)dest->priv; /* cast out const */ - - if (priv->name == NULL) { - if (priv->card != NULL) { - priv->name = e_card_name_to_string (priv->card->name); - - if (priv->name == NULL || *priv->name == '\0') { - g_free (priv->name); - priv->name = g_strdup (priv->card->file_as); - } - - if (priv->name == NULL || *priv->name == '\0') { - g_free (priv->name); - if (e_card_evolution_list (priv->card)) - priv->name = g_strdup (_("Unnamed List")); - else - priv->name = g_strdup (e_destination_get_email (dest)); - } - } else if (priv->raw != NULL) { - CamelInternetAddress *addr = camel_internet_address_new (); - - if (camel_address_unformat (CAMEL_ADDRESS (addr), priv->raw)) { - const char *camel_name = NULL; - - camel_internet_address_get (addr, 0, &camel_name, NULL); - priv->name = g_strdup (camel_name); - } - - camel_object_unref (CAMEL_OBJECT (addr)); - } - } - - return priv->name; -} - -const gchar * -e_destination_get_email (const EDestination *dest) -{ - struct _EDestinationPrivate *priv; - - g_return_val_if_fail (dest && E_IS_DESTINATION (dest), NULL); - - priv = (struct _EDestinationPrivate *)dest->priv; /* cast out const */ - - if (priv->email == NULL) { - if (priv->card != NULL) { - /* Pull the address out of the card. */ - if (priv->card->email) { - EIterator *iter = e_list_get_iterator (priv->card->email); - int n = priv->card_email_num; - - if (n >= 0) { - while (n > 0) { - e_iterator_next (iter); - n--; - } - - if (e_iterator_is_valid (iter)) { - gconstpointer ptr = e_iterator_get (iter); - priv->email = g_strdup ((char *) ptr); - } - } - } - } else if (priv->raw != NULL) { - CamelInternetAddress *addr = camel_internet_address_new (); - - if (camel_address_unformat (CAMEL_ADDRESS (addr), priv->raw)) { - const gchar *camel_email = NULL; - camel_internet_address_get (addr, 0, NULL, &camel_email); - priv->email = g_strdup (camel_email); - } - - camel_object_unref (CAMEL_OBJECT (addr)); - } - - /* Force e-mail to be non-null... */ - if (priv->email == NULL) { - priv->email = g_strdup (""); - } - } - - return priv->email; -} - -const gchar * -e_destination_get_address (const EDestination *dest) -{ - struct _EDestinationPrivate *priv; - - g_return_val_if_fail (dest && E_IS_DESTINATION (dest), NULL); - - priv = (struct _EDestinationPrivate *)dest->priv; /* cast out const */ - - if (priv->addr == NULL) { - CamelInternetAddress *addr = camel_internet_address_new (); - - if (e_destination_is_evolution_list (dest)) { - GList *iter = dest->priv->list_dests; - - while (iter) { - EDestination *list_dest = E_DESTINATION (iter->data); - - if (!e_destination_is_empty (list_dest)) { - camel_internet_address_add (addr, - e_destination_get_name (list_dest), - e_destination_get_email (list_dest)); - } - iter = g_list_next (iter); - } - - priv->addr = camel_address_encode (CAMEL_ADDRESS (addr)); - } else if (priv->raw) { - - if (camel_address_unformat (CAMEL_ADDRESS (addr), priv->raw)) { - priv->addr = camel_address_encode (CAMEL_ADDRESS (addr)); - } - } else { - camel_internet_address_add (addr, - e_destination_get_name (dest), - e_destination_get_email (dest)); - - priv->addr = camel_address_encode (CAMEL_ADDRESS (addr)); - } - - camel_object_unref (CAMEL_OBJECT (addr)); - } - - return priv->addr; -} - -void -e_destination_set_raw (EDestination *dest, const gchar *raw) -{ - g_return_if_fail (E_IS_DESTINATION (dest)); - g_return_if_fail (raw != NULL); - - if (dest->priv->raw == NULL || strcmp (dest->priv->raw, raw)) { - e_destination_freeze (dest); - - e_destination_clear (dest); - dest->priv->raw = g_strdup (raw); - e_destination_changed (dest); - - e_destination_thaw (dest); - } -} - -const gchar * -e_destination_get_textrep (const EDestination *dest, gboolean include_email) -{ - const char *name, *email; - - g_return_val_if_fail (dest && E_IS_DESTINATION (dest), NULL); - - if (dest->priv->raw) - return dest->priv->raw; - - name = e_destination_get_name (dest); - email = e_destination_get_email (dest); - - if (e_destination_from_card (dest) && name != NULL && (!include_email || !email || !*email)) - return name; - - /* Make sure that our address gets quoted properly */ - if (name && email && dest->priv->textrep == NULL) { - CamelInternetAddress *addr = camel_internet_address_new (); - - camel_internet_address_add (addr, name, email); - g_free (dest->priv->textrep); - dest->priv->textrep = camel_address_format (CAMEL_ADDRESS (addr)); - camel_object_unref (CAMEL_OBJECT (addr)); - } - - if (dest->priv->textrep != NULL) - return dest->priv->textrep; - - if (email) - return email; - - return ""; -} - -gboolean -e_destination_is_evolution_list (const EDestination *dest) -{ - g_return_val_if_fail (dest && E_IS_DESTINATION (dest), FALSE); - - if (dest->priv->list_dests == NULL - && dest->priv->card != NULL - && dest->priv->card->email != NULL - && e_card_evolution_list (dest->priv->card)) { - - EIterator *iter = e_list_get_iterator (dest->priv->card->email); - - e_iterator_reset (iter); - while (e_iterator_is_valid (iter)) { - const char *dest_xml = (const char *) e_iterator_get (iter); - EDestination *list_dest = e_destination_import (dest_xml); - - if (list_dest) - dest->priv->list_dests = g_list_append (dest->priv->list_dests, list_dest); - e_iterator_next (iter); - } - } - - return dest->priv->list_dests != NULL; -} - -gboolean -e_destination_list_show_addresses (const EDestination *dest) -{ - g_return_val_if_fail (E_IS_DESTINATION (dest), FALSE); - - if (dest->priv->card != NULL) - return e_card_evolution_list_show_addresses (dest->priv->card); - - return dest->priv->show_addresses; -} - -gboolean -e_destination_get_html_mail_pref (const EDestination *dest) -{ - g_return_val_if_fail (dest && E_IS_DESTINATION (dest), FALSE); - - if (dest->priv->html_mail_override || dest->priv->card == NULL) - return dest->priv->wants_html_mail; - - return dest->priv->card->wants_html; -} - -gboolean -e_destination_allow_cardification (const EDestination *dest) -{ - g_return_val_if_fail (E_IS_DESTINATION (dest), FALSE); - - return dest->priv->allow_cardify; -} - -void -e_destination_set_allow_cardification (EDestination *dest, gboolean x) -{ - g_return_if_fail (E_IS_DESTINATION (dest)); - - dest->priv->allow_cardify = x; -} - -static void -set_cardify_book (EDestination *dest, EBook *book) -{ - if (dest->priv->cardify_book && dest->priv->cardify_book != book) { - g_object_unref (dest->priv->cardify_book); - } - - dest->priv->cardify_book = book; - - if (book) - g_object_ref (book); -} - -static void -name_and_email_simple_query_cb (EBook *book, EBookSimpleQueryStatus status, const GList *cards, gpointer closure) -{ - EDestination *dest = E_DESTINATION (closure); - - if (status == E_BOOK_SIMPLE_QUERY_STATUS_SUCCESS && g_list_length ((GList *) cards) == 1) { - ECard *card = E_CARD (cards->data); - const char *email = e_destination_get_email (dest); - int email_num = 0; - - if (e_destination_is_valid (dest) && email && *email) { - email_num = e_card_email_find_number (card, e_destination_get_email (dest)); - } - - if (email_num >= 0) { - const char *book_uri; - - book_uri = e_book_get_uri (book); - - dest->priv->has_been_cardified = TRUE; - e_destination_set_card (dest, card, email_num); - e_destination_set_book_uri (dest, book_uri); - g_signal_emit (dest, e_destination_signals[CARDIFIED], 0); - } - } - - if (!dest->priv->has_been_cardified) { - dest->priv->cannot_cardify = TRUE; - } - - g_object_unref (dest); /* drop the reference held by the query */ -} - - -static void -nickname_simple_query_cb (EBook *book, EBookSimpleQueryStatus status, const GList *cards, gpointer closure) -{ - EDestination *dest = E_DESTINATION (closure); - - if (status == E_BOOK_SIMPLE_QUERY_STATUS_SUCCESS) { - if (g_list_length ((GList *) cards) == 1) { - const char *book_uri; - - book_uri = e_book_get_uri (book); - - dest->priv->has_been_cardified = TRUE; - e_destination_set_card (dest, E_CARD (cards->data), 0); /* Uses primary e-mail by default. */ - e_destination_set_book_uri (dest, book_uri); - g_signal_emit (dest, e_destination_signals[CARDIFIED], 0); - - g_object_unref (dest); /* drop the reference held by the query */ - - } else { - /* We can only end up here if we don't look at all like an e-mail address, so - we do a name-only query on the textrep */ - - e_book_name_and_email_query (book, - e_destination_get_textrep (dest, FALSE), - NULL, - name_and_email_simple_query_cb, - dest); - } - } else { - /* Something went wrong with the query: drop our ref to the destination and return. */ - g_object_unref (dest); - } -} - -static void -launch_cardify_query (EDestination *dest) -{ - if (! e_destination_is_valid (dest)) { - /* If it doesn't look like an e-mail address, see if it is a nickname. */ - e_book_nickname_query (dest->priv->cardify_book, - e_destination_get_textrep (dest, FALSE), - nickname_simple_query_cb, - dest); - - } else { - e_book_name_and_email_query (dest->priv->cardify_book, - e_destination_get_name (dest), - e_destination_get_email (dest), - name_and_email_simple_query_cb, - dest); - } -} - -static void -use_default_book_cb (EBook *book, gpointer closure) -{ - EDestination *dest = E_DESTINATION (closure); - if (book != NULL && dest->priv->cardify_book == NULL) { - dest->priv->cardify_book = book; - g_object_ref (book); - } - - if (dest->priv->cardify_book) - launch_cardify_query (dest); - else - g_object_unref (dest); -} - - -static gboolean -e_destination_reverting_is_a_good_idea (EDestination *dest) -{ - const char *textrep; - int len, old_len; - - g_return_val_if_fail (E_IS_DESTINATION (dest), FALSE); - if (dest->priv->old_textrep == NULL) - return FALSE; - - textrep = e_destination_get_textrep (dest, FALSE); - - len = g_utf8_strlen (textrep, -1); - old_len = g_utf8_strlen (dest->priv->old_textrep, -1); - - if (len <= old_len/2) - return FALSE; - - return TRUE; -} - -void -e_destination_cardify (EDestination *dest, EBook *book) -{ - g_return_if_fail (E_IS_DESTINATION (dest)); - g_return_if_fail (book == NULL || E_IS_BOOK (book)); - - if (e_destination_is_evolution_list (dest)) - return; - - if (e_destination_contains_card (dest)) - return; - - if (!dest->priv->allow_cardify) - return; - - if (dest->priv->cannot_cardify) - return; - - e_destination_cancel_cardify (dest); - - /* In some cases, we can revert to the previous card. */ - if (!e_destination_is_valid (dest) - && e_destination_reverting_is_a_good_idea (dest) - && e_destination_revert (dest)) { - return; - } - - set_cardify_book (dest, book); - - /* Handle the case of an EDestination containing a card URL */ - if (e_destination_contains_card (dest)) { - e_destination_use_card (dest, NULL, NULL); - return; - } - - /* If we have a book ready, proceed. We hold a reference to ourselves - until our query is complete. */ - g_object_ref (dest); - if (dest->priv->cardify_book != NULL) { - launch_cardify_query (dest); - } else { - e_book_use_default_book (use_default_book_cb, dest); - } -} - -static int -do_cardify_delayed (gpointer ptr) -{ - EDestination *dest = E_DESTINATION (ptr); - - e_destination_cardify (dest, dest->priv->cardify_book); - return FALSE; -} - -void -e_destination_cardify_delayed (EDestination *dest, EBook *book, gint delay) -{ - g_return_if_fail (E_IS_DESTINATION (dest)); - g_return_if_fail (book == NULL || E_IS_BOOK (book)); - - if (delay < 0) - delay = 500; - - e_destination_cancel_cardify (dest); - - set_cardify_book (dest, book); - - dest->priv->pending_cardification = g_timeout_add (delay, do_cardify_delayed, dest); -} - -void -e_destination_cancel_cardify (EDestination *dest) -{ - g_return_if_fail (E_IS_DESTINATION (dest)); - - if (dest->priv->pending_cardification) { - g_source_remove (dest->priv->pending_cardification); - dest->priv->pending_cardification = 0; - } -} - -gboolean -e_destination_uncardify (EDestination *dest) -{ - char *email; - - g_return_val_if_fail (E_IS_DESTINATION (dest), FALSE); - - if (!e_destination_contains_card (dest)) - return FALSE; - - email = g_strdup (e_destination_get_email (dest)); - - if (email == NULL) - return FALSE; - - e_destination_freeze (dest); - e_destination_clear (dest); - e_destination_set_raw (dest, email); - g_free (email); - e_destination_thaw (dest); - - return TRUE; -} - -gboolean -e_destination_revert (EDestination *dest) -{ - g_return_val_if_fail (E_IS_DESTINATION (dest), FALSE); - - if (dest->priv->old_card) { - ECard *card; - int card_email_num; - - card = dest->priv->old_card; - card_email_num = dest->priv->old_card_email_num; - - dest->priv->old_card = NULL; - g_free (dest->priv->old_textrep); - dest->priv->old_textrep = NULL; - - e_destination_freeze (dest); - e_destination_clear (dest); - e_destination_set_card (dest, card, card_email_num); - e_destination_thaw (dest); - - return TRUE; - } - - return FALSE; -} - -/* - * Destination import/export - */ - -gchar * -e_destination_get_address_textv (EDestination **destv) -{ - int i, j, len = 0; - char **strv; - char *str; - - g_return_val_if_fail (destv, NULL); - - /* Q: Please tell me this is only for assertion - reasons. If this is considered to be ok behavior then you - shouldn't use g_return's. Just a reminder ;-) - - A: Yes, this is just an assertion. (Though it does find the - length of the vector in the process...) - */ - while (destv[len]) { - g_return_val_if_fail (E_IS_DESTINATION (destv[len]), NULL); - len++; - } - - strv = g_new0 (char *, len + 1); - for (i = 0, j = 0; destv[i]; i++) { - if (!e_destination_is_empty (destv[i])) { - const char *addr = e_destination_get_address (destv[i]); - strv[j++] = addr ? (char *) addr : ""; - } - } - - str = g_strjoinv (", ", strv); - - g_free (strv); - - return str; -} - -xmlNodePtr -e_destination_xml_encode (const EDestination *dest) -{ - xmlNodePtr dest_node; - const char *str; - - g_return_val_if_fail (dest && E_IS_DESTINATION (dest), NULL); - - dest_node = xmlNewNode (NULL, "destination"); - - str = e_destination_get_name (dest); - if (str) - xmlNewTextChild (dest_node, NULL, "name", str); - - if (!e_destination_is_evolution_list (dest)) { - str = e_destination_get_email (dest); - if (str) - xmlNewTextChild (dest_node, NULL, "email", str); - } else { - GList *iter = dest->priv->list_dests; - - while (iter) { - EDestination *list_dest = E_DESTINATION (iter->data); - xmlNodePtr list_node = xmlNewNode (NULL, "list_entry"); - - str = e_destination_get_name (list_dest); - if (str) - xmlNewTextChild (list_node, NULL, "name", str); - - str = e_destination_get_email (list_dest); - if (str) - xmlNewTextChild (list_node, NULL, "email", str); - - xmlAddChild (dest_node, list_node); - - iter = g_list_next (iter); - } - - xmlNewProp (dest_node, "is_list", "yes"); - xmlNewProp (dest_node, "show_addresses", - e_destination_list_show_addresses (dest) ? "yes" : "no"); - } - - str = e_destination_get_book_uri (dest); - if (str) { - xmlNewTextChild (dest_node, NULL, "book_uri", str); - } - - str = e_destination_get_card_uid (dest); - if (str) { - char buf[16]; - - xmlNodePtr uri_node = xmlNewTextChild (dest_node, NULL, "card_uid", str); - g_snprintf (buf, 16, "%d", e_destination_get_email_num (dest)); - xmlNewProp (uri_node, "email_num", buf); - } - - xmlNewProp (dest_node, "html_mail", e_destination_get_html_mail_pref (dest) ? "yes" : "no"); - - xmlNewProp (dest_node, "auto_recipient", - e_destination_is_auto_recipient (dest) ? "yes" : "no"); - - return dest_node; -} - -gboolean -e_destination_xml_decode (EDestination *dest, xmlNodePtr node) -{ - char *name = NULL, *email = NULL, *book_uri = NULL, *card_uid = NULL; - gboolean is_list = FALSE, show_addr = FALSE, auto_recip = FALSE; - gboolean html_mail = FALSE; - GList *list_dests = NULL; - int email_num = -1; - char *tmp; - - g_return_val_if_fail (dest && E_IS_DESTINATION (dest), FALSE); - g_return_val_if_fail (node != NULL, FALSE); - - if (strcmp (node->name, "destination")) - return FALSE; - - tmp = xmlGetProp (node, "html_mail"); - if (tmp) { - html_mail = !strcmp (tmp, "yes"); - xmlFree (tmp); - } - - tmp = xmlGetProp (node, "is_list"); - if (tmp) { - is_list = !strcmp (tmp, "yes"); - xmlFree (tmp); - } - - tmp = xmlGetProp (node, "show_addresses"); - if (tmp) { - show_addr = !strcmp (tmp, "yes"); - xmlFree (tmp); - } - - tmp = xmlGetProp (node, "auto_recipient"); - if (tmp) { - auto_recip = !strcmp (tmp, "yes"); - xmlFree (tmp); - } - - node = node->xmlChildrenNode; - while (node) { - if (!strcmp (node->name, "name")) { - tmp = xmlNodeGetContent (node); - g_free (name); - name = g_strdup (tmp); - xmlFree (tmp); - } else if (!is_list && !strcmp (node->name, "email")) { - tmp = xmlNodeGetContent (node); - g_free (email); - email = g_strdup (tmp); - xmlFree (tmp); - } else if (is_list && !strcmp (node->name, "list_entry")) { - xmlNodePtr subnode = node->xmlChildrenNode; - char *list_name = NULL, *list_email = NULL; - - while (subnode) { - if (!strcmp (subnode->name, "name")) { - tmp = xmlNodeGetContent (subnode); - g_free (list_name); - list_name = g_strdup (tmp); - xmlFree (tmp); - } else if (!strcmp (subnode->name, "email")) { - tmp = xmlNodeGetContent (subnode); - g_free (list_email); - list_email = g_strdup (tmp); - xmlFree (tmp); - } - - subnode = subnode->next; - } - - if (list_name || list_email) { - EDestination *list_dest = e_destination_new (); - - if (list_name) - e_destination_set_name (list_dest, list_name); - if (list_email) - e_destination_set_email (list_dest, list_email); - - g_free (list_name); - g_free (list_email); - - list_dests = g_list_append (list_dests, list_dest); - } - } else if (!strcmp (node->name, "book_uri")) { - tmp = xmlNodeGetContent (node); - g_free (book_uri); - book_uri = g_strdup (tmp); - xmlFree (tmp); - } else if (!strcmp (node->name, "card_uid")) { - tmp = xmlNodeGetContent (node); - g_free (card_uid); - card_uid = g_strdup (tmp); - xmlFree (tmp); - - tmp = xmlGetProp (node, "email_num"); - email_num = atoi (tmp); - xmlFree (tmp); - } - - node = node->next; - } - - e_destination_freeze (dest); - - e_destination_clear (dest); - - if (name) { - e_destination_set_name (dest, name); - g_free (name); - } - if (email) { - e_destination_set_email (dest, email); - g_free (email); - } - if (book_uri) { - e_destination_set_book_uri (dest, book_uri); - g_free (book_uri); - } - if (card_uid) { - e_destination_set_card_uid (dest, card_uid, email_num); - g_free (card_uid); - } - if (list_dests) - dest->priv->list_dests = list_dests; - - dest->priv->html_mail_override = TRUE; - dest->priv->wants_html_mail = html_mail; - - dest->priv->show_addresses = show_addr; - - dest->priv->auto_recipient = auto_recip; - - e_destination_thaw (dest); - - return TRUE; -} - -/* FIXME: Make utf-8 safe */ -static gchar * -null_terminate_and_remove_extra_whitespace (xmlChar *xml_in, gint size) -{ - gboolean skip_white = FALSE; - char *xml, *r, *w; - - if (xml_in == NULL || size <= 0) - return NULL; - - xml = g_strndup (xml_in, size); - r = w = xml; - - while (*r) { - if (*r == '\n' || *r == '\r') { - skip_white = TRUE; - } else { - gboolean is_space = isspace (*r); - - *w = *r; - - if (!(skip_white && is_space)) - w++; - if (!is_space) - skip_white = FALSE; - } - r++; - } - - *w = '\0'; - - return xml; -} - -gchar * -e_destination_export (const EDestination *dest) -{ - xmlNodePtr dest_node; - xmlDocPtr dest_doc; - xmlChar *buffer = NULL; - int size = -1; - char *str; - - g_return_val_if_fail (dest && E_IS_DESTINATION (dest), NULL); - - dest_node = e_destination_xml_encode (dest); - if (dest_node == NULL) - return NULL; - - dest_doc = xmlNewDoc (XML_DEFAULT_VERSION); - xmlDocSetRootElement (dest_doc, dest_node); - - xmlDocDumpMemory (dest_doc, &buffer, &size); - xmlFreeDoc (dest_doc); - - str = null_terminate_and_remove_extra_whitespace (buffer, size); - xmlFree (buffer); - - return str; -} - -EDestination * -e_destination_import (const gchar *str) -{ - EDestination *dest = NULL; - xmlDocPtr dest_doc; - - if (!(str && *str)) - return NULL; - - dest_doc = xmlParseMemory ((char *) str, strlen (str)); - if (dest_doc && dest_doc->xmlRootNode) { - dest = e_destination_new (); - if (! e_destination_xml_decode (dest, dest_doc->xmlRootNode)) { - g_object_unref (dest); - dest = NULL; - } - } - xmlFreeDoc (dest_doc); - - return dest; -} - -gchar * -e_destination_exportv (EDestination **destv) -{ - xmlDocPtr destv_doc; - xmlNodePtr destv_node; - xmlChar *buffer = NULL; - int i, size = -1; - char *str; - - if (destv == NULL || *destv == NULL) - return NULL; - - destv_doc = xmlNewDoc (XML_DEFAULT_VERSION); - destv_node = xmlNewNode (NULL, "destinations"); - xmlDocSetRootElement (destv_doc, destv_node); - - for (i = 0; destv[i]; i++) { - if (! e_destination_is_empty (destv[i])) { - xmlNodePtr dest_node = e_destination_xml_encode (destv[i]); - if (dest_node) - xmlAddChild (destv_node, dest_node); - } - } - - xmlDocDumpMemory (destv_doc, &buffer, &size); - xmlFreeDoc (destv_doc); - - str = null_terminate_and_remove_extra_whitespace (buffer, size); - xmlFree (buffer); - - return str; -} - -EDestination ** -e_destination_importv (const gchar *str) -{ - GPtrArray *dest_array = NULL; - xmlDocPtr destv_doc; - xmlNodePtr node; - EDestination **destv = NULL; - - if (!(str && *str)) - return NULL; - - destv_doc = xmlParseMemory ((char *)str, strlen (str)); - if (destv_doc == NULL) - return NULL; - - node = destv_doc->xmlRootNode; - - if (strcmp (node->name, "destinations")) - goto finished; - - node = node->xmlChildrenNode; - - dest_array = g_ptr_array_new (); - - while (node) { - EDestination *dest; - - dest = e_destination_new (); - if (e_destination_xml_decode (dest, node) && !e_destination_is_empty (dest)) { - g_ptr_array_add (dest_array, dest); - } else { - g_object_unref (dest); - } - - node = node->next; - } - - /* we need destv to be NULL terminated */ - g_ptr_array_add (dest_array, NULL); - - destv = (EDestination **) dest_array->pdata; - g_ptr_array_free (dest_array, FALSE); - - finished: - xmlFreeDoc (destv_doc); - - return destv; -} - -EDestination ** -e_destination_list_to_vector_sized (GList *list, int n) -{ - EDestination **destv; - int i = 0; - - if (n == -1) - n = g_list_length (list); - - if (n == 0) - return NULL; - - destv = g_new (EDestination *, n + 1); - while (list != NULL && i < n) { - destv[i] = E_DESTINATION (list->data); - list->data = NULL; - i++; - list = g_list_next (list); - } - destv[i] = NULL; - - return destv; -} - -EDestination ** -e_destination_list_to_vector (GList *list) -{ - return e_destination_list_to_vector_sized (list, -1); -} - -void -e_destination_freev (EDestination **destv) -{ - int i; - - if (destv) { - for (i = 0; destv[i] != NULL; ++i) { - g_object_unref (destv[i]); - } - g_free (destv); - } - -} - -static void -touch_cb (EBook *book, const gchar *addr, ECard *card, gpointer closure) -{ - if (book != NULL && card != NULL) { - e_card_touch (card); - d(g_message ("Use score for \"%s\" is now %f", addr, e_card_get_use_score (card))); - e_book_commit_card (book, card, NULL, NULL); - } -} - -void -e_destination_touch (EDestination *dest) -{ - const char *email; - - g_return_if_fail (dest && E_IS_DESTINATION (dest)); - - if (!e_destination_is_auto_recipient (dest)) { - email = e_destination_get_email (dest); - - if (email) - e_book_query_address_default (email, touch_cb, NULL); - } -} - -void -e_destination_touchv (EDestination **destv) -{ - int i; - - g_return_if_fail (destv != NULL); - - for (i = 0; destv[i] != NULL; ++i) { - e_destination_touch (destv[i]); - } -} diff --git a/addressbook/backend/ebook/e-destination.h b/addressbook/backend/ebook/e-destination.h deleted file mode 100644 index acd6af1bc4..0000000000 --- a/addressbook/backend/ebook/e-destination.h +++ /dev/null @@ -1,140 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -/* - * e-destination.h - * - * Copyright (C) 2001 Ximian, Inc. - * - * Developed by Jon Trowbridge <trow@ximian.com> - */ - -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA. - */ - -#ifndef __E_DESTINATION_H__ -#define __E_DESTINATION_H__ - -#include <glib.h> -#include <glib-object.h> -#include <ebook/e-card.h> -#include <ebook/e-book.h> -#include <libxml/tree.h> - -#define E_TYPE_DESTINATION (e_destination_get_type ()) -#define E_DESTINATION(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), E_TYPE_DESTINATION, EDestination)) -#define E_DESTINATION_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), E_TYPE_DESTINATION, EDestinationClass)) -#define E_IS_DESTINATION(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), E_TYPE_DESTINATION)) -#define E_IS_DESTINATION_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), E_TYPE_DESTINATION)) -#define E_DESTINATION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), E_TYPE_DESTINATION, EDestinationClass)) - -typedef struct _EDestination EDestination; -typedef struct _EDestinationClass EDestinationClass; - -typedef void (*EDestinationCardCallback) (EDestination *dest, ECard *card, gpointer closure); - -struct _EDestinationPrivate; - -struct _EDestination { - GObject object; - - struct _EDestinationPrivate *priv; -}; - -struct _EDestinationClass { - GObjectClass parent_class; - - void (*changed) (EDestination *dest); - void (*cardified) (EDestination *dest); -}; - -GType e_destination_get_type (void); - - -EDestination *e_destination_new (void); -void e_destination_changed (EDestination *); -EDestination *e_destination_copy (const EDestination *); -void e_destination_clear (EDestination *); - -gboolean e_destination_is_empty (const EDestination *); -gboolean e_destination_is_valid (const EDestination *); -gboolean e_destination_equal (const EDestination *a, const EDestination *b); - -void e_destination_set_card (EDestination *, ECard *card, gint email_num); -void e_destination_set_book_uri (EDestination *, const gchar *uri); -void e_destination_set_card_uid (EDestination *, const gchar *uid, gint email_num); - -void e_destination_set_name (EDestination *, const gchar *name); -void e_destination_set_email (EDestination *, const gchar *email); - -void e_destination_set_html_mail_pref (EDestination *, gboolean); - -gboolean e_destination_contains_card (const EDestination *); -gboolean e_destination_from_card (const EDestination *); - -gboolean e_destination_is_auto_recipient (const EDestination *); -void e_destination_set_auto_recipient (EDestination *, gboolean value); - -void e_destination_use_card (EDestination *, EDestinationCardCallback cb, gpointer closure); - -ECard *e_destination_get_card (const EDestination *); -const gchar *e_destination_get_book_uri (const EDestination *); -const gchar *e_destination_get_card_uid (const EDestination *); -gint e_destination_get_email_num (const EDestination *); - -const gchar *e_destination_get_name (const EDestination *); /* "Jane Smith" */ -const gchar *e_destination_get_email (const EDestination *); /* "jane@assbarn.com" */ -const gchar *e_destination_get_address (const EDestination *);; /* "Jane Smith <jane@assbarn.com>" (or a comma-sep set of such for a list) */ - -void e_destination_set_raw (EDestination *, const gchar *free_form_string); -const gchar *e_destination_get_textrep (const EDestination *, gboolean include_email); /* "Jane Smith" or "jane@assbarn.com" */ - -gboolean e_destination_is_evolution_list (const EDestination *); -gboolean e_destination_list_show_addresses (const EDestination *); - -/* If true, they want HTML mail. */ -gboolean e_destination_get_html_mail_pref (const EDestination *); - -gboolean e_destination_allow_cardification (const EDestination *); -void e_destination_set_allow_cardification (EDestination *, gboolean); -void e_destination_cardify (EDestination *, EBook *); -void e_destination_cardify_delayed (EDestination *, EBook *, gint delay); /* delay < 0: "default" */ -void e_destination_cancel_cardify (EDestination *); -gboolean e_destination_uncardify (EDestination *); - -gboolean e_destination_revert (EDestination *); - -gchar *e_destination_get_address_textv (EDestination **); - -xmlNodePtr e_destination_xml_encode (const EDestination *dest); -gboolean e_destination_xml_decode (EDestination *dest, xmlNodePtr node); - -gchar *e_destination_export (const EDestination *); -EDestination *e_destination_import (const gchar *str); - -gchar *e_destination_exportv (EDestination **); -EDestination **e_destination_importv (const gchar *str); - -EDestination **e_destination_list_to_vector_sized (GList *, int n); -EDestination **e_destination_list_to_vector (GList *); - -void e_destination_freev (EDestination **); - -void e_destination_touch (EDestination *); -void e_destination_touchv (EDestination **); - - -#endif /* __E_DESTINATION_H__ */ - diff --git a/addressbook/backend/ebook/e-vcard.c b/addressbook/backend/ebook/e-vcard.c deleted file mode 100644 index 62ebda9349..0000000000 --- a/addressbook/backend/ebook/e-vcard.c +++ /dev/null @@ -1,925 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* evcard.h - * - * Copyright (C) 2003 Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * - * Author: Chris Toshok (toshok@ximian.com) - */ - -#include <glib.h> -#include <stdio.h> -#include <ctype.h> -#include "e-vcard.h" - -#define CRLF "\r\n" - -struct _EVCardPrivate { - GList *attributes; -}; - -struct _EVCardAttribute { - char *group; - char *name; - GList *params; /* EVCardParam */ - GList *values; -}; - -struct _EVCardAttributeParam { - char *name; - GList *values; /* GList of char*'s*/ -}; - -static GObjectClass *parent_class; - -static void -e_vcard_dispose (GObject *object) -{ - EVCard *evc = E_VCARD (object); - - if (!evc->priv) - return; - - g_list_foreach (evc->priv->attributes, (GFunc)e_vcard_attribute_free, NULL); - g_list_free (evc->priv->attributes); - - g_free (evc->priv); - evc->priv = NULL; - - if (G_OBJECT_CLASS (parent_class)->dispose) - G_OBJECT_CLASS (parent_class)->dispose (object); -} - -static void -e_vcard_class_init (EVCardClass *klass) -{ - GObjectClass *object_class; - - object_class = G_OBJECT_CLASS(klass); - - parent_class = g_type_class_ref (G_TYPE_OBJECT); - - object_class->dispose = e_vcard_dispose; -} - -static void -e_vcard_init (EVCard *evc) -{ - evc->priv = g_new0 (EVCardPrivate, 1); -} - -GType -e_vcard_get_type (void) -{ - static GType vcard_type = 0; - - if (!vcard_type) { - static const GTypeInfo vcard_info = { - sizeof (EVCardClass), - NULL, /* base_init */ - NULL, /* base_finalize */ - (GClassInitFunc) e_vcard_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (EVCard), - 0, /* n_preallocs */ - (GInstanceInitFunc) e_vcard_init, - }; - - vcard_type = g_type_register_static (G_TYPE_OBJECT, "EVCard", &vcard_info, 0); - } - - return vcard_type; -} - - - -static char* -fold_lines (char *buf) -{ - GString *str = g_string_new (""); - char *p = buf; - char *next, *next2; - - /* we're pretty liberal with line folding here. We handle - lines folded with \r\n<WS>... and \n\r<WS>... and - \n<WS>... We also turn single \r's and \n's not followed by - WS into \r\n's. */ - while (*p) { - if (*p == '\r' || *p == '\n') { - next = g_utf8_next_char (p); - if (*next == '\n' || *next == '\r') { - next2 = g_utf8_next_char (next); - if (*next2 == ' ' || *next2 == '\t') { - p = g_utf8_next_char (next2); - } - else { - str = g_string_append (str, CRLF); - p = g_utf8_next_char (next); - } - } - else if (*next == ' ' || *next == '\t') { - p = g_utf8_next_char (next); - } - else { - str = g_string_append (str, CRLF); - p = g_utf8_next_char (p); - } - } - else { - str = g_string_append_unichar (str, g_utf8_get_char (p)); - p = g_utf8_next_char (p); - } - } - - g_free (buf); - - return g_string_free (str, FALSE); -} - -/* skip forward until we hit the CRLF, or \0 */ -static void -skip_to_next_line (char **p) -{ - char *lp; - lp = *p; - - while (*lp != '\r' && *lp != '\0') - lp = g_utf8_next_char (lp); - - if (*lp == '\r') { - lp = g_utf8_next_char (lp); /* \n */ - lp = g_utf8_next_char (lp); /* start of the next line */ - } - - *p = lp; -} - -/* skip forward until we hit a character in @s, CRLF, or \0 */ -static void -skip_until (char **p, char *s) -{ - /* XXX write me plz k thx */ - g_assert_not_reached(); -} - -static void -read_attribute_value (EVCardAttribute *attr, char **p, gboolean quoted_printable) -{ - char *lp = *p; - GString *str; - - /* read in the value */ - str = g_string_new (""); - while (*lp != '\r' && *lp != '\0') { - if (*lp == '=' && quoted_printable) { - char a, b; - if ((a = *(++lp)) == '\0') break; - if ((b = *(++lp)) == '\0') break; - if (a == '\r' && b == '\n') { - /* it was a = at the end of the line, - * just ignore this and continue - * parsing on the next line. yay for - * 2 kinds of line folding - */ - } - else if (isalnum(a) && isalnum (b)) { - char c; - - a = tolower (a); - b = tolower (b); - - c = (((a>='a'?a-'a'+10:a-'0')&0x0f) << 4) - | ((b>='a'?b-'a'+10:b-'0')&0x0f); - - str = g_string_append_c (str, c); - } - /* silently consume malformed input, and - continue parsing */ - lp++; - } - else if (*lp == '\\') { - /* convert back to the non-escaped version of - the characters */ - lp = g_utf8_next_char(lp); - if (*lp == '\0') { - str = g_string_append_c (str, '\\'); - break; - } - switch (*lp) { - case 'n': str = g_string_append_c (str, '\n'); break; - case 'r': str = g_string_append_c (str, '\r'); break; - case ';': str = g_string_append_c (str, ';'); break; - case ',': str = g_string_append_c (str, ','); break; - case '\\': str = g_string_append_c (str, '\\'); break; - default: - g_warning ("invalid escape, passing it through"); - str = g_string_append_c (str, '\\'); - str = g_string_append_unichar (str, g_utf8_get_char(lp)); - lp = g_utf8_next_char(lp); - break; - } - } - else if (*lp == ';') { - e_vcard_attribute_add_value (attr, g_string_free (str, FALSE)); - str = g_string_new (""); - lp = g_utf8_next_char(lp); - } - else { - str = g_string_append_unichar (str, g_utf8_get_char (lp)); - lp = g_utf8_next_char(lp); - } - } - if (str) - e_vcard_attribute_add_value (attr, g_string_free (str, FALSE)); - - if (*lp == '\r') { - lp = g_utf8_next_char (lp); /* \n */ - lp = g_utf8_next_char (lp); /* start of the next line */ - } - - *p = lp; -} - -static void -read_attribute_params (EVCardAttribute *attr, char **p, gboolean *quoted_printable) -{ - char *lp = *p; - GString *str; - EVCardAttributeParam *param = NULL; - - str = g_string_new (""); - while (*lp != '\0') { - /* accumulate until we hit the '=' or ';'. If we hit - * a '=' the string contains the parameter name. if - * we hit a ';' the string contains the parameter - * value and the name is either ENCODING (if value == - * QUOTED-PRINTABLE) or TYPE (in any other case.) - */ - if (*lp == '=') { - if (str->len > 0) { - param = e_vcard_attribute_param_new (str->str); - str = g_string_assign (str, ""); - lp = g_utf8_next_char (lp); - } - else { - skip_until (&lp, ":;"); - if (*lp == '\r') { - lp = g_utf8_next_char (lp); /* \n */ - lp = g_utf8_next_char (lp); /* start of the next line */ - break; - } - else if (*lp == ';') - lp = g_utf8_next_char (lp); - } - } - else if (*lp == ';' || *lp == ':' || *lp == ',') { - gboolean colon = (*lp == ':'); - gboolean comma = (*lp == ','); - - if (param) { - if (str->len > 0) { - e_vcard_attribute_param_add_value (param, str->str); - str = g_string_assign (str, ""); - if (!colon) - lp = g_utf8_next_char (lp); - } - else { - /* we've got a parameter of the form: - * PARAM=(.*,)?[:;] - * so what we do depends on if there are already values - * for the parameter. If there are, we just finish - * this parameter and skip past the offending character - * (unless it's the ':'). If there aren't values, we free - * the parameter then skip past the character. - */ - if (!param->values) { - e_vcard_attribute_param_free (param); - param = NULL; - } - } - - if (param - && !g_ascii_strcasecmp (param->name, "encoding") - && !g_ascii_strcasecmp (param->values->data, "quoted-printable")) { - *quoted_printable = TRUE; - e_vcard_attribute_param_free (param); - param = NULL; - } - } - else { - if (str->len > 0) { - char *param_name; - if (!g_ascii_strcasecmp (str->str, - "quoted-printable")) { - param_name = NULL; - *quoted_printable = TRUE; - } - else { - param_name = "TYPE"; - } - - if (param_name) { - param = e_vcard_attribute_param_new (param_name); - e_vcard_attribute_param_add_value (param, str->str); - } - str = g_string_assign (str, ""); - if (!colon) - lp = g_utf8_next_char (lp); - } - else { - /* XXX more here */ - g_assert_not_reached (); - } - } - if (param && !comma) { - e_vcard_attribute_add_param (attr, param); - param = NULL; - } - if (colon) - break; - } - else if (g_unichar_isalnum (g_utf8_get_char (lp)) || *lp == '-' || *lp == '_') { - str = g_string_append_unichar (str, g_utf8_get_char (lp)); - lp = g_utf8_next_char (lp); - } - else { - g_warning ("invalid character found in parameter spec"); - str = g_string_assign (str, ""); - skip_until (&lp, ":;"); - } - } - - if (str) - g_string_free (str, TRUE); - - *p = lp; -} - -/* reads an entire attribute from the input buffer, leaving p pointing - at the start of the next line (past the \r\n) */ -static EVCardAttribute* -read_attribute (char **p) -{ - char *attr_group = NULL; - char *attr_name = NULL; - EVCardAttribute *attr = NULL; - GString *str; - char *lp = *p; - gboolean is_qp = FALSE; - - /* first read in the group/name */ - str = g_string_new (""); - while (*lp != '\r' && *lp != '\0') { - if (*lp == ':' || *lp == ';') { - if (str->len != 0) { - /* we've got a name, break out to the value/attribute parsing */ - attr_name = g_string_free (str, FALSE); - break; - } - else { - /* a line of the form: - * (group.)?[:;] - * - * since we don't have an attribute - * name, skip to the end of the line - * and try again. - */ - g_string_free (str, TRUE); - *p = lp; - skip_to_next_line(p); - goto lose; - } - } - else if (*lp == '.') { - if (attr_group) { - g_warning ("extra `.' in attribute specification. ignoring extra group `%s'", - str->str); - g_string_free (str, TRUE); - str = g_string_new (""); - } - if (str->len != 0) { - attr_group = g_string_free (str, FALSE); - str = g_string_new (""); - } - } - else if (g_unichar_isalnum (g_utf8_get_char (lp)) || *lp == '-' || *lp == '_') { - str = g_string_append_unichar (str, g_utf8_get_char (lp)); - } - else { - g_warning ("invalid character found in attribute group/name"); - g_string_free (str, TRUE); - *p = lp; - skip_to_next_line(p); - goto lose; - } - - lp = g_utf8_next_char(lp); - } - - if (!attr_name) { - skip_to_next_line (p); - goto lose; - } - - attr = e_vcard_attribute_new (attr_group, attr_name); - g_free (attr_group); - g_free (attr_name); - - if (*lp == ';') { - /* skip past the ';' */ - lp = g_utf8_next_char(lp); - read_attribute_params (attr, &lp, &is_qp); - } - if (*lp == ':') { - /* skip past the ':' */ - lp = g_utf8_next_char(lp); - read_attribute_value (attr, &lp, is_qp); - } - - *p = lp; - - if (!attr->values) - goto lose; - - return attr; - lose: - if (attr) - e_vcard_attribute_free (attr); - return NULL; -} - -/* we try to be as forgiving as we possibly can here - this isn't a - * validator. Almost nothing is considered a fatal error. We always - * try to return *something*. - */ -static void -parse (EVCard *evc, const char *str) -{ - char *buf = g_strdup (str); - char *p, *end; - EVCardAttribute *attr; - - /* first validate the string is valid utf8 */ - if (!g_utf8_validate (buf, -1, (const char **)&end)) { - /* if the string isn't valid, we parse as much as we can from it */ - g_warning ("invalid utf8 passed to EVCard. Limping along."); - *end = '\0'; - } - - printf ("BEFORE FOLDING:\n"); - printf (str); - - buf = fold_lines (buf); - - printf ("\n\nAFTER FOLDING:\n"); - printf (buf); - - p = buf; - - attr = read_attribute (&p); - if (!attr || attr->group || g_ascii_strcasecmp (attr->name, "begin")) { - g_warning ("vcard began without a BEGIN:VCARD\n"); - } - - while (*p) { - EVCardAttribute *next_attr = read_attribute (&p); - - if (next_attr) { - if (g_ascii_strcasecmp (next_attr->name, "end")) - e_vcard_add_attribute (evc, next_attr); - attr = next_attr; - } - } - - if (!attr || attr->group || g_ascii_strcasecmp (attr->name, "end")) { - g_warning ("vcard ended without END:VCARD\n"); - } -} - -static char* -escape_string (const char *s) -{ - GString *str = g_string_new (""); - const char *p; - - /* Escape a string as described in RFC2426, section 5 */ - for (p = s; *p; p++) { - switch (*p) { - case '\n': - str = g_string_append (str, "\\n"); - break; - case '\r': - if (*(p+1) == '\n') - p++; - str = g_string_append (str, "\\n"); - break; - case ';': - str = g_string_append (str, "\\;"); - break; - case ',': - str = g_string_append (str, "\\,"); - break; - case '\\': - str = g_string_append (str, "\\\\"); - break; - default: - str = g_string_append_c (str, *p); - break; - } - } - - return g_string_free (str, FALSE); -} - -#if notyet -static char* -unescape_string (const char *s) -{ - GString *str = g_string_new (""); - const char *p; - - /* Unescape a string as described in RFC2426, section 5 */ - for (p = s; *p; p++) { - if (*p == '\\') { - p++; - if (*p == '\0') { - str = g_string_append_c (str, '\\'); - break; - } - switch (*p) { - case 'n': str = g_string_append_c (str, '\n'); break; - case 'r': str = g_string_append_c (str, '\r'); break; - case ';': str = g_string_append_c (str, ';'); break; - case ',': str = g_string_append_c (str, ','); break; - case '\\': str = g_string_append_c (str, '\\'); break; - default: - g_warning ("invalid escape, passing it through"); - str = g_string_append_c (str, '\\'); - str = g_string_append_unichar (str, g_utf8_get_char(p)); - break; - } - } - } - - return g_string_free (str, FALSE); -} -#endif - -EVCard * -e_vcard_new () -{ - return g_object_new (E_TYPE_VCARD, NULL); -} - -EVCard * -e_vcard_new_from_string (const char *str) -{ - EVCard *evc = e_vcard_new (); - - parse (evc, str); - - return evc; -} - -char* -e_vcard_to_string (EVCard *evc) -{ - GList *l; - GList *v; - - GString *str = g_string_new (""); - - str = g_string_append (str, "BEGIN:vCard" CRLF); - - for (l = evc->priv->attributes; l; l = l->next) { - GList *p; - EVCardAttribute *attr = l->data; - GString *attr_str = g_string_new (""); - int l; - - /* From rfc2425, 5.8.2 - * - * contentline = [group "."] name *(";" param) ":" value CRLF - */ - - if (attr->group) { - attr_str = g_string_append (attr_str, attr->group); - attr_str = g_string_append_c (attr_str, '.'); - } - attr_str = g_string_append (attr_str, attr->name); - - /* handle the parameters */ - for (p = attr->params; p; p = p->next) { - EVCardAttributeParam *param = p->data; - /* 5.8.2: - * param = param-name "=" param-value *("," param-value) - */ - attr_str = g_string_append_c (attr_str, ';'); - attr_str = g_string_append (attr_str, param->name); - if (param->values) { - attr_str = g_string_append_c (attr_str, '='); - for (v = param->values; v; v = v->next) { - char *value = v->data; - attr_str = g_string_append (attr_str, value); - if (v->next) - attr_str = g_string_append_c (attr_str, ','); - } - } - } - - attr_str = g_string_append_c (attr_str, ':'); - - for (v = attr->values; v; v = v->next) { - char *value = v->data; - char *escaped_value = NULL; - - escaped_value = escape_string (value); - - attr_str = g_string_append (attr_str, escaped_value); - if (v->next) - attr_str = g_string_append_c (attr_str, ';'); - - g_free (escaped_value); - } - - /* 5.8.2: - * When generating a content line, lines longer than 75 - * characters SHOULD be folded - */ - l = 0; - do { - if (attr_str->len - l > 75) { - l += 75; - attr_str = g_string_insert_len (attr_str, l, CRLF " ", sizeof (CRLF " ") - 1); - } - else - break; - } while (l < attr_str->len); - - attr_str = g_string_append (attr_str, CRLF); - - str = g_string_append (str, g_string_free (attr_str, FALSE)); - } - - str = g_string_append (str, "END:vCard"); - - return g_string_free (str, FALSE); -} - -void -e_vcard_dump_structure (EVCard *evc) -{ - GList *a; - GList *v; - int i; - - printf ("vCard\n"); - for (a = evc->priv->attributes; a; a = a->next) { - GList *p; - EVCardAttribute *attr = a->data; - printf ("+-- %s\n", attr->name); - if (attr->params) { - printf (" +- params=\n"); - - for (p = attr->params, i = 0; p; p = p->next, i++) { - EVCardAttributeParam *param = p->data; - printf (" | [%d] = %s", i,param->name); - printf ("("); - for (v = param->values; v; v = v->next) { - char *value = escape_string ((char*)v->data); - printf ("%s", value); - if (v->next) - printf (","); - g_free (value); - } - - printf (")\n"); - } - } - printf (" +- values=\n"); - for (v = attr->values, i = 0; v; v = v->next, i++) { - printf (" [%d] = `%s'\n", i, (char*)v->data); - } - } -} - - -EVCardAttribute* -e_vcard_attribute_new (const char *attr_group, const char *attr_name) -{ - EVCardAttribute *attr = g_new0 (EVCardAttribute, 1); - - attr->group = g_strdup (attr_group); - attr->name = g_strdup (attr_name); - - return attr; -} - -void -e_vcard_attribute_free (EVCardAttribute *attr) -{ - GList *p; - - g_free (attr->group); - g_free (attr->name); - - g_list_foreach (attr->values, (GFunc)g_free, NULL); - g_list_free (attr->values); - - for (p = attr->params; p; p = p->next) { - EVCardAttributeParam *param = p->data; - - g_free (param->name); - g_list_foreach (param->values, (GFunc)g_free, NULL); - g_list_free (param->values); - g_free (param); - } - - g_free (attr); -} - -void -e_vcard_add_attribute (EVCard *evc, EVCardAttribute *attr) -{ - evc->priv->attributes = g_list_append (evc->priv->attributes, attr); -} - -void -e_vcard_add_attribute_with_value (EVCard *evcard, - EVCardAttribute *attr, const char *value) -{ - e_vcard_attribute_add_value (attr, value); - - e_vcard_add_attribute (evcard, attr); -} - -void -e_vcard_add_attribute_with_values (EVCard *evcard, EVCardAttribute *attr, ...) -{ - va_list ap; - char *v; - - va_start (ap, attr); - - while ((v = va_arg (ap, char*))) { - e_vcard_attribute_add_value (attr, v); - } - - va_end (ap); - - e_vcard_add_attribute (evcard, attr); -} - -void -e_vcard_attribute_add_value (EVCardAttribute *attr, const char *value) -{ - attr->values = g_list_append (attr->values, g_strdup (value)); -} - -void -e_vcard_attribute_add_values (EVCardAttribute *attr, - ...) -{ - va_list ap; - char *v; - - va_start (ap, attr); - - while ((v = va_arg (ap, char*))) { - e_vcard_attribute_add_value (attr, v); - } - - va_end (ap); -} - - -EVCardAttributeParam* -e_vcard_attribute_param_new (const char *name) -{ - EVCardAttributeParam *param = g_new0 (EVCardAttributeParam, 1); - param->name = g_strdup (name); - - return param; -} - -void -e_vcard_attribute_param_free (EVCardAttributeParam *param) -{ - g_free (param->name); - g_list_foreach (param->values, (GFunc)g_free, NULL); - g_list_free (param->values); - g_free (param); -} - -void -e_vcard_attribute_add_param (EVCardAttribute *attr, - EVCardAttributeParam *param) -{ - attr->params = g_list_append (attr->params, param); -} - -void -e_vcard_attribute_param_add_value (EVCardAttributeParam *param, - const char *value) -{ - param->values = g_list_append (param->values, g_strdup (value)); -} - -void -e_vcard_attribute_param_add_values (EVCardAttributeParam *param, - ...) -{ - va_list ap; - char *v; - - va_start (ap, param); - - while ((v = va_arg (ap, char*))) { - e_vcard_attribute_param_add_value (param, v); - } - - va_end (ap); -} - -void -e_vcard_attribute_add_param_with_value (EVCardAttribute *attr, - EVCardAttributeParam *param, const char *value) -{ - e_vcard_attribute_param_add_value (param, value); - - e_vcard_attribute_add_param (attr, param); -} - -void -e_vcard_attribute_add_param_with_values (EVCardAttribute *attr, - EVCardAttributeParam *param, ...) -{ - va_list ap; - char *v; - - va_start (ap, param); - - while ((v = va_arg (ap, char*))) { - e_vcard_attribute_param_add_value (param, v); - } - - va_end (ap); - - e_vcard_attribute_add_param (attr, param); -} - -GList* -e_vcard_get_attributes (EVCard *evcard) -{ - return evcard->priv->attributes; -} - -const char* -e_vcard_attribute_get_group (EVCardAttribute *attr) -{ - return attr->group; -} - -const char* -e_vcard_attribute_get_name (EVCardAttribute *attr) -{ - return attr->name; -} - -GList* -e_vcard_attribute_get_values (EVCardAttribute *attr) -{ - return attr->values; -} - -GList* -e_vcard_attribute_get_params (EVCardAttribute *attr) -{ - return attr->params; -} - -const char* -e_vcard_attribute_param_get_name (EVCardAttributeParam *param) -{ - return param->name; -} - -GList* -e_vcard_attribute_param_get_values (EVCardAttributeParam *param) -{ - return param->values; -} diff --git a/addressbook/backend/ebook/e-vcard.h b/addressbook/backend/ebook/e-vcard.h deleted file mode 100644 index 69e0a3e10b..0000000000 --- a/addressbook/backend/ebook/e-vcard.h +++ /dev/null @@ -1,108 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* e-vcard.h - * - * Copyright (C) 2003 Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * - * Author: Chris Toshok (toshok@ximian.com) - */ - -#ifndef _EVCARD_H -#define _EVCARD_H - -#include <glib.h> -#include <glib-object.h> - -#define EVC_FN "FN" -#define EVC_ORG "ORG" -#define EVC_URL "URL" -#define EVC_VERSION "VERSION" -#define EVC_REV "REV" -#define EVC_PRODID "PRODID" -#define EVC_TYPE "TYPE" -#define EVC_ADR "ADR" -#define EVC_TEL "TEL" - -#define EVC_ENCODING "ENCODING" -#define EVC_QUOTEDPRINTABLE "QUOTED-PRINTABLE" - -#define E_TYPE_VCARD (e_vcard_get_type ()) -#define E_VCARD(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_TYPE_VCARD, EVCard)) -#define E_VCARD_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), E_TYPE_VCARD, EVCardClass)) -#define E_IS_VCARD(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), E_TYPE_VCARD)) -#define E_IS_VCARD_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), E_TYPE_VCARD)) -#define E_VCARD_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), E_TYPE_VCARD, EVCardClass)) - -typedef struct _EVCard EVCard; -typedef struct _EVCardClass EVCardClass; -typedef struct _EVCardPrivate EVCardPrivate; -typedef struct _EVCardAttribute EVCardAttribute; -typedef struct _EVCardAttributeParam EVCardAttributeParam; - -struct _EVCard { - GObject parent; - - EVCardPrivate *priv; -}; - -struct _EVCardClass { - GObjectClass parent_class; -}; - -GType e_vcard_get_type (void); -EVCard* e_vcard_new (void); -EVCard* e_vcard_new_from_string (const char *str); -char* e_vcard_to_string (EVCard *evcard); -/* mostly for debugging */ -void e_vcard_dump_structure (EVCard *evc); - - -/* attributes */ -EVCardAttribute *e_vcard_attribute_new (const char *attr_group, const char *attr_name); -void e_vcard_attribute_free (EVCardAttribute *attr); -void e_vcard_add_attribute (EVCard *evcard, EVCardAttribute *attr); -void e_vcard_add_attribute_with_value (EVCard *evcard, EVCardAttribute *attr, const char *value); -void e_vcard_add_attribute_with_values (EVCard *evcard, EVCardAttribute *attr, ...); -void e_vcard_attribute_add_value (EVCardAttribute *attr, const char *value); -void e_vcard_attribute_add_values (EVCardAttribute *attr, ...); - -/* attribute parameters */ -EVCardAttributeParam* e_vcard_attribute_param_new (const char *param_name); -void e_vcard_attribute_param_free (EVCardAttributeParam *param); -void e_vcard_attribute_add_param (EVCardAttribute *attr, EVCardAttributeParam *param); -void e_vcard_attribute_add_param_with_value (EVCardAttribute *attr, - EVCardAttributeParam *param, const char *value); -void e_vcard_attribute_add_param_with_values (EVCardAttribute *attr, - EVCardAttributeParam *param, ...); - -void e_vcard_attribute_param_add_value (EVCardAttributeParam *param, - const char *value); -void e_vcard_attribute_param_add_values (EVCardAttributeParam *param, - ...); - -/* EVCard* accessors. nothing returned from these functions should be - freed by the caller. */ -GList* e_vcard_get_attributes (EVCard *evcard); -const char* e_vcard_attribute_get_group (EVCardAttribute *attr); -const char* e_vcard_attribute_get_name (EVCardAttribute *attr); -GList* e_vcard_attribute_get_values (EVCardAttribute *attr); - -GList* e_vcard_attribute_get_params (EVCardAttribute *attr); -const char* e_vcard_attribute_param_get_name (EVCardAttributeParam *param); -GList* e_vcard_attribute_param_get_values (EVCardAttributeParam *param); - - -#endif /* _EVCARD_H */ diff --git a/addressbook/backend/ebook/evolution-ldif-importer.c b/addressbook/backend/ebook/evolution-ldif-importer.c deleted file mode 100644 index 559e591fdb..0000000000 --- a/addressbook/backend/ebook/evolution-ldif-importer.c +++ /dev/null @@ -1,592 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -/* - * LDIF importer. LDIF is the file format of an exported Netscape - * addressbook. - * - * Framework copied from evolution-gnomecard-importer.c - * - * Michael M. Morrison (mmorrison@kqcorp.com) - * - * Multi-line value support, mailing list support, base64 support, and - * various fixups: Chris Toshok (toshok@ximian.com) - */ - -#include <config.h> -#include <stdio.h> -#include <ctype.h> -#include <string.h> - -#include <e-book.h> -#include <e-book-util.h> -#include <e-card-simple.h> -#include <e-destination.h> - -#include <libgnome/gnome-init.h> -#include <bonobo/bonobo-generic-factory.h> -#include <bonobo/bonobo-main.h> - -#include <importer/evolution-importer.h> -#include <importer/GNOME_Evolution_Importer.h> - -#define COMPONENT_FACTORY_IID "OAFIID:GNOME_Evolution_Addressbook_LDIF_ImporterFactory" -#define COMPONENT_IID "OAFIID:GNOME_Evolution_Addressbook_LDIF_Importer" - -static GHashTable *dn_card_hash; - -typedef struct { - char *filename; - GList *cardlist; - GList *iterator; - EBook *book; - gboolean ready; -} LDIFImporter; - -static struct { - char *ldif_attribute; - ECardSimpleField simple_field; -#define FLAG_ADDRESS 0x01 - int flags; -} -ldif_fields[] = { - { "cn", E_CARD_SIMPLE_FIELD_FULL_NAME }, - { "mail", E_CARD_SIMPLE_FIELD_EMAIL }, -#if 0 - { "givenname", E_CARD_SIMPLE_FIELD_GIVEN_NAME }, -#endif - { "sn", E_CARD_SIMPLE_FIELD_FAMILY_NAME }, - { "xmozillanickname", E_CARD_SIMPLE_FIELD_NICKNAME }, - { "o", E_CARD_SIMPLE_FIELD_ORG }, - { "locality", 0, FLAG_ADDRESS}, - { "st", 0, FLAG_ADDRESS }, - { "streetaddress", 0, FLAG_ADDRESS }, - { "title", E_CARD_SIMPLE_FIELD_TITLE }, - { "postalcode", 0, FLAG_ADDRESS }, - { "countryname", 0, FLAG_ADDRESS }, - { "telephonenumber", E_CARD_SIMPLE_FIELD_PHONE_BUSINESS}, - { "homephone", E_CARD_SIMPLE_FIELD_PHONE_HOME }, - { "facsimiletelephonenumber", E_CARD_SIMPLE_FIELD_PHONE_BUSINESS_FAX }, - { "ou", E_CARD_SIMPLE_FIELD_ORG_UNIT }, - { "pagerphone", E_CARD_SIMPLE_FIELD_PHONE_PAGER }, - { "cellphone", E_CARD_SIMPLE_FIELD_PHONE_MOBILE }, - { "homeurl", E_CARD_SIMPLE_FIELD_URL }, - { "description", E_CARD_SIMPLE_FIELD_NOTE }, - { "xmozillausehtmlmail", E_CARD_SIMPLE_FIELD_WANTS_HTML } -}; -static int num_ldif_fields = sizeof(ldif_fields) / sizeof (ldif_fields[0]); - -static unsigned char base64_rank[256] = { - 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255,255,255,255, 62,255,255,255, 63, - 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,255,255,255, 0,255,255, - 255, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,255,255,255,255,255, - 255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, - 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,255,255,255,255,255, - 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, -}; - -/** - * base64_decode_step: decode a chunk of base64 encoded data - * @in: input stream - * @len: max length of data to decode - * @out: output stream - * @state: holds the number of bits that are stored in @save - * @save: leftover bits that have not yet been decoded - * - * Decodes a chunk of base64 encoded data - **/ -static int -base64_decode_step(unsigned char *in, int len, unsigned char *out, int *state, unsigned int *save) -{ - register unsigned char *inptr, *outptr; - unsigned char *inend, c; - register unsigned int v; - int i; - - inend = in+len; - outptr = out; - - /* convert 4 base64 bytes to 3 normal bytes */ - v=*save; - i=*state; - inptr = in; - while (inptr<inend) { - c = base64_rank[*inptr++]; - if (c != 0xff) { - v = (v<<6) | c; - i++; - if (i==4) { - *outptr++ = v>>16; - *outptr++ = v>>8; - *outptr++ = v; - i=0; - } - } - } - - *save = v; - *state = i; - - /* quick scan back for '=' on the end somewhere */ - /* fortunately we can drop 1 output char for each trailing = (upto 2) */ - i=2; - while (inptr>in && i) { - inptr--; - if (base64_rank[*inptr] != 0xff) { - if (*inptr == '=') - outptr--; - i--; - } - } - - /* if i!= 0 then there is a truncation error! */ - return outptr-out; -} - -static int -base64_decode_simple (char *data, int len) -{ - int state = 0; - unsigned int save = 0; - - return base64_decode_step ((unsigned char *)data, len, - (unsigned char *)data, &state, &save); -} - -static GString * -getValue( char **src ) -{ - GString *dest = g_string_new(""); - char *s = *src; - gboolean need_base64 = (*s == ':'); - - copy_line: - while( *s != 0 && *s != '\n' && *s != '\r' ) - dest = g_string_append_c (dest, *s++); - - if (*s == '\r') s++; - if (*s == '\n') s++; - - /* check for continuation here */ - if (*s == ' ') { - s++; - goto copy_line; - } - - if (need_base64) { - int new_len; - /* it's base64 encoded */ - dest = g_string_erase (dest, 0, 2); - new_len = base64_decode_simple (dest->str, strlen (dest->str)); - dest = g_string_truncate (dest, new_len); - } - - *src = s; - - return dest; -} - -static gboolean -parseLine( ECardSimple *simple, ECardDeliveryAddress *address, char **buf ) -{ - char *ptr; - char *colon, *value; - gboolean field_handled; - GString *ldif_value; - - ptr = *buf; - - /* if the string is empty, return */ - if (*ptr == '\0') { - *buf = NULL; - return TRUE; - } - - /* skip comment lines */ - if (*ptr == '#') { - ptr = strchr (ptr, '\n'); - if (!ptr) - *buf = NULL; - else - *buf = ptr + 1; - return TRUE; - } - - /* first, check for a 'continuation' line */ - if( ptr[0] == ' ' && ptr[1] != '\n' ) { - g_warning ("unexpected continuation line"); - return FALSE; - } - - colon = (char *)strchr( ptr, ':' ); - if (colon) { - int i; - - *colon = 0; - value = colon + 1; - while ( isspace(*value) ) - value++; - - ldif_value = getValue(&value ); - - field_handled = FALSE; - for (i = 0; i < num_ldif_fields; i ++) { - if (!g_ascii_strcasecmp (ptr, ldif_fields[i].ldif_attribute)) { - if (ldif_fields[i].flags & FLAG_ADDRESS) { - if (!g_ascii_strcasecmp (ptr, "locality")) - address->city = g_strdup (ldif_value->str); - else if (!g_ascii_strcasecmp (ptr, "countryname")) - address->country = g_strdup (ldif_value->str); - else if (!g_ascii_strcasecmp (ptr, "postalcode")) - address->code = g_strdup (ldif_value->str); - else if (!g_ascii_strcasecmp (ptr, "st")) - address->region = g_strdup (ldif_value->str); - else if (!g_ascii_strcasecmp (ptr, "streetaddress")) - address->street = g_strdup (ldif_value->str); - } - else { - e_card_simple_set (simple, ldif_fields[i].simple_field, ldif_value->str); - printf ("set %s to %s\n", ptr, ldif_value->str); - } - field_handled = TRUE; - break; - } - } - - /* handle objectclass/dn/member out here */ - if (!field_handled) { - if (!g_ascii_strcasecmp (ptr, "dn")) - g_hash_table_insert (dn_card_hash, g_strdup(ldif_value->str), simple->card); - else if (!g_ascii_strcasecmp (ptr, "objectclass") && !g_ascii_strcasecmp (ldif_value->str, "groupofnames")) { - e_card_simple_set (simple, E_CARD_SIMPLE_FIELD_IS_LIST, "true"); - } - else if (!g_ascii_strcasecmp (ptr, "member")) { - EList *email; - g_object_get (simple->card, - "email", &email, - NULL); - e_list_append (email, ldif_value->str); - g_object_unref (email); - } - } - - /* put the colon back the way it was, just for kicks */ - *colon = ':'; - - g_string_free (ldif_value, TRUE); - } - else { - g_warning ("unrecognized entry %s", ptr); - return FALSE; - } - - *buf = value; - - return TRUE; -} - -static ECard * -getNextLDIFEntry( FILE *f ) -{ - ECard *card; - ECardAddrLabel *label; - ECardSimple *simple; - ECardDeliveryAddress *address; - GString *str; - char line[1024]; - char *buf; - - str = g_string_new (""); - /* read from the file until we get to a blank line (or eof) */ - while (!feof (f)) { - if (!fgets (line, sizeof(line), f)) - break; - if (line[0] == '\n' || (line[0] == '\r' && line[1] == '\n')) - break; - str = g_string_append (str, line); - } - - if (strlen (str->str) == 0) { - g_string_free (str, TRUE); - return NULL; - } - - /* now parse that entry */ - card = e_card_new (""); - simple = e_card_simple_new (card); - address = e_card_delivery_address_new (); - - buf = str->str; - while (buf) { - if (!parseLine (simple, address, &buf)) { - /* parsing error */ - g_object_unref (simple); - e_card_delivery_address_unref (address); - return NULL; - } - } - - - /* fill in the address */ - address->flags = E_CARD_ADDR_HOME; - - label = e_card_delivery_address_to_label (address); - e_card_delivery_address_unref (address); - - e_card_simple_set_address (simple, E_CARD_SIMPLE_ADDRESS_ID_HOME, label); - - e_card_address_label_unref (label); - - e_card_simple_sync_card (simple); - - g_string_free (str, TRUE); - - return card; -} - -static void -add_card_cb (EBook *book, EBookStatus status, const gchar *id, gpointer closure) -{ - ECard *card = E_CARD(closure); - char *vcard; - - e_card_set_id (card, id); - - vcard = e_card_get_vcard(card); - - g_print ("Saved card: %s\n", vcard); - g_free(vcard); -} - -static void -resolve_list_card (LDIFImporter *gci, ECard *card) -{ - EList *email; - EIterator *email_iter; - char *full_name; - - if (!e_card_evolution_list (card)) - return; - - g_object_get (card, - "email", &email, - "full_name", &full_name, - NULL); - - /* set file_as to full_name so we don't later try and figure - out a first/last name for the list. */ - if (full_name) { - g_object_set (card, - "file_as", full_name, - NULL); - g_free (full_name); - } - - email_iter = e_list_get_iterator (email); - while (e_iterator_is_valid (email_iter)) { - const char *dn = e_iterator_get (email_iter); - ECard *dn_card = g_hash_table_lookup (dn_card_hash, dn); - - /* break list chains here, since we don't support them just yet */ - if (dn_card && !e_card_evolution_list (dn_card)) { - EDestination *dest = e_destination_new (); - gchar *dest_xml; - e_destination_set_card (dest, dn_card, 0); /* Hard-wired for default e-mail, since netscape only exports 1 email address */ - dest_xml = e_destination_export (dest); - g_object_unref (dest); - if (dest_xml) { - e_iterator_set (email_iter, dest_xml); - g_free (dest_xml); - e_iterator_next (email_iter); - } - else { - e_iterator_delete (email_iter); - } - } - else { - e_iterator_delete (email_iter); - } - } - g_object_unref(email); -} - -static void -book_open_cb (EBook *book, EBookStatus status, gpointer closure) -{ - LDIFImporter *gci = (LDIFImporter *) closure; - GList * list = NULL; - GList * list_list = NULL; - FILE * file; - ECard *card; - - if(!( file = fopen( gci->filename, "r" ) )) { - g_warning("!!!Can't open .ldif file"); - return; - } - - dn_card_hash = g_hash_table_new (g_str_hash, g_str_equal); - - while ((card = getNextLDIFEntry (file))) { - - if (e_card_evolution_list (card)) - list_list = g_list_append (list_list, card); - else - list = g_list_append (list, card); - } - - fclose( file ); - - list = g_list_reverse( list ); - list_list = g_list_reverse (list_list); - list = g_list_concat (list, list_list); - - gci->cardlist = list; - gci->ready = TRUE; -} - -static void -ebook_open (LDIFImporter *gci, const char *uri) -{ - gci->book = e_book_new (); - - if (!gci->book) { - printf ("%s: %s(): Couldn't create EBook, bailing.\n", - __FILE__, - G_GNUC_FUNCTION); - return; - } - - e_book_load_address_book_by_uri (gci->book, uri, book_open_cb, gci); -} - -/* EvolutionImporter methods */ -static void -process_item_fn (EvolutionImporter *importer, - CORBA_Object listener, - void *closure, - CORBA_Environment *ev) -{ - LDIFImporter *gci = (LDIFImporter *) closure; - ECard *card; - - if (gci->iterator == NULL) - gci->iterator = gci->cardlist; - - if (gci->ready == FALSE) { - GNOME_Evolution_ImporterListener_notifyResult (listener, - GNOME_Evolution_ImporterListener_NOT_READY, - gci->iterator ? TRUE : FALSE, - ev); - return; - } - - if (gci->iterator == NULL) { - GNOME_Evolution_ImporterListener_notifyResult (listener, - GNOME_Evolution_ImporterListener_UNSUPPORTED_OPERATION, - FALSE, ev); - return; - } - - card = gci->iterator->data; - if (e_card_evolution_list (card)) - resolve_list_card (gci, card); - e_book_add_card (gci->book, card, add_card_cb, card); - - gci->iterator = gci->iterator->next; - - GNOME_Evolution_ImporterListener_notifyResult (listener, - GNOME_Evolution_ImporterListener_OK, - gci->iterator ? TRUE : FALSE, - ev); - if (ev->_major != CORBA_NO_EXCEPTION) { - g_warning ("Error notifying listeners."); - } - - return; -} - -static char *supported_extensions[2] = { - ".ldif", NULL -}; - -static gboolean -support_format_fn (EvolutionImporter *importer, - const char *filename, - void *closure) -{ - char *ext; - int i; - - ext = strrchr (filename, '.'); - if (ext == NULL) { - return FALSE; - } - - for (i = 0; supported_extensions[i] != NULL; i++) { - if (strcmp (supported_extensions[i], ext) == 0) - return TRUE; - } - - return FALSE; -} - -static void -importer_destroy_cb (gpointer data, - GObject *where_object_was) -{ - bonobo_main_quit (); -} - -static gboolean -load_file_fn (EvolutionImporter *importer, - const char *filename, - const char *uri, - const char *folder_type, - void *closure) -{ - LDIFImporter *gci; - - gci = (LDIFImporter *) closure; - gci->filename = g_strdup (filename); - gci->cardlist = NULL; - gci->iterator = NULL; - gci->ready = FALSE; - ebook_open (gci, uri); - - return TRUE; -} - -static BonoboObject * -factory_fn (BonoboGenericFactory *_factory, - const char *component_id, - void *closure) -{ - EvolutionImporter *importer; - LDIFImporter *gci; - - if (!strcmp (component_id, COMPONENT_IID)) { - gci = g_new (LDIFImporter, 1); - importer = evolution_importer_new (support_format_fn, load_file_fn, - process_item_fn, NULL, gci); - - g_object_weak_ref (G_OBJECT (importer), - importer_destroy_cb, gci); - - return BONOBO_OBJECT (importer); - } - else { - g_warning (COMPONENT_FACTORY_IID ": Don't know what to do with %s", component_id); - return NULL; - } -} - -BONOBO_ACTIVATION_FACTORY (COMPONENT_FACTORY_IID, "Evolution LDIF Importer Factory", VERSION, factory_fn, NULL); diff --git a/addressbook/backend/ebook/evolution-vcard-importer.c b/addressbook/backend/ebook/evolution-vcard-importer.c deleted file mode 100644 index c01c118cae..0000000000 --- a/addressbook/backend/ebook/evolution-vcard-importer.c +++ /dev/null @@ -1,214 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -#include <config.h> -#include <stdio.h> -#include <string.h> - -#include <bonobo/bonobo-context.h> -#include <bonobo/bonobo-generic-factory.h> -#include <bonobo/bonobo-main.h> - -#include <e-book.h> -#include <e-book-util.h> - -#include <importer/evolution-importer.h> -#include <importer/GNOME_Evolution_Importer.h> - -#include <e-util/e-path.h> - -#define COMPONENT_FACTORY_IID "OAFIID:GNOME_Evolution_Addressbook_VCard_ImporterFactory" -#define COMPONENT_IID "OAFIID:GNOME_Evolution_Addressbook_VCard_Importer" - -typedef struct { - char *filename; - GList *cardlist; - GList *iterator; - EBook *book; - gboolean ready; -} VCardImporter; - -static void -add_card_cb (EBook *book, EBookStatus status, const gchar *id, gpointer closure) -{ - ECard *card = E_CARD(closure); - g_object_unref(card); -} - -static void -book_open_cb (EBook *book, EBookStatus status, gpointer closure) -{ - VCardImporter *gci = (VCardImporter *) closure; - - gci->cardlist = e_card_load_cards_from_file_with_default_charset(gci->filename, "ISO-8859-1"); - gci->ready = TRUE; -} - -static void -ebook_open (VCardImporter *gci, const char *uri) -{ - gci->book = e_book_new (); - - if (!gci->book) { - printf ("%s: %s(): Couldn't create EBook, bailing.\n", - __FILE__, - G_GNUC_FUNCTION); - return; - } - - e_book_load_address_book_by_uri (gci->book, uri, book_open_cb, gci); -} - -/* EvolutionImporter methods */ -static void -process_item_fn (EvolutionImporter *importer, - CORBA_Object listener, - void *closure, - CORBA_Environment *ev) -{ - VCardImporter *gci = (VCardImporter *) closure; - ECard *card; - - if (gci->iterator == NULL) - gci->iterator = gci->cardlist; - - if (gci->ready == FALSE) { - GNOME_Evolution_ImporterListener_notifyResult (listener, - GNOME_Evolution_ImporterListener_NOT_READY, - gci->iterator ? TRUE : FALSE, - ev); - return; - } - - if (gci->iterator == NULL) { - GNOME_Evolution_ImporterListener_notifyResult (listener, - GNOME_Evolution_ImporterListener_UNSUPPORTED_OPERATION, - FALSE, ev); - return; - } - - card = gci->iterator->data; - e_book_add_card (gci->book, card, add_card_cb, card); - - gci->iterator = gci->iterator->next; - - GNOME_Evolution_ImporterListener_notifyResult (listener, - GNOME_Evolution_ImporterListener_OK, - gci->iterator ? TRUE : FALSE, - ev); - if (ev->_major != CORBA_NO_EXCEPTION) { - g_warning ("Error notifying listeners."); - } - - return; -} - -static char *supported_extensions[3] = { - ".vcf", - ".gcrd", - NULL -}; - -/* Actually check the contents of this file */ -static gboolean -check_file_is_vcard (const char *filename) -{ - FILE *handle; - char line[4096]; - gboolean result; - - handle = fopen (filename, "r"); - if (handle == NULL) { - g_print ("\n"); - return FALSE; - } - - fgets (line, 4096, handle); - if (line == NULL) { - fclose (handle); - g_print ("\n"); - return FALSE; - } - - if (g_ascii_strncasecmp (line, "BEGIN:VCARD", 11) == 0) { - result = TRUE; - } else { - result = FALSE; - } - - fclose (handle); - return result; -} - -static gboolean -support_format_fn (EvolutionImporter *importer, - const char *filename, - void *closure) -{ - char *ext; - int i; - - ext = strrchr (filename, '.'); - if (ext == NULL) { - return check_file_is_vcard (filename); - } - for (i = 0; supported_extensions[i] != NULL; i++) { - if (g_ascii_strcasecmp (supported_extensions[i], ext) == 0) - return check_file_is_vcard (filename); - } - - return FALSE; -} - -static void -importer_destroy_cb (gpointer data, - GObject *where_object_was) -{ - bonobo_main_quit (); -} - -static gboolean -load_file_fn (EvolutionImporter *importer, - const char *filename, - const char *uri, - const char *folder_type, - void *closure) -{ - VCardImporter *gci; - - if (check_file_is_vcard (filename) == FALSE) { - return FALSE; - } - - gci = (VCardImporter *) closure; - gci->filename = g_strdup (filename); - gci->cardlist = NULL; - gci->iterator = NULL; - gci->ready = FALSE; - ebook_open (gci, uri); - - return TRUE; -} - -static BonoboObject * -factory_fn (BonoboGenericFactory *_factory, - const char *component_id, - void *closure) -{ - EvolutionImporter *importer; - VCardImporter *gci; - - if (!strcmp (component_id, COMPONENT_IID)) { - gci = g_new (VCardImporter, 1); - importer = evolution_importer_new (support_format_fn, load_file_fn, - process_item_fn, NULL, gci); - - g_object_weak_ref (G_OBJECT (importer), - importer_destroy_cb, gci); - return BONOBO_OBJECT (importer); - } - else { - g_warning (COMPONENT_FACTORY_IID ": Don't know what to do with %s", component_id); - return NULL; - } -} - -BONOBO_ACTIVATION_FACTORY (COMPONENT_FACTORY_IID, "Evolution VCard Importer Factory", VERSION, factory_fn, NULL); diff --git a/addressbook/backend/ebook/load-gnomecard-addressbook.c b/addressbook/backend/ebook/load-gnomecard-addressbook.c deleted file mode 100644 index f6fde225e0..0000000000 --- a/addressbook/backend/ebook/load-gnomecard-addressbook.c +++ /dev/null @@ -1,77 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -#include <config.h> -#include <stdio.h> -#include <glib.h> - -#include <bonobo/bonobo-i18n.h> -#include <bonobo/bonobo-main.h> -#include <libgnome/gnome-init.h> - -#include "e-book.h" - -static void -add_card_cb (EBook *book, EBookStatus status, const gchar *id, gpointer closure) -{ - ECard *card = E_CARD(closure); - char *vcard = e_card_get_vcard_assume_utf8(card); - g_print ("Saved card: %s\n", vcard); - g_free(vcard); - g_object_unref(card); -} - -static void -book_open_cb (EBook *book, EBookStatus status, gpointer closure) -{ - GList *list = e_card_load_cards_from_file_with_default_charset("gnomecard.vcf", "ISO-8859-1"); - GList *iterator; - for (iterator = list; iterator; iterator = g_list_next(iterator)) { - ECard *card = iterator->data; - e_book_add_card(book, card, add_card_cb, card); - } - g_list_free(list); -} - -static gboolean -ebook_create (gpointer data) -{ - EBook *book; - gchar *path, *uri; - - book = e_book_new (); - - if (!book) { - printf ("%s: %s(): Couldn't create EBook, bailing.\n", - __FILE__, - G_GNUC_FUNCTION); - return FALSE; - } - - - path = g_build_filename (g_get_home_dir (), - "evolution/local/Contacts/addressbook.db", - NULL); - uri = g_strdup_printf ("file://%s", path); - g_free (path); - - e_book_load_uri (book, uri, book_open_cb, NULL); - g_free(uri); - - - return FALSE; -} - -int -main (int argc, char **argv) -{ - GnomeProgram *program; - - program = gnome_program_init ("load-gnomecard-addressbook", VERSION, LIBGNOME_MODULE, argc, argv, - GNOME_PROGRAM_STANDARD_PROPERTIES, - NULL); - - g_idle_add (ebook_create, NULL); - - bonobo_main (); - - return 0; -} diff --git a/addressbook/backend/ebook/load-pine-addressbook.c b/addressbook/backend/ebook/load-pine-addressbook.c deleted file mode 100644 index ece04bbdef..0000000000 --- a/addressbook/backend/ebook/load-pine-addressbook.c +++ /dev/null @@ -1,159 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -#include <config.h> -#include <ctype.h> -#include <stdio.h> -#include <string.h> -#include <glib.h> -#include <bonobo/bonobo-i18n.h> -#include <bonobo/bonobo-main.h> -#include <libgnome/gnome-init.h> - -#include "e-book.h" - -static void -add_card_cb (EBook *book, EBookStatus status, const gchar *id, gpointer closure) -{ - ECard *card = E_CARD(closure); - char *vcard = e_card_get_vcard_assume_utf8(card); - g_print ("Saved card: %s\n", vcard); - g_free(vcard); - g_object_unref(card); -} - -static void -parse_line (EBook *book, char *line) -{ - char **strings; - ECardName *name; - ECard *card; - EList *list; - - card = e_card_new(""); - strings = g_strsplit(line, "\t", 3); - if (strings[0] && strings[1] && strings[2]) { - name = e_card_name_from_string(strings[1]); - g_object_set(card, - "nickname", strings[0], - "full_name", strings[1], - "name", name, - NULL); - g_object_get(card, - "email", &list, - NULL); - e_list_append(list, strings[2]); - e_book_add_card(book, card, add_card_cb, card); - g_object_unref(list); - } - g_strfreev(strings); -} - -static void -book_open_cb (EBook *book, EBookStatus status, gpointer closure) -{ - FILE *fp = fopen (".addressbook", "r"); - char line[2 * 1024]; - int which = 0; - char *lastline = NULL; - - if (!fp) { - g_warning ("Can't find .addressbook"); - return; - } - - while(fgets(line + which * 1024, 1024, fp)) { - int length; - char *thisline = line + which * 1024; - length = strlen(thisline); - if (thisline[length - 1] == '\n') - line[--length] = 0; - if (lastline && *thisline && isspace(*thisline)) { - char *temp; - while(*thisline && isspace(*thisline)) - thisline ++; - temp = lastline; - lastline = g_strdup_printf("%s%s", lastline, thisline); - g_free(temp); - continue; - } - if (lastline) { - parse_line (book, lastline); - g_free(lastline); - } - lastline = g_strdup(thisline); - } - - if (lastline) { - parse_line (book, lastline); - g_free(lastline); - } -} - -static gboolean -ebook_create (gpointer data) -{ - EBook *book; - gchar *path, *uri; - - book = e_book_new (); - - if (!book) { - printf ("%s: %s(): Couldn't create EBook, bailing.\n", - __FILE__, G_GNUC_FUNCTION); - return FALSE; - } - - - path = g_build_filename (g_get_home_dir (), - "evolution/local/Contacts/addressbook.db", - NULL); - - uri = g_strdup_printf ("file://%s", path); - g_free (path); - - e_book_load_uri (book, uri, book_open_cb, NULL); - g_free(uri); - - - return FALSE; -} - -#if 0 -static char * -read_file (char *name) -{ - int len; - char buff[65536]; - char line[1024]; - FILE *f; - - f = fopen (name, "r"); - if (f == NULL) - g_error ("Unable to open %s!\n", name); - - len = 0; - while (fgets (line, sizeof (line), f) != NULL) { - strcpy (buff + len, line); - len += strlen (line); - } - - fclose (f); - - return g_strdup (buff); -} -#endif - -int -main (int argc, char **argv) -{ - GnomeProgram *program; - - program = gnome_program_init ("load-pine-addressbook", VERSION, LIBGNOME_MODULE, argc, argv, - GNOME_PROGRAM_STANDARD_PROPERTIES, - NULL); - - g_idle_add (ebook_create, NULL); - - bonobo_main (); - - return 0; -} diff --git a/addressbook/backend/ebook/test-card.c b/addressbook/backend/ebook/test-card.c deleted file mode 100644 index 21806b0313..0000000000 --- a/addressbook/backend/ebook/test-card.c +++ /dev/null @@ -1,193 +0,0 @@ -#include <string.h> -#include "e-card.h" -#include <libgnome/gnome-init.h> - -#define TEST_VCARD \ -"BEGIN:VCARD\r\n" \ -"FN:Nat\r\n" \ -"N:Friedman;Nat;D;Mr.\r\n" \ -"ORG:Ximian, Inc.\r\n" \ -"TITLE:Head Geek\r\n" \ -"ROLE:Programmer/Executive\r\n" \ -"BDAY:1977-08-06\r\n" \ -"TEL;WORK:617 679 1984\r\n" \ -"TEL;CELL:123 456 7890\r\n" \ -"EMAIL;INTERNET:nat@nat.org\r\n" \ -"EMAIL;INTERNET:nat@ximian.com\r\n" \ -"ADR;WORK;POSTAL:P.O. Box 101;;;Any Town;CA;91921-1234;\r\n" \ -"ADR;HOME;POSTAL;INTL:P.O. Box 202;;;Any Town 2;MI;12344-4321;USA\r\n" \ -"END:VCARD\r\n" \ -"\r\n" - -static char * -read_file (char *name) -{ - int len; - char buff[65536]; - char line[1024]; - FILE *f; - - f = fopen (name, "r"); - if (f == NULL) - g_error ("Unable to open %s!\n", name); - - len = 0; - while (fgets (line, sizeof (line), f) != NULL) { - strcpy (buff + len, line); - len += strlen (line); - } - - fclose (f); - - return g_strdup (buff); -} - - - -int -main (int argc, char **argv) -{ - char *cardstr; - ECard *card; - - /* Fields */ - char *fname; - char *org; - char *org_unit; - char *title; - char *role; - char *nickname; - char *fburl; - ECardName *name; - EList *address; - EList *phone; - EList *email; - EList *arbitrary; - EIterator *iterator; - ECardDate *bday; - - gnome_program_init("test-card", "0.0", LIBGNOME_MODULE, argc, argv, NULL); - - cardstr = NULL; - if (argc == 2) - cardstr = read_file (argv [1]); - - if (cardstr == NULL) - cardstr = TEST_VCARD; -#if 0 - { - int i; - for ( i = 0; i < 100000; i++ ) { - card = e_card_new (cardstr); - - g_object_unref (card); - } - } -#endif - card = e_card_new_with_default_charset (cardstr, "ISO-8859-1"); - g_object_get(card, - "full_name", &fname, - "name", &name, - "address", &address, - "phone", &phone, - "email", &email, - "org", &org, - "org_unit", &org_unit, - "title", &title, - "role", &role, - "nickname", &nickname, - "fburl", &fburl, - "arbitrary", &arbitrary, - "birth_date", &bday, - NULL); - if ( fname ) { - printf("Name : %s\n", fname); - g_free(fname); - } - if ( name ) { - printf("Full Name:\n"); - if ( name->prefix ) - printf(" prefix : %s\n", name->prefix); - if ( name->given ) - printf(" given : %s\n", name->given); - if ( name->additional ) - printf(" additional : %s\n", name->additional); - if ( name->family ) - printf(" family : %s\n", name->family); - if ( name->suffix ) - printf(" suffix : %s\n", name->suffix); - } - if ( org ) { - printf("Company : %s\n", org); - } - if ( org_unit ) { - printf("Department : %s\n", org_unit); - } - if ( title ) { - printf("Title : %s\n", title); - } - if ( role ) { - printf("Profession : %s\n", role); - } - if ( nickname ) { - printf("Nickname : %s\n", nickname); - } - if ( fburl ) { - printf("Free Busy URL : %s\n", fburl); - } - if ( arbitrary ) { - iterator = e_list_get_iterator(arbitrary); - for (; e_iterator_is_valid(iterator); e_iterator_next(iterator)) { - ECardArbitrary *arbitrary = (ECardArbitrary *) e_iterator_get(iterator); - printf("Arbitrary : %s, %s\n", arbitrary->key, arbitrary->value); - } - g_object_unref(iterator); - } - if ( bday ) { - printf("BDay : %4d-%02d-%02d\n", bday->year, bday->month, bday->day); - } - if ( email ) { - iterator = e_list_get_iterator(address); - for (; e_iterator_is_valid(iterator); e_iterator_next(iterator)) { - printf("Email : %s\n", (char *) e_iterator_get(iterator)); - } - g_object_unref(iterator); - g_object_unref(email); - } - if ( phone ) { - iterator = e_list_get_iterator(address); - for (; e_iterator_is_valid(iterator); e_iterator_next(iterator)) { - ECardPhone *e_card_phone = (ECardPhone *) e_iterator_get(iterator); - printf("Phone ; %d : %s\n", e_card_phone->flags, e_card_phone->number); - } - g_object_unref(iterator); - g_object_unref(phone); - } - if ( address ) { - iterator = e_list_get_iterator(address); - for (; e_iterator_is_valid(iterator); e_iterator_next(iterator)) { - ECardDeliveryAddress *del_address = (ECardDeliveryAddress *) e_iterator_get(iterator); - printf("Address ; %d:\n", del_address->flags); - if ( del_address->po ) - printf(" Po : %s\n", del_address->po); - if ( del_address->ext ) - printf(" Ext : %s\n", del_address->ext); - if ( del_address->street ) - printf(" Street : %s\n", del_address->street); - if ( del_address->city ) - printf(" City : %s\n", del_address->city); - if ( del_address->region ) - printf(" Region : %s\n", del_address->region); - if ( del_address->code ) - printf(" Code : %s\n", del_address->code); - if ( del_address->country ) - printf(" Country : %s\n", del_address->country); - } - g_object_unref(iterator); - g_object_unref(address); - } - printf("%s", e_card_get_vcard_assume_utf8(card)); - g_object_unref (card); - - return 0; -} diff --git a/addressbook/backend/ebook/test-client-list.c b/addressbook/backend/ebook/test-client-list.c deleted file mode 100644 index 6fa3d6b094..0000000000 --- a/addressbook/backend/ebook/test-client-list.c +++ /dev/null @@ -1,65 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -#include <config.h> - -#include <glib.h> -#include <bonobo/bonobo-i18n.h> -#include <bonobo/bonobo-main.h> -#include <libgnome/gnome-init.h> - -#include "e-book.h" - -static void -init_bonobo (int *argc, char **argv) -{ - if (bonobo_init (argc, argv) == FALSE) - g_error (_("Could not initialize Bonobo")); -} - -static void -get_cursor_cb (EBook *book, EBookStatus status, ECardCursor *cursor, gpointer closure) -{ - long length = e_card_cursor_get_length(cursor); - long i; - - printf ("Length: %d\n", (int) length); - for ( i = 0; i < length; i++ ) { - ECard *card = e_card_cursor_get_nth(cursor, i); - char *vcard = e_card_get_vcard_assume_utf8(card); - printf("[%s]\n", vcard); - g_free(vcard); - g_object_unref(card); - } -} - -static void -book_open_cb (EBook *book, EBookStatus status, gpointer closure) -{ - printf ("Book opened.\n"); - e_book_get_cursor(book, "", get_cursor_cb, NULL); -} - -static gboolean -ebook_create (gpointer data) -{ - EBook *book; - - book = e_book_new (); - - e_book_load_uri (book, "file:/tmp/test.db", book_open_cb, NULL); - - return FALSE; -} - -int -main (int argc, char **argv) -{ - gnome_program_init("test-client-list", "0.0", LIBGNOME_MODULE, argc, argv, NULL); - - init_bonobo (&argc, argv); - - g_idle_add (ebook_create, NULL); - - bonobo_main (); - - return 0; -} diff --git a/addressbook/backend/ebook/test-client.c b/addressbook/backend/ebook/test-client.c deleted file mode 100644 index 63461fb671..0000000000 --- a/addressbook/backend/ebook/test-client.c +++ /dev/null @@ -1,191 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -#include <config.h> -#include <glib.h> -#include <bonobo/bonobo-i18n.h> -#include <bonobo/bonobo-main.h> -#include <libgnome/gnome-init.h> -#include <stdlib.h> -#include <string.h> - -#include "e-book.h" -#include "e-book-util.h" - -#define TEST_VCARD \ -"BEGIN:VCARD\r\n" \ -"FN:Nat\r\n" \ -"N:Friedman;Nat;D;Mr.\r\n" \ -"BDAY:1977-08-06\r\n" \ -"TEL;WORK:617 679 1984\r\n" \ -"TEL;CELL:123 456 7890\r\n" \ -"EMAIL;INTERNET:nat@nat.org\r\n" \ -"EMAIL;INTERNET:nat@ximian.com\r\n" \ -"ADR;WORK;POSTAL:P.O. Box 101;;;Any Town;CA;91921-1234;\r\n" \ -"END:VCARD\r\n" \ -"\r\n" - -static CORBA_Environment ev; -static char *cardstr; - -static void -init_bonobo (int *argc, char **argv) -{ - if (bonobo_init (argc, argv) == FALSE) - g_error (_("Could not initialize Bonobo")); -} - -static void -get_cursor_cb (EBook *book, EBookStatus status, ECardCursor *cursor, gpointer closure) -{ - long length = e_card_cursor_get_length(cursor); - long i; - - /* we just added a card, so the length should be >1 */ - printf ("\n%s: %s(): Number of cards is %ld\n", - __FILE__, G_GNUC_FUNCTION, length); - if (length < 1) - printf ("*** Why isn't this above zero?? ***\n\n"); - - for ( i = 0; i < length; i++ ) { - ECard *card = e_card_cursor_get_nth(cursor, i); - char *vcard = e_card_get_vcard_assume_utf8(card); - printf("Get all cards callback: [%s]\n", vcard); - g_free(vcard); - g_object_unref(card); - } - - g_object_unref (book); - exit(0); -} - -static void -get_card_cb (EBook *book, EBookStatus status, ECard *card, gpointer closure) -{ - char *vcard; - - vcard = e_card_get_vcard_assume_utf8(card); - printf ("Card added: [%s]\n", vcard); - g_free(vcard); - - printf ("Getting cards..\n"); - e_book_get_cursor(book, "(contains \"x-evolution-any-field\" \"\")", get_cursor_cb, NULL); - printf ("Done getting all cards.\n"); -} - -static void -add_card_cb (EBook *book, EBookStatus status, const gchar *id, gpointer closure) -{ - GTimer *timer; - - printf ("Status: %d\n", status); - - printf ("Id: %s\n", id); - - timer = g_timer_new (); - g_timer_start (timer); - e_book_get_card (book, id, get_card_cb, closure); - g_timer_stop (timer); - printf ("%g\n", g_timer_elapsed (timer, NULL)); -} - -static void -get_fields_cb (EBook *book, EBookStatus status, EList *fields, gpointer closure) -{ - if (fields) { - EIterator *iter = e_list_get_iterator (fields); - - printf ("Supported fields:\n"); - - for (; e_iterator_is_valid (iter); e_iterator_next (iter)) { - printf (" %s\n", (char*)e_iterator_get (iter)); - } - - g_object_unref(fields); - } - else { - printf ("No supported fields?\n"); - } - - e_book_add_vcard(book, cardstr, add_card_cb, NULL); -} - - -static void -auth_user_cb (EBook *book, EBookStatus status, gpointer closure) -{ - printf ("user authenticated\n"); - e_book_get_supported_fields (book, get_fields_cb, closure); -} - -static void -book_open_cb (EBook *book, EBookStatus status, gpointer closure) -{ - e_book_authenticate_user (book, "username", "password", "auth_method", auth_user_cb, NULL); -} - -static gboolean -ebook_create (gpointer data) -{ - EBook *book; - - book = e_book_new (); - - if (!book) { - printf ("%s: %s(): Couldn't create EBook, bailing.\n", - __FILE__, - G_GNUC_FUNCTION); - return FALSE; - } - - - e_book_load_default_book (book, book_open_cb, NULL); - - return FALSE; -} - -static char * -read_file (char *name) -{ - int len; - char buff[65536]; - char line[1024]; - FILE *f; - - f = fopen (name, "r"); - if (f == NULL) - g_error ("Unable to open %s!\n", name); - - len = 0; - while (fgets (line, sizeof (line), f) != NULL) { - strcpy (buff + len, line); - len += strlen (line); - } - - fclose (f); - - return g_strdup (buff); -} - - -int -main (int argc, char **argv) -{ - - CORBA_exception_init (&ev); - - gnome_program_init("test-client", "0.0", LIBGNOME_MODULE, argc, argv, NULL); - - init_bonobo (&argc, argv); - - cardstr = NULL; - if (argc == 2) - cardstr = read_file (argv [1]); - - if (cardstr == NULL) - cardstr = TEST_VCARD; - - g_idle_add (ebook_create, NULL); - - bonobo_main (); - - return 0; -} diff --git a/addressbook/backend/ebook/tests/.cvsignore b/addressbook/backend/ebook/tests/.cvsignore deleted file mode 100644 index 282522db03..0000000000 --- a/addressbook/backend/ebook/tests/.cvsignore +++ /dev/null @@ -1,2 +0,0 @@ -Makefile -Makefile.in diff --git a/addressbook/backend/ebook/tests/Makefile.am b/addressbook/backend/ebook/tests/Makefile.am deleted file mode 100644 index f17f979485..0000000000 --- a/addressbook/backend/ebook/tests/Makefile.am +++ /dev/null @@ -1 +0,0 @@ -SUBDIRS=vcard
\ No newline at end of file diff --git a/addressbook/backend/ebook/tests/vcard/.cvsignore b/addressbook/backend/ebook/tests/vcard/.cvsignore deleted file mode 100644 index 41d78c77a2..0000000000 --- a/addressbook/backend/ebook/tests/vcard/.cvsignore +++ /dev/null @@ -1,3 +0,0 @@ -Makefile -Makefile.in -dump-vcard diff --git a/addressbook/backend/ebook/tests/vcard/1.vcf b/addressbook/backend/ebook/tests/vcard/1.vcf deleted file mode 100644 index 308144c5f1..0000000000 --- a/addressbook/backend/ebook/tests/vcard/1.vcf +++ /dev/null @@ -1,12 +0,0 @@ -BEGIN:vCard -VERSION:3.0 -FN:Frank Dawson -ORG:Lotus Development Corporation -ADR;TYPE=WORK,POSTAL,PARCEL:;;6544 Battleford Drive - ;Raleigh;NC;27613-3502;U.S.A. -TEL;TYPE=VOICE,MSG,WORK:+1-919-676-9515 -TEL;TYPE=FAX,WORK:+1-919-676-9564 -EMAIL;TYPE=INTERNET,PREF:Frank_Dawson@Lotus.com -EMAIL;TYPE=INTERNET:fdawson@earthlink.net -URL:http://home.earthlink.net/~fdawson -END:vCard diff --git a/addressbook/backend/ebook/tests/vcard/10.vcf b/addressbook/backend/ebook/tests/vcard/10.vcf deleted file mode 100644 index 4bccbe9ffb..0000000000 --- a/addressbook/backend/ebook/tests/vcard/10.vcf +++ /dev/null @@ -1,12 +0,0 @@ -BEGIN:vCard -vCard.vCard.VERSION:3.0 -vCard.FN:Frank Dawson -vCard.ORG:Lotus Development Corporation -vCard.ADR;TYPE=WORK,POSTAL,PARCEL:;;6544 Battleford Drive - ;Raleigh;NC;27613-3502;U.S.A. -vCard.TEL;TYPE=VOICE,MSG,WORK:+1-919-676-9515 -vCard.TEL;TYPE=FAX,WORK:+1-919-676-9564 -vCard.EMAIL;TYPE=INTERNET,PREF:Frank_Dawson@Lotus.com -vCard.EMAIL;TYPE=INTERNET:fdawson@earthlink.net -vCard.URL:http://home.earthlink.net/~fdawson -END:vCard diff --git a/addressbook/backend/ebook/tests/vcard/2.vcf b/addressbook/backend/ebook/tests/vcard/2.vcf deleted file mode 100644 index bdf14ea1b7..0000000000 --- a/addressbook/backend/ebook/tests/vcard/2.vcf +++ /dev/null @@ -1,10 +0,0 @@ -BEGIN:vCard -VERSION:3.0 -FN:Tim Howes -ORG:Netscape Communications Corp. -ADR;TYPE=WORK:;;501 E. Middlefield Rd.;Mountain View; - CA; 94043;U.S.A. -TEL;TYPE=VOICE,MSG,WORK:+1-415-937-3419 -TEL;TYPE=FAX,WORK:+1-415-528-4164 -EMAIL;TYPE=INTERNET:howes@netscape.com -END:vCard diff --git a/addressbook/backend/ebook/tests/vcard/3.vcf b/addressbook/backend/ebook/tests/vcard/3.vcf deleted file mode 100644 index 3058716959..0000000000 --- a/addressbook/backend/ebook/tests/vcard/3.vcf +++ /dev/null @@ -1,13 +0,0 @@ -BEGIN:VCARD -VERSION:2.1 -X-EVOLUTION-FILE-AS:Friedman, Nat -FN:Nat -N:Friedman;Nat;D;Mr. -ADR;POSTAL;WORK:P.O. Box 101;;;Any Town;CA;91921-1234 -TEL;WORK:617 679 1984 -TEL;CELL:123 456 7890 -EMAIL;INTERNET:nat@nat.org -EMAIL;INTERNET:nat@ximian.com -BDAY:1977-08-06 -UID:pas-id-3E65886900000002 -END:VCARD diff --git a/addressbook/backend/ebook/tests/vcard/4.vcf b/addressbook/backend/ebook/tests/vcard/4.vcf deleted file mode 100644 index 46878f753b..0000000000 --- a/addressbook/backend/ebook/tests/vcard/4.vcf +++ /dev/null @@ -1,11 +0,0 @@ -BEGIN:VCARD -VERSION:2.1 -X-EVOLUTION-FILE-AS:address, canada -FN:canada address -N:address;canada -ADR;WORK:;;92 Main St. N.;Newmarket;ON;L3Y 4A1;Canada -ADR;HOME;PREF:;;92 Main St. N.;Newmarket;ON;L3Y 4A1;Canada -LABEL;QUOTED-PRINTABLE;WORK:92 Main St. N.=0ANewmarket, ON L3Y 4A1=0ACanada -LABEL;QUOTED-PRINTABLE;HOME;PREF:92 Main St. N.=0ANewmarket, ON L3Y 4A1=0ACanada -UID:pas-id-3E84C16E00000001 -END:VCARD diff --git a/addressbook/backend/ebook/tests/vcard/5.vcf b/addressbook/backend/ebook/tests/vcard/5.vcf deleted file mode 100644 index 51bbe207a6..0000000000 --- a/addressbook/backend/ebook/tests/vcard/5.vcf +++ /dev/null @@ -1,32 +0,0 @@ -BEGIN:VCARD -VERSION:2.1 -X-EVOLUTION-FILE-AS;CHARSET=UTF-8;QUOTED-PRINTABLE:=E5=8D=81=E5=9F=8E=E7=9B=AE=E7=AE=A1=E7=90=86=E5=A4=A7=E5=9E=8B=E7=9F=A5=E5= -=BA=A7 -FN;CHARSET=UTF-8;QUOTED-PRINTABLE:=E5=8D=81=E5=9F=8E=E7=9B=AE=E7=AE=A1=E7=90=86=E5=A4=A7=E5=9E=8B=E7=9F=A5=E5= -=BA=A7 -N;CHARSET=UTF-8:;å城目管ç†å¤§åž‹çŸ¥åº§ -ADR;WORK;PREF;QUOTED-PRINTABLE;CHARSET=UTF-8:;=E5=8D=81=E5=9F=8E=E7=9B=AE=E7=AE=A1=E7=90=86=E5=A4=A7=E5=9E=8B=E7=9F=A5=E5= -=BA=A7=0A=E5=8D=81=E5=9F=8E=E7=9B=AE=E7=AE=A1=E7=90=86=E5=A4=A7=E5=9E=8B=E7= -=9F=A5=E5=BA=A7=0A=E5=8D=81=E5=9F=8E=E7=9B=AE=E7=AE=A1=E7=90=86=E5=A4=A7=E5= -=9E=8B=E7=9F=A5=E5=BA=A7;=E5=8D=81=E5=9F=8E=E7=9B=AE=E7=AE=A1=E7=90=86=E5=A4=A7=E5=9E=8B=E7=9F=A5=E5= -=BA=A7 -LABEL;CHARSET=UTF-8;QUOTED-PRINTABLE;WORK;PREF:=E5=8D=81=E5=9F=8E=E7=9B=AE=E7=AE=A1=E7=90=86=E5=A4=A7=E5=9E=8B=E7=9F=A5=E5= -=BA=A7=0A=E5=8D=81=E5=9F=8E=E7=9B=AE=E7=AE=A1=E7=90=86=E5=A4=A7=E5=9E=8B=E7= -=9F=A5=E5=BA=A7=0A=E5=8D=81=E5=9F=8E=E7=9B=AE=E7=AE=A1=E7=90=86=E5=A4=A7=E5= -=9E=8B=E7=9F=A5=E5=BA=A7=0A=E5=8D=81=E5=9F=8E=E7=9B=AE=E7=AE=A1=E7=90=86=E5= -=A4=A7=E5=9E=8B=E7=9F=A5=E5=BA=A7 -TEL;CHARSET=UTF-8;QUOTED-PRINTABLE;WORK;VOICE:=E5=8D=81=E5=9F=8E=E7=9B=AE=E7=AE=A1=E7=90=86=E5=A4=A7=E5=9E=8B=E7=9F=A5=E5= -=BA=A7 -TEL;CHARSET=UTF-8;QUOTED-PRINTABLE;WORK;FAX:=E5=8D=81=E5=9F=8E=E7=9B=AE=E7=AE=A1=E7=90=86=E5=A4=A7=E5=9E=8B=E7=9F=A5=E5= -=BA=A7 -TEL;CHARSET=UTF-8;QUOTED-PRINTABLE;HOME:=E5=8D=81=E5=9F=8E=E7=9B=AE=E7=AE=A1=E7=90=86=E5=A4=A7=E5=9E=8B=E7=9F=A5=E5= -=BA=A7 -TEL;CHARSET=UTF-8;QUOTED-PRINTABLE;CELL:=E5=8D=81=E5=9F=8E=E7=9B=AE=E7=AE=A1=E7=90=86=E5=A4=A7=E5=9E=8B=E7=9F=A5=E5= -=BA=A7 -EMAIL;INTERNET:weird@weird.com -ORG;CHARSET=UTF-8:å城目管ç†å¤§åž‹çŸ¥åº§ -TITLE;CHARSET=UTF-8;QUOTED-PRINTABLE:=E5=8D=81=E5=9F=8E=E7=9B=AE=E7=AE=A1=E7=90=86=E5=A4=A7=E5=9E=8B=E7=9F=A5=E5= -=BA=A7 -UID:pas-id-3E52FE2E00000000 -END:VCARD - diff --git a/addressbook/backend/ebook/tests/vcard/6.vcf b/addressbook/backend/ebook/tests/vcard/6.vcf deleted file mode 100644 index e5e8310eb3..0000000000 --- a/addressbook/backend/ebook/tests/vcard/6.vcf +++ /dev/null @@ -1,12 +0,0 @@ -BEGIN:vCard -VERSION:3.0 -FN:Frank Dawson -ORG:Lotus Development Corporation -ADR;TYPE=WORK,:;;6544 Battleford Drive - ;Raleigh;NC;27613-3502;U.S.A. -TEL;TYPE=VOICE;MSG,WORK:+1-919-676-9515 -TEL;FAX,WORK:+1-919-676-9564 -EMAIL;TYPE=INTERNET,PREF:Frank_Dawson@Lotus.com -EMAIL;TYPE=INTERNET:fdawson@earthlink.net -URL:http://home.earthlink.net/~fdawson -END:vCard diff --git a/addressbook/backend/ebook/tests/vcard/7.vcf b/addressbook/backend/ebook/tests/vcard/7.vcf deleted file mode 100644 index fb88173032..0000000000 --- a/addressbook/backend/ebook/tests/vcard/7.vcf +++ /dev/null @@ -1,11 +0,0 @@ -VERSION:3.0 -FN:Frank Dawson -ORG:Lotus Development Corporation -ADR;TYPE=WORK,POSTAL,PARCEL:;;6544 Battleford Drive - ;Raleigh;NC;27613-3502;U.S.A. -TEL;TYPE=VOICE,MSG,WORK:+1-919-676-9515 -TEL;TYPE=FAX,WORK:+1-919-676-9564 -EMAIL;TYPE=INTERNET,PREF:Frank_Dawson@Lotus.com -EMAIL;TYPE=INTERNET:fdawson@earthlink.net -URL:http://home.earthlink.net/~fdawson -END:vCard diff --git a/addressbook/backend/ebook/tests/vcard/8.vcf b/addressbook/backend/ebook/tests/vcard/8.vcf deleted file mode 100644 index 172d1d2c68..0000000000 --- a/addressbook/backend/ebook/tests/vcard/8.vcf +++ /dev/null @@ -1,11 +0,0 @@ -BEGIN:vCard -VERSION:3.0 -FN:Frank Dawson -ORG:Lotus Development Corporation -ADR;TYPE=WORK,POSTAL,PARCEL:;;6544 Battleford Drive - ;Raleigh;NC;27613-3502;U.S.A. -TEL;TYPE=VOICE,MSG,WORK:+1-919-676-9515 -TEL;TYPE=FAX,WORK:+1-919-676-9564 -EMAIL;TYPE=INTERNET,PREF:Frank_Dawson@Lotus.com -EMAIL;TYPE=INTERNET:fdawson@earthlink.net -URL:http://home.earthlink.net/~fdawson diff --git a/addressbook/backend/ebook/tests/vcard/9.vcf b/addressbook/backend/ebook/tests/vcard/9.vcf deleted file mode 100644 index 7043ab8c13..0000000000 --- a/addressbook/backend/ebook/tests/vcard/9.vcf +++ /dev/null @@ -1,9 +0,0 @@ -BEGIN:vCard -VERSION:3.0 -FN:Frank Dawson -ORG:Lotus Development Corporation -ADR;TYPE=WORK,POSTAL,PARCEL:;;6544 Battleford Drive - ;Raleigh;NC;27613-3502;U.S.A. -TEL;TYPE=VOICE,MSG,WORK:+1-919-676-9515 -TEL;TYPE=FAX,WORK:+1-919-676-9564 -E diff --git a/addressbook/backend/ebook/tests/vcard/Makefile.am b/addressbook/backend/ebook/tests/vcard/Makefile.am deleted file mode 100644 index ae16780095..0000000000 --- a/addressbook/backend/ebook/tests/vcard/Makefile.am +++ /dev/null @@ -1,6 +0,0 @@ - -CFLAGS=-I$(srcdir)/../.. `pkg-config --cflags gobject-2.0` - -noinst_PROGRAMS=dump-vcard - -dump_vcard_LDFLAGS=$(top_builddir)/addressbook/backend/ebook/libevcard.la `pkg-config --libs gobject-2.0` diff --git a/addressbook/backend/ebook/tests/vcard/README b/addressbook/backend/ebook/tests/vcard/README deleted file mode 100644 index 06ae719c5e..0000000000 --- a/addressbook/backend/ebook/tests/vcard/README +++ /dev/null @@ -1,41 +0,0 @@ -This is the list of tests I've been using while writing e-vcard.c. -The parser is all handcrafted, and it's not a validating parser by any -stretch of the imagination. It tries very hard to deal with any -possible input (it'll even parse rfc822 mail headers and spit out -vCard-ish results.) - -Test : Description ----------------------- - -1.vcf : Frank Dawson's vCard from RFC 2426 (missing the required N - attribute.) - -2.vcf : Tim Howes's vCard from from RFC 2426 (missing the required N - attribute.) - -3.vcf : Nat's old vCard. - -4.vcf : A vCard containing a canadian address (quoted-printable - encoded attribute values.) - -5.vcf : A vCard containing utf8 characters quoted-printable encoded. - -6.vcf : A vCard with several errors in attribute parameters: - line 5: an missing parameter value (a , with nothing after it). - line 6: a missing parameter name when using multiple - values. (this may not be in violation of the rfc.) - line 7: a missing parameter name when using multiple - values. (this may not be in violation of the rfc.) - -7.vcf : A vCard missing its begin:vcard attribute, as well as missing - the required N attribute. - -8.vcf : A vCard missing its end: vcard attribute, as well as missing - the required N attribute. - -9.vcf : A vCard that ends (\0) in the middle of an attribute - name/group. - -10.vcf : A vCard with an attribute with more than 1 group specified. - ----------------------- diff --git a/addressbook/backend/ebook/tests/vcard/dump-vcard.c b/addressbook/backend/ebook/tests/vcard/dump-vcard.c deleted file mode 100644 index 52dbf8a957..0000000000 --- a/addressbook/backend/ebook/tests/vcard/dump-vcard.c +++ /dev/null @@ -1,32 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -#include <stdio.h> -#include "e-vcard.h" - -FILE *fp; - -int -main(int argc, char **argv) -{ - EVCard *vcard; - GString *str = g_string_new (""); - - if (argc < 2) - return 0; - - g_type_init_with_debug_flags (G_TYPE_DEBUG_OBJECTS); - - fp = fopen (argv[1], "r"); - - while (!feof (fp)) { - char buf[1024]; - if (fgets (buf, sizeof(buf), fp)) - str = g_string_append (str, buf); - } - - vcard = e_vcard_new_from_string (str->str); - - e_vcard_dump_structure (vcard); - - return 0; -} diff --git a/addressbook/backend/idl/.cvsignore b/addressbook/backend/idl/.cvsignore deleted file mode 100644 index 09980ae6ba..0000000000 --- a/addressbook/backend/idl/.cvsignore +++ /dev/null @@ -1,6 +0,0 @@ -.deps -.libs -Makefile -Makefile.in -*.lo -*.la diff --git a/addressbook/backend/idl/Makefile.am b/addressbook/backend/idl/Makefile.am deleted file mode 100644 index e9f011975b..0000000000 --- a/addressbook/backend/idl/Makefile.am +++ /dev/null @@ -1,4 +0,0 @@ -idl_DATA = \ - addressbook.idl - -EXTRA_DIST = $(idl_DATA) diff --git a/addressbook/backend/idl/addressbook.idl b/addressbook/backend/idl/addressbook.idl deleted file mode 100644 index c9ce728a15..0000000000 --- a/addressbook/backend/idl/addressbook.idl +++ /dev/null @@ -1,214 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * - * Author: - * Nat Friedman (nat@ximian.com) - * - * Copyright 2000, Ximian, Inc. - */ - -#include <Bonobo.idl> - -module GNOME { -module Evolution { -module Addressbook { - typedef string CardId; - typedef string VCard; - typedef sequence<VCard> VCardList; - typedef sequence<CardId> CardIdList; - typedef sequence<string> stringlist; - - interface CardCursor : Bonobo::Unknown { - long count (); - string getNth (in long n); - }; - - /* - * A book view is a live view of a book. It's either a view - * of all the cards in the book or a view of a query. When - * created, it will get a series of signal_card_added calls - * for all objects in the initial set. After that, it will - * get added, removed, or changed signals whenever the book - * changes (if it affects the set of viewed cards.) - */ - interface BookViewListener : Bonobo::Unknown { - enum CallStatus { - Success, - /* These are still successful searches, but - the result set was truncated */ - SearchSizeLimitExceeded, - SearchTimeLimitExceeded, - - /* These are failures */ - InvalidQuery, - QueryRefused, - OtherError - }; - void notifyCardAdded (in VCardList cards); - void notifyCardsRemoved (in CardIdList ids); - void notifyCardChanged (in VCardList cards); - void notifySequenceComplete (in CallStatus status); - void notifyStatusMessage (in string message); - }; - - interface BookView : Bonobo::Unknown { - }; - - interface Book : Bonobo::Unknown { - - /* - * Fetching cards in the addresbook. - */ - void getVCard (in CardId id); - - void authenticateUser (in string user, in string passwd, - in string authMethod); - - /* - * Adding and deleting cards in the book. - */ - void addCard (in VCard vcard); - void removeCards (in CardIdList Id); - - /* - * Modifying cards in the addressbook. - */ - void modifyCard (in VCard vcard); - - /* - * This function returns a cursor to the book - * listener. This is for people who want a snapshot - * of the addressbook. - */ - void getCursor (in string query); - - /* - * These two functions return a book view to the book - * listener. This is for people who want a live view - * of the addressbook. - */ - void getBookView (in BookViewListener listener, in string query); - - void getChanges (in BookViewListener listener, in string change_id); - - /* - * This function returns a book view that is identical - * to a normal book view, except in one way - The only - * values reflected in the cards that are transfered - * back are: File As, family name, given name, email - * addresses, and nickname. It is intended for use in - * completion searches. - */ - void getCompletionView (in BookViewListener listener, in string query); - - void checkConnection (); - - void getSupportedFields (); - - /* - * This function returns a list of strings - * representing the auth methods (e.g. SASL mechs) - * that a backend/server supports. - * - * Some examples are: - * - * "ldap/simple-email|By email Address" - * "sasl/CRAM-MD5|CRAM-MD5(SASL)" - * - * The format should be: - * - * <class>/<type>|<i18nized string> - * - * "i18nized string" is shown in the UI, and should be - * a user friendly representation of the auth method. - * - * in the case of SASL auth mechs, the text trailing - * the '/' should be the proper name of the mechanism, - * as it will be passed unchanged to the backend auth - * function (eg. ldap_sasl_bind) - */ - void getSupportedAuthMethods (); - - string getStaticCapabilities (); - - string getName (); - }; - - interface BookListener : Bonobo::Unknown { - - enum CallStatus { - Success, - RepositoryOffline, - PermissionDenied, - CardNotFound, - CardIdAlreadyExists, - ProtocolNotSupported, - AuthenticationFailed, - AuthenticationRequired, - UnsupportedField, - UnsupportedAuthenticationMethod, - TLSNotAvailable, - NoSuchBook, - - OtherError - }; - - void notifyCardCreated (in CallStatus status, in CardId Id); - - void notifyCardsRemoved (in CallStatus status); - - void notifyCardModified (in CallStatus status); - - void notifyOpenBookProgress (in string status_message, in short percent); - - void notifyBookOpened (in CallStatus status, in Book book); - - void notifyCardRequested (in CallStatus status, in VCard card); - - void notifyCursorRequested (in CallStatus status, in CardCursor cursor); - - void notifyViewRequested (in CallStatus status, in BookView view); - - void notifyChangesRequested (in CallStatus status, in BookView view); - - void notifyAuthenticationResult (in CallStatus status); - - void notifySupportedFields (in CallStatus status, in stringlist fields); - - void notifySupportedAuthMethods (in CallStatus status, in stringlist fields); - - /** - * notifyConnectionStatus: - * - * Used to report changes in the connection to the - * contact repository. This is often a response to a - * call to check_connection() on the Book, but wombat - * is free to report the connection status without - * being asked. - */ - void notifyConnectionStatus (in boolean connected); - - /** - * notifyWritable: - * - * Used to report whether or not a backend can write - * to a given addressbook. All books default to - * read-only, so unless you receive a notification - * saying otherwise, treat the book as read-only. It - * is presumed that this notification will be sent - * early (just after a connection is opened, usually), - * but it may also be sent later, if/when the backend - * notices a change. - */ - void notifyWritable (in boolean writable); - }; - - interface BookFactory : Bonobo::Unknown { - exception ProtocolNotSupported {}; - - void openBook (in string uri, in BookListener listener) - raises (ProtocolNotSupported); - }; -}; -}; -}; diff --git a/addressbook/backend/pas/.cvsignore b/addressbook/backend/pas/.cvsignore deleted file mode 100644 index 6eb58802ec..0000000000 --- a/addressbook/backend/pas/.cvsignore +++ /dev/null @@ -1,13 +0,0 @@ -.deps -.libs -.pure -Makefile -Makefile.in -addressbook-stubs.c -addressbook-skels.c -addressbook-common.c -addressbook.h -*.lo -*.la -pas-marshal.c -pas-marshal.h
\ No newline at end of file diff --git a/addressbook/backend/pas/Makefile.am b/addressbook/backend/pas/Makefile.am deleted file mode 100644 index 92115eae19..0000000000 --- a/addressbook/backend/pas/Makefile.am +++ /dev/null @@ -1,101 +0,0 @@ -CORBA_SOURCE_H = addressbook.h - -CORBA_SOURCE_C = \ - addressbook-common.c \ - addressbook-stubs.c \ - addressbook-skels.c - -CORBA_SOURCE = $(CORBA_SOURCE_H) $(CORBA_SOURCE_C) - -idls = \ - $(srcdir)/../idl/addressbook.idl - -$(CORBA_SOURCE_H): $(idls) - $(ORBIT_IDL) $(IDL_INCLUDES) -I $(srcdir) $(srcdir)/../idl/addressbook.idl - -$(CORBA_SOURCE_C): $(CORBA_SOURCE_H) - - -INCLUDES = \ - $(DB3_CFLAGS) \ - $(LDAP_CFLAGS) \ - -DG_LOG_DOMAIN=\"wombat-pas\" \ - -I$(top_srcdir) \ - -I$(top_srcdir)/addressbook/backend \ - -I$(top_builddir)/addressbook/backend \ - -DG_DISABLE_DEPRECATED \ - -DLIBGNOME_DISABLE_DEPRECATED \ - $(EVOLUTION_ADDRESSBOOK_CFLAGS) - -LDAP_SCHEMA = \ - evolutionperson.schema - -LDAP_BACKEND_FILES = \ - pas-backend-ldap.c \ - pas-backend-ldap.h - -if ENABLE_LDAP -LDAP_BACKEND = libpasldap.a -endif - -ldapschemadir = $(privdatadir) -ldapschema_DATA= $(LDAP_SCHEMA) - -privlib_LIBRARIES = libpas.a -noinst_LIBRARIES = libpasfile.a $(LDAP_BACKEND) - -pasincludedir = $(privincludedir)/pas - -pasinclude_HEADERS = \ - $(CORBA_SOURCE_H) \ - pas-book-factory.h \ - pas-book-view.h \ - pas-book.h \ - pas-backend-card-sexp.h \ - pas-backend.h \ - pas-backend-summary.h \ - pas-card-cursor.h - -libpas_a_SOURCES = \ - $(pasinclude_HEADERS) \ - $(CORBA_SOURCE_C) \ - pas-book-factory.c \ - pas-book-view.c \ - pas-book.c \ - pas-backend-card-sexp.c \ - pas-backend-file.c \ - pas-backend.c \ - pas-backend-summary.c \ - pas-card-cursor.c \ - pas-marshal.c - -libpasfile_a_SOURCES = \ - pas-backend-file.c \ - pas-backend-file.h - -if ENABLE_LDAP -libpasldap_a_SOURCES = \ - $(LDAP_BACKEND_FILES) -endif - -# GLib marshalling cruft - -pas-marshal.h: pas-marshal.list - ( @GLIB_GENMARSHAL@ --prefix=pas_marshal pas-marshal.list --header > pas-marshal.tmp \ - && mv pas-marshal.tmp pas-marshal.h ) \ - || ( rm -f pas-marshal.tmp && exit 1 ) - -pas-marshal.c: pas-marshal.h - ( @GLIB_GENMARSHAL@ --prefix=pas_marshal pas-marshal.list --body > pas-marshal.tmp \ - && mv pas-marshal.tmp pas-marshal.c ) \ - || ( rm -f pas-marshal.tmp && exit 1 ) - -MARSHAL_GENERATED = pas-marshal.c pas-marshal.h - -BUILT_SOURCES = $(CORBA_SOURCE) $(MARSHAL_GENERATED) -CLEANFILES = $(BUILT_SOURCES) - -dist-hook: - cd $(distdir); rm -f $(BUILT_SOURCES) - -EXTRA_DIST = $(LDAP_BACKEND_FILES) $(LDAP_SCHEMA) pas-marshal.list diff --git a/addressbook/backend/pas/TODO b/addressbook/backend/pas/TODO deleted file mode 100644 index 0c77c1b200..0000000000 --- a/addressbook/backend/pas/TODO +++ /dev/null @@ -1,2 +0,0 @@ -* Implement pas_book_factory_activate -* Authentication
\ No newline at end of file diff --git a/addressbook/backend/pas/evolutionperson.schema b/addressbook/backend/pas/evolutionperson.schema deleted file mode 100644 index cc32a96262..0000000000 --- a/addressbook/backend/pas/evolutionperson.schema +++ /dev/null @@ -1,212 +0,0 @@ -# -# Depends upon -# Definition of an X.500 Attribute Type and an Object Class to Hold -# Uniform Resource Identifiers (URIs) [RFC2079] -# (core.schema) -# -# A Summary of the X.500(96) User Schema for use with LDAPv3 [RFC2256] -# (core.schema) -# -# The COSINE and Internet X.500 Schema [RFC1274] (cosine.schema) -# -# The Internet Organizational Person Schema (inetorgperson) -# -# OIDs are broken up into the following: -# 1.3.6.1.4.1.8506.1.? -# .1 Syntaxes -# .2 Attributes -# .3 Objectclasses - -# primaryPhone -attributetype ( 1.3.6.1.4.1.8506.1.2.1 - NAME 'primaryPhone' - DESC 'preferred phone number used to contact a person' - EQUALITY caseIgnoreMatch - SUBSTR caseIgnoreSubstringsMatch - SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 - SINGLE-VALUE ) - -# carPhone -attributetype ( 1.3.6.1.4.1.8506.1.2.2 - NAME 'carPhone' - DESC 'car phone telephone number of the person' - EQUALITY telephoneNumberMatch - SUBSTR telephoneNumberSubstringsMatch - SYNTAX 1.3.6.1.4.1.1466.115.121.1.50 - SINGLE-VALUE ) - -attributetype ( 1.3.6.1.4.1.8506.1.2.3 - NAME ( 'homeFacsimileTelephoneNumber' 'homeFax' ) - SYNTAX 1.3.6.1.4.1.1466.115.121.1.22 ) - -attributetype ( 1.3.6.1.4.1.8506.1.2.4 - NAME 'otherPhone' - EQUALITY telephoneNumberMatch - SUBSTR telephoneNumberSubstringsMatch - SYNTAX 1.3.6.1.4.1.1466.115.121.1.50 ) - -attributetype ( 1.3.6.1.4.1.8506.1.2.5 - NAME 'businessRole' - EQUALITY caseIgnoreMatch - SUBSTR caseIgnoreSubstringsMatch - SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 ) - -attributetype ( 1.3.6.1.4.1.8506.1.2.6 - NAME 'managerName' - SUP name ) - -attributetype ( 1.3.6.1.4.1.8506.1.2.7 - NAME 'assistantName' - SUP name ) - -# spouseName -# single valued (/me smirks) -attributetype ( 1.3.6.1.4.1.8506.1.2.8 - NAME 'spouseName' - SUP name - SINGLE-VALUE ) - -attributetype ( 1.3.6.1.4.1.8506.1.2.9 - NAME 'otherPostalAddress' - EQUALITY caseIgnoreListMatch - SUBSTR caseIgnoreListSubstringsMatch - SYNTAX 1.3.6.1.4.1.1466.115.121.1.41 ) - -attributetype ( 1.3.6.1.4.1.8506.1.2.10 - NAME ( 'mailer' 'mua' ) - EQUALITY caseIgnoreMatch - SUBSTR caseIgnoreSubstringsMatch - SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{32} ) - -attributetype ( 1.3.6.1.4.1.8506.1.2.11 - NAME ( 'birthDate' 'dob' ) - EQUALITY caseIgnoreMatch - SUBSTR caseIgnoreSubstringsMatch - SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{128} ) - -attributetype ( 1.3.6.1.4.1.8506.1.2.12 - NAME 'anniversary' - EQUALITY caseIgnoreMatch - SUBSTR caseIgnoreSubstringsMatch - SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{128} ) - -attributetype ( 1.3.6.1.4.1.8506.1.2.13 - NAME 'note' - EQUALITY caseIgnoreMatch - SUBSTR caseIgnoreSubstringsMatch - SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{1024} ) - -attributetype ( 1.3.6.1.4.1.8506.1.2.14 - NAME 'evolutionArbitrary' - EQUALITY caseIgnoreMatch - SUBSTR caseIgnoreSubstringsMatch - SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{4096} ) - ) - -attributetype ( 1.3.6.1.4.1.8506.1.2.15 - NAME 'fileAs' - SUP name ) - -attributetype ( 1.3.6.1.4.1.8506.1.2.16 - NAME 'assistantPhone' - EQUALITY telephoneNumberMatch - SUBSTR telephoneNumberSubstringsMatch - SYNTAX 1.3.6.1.4.1.1466.115.121.1.50 ) - -attributetype ( 1.3.6.1.4.1.8506.1.2.17 - NAME 'companyPhone' - EQUALITY telephoneNumberMatch - SUBSTR telephoneNumberSubstringsMatch - SYNTAX 1.3.6.1.4.1.1466.115.121.1.50 ) - -attributetype ( 1.3.6.1.4.1.8506.1.2.18 - NAME 'callbackPhone' - EQUALITY telephoneNumberMatch - SUBSTR telephoneNumberSubstringsMatch - SYNTAX 1.3.6.1.4.1.1466.115.121.1.50 ) - -attributetype ( 1.3.6.1.4.1.8506.1.2.19 - NAME ( 'otherFacsimileTelephoneNumber' 'otherFax' ) - SYNTAX 1.3.6.1.4.1.1466.115.121.1.22 ) - -attributetype ( 1.3.6.1.4.1.8506.1.2.20 - NAME 'radio' - EQUALITY telephoneNumberMatch - SUBSTR telephoneNumberSubstringsMatch - SYNTAX 1.3.6.1.4.1.1466.115.121.1.50 ) - -attributetype ( 1.3.6.1.4.1.8506.1.2.21 - NAME 'telex' - EQUALITY telephoneNumberMatch - SUBSTR telephoneNumberSubstringsMatch - SYNTAX 1.3.6.1.4.1.1466.115.121.1.50 ) - -attributetype ( 1.3.6.1.4.1.8506.1.2.22 - NAME 'tty' - EQUALITY telephoneNumberMatch - SUBSTR telephoneNumberSubstringsMatch - SYNTAX 1.3.6.1.4.1.1466.115.121.1.50 ) - -# deprecated - use the multivalued category -attributetype ( 1.3.6.1.4.1.8506.1.2.23 - NAME 'categories' - EQUALITY caseIgnoreMatch - SUBSTR caseIgnoreSubstringsMatch - SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{4096} ) - -attributetype ( 1.3.6.1.4.1.8506.1.2.24 - NAME 'contact' - EQUALITY distinguishedNameMatch - SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 ) - -attributetype ( 1.3.6.1.4.1.8506.1.2.25 - NAME 'listName' - SUP name - SINGLE-VALUE ) - -# deprecated - use calEntry and its attributes from RFC 2739 -attributetype ( 1.3.6.1.4.1.8506.1.2.26 - NAME 'calendarURI' - EQUALITY caseExactIA5Match - SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 - SINGLE-VALUE ) - -# deprecated - use calEntry and its attributes from RFC 2739 -attributetype ( 1.3.6.1.4.1.8506.1.2.27 - NAME 'freeBusyURI' - EQUALITY caseExactIA5Match - SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 - SINGLE-VALUE ) - -attributetype ( 1.3.6.1.4.1.8506.1.2.28 - NAME 'category' - EQUALITY caseIgnoreMatch - SUBSTR caseIgnoreSubstringsMatch - SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{4096} ) - - -# evolutionPerson -objectclass ( 1.3.6.1.4.1.8506.1.3.1 - NAME 'evolutionPerson' - DESC 'Objectclass geared to Evolution Usage' - SUP inetOrgPerson - STRUCTURAL - MAY ( - fileAs $ primaryPhone $ carPhone $ homeFacsimileTelephoneNumber $ - otherPhone $ businessRole $ managerName $ assistantName $ assistantPhone $ - otherPostalAddress $ mailer $ birthDate $ anniversary $ spouseName $ - note $ companyPhone $ callbackPhone $ otherFacsimileTelephoneNumber $ - radio $ telex $ tty $ categories $ category $ calendarURI $ freeBusyURI ) - ) - -# evolutionPersonList -objectclass ( 1.3.6.1.4.1.8506.1.3.2 - NAME 'evolutionPersonList' - DESC 'Objectclass geared to Evolution Contact Lists' - SUP top - STRUCTURAL - MUST ( - listName ) - MAY ( - mail $ contact ) - ) diff --git a/addressbook/backend/pas/pas-backend-card-sexp.c b/addressbook/backend/pas/pas-backend-card-sexp.c deleted file mode 100644 index e7b5d8a87d..0000000000 --- a/addressbook/backend/pas/pas-backend-card-sexp.c +++ /dev/null @@ -1,489 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * pas-backend-card-sexp.c - * Copyright 1999, 2000, 2001, Ximian, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License, version 2, as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - * 02111-1307, USA. - */ - -#include "pas-backend-card-sexp.h" - -#include <string.h> -#include <e-util/e-sexp.h> -#include <ebook/e-card-simple.h> -#include <gal/widgets/e-unicode.h> - -static GObjectClass *parent_class; - -typedef struct _SearchContext SearchContext; - -struct _PASBackendCardSExpPrivate { - ESExp *search_sexp; - SearchContext *search_context; -}; - -struct _SearchContext { - ECardSimple *card; -}; - -static gboolean -compare_email (ECardSimple *card, const char *str, - char *(*compare)(const char*, const char*)) -{ - int i; - - for (i = E_CARD_SIMPLE_EMAIL_ID_EMAIL; i < E_CARD_SIMPLE_EMAIL_ID_LAST; i ++) { - const char *email = e_card_simple_get_email (card, i); - - if (email && compare(email, str)) - return TRUE; - } - - return FALSE; -} - -static gboolean -compare_phone (ECardSimple *card, const char *str, - char *(*compare)(const char*, const char*)) -{ - int i; - - for (i = E_CARD_SIMPLE_PHONE_ID_ASSISTANT; i < E_CARD_SIMPLE_PHONE_ID_LAST; i ++) { - const ECardPhone *phone = e_card_simple_get_phone (card, i); - - if (phone && compare(phone->number, str)) - return TRUE; - } - - return FALSE; -} - -static gboolean -compare_name (ECardSimple *card, const char *str, - char *(*compare)(const char*, const char*)) -{ - const char *name; - - name = e_card_simple_get_const (card, E_CARD_SIMPLE_FIELD_FULL_NAME); - if (name && compare (name, str)) - return TRUE; - - name = e_card_simple_get_const (card, E_CARD_SIMPLE_FIELD_FAMILY_NAME); - if (name && compare (name, str)) - return TRUE; - - return FALSE; -} - -static gboolean -compare_address (ECardSimple *card, const char *str, - char *(*compare)(const char*, const char*)) -{ - g_warning("address searching not implemented\n"); - return FALSE; -} - -static gboolean -compare_category (ECardSimple *card, const char *str, - char *(*compare)(const char*, const char*)) -{ - EList *categories; - EIterator *iterator; - ECard *ecard; - gboolean ret_val = FALSE; - - g_object_get (card, - "card", &ecard, - NULL); - g_object_get (ecard, - "category_list", &categories, - NULL); - - for (iterator = e_list_get_iterator(categories); e_iterator_is_valid (iterator); e_iterator_next (iterator)) { - const char *category = e_iterator_get (iterator); - - if (compare(category, str)) { - ret_val = TRUE; - break; - } - } - - g_object_unref (iterator); - e_card_free_empty_lists (ecard); - g_object_unref (categories); - g_object_unref (ecard); - return ret_val; -} - -static gboolean -compare_arbitrary (ECardSimple *card, const char *str, - char *(*compare)(const char*, const char*)) -{ - EList *list; - EIterator *iterator; - ECard *ecard; - gboolean ret_val = FALSE; - - g_object_get (card, - "card", &ecard, - NULL); - g_object_get (ecard, - "arbitrary", &list, - NULL); - - for (iterator = e_list_get_iterator(list); e_iterator_is_valid (iterator); e_iterator_next (iterator)) { - const ECardArbitrary *arbitrary = e_iterator_get (iterator); - - if (compare(arbitrary->key, str)) { - ret_val = TRUE; - break; - } - } - - g_object_unref (iterator); - e_card_free_empty_lists (ecard); - g_object_unref (list); - g_object_unref (ecard); - return ret_val; -} - -static struct prop_info { - ECardSimpleField field_id; - const char *query_prop; - const char *ecard_prop; -#define PROP_TYPE_NORMAL 0x01 -#define PROP_TYPE_LIST 0x02 -#define PROP_TYPE_LISTITEM 0x03 -#define PROP_TYPE_ID 0x04 - int prop_type; - gboolean (*list_compare)(ECardSimple *ecard, const char *str, - char *(*compare)(const char*, const char*)); - -} prop_info_table[] = { -#define NORMAL_PROP(f,q,e) {f, q, e, PROP_TYPE_NORMAL, NULL} -#define ID_PROP {0, "id", NULL, PROP_TYPE_ID, NULL} -#define LIST_PROP(q,e,c) {0, q, e, PROP_TYPE_LIST, c} - - /* query prop, ecard prop, type, list compare function */ - NORMAL_PROP ( E_CARD_SIMPLE_FIELD_FILE_AS, "file_as", "file_as" ), - LIST_PROP ( "full_name", "full_name", compare_name), /* not really a list, but we need to compare both full and surname */ - NORMAL_PROP ( E_CARD_SIMPLE_FIELD_URL, "url", "url" ), - NORMAL_PROP ( E_CARD_SIMPLE_FIELD_MAILER, "mailer", "mailer"), - NORMAL_PROP ( E_CARD_SIMPLE_FIELD_ORG, "org", "org"), - NORMAL_PROP ( E_CARD_SIMPLE_FIELD_ORG_UNIT, "org_unit", "org_unit"), - NORMAL_PROP ( E_CARD_SIMPLE_FIELD_OFFICE, "office", "office"), - NORMAL_PROP ( E_CARD_SIMPLE_FIELD_TITLE, "title", "title"), - NORMAL_PROP ( E_CARD_SIMPLE_FIELD_ROLE, "role", "role"), - NORMAL_PROP ( E_CARD_SIMPLE_FIELD_MANAGER, "manager", "manager"), - NORMAL_PROP ( E_CARD_SIMPLE_FIELD_ASSISTANT, "assistant", "assistant"), - NORMAL_PROP ( E_CARD_SIMPLE_FIELD_NICKNAME, "nickname", "nickname"), - NORMAL_PROP ( E_CARD_SIMPLE_FIELD_SPOUSE, "spouse", "spouse" ), - NORMAL_PROP ( E_CARD_SIMPLE_FIELD_NOTE, "note", "note"), - ID_PROP, - LIST_PROP ( "email", "email", compare_email ), - LIST_PROP ( "phone", "phone", compare_phone ), - LIST_PROP ( "address", "address", compare_address ), - LIST_PROP ( "category", "category", compare_category ), - LIST_PROP ( "arbitrary", "arbitrary", compare_arbitrary ) -}; -static int num_prop_infos = sizeof(prop_info_table) / sizeof(prop_info_table[0]); - -static ESExpResult * -entry_compare(SearchContext *ctx, struct _ESExp *f, - int argc, struct _ESExpResult **argv, - char *(*compare)(const char*, const char*)) -{ - ESExpResult *r; - int truth = FALSE; - - if (argc == 2 - && argv[0]->type == ESEXP_RES_STRING - && argv[1]->type == ESEXP_RES_STRING) { - char *propname; - struct prop_info *info = NULL; - int i; - gboolean any_field; - - propname = argv[0]->value.string; - - any_field = !strcmp(propname, "x-evolution-any-field"); - for (i = 0; i < num_prop_infos; i ++) { - if (any_field - || !strcmp (prop_info_table[i].query_prop, propname)) { - info = &prop_info_table[i]; - - if (info->prop_type == PROP_TYPE_NORMAL) { - char *prop = NULL; - /* searches where the query's property - maps directly to an ecard property */ - - prop = e_card_simple_get (ctx->card, info->field_id); - - if (prop && compare(prop, argv[1]->value.string)) { - truth = TRUE; - } - if ((!prop) && compare("", argv[1]->value.string)) { - truth = TRUE; - } - g_free (prop); - } else if (info->prop_type == PROP_TYPE_LIST) { - /* the special searches that match any of the list elements */ - truth = info->list_compare (ctx->card, argv[1]->value.string, compare); - } else if (info->prop_type == PROP_TYPE_ID) { - const char *prop = NULL; - /* searches where the query's property - maps directly to an ecard property */ - - prop = e_card_get_id (ctx->card->card); - - if (prop && compare(prop, argv[1]->value.string)) { - truth = TRUE; - } - if ((!prop) && compare("", argv[1]->value.string)) { - truth = TRUE; - } - } - - /* if we're looking at all fields and find a match, - or if we're just looking at this one field, - break. */ - if ((any_field && truth) - || !any_field) - break; - } - } - - } - r = e_sexp_result_new(f, ESEXP_RES_BOOL); - r->value.bool = truth; - - return r; -} - -static ESExpResult * -func_contains(struct _ESExp *f, int argc, struct _ESExpResult **argv, void *data) -{ - SearchContext *ctx = data; - - return entry_compare (ctx, f, argc, argv, (char *(*)(const char*, const char*)) e_utf8_strstrcase); -} - -static char * -is_helper (const char *s1, const char *s2) -{ - if (!strcasecmp(s1, s2)) - return (char*)s1; - else - return NULL; -} - -static ESExpResult * -func_is(struct _ESExp *f, int argc, struct _ESExpResult **argv, void *data) -{ - SearchContext *ctx = data; - - return entry_compare (ctx, f, argc, argv, is_helper); -} - -static char * -endswith_helper (const char *s1, const char *s2) -{ - char *p; - if ((p = (char*)e_utf8_strstrcase(s1, s2)) - && (strlen(p) == strlen(s2))) - return p; - else - return NULL; -} - -static ESExpResult * -func_endswith(struct _ESExp *f, int argc, struct _ESExpResult **argv, void *data) -{ - SearchContext *ctx = data; - - return entry_compare (ctx, f, argc, argv, endswith_helper); -} - -static char * -beginswith_helper (const char *s1, const char *s2) -{ - char *p; - if ((p = (char*)e_utf8_strstrcase(s1, s2)) - && (p == s1)) - return p; - else - return NULL; -} - -static ESExpResult * -func_beginswith(struct _ESExp *f, int argc, struct _ESExpResult **argv, void *data) -{ - SearchContext *ctx = data; - - return entry_compare (ctx, f, argc, argv, beginswith_helper); -} - -/* 'builtin' functions */ -static struct { - char *name; - ESExpFunc *func; - int type; /* set to 1 if a function can perform shortcut evaluation, or - doesn't execute everything, 0 otherwise */ -} symbols[] = { - { "contains", func_contains, 0 }, - { "is", func_is, 0 }, - { "beginswith", func_beginswith, 0 }, - { "endswith", func_endswith, 0 }, -}; - -gboolean -pas_backend_card_sexp_match_ecard (PASBackendCardSExp *sexp, ECard *ecard) -{ - ESExpResult *r; - gboolean retval; - - sexp->priv->search_context->card = e_card_simple_new (ecard); - - /* if it's not a valid vcard why is it in our db? :) */ - if (!sexp->priv->search_context->card) - return FALSE; - - r = e_sexp_eval(sexp->priv->search_sexp); - - retval = (r && r->type == ESEXP_RES_BOOL && r->value.bool); - - g_object_unref(sexp->priv->search_context->card); - - e_sexp_result_free(sexp->priv->search_sexp, r); - - return retval; -} - -gboolean -pas_backend_card_sexp_match_vcard (PASBackendCardSExp *sexp, const char *vcard) -{ - ECard *card; - gboolean retval; - - card = e_card_new ((char*)vcard); - - retval = pas_backend_card_sexp_match_ecard (sexp, card); - - g_object_unref(card); - - return retval; -} - - - -/** - * pas_backend_card_sexp_new: - */ -PASBackendCardSExp * -pas_backend_card_sexp_new (const char *text) -{ - PASBackendCardSExp *sexp = g_object_new (PAS_TYPE_BACKEND_CARD_SEXP, NULL); - int esexp_error; - int i; - - sexp->priv->search_sexp = e_sexp_new(); - - for(i=0;i<sizeof(symbols)/sizeof(symbols[0]);i++) { - if (symbols[i].type == 1) { - e_sexp_add_ifunction(sexp->priv->search_sexp, 0, symbols[i].name, - (ESExpIFunc *)symbols[i].func, sexp->priv->search_context); - } else { - e_sexp_add_function(sexp->priv->search_sexp, 0, symbols[i].name, - symbols[i].func, sexp->priv->search_context); - } - } - - e_sexp_input_text(sexp->priv->search_sexp, text, strlen(text)); - esexp_error = e_sexp_parse(sexp->priv->search_sexp); - - if (esexp_error == -1) { - g_object_unref (sexp); - sexp = NULL; - } - - return sexp; -} - -static void -pas_backend_card_sexp_dispose (GObject *object) -{ - PASBackendCardSExp *sexp = PAS_BACKEND_CARD_SEXP (object); - - if (sexp->priv) { - e_sexp_unref(sexp->priv->search_sexp); - - g_free (sexp->priv->search_context); - g_free (sexp->priv); - sexp->priv = NULL; - } - - if (G_OBJECT_CLASS (parent_class)->dispose) - G_OBJECT_CLASS (parent_class)->dispose (object); -} - -static void -pas_backend_card_sexp_class_init (PASBackendCardSExpClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - parent_class = g_type_class_peek_parent (klass); - - /* Set the virtual methods. */ - - object_class->dispose = pas_backend_card_sexp_dispose; -} - -static void -pas_backend_card_sexp_init (PASBackendCardSExp *sexp) -{ - PASBackendCardSExpPrivate *priv; - - priv = g_new0 (PASBackendCardSExpPrivate, 1); - - sexp->priv = priv; - priv->search_context = g_new (SearchContext, 1); -} - -/** - * pas_backend_card_sexp_get_type: - */ -GType -pas_backend_card_sexp_get_type (void) -{ - static GType type = 0; - - if (! type) { - GTypeInfo info = { - sizeof (PASBackendCardSExpClass), - NULL, /* base_class_init */ - NULL, /* base_class_finalize */ - (GClassInitFunc) pas_backend_card_sexp_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (PASBackendCardSExp), - 0, /* n_preallocs */ - (GInstanceInitFunc) pas_backend_card_sexp_init - }; - - type = g_type_register_static (G_TYPE_OBJECT, "PASBackendCardSExp", &info, 0); - } - - return type; -} diff --git a/addressbook/backend/pas/pas-backend-card-sexp.h b/addressbook/backend/pas/pas-backend-card-sexp.h deleted file mode 100644 index eb7c7c6641..0000000000 --- a/addressbook/backend/pas/pas-backend-card-sexp.h +++ /dev/null @@ -1,55 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * pas-backend-card-sexp.h - * Copyright 2000, 2001, Ximian, Inc. - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License, version 2, as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - * 02111-1307, USA. - */ - -#ifndef __PAS_BACKEND_CARD_SEXP_H__ -#define __PAS_BACKEND_CARD_SEXP_H__ - -#include <glib.h> -#include <glib-object.h> -#include <ebook/e-card.h> - -#define PAS_TYPE_BACKEND_CARD_SEXP (pas_backend_card_sexp_get_type ()) -#define PAS_BACKEND_CARD_SEXP(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), PAS_TYPE_BACKEND_CARD_SEXP, PASBackendCardSExp)) -#define PAS_BACKEND_CARD_SEXP_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), PAS_BACKEND_TYPE, PASBackendCardSExpClass)) -#define PAS_IS_BACKEND_CARD_SEXP(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), PAS_TYPE_BACKEND_CARD_SEXP)) -#define PAS_IS_BACKEND_CARD_SEXP_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), PAS_TYPE_BACKEND_CARD_SEXP)) -#define PAS_BACKEND_CARD_SEXP_GET_CLASS(k) (G_TYPE_INSTANCE_GET_CLASS ((obj), PAS_TYPE_BACKEND_CARD_SEXP, PASBackendCardSExpClass)) - -typedef struct _PASBackendCardSExpPrivate PASBackendCardSExpPrivate; - -typedef struct { - GObject parent_object; - PASBackendCardSExpPrivate *priv; -} PASBackendCardSExp; - -typedef struct { - GObjectClass parent_class; -} PASBackendCardSExpClass; - -PASBackendCardSExp *pas_backend_card_sexp_new (const char *text); -GType pas_backend_card_sexp_get_type (void); - -gboolean pas_backend_card_sexp_match_vcard (PASBackendCardSExp *sexp, const char *vcard); -gboolean pas_backend_card_sexp_match_ecard (PASBackendCardSExp *sexp, ECard *ecard); - -#endif /* __PAS_BACKEND_CARD_SEXP_H__ */ diff --git a/addressbook/backend/pas/pas-backend-file.c b/addressbook/backend/pas/pas-backend-file.c deleted file mode 100644 index b11c62cb86..0000000000 --- a/addressbook/backend/pas/pas-backend-file.c +++ /dev/null @@ -1,1617 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * Author: - * Nat Friedman (nat@ximian.com) - * - * Copyright 2000, Ximian, Inc. - */ - -#include "config.h" -#include "pas-backend-file.h" - -#include <stdio.h> -#include <string.h> -#include <unistd.h> -#include <fcntl.h> -#include <time.h> -#include <db.h> -#include <sys/stat.h> - -#include <e-util/e-db3-utils.h> - -#if DB_VERSION_MAJOR != 3 || \ - DB_VERSION_MINOR != 1 || \ - DB_VERSION_PATCH != 17 -#error Including wrong DB3. Need libdb 3.1.17. -#endif - -#include <gal/util/e-util.h> -#include <gal/widgets/e-unicode.h> - -#include <ebook/e-card-simple.h> -#include <e-util/e-dbhash.h> -#include <e-util/e-db3-utils.h> -#include <libgnome/gnome-i18n.h> - -#include "pas-book.h" -#include "pas-card-cursor.h" -#include "pas-backend-card-sexp.h" -#include "pas-backend-summary.h" - -#define PAS_BACKEND_FILE_VERSION_NAME "PAS-DB-VERSION" -#define PAS_BACKEND_FILE_VERSION "0.2" - -#define PAS_ID_PREFIX "pas-id-" -#define SUMMARY_FLUSH_TIMEOUT 5000 - -static PASBackendClass *pas_backend_file_parent_class; -typedef struct _PASBackendFileCursorPrivate PASBackendFileCursorPrivate; -typedef struct _PASBackendFileBookView PASBackendFileBookView; -typedef struct _PASBackendFileSearchContext PASBackendFileSearchContext; -typedef struct _PasBackendFileChangeContext PASBackendFileChangeContext; - -struct _PASBackendFilePrivate { - char *uri; - char *filename; - DB *file_db; - EList *book_views; - GHashTable *address_lists; - PASBackendSummary *summary; -}; - -struct _PASBackendFileCursorPrivate { - PASBackend *backend; - PASBook *book; - - GList *elements; - guint32 num_elements; -}; - -struct _PASBackendFileBookView { - PASBookView *book_view; - gchar *search; - PASBackendCardSExp *card_sexp; - gchar *change_id; - PASBackendFileChangeContext *change_context; -}; - -struct _PasBackendFileChangeContext { - DB *db; - - GList *add_cards; - GList *add_ids; - GList *mod_cards; - GList *mod_ids; - GList *del_ids; -}; - -static void -string_to_dbt(const char *str, DBT *dbt) -{ - memset (dbt, 0, sizeof (*dbt)); - dbt->data = (void*)str; - dbt->size = strlen (str) + 1; -} - -static void -build_summary (PASBackendFilePrivate *bfpriv) -{ - DB *db = bfpriv->file_db; - DBC *dbc; - int db_error; - DBT id_dbt, vcard_dbt; - - db_error = db->cursor (db, NULL, &dbc, 0); - - if (db_error != 0) { - g_warning ("pas_backend_file_build_all_cards_list: error building list\n"); - } - - memset (&vcard_dbt, 0, sizeof (vcard_dbt)); - memset (&id_dbt, 0, sizeof (id_dbt)); - db_error = dbc->c_get(dbc, &id_dbt, &vcard_dbt, DB_FIRST); - - while (db_error == 0) { - - /* don't include the version in the list of cards */ - if (id_dbt.size != strlen(PAS_BACKEND_FILE_VERSION_NAME) + 1 - || strcmp (id_dbt.data, PAS_BACKEND_FILE_VERSION_NAME)) { - - pas_backend_summary_add_card (bfpriv->summary, vcard_dbt.data); - } - - db_error = dbc->c_get(dbc, &id_dbt, &vcard_dbt, DB_NEXT); - - } -} - -static void -do_summary_query (PASBackendFile *bf, - PASBackendFileBookView *view, - gboolean completion_search) -{ - GPtrArray *ids = pas_backend_summary_search (bf->priv->summary, view->search); - int db_error = 0; - GList *cards = NULL; - gint card_count = 0, card_threshold = 20, card_threshold_max = 3000; - DB *db = bf->priv->file_db; - DBT id_dbt, vcard_dbt; - int i; - - for (i = 0; i < ids->len; i ++) { - char *id = g_ptr_array_index (ids, i); - char *vcard = NULL; - -#if SUMMARY_STORES_ENOUGH_INFO - /* this is disabled for the time being because lists - can have more than 3 email addresses and the - summary only stores 3. */ - - if (completion_search) { - vcard = pas_backend_summary_get_summary_vcard (bf->priv->summary, - id); - } - else { -#endif - string_to_dbt (id, &id_dbt); - memset (&vcard_dbt, 0, sizeof (vcard_dbt)); - - db_error = db->get (db, NULL, &id_dbt, &vcard_dbt, 0); - - if (db_error == 0) - vcard = g_strdup (vcard_dbt.data); -#if SUMMARY_STORES_ENOUGH_INFO - } -#endif - - if (vcard) { - cards = g_list_prepend (cards, vcard); - card_count ++; - - /* If we've accumulated a number of checks, pass them off to the client. */ - if (card_count >= card_threshold) { - pas_book_view_notify_add (view->book_view, cards); - /* Clean up the handed-off data. */ - g_list_foreach (cards, (GFunc)g_free, NULL); - g_list_free (cards); - cards = NULL; - card_count = 0; - - /* Yeah, this scheme is overly complicated. But I like it. */ - if (card_threshold < card_threshold_max) { - card_threshold = MIN (2*card_threshold, card_threshold_max); - } - } - } - else - continue; /* XXX */ - } - - g_ptr_array_free (ids, TRUE); - - if (card_count) - pas_book_view_notify_add (view->book_view, cards); - - pas_book_view_notify_complete (view->book_view, GNOME_Evolution_Addressbook_BookViewListener_Success); - - g_list_foreach (cards, (GFunc)g_free, NULL); - g_list_free (cards); -} - -static PASBackendFileBookView * -pas_backend_file_book_view_copy(const PASBackendFileBookView *book_view, void *closure) -{ - PASBackendFileBookView *new_book_view; - new_book_view = g_new (PASBackendFileBookView, 1); - new_book_view->book_view = book_view->book_view; - - new_book_view->search = g_strdup(book_view->search); - new_book_view->card_sexp = book_view->card_sexp; - if (new_book_view->card_sexp) - g_object_ref(new_book_view->card_sexp); - - new_book_view->change_id = g_strdup(book_view->change_id); - if (book_view->change_context) { - new_book_view->change_context = g_new(PASBackendFileChangeContext, 1); - new_book_view->change_context->db = book_view->change_context->db; - new_book_view->change_context->add_cards = book_view->change_context->add_cards; - new_book_view->change_context->add_ids = book_view->change_context->add_ids; - new_book_view->change_context->mod_cards = book_view->change_context->mod_cards; - new_book_view->change_context->mod_ids = book_view->change_context->mod_ids; - new_book_view->change_context->del_ids = book_view->change_context->del_ids; - } else - new_book_view->change_context = NULL; - - return new_book_view; -} - -static void -pas_backend_file_book_view_free(PASBackendFileBookView *book_view, void *closure) -{ - g_free(book_view->search); - if (book_view->card_sexp) - g_object_unref (book_view->card_sexp); - - g_free(book_view->change_id); - if (book_view->change_context) { - g_list_foreach (book_view->change_context->add_cards, (GFunc)g_free, NULL); - g_list_foreach (book_view->change_context->add_ids, (GFunc)g_free, NULL); - g_list_foreach (book_view->change_context->mod_cards, (GFunc)g_free, NULL); - g_list_foreach (book_view->change_context->mod_ids, (GFunc)g_free, NULL); - g_list_foreach (book_view->change_context->del_ids, (GFunc)g_free, NULL); - g_list_free (book_view->change_context->add_cards); - g_list_free (book_view->change_context->add_ids); - g_list_free (book_view->change_context->mod_cards); - g_list_free (book_view->change_context->mod_ids); - g_list_free (book_view->change_context->del_ids); - } - g_free(book_view->change_context); - - g_free(book_view); -} - -static long -get_length(PASCardCursor *cursor, gpointer data) -{ - PASBackendFileCursorPrivate *cursor_data = (PASBackendFileCursorPrivate *) data; - - return cursor_data->num_elements; -} - -static char * -get_nth(PASCardCursor *cursor, long n, gpointer data) -{ - PASBackendFileCursorPrivate *cursor_data = (PASBackendFileCursorPrivate *) data; - GList *nth_item = g_list_nth(cursor_data->elements, n); - - return g_strdup((char*)nth_item->data); -} - -static void -cursor_destroy(gpointer data, GObject *where_object_was) -{ - CORBA_Environment ev; - GNOME_Evolution_Addressbook_Book corba_book; - PASBackendFileCursorPrivate *cursor_data = (PASBackendFileCursorPrivate *) data; - - corba_book = bonobo_object_corba_objref(BONOBO_OBJECT(cursor_data->book)); - - CORBA_exception_init(&ev); - - GNOME_Evolution_Addressbook_Book_unref(corba_book, &ev); - - if (ev._major != CORBA_NO_EXCEPTION) { - g_warning("cursor_destroy: Exception unreffing " - "corba book.\n"); - } - - CORBA_exception_free(&ev); - - g_list_foreach(cursor_data->elements, (GFunc)g_free, NULL); - g_list_free (cursor_data->elements); - - g_free(cursor_data); -} - -static void -view_destroy(gpointer data, GObject *where_object_was) -{ - PASBook *book = (PASBook *)data; - PASBackendFile *bf; - EIterator *iterator; - gboolean success = FALSE; - - bf = PAS_BACKEND_FILE(pas_book_get_backend(book)); - for (iterator = e_list_get_iterator(bf->priv->book_views); e_iterator_is_valid(iterator); e_iterator_next(iterator)) { - const PASBackendFileBookView *view = e_iterator_get(iterator); - if (view->book_view == (PASBookView*)where_object_was) { - e_iterator_delete(iterator); - success = TRUE; - break; - } - } - if (!success) - g_warning ("Failed to remove from book_views list"); - g_object_unref(iterator); - - bonobo_object_unref(BONOBO_OBJECT(book)); -} - -static char * -pas_backend_file_create_unique_id (char *vcard) -{ - /* use a 32 counter and the 32 bit timestamp to make an id. - it's doubtful 2^32 id's will be created in a second, so we - should be okay. */ - static guint c = 0; - return g_strdup_printf (PAS_ID_PREFIX "%08lX%08X", time(NULL), c++); -} - -static gboolean -vcard_matches_search (const PASBackendFileBookView *view, char *vcard_string) -{ - /* If this is not a search context view, it doesn't match be default */ - if (view->card_sexp == NULL) - return FALSE; - - return pas_backend_card_sexp_match_vcard (view->card_sexp, vcard_string); -} - -static gboolean -ecard_matches_search (const PASBackendFileBookView *view, ECard *card) -{ - /* If this is not a search context view, it doesn't match be default */ - if (view->card_sexp == NULL) - return FALSE; - - return pas_backend_card_sexp_match_ecard (view->card_sexp, card); -} - -typedef struct { - PASBackendFile *bf; - PASBook *book; - const PASBackendFileBookView *view; - DBC *dbc; - - int card_count; - int card_threshold; - int card_threshold_max; - GList *cards; - - gboolean done_first; - gboolean search_needed; -} FileBackendSearchClosure; - -static void -free_search_closure (FileBackendSearchClosure *closure) -{ - g_list_foreach (closure->cards, (GFunc)g_free, NULL); - g_list_free (closure->cards); - g_free (closure); -} - -static gboolean -pas_backend_file_search_timeout (gpointer data) -{ - FileBackendSearchClosure *closure = data; - int db_error = 0; - DBT id_dbt, vcard_dbt; - int file_version_name_len; - DBC *dbc = closure->dbc; - - file_version_name_len = strlen (PAS_BACKEND_FILE_VERSION_NAME); - - memset (&id_dbt, 0, sizeof (id_dbt)); - memset (&vcard_dbt, 0, sizeof (vcard_dbt)); - - if (closure->done_first) { - db_error = dbc->c_get(dbc, &id_dbt, &vcard_dbt, DB_NEXT); - } - else { - db_error = dbc->c_get(dbc, &id_dbt, &vcard_dbt, DB_FIRST); - closure->done_first = TRUE; - } - - while (db_error == 0) { - - /* don't include the version in the list of cards */ - if (strcmp (id_dbt.data, PAS_BACKEND_FILE_VERSION_NAME)) { - char *vcard_string = vcard_dbt.data; - - /* check if the vcard matches the search sexp */ - if ((!closure->search_needed) || vcard_matches_search (closure->view, vcard_string)) { - closure->cards = g_list_prepend (closure->cards, g_strdup (vcard_string)); - closure->card_count ++; - } - - /* If we've accumulated a number of checks, pass them off to the client. */ - if (closure->card_count >= closure->card_threshold) { - pas_book_view_notify_add (closure->view->book_view, closure->cards); - /* Clean up the handed-off data. */ - g_list_foreach (closure->cards, (GFunc)g_free, NULL); - g_list_free (closure->cards); - closure->cards = NULL; - closure->card_count = 0; - - /* Yeah, this scheme is overly complicated. But I like it. */ - if (closure->card_threshold < closure->card_threshold_max) { - closure->card_threshold = MIN (2*closure->card_threshold, closure->card_threshold_max); - } - - /* return here, we'll do the next lump in the next callback */ - g_timeout_add (200, pas_backend_file_search_timeout, closure); - - return FALSE; - } - } - - db_error = dbc->c_get(dbc, &id_dbt, &vcard_dbt, DB_NEXT); - } - - dbc->c_close (dbc); - - if (db_error != DB_NOTFOUND) { - g_warning ("pas_backend_file_search: error building list\n"); - free_search_closure (closure); - } - - if (closure->card_count) - pas_book_view_notify_add (closure->view->book_view, closure->cards); - - pas_book_view_notify_complete (closure->view->book_view, GNOME_Evolution_Addressbook_BookViewListener_Success); - - free_search_closure (closure); - - return FALSE; -} - - -static void -pas_backend_file_search (PASBackendFile *bf, - PASBook *book, - const PASBackendFileBookView *cnstview, - gboolean completion_search) -{ - PASBackendFileBookView *view = (PASBackendFileBookView *)cnstview; - gboolean search_needed; - - search_needed = TRUE; - - if ( ! strcmp (view->search, "(contains \"x-evolution-any-field\" \"\")")) - search_needed = FALSE; - - if (search_needed) - pas_book_view_notify_status_message (view->book_view, _("Searching...")); - else - pas_book_view_notify_status_message (view->book_view, _("Loading...")); - - if (view->card_sexp) { - g_object_unref (view->card_sexp); - view->card_sexp = NULL; - } - - view->card_sexp = pas_backend_card_sexp_new (view->search); - - if (!view->card_sexp) { - pas_book_view_notify_complete (view->book_view, GNOME_Evolution_Addressbook_BookViewListener_InvalidQuery); - return; - } - - if (pas_backend_summary_is_summary_query (bf->priv->summary, view->search)) { - do_summary_query (bf, view, completion_search); - } - else { - FileBackendSearchClosure *closure = g_new0 (FileBackendSearchClosure, 1); - DB *db = bf->priv->file_db; - int db_error; - - closure->card_threshold = 20; - closure->card_threshold_max = 3000; - closure->search_needed = search_needed; - closure->view = view; - closure->bf = bf; - closure->book = book; - - db_error = db->cursor (db, NULL, &closure->dbc, 0); - - if (db_error != 0) { - g_warning ("pas_backend_file_search: error building list\n"); - } else { - g_idle_add (pas_backend_file_search_timeout, closure); - } - } -} - -static void -pas_backend_file_changes_foreach_key (const char *key, gpointer user_data) -{ - PASBackendFileChangeContext *ctx = user_data; - DB *db = ctx->db; - DBT id_dbt, vcard_dbt; - int db_error = 0; - - string_to_dbt (key, &id_dbt); - memset (&vcard_dbt, 0, sizeof (vcard_dbt)); - db_error = db->get (db, NULL, &id_dbt, &vcard_dbt, 0); - - if (db_error != 0) { - char *id = id_dbt.data; - - ctx->del_ids = g_list_append (ctx->del_ids, g_strdup (id)); - } -} - -static void -pas_backend_file_changes (PASBackendFile *bf, - PASBook *book, - const PASBackendFileBookView *cnstview) -{ - int db_error = 0; - DBT id_dbt, vcard_dbt; - char *filename; - EDbHash *ehash; - GList *i, *v; - DB *db = bf->priv->file_db; - DBC *dbc; - PASBackendFileBookView *view = (PASBackendFileBookView *)cnstview; - PASBackendFileChangeContext *ctx = cnstview->change_context; - char *dirname, *slash; - - memset (&id_dbt, 0, sizeof (id_dbt)); - memset (&vcard_dbt, 0, sizeof (vcard_dbt)); - - /* Find the changed ids */ - dirname = g_strdup (bf->priv->filename); - slash = strrchr (dirname, '/'); - *slash = '\0'; - - filename = g_strdup_printf ("%s/%s.db", dirname, view->change_id); - ehash = e_dbhash_new (filename); - g_free (filename); - g_free (dirname); - - db_error = db->cursor (db, NULL, &dbc, 0); - - if (db_error != 0) { - g_warning ("pas_backend_file_changes: error building list\n"); - } else { - db_error = dbc->c_get(dbc, &id_dbt, &vcard_dbt, DB_FIRST); - - while (db_error == 0) { - - /* don't include the version in the list of cards */ - if (id_dbt.size != strlen(PAS_BACKEND_FILE_VERSION_NAME) + 1 - || strcmp (id_dbt.data, PAS_BACKEND_FILE_VERSION_NAME)) { - ECard *card; - char *id = id_dbt.data; - char *vcard_string; - - /* Remove fields the user can't change - * and can change without the rest of the - * card changing - */ - card = e_card_new (vcard_dbt.data); - g_object_set (card, "last_use", NULL, "use_score", 0.0, NULL); - vcard_string = e_card_get_vcard_assume_utf8 (card); - g_object_unref (card); - - /* check what type of change has occurred, if any */ - switch (e_dbhash_compare (ehash, id, vcard_string)) { - case E_DBHASH_STATUS_SAME: - break; - case E_DBHASH_STATUS_NOT_FOUND: - ctx->add_cards = g_list_append (ctx->add_cards, - vcard_string); - ctx->add_ids = g_list_append (ctx->add_ids, g_strdup(id)); - break; - case E_DBHASH_STATUS_DIFFERENT: - ctx->mod_cards = g_list_append (ctx->mod_cards, - vcard_string); - ctx->mod_ids = g_list_append (ctx->mod_ids, g_strdup(id)); - break; - } - } - - db_error = dbc->c_get(dbc, &id_dbt, &vcard_dbt, DB_NEXT); - } - dbc->c_close (dbc); - } - - e_dbhash_foreach_key (ehash, (EDbHashFunc)pas_backend_file_changes_foreach_key, view->change_context); - - /* Send the changes */ - if (db_error != DB_NOTFOUND) { - g_warning ("pas_backend_file_changes: error building list\n"); - } else { - if (ctx->add_cards != NULL) - pas_book_view_notify_add (view->book_view, ctx->add_cards); - - if (ctx->mod_cards != NULL) - pas_book_view_notify_change (view->book_view, ctx->mod_cards); - - for (v = ctx->del_ids; v != NULL; v = v->next){ - char *id = v->data; - pas_book_view_notify_remove_1 (view->book_view, id); - } - - pas_book_view_notify_complete (view->book_view, GNOME_Evolution_Addressbook_BookViewListener_Success); - } - - /* Update the hash */ - for (i = ctx->add_ids, v = ctx->add_cards; i != NULL; i = i->next, v = v->next){ - char *id = i->data; - char *vcard = v->data; - - e_dbhash_add (ehash, id, vcard); - g_free (i->data); - g_free (v->data); - } - for (i = ctx->mod_ids, v = ctx->mod_cards; i != NULL; i = i->next, v = v->next){ - char *id = i->data; - char *vcard = v->data; - - e_dbhash_add (ehash, id, vcard); - g_free (i->data); - g_free (v->data); - } - for (i = ctx->del_ids; i != NULL; i = i->next){ - char *id = i->data; - - e_dbhash_remove (ehash, id); - g_free (i->data); - } - - e_dbhash_write (ehash); - e_dbhash_destroy (ehash); -} - -static char * -do_create(PASBackend *backend, - char *vcard_req, - char **vcard_ptr) -{ - PASBackendFile *bf = PAS_BACKEND_FILE (backend); - DB *db = bf->priv->file_db; - DBT id_dbt, vcard_dbt; - int db_error; - char *id; - ECard *card; - char *vcard; - char *ret_val; - - id = pas_backend_file_create_unique_id (vcard_req); - - string_to_dbt (id, &id_dbt); - - card = e_card_new(vcard_req); - e_card_set_id(card, id); - vcard = e_card_get_vcard_assume_utf8(card); - - string_to_dbt (vcard, &vcard_dbt); - - db_error = db->put (db, NULL, &id_dbt, &vcard_dbt, 0); - - if (0 == db_error) { - db_error = db->sync (db, 0); - if (db_error != 0) - g_warning ("db->sync failed.\n"); - ret_val = id; - - } - else { - g_free (id); - ret_val = NULL; - } - - g_object_unref(card); - card = NULL; - - if (vcard_ptr && ret_val) - *vcard_ptr = vcard; - else - g_free (vcard); - - return ret_val; -} - -static void -pas_backend_file_process_create_card (PASBackend *backend, - PASBook *book, - PASCreateCardRequest *req) -{ - char *id; - char *vcard; - EIterator *iterator; - PASBackendFile *bf = PAS_BACKEND_FILE (backend); - - id = do_create(backend, req->vcard, &vcard); - if (id) { - for (iterator = e_list_get_iterator(bf->priv->book_views); e_iterator_is_valid(iterator); e_iterator_next(iterator)) { - const PASBackendFileBookView *view = e_iterator_get(iterator); - if (vcard_matches_search (view, vcard)) { - bonobo_object_ref (BONOBO_OBJECT (view->book_view)); - pas_book_view_notify_add_1 (view->book_view, vcard); - pas_book_view_notify_complete (view->book_view, GNOME_Evolution_Addressbook_BookViewListener_Success); - bonobo_object_unref (BONOBO_OBJECT (view->book_view)); - } - } - g_object_unref(iterator); - - pas_book_respond_create ( - book, - GNOME_Evolution_Addressbook_BookListener_Success, - id); - - pas_backend_summary_add_card (bf->priv->summary, vcard); - - g_free(vcard); - g_free(id); - } - else { - /* XXX need a different call status for this case, i - think */ - pas_book_respond_create ( - book, - GNOME_Evolution_Addressbook_BookListener_CardNotFound, - ""); - } -} - -static void -pas_backend_file_process_remove_cards (PASBackend *backend, - PASBook *book, - PASRemoveCardsRequest *req) -{ - PASBackendFile *bf = PAS_BACKEND_FILE (backend); - DB *db = bf->priv->file_db; - DBT id_dbt, vcard_dbt; - int db_error; - EIterator *iterator; - const char *id; - GList *l; - GList *removed_cards = NULL; - GNOME_Evolution_Addressbook_BookListener_CallStatus rv = GNOME_Evolution_Addressbook_BookListener_Success; - - for (l = req->ids; l; l = l->next) { - id = l->data; - - string_to_dbt (id, &id_dbt); - memset (&vcard_dbt, 0, sizeof (vcard_dbt)); - - db_error = db->get (db, NULL, &id_dbt, &vcard_dbt, 0); - if (0 != db_error) { - rv = GNOME_Evolution_Addressbook_BookListener_CardNotFound; - continue; - } - - db_error = db->del (db, NULL, &id_dbt, 0); - if (0 != db_error) { - rv = GNOME_Evolution_Addressbook_BookListener_CardNotFound; - continue; - } - - removed_cards = g_list_prepend (removed_cards, e_card_new (vcard_dbt.data)); - } - - /* if we actually removed some, try to sync */ - if (removed_cards) { - db_error = db->sync (db, 0); - if (db_error != 0) - g_warning ("db->sync failed.\n"); - } - - for (iterator = e_list_get_iterator (bf->priv->book_views); e_iterator_is_valid(iterator); e_iterator_next(iterator)) { - const PASBackendFileBookView *view = e_iterator_get(iterator); - GList *view_removed = NULL; - for (l = removed_cards; l; l = l->next) { - ECard *removed_card = l->data; - if (ecard_matches_search (view, removed_card)) { - view_removed = g_list_prepend (view_removed, (char*)e_card_get_id (removed_card)); - } - } - if (view_removed) { - bonobo_object_ref (BONOBO_OBJECT (view->book_view)); - pas_book_view_notify_remove (view->book_view, view_removed); - pas_book_view_notify_complete (view->book_view, GNOME_Evolution_Addressbook_BookViewListener_Success); - bonobo_object_unref (BONOBO_OBJECT (view->book_view)); - g_list_free (view_removed); - } - } - g_object_unref(iterator); - - pas_book_respond_remove (book, rv); - - for (l = removed_cards; l; l = l->next) { - ECard *c = l->data; - pas_backend_summary_remove_card (bf->priv->summary, e_card_get_id (c)); - g_object_unref (c); - } - - g_list_free (removed_cards); -} - -static void -pas_backend_file_process_modify_card (PASBackend *backend, - PASBook *book, - PASModifyCardRequest *req) -{ - PASBackendFile *bf = PAS_BACKEND_FILE (backend); - DB *db = bf->priv->file_db; - DBT id_dbt, vcard_dbt; - int db_error; - EIterator *iterator; - ECard *card; - const char *id, *lookup_id; - char *old_vcard_string; - - /* create a new ecard from the request data */ - card = e_card_new(req->vcard); - id = e_card_get_id(card); - - /* This is disgusting, but for a time cards were added with - ID's that are no longer used (they contained both the uri - and the id.) If we recognize it as a uri (file:///...) trim - off everything before the last '/', and use that as the - id.*/ - if (!strncmp (id, "file:///", strlen ("file:///"))) { - lookup_id = strrchr (id, '/') + 1; - } - else - lookup_id = id; - - string_to_dbt (lookup_id, &id_dbt); - memset (&vcard_dbt, 0, sizeof (vcard_dbt)); - - /* get the old ecard - the one that's presently in the db */ - db_error = db->get (db, NULL, &id_dbt, &vcard_dbt, 0); - if (0 != db_error) { - pas_book_respond_modify ( - book, - GNOME_Evolution_Addressbook_BookListener_CardNotFound); - return; - } - old_vcard_string = g_strdup(vcard_dbt.data); - - string_to_dbt (req->vcard, &vcard_dbt); - - db_error = db->put (db, NULL, &id_dbt, &vcard_dbt, 0); - - if (0 == db_error) { - db_error = db->sync (db, 0); - if (db_error != 0) - g_warning ("db->sync failed.\n"); - - for (iterator = e_list_get_iterator(bf->priv->book_views); e_iterator_is_valid(iterator); e_iterator_next(iterator)) { - CORBA_Environment ev; - const PASBackendFileBookView *view = e_iterator_get(iterator); - gboolean old_match, new_match; - - CORBA_exception_init(&ev); - - bonobo_object_dup_ref(bonobo_object_corba_objref(BONOBO_OBJECT(view->book_view)), &ev); - - old_match = vcard_matches_search (view, old_vcard_string); - new_match = vcard_matches_search (view, req->vcard); - if (old_match && new_match) - pas_book_view_notify_change_1 (view->book_view, req->vcard); - else if (new_match) - pas_book_view_notify_add_1 (view->book_view, req->vcard); - else /* if (old_match) */ - pas_book_view_notify_remove_1 (view->book_view, id); - - pas_book_view_notify_complete (view->book_view, GNOME_Evolution_Addressbook_BookViewListener_Success); - - bonobo_object_release_unref(bonobo_object_corba_objref(BONOBO_OBJECT(view->book_view)), &ev); - - CORBA_exception_free (&ev); - } - - g_object_unref(iterator); - - pas_book_respond_modify ( - book, - GNOME_Evolution_Addressbook_BookListener_Success); - - pas_backend_summary_remove_card (bf->priv->summary, id); - pas_backend_summary_add_card (bf->priv->summary, req->vcard); - } - else { - pas_book_respond_modify ( - book, - GNOME_Evolution_Addressbook_BookListener_CardNotFound); - } - - g_free(old_vcard_string); - - g_object_unref(card); -} - -static void -pas_backend_file_build_cards_list(PASBackend *backend, - PASBackendFileCursorPrivate *cursor_data, - char *search) -{ - PASBackendFile *bf = PAS_BACKEND_FILE (backend); - DB *db = bf->priv->file_db; - DBC *dbc; - int db_error; - DBT id_dbt, vcard_dbt; - PASBackendCardSExp *card_sexp = NULL; - gboolean search_needed; - - cursor_data->elements = NULL; - - search_needed = TRUE; - - if (!strcmp (search, "(contains \"x-evolution-any-field\" \"\")")) - search_needed = FALSE; - - card_sexp = pas_backend_card_sexp_new (search); - - if (!card_sexp) - g_warning ("pas_backend_file_build_all_cards_list: error building list\n"); - - db_error = db->cursor (db, NULL, &dbc, 0); - - if (db_error != 0) { - g_warning ("pas_backend_file_build_all_cards_list: error building list\n"); - } - - memset (&vcard_dbt, 0, sizeof (vcard_dbt)); - memset (&id_dbt, 0, sizeof (id_dbt)); - db_error = dbc->c_get(dbc, &id_dbt, &vcard_dbt, DB_FIRST); - - while (db_error == 0) { - - /* don't include the version in the list of cards */ - if (id_dbt.size != strlen(PAS_BACKEND_FILE_VERSION_NAME) + 1 - || strcmp (id_dbt.data, PAS_BACKEND_FILE_VERSION_NAME)) { - - if ((!search_needed) || (card_sexp != NULL && pas_backend_card_sexp_match_vcard (card_sexp, vcard_dbt.data))) { - cursor_data->elements = g_list_prepend (cursor_data->elements, g_strdup (vcard_dbt.data)); - } - } - - db_error = dbc->c_get(dbc, &id_dbt, &vcard_dbt, DB_NEXT); - - } - - if (db_error != DB_NOTFOUND) { - g_warning ("pas_backend_file_build_all_cards_list: error building list\n"); - } - else { - cursor_data->num_elements = g_list_length (cursor_data->elements); - cursor_data->elements = g_list_reverse (cursor_data->elements); - } -} - -static void -pas_backend_file_process_get_vcard (PASBackend *backend, - PASBook *book, - PASGetVCardRequest *req) -{ - PASBackendFile *bf; - DB *db; - DBT id_dbt, vcard_dbt; - int db_error = 0; - char *card; - GNOME_Evolution_Addressbook_BookListener_CallStatus status; - - bf = PAS_BACKEND_FILE (pas_book_get_backend (book)); - db = bf->priv->file_db; - - string_to_dbt (req->id, &id_dbt); - memset (&vcard_dbt, 0, sizeof (vcard_dbt)); - - db_error = db->get (db, NULL, &id_dbt, &vcard_dbt, 0); - - if (db_error == 0) { - card = vcard_dbt.data; - status = GNOME_Evolution_Addressbook_BookListener_Success; - } else { - card = ""; - status = GNOME_Evolution_Addressbook_BookListener_CardNotFound; - } - - pas_book_respond_get_vcard (book, - status, - card); -} - -static void -pas_backend_file_process_get_cursor (PASBackend *backend, - PASBook *book, - PASGetCursorRequest *req) -{ - /* - PASBackendFile *bf = PAS_BACKEND_FILE (backend); - DB *db = bf->priv->file_db; - DBT id_dbt, vcard_dbt; - */ - CORBA_Environment ev; - int db_error = 0; - PASBackendFileCursorPrivate *cursor_data; - PASCardCursor *cursor; - GNOME_Evolution_Addressbook_Book corba_book; - - cursor_data = g_new(PASBackendFileCursorPrivate, 1); - cursor_data->backend = backend; - cursor_data->book = book; - - pas_backend_file_build_cards_list(backend, cursor_data, req->search); - - corba_book = bonobo_object_corba_objref(BONOBO_OBJECT(book)); - - CORBA_exception_init(&ev); - - GNOME_Evolution_Addressbook_Book_ref(corba_book, &ev); - - if (ev._major != CORBA_NO_EXCEPTION) { - g_warning("pas_backend_file_process_get_cursor: Exception reffing " - "corba book.\n"); - } - - CORBA_exception_free(&ev); - - cursor = pas_card_cursor_new(get_length, - get_nth, - cursor_data); - - g_object_weak_ref (G_OBJECT (cursor), - cursor_destroy, cursor_data); - - pas_book_respond_get_cursor ( - book, - (db_error == 0 - ? GNOME_Evolution_Addressbook_BookListener_Success - : GNOME_Evolution_Addressbook_BookListener_CardNotFound), - cursor); -} - -static void -pas_backend_file_process_get_book_view (PASBackend *backend, - PASBook *book, - PASGetBookViewRequest *req) -{ - PASBackendFile *bf = PAS_BACKEND_FILE (backend); - PASBookView *book_view; - PASBackendFileBookView view; - EIterator *iterator; - - bonobo_object_ref(BONOBO_OBJECT(book)); - - book_view = pas_book_view_new (req->listener); - - g_object_weak_ref (G_OBJECT (book_view), view_destroy, book); - - view.book_view = book_view; - view.search = g_strdup (req->search); - view.card_sexp = NULL; - view.change_id = NULL; - view.change_context = NULL; - - e_list_append(bf->priv->book_views, &view); - - pas_book_respond_get_book_view (book, - (book_view != NULL - ? GNOME_Evolution_Addressbook_BookListener_Success - : GNOME_Evolution_Addressbook_BookListener_CardNotFound /* XXX */), - book_view); - - if (!pas_backend_is_loaded (backend)) - return; - - iterator = e_list_get_iterator(bf->priv->book_views); - e_iterator_last(iterator); - pas_backend_file_search (bf, book, e_iterator_get(iterator), FALSE); - g_object_unref(iterator); -} - -static void -pas_backend_file_process_get_completion_view (PASBackend *backend, - PASBook *book, - PASGetCompletionViewRequest *req) -{ - PASBackendFile *bf = PAS_BACKEND_FILE (backend); - PASBookView *book_view; - PASBackendFileBookView view; - EIterator *iterator; - - bonobo_object_ref(BONOBO_OBJECT(book)); - - book_view = pas_book_view_new (req->listener); - - g_object_weak_ref (G_OBJECT (book_view), view_destroy, book); - - view.book_view = book_view; - view.search = g_strdup (req->search); - view.card_sexp = NULL; - view.change_id = NULL; - view.change_context = NULL; - - e_list_append(bf->priv->book_views, &view); - - pas_book_respond_get_completion_view (book, - (book_view != NULL - ? GNOME_Evolution_Addressbook_BookListener_Success - : GNOME_Evolution_Addressbook_BookListener_CardNotFound /* XXX */), - book_view); - - if (!pas_backend_is_loaded (backend)) - return; - - iterator = e_list_get_iterator(bf->priv->book_views); - e_iterator_last(iterator); - pas_backend_file_search (bf, book, e_iterator_get(iterator), TRUE); - g_object_unref(iterator); -} - -static void -pas_backend_file_process_get_changes (PASBackend *backend, - PASBook *book, - PASGetChangesRequest *req) -{ - PASBackendFile *bf = PAS_BACKEND_FILE (backend); - PASBookView *book_view; - PASBackendFileBookView view; - PASBackendFileChangeContext ctx; - EIterator *iterator; - - bonobo_object_ref(BONOBO_OBJECT(book)); - - book_view = pas_book_view_new (req->listener); - - g_object_weak_ref (G_OBJECT (book_view), view_destroy, book); - - pas_book_respond_get_changes (book, - (book_view != NULL - ? GNOME_Evolution_Addressbook_BookListener_Success - : GNOME_Evolution_Addressbook_BookListener_CardNotFound /* XXX */), - book_view); - - view.book_view = book_view; - view.change_id = req->change_id; - view.change_context = &ctx; - ctx.db = bf->priv->file_db; - ctx.add_cards = NULL; - ctx.add_ids = NULL; - ctx.mod_cards = NULL; - ctx.mod_ids = NULL; - ctx.del_ids = NULL; - view.search = NULL; - view.card_sexp = NULL; - - e_list_append(bf->priv->book_views, &view); - - if (!pas_backend_is_loaded (backend)) - return; - - iterator = e_list_get_iterator(bf->priv->book_views); - e_iterator_last(iterator); - pas_backend_file_changes (bf, book, e_iterator_get(iterator)); - g_object_unref(iterator); -} - -static void -pas_backend_file_process_check_connection (PASBackend *backend, - PASBook *book, - PASCheckConnectionRequest *req) -{ - PASBackendFile *bf = PAS_BACKEND_FILE (backend); - - pas_book_report_connection (book, bf->priv->file_db != NULL); -} - -static char * -pas_backend_file_extract_path_from_uri (const char *uri) -{ - g_assert (strncasecmp (uri, "file:", 5) == 0); - - return g_strdup (uri + 5); -} - -static void -pas_backend_file_process_authenticate_user (PASBackend *backend, - PASBook *book, - PASAuthenticateUserRequest *req) -{ - pas_book_respond_authenticate_user (book, - GNOME_Evolution_Addressbook_BookListener_Success); -} - -static void -pas_backend_file_process_get_supported_fields (PASBackend *backend, - PASBook *book, - PASGetSupportedFieldsRequest *req) -{ - EList *fields = e_list_new ((EListCopyFunc)g_strdup, (EListFreeFunc)g_free, NULL); - ECardSimple *simple; - ECard *card; - int i; - - /* we support everything, so instantiate an e-card, and loop - through all fields, adding their ecard_fields. */ - - card = e_card_new (""); - simple = e_card_simple_new (card); - - for (i = 0; i < E_CARD_SIMPLE_FIELD_LAST; i ++) - e_list_append (fields, e_card_simple_get_ecard_field (simple, i)); - - g_object_unref (card); - g_object_unref (simple); - - pas_book_respond_get_supported_fields (book, - GNOME_Evolution_Addressbook_BookListener_Success, - fields); -} - -/* -** versions: -** -** 0.0 just a list of cards -** -** 0.1 same as 0.0, but with the version tag -** -** 0.2 not a real format upgrade, just a hack to fix broken ids caused -** by a bug in early betas, but we only need to convert them if -** the previous version is 0.1, since the bug existed after 0.1 -** came about. -*/ -static gboolean -pas_backend_file_upgrade_db (PASBackendFile *bf, char *old_version) -{ - DB *db = bf->priv->file_db; - int db_error; - DBT version_name_dbt, version_dbt; - - if (strcmp (old_version, "0.0") - && strcmp (old_version, "0.1")) { - g_warning ("unsupported version '%s' found in PAS backend file\n", - old_version); - return FALSE; - } - - if (!strcmp (old_version, "0.1")) { - /* we just loop through all the cards in the db, - giving them valid ids if they don't have them */ - DBT id_dbt, vcard_dbt; - DBC *dbc; - int card_failed = 0; - - db_error = db->cursor (db, NULL, &dbc, 0); - if (db_error != 0) { - g_warning ("unable to get cursor"); - return FALSE; - } - - memset (&id_dbt, 0, sizeof (id_dbt)); - memset (&vcard_dbt, 0, sizeof (vcard_dbt)); - - db_error = dbc->c_get(dbc, &id_dbt, &vcard_dbt, DB_FIRST); - - while (db_error == 0) { - if (id_dbt.size != strlen(PAS_BACKEND_FILE_VERSION_NAME) + 1 - || strcmp (id_dbt.data, PAS_BACKEND_FILE_VERSION_NAME)) { - ECard *card; - - card = e_card_new (vcard_dbt.data); - - /* the cards we're looking for are - created with a normal id dbt, but - with the id field in the vcard set - to something that doesn't match. - so, we need to modify the card to - have the same id as the the dbt. */ - if (strcmp (id_dbt.data, e_card_get_id (card))) { - char *vcard; - - e_card_set_id (card, id_dbt.data); - - vcard = e_card_get_vcard (card); - string_to_dbt (vcard, &vcard_dbt); - - db_error = db->put (db, NULL, - &id_dbt, &vcard_dbt, 0); - - g_free (vcard); - - if (db_error != 0) - card_failed++; - } - - g_object_unref (card); - } - - db_error = dbc->c_get(dbc, &id_dbt, &vcard_dbt, DB_NEXT); - } - - if (card_failed) { - g_warning ("failed to update %d cards\n", card_failed); - return FALSE; - } - } - - string_to_dbt (PAS_BACKEND_FILE_VERSION_NAME, &version_name_dbt); - string_to_dbt (PAS_BACKEND_FILE_VERSION, &version_dbt); - - db_error = db->put (db, NULL, &version_name_dbt, &version_dbt, 0); - if (db_error == 0) - return TRUE; - else - return FALSE; -} - -static gboolean -pas_backend_file_maybe_upgrade_db (PASBackendFile *bf) -{ - DB *db = bf->priv->file_db; - DBT version_name_dbt, version_dbt; - int db_error; - char *version; - gboolean ret_val = TRUE; - - string_to_dbt (PAS_BACKEND_FILE_VERSION_NAME, &version_name_dbt); - memset (&version_dbt, 0, sizeof (version_dbt)); - - db_error = db->get (db, NULL, &version_name_dbt, &version_dbt, 0); - if (db_error == 0) { - /* success */ - version = g_strdup (version_dbt.data); - } - else { - /* key was not in file */ - version = g_strdup ("0.0"); - } - - if (strcmp (version, PAS_BACKEND_FILE_VERSION)) - ret_val = pas_backend_file_upgrade_db (bf, version); - - g_free (version); - - return ret_val; -} - -#define INITIAL_VCARD "BEGIN:VCARD\n\ -X-EVOLUTION-FILE-AS:Ximian, Inc.\n\ -LABEL;WORK;QUOTED-PRINTABLE:401 Park Drive 3 West=0ABoston, MA 02215=0AUSA\n\ -TEL;WORK;VOICE:(617) 375-3800\n\ -TEL;WORK;FAX:(617) 236-8630\n\ -EMAIL;INTERNET:hello@ximian.com\n\ -URL:www.ximian.com/\n\ -ORG:Ximian, Inc.;\n\ -NOTE:Welcome to the Ximian Addressbook.\n\ -END:VCARD" - -static GNOME_Evolution_Addressbook_BookListener_CallStatus -pas_backend_file_load_uri (PASBackend *backend, - const char *uri) -{ - PASBackendFile *bf = PAS_BACKEND_FILE (backend); - char *filename; - gboolean writable = FALSE; - int db_error; - DB *db; - int major, minor, patch; - time_t db_mtime; - struct stat sb; - char *summary_filename; - - g_free(bf->priv->uri); - bf->priv->uri = g_strdup (uri); - - db_version (&major, &minor, &patch); - - if (major != 3 || - minor != 1 || - patch != 17) { - g_warning ("Wrong version of libdb."); - return GNOME_Evolution_Addressbook_BookListener_OtherError; - } - - filename = pas_backend_file_extract_path_from_uri (uri); - - db_error = e_db3_utils_maybe_recover (filename); - if (db_error != 0) - return GNOME_Evolution_Addressbook_BookListener_OtherError; - - db_error = db_create (&db, NULL, 0); - if (db_error != 0) - return GNOME_Evolution_Addressbook_BookListener_OtherError; - - db_error = db->open (db, filename, NULL, DB_HASH, 0, 0666); - - if (db_error == DB_OLD_VERSION) { - db_error = e_db3_utils_upgrade_format (filename); - - if (db_error != 0) - return GNOME_Evolution_Addressbook_BookListener_OtherError; - - db_error = db->open (db, filename, NULL, DB_HASH, 0, 0666); - } - - bf->priv->file_db = db; - - if (db_error == 0) { - writable = TRUE; - } else { - db_error = db->open (db, filename, NULL, DB_HASH, DB_RDONLY, 0666); - - if (db_error != 0) { - db_error = db->open (db, filename, NULL, DB_HASH, DB_CREATE, 0666); - - if (db_error == 0) { - char *create_initial_file; - char *dir; - - dir = g_path_get_dirname(filename); - create_initial_file = g_build_filename (dir, "create-initial", NULL); - - if (g_file_test(create_initial_file, G_FILE_TEST_EXISTS)) { - char *id; - id = do_create(backend, INITIAL_VCARD, NULL); - g_free (id); - } - - g_free(create_initial_file); - g_free(dir); - - writable = TRUE; - } - } - } - - if (db_error != 0) { - bf->priv->file_db = NULL; - return GNOME_Evolution_Addressbook_BookListener_OtherError; - } - - if (!pas_backend_file_maybe_upgrade_db (bf)) { - db->close (db, 0); - bf->priv->file_db = NULL; - return GNOME_Evolution_Addressbook_BookListener_OtherError; - } - - g_free (bf->priv->filename); - bf->priv->filename = filename; - - if (stat (bf->priv->filename, &sb) == -1) { - db->close (db, 0); - bf->priv->file_db = NULL; - return GNOME_Evolution_Addressbook_BookListener_OtherError; - } - db_mtime = sb.st_mtime; - - summary_filename = g_strconcat (bf->priv->filename, ".summary", NULL); - bf->priv->summary = pas_backend_summary_new (summary_filename, SUMMARY_FLUSH_TIMEOUT); - g_free (summary_filename); - - if (pas_backend_summary_is_up_to_date (bf->priv->summary, db_mtime) == FALSE - || pas_backend_summary_load (bf->priv->summary) == FALSE ) { - build_summary (bf->priv); - } - - pas_backend_set_is_loaded (backend, TRUE); - pas_backend_set_is_writable (backend, writable); - return GNOME_Evolution_Addressbook_BookListener_Success; -} - -/* Get_uri handler for the addressbook file backend */ -static const char * -pas_backend_file_get_uri (PASBackend *backend) -{ - PASBackendFile *bf; - - bf = PAS_BACKEND_FILE (backend); - - g_assert (bf->priv->uri != NULL); - - return bf->priv->uri; -} - -static char * -pas_backend_file_get_static_capabilities (PASBackend *backend) -{ - return g_strdup("local,do-initial-query,bulk-removes"); -} - -static gboolean -pas_backend_file_construct (PASBackendFile *backend) -{ - g_assert (backend != NULL); - g_assert (PAS_IS_BACKEND_FILE (backend)); - - if (! pas_backend_construct (PAS_BACKEND (backend))) - return FALSE; - - return TRUE; -} - -/** - * pas_backend_file_new: - */ -PASBackend * -pas_backend_file_new (void) -{ - PASBackendFile *backend; - - backend = g_object_new (PAS_TYPE_BACKEND_FILE, NULL); - - if (! pas_backend_file_construct (backend)) { - g_object_unref (backend); - - return NULL; - } - - return PAS_BACKEND (backend); -} - -static void -pas_backend_file_dispose (GObject *object) -{ - PASBackendFile *bf; - - bf = PAS_BACKEND_FILE (object); - - if (bf->priv) { - g_object_unref(bf->priv->book_views); - if (bf->priv->summary) - g_object_unref(bf->priv->summary); - g_free (bf->priv->uri); - g_free (bf->priv->filename); - - g_free (bf->priv); - bf->priv = NULL; - } - - G_OBJECT_CLASS (pas_backend_file_parent_class)->dispose (object); -} - -static void -pas_backend_file_class_init (PASBackendFileClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - PASBackendClass *parent_class; - - pas_backend_file_parent_class = g_type_class_peek_parent (klass); - - parent_class = PAS_BACKEND_CLASS (klass); - - /* Set the virtual methods. */ - parent_class->load_uri = pas_backend_file_load_uri; - parent_class->get_uri = pas_backend_file_get_uri; - parent_class->get_static_capabilities = pas_backend_file_get_static_capabilities; - - parent_class->create_card = pas_backend_file_process_create_card; - parent_class->remove_cards = pas_backend_file_process_remove_cards; - parent_class->modify_card = pas_backend_file_process_modify_card; - parent_class->check_connection = pas_backend_file_process_check_connection; - parent_class->get_vcard = pas_backend_file_process_get_vcard; - parent_class->get_cursor = pas_backend_file_process_get_cursor; - parent_class->get_book_view = pas_backend_file_process_get_book_view; - parent_class->get_completion_view = pas_backend_file_process_get_completion_view; - parent_class->get_changes = pas_backend_file_process_get_changes; - parent_class->authenticate_user = pas_backend_file_process_authenticate_user; - parent_class->get_supported_fields = pas_backend_file_process_get_supported_fields; - - object_class->dispose = pas_backend_file_dispose; -} - -static void -pas_backend_file_init (PASBackendFile *backend) -{ - PASBackendFilePrivate *priv; - - priv = g_new0 (PASBackendFilePrivate, 1); - priv->book_views = e_list_new((EListCopyFunc) pas_backend_file_book_view_copy, (EListFreeFunc) pas_backend_file_book_view_free, NULL); - priv->uri = NULL; - - backend->priv = priv; -} - -/** - * pas_backend_file_get_type: - */ -GType -pas_backend_file_get_type (void) -{ - static GType type = 0; - - if (! type) { - GTypeInfo info = { - sizeof (PASBackendFileClass), - NULL, /* base_class_init */ - NULL, /* base_class_finalize */ - (GClassInitFunc) pas_backend_file_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (PASBackendFile), - 0, /* n_preallocs */ - (GInstanceInitFunc) pas_backend_file_init - }; - - type = g_type_register_static (PAS_TYPE_BACKEND, "PASBackendFile", &info, 0); - } - - return type; -} diff --git a/addressbook/backend/pas/pas-backend-file.h b/addressbook/backend/pas/pas-backend-file.h deleted file mode 100644 index fd98d2cdd5..0000000000 --- a/addressbook/backend/pas/pas-backend-file.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright 2000, Ximian, Inc. - */ - -#ifndef __PAS_BACKEND_FILE_H__ -#define __PAS_BACKEND_FILE_H__ - -#include "pas-backend.h" - -#define PAS_TYPE_BACKEND_FILE (pas_backend_file_get_type ()) -#define PAS_BACKEND_FILE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), PAS_TYPE_BACKEND_FILE, PASBackendFile)) -#define PAS_BACKEND_FILE_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), PAS_BACKEND_TYPE, PASBackendFileClass)) -#define PAS_IS_BACKEND_FILE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), PAS_TYPE_BACKEND_FILE)) -#define PAS_IS_BACKEND_FILE_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), PAS_TYPE_BACKEND_FILE)) -#define PAS_BACKEND_FILE_GET_CLASS(k) (G_TYPE_INSTANCE_GET_CLASS ((obj), PAS_TYPE_BACKEND_FILE, PASBackendFileClass)) - -typedef struct _PASBackendFilePrivate PASBackendFilePrivate; - -typedef struct { - PASBackend parent_object; - PASBackendFilePrivate *priv; -} PASBackendFile; - -typedef struct { - PASBackendClass parent_class; -} PASBackendFileClass; - -PASBackend *pas_backend_file_new (void); -GType pas_backend_file_get_type (void); - -#endif /* ! __PAS_BACKEND_FILE_H__ */ - diff --git a/addressbook/backend/pas/pas-backend-ldap.c b/addressbook/backend/pas/pas-backend-ldap.c deleted file mode 100644 index 1e8677e559..0000000000 --- a/addressbook/backend/pas/pas-backend-ldap.c +++ /dev/null @@ -1,3555 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * Author: - * Chris Toshok (toshok@ximian.com) - * - * Copyright 2000, Ximian, Inc. - */ - -#define DEBUG - -#include "config.h" -#include <fcntl.h> -#include <string.h> - -#ifdef DEBUG -#define LDAP_DEBUG -#define LDAP_DEBUG_ADD -#endif -#include <ldap.h> -#ifdef DEBUG -#undef LDAP_DEBUG -#endif - -#if LDAP_VENDOR_VERSION > 20000 -#define OPENLDAP2 -#else -#define OPENLDAP1 -#endif - -#ifdef OPENLDAP2 -#include <ldap_schema.h> -#endif - -#include <sys/time.h> - -#include <e-util/e-sexp.h> -#include <ebook/e-card-simple.h> -#include <libgnome/gnome-i18n.h> - -#include "pas-backend-ldap.h" -#include "pas-backend-card-sexp.h" -#include "pas-book.h" -#include "pas-card-cursor.h" - -#include <stdlib.h> - -/* this is broken currently, don't enable it */ -/*#define ENABLE_SASL_BINDS*/ - -typedef enum { - PAS_BACKEND_LDAP_TLS_NO, - PAS_BACKEND_LDAP_TLS_ALWAYS, - PAS_BACKEND_LDAP_TLS_WHEN_POSSIBLE, -} PASBackendLDAPUseTLS; - -/* interval for our poll_ldap timeout */ -#define LDAP_POLL_INTERVAL 20 - -/* timeout for ldap_result */ -#define LDAP_RESULT_TIMEOUT_MILLIS 10 - -/* smart grouping stuff */ -#define GROUPING_INITIAL_SIZE 1 -#define GROUPING_MAXIMUM_SIZE 200 - -/* the next two are in milliseconds */ -#define GROUPING_MINIMUM_WAIT 0 /* we never send updates faster than this, to avoid totally spamming the UI */ -#define GROUPING_MAXIMUM_WAIT 250 /* we always send updates (if there are pending cards) when we hit this */ - -#define TV_TO_MILLIS(timeval) ((timeval).tv_sec * 1000 + (timeval).tv_usec / 1000) - -/* the objectClasses we need */ -#define TOP "top" -#define PERSON "person" -#define ORGANIZATIONALPERSON "organizationalPerson" -#define INETORGPERSON "inetOrgPerson" -#define CALENTRY "calEntry" -#define EVOLUTIONPERSON "evolutionPerson" - -static gchar *query_prop_to_ldap(gchar *query_prop); - -static PASBackendClass *pas_backend_ldap_parent_class; -typedef struct _PASBackendLDAPCursorPrivate PASBackendLDAPCursorPrivate; -typedef struct _PASBackendLDAPBookView PASBackendLDAPBookView; -typedef struct LDAPOp LDAPOp; - - -struct _PASBackendLDAPPrivate { - char *uri; - gboolean connected; - - gchar *ldap_host; /* the hostname of the server */ - int ldap_port; /* the port of the server */ - char *schema_dn; /* the base dn for schema information */ - gchar *ldap_rootdn; /* the base dn of our searches */ - int ldap_scope; /* the scope used for searches */ - int ldap_limit; /* the search limit */ - int ldap_timeout; /* the search timeout */ - - gchar *auth_dn; - gchar *auth_passwd; - - gboolean ldap_v3; /* TRUE if the server supports protocol - revision 3 (necessary for TLS) */ - gboolean starttls; /* TRUE if the *library* supports - starttls. will be false if openssl - was not built into openldap. */ - PASBackendLDAPUseTLS use_tls; - - EList *book_views; - - LDAP *ldap; - - EList *supported_fields; - EList *supported_auth_methods; - - /* whether or not there's support for the objectclass we need - to store all our additional fields */ - gboolean evolutionPersonSupported; - gboolean calEntrySupported; - gboolean evolutionPersonChecked; - - /* our operations */ - GHashTable *id_to_op; - int active_ops; - int poll_timeout; -}; - -struct _PASBackendLDAPCursorPrivate { - PASBackend *backend; - PASBook *book; - - GList *elements; - long num_elements; -}; - -struct _PASBackendLDAPBookView { - PASBookView *book_view; - PASBackendLDAPPrivate *blpriv; - gchar *search; - PASBackendCardSExp *card_sexp; - int limit; - - LDAPOp *search_op; -}; - -typedef void (*LDAPOpHandler)(LDAPOp *op, LDAPMessage *res); -typedef void (*LDAPOpDtor)(LDAPOp *op); - -struct LDAPOp { - LDAPOpHandler handler; - LDAPOpDtor dtor; - PASBackend *backend; - PASBook *book; - PASBookView *view; - int id; -}; - -static void ldap_op_add (LDAPOp *op, PASBackend *backend, PASBook *book, - PASBookView *view, int id, LDAPOpHandler handler, LDAPOpDtor dtor); -static void ldap_op_finished (LDAPOp *op); - -static void ldap_search_op_timeout (LDAPOp *op, glong cur_millis); - -static gboolean poll_ldap (PASBackendLDAP *bl); - -static ECardSimple *build_card_from_entry (LDAP *ldap, LDAPMessage *e, GList **existing_objectclasses); - -static void email_populate (ECardSimple *card, char **values); -struct berval** email_ber (ECardSimple *card); -static gboolean email_compare (ECardSimple *ecard1, ECardSimple *ecard2); - -static void homephone_populate (ECardSimple *card, char **values); -struct berval** homephone_ber (ECardSimple *card); -static gboolean homephone_compare (ECardSimple *ecard1, ECardSimple *ecard2); - -static void business_populate (ECardSimple *card, char **values); -struct berval** business_ber (ECardSimple *card); -static gboolean business_compare (ECardSimple *ecard1, ECardSimple *ecard2); - -static void anniversary_populate (ECardSimple *card, char **values); -struct berval** anniversary_ber (ECardSimple *card); -static gboolean anniversary_compare (ECardSimple *ecard1, ECardSimple *ecard2); - -static void birthday_populate (ECardSimple *card, char **values); -struct berval** birthday_ber (ECardSimple *card); -static gboolean birthday_compare (ECardSimple *ecard1, ECardSimple *ecard2); - -static void category_populate (ECardSimple *card, char **values); -struct berval** category_ber (ECardSimple *card); -static gboolean category_compare (ECardSimple *ecard1, ECardSimple *ecard2); - -struct prop_info { - ECardSimpleField field_id; - char *query_prop; - char *ldap_attr; -#define PROP_TYPE_STRING 0x01 -#define PROP_TYPE_COMPLEX 0x02 -#define PROP_DN 0x04 -#define PROP_EVOLVE 0x08 - int prop_type; - - /* the remaining items are only used for the TYPE_COMPLEX props */ - - /* used when reading from the ldap server populates ECard with the values in **values. */ - void (*populate_ecard_func)(ECardSimple *card, char **values); - /* used when writing to an ldap server. returns a NULL terminated array of berval*'s */ - struct berval** (*ber_func)(ECardSimple *card); - /* used to compare list attributes */ - gboolean (*compare_func)(ECardSimple *card1, ECardSimple *card2); - -} prop_info[] = { - -#define COMPLEX_PROP(fid,q,a,ctor,ber,cmp) {fid, q, a, PROP_TYPE_COMPLEX, ctor, ber, cmp} -#define E_COMPLEX_PROP(fid,q,a,ctor,ber,cmp) {fid, q, a, PROP_TYPE_COMPLEX | PROP_EVOLVE, ctor, ber, cmp} -#define STRING_PROP(fid,q,a) {fid, q, a, PROP_TYPE_STRING} -#define E_STRING_PROP(fid,q,a) {fid, q, a, PROP_TYPE_STRING | PROP_EVOLVE} - - - /* name fields */ - STRING_PROP (E_CARD_SIMPLE_FIELD_FULL_NAME, "full_name", "cn" ), - STRING_PROP (E_CARD_SIMPLE_FIELD_FAMILY_NAME, "family_name", "sn" ), - - /* email addresses */ - COMPLEX_PROP (E_CARD_SIMPLE_FIELD_EMAIL, "email", "mail", email_populate, email_ber, email_compare), - - /* phone numbers */ - E_STRING_PROP (E_CARD_SIMPLE_FIELD_PHONE_PRIMARY, "primary_phone", "primaryPhone"), - COMPLEX_PROP (E_CARD_SIMPLE_FIELD_PHONE_BUSINESS, "business_phone", "telephoneNumber", business_populate, business_ber, business_compare), - COMPLEX_PROP (E_CARD_SIMPLE_FIELD_PHONE_HOME, "home_phone", "homePhone", homephone_populate, homephone_ber, homephone_compare), - STRING_PROP (E_CARD_SIMPLE_FIELD_PHONE_MOBILE, "mobile_phone", "mobile"), - E_STRING_PROP (E_CARD_SIMPLE_FIELD_PHONE_CAR, "car_phone", "carPhone"), - STRING_PROP (E_CARD_SIMPLE_FIELD_PHONE_BUSINESS_FAX, "business_fax", "facsimileTelephoneNumber"), - E_STRING_PROP (E_CARD_SIMPLE_FIELD_PHONE_HOME_FAX, "home_fax", "homeFacsimileTelephoneNumber"), - E_STRING_PROP (E_CARD_SIMPLE_FIELD_PHONE_OTHER, "other_phone", "otherPhone"), - E_STRING_PROP (E_CARD_SIMPLE_FIELD_PHONE_OTHER_FAX, "other_fax", "otherFacsimileTelephoneNumber"), - STRING_PROP (E_CARD_SIMPLE_FIELD_PHONE_ISDN, "isdn", "internationaliSDNNumber"), - STRING_PROP (E_CARD_SIMPLE_FIELD_PHONE_PAGER, "pager", "pager"), - E_STRING_PROP (E_CARD_SIMPLE_FIELD_PHONE_RADIO, "radio", "radio"), - E_STRING_PROP (E_CARD_SIMPLE_FIELD_PHONE_TELEX, "telex", "telex"), - E_STRING_PROP (E_CARD_SIMPLE_FIELD_PHONE_ASSISTANT, "assistant_phone", "assistantPhone"), - E_STRING_PROP (E_CARD_SIMPLE_FIELD_PHONE_COMPANY, "company_phone", "companyPhone"), - E_STRING_PROP (E_CARD_SIMPLE_FIELD_PHONE_CALLBACK, "callback_phone", "callbackPhone"), - E_STRING_PROP (E_CARD_SIMPLE_FIELD_PHONE_TTYTDD, "tty", "tty"), - - /* org information */ - STRING_PROP (E_CARD_SIMPLE_FIELD_ORG, "org", "o"), - STRING_PROP (E_CARD_SIMPLE_FIELD_ORG_UNIT, "org_unit", "ou"), - STRING_PROP (E_CARD_SIMPLE_FIELD_OFFICE, "office", "roomNumber"), - STRING_PROP (E_CARD_SIMPLE_FIELD_TITLE, "title", "title"), - E_STRING_PROP (E_CARD_SIMPLE_FIELD_ROLE, "role", "businessRole"), - E_STRING_PROP (E_CARD_SIMPLE_FIELD_MANAGER, "manager", "managerName"), - E_STRING_PROP (E_CARD_SIMPLE_FIELD_ASSISTANT, "assistant", "assistantName"), - - /* addresses */ - STRING_PROP (E_CARD_SIMPLE_FIELD_ADDRESS_BUSINESS, "business_address", "postalAddress"), - STRING_PROP (E_CARD_SIMPLE_FIELD_ADDRESS_HOME, "home_address", "homePostalAddress"), - E_STRING_PROP (E_CARD_SIMPLE_FIELD_ADDRESS_OTHER, "other_address", "otherPostalAddress"), - - /* misc fields */ - STRING_PROP (E_CARD_SIMPLE_FIELD_URL, "url", "labeledURI"), - /* map nickname to displayName */ - STRING_PROP (E_CARD_SIMPLE_FIELD_NICKNAME, "nickname", "displayName"), - E_STRING_PROP (E_CARD_SIMPLE_FIELD_SPOUSE, "spouse", "spouseName"), - E_STRING_PROP (E_CARD_SIMPLE_FIELD_NOTE, "note", "note"), - E_COMPLEX_PROP (E_CARD_SIMPLE_FIELD_ANNIVERSARY, "anniversary", "anniversary", anniversary_populate, anniversary_ber, anniversary_compare), - E_COMPLEX_PROP (E_CARD_SIMPLE_FIELD_BIRTH_DATE, "birth_date", "birthDate", birthday_populate, birthday_ber, birthday_compare), - E_STRING_PROP (E_CARD_SIMPLE_FIELD_MAILER, "mailer", "mailer"), - - E_STRING_PROP (E_CARD_SIMPLE_FIELD_FILE_AS, "file_as", "fileAs"), - E_COMPLEX_PROP (E_CARD_SIMPLE_FIELD_CATEGORIES, "categories", "category", category_populate, category_ber, category_compare), - - STRING_PROP (E_CARD_SIMPLE_FIELD_CALURI, "caluri", "calCalURI"), - STRING_PROP (E_CARD_SIMPLE_FIELD_FBURL, "fburl", "calFBURL"), - STRING_PROP (E_CARD_SIMPLE_FIELD_ICSCALENDAR, "icscalendar", "icsCalendar"), - -/* E_CARD_SIMPLE_FIELD_NAME_OR_ORG, */ - - -#undef E_STRING_PROP -#undef STRING_PROP -#undef E_COMPLEX_PROP -#undef COMPLEX_PROP -}; - -static int num_prop_infos = sizeof(prop_info) / sizeof(prop_info[0]); - -static void -remove_view (int msgid, LDAPOp *op, PASBookView *view) -{ - if (op->view == view) - op->view = NULL; -} - -static void -view_destroy(gpointer data, GObject *where_object_was) -{ - PASBook *book = (PASBook *)data; - PASBackendLDAP *bl; - EIterator *iter; - - bl = PAS_BACKEND_LDAP(pas_book_get_backend(book)); - - iter = e_list_get_iterator (bl->priv->book_views); - - while (e_iterator_is_valid (iter)) { - PASBackendLDAPBookView *view = (PASBackendLDAPBookView*)e_iterator_get (iter); - - if (view->book_view == (PASBookView*)where_object_was) { - GNOME_Evolution_Addressbook_Book corba_book; - CORBA_Environment ev; - - /* if we have an active search, interrupt it */ - if (view->search_op) { - ldap_op_finished (view->search_op); - } - /* and remove us as the view for any other - operations that might be using us to spew - status messages to the gui */ - g_hash_table_foreach (bl->priv->id_to_op, (GHFunc)remove_view, view->book_view); - - /* free up the view structure */ - g_free (view->search); - g_object_unref (view->card_sexp); - g_free (view); - - /* and remove it from our list */ - e_iterator_delete (iter); - - /* unref the book now */ - corba_book = bonobo_object_corba_objref(BONOBO_OBJECT(book)); - - CORBA_exception_init(&ev); - - GNOME_Evolution_Addressbook_Book_unref(corba_book, &ev); - - if (ev._major != CORBA_NO_EXCEPTION) { - g_warning("view_destroy: Exception unreffing " - "corba book.\n"); - } - - CORBA_exception_free(&ev); - break; - } - - e_iterator_next (iter); - } - - g_object_unref (iter); - -} - -static void -book_view_notify_status (PASBookView *view, const char *status) -{ - if (!view) - return; - pas_book_view_notify_status_message (view, status); -} - -static PASBookView* -find_book_view (PASBackendLDAP *bl) -{ - EIterator *iter = e_list_get_iterator (bl->priv->book_views); - PASBookView *rv = NULL; - - if (e_iterator_is_valid (iter)) { - /* just always use the first book view */ - PASBackendLDAPBookView *v = (PASBackendLDAPBookView*)e_iterator_get(iter); - if (v) - rv = v->book_view; - } - - g_object_unref (iter); - - return rv; -} - -static void -add_to_supported_fields (PASBackendLDAP *bl, char **attrs, GHashTable *attr_hash) -{ - int i; - for (i = 0; attrs[i]; i ++) { - char *query_prop = g_hash_table_lookup (attr_hash, attrs[i]); - - if (query_prop) { - e_list_append (bl->priv->supported_fields, query_prop); - - /* handle the list attributes here */ - if (!strcmp (query_prop, "email")) { - e_list_append (bl->priv->supported_fields, "email_2"); - e_list_append (bl->priv->supported_fields, "email_3"); - } - else if (!strcmp (query_prop, "business_phone")) { - e_list_append (bl->priv->supported_fields, "business_phone_2"); - } - else if (!strcmp (query_prop, "home_phone")) { - e_list_append (bl->priv->supported_fields, "home_phone_2"); - } - } - } -} - -static void -add_oc_attributes_to_supported_fields (PASBackendLDAP *bl, LDAPObjectClass *oc) -{ - int i; - GHashTable *attr_hash = g_hash_table_new (g_str_hash, g_str_equal); - - for (i = 0; i < num_prop_infos; i ++) - g_hash_table_insert (attr_hash, prop_info[i].ldap_attr, prop_info[i].query_prop); - - if (oc->oc_at_oids_must) - add_to_supported_fields (bl, oc->oc_at_oids_must, attr_hash); - - if (oc->oc_at_oids_may) - add_to_supported_fields (bl, oc->oc_at_oids_may, attr_hash); - - g_hash_table_destroy (attr_hash); -} - -static void -check_schema_support (PASBackendLDAP *bl) -{ - char *attrs[2]; - LDAPMessage *resp; - LDAP *ldap = bl->priv->ldap; - struct timeval timeout; - - if (!bl->priv->schema_dn) - return; - - bl->priv->evolutionPersonChecked = TRUE; - - attrs[0] = "objectClasses"; - attrs[1] = NULL; - - timeout.tv_sec = 30; - timeout.tv_usec = 0; - - if (ldap_search_ext_s (ldap, bl->priv->schema_dn, LDAP_SCOPE_BASE, - "(objectClass=subschema)", attrs, 0, - NULL, NULL, &timeout, LDAP_NO_LIMIT, &resp) == LDAP_SUCCESS) { - char **values; - - values = ldap_get_values (ldap, resp, "objectClasses"); - - if (values) { - int i; - for (i = 0; values[i]; i ++) { - int j; - int code; - const char *err; - LDAPObjectClass *oc = ldap_str2objectclass (values[i], &code, &err, 0); - - if (!oc) - continue; - - for (j = 0; oc->oc_names[j]; j++) - if (!g_ascii_strcasecmp (oc->oc_names[j], EVOLUTIONPERSON)) { - g_print ("support found on ldap server for objectclass evolutionPerson\n"); - bl->priv->evolutionPersonSupported = TRUE; - - add_oc_attributes_to_supported_fields (bl, oc); - } - else if (!g_ascii_strcasecmp (oc->oc_names[j], CALENTRY)) { - g_print ("support found on ldap server for objectclass calEntry\n"); - bl->priv->calEntrySupported = TRUE; - add_oc_attributes_to_supported_fields (bl, oc); - } - else if (!g_ascii_strcasecmp (oc->oc_names[j], INETORGPERSON) - || !g_ascii_strcasecmp (oc->oc_names[j], ORGANIZATIONALPERSON) - || !g_ascii_strcasecmp (oc->oc_names[j], PERSON)) { - add_oc_attributes_to_supported_fields (bl, oc); - } - - ldap_objectclass_free (oc); - } - - ldap_value_free (values); - } - else { - /* the reason for this is so that if the user - ends up authenticating to the ldap server, - we will requery for the subschema values. - This makes it a bit more robust in the face - of draconian acl's that keep subschema - reads from working until the user is - authed. */ - if (!pas_backend_is_writable (PAS_BACKEND (bl))) { - g_warning ("subschema read returned nothing before successful auth"); - bl->priv->evolutionPersonChecked = FALSE; - } - else { - g_warning ("subschema read returned nothing after successful auth"); - } - } - - ldap_msgfree (resp); - } -} - -static void -get_ldap_library_info () -{ - LDAPAPIInfo info; - LDAP *ldap; - - if (LDAP_SUCCESS != ldap_create (&ldap)) { - g_warning ("couldn't create LDAP* for getting at the client lib api info"); - return; - } - - info.ldapai_info_version = LDAP_API_INFO_VERSION; - - if (LDAP_OPT_SUCCESS != ldap_get_option (ldap, LDAP_OPT_API_INFO, &info)) { - g_warning ("couldn't get ldap api info"); - } - else { - int i; - g_message ("libldap vendor/version: %s %2d.%02d.%02d", - info.ldapai_vendor_name, - info.ldapai_vendor_version / 10000, - (info.ldapai_vendor_version % 10000) / 1000, - info.ldapai_vendor_version % 1000); - - g_message ("extensions present:"); - /* yuck. we have to free these? */ - for (i = 0; info.ldapai_extensions[i]; i++) { - char *extension = info.ldapai_extensions[i]; - g_message (extension); - ldap_memfree (extension); - } - ldap_memfree (info.ldapai_extensions); - ldap_memfree (info.ldapai_vendor_name); - } - - ldap_unbind_ext_s (ldap, NULL, NULL); -} - -static int -query_ldap_root_dse (PASBackendLDAP *bl) -{ -#define MAX_DSE_ATTRS 20 - LDAP *ldap = bl->priv->ldap; - LDAPMessage *resp; - int ldap_error; - char *attrs[MAX_DSE_ATTRS], **values; - int i = 0; - struct timeval timeout; - - attrs[i++] = "supportedControl"; - attrs[i++] = "supportedExtension"; - attrs[i++] = "supportedFeatures"; - attrs[i++] = "supportedSASLMechanisms"; - attrs[i++] = "supportedLDAPVersion"; - attrs[i++] = "subschemaSubentry"; /* OpenLDAP's dn for schema information */ - attrs[i++] = "schemaNamingContext"; /* Active directory's dn for schema information */ - attrs[i] = NULL; - - timeout.tv_sec = 30; - timeout.tv_usec = 0; - - ldap_error = ldap_search_ext_s (ldap, - LDAP_ROOT_DSE, LDAP_SCOPE_BASE, - "(objectclass=*)", - attrs, 0, NULL, NULL, &timeout, LDAP_NO_LIMIT, &resp); - if (ldap_error != LDAP_SUCCESS) { - g_warning ("could not perform query on Root DSE (ldap_error 0x%02x)", ldap_error); - return ldap_error; - } - - values = ldap_get_values (ldap, resp, "supportedControl"); - if (values) { - for (i = 0; values[i]; i++) - g_message ("supported server control: %s", values[i]); - ldap_value_free (values); - } - - values = ldap_get_values (ldap, resp, "supportedExtension"); - if (values) { - for (i = 0; values[i]; i++) { - g_message ("supported server extension: %s", values[i]); - if (!strcmp (values[i], LDAP_EXOP_START_TLS)) { - g_message ("server reports LDAP_EXOP_START_TLS"); - } - } - ldap_value_free (values); - } - - values = ldap_get_values (ldap, resp, "supportedSASLMechanisms"); - if (values) { - char *auth_method; - if (bl->priv->supported_auth_methods) - g_object_unref (bl->priv->supported_auth_methods); - bl->priv->supported_auth_methods = e_list_new ((EListCopyFunc)g_strdup, (EListFreeFunc)g_free, NULL); - - auth_method = g_strdup_printf ("ldap/simple-binddn|%s", _("Using Distinguished Name (DN)")); - e_list_append (bl->priv->supported_auth_methods, auth_method); - g_free (auth_method); - - auth_method = g_strdup_printf ("ldap/simple-email|%s", _("Using Email Address")); - e_list_append (bl->priv->supported_auth_methods, auth_method); - g_free (auth_method); - - for (i = 0; values[i]; i++) { - auth_method = g_strdup_printf ("sasl/%s|%s", values[i], values[i]); - e_list_append (bl->priv->supported_auth_methods, auth_method); - g_free (auth_method); - g_message ("supported SASL mechanism: %s", values[i]); - } - ldap_value_free (values); - } - - - values = ldap_get_values (ldap, resp, "subschemaSubentry"); - if (!values || !values[0]) { - if (values) ldap_value_free (values); - values = ldap_get_values (ldap, resp, "schemaNamingContext"); - } - if (values && values[0]) { - g_free (bl->priv->schema_dn); - bl->priv->schema_dn = g_strdup (values[0]); - } - else { - g_warning ("could not determine location of schema information on LDAP server"); - } - if (values) - ldap_value_free (values); - - ldap_msgfree (resp); - - return LDAP_SUCCESS; -} - -static GNOME_Evolution_Addressbook_BookListener_CallStatus -pas_backend_ldap_connect (PASBackendLDAP *bl) -{ - PASBackendLDAPPrivate *blpriv = bl->priv; - - /* close connection first if it's open first */ - if (blpriv->ldap) - ldap_unbind_ext (blpriv->ldap, NULL, NULL); - - blpriv->ldap = ldap_init (blpriv->ldap_host, blpriv->ldap_port); -#if defined (DEBUG) && defined (LDAP_OPT_DEBUG_LEVEL) - { - int debug_level = 4; - ldap_set_option (blpriv->ldap, LDAP_OPT_DEBUG_LEVEL, &debug_level); - } -#endif - - if (NULL != blpriv->ldap) { - int ldap_error; - - if (bl->priv->use_tls != PAS_BACKEND_LDAP_TLS_NO) { - int protocol_version = LDAP_VERSION3; - ldap_error = ldap_set_option (blpriv->ldap, LDAP_OPT_PROTOCOL_VERSION, &protocol_version); - if (LDAP_OPT_SUCCESS != ldap_error) { - g_warning ("failed to set protocol version to LDAPv3"); - bl->priv->ldap_v3 = FALSE; - } - else - bl->priv->ldap_v3 = TRUE; - - if (!bl->priv->ldap_v3 && bl->priv->use_tls == PAS_BACKEND_LDAP_TLS_ALWAYS) { - g_message ("TLS not available (fatal version), v3 protocol could not be established (ldap_error 0x%02x)", ldap_error); - ldap_unbind (blpriv->ldap); - blpriv->ldap = NULL; - return GNOME_Evolution_Addressbook_BookListener_TLSNotAvailable; - } - - if (bl->priv->ldap_port == LDAPS_PORT && bl->priv->use_tls == PAS_BACKEND_LDAP_TLS_ALWAYS) { - int tls_level = LDAP_OPT_X_TLS_HARD; - ldap_set_option (blpriv->ldap, LDAP_OPT_X_TLS, &tls_level); - } - else if (bl->priv->use_tls) { - ldap_error = ldap_start_tls_s (blpriv->ldap, NULL, NULL); - if (LDAP_SUCCESS != ldap_error) { - if (bl->priv->use_tls == PAS_BACKEND_LDAP_TLS_ALWAYS) { - g_message ("TLS not available (fatal version), (ldap_error 0x%02x)", ldap_error); - ldap_unbind (blpriv->ldap); - blpriv->ldap = NULL; - return GNOME_Evolution_Addressbook_BookListener_TLSNotAvailable; - } - else { - g_message ("TLS not available (ldap_error 0x%02x)", ldap_error); - } - } - else - g_message ("TLS active"); - } - } - - /* bind anonymously initially, we'll actually - authenticate the user properly later (in - authenticate_user) if they've selected - authentication */ - ldap_error = ldap_simple_bind_s (blpriv->ldap, NULL, NULL); - if (ldap_error == LDAP_SERVER_DOWN) { - /* we only want this to be fatal if the server is down. */ - g_warning ("failed to bind anonymously while connecting (ldap_error 0x%02x)", ldap_error); - return GNOME_Evolution_Addressbook_BookListener_RepositoryOffline; - } - - ldap_error = query_ldap_root_dse (bl); - /* query_ldap_root_dse will cause the actual - connect(), so any tcpip problems will show up - here */ - - /* we can't just check for LDAP_SUCCESS here since in - older servers (namely openldap1.x servers), there's - not a root DSE at all, so the query will fail with - LDAP_NO_SUCH_OBJECT. */ - if (ldap_error == LDAP_SUCCESS || LDAP_NAME_ERROR (ldap_error)) { - blpriv->connected = TRUE; - - /* check to see if evolutionPerson is supported, if we can (me - might not be able to if we can't authenticate. if we - can't, try again in auth_user.) */ - if (!bl->priv->evolutionPersonChecked) - check_schema_support (bl); - - pas_backend_set_is_loaded (PAS_BACKEND (bl), TRUE); - return GNOME_Evolution_Addressbook_BookListener_Success; - } - else - g_warning ("Failed to perform root dse query anonymously, (ldap_error 0x%02x)", ldap_error); - } - - g_warning ("pas_backend_ldap_connect failed for " - "'ldap://%s:%d/%s'\n", - blpriv->ldap_host, - blpriv->ldap_port, - blpriv->ldap_rootdn ? blpriv->ldap_rootdn : ""); - blpriv->connected = FALSE; - return GNOME_Evolution_Addressbook_BookListener_RepositoryOffline; -} - -static gboolean -pas_backend_ldap_reconnect (PASBackendLDAP *bl, PASBookView *book_view, int ldap_status) -{ - /* we need to reconnect if we were previously connected */ - if (bl->priv->connected && ldap_status == LDAP_SERVER_DOWN) { - GNOME_Evolution_Addressbook_BookListener_CallStatus status; - int ldap_error = LDAP_SUCCESS; - - book_view_notify_status (book_view, _("Reconnecting to LDAP server...")); - - status = pas_backend_ldap_connect (bl); - - if (status != GNOME_Evolution_Addressbook_BookListener_Success) { - book_view_notify_status (book_view, ""); - return FALSE; - } - - if (bl->priv->auth_dn) - ldap_error = ldap_simple_bind_s(bl->priv->ldap, - bl->priv->auth_dn, - bl->priv->auth_passwd); - book_view_notify_status (book_view, ""); - return (ldap_error == LDAP_SUCCESS); - } - else { - return FALSE; - } -} - -static void -ldap_op_add (LDAPOp *op, PASBackend *backend, - PASBook *book, PASBookView *view, - int id, - LDAPOpHandler handler, LDAPOpDtor dtor) -{ - PASBackendLDAP *bl = PAS_BACKEND_LDAP (backend); - - op->backend = backend; - op->book = book; - op->view = view; - op->id = id; - op->handler = handler; - op->dtor = dtor; - - if (g_hash_table_lookup (bl->priv->id_to_op, &op->id)) { - g_warning ("conflicting ldap msgid's"); - } - - g_hash_table_insert (bl->priv->id_to_op, - &op->id, op); - - bl->priv->active_ops ++; - - if (bl->priv->poll_timeout == -1) - bl->priv->poll_timeout = g_timeout_add (LDAP_POLL_INTERVAL, - (GSourceFunc) poll_ldap, - bl); -} - -static void -ldap_op_finished (LDAPOp *op) -{ - PASBackend *backend = op->backend; - PASBackendLDAP *bl = PAS_BACKEND_LDAP (backend); - - g_hash_table_remove (bl->priv->id_to_op, &op->id); - - /* should handle errors here */ - ldap_abandon (bl->priv->ldap, op->id); - - op->dtor (op); - - bl->priv->active_ops--; - - if (bl->priv->active_ops == 0) { - if (bl->priv->poll_timeout != -1) - g_source_remove (bl->priv->poll_timeout); - bl->priv->poll_timeout = -1; - } -} - -static void -ldap_op_change_id (LDAPOp *op, int msg_id) -{ - PASBackend *backend = op->backend; - PASBackendLDAP *bl = PAS_BACKEND_LDAP (backend); - - g_hash_table_remove (bl->priv->id_to_op, &op->id); - - op->id = msg_id; - - g_hash_table_insert (bl->priv->id_to_op, - &op->id, op); -} - -static int -ldap_error_to_response (int ldap_error) -{ - if (ldap_error == LDAP_SUCCESS) - return GNOME_Evolution_Addressbook_BookListener_Success; - else if (LDAP_NAME_ERROR (ldap_error)) - return GNOME_Evolution_Addressbook_BookListener_CardNotFound; - else if (ldap_error == LDAP_INSUFFICIENT_ACCESS) - return GNOME_Evolution_Addressbook_BookListener_PermissionDenied; - else if (ldap_error == LDAP_SERVER_DOWN) - return GNOME_Evolution_Addressbook_BookListener_RepositoryOffline; - else if (ldap_error == LDAP_ALREADY_EXISTS) - return GNOME_Evolution_Addressbook_BookListener_CardIdAlreadyExists; - else - return GNOME_Evolution_Addressbook_BookListener_OtherError; -} - - -static char * -create_dn_from_ecard (ECardSimple *card, const char *root_dn) -{ - char *cn, *cn_part = NULL; - char *dn; - - cn = e_card_simple_get (card, E_CARD_SIMPLE_FIELD_FULL_NAME); - if (cn) { - if (strchr (cn, ',')) { - /* need to escape commas */ - char *new_cn = g_malloc0 (strlen (cn) * 3 + 1); - int i, j; - - for (i = 0, j = 0; i < strlen (cn); i ++) { - if (cn[i] == ',') { - sprintf (new_cn + j, "%%%02X", cn[i]); - j += 3; - } - else { - new_cn[j++] = cn[i]; - } - } - cn_part = g_strdup_printf ("cn=%s", new_cn); - g_free (new_cn); - } - else { - cn_part = g_strdup_printf ("cn=%s", cn); - } - } - else { - cn_part = g_strdup (""); - } - - dn = g_strdup_printf ("%s%s%s", cn_part, - (root_dn && strlen(root_dn)) ? "," : "", - (root_dn && strlen(root_dn)) ? root_dn: ""); - - g_free (cn_part); - - g_print ("generated dn: %s\n", dn); - - return dn; -} - -static void -free_mods (GPtrArray *mods) -{ - int i = 0; - LDAPMod *mod; - - while ((mod = g_ptr_array_index (mods, i++))) { - int j; - g_free (mod->mod_type); - - if (mod->mod_op & LDAP_MOD_BVALUES) { - for (j = 0; mod->mod_bvalues[j]; j++) { - g_free (mod->mod_bvalues[j]->bv_val); - g_free (mod->mod_bvalues[j]); - } - } - else { - for (j = 0; mod->mod_values[j]; j++) - g_free (mod->mod_values[j]); - } - g_free (mod); - } - - g_ptr_array_free (mods, TRUE); -} - -static GPtrArray* -build_mods_from_ecards (PASBackendLDAP *bl, ECardSimple *current, ECardSimple *new, gboolean *new_dn_needed) -{ - gboolean adding = (current == NULL); - GPtrArray *result = g_ptr_array_new(); - int i; - - if (new_dn_needed) - *new_dn_needed = FALSE; - - /* we walk down the list of properties we can deal with (that - big table at the top of the file) */ - - for (i = 0; i < num_prop_infos; i ++) { - gboolean include; - gboolean new_prop_present = FALSE; - gboolean current_prop_present = FALSE; - struct berval** new_prop_bers = NULL; - char *new_prop = NULL; - char *current_prop = NULL; - - /* XXX if it's an evolutionPerson prop and the ldap - server doesn't support that objectclass, skip it. */ - if (prop_info[i].prop_type & PROP_EVOLVE && !bl->priv->evolutionPersonSupported) - continue; - - /* get the value for the new card, and compare it to - the value in the current card to see if we should - update it -- if adding is TRUE, short circuit the - check. */ - if (prop_info[i].prop_type & PROP_TYPE_STRING) { - new_prop = e_card_simple_get (new, prop_info[i].field_id); - new_prop_present = (new_prop != NULL); - } - else { - new_prop_bers = prop_info[i].ber_func (new); - new_prop_present = (new_prop_bers != NULL); - } - - /* need to set INCLUDE to true if the field needs to - show up in the ldap modify request */ - if (adding) { - /* if we're creating a new card, include it if the - field is there at all */ - if (prop_info[i].prop_type & PROP_TYPE_STRING) - include = (new_prop_present && *new_prop); /* empty strings cause problems */ - else - include = new_prop_present; - } - else { - /* if we're modifying an existing card, - include it if the current field value is - different than the new one, if it didn't - exist previously, or if it's been - removed. */ - if (prop_info[i].prop_type & PROP_TYPE_STRING) { - current_prop = e_card_simple_get (current, prop_info[i].field_id); - current_prop_present = (current_prop != NULL); - - if (new_prop && current_prop) - include = *new_prop && strcmp (new_prop, current_prop); - else - include = (!!new_prop != !!current_prop); - } - else { - int j; - struct berval **current_prop_bers = prop_info[i].ber_func (current); - - current_prop_present = (current_prop_bers != NULL); - - /* free up the current_prop_bers */ - if (current_prop_bers) { - for (j = 0; current_prop_bers[j]; j++) { - g_free (current_prop_bers[j]->bv_val); - g_free (current_prop_bers[j]); - } - g_free (current_prop_bers); - } - - include = !prop_info[i].compare_func (new, current); - } - } - - if (include) { - LDAPMod *mod = g_new (LDAPMod, 1); - - /* the included attribute has changed - we - need to update the dn if it's one of the - attributes we compute the dn from. */ - if (new_dn_needed) - *new_dn_needed |= prop_info[i].prop_type & PROP_DN; - - if (adding) { - mod->mod_op = LDAP_MOD_ADD; - } - else { - if (!new_prop_present) - mod->mod_op = LDAP_MOD_DELETE; - else if (!current_prop_present) - mod->mod_op = LDAP_MOD_ADD; - else - mod->mod_op = LDAP_MOD_REPLACE; - } - - mod->mod_type = g_strdup (prop_info[i].ldap_attr); - - if (prop_info[i].prop_type & PROP_TYPE_STRING) { - mod->mod_values = g_new (char*, 2); - mod->mod_values[0] = new_prop; - mod->mod_values[1] = NULL; - } - else { /* PROP_TYPE_COMPLEX */ - mod->mod_op |= LDAP_MOD_BVALUES; - mod->mod_bvalues = new_prop_bers; - } - - g_ptr_array_add (result, mod); - } - - } - - /* NULL terminate the list of modifications */ - g_ptr_array_add (result, NULL); - - return result; -} - -static void -add_objectclass_mod (PASBackendLDAP *bl, GPtrArray *mod_array, GList *existing_objectclasses) -{ -#define FIND_INSERT(oc) \ - if (!g_list_find_custom (existing_objectclasses, (oc), (GCompareFunc)g_ascii_strcasecmp)) \ - g_ptr_array_add (objectclasses, g_strdup ((oc))) -#define INSERT(oc) \ - g_ptr_array_add (objectclasses, g_strdup ((oc))) - - LDAPMod *objectclass_mod; - GPtrArray *objectclasses = g_ptr_array_new(); - - if (existing_objectclasses) { - objectclass_mod = g_new (LDAPMod, 1); - objectclass_mod->mod_op = LDAP_MOD_ADD; - objectclass_mod->mod_type = g_strdup ("objectClass"); - - /* yes, this is a linear search for each of our - objectclasses, but really, how many objectclasses - are there going to be in any sane ldap entry? */ - FIND_INSERT (TOP); - FIND_INSERT (PERSON); - FIND_INSERT (ORGANIZATIONALPERSON); - FIND_INSERT (INETORGPERSON); - if (bl->priv->calEntrySupported) - FIND_INSERT (CALENTRY); - if (bl->priv->evolutionPersonSupported) - FIND_INSERT (EVOLUTIONPERSON); - - if (objectclasses->len) { - g_ptr_array_add (objectclasses, NULL); - objectclass_mod->mod_values = (char**)objectclasses->pdata; - g_ptr_array_add (mod_array, objectclass_mod); - g_ptr_array_free (objectclasses, FALSE); - } - else { - g_ptr_array_free (objectclasses, TRUE); - g_free (objectclass_mod->mod_type); - g_free (objectclass_mod); - } - - } - else { - objectclass_mod = g_new (LDAPMod, 1); - objectclass_mod->mod_op = LDAP_MOD_ADD; - objectclass_mod->mod_type = g_strdup ("objectClass"); - - INSERT(TOP); - INSERT(PERSON); - INSERT(ORGANIZATIONALPERSON); - INSERT(INETORGPERSON); - if (bl->priv->calEntrySupported) - INSERT(CALENTRY); - if (bl->priv->evolutionPersonSupported) - INSERT(EVOLUTIONPERSON); - g_ptr_array_add (objectclasses, NULL); - objectclass_mod->mod_values = (char**)objectclasses->pdata; - g_ptr_array_add (mod_array, objectclass_mod); - g_ptr_array_free (objectclasses, FALSE); - } -} - -typedef struct { - LDAPOp op; - char *dn; - ECardSimple *new_card; -} LDAPCreateOp; - -static void -create_card_handler (LDAPOp *op, LDAPMessage *res) -{ - LDAPCreateOp *create_op = (LDAPCreateOp*)op; - PASBackendLDAP *bl = PAS_BACKEND_LDAP (op->backend); - LDAP *ldap = bl->priv->ldap; - int ldap_error; - int response; - - if (LDAP_RES_ADD != ldap_msgtype (res)) { - g_warning ("incorrect msg type %d passed to create_card_handler", ldap_msgtype (res)); - pas_book_respond_create (op->book, - GNOME_Evolution_Addressbook_BookListener_OtherError, - create_op->dn); - ldap_op_finished (op); - return; - } - - ldap_parse_result (ldap, res, &ldap_error, - NULL, NULL, NULL, NULL, 0); - - if (ldap_error == LDAP_SUCCESS) { - /* the card was created, let's let the views know about it */ - EIterator *iter; - - iter = e_list_get_iterator (bl->priv->book_views); - while (e_iterator_is_valid (iter)) { - CORBA_Environment ev; - gboolean match; - PASBackendLDAPBookView *view = (PASBackendLDAPBookView*)e_iterator_get (iter); - char *new_vcard; - - CORBA_exception_init(&ev); - - bonobo_object_dup_ref(bonobo_object_corba_objref(BONOBO_OBJECT(view->book_view)), &ev); - - new_vcard = e_card_simple_get_vcard_assume_utf8 (create_op->new_card); - - match = pas_backend_card_sexp_match_vcard (view->card_sexp, - new_vcard); - if (match) { - pas_book_view_notify_add_1 (view->book_view, - new_vcard); - } - pas_book_view_notify_complete (view->book_view, GNOME_Evolution_Addressbook_BookViewListener_Success); - - g_free (new_vcard); - - bonobo_object_release_unref(bonobo_object_corba_objref(BONOBO_OBJECT(view->book_view)), &ev); - - e_iterator_next (iter); - } - g_object_unref (iter); - } - else { - ldap_perror (ldap, "create_card"); - } - - if (op->view) - pas_book_view_notify_complete (op->view, GNOME_Evolution_Addressbook_BookViewListener_Success); - - /* and lastly respond */ - response = ldap_error_to_response (ldap_error); - pas_book_respond_create (op->book, - response, - create_op->dn); - - ldap_op_finished (op); -} - -static void -create_card_dtor (LDAPOp *op) -{ - LDAPCreateOp *create_op = (LDAPCreateOp*)op; - - g_free (create_op->dn); - g_object_unref (create_op->new_card); - g_free (create_op); -} - -static void -pas_backend_ldap_process_create_card (PASBackend *backend, - PASBook *book, - PASCreateCardRequest *req) -{ - LDAPCreateOp *create_op = g_new (LDAPCreateOp, 1); - PASBackendLDAP *bl = PAS_BACKEND_LDAP (backend); - PASBookView *book_view; - int create_card_msgid; - ECard *new_ecard; - int response; - int err; - GPtrArray *mod_array; - LDAPMod **ldap_mods; - LDAP *ldap; - - book_view = find_book_view (bl); - - printf ("vcard = %s\n", req->vcard); - - new_ecard = e_card_new (req->vcard); - create_op->new_card = e_card_simple_new (new_ecard); - - create_op->dn = create_dn_from_ecard (create_op->new_card, bl->priv->ldap_rootdn); - e_card_simple_set_id (create_op->new_card, create_op->dn); /* for the notification code below */ - - ldap = bl->priv->ldap; - - /* build our mods */ - mod_array = build_mods_from_ecards (bl, NULL, create_op->new_card, NULL); - -#if 0 - if (!mod_array) { - /* there's an illegal field in there. report - UnsupportedAttribute back */ - pas_book_respond_create (book, - GNOME_Evolution_Addressbook_BookListener_UnsupportedField, - create_op->dn); - - g_free (create_op->dn); - g_object_unref (create_op->new_card); - g_free (create_op); - return; - } -#endif - - /* remove the NULL at the end */ - g_ptr_array_remove (mod_array, NULL); - - /* add our objectclass(es) */ - add_objectclass_mod (bl, mod_array, NULL); - - /* then put the NULL back */ - g_ptr_array_add (mod_array, NULL); - -#ifdef LDAP_DEBUG_ADD - { - int i; - printf ("Sending the following to the server as ADD\n"); - - for (i = 0; g_ptr_array_index(mod_array, i); i ++) { - LDAPMod *mod = g_ptr_array_index(mod_array, i); - if (mod->mod_op & LDAP_MOD_DELETE) - printf ("del "); - else if (mod->mod_op & LDAP_MOD_REPLACE) - printf ("rep "); - else - printf ("add "); - if (mod->mod_op & LDAP_MOD_BVALUES) - printf ("ber "); - else - printf (" "); - - printf (" %s:\n", mod->mod_type); - - if (mod->mod_op & LDAP_MOD_BVALUES) { - int j; - for (j = 0; mod->mod_bvalues[j] && mod->mod_bvalues[j]->bv_val; j++) - printf ("\t\t'%s'\n", mod->mod_bvalues[j]->bv_val); - } - else { - int j; - - for (j = 0; mod->mod_values[j]; j++) - printf ("\t\t'%s'\n", mod->mod_values[j]); - } - } - } -#endif - - ldap_mods = (LDAPMod**)mod_array->pdata; - - do { - book_view_notify_status (book_view, _("Adding card to LDAP server...")); - - err = ldap_add_ext (ldap, create_op->dn, ldap_mods, - NULL, NULL, &create_card_msgid); - - } while (pas_backend_ldap_reconnect (bl, book_view, err)); - - /* and clean up */ - free_mods (mod_array); - - if (LDAP_SUCCESS != err) { - response = ldap_error_to_response (err); - pas_book_respond_create (create_op->op.book, - response, - create_op->dn); - create_card_dtor ((LDAPOp*)create_op); - return; - } - else { - g_print ("ldap_add_ext returned %d\n", err); - ldap_op_add ((LDAPOp*)create_op, backend, book, - book_view, create_card_msgid, - create_card_handler, create_card_dtor); - } -} - - -typedef struct { - LDAPOp op; - char *id; -} LDAPRemoveOp; - -static void -remove_card_handler (LDAPOp *op, LDAPMessage *res) -{ - LDAPRemoveOp *remove_op = (LDAPRemoveOp*)op; - PASBackendLDAP *bl = PAS_BACKEND_LDAP (op->backend); - int ldap_error; - - if (LDAP_RES_DELETE != ldap_msgtype (res)) { - g_warning ("incorrect msg type %d passed to remove_card_handler", ldap_msgtype (res)); - pas_book_respond_remove (op->book, - GNOME_Evolution_Addressbook_BookListener_OtherError); - ldap_op_finished (op); - return; - } - - ldap_parse_result (bl->priv->ldap, res, &ldap_error, - NULL, NULL, NULL, NULL, 0); - - if (ldap_error == LDAP_SUCCESS) { - /* the card was removed, let's let the views know about it */ - EIterator *iter = e_list_get_iterator (bl->priv->book_views); - - while (e_iterator_is_valid (iter)) { - CORBA_Environment ev; - PASBackendLDAPBookView *view = (PASBackendLDAPBookView*)e_iterator_get (iter); - - CORBA_exception_init(&ev); - - bonobo_object_dup_ref(bonobo_object_corba_objref(BONOBO_OBJECT(view->book_view)), &ev); - - pas_book_view_notify_remove_1 (view->book_view, remove_op->id); - - bonobo_object_release_unref(bonobo_object_corba_objref(BONOBO_OBJECT(view->book_view)), &ev); - - e_iterator_next (iter); - } - g_object_unref (iter); - } - else { - ldap_perror (bl->priv->ldap, "remove_card"); - } - - pas_book_respond_remove (remove_op->op.book, - ldap_error_to_response (ldap_error)); - - if (op->view) - pas_book_view_notify_complete (op->view, GNOME_Evolution_Addressbook_BookViewListener_Success); -} - -static void -remove_card_dtor (LDAPOp *op) -{ - LDAPRemoveOp *remove_op = (LDAPRemoveOp*)op; - - g_free (remove_op->id); - g_free (remove_op); -} - -static void -pas_backend_ldap_process_remove_cards (PASBackend *backend, - PASBook *book, - PASRemoveCardsRequest *req) -{ - LDAPRemoveOp *remove_op = g_new (LDAPRemoveOp, 1); - PASBackendLDAP *bl = PAS_BACKEND_LDAP (backend); - PASBookView *book_view; - int remove_msgid; - int ldap_error; - - book_view = find_book_view (bl); - - /* - ** since we didn't pass "bulk-removes" in our static - ** capabilities, we should only get 1 length lists here, so - ** the id we're deleting is the first and only id in the list. - */ - remove_op->id = g_strdup (req->ids->data); - - do { - book_view_notify_status (book_view, _("Removing card from LDAP server...")); - - ldap_error = ldap_delete_ext (bl->priv->ldap, - remove_op->id, - NULL, NULL, &remove_msgid); - } while (pas_backend_ldap_reconnect (bl, book_view, ldap_error)); - - if (ldap_error != LDAP_SUCCESS) { - pas_book_respond_remove (remove_op->op.book, - ldap_error_to_response (ldap_error)); - remove_card_dtor ((LDAPOp*)remove_op); - return; - } - else { - g_print ("ldap_delete_ext returned %d\n", ldap_error); - ldap_op_add ((LDAPOp*)remove_op, backend, book, - book_view, remove_msgid, - remove_card_handler, remove_card_dtor); - } -} - - -/* -** MODIFY -** -** The modification request is actually composed of 2 separate -** requests. Since we need to get a list of theexisting objectclasses -** used by the ldap server for the entry, and since the UI only sends -** us the current card, we need to query the ldap server for the -** existing card. -** -*/ - -typedef struct { - LDAPOp op; - const char *id; /* the id of the card we're modifying */ - char *current_vcard; /* current in the LDAP db */ - ECardSimple *current_card; - char *vcard; /* the VCard we want to store */ - ECardSimple *card; - GList *existing_objectclasses; -} LDAPModifyOp; - -static void -modify_card_modify_handler (LDAPOp *op, LDAPMessage *res) -{ - LDAPModifyOp *modify_op = (LDAPModifyOp*)op; - PASBackendLDAP *bl = PAS_BACKEND_LDAP (op->backend); - LDAP *ldap = bl->priv->ldap; - int ldap_error; - - if (LDAP_RES_MODIFY != ldap_msgtype (res)) { - g_warning ("incorrect msg type %d passed to modify_card_handler", ldap_msgtype (res)); - pas_book_respond_modify (op->book, - GNOME_Evolution_Addressbook_BookListener_OtherError); - ldap_op_finished (op); - return; - } - - ldap_parse_result (ldap, res, &ldap_error, - NULL, NULL, NULL, NULL, 0); - - if (ldap_error == LDAP_SUCCESS) { - /* the card was modified, let's let the views know about it */ - EIterator *iter = e_list_get_iterator (bl->priv->book_views); - while (e_iterator_is_valid (iter)) { - CORBA_Environment ev; - gboolean old_match, new_match; - PASBackendLDAPBookView *view = (PASBackendLDAPBookView*)e_iterator_get (iter); - - CORBA_exception_init(&ev); - - bonobo_object_dup_ref(bonobo_object_corba_objref(BONOBO_OBJECT(view->book_view)), &ev); - - old_match = pas_backend_card_sexp_match_vcard (view->card_sexp, - modify_op->current_vcard); - new_match = pas_backend_card_sexp_match_vcard (view->card_sexp, - modify_op->vcard); - if (old_match && new_match) - pas_book_view_notify_change_1 (view->book_view, modify_op->vcard); - else if (new_match) - pas_book_view_notify_add_1 (view->book_view, modify_op->vcard); - else /* if (old_match) */ - pas_book_view_notify_remove_1 (view->book_view, e_card_simple_get_id (modify_op->card)); - pas_book_view_notify_complete (view->book_view, GNOME_Evolution_Addressbook_BookViewListener_Success); - - bonobo_object_release_unref(bonobo_object_corba_objref(BONOBO_OBJECT(view->book_view)), &ev); - - e_iterator_next (iter); - } - g_object_unref (iter); - } - else { - ldap_perror (ldap, "ldap_modify_s"); - } - - /* and lastly respond */ - pas_book_respond_modify (op->book, - ldap_error_to_response (ldap_error)); - ldap_op_finished (op); -} - -static void -modify_card_search_handler (LDAPOp *op, LDAPMessage *res) -{ - LDAPModifyOp *modify_op = (LDAPModifyOp*)op; - PASBackendLDAP *bl = PAS_BACKEND_LDAP (op->backend); - LDAP *ldap = bl->priv->ldap; - int msg_type; - - /* if it's successful, we should get called with a - RES_SEARCH_ENTRY and a RES_SEARCH_RESULT. if it's - unsuccessful, we should only see a RES_SEARCH_RESULT */ - - msg_type = ldap_msgtype (res); - if (msg_type == LDAP_RES_SEARCH_ENTRY) { - LDAPMessage *e = ldap_first_entry(ldap, res); - - if (!e) { - g_warning ("uh, this shouldn't happen"); - pas_book_respond_modify (op->book, - GNOME_Evolution_Addressbook_BookListener_OtherError); - ldap_op_finished (op); - return; - } - - modify_op->current_card = build_card_from_entry (ldap, e, - &modify_op->existing_objectclasses); - modify_op->current_vcard = e_card_simple_get_vcard_assume_utf8 (modify_op->current_card); - } - else if (msg_type == LDAP_RES_SEARCH_RESULT) { - int ldap_error; - LDAPMod **ldap_mods; - GPtrArray *mod_array; - gboolean differences; - gboolean need_new_dn; - int modify_card_msgid; - - /* grab the result code, and set up the actual modify - if it was successful */ - ldap_parse_result (bl->priv->ldap, res, &ldap_error, - NULL, NULL, NULL, NULL, 0); - - if (ldap_error != LDAP_SUCCESS) { - /* more here i'm sure */ - pas_book_respond_modify (op->book, - ldap_error_to_response (ldap_error)); - ldap_op_finished (op); - return; - } - - /* build our mods */ - mod_array = build_mods_from_ecards (bl, modify_op->current_card, modify_op->card, &need_new_dn); - differences = mod_array->len > 0; - - if (differences) { - /* remove the NULL at the end */ - g_ptr_array_remove (mod_array, NULL); - - /* add our objectclass(es), making sure - evolutionPerson is there if it's supported */ - add_objectclass_mod (bl, mod_array, modify_op->existing_objectclasses); - - /* then put the NULL back */ - g_ptr_array_add (mod_array, NULL); - - ldap_mods = (LDAPMod**)mod_array->pdata; - - /* actually perform the ldap modify */ - ldap_error = ldap_modify_ext (ldap, modify_op->id, ldap_mods, - NULL, NULL, &modify_card_msgid); - - if (ldap_error == LDAP_SUCCESS) { - op->handler = modify_card_modify_handler; - ldap_op_change_id ((LDAPOp*)modify_op, - modify_card_msgid); - } - else { - g_warning ("ldap_modify_ext returned %d\n", ldap_error); - pas_book_respond_modify (op->book, - ldap_error_to_response (ldap_error)); - ldap_op_finished (op); - return; - } - } - - /* and clean up */ - free_mods (mod_array); - } - else { - g_warning ("unhandled result type %d returned", msg_type); - pas_book_respond_modify (op->book, - GNOME_Evolution_Addressbook_BookListener_OtherError); - ldap_op_finished (op); - } -} - -static void -modify_card_dtor (LDAPOp *op) -{ - LDAPModifyOp *modify_op = (LDAPModifyOp*)op; - - g_list_foreach (modify_op->existing_objectclasses, (GFunc)g_free, NULL); - g_list_free (modify_op->existing_objectclasses); - g_free (modify_op->current_vcard); - if (modify_op->current_card) - g_object_unref (modify_op->current_card); - g_free (modify_op->vcard); - if (modify_op->card) - g_object_unref (modify_op->card); - g_free (modify_op); -} - -static void -pas_backend_ldap_process_modify_card (PASBackend *backend, - PASBook *book, - PASModifyCardRequest *req) -{ - LDAPModifyOp *modify_op = g_new0 (LDAPModifyOp, 1); - PASBackendLDAP *bl = PAS_BACKEND_LDAP (backend); - ECard *new_ecard; - int ldap_error; - LDAP *ldap; - int modify_card_msgid; - PASBookView *book_view; - - book_view = find_book_view (bl); - - modify_op->vcard = g_strdup (req->vcard); - new_ecard = e_card_new (modify_op->vcard); - modify_op->card = e_card_simple_new (new_ecard); - g_object_unref (new_ecard); - modify_op->id = e_card_simple_get_id(modify_op->card); - - ldap = bl->priv->ldap; - - book_view_notify_status (book_view, _("Modifying card from LDAP server...")); - - do { - book_view_notify_status (book_view, _("Modifying card from LDAP server...")); - - ldap_error = ldap_search_ext (ldap, modify_op->id, - LDAP_SCOPE_BASE, - "(objectclass=*)", - NULL, 0, NULL, NULL, - NULL, /* XXX timeout */ - 1, &modify_card_msgid); - - } while (pas_backend_ldap_reconnect (bl, book_view, ldap_error)); - - if (ldap_error == LDAP_SUCCESS) { - ldap_op_add ((LDAPOp*)modify_op, backend, book, - book_view, modify_card_msgid, - modify_card_search_handler, modify_card_dtor); - } - else { - g_warning ("ldap_search_ext returned %d\n", ldap_error); - pas_book_respond_modify (book, - GNOME_Evolution_Addressbook_BookListener_OtherError); - modify_card_dtor ((LDAPOp*)modify_op); - } -} - - -typedef struct { - LDAPOp op; -} LDAPGetVCardOp; - -static void -get_vcard_handler (LDAPOp *op, LDAPMessage *res) -{ - PASBackendLDAP *bl = PAS_BACKEND_LDAP (op->backend); - int msg_type; - - /* the msg_type will be either SEARCH_ENTRY (if we're - successful) or SEARCH_RESULT (if we're not), so we finish - the op after either */ - msg_type = ldap_msgtype (res); - if (msg_type == LDAP_RES_SEARCH_ENTRY) { - LDAPMessage *e = ldap_first_entry(bl->priv->ldap, res); - ECardSimple *simple; - char *vcard; - - if (!e) { - g_warning ("uh, this shouldn't happen"); - pas_book_respond_get_vcard (op->book, - GNOME_Evolution_Addressbook_BookListener_OtherError, - ""); - ldap_op_finished (op); - return; - } - - simple = build_card_from_entry (bl->priv->ldap, e, NULL); - vcard = e_card_simple_get_vcard_assume_utf8 (simple); - pas_book_respond_get_vcard (op->book, - GNOME_Evolution_Addressbook_BookListener_Success, - vcard); - g_free (vcard); - g_object_unref (simple); - ldap_op_finished (op); - } - else if (msg_type == LDAP_RES_SEARCH_RESULT) { - int ldap_error; - ldap_parse_result (bl->priv->ldap, res, &ldap_error, - NULL, NULL, NULL, NULL, 0); - pas_book_respond_get_vcard (op->book, ldap_error_to_response (ldap_error), ""); - ldap_op_finished (op); - } - else { - g_warning ("unhandled result type %d returned", msg_type); - pas_book_respond_get_vcard (op->book, GNOME_Evolution_Addressbook_BookListener_OtherError, - ""); - ldap_op_finished (op); - } - -} - -static void -get_vcard_dtor (LDAPOp *op) -{ - LDAPGetVCardOp *get_vcard_op = (LDAPGetVCardOp*)op; - - g_free (get_vcard_op); -} - -static void -pas_backend_ldap_process_get_vcard (PASBackend *backend, - PASBook *book, - PASGetVCardRequest *req) -{ - LDAPGetVCardOp *get_vcard_op = g_new0 (LDAPGetVCardOp, 1); - PASBackendLDAP *bl = PAS_BACKEND_LDAP (backend); - LDAP *ldap = bl->priv->ldap; - int get_vcard_msgid; - PASBookView *book_view; - int ldap_error; - - book_view = find_book_view (bl); - - do { - ldap_error = ldap_search_ext (ldap, req->id, - LDAP_SCOPE_BASE, - "(objectclass=*)", - NULL, 0, NULL, NULL, - NULL, /* XXX timeout */ - 1, &get_vcard_msgid); - } while (pas_backend_ldap_reconnect (bl, book_view, ldap_error)); - - if (ldap_error == LDAP_SUCCESS) { - ldap_op_add ((LDAPOp*)get_vcard_op, backend, book, - book_view, get_vcard_msgid, - get_vcard_handler, get_vcard_dtor); - } - else { - pas_book_respond_get_vcard (book, - ldap_error_to_response (ldap_error), - ""); - get_vcard_dtor ((LDAPOp*)get_vcard_op); - } -} - - -typedef struct { - LDAPOp op; - PASBackendLDAPCursorPrivate *cursor_data; - gboolean responded; /* if FALSE, we need to free cursor_data in the dtor */ -} LDAPGetCursorOp; - -static long -get_length(PASCardCursor *cursor, gpointer data) -{ - PASBackendLDAPCursorPrivate *cursor_data = (PASBackendLDAPCursorPrivate *) data; - - return cursor_data->num_elements; -} - -static char * -get_nth(PASCardCursor *cursor, long n, gpointer data) -{ - PASBackendLDAPCursorPrivate *cursor_data = (PASBackendLDAPCursorPrivate *) data; - - g_return_val_if_fail (n < cursor_data->num_elements, NULL); - - return (char*)g_list_nth (cursor_data->elements, n); -} - -static void -cursor_destroy(gpointer data, GObject *where_object_was) -{ - PASBackendLDAPCursorPrivate *cursor_data = (PASBackendLDAPCursorPrivate *) data; - - if (cursor_data->book) { - CORBA_Environment ev; - GNOME_Evolution_Addressbook_Book corba_book; - - corba_book = bonobo_object_corba_objref(BONOBO_OBJECT(cursor_data->book)); - - CORBA_exception_init(&ev); - - GNOME_Evolution_Addressbook_Book_unref(corba_book, &ev); - - if (ev._major != CORBA_NO_EXCEPTION) { - g_warning("cursor_destroy: Exception unreffing " - "corba book.\n"); - } - - CORBA_exception_free(&ev); - } - - /* free the ldap specific cursor information */ - g_list_foreach (cursor_data->elements, (GFunc)g_free, NULL); - g_list_free (cursor_data->elements); - - g_free(cursor_data); -} - -static void -get_cursor_handler (LDAPOp *op, LDAPMessage *res) -{ - LDAPGetCursorOp *cursor_op = (LDAPGetCursorOp*)op; - PASBackendLDAP *bl = PAS_BACKEND_LDAP (op->backend); - LDAP *ldap = bl->priv->ldap; - int msg_type; - - msg_type = ldap_msgtype (res); - if (msg_type == LDAP_RES_SEARCH_ENTRY) { - LDAPMessage *e; - - e = ldap_first_entry (ldap, res); - while (e) { - ECardSimple *simple; - - simple = build_card_from_entry (ldap, e, NULL); - if (simple) { - char *vcard = e_card_simple_get_vcard_assume_utf8 (simple); - cursor_op->cursor_data->num_elements ++; - cursor_op->cursor_data->elements = g_list_prepend (cursor_op->cursor_data->elements, - vcard); - g_object_unref (simple); - } - } - } - else if (msg_type == LDAP_RES_SEARCH_RESULT) { - PASCardCursor *cursor = CORBA_OBJECT_NIL; - int ldap_error; - ldap_parse_result (bl->priv->ldap, res, &ldap_error, - NULL, NULL, NULL, NULL, 0); - - if (ldap_error == LDAP_SUCCESS) { - cursor = pas_card_cursor_new(get_length, - get_nth, - cursor_op->cursor_data); - - g_object_weak_ref (G_OBJECT (cursor), cursor_destroy, cursor_op->cursor_data); - - cursor_op->responded = TRUE; - } - - pas_book_respond_get_cursor (cursor_op->cursor_data->book, - ldap_error_to_response (ldap_error), - cursor); - - ldap_op_finished (op); - } - else { - g_warning ("unhandled result type %d returned", msg_type); - pas_book_respond_get_cursor (op->book, - GNOME_Evolution_Addressbook_BookListener_OtherError, - CORBA_OBJECT_NIL); - ldap_op_finished (op); - } -} - -static void -get_cursor_dtor (LDAPOp *op) -{ - LDAPGetCursorOp *cursor_op = (LDAPGetCursorOp*)op; - - if (!cursor_op->responded) { - cursor_destroy (cursor_op->cursor_data, NULL); - } - - g_free (op); -} - -static void -pas_backend_ldap_process_get_cursor (PASBackend *backend, - PASBook *book, - PASGetCursorRequest *req) -{ - PASBackendLDAP *bl = PAS_BACKEND_LDAP (backend); - LDAP *ldap = bl->priv->ldap; - int ldap_error; - int get_cursor_msgid; - LDAPGetCursorOp *cursor_op; - PASBookView *book_view; - - book_view = find_book_view (bl); - - cursor_op = g_new0 (LDAPGetCursorOp, 1); - cursor_op->cursor_data = g_new0 (PASBackendLDAPCursorPrivate, 1); - - do { - ldap_error = ldap_search_ext (ldap, - bl->priv->ldap_rootdn, - bl->priv->ldap_scope, - "(objectclass=*)", - NULL, 0, - NULL, NULL, NULL, /* timeout */ - 0, &get_cursor_msgid); - } while (pas_backend_ldap_reconnect (bl, book_view, ldap_error)); - - if (ldap_error == LDAP_SUCCESS) { - CORBA_Environment ev; - GNOME_Evolution_Addressbook_Book corba_book; - - corba_book = bonobo_object_corba_objref(BONOBO_OBJECT(book)); - - CORBA_exception_init(&ev); - - GNOME_Evolution_Addressbook_Book_ref(corba_book, &ev); - - cursor_op->cursor_data->backend = backend; - cursor_op->cursor_data->book = book; - - if (ev._major != CORBA_NO_EXCEPTION) { - g_warning("pas_backend_ldap_process_get_cursor: Exception reffing " - "corba book.\n"); - } - - CORBA_exception_free(&ev); - - - ldap_op_add ((LDAPOp*)cursor_op, backend, book, - NULL, get_cursor_msgid, get_cursor_handler, get_cursor_dtor); - } - else { - pas_book_respond_get_cursor (book, - ldap_error_to_response (ldap_error), - CORBA_OBJECT_NIL); - get_cursor_dtor ((LDAPOp*)cursor_op); - } -} - - -/* List property functions */ -static void -email_populate(ECardSimple *card, char **values) -{ - int i; - - for (i = 0; values[i] && i < 3; i ++) { - e_card_simple_set_email (card, i, values[i]); - } -} - -struct berval** -email_ber(ECardSimple *card) -{ - struct berval** result; - const char *emails[3]; - int i, j, num; - - num = 0; - for (i = 0; i < 3; i ++) { - emails[i] = e_card_simple_get_email (card, E_CARD_SIMPLE_EMAIL_ID_EMAIL + i); - if (emails[i]) - num++; - } - - if (num == 0) - return NULL; - - result = g_new (struct berval*, num + 1); - - for (i = 0; i < num; i ++) - result[i] = g_new (struct berval, 1); - - j = 0; - for (i = 0; i < 3; i ++) { - if (emails[i]) { - result[j]->bv_val = g_strdup (emails[i]); - result[j++]->bv_len = strlen (emails[i]); - } - } - - result[num] = NULL; - - return result; -} - -static gboolean -email_compare (ECardSimple *ecard1, ECardSimple *ecard2) -{ - const char *email1, *email2; - int i; - - for (i = 0; i < 3; i ++) { - gboolean equal; - email1 = e_card_simple_get_email (ecard1, E_CARD_SIMPLE_EMAIL_ID_EMAIL + i); - email2 = e_card_simple_get_email (ecard2, E_CARD_SIMPLE_EMAIL_ID_EMAIL + i); - - if (email1 && email2) - equal = !strcmp (email1, email2); - else - equal = (!!email1 == !!email2); - - if (!equal) - return equal; - } - - return TRUE; -} - -static void -homephone_populate(ECardSimple *card, char **values) -{ - if (values[0]) { - e_card_simple_set (card, E_CARD_SIMPLE_FIELD_PHONE_HOME, values[0]); - if (values[1]) - e_card_simple_set (card, E_CARD_SIMPLE_FIELD_PHONE_HOME_2, values[1]); - } -} - -struct berval** -homephone_ber(ECardSimple *card) -{ - struct berval** result; - const char *homephones[3]; - int i, j, num; - - num = 0; - if ((homephones[0] = e_card_simple_get (card, E_CARD_SIMPLE_FIELD_PHONE_HOME))) - num++; - if ((homephones[1] = e_card_simple_get (card, E_CARD_SIMPLE_FIELD_PHONE_HOME_2))) - num++; - - if (num == 0) - return NULL; - - result = g_new (struct berval*, num + 1); - - for (i = 0; i < num; i ++) - result[i] = g_new (struct berval, 1); - - j = 0; - for (i = 0; i < 2; i ++) { - if (homephones[i]) { - result[j]->bv_val = g_strdup (homephones[i]); - result[j++]->bv_len = strlen (homephones[i]); - } - } - - result[num] = NULL; - - return result; -} - -static gboolean -homephone_compare (ECardSimple *ecard1, ECardSimple *ecard2) -{ - int phone_ids[2] = { E_CARD_SIMPLE_FIELD_PHONE_HOME, E_CARD_SIMPLE_FIELD_PHONE_HOME_2 }; - const char *phone1, *phone2; - int i; - - for (i = 0; i < 2; i ++) { - gboolean equal; - phone1 = e_card_simple_get (ecard1, phone_ids[i]); - phone2 = e_card_simple_get (ecard2, phone_ids[i]); - - if (phone1 && phone2) - equal = !strcmp (phone1, phone2); - else - equal = (!!phone1 == !!phone2); - - if (!equal) - return equal; - } - - return TRUE; -} - -static void -business_populate(ECardSimple *card, char **values) -{ - if (values[0]) { - e_card_simple_set (card, E_CARD_SIMPLE_FIELD_PHONE_BUSINESS, values[0]); - if (values[1]) - e_card_simple_set (card, E_CARD_SIMPLE_FIELD_PHONE_BUSINESS_2, values[1]); - } -} - -struct berval** -business_ber(ECardSimple *card) -{ - struct berval** result; - const char *business_phones[3]; - int i, j, num; - - num = 0; - if ((business_phones[0] = e_card_simple_get (card, E_CARD_SIMPLE_FIELD_PHONE_BUSINESS))) - num++; - if ((business_phones[1] = e_card_simple_get (card, E_CARD_SIMPLE_FIELD_PHONE_BUSINESS_2))) - num++; - - if (num == 0) - return NULL; - - result = g_new (struct berval*, num + 1); - - for (i = 0; i < num; i ++) - result[i] = g_new (struct berval, 1); - - j = 0; - for (i = 0; i < 2; i ++) { - if (business_phones[i]) { - result[j]->bv_val = g_strdup (business_phones[i]); - result[j++]->bv_len = strlen (business_phones[i]); - } - } - - result[num] = NULL; - - return result; -} - -static gboolean -business_compare (ECardSimple *ecard1, ECardSimple *ecard2) -{ - int phone_ids[2] = { E_CARD_SIMPLE_FIELD_PHONE_BUSINESS, E_CARD_SIMPLE_FIELD_PHONE_BUSINESS_2 }; - const char *phone1, *phone2; - int i; - - for (i = 0; i < 2; i ++) { - gboolean equal; - phone1 = e_card_simple_get (ecard1, phone_ids[i]); - phone2 = e_card_simple_get (ecard2, phone_ids[i]); - - if (phone1 && phone2) - equal = !strcmp (phone1, phone2); - else - equal = (!!phone1 == !!phone2); - - if (!equal) - return equal; - } - - return TRUE; -} - -static void -anniversary_populate (ECardSimple *card, char **values) -{ - if (values[0]) { - ECardDate dt = e_card_date_from_string (values[0]); - g_object_set (card->card, - "anniversary", &dt, - NULL); - } -} - -struct berval** -anniversary_ber (ECardSimple *card) -{ - ECardDate *dt; - struct berval** result = NULL; - - g_object_get (card->card, - "anniversary", &dt, - NULL); - - if (dt) { - char *anniversary; - - anniversary = e_card_date_to_string (dt); - - result = g_new (struct berval*, 2); - result[0] = g_new (struct berval, 1); - result[0]->bv_val = anniversary; - result[0]->bv_len = strlen (anniversary); - - result[1] = NULL; - } - - return result; -} - -static gboolean -anniversary_compare (ECardSimple *ecard1, ECardSimple *ecard2) -{ - ECardDate *dt; - char *date1 = NULL, *date2 = NULL; - gboolean equal; - - g_object_get (ecard1->card, - "anniversary", &dt, - NULL); - if (dt) - date1 = e_card_date_to_string (dt); - - g_object_get (ecard2->card, - "anniversary", &dt, - NULL); - if (dt) - date2 = e_card_date_to_string (dt); - - if (date1 && date2) - equal = !strcmp (date1, date2); - else - equal = (!!date1 == !!date2); - - g_free (date1); - g_free (date2); - - return equal; -} - -static void -birthday_populate (ECardSimple *card, char **values) -{ - if (values[0]) { - ECardDate dt = e_card_date_from_string (values[0]); - g_object_set (card->card, - "birth_date", &dt, - NULL); - } -} - -struct berval** -birthday_ber (ECardSimple *card) -{ - ECardDate *dt; - struct berval** result = NULL; - - g_object_get (card->card, - "birth_date", &dt, - NULL); - - if (dt) { - char *birthday; - - birthday = e_card_date_to_string (dt); - - result = g_new (struct berval*, 2); - result[0] = g_new (struct berval, 1); - result[0]->bv_val = birthday; - result[0]->bv_len = strlen (birthday); - - result[1] = NULL; - } - - return result; -} - -static gboolean -birthday_compare (ECardSimple *ecard1, ECardSimple *ecard2) -{ - ECardDate *dt; - char *date1 = NULL, *date2 = NULL; - gboolean equal; - - g_object_get (ecard1->card, - "birth_date", &dt, - NULL); - if (dt) - date1 = e_card_date_to_string (dt); - - g_object_get (ecard2->card, - "birth_date", &dt, - NULL); - if (dt) - date2 = e_card_date_to_string (dt); - - if (date1 && date2) - equal = !strcmp (date1, date2); - else - equal = (!!date1 == !!date2); - - g_free (date1); - g_free (date2); - - return equal; -} - -static void -category_populate (ECardSimple *card, char **values) -{ - int i; - ECard *ecard; - EList *categories; - - g_object_get (card, - "card", &ecard, - NULL); - - categories = e_list_new((EListCopyFunc) g_strdup, - (EListFreeFunc) g_free, - NULL); - - for (i = 0; values[i]; i++) - e_list_append (categories, values[i]); - - g_object_set (ecard, - "category_list", categories, - NULL); - - g_object_unref (categories); - - e_card_simple_sync_card (card); - g_object_unref (ecard); -} - -struct berval** -category_ber (ECardSimple *card) -{ - struct berval** result = NULL; - EList *categories; - EIterator *iterator; - ECard *ecard; - int i; - - g_object_get (card, - "card", &ecard, - NULL); - - g_object_get (ecard, - "category_list", &categories, - NULL); - - if (e_list_length (categories) != 0) { - result = g_new0 (struct berval*, e_list_length (categories) + 1); - - for (iterator = e_list_get_iterator(categories), i = 0; e_iterator_is_valid (iterator); - e_iterator_next (iterator), i++) { - const char *category = e_iterator_get (iterator); - - result[i] = g_new (struct berval, 1); - result[i]->bv_val = g_strdup (category); - result[i]->bv_len = strlen (category); - } - - g_object_unref (iterator); - } - - g_object_unref (categories); - g_object_unref (ecard); - return result; -} - -static gboolean -category_compare (ECardSimple *ecard1, ECardSimple *ecard2) -{ - char *categories1, *categories2; - gboolean equal; - - categories1 = e_card_simple_get (ecard1, E_CARD_SIMPLE_FIELD_CATEGORIES); - categories2 = e_card_simple_get (ecard2, E_CARD_SIMPLE_FIELD_CATEGORIES); - - equal = !strcmp (categories1, categories2); - - g_free (categories1); - g_free (categories2); - - return equal; -} - -typedef struct { - GList *list; - PASBackendLDAP *bl; -} PASBackendLDAPSExpData; - -#define IS_RFC2254_CHAR(c) ((c) == '*' || (c) =='\\' || (c) == '(' || (c) == ')' || (c) == '\0') -static char * -rfc2254_escape(char *str) -{ - int i; - int len = strlen(str); - int newlen = 0; - - for (i = 0; i < len; i ++) { - if (IS_RFC2254_CHAR(str[i])) - newlen += 3; - else - newlen ++; - } - - if (len == newlen) { - return g_strdup (str); - } - else { - char *newstr = g_malloc0 (newlen + 1); - int j = 0; - for (i = 0; i < len; i ++) { - if (IS_RFC2254_CHAR(str[i])) { - sprintf (newstr + j, "\\%02x", str[i]); - j+= 3; - } - else { - newstr[j++] = str[i]; - } - } - return newstr; - } -} - -static ESExpResult * -func_and(struct _ESExp *f, int argc, struct _ESExpResult **argv, void *data) -{ - PASBackendLDAPSExpData *ldap_data = data; - ESExpResult *r; - char ** strings; - - if (argc > 0) { - int i; - - strings = g_new0(char*, argc+3); - strings[0] = g_strdup ("(&"); - strings[argc+3 - 2] = g_strdup (")"); - - for (i = 0; i < argc; i ++) { - GList *list_head = ldap_data->list; - if (!list_head) - break; - strings[argc - i] = list_head->data; - ldap_data->list = g_list_remove_link(list_head, list_head); - g_list_free_1(list_head); - } - - ldap_data->list = g_list_prepend(ldap_data->list, g_strjoinv(" ", strings)); - - for (i = 0 ; i < argc + 2; i ++) - g_free (strings[i]); - - g_free (strings); - } - - r = e_sexp_result_new(f, ESEXP_RES_BOOL); - r->value.bool = FALSE; - - return r; -} - -static ESExpResult * -func_or(struct _ESExp *f, int argc, struct _ESExpResult **argv, void *data) -{ - PASBackendLDAPSExpData *ldap_data = data; - ESExpResult *r; - char ** strings; - - if (argc > 0) { - int i; - - strings = g_new0(char*, argc+3); - strings[0] = g_strdup ("(|"); - strings[argc+3 - 2] = g_strdup (")"); - - for (i = 0; i < argc; i ++) { - GList *list_head = ldap_data->list; - if (!list_head) - break; - strings[argc - i] = list_head->data; - ldap_data->list = g_list_remove_link(list_head, list_head); - g_list_free_1(list_head); - } - - ldap_data->list = g_list_prepend(ldap_data->list, g_strjoinv(" ", strings)); - - for (i = 0 ; i < argc + 2; i ++) - g_free (strings[i]); - - g_free (strings); - } - - r = e_sexp_result_new(f, ESEXP_RES_BOOL); - r->value.bool = FALSE; - - return r; -} - -static ESExpResult * -func_not(struct _ESExp *f, int argc, struct _ESExpResult **argv, void *data) -{ - PASBackendLDAPSExpData *ldap_data = data; - ESExpResult *r; - - /* just replace the head of the list with the NOT of it. */ - if (argc > 0) { - char *term = ldap_data->list->data; - ldap_data->list->data = g_strdup_printf("(!%s)", term); - g_free (term); - } - - r = e_sexp_result_new(f, ESEXP_RES_BOOL); - r->value.bool = FALSE; - - return r; -} - -static ESExpResult * -func_contains(struct _ESExp *f, int argc, struct _ESExpResult **argv, void *data) -{ - PASBackendLDAPSExpData *ldap_data = data; - ESExpResult *r; - - if (argc == 2 - && argv[0]->type == ESEXP_RES_STRING - && argv[1]->type == ESEXP_RES_STRING) { - char *propname = argv[0]->value.string; - char *str = rfc2254_escape(argv[1]->value.string); - gboolean one_star = FALSE; - - if (strlen(str) == 0) - one_star = TRUE; - - if (!strcmp (propname, "x-evolution-any-field")) { - int i; - int query_length; - char *big_query; - char *match_str; - - match_str = g_strdup_printf("=*%s%s)", - str, one_star ? "" : "*"); - - query_length = 3; /* strlen ("(|") + strlen (")") */ - - for (i = 0; i < num_prop_infos; i ++) { - query_length += 1 /* strlen ("(") */ + strlen(prop_info[i].ldap_attr) + strlen (match_str); - } - - big_query = g_malloc0(query_length + 1); - strcat (big_query, "(|"); - for (i = 0; i < num_prop_infos; i ++) { - strcat (big_query, "("); - strcat (big_query, prop_info[i].ldap_attr); - strcat (big_query, match_str); - } - strcat (big_query, ")"); - - ldap_data->list = g_list_prepend(ldap_data->list, big_query); - - g_free (match_str); - } - else { - char *ldap_attr = query_prop_to_ldap(propname); - - if (ldap_attr) - ldap_data->list = g_list_prepend(ldap_data->list, - g_strdup_printf("(%s=*%s%s)", - ldap_attr, - str, - one_star ? "" : "*")); - } - - g_free (str); - } - - r = e_sexp_result_new(f, ESEXP_RES_BOOL); - r->value.bool = FALSE; - - return r; -} - -static ESExpResult * -func_is(struct _ESExp *f, int argc, struct _ESExpResult **argv, void *data) -{ - PASBackendLDAPSExpData *ldap_data = data; - ESExpResult *r; - - if (argc == 2 - && argv[0]->type == ESEXP_RES_STRING - && argv[1]->type == ESEXP_RES_STRING) { - char *propname = argv[0]->value.string; - char *str = rfc2254_escape(argv[1]->value.string); - char *ldap_attr = query_prop_to_ldap(propname); - - if (ldap_attr) - ldap_data->list = g_list_prepend(ldap_data->list, - g_strdup_printf("(%s=%s)", - ldap_attr, str)); - else { - g_warning ("unknown query property\n"); - /* we want something that'll always be false */ - ldap_data->list = g_list_prepend(ldap_data->list, - g_strdup("objectClass=MyBarnIsBiggerThanYourBarn")); - } - - g_free (str); - } - - r = e_sexp_result_new(f, ESEXP_RES_BOOL); - r->value.bool = FALSE; - - return r; -} - -static ESExpResult * -func_beginswith(struct _ESExp *f, int argc, struct _ESExpResult **argv, void *data) -{ - PASBackendLDAPSExpData *ldap_data = data; - ESExpResult *r; - - if (argc == 2 - && argv[0]->type == ESEXP_RES_STRING - && argv[1]->type == ESEXP_RES_STRING) { - char *propname = argv[0]->value.string; - char *str = rfc2254_escape(argv[1]->value.string); - char *ldap_attr = query_prop_to_ldap(propname); - - /* insert hack for fileAs queries, since we need to do - the right thing if the server supports them or not, - and for entries that have no fileAs attribute. */ - if (ldap_attr) { - if (!strcmp (propname, "full_name")) { - ldap_data->list = g_list_prepend(ldap_data->list, - g_strdup_printf( - "(|(cn=%s*)(sn=%s*))", - str, str)); - } - else if (!strcmp (ldap_attr, "fileAs")) { - if (ldap_data->bl->priv->evolutionPersonSupported) - ldap_data->list = g_list_prepend(ldap_data->list, - g_strdup_printf("(|(fileAs=%s*)(&(!(fileAs=*))(sn=%s*)))", - str, str)); - else - ldap_data->list = g_list_prepend(ldap_data->list, - g_strdup_printf("(sn=%s*)", str)); - } - else { - ldap_data->list = g_list_prepend(ldap_data->list, - g_strdup_printf("(%s=%s*)", - ldap_attr, - str)); - } - } - - g_free (str); - } - - r = e_sexp_result_new(f, ESEXP_RES_BOOL); - r->value.bool = FALSE; - - return r; -} - -static ESExpResult * -func_endswith(struct _ESExp *f, int argc, struct _ESExpResult **argv, void *data) -{ - PASBackendLDAPSExpData *ldap_data = data; - ESExpResult *r; - - if (argc == 2 - && argv[0]->type == ESEXP_RES_STRING - && argv[1]->type == ESEXP_RES_STRING) { - char *propname = argv[0]->value.string; - char *str = rfc2254_escape(argv[1]->value.string); - char *ldap_attr = query_prop_to_ldap(propname); - - if (ldap_attr) - ldap_data->list = g_list_prepend(ldap_data->list, - g_strdup_printf("(%s=*%s)", - ldap_attr, - str)); - g_free (str); - } - - r = e_sexp_result_new(f, ESEXP_RES_BOOL); - r->value.bool = FALSE; - - return r; -} - -/* 'builtin' functions */ -static struct { - char *name; - ESExpFunc *func; - int type; /* set to 1 if a function can perform shortcut evaluation, or - doesn't execute everything, 0 otherwise */ -} symbols[] = { - { "and", func_and, 0 }, - { "or", func_or, 0 }, - { "not", func_not, 0 }, - { "contains", func_contains, 0 }, - { "is", func_is, 0 }, - { "beginswith", func_beginswith, 0 }, - { "endswith", func_endswith, 0 }, -}; - -static gchar * -pas_backend_ldap_build_query (PASBackendLDAP *bl, gchar *query) -{ - ESExp *sexp; - ESExpResult *r; - gchar *retval; - PASBackendLDAPSExpData data; - int i; - - data.list = NULL; - data.bl = bl; - - sexp = e_sexp_new(); - - for(i=0;i<sizeof(symbols)/sizeof(symbols[0]);i++) { - if (symbols[i].type == 1) { - e_sexp_add_ifunction(sexp, 0, symbols[i].name, - (ESExpIFunc *)symbols[i].func, &data); - } else { - e_sexp_add_function(sexp, 0, symbols[i].name, - symbols[i].func, &data); - } - } - - e_sexp_input_text(sexp, query, strlen(query)); - e_sexp_parse(sexp); - - r = e_sexp_eval(sexp); - - e_sexp_result_free(sexp, r); - e_sexp_unref (sexp); - - if (data.list) { - if (data.list->next) { - g_warning ("conversion to ldap query string failed"); - retval = NULL; - g_list_foreach (data.list, (GFunc)g_free, NULL); - } - else { - retval = data.list->data; - } - } - else { - g_warning ("conversion to ldap query string failed"); - retval = NULL; - } - - g_list_free (data.list); - return retval; -} - -static gchar * -query_prop_to_ldap(gchar *query_prop) -{ - int i; - - for (i = 0; i < num_prop_infos; i ++) - if (!strcmp (query_prop, prop_info[i].query_prop)) - return prop_info[i].ldap_attr; - - return NULL; -} - - -typedef struct { - LDAPOp op; - PASBackendLDAPBookView *view; - - /* grouping stuff */ - GList *pending_adds; /* the cards we're sending */ - int num_pending_adds; /* the number waiting to be sent */ - int target_pending_adds; /* the cutoff that forces a flush to the client, if it happens before the timeout */ - int num_sent_this_time; /* the number of cards we sent to the client before the most recent timeout */ - int num_sent_last_time; /* the number of cards we sent to the client before the previous timeout */ - glong grouping_time_start; - - /* used by search_handler to only send the status messages once */ - gboolean notified_receiving_results; -} LDAPSearchOp; - -static ECardSimple * -build_card_from_entry (LDAP *ldap, LDAPMessage *e, GList **existing_objectclasses) -{ - ECard *ecard = e_card_new (""); - ECardSimple *card = e_card_simple_new (ecard); - char *dn; - char *attr; - BerElement *ber = NULL; - - dn = ldap_get_dn(ldap, e); - e_card_simple_set_id (card, dn); - ldap_memfree (dn); - - for (attr = ldap_first_attribute (ldap, e, &ber); attr; - attr = ldap_next_attribute (ldap, e, ber)) { - int i; - struct prop_info *info = NULL; - char **values; - - if (existing_objectclasses && !g_ascii_strcasecmp (attr, "objectclass")) { - values = ldap_get_values (ldap, e, attr); - for (i = 0; values[i]; i ++) - *existing_objectclasses = g_list_append (*existing_objectclasses, g_strdup (values[i])); - - ldap_value_free (values); - } - else { - for (i = 0; i < num_prop_infos; i ++) - if (!g_ascii_strcasecmp (attr, prop_info[i].ldap_attr)) { - info = &prop_info[i]; - break; - } - - if (info) { - values = ldap_get_values (ldap, e, attr); - - if (values) { - if (info->prop_type & PROP_TYPE_STRING) { - /* if it's a normal property just set the string */ - if (values[0]) - e_card_simple_set (card, info->field_id, values[0]); - - } - else if (info->prop_type & PROP_TYPE_COMPLEX) { - /* if it's a list call the ecard-populate function, - which calls g_object_set to set the property */ - info->populate_ecard_func(card, - values); - } - - ldap_value_free (values); - } - } - } - - ldap_memfree (attr); - } - - if (ber) - ber_free (ber, 0); - - e_card_simple_sync_card (card); - - g_object_unref (ecard); - - return card; -} - -static gboolean -poll_ldap (PASBackendLDAP *bl) -{ - LDAP *ldap = bl->priv->ldap; - int rc; - LDAPMessage *res; - GTimeVal cur_time; - glong cur_millis; - struct timeval timeout; - EIterator *iter; - - if (!bl->priv->active_ops) { - g_warning ("poll_ldap being called for backend with no active operations"); - return FALSE; - } - - timeout.tv_sec = 0; - timeout.tv_usec = LDAP_RESULT_TIMEOUT_MILLIS * 1000; - - rc = ldap_result (ldap, LDAP_RES_ANY, 0, &timeout, &res); - if (rc != 0) {/* rc == 0 means timeout exceeded */ - if (rc == -1) { - PASBookView *book_view = find_book_view (bl); - g_warning ("ldap_result returned -1, restarting ops"); - - pas_backend_ldap_reconnect (bl, book_view, LDAP_SERVER_DOWN); -#if 0 - if (bl->priv->connected) - restart_ops (bl); -#endif - } - else { - int msgid = ldap_msgid (res); - LDAPOp *op; - - op = g_hash_table_lookup (bl->priv->id_to_op, &msgid); - - if (op) - op->handler (op, res); - else - g_warning ("unknown operation, msgid = %d", msgid); - - ldap_msgfree(res); - } - } - - g_get_current_time (&cur_time); - cur_millis = TV_TO_MILLIS (cur_time); - - iter = e_list_get_iterator (bl->priv->book_views); - while (e_iterator_is_valid (iter)) { - PASBackendLDAPBookView *view = (PASBackendLDAPBookView *)e_iterator_get (iter); - if (view->search_op) { - bonobo_object_dup_ref(bonobo_object_corba_objref(BONOBO_OBJECT(view->book_view)), NULL); - - ldap_search_op_timeout (view->search_op, cur_millis); - - bonobo_object_release_unref(bonobo_object_corba_objref(BONOBO_OBJECT(view->book_view)), NULL); - } - e_iterator_next (iter); - } - g_object_unref (iter); - - return TRUE; -} - -static void -send_pending_adds (LDAPSearchOp *search_op) -{ - search_op->num_sent_this_time += search_op->num_pending_adds; - pas_book_view_notify_add (search_op->op.view, search_op->pending_adds); - g_list_foreach (search_op->pending_adds, (GFunc)g_free, NULL); - g_list_free (search_op->pending_adds); - search_op->pending_adds = NULL; - search_op->num_pending_adds = 0; -} - -static void -ldap_search_op_timeout (LDAPOp *op, glong cur_millis) -{ - LDAPSearchOp *search_op = (LDAPSearchOp*)op; - - if (cur_millis - search_op->grouping_time_start > GROUPING_MINIMUM_WAIT) { - - if (search_op->num_pending_adds >= search_op->target_pending_adds) - send_pending_adds (search_op); - - if (cur_millis - search_op->grouping_time_start > GROUPING_MAXIMUM_WAIT) { - GTimeVal new_start; - - if (search_op->num_pending_adds) - send_pending_adds (search_op); - search_op->target_pending_adds = MIN (GROUPING_MAXIMUM_SIZE, - (search_op->num_sent_this_time + search_op->num_sent_last_time) / 2); - search_op->target_pending_adds = MAX (search_op->target_pending_adds, 1); - -#ifdef PERFORMANCE_SPEW - printf ("num sent this time %d, last time %d, target pending adds set to %d\n", - search_op->num_sent_this_time, - search_op->num_sent_last_time, - search_op->target_pending_adds); -#endif - g_get_current_time (&new_start); - search_op->grouping_time_start = TV_TO_MILLIS (new_start); - search_op->num_sent_last_time = search_op->num_sent_this_time; - search_op->num_sent_this_time = 0; - } - } -} - -static void -ldap_search_handler (LDAPOp *op, LDAPMessage *res) -{ - LDAPSearchOp *search_op = (LDAPSearchOp*)op; - PASBackendLDAPBookView *view = search_op->view; - PASBackendLDAP *bl = PAS_BACKEND_LDAP (op->backend); - LDAP *ldap = bl->priv->ldap; - LDAPMessage *e; - int msg_type; - - bonobo_object_dup_ref(bonobo_object_corba_objref(BONOBO_OBJECT(view->book_view)), NULL); - - if (!search_op->notified_receiving_results) { - search_op->notified_receiving_results = TRUE; - book_view_notify_status (op->view, _("Receiving LDAP search results...")); - } - - msg_type = ldap_msgtype (res); - if (msg_type == LDAP_RES_SEARCH_ENTRY) { - e = ldap_first_entry(ldap, res); - - while (NULL != e) { - ECardSimple *card = build_card_from_entry (ldap, e, NULL); - - search_op->pending_adds = g_list_append (search_op->pending_adds, - e_card_simple_get_vcard_assume_utf8 (card)); - search_op->num_pending_adds ++; - - g_object_unref (card); - - e = ldap_next_entry(ldap, e); - } - } - else if (msg_type == LDAP_RES_SEARCH_RESULT) { - int ldap_error; - - ldap_parse_result (ldap, res, &ldap_error, - NULL, NULL, NULL, NULL, 0); - - g_warning ("search returned %d\n", ldap_error); - - /* the entry that marks the end of our search */ - if (search_op->num_pending_adds) - send_pending_adds (search_op); - - if (ldap_error == LDAP_TIMELIMIT_EXCEEDED) - pas_book_view_notify_complete (search_op->op.view, GNOME_Evolution_Addressbook_BookViewListener_SearchTimeLimitExceeded); - else if (ldap_error == LDAP_SIZELIMIT_EXCEEDED) - pas_book_view_notify_complete (search_op->op.view, GNOME_Evolution_Addressbook_BookViewListener_SearchSizeLimitExceeded); - else if (ldap_error == LDAP_SUCCESS) - pas_book_view_notify_complete (search_op->op.view, GNOME_Evolution_Addressbook_BookViewListener_Success); - else - pas_book_view_notify_complete (search_op->op.view, GNOME_Evolution_Addressbook_BookViewListener_OtherError); - - ldap_op_finished (op); - } - else { - g_warning ("unhandled search result type %d returned", msg_type); - if (search_op->num_pending_adds) - send_pending_adds (search_op); - pas_book_view_notify_complete (search_op->op.view, GNOME_Evolution_Addressbook_BookViewListener_OtherError); - ldap_op_finished (op); - } - - - bonobo_object_release_unref(bonobo_object_corba_objref(BONOBO_OBJECT(view->book_view)), NULL); -} - -static void -ldap_search_dtor (LDAPOp *op) -{ - LDAPSearchOp *search_op = (LDAPSearchOp*) op; - - /* unhook us from our PASBackendLDAPBookView */ - if (search_op->view) - search_op->view->search_op = NULL; - - g_list_foreach (search_op->pending_adds, (GFunc)g_free, NULL); - g_list_free (search_op->pending_adds); - search_op->pending_adds = NULL; - search_op->num_pending_adds = 0; - - g_free (search_op); -} - -static void -pas_backend_ldap_search (PASBackendLDAP *bl, - PASBook *book, - PASBackendLDAPBookView *view) -{ - char *ldap_query; - - ldap_query = pas_backend_ldap_build_query(bl, view->search); - - if (ldap_query != NULL) { - LDAP *ldap = bl->priv->ldap; - int ldap_err; - GTimeVal search_start; - int search_msgid; - - printf ("searching server using filter: %s\n", ldap_query); - - do { - book_view_notify_status (view->book_view, _("Searching...")); - - ldap_err = ldap_search_ext (ldap, bl->priv->ldap_rootdn, - bl->priv->ldap_scope, - ldap_query, - NULL, 0, - NULL, /* XXX */ - NULL, /* XXX */ - NULL, /* XXX timeout */ - view->limit, &search_msgid); - } while (pas_backend_ldap_reconnect (bl, view->book_view, ldap_err)); - - g_free (ldap_query); - - if (ldap_err != LDAP_SUCCESS) { - book_view_notify_status (view->book_view, ldap_err2string(ldap_err)); - return; - } - else if (search_msgid == -1) { - book_view_notify_status (view->book_view, - _("Error performing search")); - return; - } - else { - LDAPSearchOp *op = g_new0 (LDAPSearchOp, 1); - - op->target_pending_adds = GROUPING_INITIAL_SIZE; - - g_get_current_time (&search_start); - op->grouping_time_start = TV_TO_MILLIS (search_start); - - op->view = view; - - view->search_op = (LDAPOp*)op; - - ldap_op_add ((LDAPOp*)op, PAS_BACKEND(bl), book, view->book_view, - search_msgid, - ldap_search_handler, ldap_search_dtor); - - } - return; - } - else { - pas_book_view_notify_complete (view->book_view, - GNOME_Evolution_Addressbook_BookViewListener_InvalidQuery); - return; - } - -} - -static void -ldap_get_view (PASBackend *backend, - PASBook *book, - const char *search, - GNOME_Evolution_Addressbook_BookViewListener listener, - int limit) -{ - PASBackendLDAP *bl = PAS_BACKEND_LDAP (backend); - PASBookView *book_view; - PASBackendLDAPBookView *view; - - book_view = pas_book_view_new (listener); - - bonobo_object_ref(BONOBO_OBJECT(book)); - g_object_weak_ref (G_OBJECT (book_view), view_destroy, book); - - view = g_new0(PASBackendLDAPBookView, 1); - view->book_view = book_view; - view->search = g_strdup(search); - view->card_sexp = pas_backend_card_sexp_new (view->search); - view->blpriv = bl->priv; - view->limit = limit; - - e_list_append(bl->priv->book_views, view); - - pas_book_respond_get_book_view (book, - (book_view != NULL - ? GNOME_Evolution_Addressbook_BookListener_Success - : GNOME_Evolution_Addressbook_BookListener_CardNotFound /* XXX */), - book_view); - - pas_backend_ldap_search (bl, book, view); - - bonobo_object_unref (BONOBO_OBJECT (book_view)); -} - -static void -pas_backend_ldap_process_get_book_view (PASBackend *backend, - PASBook *book, - PASGetBookViewRequest *req) -{ - PASBackendLDAP *bl = PAS_BACKEND_LDAP (backend); - - ldap_get_view (backend, book, req->search, req->listener, - bl->priv->ldap_limit); -} - -static void -pas_backend_ldap_process_get_completion_view (PASBackend *backend, - PASBook *book, - PASGetCompletionViewRequest *req) -{ - PASBackendLDAP *bl = PAS_BACKEND_LDAP (backend); - - ldap_get_view (backend, book, req->search, req->listener, - MIN (bl->priv->ldap_limit, 100)); -} - -static void -pas_backend_ldap_process_get_changes (PASBackend *backend, - PASBook *book, - PASGetChangesRequest *req) -{ - /* FIXME: implement */ -} - -static void -pas_backend_ldap_process_check_connection (PASBackend *backend, - PASBook *book, - PASCheckConnectionRequest *req) -{ - PASBackendLDAP *bl = PAS_BACKEND_LDAP (backend); - - pas_book_report_connection (book, bl->priv->connected); -} - -#define LDAP_SIMPLE_PREFIX "ldap/simple-" -#define SASL_PREFIX "sasl/" - -static void -pas_backend_ldap_process_authenticate_user (PASBackend *backend, - PASBook *book, - PASAuthenticateUserRequest *req) -{ - PASBackendLDAP *bl = PAS_BACKEND_LDAP (backend); - int ldap_error; - char *dn = NULL; - - if (!strncasecmp (req->auth_method, LDAP_SIMPLE_PREFIX, strlen (LDAP_SIMPLE_PREFIX))) { - - if (!strcmp (req->auth_method, "ldap/simple-email")) { - LDAPMessage *res, *e; - char *query = g_strdup_printf ("(mail=%s)", req->user); - - ldap_error = ldap_search_s (bl->priv->ldap, - bl->priv->ldap_rootdn, - bl->priv->ldap_scope, - query, - NULL, 0, &res); - g_free (query); - - if (ldap_error == LDAP_SUCCESS) { - char *entry_dn; - - e = ldap_first_entry (bl->priv->ldap, res); - - entry_dn = ldap_get_dn (bl->priv->ldap, e); - dn = g_strdup(entry_dn); - - ldap_memfree (entry_dn); - ldap_msgfree (res); - } - else { - pas_book_respond_authenticate_user (book, - GNOME_Evolution_Addressbook_BookListener_PermissionDenied); - return; - } - } - else if (!strcmp (req->auth_method, "ldap/simple-binddn")) { - dn = g_strdup (req->user); - } - - /* now authenticate against the DN we were either supplied or queried for */ - printf ("simple auth as %s\n", dn); - ldap_error = ldap_simple_bind_s(bl->priv->ldap, - dn, - req->passwd); - - pas_book_respond_authenticate_user (book, - ldap_error_to_response (ldap_error)); - } -#ifdef ENABLE_SASL_BINDS - else if (!strncasecmp (req->auth_method, SASL_PREFIX, strlen (SASL_PREFIX))) { - g_print ("sasl bind (mech = %s) as %s", req->auth_method + strlen (SASL_PREFIX), req->user); - ldap_error = ldap_sasl_bind_s (bl->priv->ldap, - NULL, - req->auth_method + strlen (SASL_PREFIX), - req->passwd, - NULL, - NULL, - NULL); - - if (ldap_error == LDAP_NOT_SUPPORTED) - pas_book_respond_authenticate_user (book, - GNOME_Evolution_Addressbook_BookListener_UnsupportedAuthenticationMethod); - else - pas_book_respond_authenticate_user (book, - ldap_error_to_response (ldap_error)); - } -#endif - else { - pas_book_respond_authenticate_user (book, - GNOME_Evolution_Addressbook_BookListener_UnsupportedAuthenticationMethod); - return; - } - - if (ldap_error == LDAP_SUCCESS) { - bl->priv->auth_dn = dn; - bl->priv->auth_passwd = g_strdup (req->passwd); - - pas_backend_set_is_writable (backend, TRUE); - - /* force a requery on the root dse since some ldap - servers are set up such that they don't report - anything (including the schema DN) until the user - is authenticated */ - if (!bl->priv->evolutionPersonChecked) { - ldap_error = query_ldap_root_dse (bl); - - if (LDAP_SUCCESS == ldap_error) { - if (!bl->priv->evolutionPersonChecked) - check_schema_support (bl); - } - else - g_warning ("Failed to perform root dse query after authenticating, (ldap_error 0x%02x)", ldap_error); - } - - pas_book_report_writable (book, TRUE); - } - -} - -static void -pas_backend_ldap_process_get_supported_fields (PASBackend *backend, - PASBook *book, - PASGetSupportedFieldsRequest *req) - -{ - PASBackendLDAP *bl = PAS_BACKEND_LDAP (backend); - - pas_book_respond_get_supported_fields (book, - GNOME_Evolution_Addressbook_BookListener_Success, - bl->priv->supported_fields); -} - -static void -pas_backend_ldap_process_get_supported_auth_methods (PASBackend *backend, - PASBook *book, - PASGetSupportedAuthMethodsRequest *req) - -{ - PASBackendLDAP *bl = PAS_BACKEND_LDAP (backend); - - pas_book_respond_get_supported_auth_methods (book, - GNOME_Evolution_Addressbook_BookListener_Success, - bl->priv->supported_auth_methods); -} - -static GNOME_Evolution_Addressbook_BookListener_CallStatus -pas_backend_ldap_load_uri (PASBackend *backend, - const char *uri) -{ - PASBackendLDAP *bl = PAS_BACKEND_LDAP (backend); - LDAPURLDesc *lud; - int ldap_error; - char **attributes; - int i; - int limit = 100; - int timeout = 60; /* 1 minute */ - - g_assert (bl->priv->connected == FALSE); - - attributes = g_strsplit (uri, ";", 0); - - if (attributes[0] == NULL) - return FALSE; - - for (i = 1; attributes[i]; i++) { - char *equals; - char *value; - int key_length; - equals = strchr (attributes[i], '='); - if (equals) { - key_length = equals - attributes[i]; - value = equals + 1; - } else { - key_length = strlen (attributes[i]); - value = NULL; - } - - if (key_length == strlen("limit") && !strncmp (attributes[i], "limit", key_length)) { - if (value) - limit = atoi(value); - } - else if (key_length == strlen("ssl") && !strncmp (attributes[i], "ssl", key_length)) { - if (value) { - if (!strncmp (value, "always", 6)) { - bl->priv->use_tls = PAS_BACKEND_LDAP_TLS_ALWAYS; - } - else if (!strncmp (value, "whenever_possible", 3)) { - bl->priv->use_tls = PAS_BACKEND_LDAP_TLS_WHEN_POSSIBLE; - } - else if (strncmp (value, "never", 5)) { - g_warning ("unhandled value for use_tls, not using it"); - } - } - else { - bl->priv->use_tls = PAS_BACKEND_LDAP_TLS_WHEN_POSSIBLE; - } - } - else if (key_length == strlen("timeout") && !strncmp (attributes[i], "timeout", key_length)) { - if (value) - timeout = atoi (value); - } - } - - ldap_error = ldap_url_parse ((char*)attributes[0], &lud); - g_strfreev (attributes); - - if (ldap_error == LDAP_SUCCESS) { - g_free(bl->priv->uri); - bl->priv->uri = g_strdup (uri); - bl->priv->ldap_host = g_strdup(lud->lud_host); - bl->priv->ldap_port = lud->lud_port; - /* if a port wasn't specified, default to LDAP_PORT */ - if (bl->priv->ldap_port == 0) - bl->priv->ldap_port = LDAP_PORT; - bl->priv->ldap_rootdn = g_strdup(lud->lud_dn); - bl->priv->ldap_limit = limit; - bl->priv->ldap_timeout = timeout; - bl->priv->ldap_scope = lud->lud_scope; - - ldap_free_urldesc(lud); - - return pas_backend_ldap_connect (bl); - } else - return GNOME_Evolution_Addressbook_BookListener_OtherError; -} - -/* Get_uri handler for the addressbook LDAP backend */ -static const char * -pas_backend_ldap_get_uri (PASBackend *backend) -{ - PASBackendLDAP *bl; - - bl = PAS_BACKEND_LDAP (backend); - return bl->priv->uri; -} - -static char* -pas_backend_ldap_get_static_capabilities (PASBackend *backend) -{ - return g_strdup("net"); -} - -static gboolean -pas_backend_ldap_construct (PASBackendLDAP *backend) -{ - g_assert (backend != NULL); - g_assert (PAS_IS_BACKEND_LDAP (backend)); - - if (! pas_backend_construct (PAS_BACKEND (backend))) - return FALSE; - - return TRUE; -} - -/** - * pas_backend_ldap_new: - */ -PASBackend * -pas_backend_ldap_new (void) -{ - PASBackendLDAP *backend; - - backend = g_object_new (PAS_TYPE_BACKEND_LDAP, NULL); - - if (! pas_backend_ldap_construct (backend)) { - g_object_unref (backend); - - return NULL; - } - - return PAS_BACKEND (backend); -} - -static gboolean -call_dtor (int msgid, LDAPOp *op, gpointer data) -{ - ldap_abandon (PAS_BACKEND_LDAP(op->backend)->priv->ldap, op->id); - - op->dtor (op); - - return TRUE; -} - -static void -pas_backend_ldap_dispose (GObject *object) -{ - PASBackendLDAP *bl; - - bl = PAS_BACKEND_LDAP (object); - - if (bl->priv) { - g_hash_table_foreach_remove (bl->priv->id_to_op, (GHRFunc)call_dtor, NULL); - g_hash_table_destroy (bl->priv->id_to_op); - - if (bl->priv->poll_timeout != -1) { - printf ("removing timeout\n"); - g_source_remove (bl->priv->poll_timeout); - } - - g_object_unref (bl->priv->book_views); - - if (bl->priv->supported_fields) - g_object_unref (bl->priv->supported_fields); - - if (bl->priv->supported_auth_methods) - g_object_unref (bl->priv->supported_auth_methods); - - g_free (bl->priv->uri); - - g_free (bl->priv); - bl->priv = NULL; - } - - if (G_OBJECT_CLASS (pas_backend_ldap_parent_class)->dispose) - G_OBJECT_CLASS (pas_backend_ldap_parent_class)->dispose (object); -} - -static void -pas_backend_ldap_class_init (PASBackendLDAPClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - PASBackendClass *parent_class; - - /* get client side information (extensions present in the library) */ - get_ldap_library_info (); - - pas_backend_ldap_parent_class = g_type_class_peek_parent (klass); - - parent_class = PAS_BACKEND_CLASS (klass); - - /* Set the virtual methods. */ - parent_class->load_uri = pas_backend_ldap_load_uri; - parent_class->get_uri = pas_backend_ldap_get_uri; - parent_class->get_static_capabilities = pas_backend_ldap_get_static_capabilities; - - parent_class->create_card = pas_backend_ldap_process_create_card; - parent_class->remove_cards = pas_backend_ldap_process_remove_cards; - parent_class->modify_card = pas_backend_ldap_process_modify_card; - parent_class->check_connection = pas_backend_ldap_process_check_connection; - parent_class->get_vcard = pas_backend_ldap_process_get_vcard; - parent_class->get_cursor = pas_backend_ldap_process_get_cursor; - parent_class->get_book_view = pas_backend_ldap_process_get_book_view; - parent_class->get_completion_view = pas_backend_ldap_process_get_completion_view; - parent_class->get_changes = pas_backend_ldap_process_get_changes; - parent_class->authenticate_user = pas_backend_ldap_process_authenticate_user; - parent_class->get_supported_fields = pas_backend_ldap_process_get_supported_fields; - parent_class->get_supported_auth_methods = pas_backend_ldap_process_get_supported_auth_methods; - - object_class->dispose = pas_backend_ldap_dispose; -} - -static void -pas_backend_ldap_init (PASBackendLDAP *backend) -{ - PASBackendLDAPPrivate *priv; - - priv = g_new0 (PASBackendLDAPPrivate, 1); - - priv->supported_fields = e_list_new ((EListCopyFunc)g_strdup, (EListFreeFunc)g_free, NULL); - priv->ldap_limit = 100; - priv->id_to_op = g_hash_table_new (g_int_hash, g_int_equal); - priv->poll_timeout = -1; - priv->book_views = e_list_new (NULL, NULL, NULL); - - backend->priv = priv; -} - -/** - * pas_backend_ldap_get_type: - */ -GType -pas_backend_ldap_get_type (void) -{ - static GType type = 0; - - if (! type) { - GTypeInfo info = { - sizeof (PASBackendLDAPClass), - NULL, /* base_class_init */ - NULL, /* base_class_finalize */ - (GClassInitFunc) pas_backend_ldap_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (PASBackendLDAP), - 0, /* n_preallocs */ - (GInstanceInitFunc) pas_backend_ldap_init - }; - - type = g_type_register_static (PAS_TYPE_BACKEND, "PASBackendLDAP", &info, 0); - } - - return type; -} diff --git a/addressbook/backend/pas/pas-backend-ldap.h b/addressbook/backend/pas/pas-backend-ldap.h deleted file mode 100644 index ca04ee6a21..0000000000 --- a/addressbook/backend/pas/pas-backend-ldap.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright 2000, Ximian, Inc. - */ - -#ifndef __PAS_BACKEND_LDAP_H__ -#define __PAS_BACKEND_LDAP_H__ - -#include "pas-backend.h" - -#define PAS_TYPE_BACKEND_LDAP (pas_backend_ldap_get_type ()) -#define PAS_BACKEND_LDAP(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), PAS_TYPE_BACKEND_LDAP, PASBackendLDAP)) -#define PAS_BACKEND_LDAP_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), PAS_BACKEND_TYPE, PASBackendLDAPClass)) -#define PAS_IS_BACKEND_LDAP(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), PAS_TYPE_BACKEND_LDAP)) -#define PAS_IS_BACKEND_LDAP_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), PAS_TYPE_BACKEND_LDAP)) -#define PAS_BACKEND_LDAP_GET_CLASS(k) (G_TYPE_INSTANCE_GET_CLASS ((obj), PAS_TYPE_BACKEND_LDAP, PASBackendLDAPClass)) - -typedef struct _PASBackendLDAPPrivate PASBackendLDAPPrivate; - -typedef struct { - PASBackend parent_object; - PASBackendLDAPPrivate *priv; -} PASBackendLDAP; - -typedef struct { - PASBackendClass parent_class; -} PASBackendLDAPClass; - -PASBackend *pas_backend_ldap_new (void); -GType pas_backend_ldap_get_type (void); - -#endif /* ! __PAS_BACKEND_LDAP_H__ */ - diff --git a/addressbook/backend/pas/pas-backend-summary.c b/addressbook/backend/pas/pas-backend-summary.c deleted file mode 100644 index 6c2c9a45c8..0000000000 --- a/addressbook/backend/pas/pas-backend-summary.c +++ /dev/null @@ -1,1092 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * pas-backend-summary.c - * Copyright 2000, 2001, Ximian, Inc. - * - * Authors: - * Chris Toshok <toshok@ximian.com> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License, version 2, as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - * 02111-1307, USA. - */ - -#include "config.h" - -#include <string.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <unistd.h> -#include <errno.h> - -#include <netinet/in.h> - -#include <gal/widgets/e-unicode.h> - -#include "ebook/e-card-simple.h" -#include "pas-backend-summary.h" -#include "e-util/e-sexp.h" - -static GObjectClass *parent_class; - -struct _PASBackendSummaryPrivate { - char *summary_path; - FILE *fp; - guint32 file_version; - time_t mtime; - gboolean upgraded; - gboolean dirty; - int flush_timeout_millis; - int flush_timeout; - GPtrArray *items; - GHashTable *id_to_item; - guint32 num_items; /* used only for loading */ -#ifdef SUMMARY_STATS - int size; -#endif -}; - -typedef struct { - char *id; - char *nickname; - char *full_name; - char *given_name; - char *surname; - char *file_as; - char *email_1; - char *email_2; - char *email_3; - gboolean wants_html; - gboolean wants_html_set; - gboolean list; - gboolean list_show_addresses; -} PASBackendSummaryItem; - -typedef struct { - /* these lengths do *not* including the terminating \0, as - it's not stored on disk. */ - guint16 id_len; - guint16 nickname_len; - guint16 full_name_len; /* version 3.0 field */ - guint16 given_name_len; - guint16 surname_len; - guint16 file_as_len; - guint16 email_1_len; - guint16 email_2_len; - guint16 email_3_len; - guint8 wants_html; - guint8 wants_html_set; - guint8 list; - guint8 list_show_addresses; -} PASBackendSummaryDiskItem; - -typedef struct { - guint32 file_version; - guint32 num_items; - guint32 summary_mtime; /* version 2.0 field */ -} PASBackendSummaryHeader; - -#define PAS_SUMMARY_MAGIC "PAS-SUMMARY" -#define PAS_SUMMARY_MAGIC_LEN 11 - -#define PAS_SUMMARY_FILE_VERSION_1_0 1000 -#define PAS_SUMMARY_FILE_VERSION_2_0 2000 -#define PAS_SUMMARY_FILE_VERSION_3_0 3000 -#define PAS_SUMMARY_FILE_VERSION_4_0 4000 - -#define PAS_SUMMARY_FILE_VERSION PAS_SUMMARY_FILE_VERSION_4_0 - -static void -free_summary_item (PASBackendSummaryItem *item) -{ - g_free (item->id); - g_free (item->nickname); - g_free (item->full_name); - g_free (item->given_name); - g_free (item->surname); - g_free (item->file_as); - g_free (item->email_1); - g_free (item->email_2); - g_free (item->email_3); - g_free (item); -} - -static void -clear_items (PASBackendSummary *summary) -{ - int i; - int num = summary->priv->items->len; - for (i = 0; i < num; i++) { - PASBackendSummaryItem *item = g_ptr_array_remove_index_fast (summary->priv->items, 0); - g_hash_table_remove (summary->priv->id_to_item, item->id); - free_summary_item (item); - } -} - -PASBackendSummary* -pas_backend_summary_new (const char *summary_path, int flush_timeout_millis) -{ - PASBackendSummary *summary = g_object_new (PAS_TYPE_BACKEND_SUMMARY, NULL); - - summary->priv->summary_path = g_strdup (summary_path); - summary->priv->flush_timeout_millis = flush_timeout_millis; - summary->priv->file_version = PAS_SUMMARY_FILE_VERSION_4_0; - - return summary; -} - -static void -pas_backend_summary_dispose (GObject *object) -{ - PASBackendSummary *summary = PAS_BACKEND_SUMMARY (object); - - if (summary->priv) { - if (summary->priv->dirty) - g_warning ("Destroying dirty summary"); - - if (summary->priv->flush_timeout) { - g_source_remove (summary->priv->flush_timeout); - summary->priv->flush_timeout = 0; - } - - if (summary->priv->fp) - fclose (summary->priv->fp); - - g_free (summary->priv->summary_path); - clear_items (summary); - g_ptr_array_free (summary->priv->items, TRUE); - - g_hash_table_destroy (summary->priv->id_to_item); - - g_free (summary->priv); - summary->priv = NULL; - } - - if (G_OBJECT_CLASS (parent_class)->dispose) - G_OBJECT_CLASS (parent_class)->dispose (object); -} - -static void -pas_backend_summary_class_init (PASBackendSummaryClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - parent_class = g_type_class_peek_parent (klass); - - /* Set the virtual methods. */ - - object_class->dispose = pas_backend_summary_dispose; -} - -static void -pas_backend_summary_init (PASBackendSummary *summary) -{ - PASBackendSummaryPrivate *priv; - - priv = g_new(PASBackendSummaryPrivate, 1); - - summary->priv = priv; - - priv->summary_path = NULL; - priv->fp = NULL; - priv->dirty = FALSE; - priv->upgraded = FALSE; - priv->items = g_ptr_array_new(); - priv->id_to_item = g_hash_table_new (g_str_hash, g_str_equal); - priv->flush_timeout_millis = 0; - priv->flush_timeout = 0; -#ifdef SUMMARY_STATS - priv->size = 0; -#endif -} - -/** - * pas_backend_summary_get_type: - */ -GType -pas_backend_summary_get_type (void) -{ - static GType type = 0; - - if (! type) { - GTypeInfo info = { - sizeof (PASBackendSummaryClass), - NULL, /* base_class_init */ - NULL, /* base_class_finalize */ - (GClassInitFunc) pas_backend_summary_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (PASBackendSummary), - 0, /* n_preallocs */ - (GInstanceInitFunc) pas_backend_summary_init - }; - - type = g_type_register_static (G_TYPE_OBJECT, "PASBackendSummary", &info, 0); - } - - return type; -} - - -static gboolean -pas_backend_summary_check_magic (PASBackendSummary *summary, FILE *fp) -{ - char buf [PAS_SUMMARY_MAGIC_LEN + 1]; - int rv; - - memset (buf, 0, sizeof (buf)); - - rv = fread (buf, PAS_SUMMARY_MAGIC_LEN, 1, fp); - if (rv != 1) - return FALSE; - if (strcmp (buf, PAS_SUMMARY_MAGIC)) - return FALSE; - - return TRUE; -} - -static gboolean -pas_backend_summary_load_header (PASBackendSummary *summary, FILE *fp, - PASBackendSummaryHeader *header) -{ - int rv; - - rv = fread (&header->file_version, sizeof (header->file_version), 1, fp); - if (rv != 1) - return FALSE; - - header->file_version = ntohl (header->file_version); - - if (header->file_version < PAS_SUMMARY_FILE_VERSION) { - return FALSE; /* this will cause the entire summary to be rebuilt */ - } - - rv = fread (&header->num_items, sizeof (header->num_items), 1, fp); - if (rv != 1) - return FALSE; - - header->num_items = ntohl (header->num_items); - - rv = fread (&header->summary_mtime, sizeof (header->summary_mtime), 1, fp); - if (rv != 1) - return FALSE; - header->summary_mtime = ntohl (header->summary_mtime); - - return TRUE; -} - -static char * -read_string (FILE *fp, int len) -{ - char *buf; - int rv; - - buf = g_new0 (char, len + 1); - - rv = fread (buf, len, 1, fp); - if (rv != 1) { - g_free (buf); - return NULL; - } - - return buf; -} - -static gboolean -pas_backend_summary_load_item (PASBackendSummary *summary, - PASBackendSummaryItem **new_item) -{ - PASBackendSummaryItem *item; - char *buf; - FILE *fp = summary->priv->fp; - - if (summary->priv->file_version >= PAS_SUMMARY_FILE_VERSION_4_0) { - PASBackendSummaryDiskItem disk_item; - int rv = fread (&disk_item, sizeof (disk_item), 1, fp); - if (rv != 1) - return FALSE; - - disk_item.id_len = ntohs (disk_item.id_len); - disk_item.nickname_len = ntohs (disk_item.nickname_len); - disk_item.full_name_len = ntohs (disk_item.full_name_len); - disk_item.given_name_len = ntohs (disk_item.given_name_len); - disk_item.surname_len = ntohs (disk_item.surname_len); - disk_item.file_as_len = ntohs (disk_item.file_as_len); - disk_item.email_1_len = ntohs (disk_item.email_1_len); - disk_item.email_2_len = ntohs (disk_item.email_2_len); - disk_item.email_3_len = ntohs (disk_item.email_3_len); - - item = g_new0 (PASBackendSummaryItem, 1); - - item->wants_html = disk_item.wants_html; - item->wants_html_set = disk_item.wants_html_set; - item->list = disk_item.list; - item->list_show_addresses = disk_item.list_show_addresses; - - if (disk_item.id_len) { - buf = read_string (fp, disk_item.id_len); - if (!buf) { - free_summary_item (item); - return FALSE; - } - item->id = buf; - } - - if (disk_item.nickname_len) { - buf = read_string (fp, disk_item.nickname_len); - if (!buf) { - free_summary_item (item); - return FALSE; - } - item->nickname = buf; - } - - if (disk_item.full_name_len) { - buf = read_string (fp, disk_item.full_name_len); - if (!buf) { - free_summary_item (item); - return FALSE; - } - item->full_name = buf; - } - - if (disk_item.given_name_len) { - buf = read_string (fp, disk_item.given_name_len); - if (!buf) { - free_summary_item (item); - return FALSE; - } - item->given_name = buf; - } - - if (disk_item.surname_len) { - buf = read_string (fp, disk_item.surname_len); - if (!buf) { - free_summary_item (item); - return FALSE; - } - item->surname = buf; - } - - if (disk_item.file_as_len) { - buf = read_string (fp, disk_item.file_as_len); - if (!buf) { - free_summary_item (item); - return FALSE; - } - item->file_as = buf; - } - - if (disk_item.email_1_len) { - buf = read_string (fp, disk_item.email_1_len); - if (!buf) { - free_summary_item (item); - return FALSE; - } - item->email_1 = buf; - } - - if (disk_item.email_2_len) { - buf = read_string (fp, disk_item.email_2_len); - if (!buf) { - free_summary_item (item); - return FALSE; - } - item->email_2 = buf; - } - - if (disk_item.email_3_len) { - buf = read_string (fp, disk_item.email_3_len); - if (!buf) { - free_summary_item (item); - return FALSE; - } - item->email_3 = buf; - } - - /* the only field that has to be there is the id */ - if (!item->id) { - free_summary_item (item); - return FALSE; - } - } - else { - /* unhandled file version */ - return FALSE; - } - - *new_item = item; - return TRUE; -} - -/* opens the file and loads the header */ -static gboolean -pas_backend_summary_open (PASBackendSummary *summary) -{ - FILE *fp; - PASBackendSummaryHeader header; - struct stat sb; - - if (summary->priv->fp) - return TRUE; - - if (stat (summary->priv->summary_path, &sb) == -1) { - /* if there's no summary present, look for the .new - file and rename it if it's there, and attempt to - load that */ - char *new_filename = g_strconcat (summary->priv->summary_path, ".new", NULL); - if (stat (new_filename, &sb) == -1) { - g_warning ("no summary present"); - g_free (new_filename); - return FALSE; - } - else { - rename (new_filename, summary->priv->summary_path); - g_free (new_filename); - } - } - - fp = fopen (summary->priv->summary_path, "r"); - if (!fp) { - g_warning ("failed to open summary file"); - return FALSE; - } - - if (!pas_backend_summary_check_magic (summary, fp)) { - g_warning ("file is not a valid summary file"); - fclose (fp); - return FALSE; - } - - if (!pas_backend_summary_load_header (summary, fp, &header)) { - g_warning ("failed to read summary header"); - fclose (fp); - return FALSE; - } - - summary->priv->num_items = header.num_items; - summary->priv->file_version = header.file_version; - summary->priv->mtime = header.summary_mtime; - summary->priv->fp = fp; - - return TRUE; -} - -gboolean -pas_backend_summary_load (PASBackendSummary *summary) -{ - PASBackendSummaryItem *new_item; - int i; - - if (!pas_backend_summary_open (summary)) - return FALSE; - - for (i = 0; i < summary->priv->num_items; i ++) { - if (!pas_backend_summary_load_item (summary, &new_item)) { - g_warning ("error while reading summary item"); - clear_items (summary); - fclose (summary->priv->fp); - summary->priv->fp = NULL; - summary->priv->dirty = FALSE; - return FALSE; - } - - g_ptr_array_add (summary->priv->items, new_item); - g_hash_table_insert (summary->priv->id_to_item, new_item->id, new_item); - } - - if (summary->priv->upgraded) { - pas_backend_summary_save (summary); - } - summary->priv->dirty = FALSE; - - return TRUE; -} - -static gboolean -pas_backend_summary_save_magic (FILE *fp) -{ - int rv; - rv = fwrite (PAS_SUMMARY_MAGIC, PAS_SUMMARY_MAGIC_LEN, 1, fp); - if (rv != 1) - return FALSE; - - return TRUE; -} - -static gboolean -pas_backend_summary_save_header (PASBackendSummary *summary, FILE *fp) -{ - PASBackendSummaryHeader header; - int rv; - - header.file_version = htonl (PAS_SUMMARY_FILE_VERSION); - header.num_items = htonl (summary->priv->items->len); - header.summary_mtime = htonl (time (NULL)); - - rv = fwrite (&header, sizeof (header), 1, fp); - if (rv != 1) - return FALSE; - - return TRUE; -} - -static gboolean -save_string (const char *str, FILE *fp) -{ - int rv; - - if (!str || !*str) - return TRUE; - - rv = fwrite (str, strlen (str), 1, fp); - return (rv == 1); -} - -static gboolean -pas_backend_summary_save_item (PASBackendSummary *summary, FILE *fp, PASBackendSummaryItem *item) -{ - PASBackendSummaryDiskItem disk_item; - int len; - int rv; - - len = item->id ? strlen (item->id) : 0; - disk_item.id_len = htons (len); - - len = item->nickname ? strlen (item->nickname) : 0; - disk_item.nickname_len = htons (len); - - len = item->given_name ? strlen (item->given_name) : 0; - disk_item.given_name_len = htons (len); - - len = item->full_name ? strlen (item->full_name) : 0; - disk_item.full_name_len = htons (len); - - len = item->surname ? strlen (item->surname) : 0; - disk_item.surname_len = htons (len); - - len = item->file_as ? strlen (item->file_as) : 0; - disk_item.file_as_len = htons (len); - - len = item->email_1 ? strlen (item->email_1) : 0; - disk_item.email_1_len = htons (len); - - len = item->email_2 ? strlen (item->email_2) : 0; - disk_item.email_2_len = htons (len); - - len = item->email_3 ? strlen (item->email_3) : 0; - disk_item.email_3_len = htons (len); - - disk_item.wants_html = item->wants_html; - disk_item.wants_html_set = item->wants_html_set; - disk_item.list = item->list; - disk_item.list_show_addresses = item->list_show_addresses; - - rv = fwrite (&disk_item, sizeof(disk_item), 1, fp); - if (rv != 1) - return FALSE; - - if (!save_string (item->id, fp)) - return FALSE; - if (!save_string (item->nickname, fp)) - return FALSE; - if (!save_string (item->full_name, fp)) - return FALSE; - if (!save_string (item->given_name, fp)) - return FALSE; - if (!save_string (item->surname, fp)) - return FALSE; - if (!save_string (item->file_as, fp)) - return FALSE; - if (!save_string (item->email_1, fp)) - return FALSE; - if (!save_string (item->email_2, fp)) - return FALSE; - if (!save_string (item->email_3, fp)) - return FALSE; - - return TRUE; -} - -gboolean -pas_backend_summary_save (PASBackendSummary *summary) -{ - struct stat sb; - FILE *fp = NULL; - char *new_filename = NULL; - int i; - - if (!summary->priv->dirty) - return TRUE; - - new_filename = g_strconcat (summary->priv->summary_path, ".new", NULL); - - fp = fopen (new_filename, "w"); - if (!fp) { - g_warning ("could not create new summary file"); - goto lose; - } - - if (!pas_backend_summary_save_magic (fp)) { - g_warning ("could not write magic to new summary file"); - goto lose; - } - - if (!pas_backend_summary_save_header (summary, fp)) { - g_warning ("could not write header to new summary file"); - goto lose; - } - - for (i = 0; i < summary->priv->items->len; i ++) { - PASBackendSummaryItem *item = g_ptr_array_index (summary->priv->items, i); - if (!pas_backend_summary_save_item (summary, fp, item)) { - g_warning ("failed to write an item to new summary file, errno = %d", errno); - goto lose; - } - } - - fclose (fp); - - /* if we have a queued flush, clear it (since we just flushed) */ - if (summary->priv->flush_timeout) { - g_source_remove (summary->priv->flush_timeout); - summary->priv->flush_timeout = 0; - } - - /* unlink the old summary and rename the new one */ - unlink (summary->priv->summary_path); - rename (new_filename, summary->priv->summary_path); - - g_free (new_filename); - - /* lastly, update the in memory mtime to that of the file */ - if (stat (summary->priv->summary_path, &sb) == -1) { - g_warning ("error stat'ing saved summary"); - } - else { - summary->priv->mtime = sb.st_mtime; - } - - return TRUE; - - lose: - if (fp) - fclose (fp); - if (new_filename) - unlink (new_filename); - g_free (new_filename); - return FALSE; -} - -void -pas_backend_summary_add_card (PASBackendSummary *summary, const char *vcard) -{ - ECard *card; - ECardSimple *simple; - PASBackendSummaryItem *new_item; - - card = e_card_new ((char*)vcard); - simple = e_card_simple_new (card); - - new_item = g_new (PASBackendSummaryItem, 1); - - new_item->id = g_strdup (e_card_simple_get_id (simple)); - new_item->nickname = e_card_simple_get (simple, E_CARD_SIMPLE_FIELD_NICKNAME); - new_item->full_name = e_card_simple_get (simple, E_CARD_SIMPLE_FIELD_FULL_NAME); - new_item->given_name = e_card_simple_get (simple, E_CARD_SIMPLE_FIELD_GIVEN_NAME); - new_item->surname = e_card_simple_get (simple, E_CARD_SIMPLE_FIELD_FAMILY_NAME); - new_item->file_as = e_card_simple_get (simple, E_CARD_SIMPLE_FIELD_FILE_AS); - new_item->email_1 = e_card_simple_get (simple, E_CARD_SIMPLE_FIELD_EMAIL); - new_item->email_2 = e_card_simple_get (simple, E_CARD_SIMPLE_FIELD_EMAIL_2); - new_item->email_3 = e_card_simple_get (simple, E_CARD_SIMPLE_FIELD_EMAIL_3); - new_item->list = e_card_evolution_list (card); - new_item->list_show_addresses = e_card_evolution_list_show_addresses (card); - new_item->wants_html = card->wants_html; - new_item->wants_html_set = card->wants_html_set; - - g_ptr_array_add (summary->priv->items, new_item); - g_hash_table_insert (summary->priv->id_to_item, new_item->id, new_item); - - g_object_unref (simple); - g_object_unref (card); - -#ifdef SUMMARY_STATS - summary->priv->size += sizeof (PASBackendSummaryItem); - summary->priv->size += new_item->id ? strlen (new_item->id) : 0; - summary->priv->size += new_item->nickname ? strlen (new_item->nickname) : 0; - summary->priv->size += new_item->full_name ? strlen (new_item->full_name) : 0; - summary->priv->size += new_item->given_name ? strlen (new_item->given_name) : 0; - summary->priv->size += new_item->surname ? strlen (new_item->surname) : 0; - summary->priv->size += new_item->file_as ? strlen (new_item->file_as) : 0; - summary->priv->size += new_item->email_1 ? strlen (new_item->email_1) : 0; - summary->priv->size += new_item->email_2 ? strlen (new_item->email_2) : 0; - summary->priv->size += new_item->email_3 ? strlen (new_item->email_3) : 0; -#endif - pas_backend_summary_touch (summary); -} - -void -pas_backend_summary_remove_card (PASBackendSummary *summary, const char *id) -{ - PASBackendSummaryItem *item = g_hash_table_lookup (summary->priv->id_to_item, id); - - if (item) { - g_ptr_array_remove (summary->priv->items, item); - g_hash_table_remove (summary->priv->id_to_item, id); - free_summary_item (item); - pas_backend_summary_touch (summary); - return; - } - - g_warning ("pas_backend_summary_remove_card: unable to locate id `%s'", id); -} - -static gboolean -summary_flush_func (gpointer data) -{ - PASBackendSummary *summary = PAS_BACKEND_SUMMARY (data); - - if (!summary->priv->dirty) { - summary->priv->flush_timeout = 0; - return FALSE; - } - - if (!pas_backend_summary_save (summary)) { - /* this isn't fatal, as we can just either 1) flush - out with the next change, or 2) regen the summary - when we next load the uri */ - g_warning ("failed to flush summary file to disk"); - return TRUE; /* try again after the next timeout */ - } - - g_warning ("flushed summary to disk"); - - /* we only want this to execute once, so return FALSE and set - summary->flush_timeout to 0 */ - summary->priv->flush_timeout = 0; - return FALSE; -} - -void -pas_backend_summary_touch (PASBackendSummary *summary) -{ - summary->priv->dirty = TRUE; - if (!summary->priv->flush_timeout - && summary->priv->flush_timeout_millis) - summary->priv->flush_timeout = g_timeout_add (summary->priv->flush_timeout_millis, - summary_flush_func, summary); -} - -gboolean -pas_backend_summary_is_up_to_date (PASBackendSummary *summary, time_t t) -{ - if (!pas_backend_summary_open (summary)) - return FALSE; - else - return summary->priv->mtime >= t; -} - - -/* we only want to do summary queries if the query is over the set fields in the summary */ - -static ESExpResult * -func_check(struct _ESExp *f, int argc, struct _ESExpResult **argv, void *data) -{ - ESExpResult *r; - int truth = FALSE; - - if (argc == 2 - && argv[0]->type == ESEXP_RES_STRING - && argv[1]->type == ESEXP_RES_STRING) { - char *query_name = argv[0]->value.string; - - if (!strcmp (query_name, "nickname") || - !strcmp (query_name, "full_name") || - !strcmp (query_name, "file_as") || - !strcmp (query_name, "email")) { - truth = TRUE; - } - } - - r = e_sexp_result_new(f, ESEXP_RES_BOOL); - r->value.bool = truth; - - return r; -} - -/* 'builtin' functions */ -static struct { - char *name; - ESExpFunc *func; - int type; /* set to 1 if a function can perform shortcut evaluation, or - doesn't execute everything, 0 otherwise */ -} check_symbols[] = { - { "contains", func_check, 0 }, - { "is", func_check, 0 }, - { "beginswith", func_check, 0 }, - { "endswith", func_check, 0 }, -}; - -gboolean -pas_backend_summary_is_summary_query (PASBackendSummary *summary, const char *query) -{ - ESExp *sexp; - ESExpResult *r; - gboolean retval; - int i; - int esexp_error; - - sexp = e_sexp_new(); - - for(i=0;i<sizeof(check_symbols)/sizeof(check_symbols[0]);i++) { - if (check_symbols[i].type == 1) { - e_sexp_add_ifunction(sexp, 0, check_symbols[i].name, - (ESExpIFunc *)check_symbols[i].func, summary); - } else { - e_sexp_add_function(sexp, 0, check_symbols[i].name, - check_symbols[i].func, summary); - } - } - - e_sexp_input_text(sexp, query, strlen(query)); - esexp_error = e_sexp_parse(sexp); - - if (esexp_error == -1) { - return FALSE; - } - - r = e_sexp_eval(sexp); - - retval = (r && r->type == ESEXP_RES_BOOL && r->value.bool); - - e_sexp_result_free(sexp, r); - - e_sexp_unref (sexp); - - return retval; -} - - - -/* the actual query mechanics */ -static ESExpResult * -do_compare (PASBackendSummary *summary, struct _ESExp *f, int argc, - struct _ESExpResult **argv, - char *(*compare)(const char*, const char*)) -{ - GPtrArray *result = g_ptr_array_new (); - ESExpResult *r; - int i; - - if (argc == 2 - && argv[0]->type == ESEXP_RES_STRING - && argv[1]->type == ESEXP_RES_STRING) { - - for (i = 0; i < summary->priv->items->len; i ++) { - PASBackendSummaryItem *item = g_ptr_array_index (summary->priv->items, i); - if (!strcmp (argv[0]->value.string, "full_name")) { - char *given = item->given_name; - char *surname = item->surname; - if ((given && compare (given, argv[1]->value.string)) - || (surname && compare (surname, argv[1]->value.string))) - g_ptr_array_add (result, item->id); - } - else if (!strcmp (argv[0]->value.string, "email")) { - char *email_1 = item->email_1; - char *email_2 = item->email_2; - char *email_3 = item->email_3; - if ((email_1 && compare (email_1, argv[1]->value.string)) - || (email_2 && compare (email_2, argv[1]->value.string)) - || (email_3 && compare (email_3, argv[1]->value.string))) - g_ptr_array_add (result, item->id); - } - else if (!strcmp (argv[0]->value.string, "file_as")) { - char *file_as = item->file_as; - if (file_as && compare (file_as, argv[1]->value.string)) - g_ptr_array_add (result, item->id); - } - else if (!strcmp (argv[0]->value.string, "nickname")) { - char *nickname = item->nickname; - if (nickname && compare (nickname, argv[1]->value.string)) - g_ptr_array_add (result, item->id); - } - } - } - - r = e_sexp_result_new(f, ESEXP_RES_ARRAY_PTR); - r->value.ptrarray = result; - - return r; -} - -static ESExpResult * -func_contains(struct _ESExp *f, int argc, struct _ESExpResult **argv, void *data) -{ - PASBackendSummary *summary = data; - - return do_compare (summary, f, argc, argv, (char *(*)(const char*, const char*)) e_utf8_strstrcase); -} - -static char * -is_helper (const char *s1, const char *s2) -{ - if (!strcasecmp(s1, s2)) - return (char*)s1; - else - return NULL; -} - -static ESExpResult * -func_is(struct _ESExp *f, int argc, struct _ESExpResult **argv, void *data) -{ - PASBackendSummary *summary = data; - - return do_compare (summary, f, argc, argv, is_helper); -} - -static char * -endswith_helper (const char *s1, const char *s2) -{ - char *p; - if ((p = (char*)e_utf8_strstrcase(s1, s2)) - && (strlen(p) == strlen(s2))) - return p; - else - return NULL; -} - -static ESExpResult * -func_endswith(struct _ESExp *f, int argc, struct _ESExpResult **argv, void *data) -{ - PASBackendSummary *summary = data; - - return do_compare (summary, f, argc, argv, endswith_helper); -} - -static char * -beginswith_helper (const char *s1, const char *s2) -{ - char *p; - if ((p = (char*)e_utf8_strstrcase(s1, s2)) - && (p == s1)) - return p; - else - return NULL; -} - -static ESExpResult * -func_beginswith(struct _ESExp *f, int argc, struct _ESExpResult **argv, void *data) -{ - PASBackendSummary *summary = data; - - return do_compare (summary, f, argc, argv, beginswith_helper); -} - -/* 'builtin' functions */ -static struct { - char *name; - ESExpFunc *func; - int type; /* set to 1 if a function can perform shortcut evaluation, or - doesn't execute everything, 0 otherwise */ -} symbols[] = { - { "contains", func_contains, 0 }, - { "is", func_is, 0 }, - { "beginswith", func_beginswith, 0 }, - { "endswith", func_endswith, 0 }, -}; - -GPtrArray* -pas_backend_summary_search (PASBackendSummary *summary, const char *query) -{ - ESExp *sexp; - ESExpResult *r; - GPtrArray *retval = g_ptr_array_new(); - int i; - int esexp_error; - - sexp = e_sexp_new(); - - for(i=0;i<sizeof(symbols)/sizeof(symbols[0]);i++) { - if (symbols[i].type == 1) { - e_sexp_add_ifunction(sexp, 0, symbols[i].name, - (ESExpIFunc *)symbols[i].func, summary); - } else { - e_sexp_add_function(sexp, 0, symbols[i].name, - symbols[i].func, summary); - } - } - - e_sexp_input_text(sexp, query, strlen(query)); - esexp_error = e_sexp_parse(sexp); - - if (esexp_error == -1) { - return NULL; - } - - r = e_sexp_eval(sexp); - - if (r && r->type == ESEXP_RES_ARRAY_PTR && r->value.ptrarray) { - GPtrArray *ptrarray = r->value.ptrarray; - int i; - - for (i = 0; i < ptrarray->len; i ++) - g_ptr_array_add (retval, g_ptr_array_index (ptrarray, i)); - } - - e_sexp_result_free(sexp, r); - - e_sexp_unref (sexp); - - return retval; -} - -char* -pas_backend_summary_get_summary_vcard(PASBackendSummary *summary, const char *id) -{ - PASBackendSummaryItem *item = g_hash_table_lookup (summary->priv->id_to_item, id); - - if (item) { - ECard *card = e_card_new (""); - ECardSimple *simple = e_card_simple_new (card); - char *vcard; - - e_card_simple_set_id (simple, item->id); - e_card_simple_set (simple, E_CARD_SIMPLE_FIELD_FILE_AS, item->file_as); - e_card_simple_set (simple, E_CARD_SIMPLE_FIELD_GIVEN_NAME, item->given_name); - e_card_simple_set (simple, E_CARD_SIMPLE_FIELD_FAMILY_NAME, item->surname); - e_card_simple_set (simple, E_CARD_SIMPLE_FIELD_NICKNAME, item->nickname); - e_card_simple_set (simple, E_CARD_SIMPLE_FIELD_FULL_NAME, item->full_name); - e_card_simple_set_email (simple, E_CARD_SIMPLE_EMAIL_ID_EMAIL, item->email_1); - e_card_simple_set_email (simple, E_CARD_SIMPLE_EMAIL_ID_EMAIL_2, item->email_2); - e_card_simple_set_email (simple, E_CARD_SIMPLE_EMAIL_ID_EMAIL_3, item->email_3); - - e_card_simple_sync_card (simple); - - card->list = item->list; - card->wants_html = item->wants_html; - card->wants_html_set = item->wants_html_set; - card->list_show_addresses = item->list_show_addresses; - - vcard = e_card_simple_get_vcard (simple); - - g_object_unref (simple); - g_object_unref (card); - - return vcard; - } - else { - g_warning ("in unable to locate card `%s' in summary", id); - return NULL; - } -} - diff --git a/addressbook/backend/pas/pas-backend-summary.h b/addressbook/backend/pas/pas-backend-summary.h deleted file mode 100644 index 54083855d5..0000000000 --- a/addressbook/backend/pas/pas-backend-summary.h +++ /dev/null @@ -1,70 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * pas-backend-summary.h - * Copyright 2000, 2001, Ximian, Inc. - * - * Authors: - * Chris Toshok <toshok@ximian.com> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License, version 2, as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - * 02111-1307, USA. - */ - -#ifndef __PAS_BACKEND_SUMMARY_H__ -#define __PAS_BACKEND_SUMMARY_H__ - -#include <glib.h> -#include <glib-object.h> - -#define PAS_TYPE_BACKEND_SUMMARY (pas_backend_summary_get_type ()) -#define PAS_BACKEND_SUMMARY(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), PAS_TYPE_BACKEND_SUMMARY, PASBackendSummary)) -#define PAS_BACKEND_SUMMARY_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), PAS_BACKEND_TYPE, PASBackendSummaryClass)) -#define PAS_IS_BACKEND_SUMMARY(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), PAS_TYPE_BACKEND_SUMMARY)) -#define PAS_IS_BACKEND_SUMMARY_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), PAS_TYPE_BACKEND_SUMMARY)) -#define PAS_BACKEND_SUMMARY_GET_CLASS(k) (G_TYPE_INSTANCE_GET_CLASS ((obj), PAS_TYPE_BACKEND_SUMMARY, PASBackendSummaryClass)) - -typedef struct _PASBackendSummaryPrivate PASBackendSummaryPrivate; - -typedef struct { - GObject parent_object; - PASBackendSummaryPrivate *priv; -} PASBackendSummary; - -typedef struct { - GObjectClass parent_class; -} PASBackendSummaryClass; - -PASBackendSummary* pas_backend_summary_new (const char *summary_path, - int flush_timeout_millis); -GType pas_backend_summary_get_type (void); - -/* returns FALSE if the load fails for any reason (including that the - summary is out of date), TRUE if it succeeds */ -gboolean pas_backend_summary_load (PASBackendSummary *summary); -/* returns FALSE if the save fails, TRUE if it succeeds (or isn't required due to no changes) */ -gboolean pas_backend_summary_save (PASBackendSummary *summary); - -void pas_backend_summary_add_card (PASBackendSummary *summary, const char *vcard); -void pas_backend_summary_remove_card (PASBackendSummary *summary, const char *id); - -void pas_backend_summary_touch (PASBackendSummary *summary); - -/* returns TRUE if the summary's mtime is >= @t. */ -gboolean pas_backend_summary_is_up_to_date (PASBackendSummary *summary, time_t t); - -gboolean pas_backend_summary_is_summary_query (PASBackendSummary *summary, const char *query); -GPtrArray* pas_backend_summary_search (PASBackendSummary *summary, const char *query); -char* pas_backend_summary_get_summary_vcard (PASBackendSummary *summary, const char *id); - -#endif /* __PAS_BACKEND_SUMMARY_H__ */ diff --git a/addressbook/backend/pas/pas-backend.c b/addressbook/backend/pas/pas-backend.c deleted file mode 100644 index acc6ed2a2c..0000000000 --- a/addressbook/backend/pas/pas-backend.c +++ /dev/null @@ -1,518 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * Author: - * Nat Friedman (nat@ximian.com) - * - * Copyright 2000, Ximian, Inc. - */ - -#include <config.h> -#include "pas-backend.h" -#include "pas-marshal.h" - -struct _PASBackendPrivate { - GList *clients; - gboolean loaded, writable; -}; - -/* Signal IDs */ -enum { - LAST_CLIENT_GONE, - LAST_SIGNAL -}; - -static guint pas_backend_signals[LAST_SIGNAL]; - -static GObjectClass *parent_class; - -gboolean -pas_backend_construct (PASBackend *backend) -{ - return TRUE; -} - -GNOME_Evolution_Addressbook_BookListener_CallStatus -pas_backend_load_uri (PASBackend *backend, - const char *uri) -{ - g_return_val_if_fail (backend != NULL, FALSE); - g_return_val_if_fail (PAS_IS_BACKEND (backend), FALSE); - g_return_val_if_fail (uri != NULL, FALSE); - g_return_val_if_fail (backend->priv->loaded == FALSE, FALSE); - - g_assert (PAS_BACKEND_GET_CLASS (backend)->load_uri != NULL); - - return (* PAS_BACKEND_GET_CLASS (backend)->load_uri) (backend, uri); -} - -/** - * pas_backend_get_uri: - * @backend: An addressbook backend. - * - * Queries the URI that an addressbook backend is serving. - * - * Return value: URI for the backend. - **/ -const char * -pas_backend_get_uri (PASBackend *backend) -{ - g_return_val_if_fail (backend != NULL, NULL); - g_return_val_if_fail (PAS_IS_BACKEND (backend), NULL); - - g_assert (PAS_BACKEND_GET_CLASS (backend)->get_uri != NULL); - - return (* PAS_BACKEND_GET_CLASS (backend)->get_uri) (backend); -} - - -void -pas_backend_create_card (PASBackend *backend, - PASBook *book, - PASCreateCardRequest *req) -{ - g_return_if_fail (PAS_IS_BACKEND (backend)); - g_return_if_fail (PAS_IS_BOOK (book)); - g_return_if_fail (req != NULL && req->vcard != NULL); - - g_assert (PAS_BACKEND_GET_CLASS (backend)->create_card != NULL); - - (* PAS_BACKEND_GET_CLASS (backend)->create_card) (backend, book, req); -} - -void -pas_backend_remove_cards (PASBackend *backend, - PASBook *book, - PASRemoveCardsRequest *req) -{ - g_return_if_fail (PAS_IS_BACKEND (backend)); - g_return_if_fail (PAS_IS_BOOK (book)); - g_return_if_fail (req != NULL && req->ids != NULL); - - g_assert (PAS_BACKEND_GET_CLASS (backend)->remove_cards != NULL); - - (* PAS_BACKEND_GET_CLASS (backend)->remove_cards) (backend, book, req); -} - -void -pas_backend_modify_card (PASBackend *backend, - PASBook *book, - PASModifyCardRequest *req) -{ - g_return_if_fail (PAS_IS_BACKEND (backend)); - g_return_if_fail (PAS_IS_BOOK (book)); - g_return_if_fail (req != NULL && req->vcard != NULL); - - g_assert (PAS_BACKEND_GET_CLASS (backend)->modify_card != NULL); - - (* PAS_BACKEND_GET_CLASS (backend)->modify_card) (backend, book, req); -} - -void -pas_backend_check_connection (PASBackend *backend, - PASBook *book, - PASCheckConnectionRequest *req) -{ - g_return_if_fail (PAS_IS_BACKEND (backend)); - g_return_if_fail (PAS_IS_BOOK (book)); - g_return_if_fail (req != NULL); - - g_assert (PAS_BACKEND_GET_CLASS (backend)->check_connection != NULL); - - (* PAS_BACKEND_GET_CLASS (backend)->check_connection) (backend, book, req); -} - -void -pas_backend_get_vcard (PASBackend *backend, - PASBook *book, - PASGetVCardRequest *req) -{ - g_return_if_fail (PAS_IS_BACKEND (backend)); - g_return_if_fail (PAS_IS_BOOK (book)); - g_return_if_fail (req != NULL && req->id != NULL); - - g_assert (PAS_BACKEND_GET_CLASS (backend)->get_vcard != NULL); - - (* PAS_BACKEND_GET_CLASS (backend)->get_vcard) (backend, book, req); -} - -void -pas_backend_get_cursor (PASBackend *backend, - PASBook *book, - PASGetCursorRequest *req) -{ - g_return_if_fail (PAS_IS_BACKEND (backend)); - g_return_if_fail (PAS_IS_BOOK (book)); - g_return_if_fail (req != NULL && req->search != NULL); - - g_assert (PAS_BACKEND_GET_CLASS (backend)->get_cursor != NULL); - - (* PAS_BACKEND_GET_CLASS (backend)->get_cursor) (backend, book, req); -} - -void -pas_backend_get_book_view (PASBackend *backend, - PASBook *book, - PASGetBookViewRequest *req) -{ - g_return_if_fail (PAS_IS_BACKEND (backend)); - g_return_if_fail (PAS_IS_BOOK (book)); - g_return_if_fail (req != NULL && req->search != NULL && req->listener != CORBA_OBJECT_NIL); - - g_assert (PAS_BACKEND_GET_CLASS (backend)->get_book_view != NULL); - - (* PAS_BACKEND_GET_CLASS (backend)->get_book_view) (backend, book, req); -} - -void -pas_backend_get_completion_view (PASBackend *backend, - PASBook *book, - PASGetCompletionViewRequest *req) -{ - g_return_if_fail (PAS_IS_BACKEND (backend)); - g_return_if_fail (PAS_IS_BOOK (book)); - g_return_if_fail (req != NULL && req->search != NULL && req->listener != CORBA_OBJECT_NIL); - - g_assert (PAS_BACKEND_GET_CLASS (backend)->get_completion_view != NULL); - - (* PAS_BACKEND_GET_CLASS (backend)->get_completion_view) (backend, book, req); -} - -void -pas_backend_get_changes (PASBackend *backend, - PASBook *book, - PASGetChangesRequest *req) -{ - g_return_if_fail (PAS_IS_BACKEND (backend)); - g_return_if_fail (PAS_IS_BOOK (book)); - g_return_if_fail (req != NULL && req->change_id != NULL && req->listener != CORBA_OBJECT_NIL); - - g_assert (PAS_BACKEND_GET_CLASS (backend)->get_changes != NULL); - - (* PAS_BACKEND_GET_CLASS (backend)->get_changes) (backend, book, req); -} - -void -pas_backend_authenticate_user (PASBackend *backend, - PASBook *book, - PASAuthenticateUserRequest *req) -{ - g_return_if_fail (PAS_IS_BACKEND (backend)); - g_return_if_fail (PAS_IS_BOOK (book)); - g_return_if_fail (req != NULL); - - g_assert (PAS_BACKEND_GET_CLASS (backend)->authenticate_user != NULL); - - (* PAS_BACKEND_GET_CLASS (backend)->authenticate_user) (backend, book, req); -} - -void -pas_backend_get_supported_fields (PASBackend *backend, - PASBook *book, - PASGetSupportedFieldsRequest *req) -{ - g_return_if_fail (PAS_IS_BACKEND (backend)); - g_return_if_fail (PAS_IS_BOOK (book)); - g_return_if_fail (req != NULL); - - g_assert (PAS_BACKEND_GET_CLASS (backend)->get_supported_fields != NULL); - - (* PAS_BACKEND_GET_CLASS (backend)->get_supported_fields) (backend, book, req); -} - -void -pas_backend_get_supported_auth_methods (PASBackend *backend, - PASBook *book, - PASGetSupportedAuthMethodsRequest *req) -{ - g_return_if_fail (PAS_IS_BACKEND (backend)); - g_return_if_fail (PAS_IS_BOOK (book)); - g_return_if_fail (req != NULL); - - g_assert (PAS_BACKEND_GET_CLASS (backend)->get_supported_auth_methods != NULL); - - (* PAS_BACKEND_GET_CLASS (backend)->get_supported_auth_methods) (backend, book, req); -} - -static void -process_client_requests (PASBook *book, gpointer user_data) -{ - PASBackend *backend; - PASRequest *req; - - backend = PAS_BACKEND (user_data); - - req = pas_book_pop_request (book); - if (req == NULL) - return; - - switch (req->op) { - case CreateCard: - pas_backend_create_card (backend, book, &req->create); - break; - - case RemoveCards: - pas_backend_remove_cards (backend, book, &req->remove); - break; - - case ModifyCard: - pas_backend_modify_card (backend, book, &req->modify); - break; - - case CheckConnection: - pas_backend_check_connection (backend, book, &req->check_connection); - break; - - case GetVCard: - pas_backend_get_vcard (backend, book, &req->get_vcard); - break; - - case GetCursor: - pas_backend_get_cursor (backend, book, &req->get_cursor); - break; - - case GetBookView: - pas_backend_get_book_view (backend, book, &req->get_book_view); - break; - - case GetCompletionView: - pas_backend_get_completion_view (backend, book, &req->get_completion_view); - break; - - case GetChanges: - pas_backend_get_changes (backend, book, &req->get_changes); - break; - - case AuthenticateUser: - pas_backend_authenticate_user (backend, book, &req->auth_user); - break; - - case GetSupportedFields: - pas_backend_get_supported_fields (backend, book, &req->get_supported_fields); - break; - - case GetSupportedAuthMethods: - pas_backend_get_supported_auth_methods (backend, book, &req->get_supported_auth_methods); - break; - } - - pas_book_free_request (req); -} - -static void -book_destroy_cb (gpointer data, GObject *where_book_was) -{ - PASBackend *backend = PAS_BACKEND (data); - - pas_backend_remove_client (backend, (PASBook *)where_book_was); -} - -static void -last_client_gone (PASBackend *backend) -{ - g_signal_emit (backend, pas_backend_signals[LAST_CLIENT_GONE], 0); -} - -static gboolean -add_client (PASBackend *backend, - GNOME_Evolution_Addressbook_BookListener listener) -{ - PASBook *book; - - book = pas_book_new (backend, listener); - if (!book) { - if (!backend->priv->clients) - last_client_gone (backend); - - return FALSE; - } - - g_object_weak_ref (G_OBJECT (book), book_destroy_cb, backend); - - g_signal_connect (book, "requests_queued", - G_CALLBACK (process_client_requests), backend); - - backend->priv->clients = g_list_prepend (backend->priv->clients, book); - - if (backend->priv->loaded) { - pas_book_respond_open ( - book, GNOME_Evolution_Addressbook_BookListener_Success); - } else { - pas_book_respond_open ( - book, GNOME_Evolution_Addressbook_BookListener_OtherError); - } - - pas_book_report_writable (book, backend->priv->writable); - - bonobo_object_unref (BONOBO_OBJECT (book)); - - return TRUE; -} - -/** - * pas_backend_add_client: - * @backend: An addressbook backend. - * @listener: Listener for notification to the client. - * - * Adds a client to an addressbook backend. - * - * Return value: TRUE on success, FALSE on failure to add the client. - */ -gboolean -pas_backend_add_client (PASBackend *backend, - GNOME_Evolution_Addressbook_BookListener listener) -{ - g_return_val_if_fail (PAS_IS_BACKEND (backend), FALSE); - g_return_val_if_fail (listener != CORBA_OBJECT_NIL, FALSE); - - g_assert (PAS_BACKEND_GET_CLASS (backend)->add_client != NULL); - - return PAS_BACKEND_GET_CLASS (backend)->add_client (backend, listener); -} - -static void -remove_client (PASBackend *backend, - PASBook *book) -{ - /* Disconnect */ - backend->priv->clients = g_list_remove (backend->priv->clients, book); - - /* When all clients go away, notify the parent factory about it so that - * it may decide whether to kill the backend or not. - */ - if (!backend->priv->clients) - last_client_gone (backend); -} - -void -pas_backend_remove_client (PASBackend *backend, - PASBook *book) -{ - g_return_if_fail (PAS_IS_BACKEND (backend)); - g_return_if_fail (PAS_IS_BOOK (book)); - - g_assert (PAS_BACKEND_GET_CLASS (backend)->remove_client != NULL); - - PAS_BACKEND_GET_CLASS (backend)->remove_client (backend, book); -} - -char * -pas_backend_get_static_capabilities (PASBackend *backend) -{ - g_return_val_if_fail (backend != NULL, NULL); - g_return_val_if_fail (PAS_IS_BACKEND (backend), NULL); - - g_assert (PAS_BACKEND_GET_CLASS (backend)->get_static_capabilities != NULL); - - return PAS_BACKEND_GET_CLASS (backend)->get_static_capabilities (backend); -} - -gboolean -pas_backend_is_loaded (PASBackend *backend) -{ - g_return_val_if_fail (PAS_IS_BACKEND (backend), FALSE); - - return backend->priv->loaded; -} - -void -pas_backend_set_is_loaded (PASBackend *backend, gboolean is_loaded) -{ - g_return_if_fail (PAS_IS_BACKEND (backend)); - - backend->priv->loaded = is_loaded; -} - -gboolean -pas_backend_is_writable (PASBackend *backend) -{ - g_return_val_if_fail (PAS_IS_BACKEND (backend), FALSE); - - return backend->priv->writable; -} - -void -pas_backend_set_is_writable (PASBackend *backend, gboolean is_writable) -{ - g_return_if_fail (PAS_IS_BACKEND (backend)); - - backend->priv->writable = is_writable; -} - -static void -pas_backend_init (PASBackend *backend) -{ - PASBackendPrivate *priv; - - priv = g_new0 (PASBackendPrivate, 1); - priv->clients = NULL; - - backend->priv = priv; -} - -static void -pas_backend_dispose (GObject *object) -{ - PASBackend *backend; - - backend = PAS_BACKEND (object); - - if (backend->priv) { - g_list_free (backend->priv->clients); - g_free (backend->priv); - - backend->priv = NULL; - } - - G_OBJECT_CLASS (parent_class)->dispose (object); -} - -static void -pas_backend_class_init (PASBackendClass *klass) -{ - GObjectClass *object_class; - - parent_class = g_type_class_peek_parent (klass); - - object_class = (GObjectClass *) klass; - - klass->add_client = add_client; - klass->remove_client = remove_client; - - object_class->dispose = pas_backend_dispose; - - pas_backend_signals[LAST_CLIENT_GONE] = - g_signal_new ("last_client_gone", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (PASBackendClass, last_client_gone), - NULL, NULL, - pas_marshal_NONE__NONE, - G_TYPE_NONE, 0); -} - -/** - * pas_backend_get_type: - */ -GType -pas_backend_get_type (void) -{ - static GType type = 0; - - if (! type) { - GTypeInfo info = { - sizeof (PASBackendClass), - NULL, /* base_class_init */ - NULL, /* base_class_finalize */ - (GClassInitFunc) pas_backend_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (PASBackend), - 0, /* n_preallocs */ - (GInstanceInitFunc) pas_backend_init - }; - - type = g_type_register_static (G_TYPE_OBJECT, "PASBackend", &info, 0); - } - - return type; -} diff --git a/addressbook/backend/pas/pas-backend.h b/addressbook/backend/pas/pas-backend.h deleted file mode 100644 index b33518116e..0000000000 --- a/addressbook/backend/pas/pas-backend.h +++ /dev/null @@ -1,140 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * An abstract class which defines the API to a given backend. - * There will be one PASBackend object for every URI which is loaded. - * - * Two people will call into the PASBackend API: - * - * 1. The PASBookFactory, when it has been asked to load a book. - * It will create a new PASBackend if one is not already running - * for the requested URI. It will call pas_backend_add_client to - * add a new client to an existing PASBackend server. - * - * 2. A PASBook, when a client has requested an operation on the - * GNOME_Evolution_Addressbook_Book interface. - * - * Author: - * Nat Friedman (nat@ximian.com) - * - * Copyright 2000, Ximian, Inc. - */ - -#ifndef __PAS_BACKEND_H__ -#define __PAS_BACKEND_H__ - -#include <glib.h> -#include <glib-object.h> -#include <pas/addressbook.h> - -#define PAS_TYPE_BACKEND (pas_backend_get_type ()) -#define PAS_BACKEND(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), PAS_TYPE_BACKEND, PASBackend)) -#define PAS_BACKEND_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), PAS_TYPE_BACKEND, PASBackendClass)) -#define PAS_IS_BACKEND(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), PAS_TYPE_BACKEND)) -#define PAS_IS_BACKEND_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), PAS_TYPE_BACKEND)) -#define PAS_BACKEND_GET_CLASS(k) (G_TYPE_INSTANCE_GET_CLASS ((k), PAS_TYPE_BACKEND, PASBackendClass)) - -typedef struct _PASBackend PASBackend; -typedef struct _PASBackendPrivate PASBackendPrivate; - -#include <pas/pas-book.h> - -struct _PASBackend { - GObject parent_object; - PASBackendPrivate *priv; -}; - -typedef struct { - GObjectClass parent_class; - - /* Virtual methods */ - GNOME_Evolution_Addressbook_BookListener_CallStatus (*load_uri) (PASBackend *backend, const char *uri); - const char *(* get_uri) (PASBackend *backend); - gboolean (*add_client) (PASBackend *backend, GNOME_Evolution_Addressbook_BookListener listener); - void (*remove_client) (PASBackend *backend, PASBook *book); - char *(*get_static_capabilities) (PASBackend *backend); - - void (*create_card) (PASBackend *backend, PASBook *book, PASCreateCardRequest *req); - void (*remove_cards) (PASBackend *backend, PASBook *book, PASRemoveCardsRequest *req); - void (*modify_card) (PASBackend *backend, PASBook *book, PASModifyCardRequest *req); - void (*check_connection) (PASBackend *backend, PASBook *book, PASCheckConnectionRequest *req); - void (*get_vcard) (PASBackend *backend, PASBook *book, PASGetVCardRequest *req); - void (*get_cursor) (PASBackend *backend, PASBook *book, PASGetCursorRequest *req); - void (*get_book_view) (PASBackend *backend, PASBook *book, PASGetBookViewRequest *req); - void (*get_completion_view) (PASBackend *backend, PASBook *book, PASGetCompletionViewRequest *req); - void (*get_changes) (PASBackend *backend, PASBook *book, PASGetChangesRequest *req); - void (*authenticate_user) (PASBackend *backend, PASBook *book, PASAuthenticateUserRequest *req); - void (*get_supported_fields) (PASBackend *backend, PASBook *book, PASGetSupportedFieldsRequest *req); - void (*get_supported_auth_methods) (PASBackend *backend, PASBook *book, PASGetSupportedAuthMethodsRequest *req); - - /* Notification signals */ - void (* last_client_gone) (PASBackend *backend); -} PASBackendClass; - -typedef PASBackend * (*PASBackendFactoryFn) (void); - -gboolean pas_backend_construct (PASBackend *backend); - -GNOME_Evolution_Addressbook_BookListener_CallStatus - pas_backend_load_uri (PASBackend *backend, - const char *uri); -const char *pas_backend_get_uri (PASBackend *backend); - -gboolean pas_backend_add_client (PASBackend *backend, - GNOME_Evolution_Addressbook_BookListener listener); -void pas_backend_remove_client (PASBackend *backend, - PASBook *book); -char *pas_backend_get_static_capabilities (PASBackend *backend); - -gboolean pas_backend_is_loaded (PASBackend *backend); - -gboolean pas_backend_is_writable (PASBackend *backend); - -void pas_backend_create_card (PASBackend *backend, - PASBook *book, - PASCreateCardRequest *req); -void pas_backend_remove_cards (PASBackend *backend, - PASBook *book, - PASRemoveCardsRequest *req); -void pas_backend_modify_card (PASBackend *backend, - PASBook *book, - PASModifyCardRequest *req); -void pas_backend_check_connection (PASBackend *backend, - PASBook *book, - PASCheckConnectionRequest *req); -void pas_backend_get_vcard (PASBackend *backend, - PASBook *book, - PASGetVCardRequest *req); -void pas_backend_get_cursor (PASBackend *backend, - PASBook *book, - PASGetCursorRequest *req); -void pas_backend_get_book_view (PASBackend *backend, - PASBook *book, - PASGetBookViewRequest *req); -void pas_backend_get_completion_view (PASBackend *backend, - PASBook *book, - PASGetCompletionViewRequest *req); -void pas_backend_get_changes (PASBackend *backend, - PASBook *book, - PASGetChangesRequest *req); -void pas_backend_authenticate_user (PASBackend *backend, - PASBook *book, - PASAuthenticateUserRequest *req); -void pas_backend_get_supported_fields (PASBackend *backend, - PASBook *book, - PASGetSupportedFieldsRequest *req); -void pas_backend_get_supported_auth_methods (PASBackend *backend, - PASBook *book, - PASGetSupportedAuthMethodsRequest *req); - - -GType pas_backend_get_type (void); - - -/* protected functions for subclasses */ -void pas_backend_set_is_loaded (PASBackend *backend, - gboolean is_loaded); -void pas_backend_set_is_writable (PASBackend *backend, - gboolean is_writable); - -#endif /* ! __PAS_BACKEND_H__ */ - diff --git a/addressbook/backend/pas/pas-book-factory.c b/addressbook/backend/pas/pas-book-factory.c deleted file mode 100644 index 2d6ed1e65b..0000000000 --- a/addressbook/backend/pas/pas-book-factory.c +++ /dev/null @@ -1,595 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * - * Author: - * Nat Friedman (nat@ximian.com) - * - * Copyright 2000, Ximian, Inc. - */ - -#include <config.h> -#include <string.h> - -#include "addressbook.h" -#include "pas-book-factory.h" -#include "pas-marshal.h" -#include <bonobo-activation/bonobo-activation.h> -#include <bonobo/bonobo-main.h> - -#define DEFAULT_PAS_BOOK_FACTORY_OAF_ID "OAFIID:GNOME_Evolution_Wombat_ServerFactory" - -static BonoboObjectClass *pas_book_factory_parent_class; - -typedef struct { - char *uri; - GNOME_Evolution_Addressbook_BookListener listener; -} PASBookFactoryQueuedRequest; - -struct _PASBookFactoryPrivate { - gint idle_id; - GHashTable *backends; - GHashTable *active_server_map; - GList *queued_requests; - - /* OAFIID of the factory */ - char *iid; - - /* Whether the factory has been registered with OAF yet */ - guint registered : 1; -}; - -/* Signal IDs */ -enum { - LAST_BOOK_GONE, - LAST_SIGNAL -}; - -static guint factory_signals[LAST_SIGNAL]; - -static char * -pas_book_factory_canonicalize_uri (const char *uri) -{ - /* FIXME: What do I do here? */ - - return g_strdup (uri); -} - -static char * -pas_book_factory_extract_proto_from_uri (const char *uri) -{ - char *proto; - char *p; - - p = strchr (uri, ':'); - - if (p == NULL) - return NULL; - - proto = g_malloc0 (p - uri + 1); - - strncpy (proto, uri, p - uri); - - return proto; -} - -/** - * pas_book_factory_register_backend: - * @factory: - * @proto: - * @backend: - */ -void -pas_book_factory_register_backend (PASBookFactory *factory, - const char *proto, - PASBackendFactoryFn backend) -{ - g_return_if_fail (factory != NULL); - g_return_if_fail (PAS_IS_BOOK_FACTORY (factory)); - g_return_if_fail (proto != NULL); - g_return_if_fail (backend != NULL); - - if (g_hash_table_lookup (factory->priv->backends, proto) != NULL) { - g_warning ("pas_book_factory_register_backend: " - "Proto \"%s\" already registered!\n", proto); - } - - g_hash_table_insert (factory->priv->backends, - g_strdup (proto), backend); -} - -/** - * pas_book_factory_get_n_backends: - * @factory: An addressbook factory. - * - * Queries the number of running addressbook backends in an addressbook factory. - * - * Return value: Number of running backends. - **/ -int -pas_book_factory_get_n_backends (PASBookFactory *factory) -{ - g_return_val_if_fail (factory != NULL, -1); - g_return_val_if_fail (PAS_IS_BOOK_FACTORY (factory), -1); - - return g_hash_table_size (factory->priv->active_server_map); -} - -static void -dump_active_server_map_entry (gpointer key, gpointer value, gpointer data) -{ - char *uri; - PASBackend *backend; - - uri = key; - backend = PAS_BACKEND (value); - - g_message (" %s: %p", uri, backend); -} - -void -pas_book_factory_dump_active_backends (PASBookFactory *factory) -{ - g_message ("Active PAS backends"); - - g_hash_table_foreach (factory->priv->active_server_map, - dump_active_server_map_entry, - NULL); - -} - -/* Callback used when a backend loses its last connected client */ -static void -backend_last_client_gone_cb (PASBackend *backend, gpointer data) -{ - PASBookFactory *factory; - const char *uri; - - factory = PAS_BOOK_FACTORY (data); - - /* Remove the backend from the active server map */ - - uri = pas_backend_get_uri (backend); - if (uri) { - gpointer orig_key; - gboolean result; - char *orig_uri; - - result = g_hash_table_lookup_extended (factory->priv->active_server_map, uri, - &orig_key, NULL); - g_assert (result != FALSE); - - orig_uri = orig_key; - - g_hash_table_remove (factory->priv->active_server_map, orig_uri); - g_free (orig_uri); - - g_object_unref (backend); - - /* Notify upstream if there are no more backends */ - } - - if (g_hash_table_size (factory->priv->active_server_map) == 0) - g_signal_emit (G_OBJECT (factory), factory_signals[LAST_BOOK_GONE], 0); -} - -static PASBackendFactoryFn -pas_book_factory_lookup_backend_factory (PASBookFactory *factory, - const char *uri) -{ - PASBackendFactoryFn backend_fn; - char *proto; - char *canonical_uri; - - g_assert (factory != NULL); - g_assert (PAS_IS_BOOK_FACTORY (factory)); - g_assert (uri != NULL); - - canonical_uri = pas_book_factory_canonicalize_uri (uri); - if (canonical_uri == NULL) - return NULL; - - proto = pas_book_factory_extract_proto_from_uri (canonical_uri); - if (proto == NULL) { - g_free (canonical_uri); - return NULL; - } - - backend_fn = g_hash_table_lookup (factory->priv->backends, proto); - - g_free (proto); - g_free (canonical_uri); - - return backend_fn; -} - -static PASBackend * -pas_book_factory_launch_backend (PASBookFactory *factory, - GNOME_Evolution_Addressbook_BookListener listener, - const char *uri) -{ - PASBackendFactoryFn backend_factory; - PASBackend *backend; - - backend_factory = pas_book_factory_lookup_backend_factory ( - factory, uri); - - if (!backend_factory) { - CORBA_Environment ev; - - CORBA_exception_init (&ev); - GNOME_Evolution_Addressbook_BookListener_notifyBookOpened ( - listener, - GNOME_Evolution_Addressbook_BookListener_ProtocolNotSupported, - CORBA_OBJECT_NIL, - &ev); - - if (ev._major != CORBA_NO_EXCEPTION) - g_message ("pas_book_factory_launch_backend(): could not notify " - "the listener"); - - CORBA_exception_free (&ev); - return NULL; - } - - backend = (* backend_factory) (); - if (!backend) { - CORBA_Environment ev; - - CORBA_exception_init (&ev); - GNOME_Evolution_Addressbook_BookListener_notifyBookOpened ( - listener, - GNOME_Evolution_Addressbook_BookListener_OtherError, - CORBA_OBJECT_NIL, - &ev); - - if (ev._major != CORBA_NO_EXCEPTION) - g_message ("pas_book_factory_launch_backend(): could not notify " - "the listener"); - - CORBA_exception_free (&ev); - return NULL; - } - - g_hash_table_insert (factory->priv->active_server_map, - g_strdup (uri), - backend); - - g_signal_connect (backend, "last_client_gone", - G_CALLBACK (backend_last_client_gone_cb), - factory); - - return backend; -} - -static void -pas_book_factory_process_request (PASBookFactory *factory, - PASBookFactoryQueuedRequest *request) -{ - PASBackend *backend; - char *uri; - GNOME_Evolution_Addressbook_BookListener listener; - CORBA_Environment ev; - - uri = request->uri; - listener = request->listener; - g_free (request); - - /* Look up the backend and create one if needed */ - - backend = g_hash_table_lookup (factory->priv->active_server_map, uri); - - if (!backend) { - GNOME_Evolution_Addressbook_BookListener_CallStatus status; - - backend = pas_book_factory_launch_backend (factory, listener, uri); - if (!backend) - goto out; - - status = pas_backend_load_uri (backend, uri); - if (status != GNOME_Evolution_Addressbook_BookListener_Success) { - /* tell the listener that we failed to open the book */ - CORBA_exception_init (&ev); - - GNOME_Evolution_Addressbook_BookListener_notifyBookOpened ( - listener, status, - CORBA_OBJECT_NIL, - &ev); - - if (ev._major != CORBA_NO_EXCEPTION) { - g_warning ("pas_book_respond_open: Exception " - "responding to BookListener!\n"); - } - - CORBA_exception_free (&ev); - - backend_last_client_gone_cb (backend, factory); - - goto out; - } - - pas_backend_add_client (backend, listener); - - goto out; - } - - pas_backend_add_client (backend, listener); - - out: - g_free (uri); - - CORBA_exception_init (&ev); - CORBA_Object_release (listener, &ev); - - if (ev._major != CORBA_NO_EXCEPTION) - g_message ("pas_book_factory_process_request(): could not release the listener"); - - CORBA_exception_free (&ev); -} - -static gboolean -pas_book_factory_process_queue (PASBookFactory *factory) -{ - /* Process pending Book-creation requests. */ - if (factory->priv->queued_requests != NULL) { - PASBookFactoryQueuedRequest *request; - GList *l; - - l = factory->priv->queued_requests; - request = l->data; - - pas_book_factory_process_request (factory, request); - - factory->priv->queued_requests = g_list_remove_link ( - factory->priv->queued_requests, l); - g_list_free_1 (l); - } - - if (factory->priv->queued_requests == NULL) { - - factory->priv->idle_id = 0; - return FALSE; - } - - return TRUE; -} - -static void -pas_book_factory_queue_request (PASBookFactory *factory, - const char *uri, - const GNOME_Evolution_Addressbook_BookListener listener) -{ - PASBookFactoryQueuedRequest *request; - GNOME_Evolution_Addressbook_BookListener listener_copy; - CORBA_Environment ev; - - CORBA_exception_init (&ev); - - listener_copy = CORBA_Object_duplicate (listener, &ev); - - if (ev._major != CORBA_NO_EXCEPTION) { - g_warning ("PASBookFactory: Could not duplicate BookListener!\n"); - CORBA_exception_free (&ev); - return; - } - - CORBA_exception_free (&ev); - - request = g_new0 (PASBookFactoryQueuedRequest, 1); - request->listener = listener_copy; - request->uri = g_strdup (uri); - - factory->priv->queued_requests = - g_list_prepend (factory->priv->queued_requests, request); - - if (! factory->priv->idle_id) { - factory->priv->idle_id = - g_idle_add ((GSourceFunc) pas_book_factory_process_queue, factory); - } -} - -static void -impl_GNOME_Evolution_Addressbook_BookFactory_openBook (PortableServer_Servant servant, - const CORBA_char *uri, - const GNOME_Evolution_Addressbook_BookListener listener, - CORBA_Environment *ev) -{ - PASBookFactory *factory = PAS_BOOK_FACTORY (bonobo_object (servant)); - PASBackendFactoryFn backend_factory; - - backend_factory = pas_book_factory_lookup_backend_factory (factory, uri); - - if (backend_factory == NULL) { - GNOME_Evolution_Addressbook_BookListener_notifyBookOpened ( - listener, - GNOME_Evolution_Addressbook_BookListener_ProtocolNotSupported, - CORBA_OBJECT_NIL, - ev); - - return; - } - - pas_book_factory_queue_request (factory, uri, listener); -} - -static void -pas_book_factory_construct (PASBookFactory *factory) -{ - /* nothing to do here.. */ -} - -/** - * pas_book_factory_new: - */ -PASBookFactory * -pas_book_factory_new (void) -{ - PASBookFactory *factory; - - factory = g_object_new (PAS_TYPE_BOOK_FACTORY, NULL); - - pas_book_factory_construct (factory); - - return factory; -} - -/** - * pas_book_factory_activate: - */ -gboolean -pas_book_factory_activate (PASBookFactory *factory, const char *iid) -{ - PASBookFactoryPrivate *priv; - Bonobo_RegistrationResult result; - char *tmp_iid; - - g_return_val_if_fail (factory != NULL, FALSE); - g_return_val_if_fail (PAS_IS_BOOK_FACTORY (factory), FALSE); - - priv = factory->priv; - - g_return_val_if_fail (!priv->registered, FALSE); - - /* if iid is NULL, use the default factory OAFIID */ - if (iid) - tmp_iid = g_strdup (iid); - else - tmp_iid = g_strdup (DEFAULT_PAS_BOOK_FACTORY_OAF_ID); - - result = bonobo_activation_active_server_register (tmp_iid, bonobo_object_corba_objref (BONOBO_OBJECT (factory))); - - switch (result) { - case Bonobo_ACTIVATION_REG_SUCCESS: - priv->registered = TRUE; - priv->iid = tmp_iid; - return TRUE; - case Bonobo_ACTIVATION_REG_NOT_LISTED: - g_message ("Error registering the PAS factory: not listed"); - break; - case Bonobo_ACTIVATION_REG_ALREADY_ACTIVE: - g_message ("Error registering the PAS factory: already active"); - break; - case Bonobo_ACTIVATION_REG_ERROR: - default: - g_message ("Error registering the PAS factory: generic error"); - break; - } - - g_free (tmp_iid); - return FALSE; -} - -static void -pas_book_factory_init (PASBookFactory *factory) -{ - factory->priv = g_new0 (PASBookFactoryPrivate, 1); - - factory->priv->active_server_map = g_hash_table_new (g_str_hash, g_str_equal); - factory->priv->backends = g_hash_table_new (g_str_hash, g_str_equal); - factory->priv->queued_requests = NULL; - factory->priv->registered = FALSE; -} - -static void -free_active_server_map_entry (gpointer key, gpointer value, gpointer data) -{ - char *uri; - PASBackend *backend; - - uri = key; - g_free (uri); - - backend = PAS_BACKEND (value); - g_object_unref (backend); -} - -static void -remove_backends_entry (gpointer key, gpointer value, gpointer data) -{ - char *uri; - - uri = key; - g_free (uri); -} - -static void -pas_book_factory_dispose (GObject *object) -{ - PASBookFactory *factory = PAS_BOOK_FACTORY (object); - - if (factory->priv) { - PASBookFactoryPrivate *priv = factory->priv; - GList *l; - - for (l = priv->queued_requests; l != NULL; l = l->next) { - PASBookFactoryQueuedRequest *request = l->data; - CORBA_Environment ev; - - g_free (request->uri); - - CORBA_exception_init (&ev); - CORBA_Object_release (request->listener, &ev); - CORBA_exception_free (&ev); - - g_free (request); - } - g_list_free (priv->queued_requests); - priv->queued_requests = NULL; - - g_hash_table_foreach (priv->active_server_map, - free_active_server_map_entry, - NULL); - g_hash_table_destroy (priv->active_server_map); - priv->active_server_map = NULL; - - g_hash_table_foreach (priv->backends, - remove_backends_entry, - NULL); - g_hash_table_destroy (priv->backends); - priv->backends = NULL; - - if (priv->registered) { - bonobo_activation_active_server_unregister (priv->iid, - bonobo_object_corba_objref (BONOBO_OBJECT (factory))); - priv->registered = FALSE; - } - - g_free (priv->iid); - - g_free (priv); - factory->priv = NULL; - } - - if (G_OBJECT_CLASS (pas_book_factory_parent_class)->dispose) - G_OBJECT_CLASS (pas_book_factory_parent_class)->dispose (object); -} - -static void -pas_book_factory_class_init (PASBookFactoryClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - POA_GNOME_Evolution_Addressbook_BookFactory__epv *epv; - - pas_book_factory_parent_class = g_type_class_peek_parent (klass); - - object_class->dispose = pas_book_factory_dispose; - - factory_signals[LAST_BOOK_GONE] = - g_signal_new ("last_book_gone", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (PASBookFactoryClass, last_book_gone), - NULL, NULL, - pas_marshal_NONE__NONE, - G_TYPE_NONE, 0); - - - epv = &klass->epv; - - epv->openBook = impl_GNOME_Evolution_Addressbook_BookFactory_openBook; -} - -BONOBO_TYPE_FUNC_FULL ( - PASBookFactory, - GNOME_Evolution_Addressbook_BookFactory, - BONOBO_TYPE_OBJECT, - pas_book_factory); diff --git a/addressbook/backend/pas/pas-book-factory.h b/addressbook/backend/pas/pas-book-factory.h deleted file mode 100644 index 9d099a6f2c..0000000000 --- a/addressbook/backend/pas/pas-book-factory.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2000, Ximian, Inc. - */ - -#include <pas/pas-backend.h> -#include <bonobo/bonobo-object.h> - -#ifndef __PAS_BOOK_FACTORY_H__ -#define __PAS_BOOK_FACTORY_H__ - -G_BEGIN_DECLS - -#define PAS_TYPE_BOOK_FACTORY (pas_book_factory_get_type ()) -#define PAS_BOOK_FACTORY(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), PAS_TYPE_BOOK_FACTORY, PASBookFactory)) -#define PAS_BOOK_FACTORY_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), PAS_TYPE_BOOK_FACTORY, PASBookFactoryClass)) -#define PAS_IS_BOOK_FACTORY(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), PAS_TYPE_BOOK_FACTORY)) -#define PAS_IS_BOOK_FACTORY_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), PAS_TYPE_BOOK_FACTORY)) -#define PAS_BOOK_FACTORY_GET_CLASS(k) (G_TYPE_INSTANCE_GET_CLASS ((obj), PAS_TYPE_BOOK_FACTORY, PASBookFactoryClass)) - -typedef struct _PASBookFactoryPrivate PASBookFactoryPrivate; - -typedef struct { - BonoboObject parent_object; - PASBookFactoryPrivate *priv; -} PASBookFactory; - -typedef struct { - BonoboObjectClass parent_class; - - POA_GNOME_Evolution_Addressbook_BookFactory__epv epv; - - /* Notification signals */ - - void (* last_book_gone) (PASBookFactory *factory); -} PASBookFactoryClass; - -PASBookFactory *pas_book_factory_new (void); - -void pas_book_factory_register_backend (PASBookFactory *factory, - const char *proto, - PASBackendFactoryFn backend_factory); - -int pas_book_factory_get_n_backends (PASBookFactory *factory); - -void pas_book_factory_dump_active_backends (PASBookFactory *factory); - -gboolean pas_book_factory_activate (PASBookFactory *factory, const char *iid); - -GType pas_book_factory_get_type (void); - -G_END_DECLS - -#endif /* ! __PAS_BOOK_FACTORY_H__ */ diff --git a/addressbook/backend/pas/pas-book-view.c b/addressbook/backend/pas/pas-book-view.c deleted file mode 100644 index fce4173f0f..0000000000 --- a/addressbook/backend/pas/pas-book-view.c +++ /dev/null @@ -1,269 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * pas-book-view.c - * - * Copyright 2000, Ximian, Inc. - */ - -#include <config.h> -#include <glib.h> -#include <bonobo/bonobo-main.h> -#include "pas-book-view.h" - -static BonoboObjectClass *pas_book_view_parent_class; - -struct _PASBookViewPrivate { - GNOME_Evolution_Addressbook_BookViewListener listener; -}; - -/** - * pas_book_view_notify_change: - */ -void -pas_book_view_notify_change (PASBookView *book_view, - const GList *cards) -{ - CORBA_Environment ev; - gint i, length; - CORBA_sequence_GNOME_Evolution_Addressbook_VCard card_sequence; - - length = g_list_length((GList *) cards); - - card_sequence._buffer = CORBA_sequence_GNOME_Evolution_Addressbook_VCard_allocbuf(length); - card_sequence._maximum = length; - card_sequence._length = length; - - for ( i = 0; cards; cards = g_list_next(cards), i++ ) { - card_sequence._buffer[i] = CORBA_string_dup((char *) cards->data); - } - - CORBA_exception_init (&ev); - - GNOME_Evolution_Addressbook_BookViewListener_notifyCardChanged ( - book_view->priv->listener, &card_sequence, &ev); - - if (ev._major != CORBA_NO_EXCEPTION) { - g_warning ("pas_book_view_notify_change: Exception signaling BookViewListener!\n"); - } - - CORBA_exception_free (&ev); - - CORBA_free(card_sequence._buffer); -} - -void -pas_book_view_notify_change_1 (PASBookView *book_view, - const char *card) -{ - GList *list = g_list_append(NULL, (char *) card); - pas_book_view_notify_change(book_view, list); - g_list_free(list); -} - -/** - * pas_book_view_notify_remove: - */ -void -pas_book_view_notify_remove_1 (PASBookView *book_view, - const char *id) -{ - GList *ids = NULL; - - ids = g_list_prepend (ids, (char*)id); - - pas_book_view_notify_remove (book_view, ids); - - g_list_free (ids); -} - -void -pas_book_view_notify_remove (PASBookView *book_view, - const GList *ids) -{ - GNOME_Evolution_Addressbook_CardIdList idlist; - CORBA_Environment ev; - const GList *l; - int num_ids, i; - - CORBA_exception_init (&ev); - - num_ids = g_list_length ((GList*)ids); - idlist._buffer = CORBA_sequence_GNOME_Evolution_Addressbook_CardId_allocbuf (num_ids); - idlist._maximum = num_ids; - idlist._length = num_ids; - - for (l = ids, i = 0; l; l=l->next, i ++) { - idlist._buffer[i] = CORBA_string_dup (l->data); - } - - GNOME_Evolution_Addressbook_BookViewListener_notifyCardsRemoved ( - book_view->priv->listener, &idlist, &ev); - - if (ev._major != CORBA_NO_EXCEPTION) { - g_warning ("pas_book_view_notify_remove: Exception signaling BookViewListener!\n"); - } - - CORBA_free(idlist._buffer); - - CORBA_exception_free (&ev); -} - -/** - * pas_book_view_notify_add: - */ -void -pas_book_view_notify_add (PASBookView *book_view, - const GList *cards) -{ - CORBA_Environment ev; - gint i, length; - CORBA_sequence_GNOME_Evolution_Addressbook_VCard card_sequence; - - length = g_list_length((GList *)cards); - - card_sequence._buffer = CORBA_sequence_GNOME_Evolution_Addressbook_VCard_allocbuf(length); - card_sequence._maximum = length; - card_sequence._length = length; - - for ( i = 0; cards; cards = g_list_next(cards), i++ ) { - card_sequence._buffer[i] = CORBA_string_dup((char *) cards->data); - } - - CORBA_exception_init (&ev); - - GNOME_Evolution_Addressbook_BookViewListener_notifyCardAdded ( - book_view->priv->listener, &card_sequence, &ev); - - if (ev._major != CORBA_NO_EXCEPTION) { - g_warning ("pas_book_view_notify_add: Exception signaling BookViewListener!\n"); - } - - CORBA_exception_free (&ev); - - CORBA_free(card_sequence._buffer); -} - -void -pas_book_view_notify_add_1 (PASBookView *book_view, - const char *card) -{ - GList *list = g_list_append(NULL, (char *) card); - pas_book_view_notify_add(book_view, list); - g_list_free(list); -} - -void -pas_book_view_notify_complete (PASBookView *book_view, - GNOME_Evolution_Addressbook_BookViewListener_CallStatus status) -{ - CORBA_Environment ev; - - CORBA_exception_init (&ev); - - GNOME_Evolution_Addressbook_BookViewListener_notifySequenceComplete ( - book_view->priv->listener, status, &ev); - - if (ev._major != CORBA_NO_EXCEPTION) { - g_warning ("pas_book_view_notify_complete: Exception signaling BookViewListener!\n"); - } - - CORBA_exception_free (&ev); -} - -void -pas_book_view_notify_status_message (PASBookView *book_view, - const char *message) -{ - CORBA_Environment ev; - - CORBA_exception_init (&ev); - - GNOME_Evolution_Addressbook_BookViewListener_notifyStatusMessage ( - book_view->priv->listener, message, &ev); - - if (ev._major != CORBA_NO_EXCEPTION) { - g_warning ("pas_book_view_notify_status_message: Exception signaling BookViewListener!\n"); - } - - CORBA_exception_free (&ev); -} - -static void -pas_book_view_construct (PASBookView *book_view, - GNOME_Evolution_Addressbook_BookViewListener listener) -{ - PASBookViewPrivate *priv; - CORBA_Environment ev; - - g_return_if_fail (book_view != NULL); - g_return_if_fail (listener != CORBA_OBJECT_NIL); - - priv = book_view->priv; - - CORBA_exception_init (&ev); - - bonobo_object_dup_ref (listener, &ev); - if (ev._major != CORBA_NO_EXCEPTION) { - g_warning("Unable to duplicate & ref listener object in pas-book-view.c\n"); - CORBA_exception_free (&ev); - return; - } - - CORBA_exception_free (&ev); - - priv->listener = listener; -} - -/** - * pas_book_view_new: - */ -PASBookView * -pas_book_view_new (GNOME_Evolution_Addressbook_BookViewListener listener) -{ - PASBookView *book_view; - - book_view = g_object_new (PAS_TYPE_BOOK_VIEW, NULL); - - pas_book_view_construct (book_view, listener); - - return book_view; -} - -static void -pas_book_view_dispose (GObject *object) -{ - PASBookView *book_view = PAS_BOOK_VIEW (object); - - if (book_view->priv) { - bonobo_object_release_unref (book_view->priv->listener, NULL); - - g_free (book_view->priv); - book_view->priv = NULL; - } - - if (G_OBJECT_CLASS (pas_book_view_parent_class)->dispose) - G_OBJECT_CLASS (pas_book_view_parent_class)->dispose (object); -} - -static void -pas_book_view_class_init (PASBookViewClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - pas_book_view_parent_class = g_type_class_peek_parent (klass); - - object_class->dispose = pas_book_view_dispose; -} - -static void -pas_book_view_init (PASBookView *book_view) -{ - book_view->priv = g_new0 (PASBookViewPrivate, 1); - book_view->priv->listener = CORBA_OBJECT_NIL; -} - -BONOBO_TYPE_FUNC_FULL ( - PASBookView, - GNOME_Evolution_Addressbook_BookView, - BONOBO_TYPE_OBJECT, - pas_book_view); diff --git a/addressbook/backend/pas/pas-book-view.h b/addressbook/backend/pas/pas-book-view.h deleted file mode 100644 index dd6c74c596..0000000000 --- a/addressbook/backend/pas/pas-book-view.h +++ /dev/null @@ -1,64 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * A wrapper object which exports the GNOME_Evolution_Addressbook_Book CORBA interface - * and which maintains a request queue. - * - * Author: - * Nat Friedman (nat@ximian.com) - * - * Copyright 2000, Ximian, Inc. - */ - -#ifndef __PAS_BOOK_VIEW_H__ -#define __PAS_BOOK_VIEW_H__ - -#include <bonobo/bonobo-object.h> -#include <pas/addressbook.h> -#include <glib.h> -#include <glib-object.h> - -#define PAS_TYPE_BOOK_VIEW (pas_book_view_get_type ()) -#define PAS_BOOK_VIEW(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), PAS_TYPE_BOOK_VIEW, PASBookView)) -#define PAS_BOOK_VIEW_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), PAS_TYPE_BOOK_VIEW, PASBookViewClass)) -#define PAS_IS_BOOK_VIEW(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), PAS_TYPE_BOOK_VIEW)) -#define PAS_IS_BOOK_VIEW_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), PAS_TYPE_BOOK_VIEW)) -#define PAS_BOOK_VIEW_GET_CLASS(k) (G_TYPE_INSTANCE_GET_CLASS ((obj), PAS_TYPE_BOOK_VIEW, PASBookView)) - -typedef struct _PASBookView PASBookView; -typedef struct _PASBookViewClass PASBookViewClass; -typedef struct _PASBookViewPrivate PASBookViewPrivate; - -struct _PASBookView { - BonoboObject parent_object; - PASBookViewPrivate *priv; -}; - -struct _PASBookViewClass { - BonoboObjectClass parent_class; - - POA_GNOME_Evolution_Addressbook_BookView__epv epv; -}; - - -PASBookView *pas_book_view_new (GNOME_Evolution_Addressbook_BookViewListener listener); - -void pas_book_view_notify_change (PASBookView *book_view, - const GList *cards); -void pas_book_view_notify_change_1 (PASBookView *book_view, - const char *card); -void pas_book_view_notify_remove (PASBookView *book_view, - const GList *ids); -void pas_book_view_notify_remove_1 (PASBookView *book_view, - const char *id); -void pas_book_view_notify_add (PASBookView *book_view, - const GList *cards); -void pas_book_view_notify_add_1 (PASBookView *book_view, - const char *card); -void pas_book_view_notify_complete (PASBookView *book_view, - GNOME_Evolution_Addressbook_BookViewListener_CallStatus); -void pas_book_view_notify_status_message (PASBookView *book_view, - const char *message); - -GType pas_book_view_get_type (void); - -#endif /* ! __PAS_BOOK_VIEW_H__ */ diff --git a/addressbook/backend/pas/pas-book.c b/addressbook/backend/pas/pas-book.c deleted file mode 100644 index dc626e59e1..0000000000 --- a/addressbook/backend/pas/pas-book.c +++ /dev/null @@ -1,1026 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * pas-book.c - * - * Copyright 2000, Ximian, Inc. - */ - -#include <config.h> -#include <bonobo/bonobo-main.h> -#include "e-util/e-list.h" -#include "pas-backend.h" -#include "pas-marshal.h" - -static BonoboObjectClass *pas_book_parent_class; -POA_GNOME_Evolution_Addressbook_Book__vepv pas_book_vepv; - -enum { - REQUESTS_QUEUED, - LAST_SIGNAL -}; - -static guint pas_book_signals [LAST_SIGNAL]; - -struct _PASBookPrivate { - PASBackend *backend; - GNOME_Evolution_Addressbook_BookListener listener; - - GList *request_queue; - gint timeout_id; - - guint timeout_lock : 1; -}; - -static gboolean -pas_book_check_queue (PASBook *book) -{ - if (book->priv->timeout_lock) - return TRUE; - - book->priv->timeout_lock = TRUE; - - if (book->priv->request_queue != NULL) { - g_signal_emit (book, pas_book_signals [REQUESTS_QUEUED], 0); - } - - if (book->priv->request_queue == NULL) { - book->priv->timeout_id = 0; - book->priv->timeout_lock = FALSE; - bonobo_object_unref (BONOBO_OBJECT (book)); - return FALSE; - } - - book->priv->timeout_lock = FALSE; - - return TRUE; -} - -static void -pas_book_queue_request (PASBook *book, PASRequest *req) -{ - book->priv->request_queue = - g_list_append (book->priv->request_queue, req); - - if (book->priv->timeout_id == 0) { - bonobo_object_ref (BONOBO_OBJECT (book)); - book->priv->timeout_id = g_timeout_add (20, (GSourceFunc) pas_book_check_queue, book); - } -} - -static void -pas_book_queue_create_card (PASBook *book, const char *vcard) -{ - PASRequest *req; - - req = g_new0 (PASRequest, 1); - req->op = CreateCard; - req->create.vcard = g_strdup (vcard); - - pas_book_queue_request (book, req); -} - -static void -pas_book_queue_remove_cards (PASBook *book, - const GNOME_Evolution_Addressbook_CardIdList *ids) -{ - PASRequest *req; - int i; - - req = g_new0 (PASRequest, 1); - req->op = RemoveCards; - req->remove.ids = NULL; - - for (i = 0; i < ids->_length; i ++) { - req->remove.ids = g_list_append (req->remove.ids, g_strdup (ids->_buffer[i])); - } - - pas_book_queue_request (book, req); -} - -static void -pas_book_queue_modify_card (PASBook *book, const char *vcard) -{ - PASRequest *req; - - req = g_new0 (PASRequest, 1); - req->op = ModifyCard; - req->modify.vcard = g_strdup (vcard); - - pas_book_queue_request (book, req); -} - -static void -pas_book_queue_get_cursor (PASBook *book, const char *search) -{ - PASRequest *req; - - req = g_new0 (PASRequest, 1); - req->op = GetCursor; - req->get_cursor.search = g_strdup(search); - - pas_book_queue_request (book, req); -} - -static void -pas_book_queue_get_vcard (PASBook *book, const char *id) -{ - PASRequest *req; - - req = g_new0 (PASRequest, 1); - req->op = GetVCard; - req->get_vcard.id = g_strdup(id); - - pas_book_queue_request (book, req); -} - -static void -pas_book_queue_authenticate_user (PASBook *book, - const char *user, const char *passwd, const char *auth_method) -{ - PASRequest *req; - - req = g_new0 (PASRequest, 1); - req->op = AuthenticateUser; - req->auth_user.user = g_strdup(user); - req->auth_user.passwd = g_strdup(passwd); - req->auth_user.auth_method = g_strdup(auth_method); - - pas_book_queue_request (book, req); -} - -static void -pas_book_queue_get_supported_fields (PASBook *book) -{ - PASRequest *req; - - req = g_new0 (PASRequest, 1); - req->op = GetSupportedFields; - - pas_book_queue_request (book, req); -} - -static void -pas_book_queue_get_supported_auth_methods (PASBook *book) -{ - PASRequest *req; - - req = g_new0 (PASRequest, 1); - req->op = GetSupportedAuthMethods; - - pas_book_queue_request (book, req); -} - - -static void -pas_book_queue_get_book_view (PASBook *book, const GNOME_Evolution_Addressbook_BookViewListener listener, const char *search) -{ - PASRequest *req; - CORBA_Environment ev; - - req = g_new0 (PASRequest, 1); - req->op = GetBookView; - req->get_book_view.search = g_strdup(search); - - CORBA_exception_init (&ev); - - req->get_book_view.listener = bonobo_object_dup_ref(listener, &ev); - - if (ev._major != CORBA_NO_EXCEPTION) { - g_warning ("pas_book_queue_get_book_view: Exception " - "duplicating BookViewListener!\n"); - } - - CORBA_exception_free (&ev); - - pas_book_queue_request (book, req); -} - -static void -pas_book_queue_get_completion_view (PASBook *book, const GNOME_Evolution_Addressbook_BookViewListener listener, const char *search) -{ - PASRequest *req; - CORBA_Environment ev; - - req = g_new0 (PASRequest, 1); - req->op = GetCompletionView; - req->get_book_view.search = g_strdup(search); - - CORBA_exception_init (&ev); - - req->get_book_view.listener = bonobo_object_dup_ref(listener, &ev); - - if (ev._major != CORBA_NO_EXCEPTION) { - g_warning ("pas_book_queue_get_completion_view: Exception " - "duplicating BookViewListener!\n"); - } - - CORBA_exception_free (&ev); - - pas_book_queue_request (book, req); -} - -static void -pas_book_queue_get_changes (PASBook *book, const GNOME_Evolution_Addressbook_BookViewListener listener, const char *change_id) -{ - PASRequest *req; - CORBA_Environment ev; - - req = g_new0 (PASRequest, 1); - req->op = GetChanges; - req->get_changes.change_id= g_strdup(change_id); - - CORBA_exception_init (&ev); - - req->get_changes.listener = bonobo_object_dup_ref(listener, &ev); - - if (ev._major != CORBA_NO_EXCEPTION) { - g_warning ("pas_book_queue_get_changes: Exception " - "duplicating BookViewListener!\n"); - } - - CORBA_exception_free (&ev); - - pas_book_queue_request (book, req); -} - -static void -pas_book_queue_check_connection (PASBook *book) -{ - PASRequest *req; - - req = g_new0 (PASRequest, 1); - req->op = CheckConnection; - - pas_book_queue_request (book, req); -} - -static void -impl_GNOME_Evolution_Addressbook_Book_getVCard (PortableServer_Servant servant, - const CORBA_char *id, - CORBA_Environment *ev) -{ - PASBook *book = PAS_BOOK (bonobo_object (servant)); - - pas_book_queue_get_vcard (book, id); -} - -static void -impl_GNOME_Evolution_Addressbook_Book_authenticateUser (PortableServer_Servant servant, - const char* user, - const char* passwd, - const char* auth_method, - CORBA_Environment *ev) -{ - PASBook *book = PAS_BOOK (bonobo_object (servant)); - - pas_book_queue_authenticate_user (book, user, passwd, auth_method); -} - -static void -impl_GNOME_Evolution_Addressbook_Book_addCard (PortableServer_Servant servant, - const CORBA_char *vcard, - CORBA_Environment *ev) -{ - PASBook *book = PAS_BOOK (bonobo_object (servant)); - - pas_book_queue_create_card (book, (const char *) vcard); -} - -static void -impl_GNOME_Evolution_Addressbook_Book_removeCards (PortableServer_Servant servant, - const GNOME_Evolution_Addressbook_CardIdList *ids, - CORBA_Environment *ev) -{ - PASBook *book = PAS_BOOK (bonobo_object (servant)); - - pas_book_queue_remove_cards (book, ids); -} - -static void -impl_GNOME_Evolution_Addressbook_Book_modifyCard (PortableServer_Servant servant, - const CORBA_char *vcard, - CORBA_Environment *ev) -{ - PASBook *book = PAS_BOOK (bonobo_object (servant)); - - pas_book_queue_modify_card (book, (const char *) vcard); -} - -static void -impl_GNOME_Evolution_Addressbook_Book_getCursor (PortableServer_Servant servant, - const CORBA_char *search, - CORBA_Environment *ev) -{ - PASBook *book = PAS_BOOK (bonobo_object (servant)); - - pas_book_queue_get_cursor (book, search); -} - -static void -impl_GNOME_Evolution_Addressbook_Book_getBookView (PortableServer_Servant servant, - const GNOME_Evolution_Addressbook_BookViewListener listener, - const CORBA_char *search, - CORBA_Environment *ev) -{ - PASBook *book = PAS_BOOK (bonobo_object (servant)); - - pas_book_queue_get_book_view (book, listener, search); -} - - -static void -impl_GNOME_Evolution_Addressbook_Book_getCompletionView (PortableServer_Servant servant, - const GNOME_Evolution_Addressbook_BookViewListener listener, - const CORBA_char *search, - CORBA_Environment *ev) -{ - PASBook *book = PAS_BOOK (bonobo_object (servant)); - - pas_book_queue_get_completion_view (book, listener, search); -} - -static void -impl_GNOME_Evolution_Addressbook_Book_getChanges (PortableServer_Servant servant, - const GNOME_Evolution_Addressbook_BookViewListener listener, - const CORBA_char *change_id, - CORBA_Environment *ev) -{ - PASBook *book = PAS_BOOK (bonobo_object (servant)); - - pas_book_queue_get_changes (book, listener, change_id); -} - -static void -impl_GNOME_Evolution_Addressbook_Book_checkConnection (PortableServer_Servant servant, - CORBA_Environment *ev) -{ - PASBook *book = PAS_BOOK (bonobo_object (servant)); - - pas_book_queue_check_connection (book); -} - -static char * -impl_GNOME_Evolution_Addressbook_Book_getStaticCapabilities (PortableServer_Servant servant, - CORBA_Environment *ev) -{ - PASBook *book = PAS_BOOK (bonobo_object (servant)); - char *temp; - char *ret_val; - - temp = pas_backend_get_static_capabilities (book->priv->backend); - ret_val = CORBA_string_dup(temp); - g_free(temp); - return ret_val; -} - -static void -impl_GNOME_Evolution_Addressbook_Book_getSupportedFields (PortableServer_Servant servant, - CORBA_Environment *ev) -{ - PASBook *book = PAS_BOOK (bonobo_object (servant)); - - pas_book_queue_get_supported_fields (book); -} - -static void -impl_GNOME_Evolution_Addressbook_Book_getSupportedAuthMethods (PortableServer_Servant servant, - CORBA_Environment *ev) -{ - PASBook *book = PAS_BOOK (bonobo_object (servant)); - - pas_book_queue_get_supported_auth_methods (book); -} - -/** - * pas_book_get_backend: - */ -PASBackend * -pas_book_get_backend (PASBook *book) -{ - g_return_val_if_fail (book != NULL, NULL); - g_return_val_if_fail (PAS_IS_BOOK (book), NULL); - - return book->priv->backend; -} - -/** - * pas_book_get_listener: - */ -GNOME_Evolution_Addressbook_BookListener -pas_book_get_listener (PASBook *book) -{ - g_return_val_if_fail (book != NULL, CORBA_OBJECT_NIL); - g_return_val_if_fail (PAS_IS_BOOK (book), CORBA_OBJECT_NIL); - - return book->priv->listener; -} - -/** - * pas_book_check_pending - */ -gint -pas_book_check_pending (PASBook *book) -{ - g_return_val_if_fail (book != NULL, -1); - g_return_val_if_fail (PAS_IS_BOOK (book), -1); - - return g_list_length (book->priv->request_queue); -} - -/** - * pas_book_pop_request: - */ -PASRequest * -pas_book_pop_request (PASBook *book) -{ - GList *popped; - PASRequest *req; - - g_return_val_if_fail (book != NULL, NULL); - g_return_val_if_fail (PAS_IS_BOOK (book), NULL); - - if (book->priv->request_queue == NULL) - return NULL; - - req = book->priv->request_queue->data; - - popped = book->priv->request_queue; - book->priv->request_queue = - g_list_remove_link (book->priv->request_queue, popped); - - g_list_free_1 (popped); - - return req; -} - -/** - * pas_book_respond_open: - */ -void -pas_book_respond_open (PASBook *book, - GNOME_Evolution_Addressbook_BookListener_CallStatus status) -{ - CORBA_Environment ev; - - CORBA_exception_init (&ev); - - if (status == GNOME_Evolution_Addressbook_BookListener_Success) { - GNOME_Evolution_Addressbook_BookListener_notifyBookOpened ( - book->priv->listener, status, - bonobo_object_corba_objref (BONOBO_OBJECT (book)), - &ev); - } else { - GNOME_Evolution_Addressbook_BookListener_notifyBookOpened ( - book->priv->listener, status, - CORBA_OBJECT_NIL, &ev); - } - - - if (ev._major != CORBA_NO_EXCEPTION) { - g_warning ("pas_book_respond_open: Exception " - "responding to BookListener!\n"); - } - - CORBA_exception_free (&ev); -} - -/** - * pas_book_respond_create: - */ -void -pas_book_respond_create (PASBook *book, - GNOME_Evolution_Addressbook_BookListener_CallStatus status, - const char *id) -{ - CORBA_Environment ev; - - CORBA_exception_init (&ev); - - GNOME_Evolution_Addressbook_BookListener_notifyCardCreated ( - book->priv->listener, status, (char *)id, &ev); - - if (ev._major != CORBA_NO_EXCEPTION) { - g_warning ("pas_book_respond_create: Exception " - "responding to BookListener!\n"); - } - - CORBA_exception_free (&ev); -} - -/** - * pas_book_respond_remove: - */ -void -pas_book_respond_remove (PASBook *book, - GNOME_Evolution_Addressbook_BookListener_CallStatus status) -{ - CORBA_Environment ev; - - CORBA_exception_init (&ev); - - GNOME_Evolution_Addressbook_BookListener_notifyCardsRemoved ( - book->priv->listener, status, &ev); - - if (ev._major != CORBA_NO_EXCEPTION) { - g_warning ("pas_book_respond_remove: Exception " - "responding to BookListener!\n"); - } - - CORBA_exception_free (&ev); -} - -/** - * pas_book_respond_modify: - */ -void -pas_book_respond_modify (PASBook *book, - GNOME_Evolution_Addressbook_BookListener_CallStatus status) -{ - CORBA_Environment ev; - - CORBA_exception_init (&ev); - - GNOME_Evolution_Addressbook_BookListener_notifyCardModified ( - book->priv->listener, status, &ev); - - if (ev._major != CORBA_NO_EXCEPTION) { - g_warning ("pas_book_respond_modify: Exception " - "responding to BookListener!\n"); - } - - CORBA_exception_free (&ev); -} - -/** - * pas_book_respond_authenticate_user: - */ -void -pas_book_respond_authenticate_user (PASBook *book, - GNOME_Evolution_Addressbook_BookListener_CallStatus status) -{ - CORBA_Environment ev; - - CORBA_exception_init (&ev); - - GNOME_Evolution_Addressbook_BookListener_notifyAuthenticationResult ( - book->priv->listener, status, &ev); - - if (ev._major != CORBA_NO_EXCEPTION) { - g_warning ("pas_book_respond_authenticate_user: Exception " - "responding to BookListener!\n"); - } - - CORBA_exception_free (&ev); -} - -void -pas_book_respond_get_supported_fields (PASBook *book, - GNOME_Evolution_Addressbook_BookListener_CallStatus status, - EList *fields) -{ - CORBA_Environment ev; - GNOME_Evolution_Addressbook_stringlist stringlist; - int num_fields; - EIterator *iter; - int i; - - CORBA_exception_init (&ev); - - num_fields = e_list_length (fields); - - stringlist._buffer = CORBA_sequence_CORBA_string_allocbuf (num_fields); - stringlist._maximum = num_fields; - stringlist._length = num_fields; - - iter = e_list_get_iterator (fields); - - for (i = 0; e_iterator_is_valid (iter); e_iterator_next (iter), i ++) { - stringlist._buffer[i] = CORBA_string_dup (e_iterator_get(iter)); - } - - g_object_unref (fields); - - GNOME_Evolution_Addressbook_BookListener_notifySupportedFields ( - book->priv->listener, status, - &stringlist, - &ev); - - CORBA_exception_free (&ev); - - CORBA_free(stringlist._buffer); -} - -void -pas_book_respond_get_supported_auth_methods (PASBook *book, - GNOME_Evolution_Addressbook_BookListener_CallStatus status, - EList *auth_methods) -{ - CORBA_Environment ev; - GNOME_Evolution_Addressbook_stringlist stringlist; - int num_auth_methods; - EIterator *iter; - int i; - - CORBA_exception_init (&ev); - - num_auth_methods = e_list_length (auth_methods); - - stringlist._buffer = CORBA_sequence_CORBA_string_allocbuf (num_auth_methods); - stringlist._maximum = num_auth_methods; - stringlist._length = num_auth_methods; - - iter = e_list_get_iterator (auth_methods); - - for (i = 0; e_iterator_is_valid (iter); e_iterator_next (iter), i ++) { - stringlist._buffer[i] = CORBA_string_dup (e_iterator_get(iter)); - } - - g_object_unref (auth_methods); - - GNOME_Evolution_Addressbook_BookListener_notifySupportedAuthMethods ( - book->priv->listener, status, - &stringlist, - &ev); - - CORBA_exception_free (&ev); - - CORBA_free(stringlist._buffer); -} - -/** - * pas_book_respond_get_cursor: - */ -void -pas_book_respond_get_cursor (PASBook *book, - GNOME_Evolution_Addressbook_BookListener_CallStatus status, - PASCardCursor *cursor) -{ - CORBA_Environment ev; - CORBA_Object object; - - CORBA_exception_init (&ev); - - object = bonobo_object_corba_objref(BONOBO_OBJECT(cursor)); - - GNOME_Evolution_Addressbook_BookListener_notifyCursorRequested ( - book->priv->listener, status, object, &ev); - - if (ev._major != CORBA_NO_EXCEPTION) { - g_warning ("pas_book_respond_get_cursor: Exception " - "responding to BookListener!\n"); - } - - CORBA_exception_free (&ev); -} - -/** - * pas_book_respond_get_book_view: - */ -void -pas_book_respond_get_book_view (PASBook *book, - GNOME_Evolution_Addressbook_BookListener_CallStatus status, - PASBookView *book_view) -{ - CORBA_Environment ev; - CORBA_Object object; - - CORBA_exception_init (&ev); - - object = bonobo_object_corba_objref(BONOBO_OBJECT(book_view)); - - GNOME_Evolution_Addressbook_BookListener_notifyViewRequested ( - book->priv->listener, status, object, &ev); - - if (ev._major != CORBA_NO_EXCEPTION) { - g_warning ("pas_book_respond_get_book_view: Exception " - "responding to BookListener!\n"); - } - - CORBA_exception_free (&ev); -} - -/** - * pas_book_respond_get_book_view: - */ -void -pas_book_respond_get_completion_view (PASBook *book, - GNOME_Evolution_Addressbook_BookListener_CallStatus status, - PASBookView *completion_view) -{ - CORBA_Environment ev; - CORBA_Object object; - - CORBA_exception_init (&ev); - - object = bonobo_object_corba_objref(BONOBO_OBJECT(completion_view)); - - GNOME_Evolution_Addressbook_BookListener_notifyViewRequested ( - book->priv->listener, status, object, &ev); - - if (ev._major != CORBA_NO_EXCEPTION) { - g_warning ("pas_book_respond_get_completion_view: Exception " - "responding to BookListener!\n"); - } - - CORBA_exception_free (&ev); -} - -/** - * pas_book_respond_get_changes: - */ -void -pas_book_respond_get_vcard (PASBook *book, - GNOME_Evolution_Addressbook_BookListener_CallStatus status, - char *vcard) -{ - CORBA_Environment ev; - - CORBA_exception_init (&ev); - - GNOME_Evolution_Addressbook_BookListener_notifyCardRequested ( - book->priv->listener, status, vcard, &ev); - - if (ev._major != CORBA_NO_EXCEPTION) { - g_warning ("pas_book_respond_get_card: Exception " - "responding to BookListener!\n"); - } - - CORBA_exception_free (&ev); -} - -/** - * pas_book_respond_get_changes: - */ -void -pas_book_respond_get_changes (PASBook *book, - GNOME_Evolution_Addressbook_BookListener_CallStatus status, - PASBookView *book_view) -{ - CORBA_Environment ev; - CORBA_Object object; - - CORBA_exception_init (&ev); - - object = bonobo_object_corba_objref(BONOBO_OBJECT(book_view)); - - GNOME_Evolution_Addressbook_BookListener_notifyChangesRequested ( - book->priv->listener, status, object, &ev); - - if (ev._major != CORBA_NO_EXCEPTION) { - g_warning ("pas_book_respond_get_changes: Exception " - "responding to BookListener!\n"); - } - - CORBA_exception_free (&ev); -} - -/** - * pas_book_report_connection: - */ -void -pas_book_report_connection (PASBook *book, - gboolean connected) -{ - CORBA_Environment ev; - - CORBA_exception_init (&ev); - - GNOME_Evolution_Addressbook_BookListener_notifyConnectionStatus ( - book->priv->listener, (CORBA_boolean) connected, &ev); - - if (ev._major != CORBA_NO_EXCEPTION) { - g_warning ("pas_book_report_connection: Exception " - "responding to BookListener!\n"); - } - - CORBA_exception_free (&ev); -} - -/** - * pas_book_report_writable: - */ -void -pas_book_report_writable (PASBook *book, - gboolean writable) -{ - CORBA_Environment ev; - - CORBA_exception_init (&ev); - - GNOME_Evolution_Addressbook_BookListener_notifyWritable ( - book->priv->listener, (CORBA_boolean) writable, &ev); - - if (ev._major != CORBA_NO_EXCEPTION) { - g_warning ("pas_book_report_writable: Exception " - "responding to BookListener!\n"); - } - - CORBA_exception_free (&ev); -} - -static void -pas_book_construct (PASBook *book, - PASBackend *backend, - GNOME_Evolution_Addressbook_BookListener listener) -{ - PASBookPrivate *priv; - CORBA_Environment ev; - - g_return_if_fail (book != NULL); - - priv = book->priv; - - priv->backend = backend; - - CORBA_exception_init (&ev); - book->priv->listener = CORBA_Object_duplicate (listener, &ev); - - if (ev._major != CORBA_NO_EXCEPTION) { - g_message ("pas_book_construct(): could not duplicate the listener"); - CORBA_exception_free (&ev); - return; - } - - CORBA_exception_free (&ev); - - priv->listener = listener; -} - -/** - * pas_book_new: - */ -PASBook * -pas_book_new (PASBackend *backend, - GNOME_Evolution_Addressbook_BookListener listener) -{ - PASBook *book; - - book = g_object_new (PAS_TYPE_BOOK, NULL); - - pas_book_construct (book, backend, listener); - - return book; -} - -void -pas_book_free_request (PASRequest *req) -{ - CORBA_Environment ev; - switch (req->op) { - case CreateCard: - g_free (req->create.id); - g_free (req->create.vcard); - break; - case RemoveCards: - g_list_foreach (req->remove.ids, (GFunc)g_free, NULL); - g_list_free (req->remove.ids); - break; - case ModifyCard: - g_free (req->modify.vcard); - break; - case GetVCard: - g_free (req->get_vcard.id); - break; - case GetCursor: - g_free (req->get_cursor.search); - break; - case GetBookView: - g_free (req->get_book_view.search); - CORBA_exception_init (&ev); - bonobo_object_release_unref (req->get_book_view.listener, &ev); - - if (ev._major != CORBA_NO_EXCEPTION) - g_message ("pas_book_free_request(GetBookView): could not release the listener"); - - CORBA_exception_free (&ev); - break; - case GetCompletionView: - g_free (req->get_completion_view.search); - CORBA_exception_init (&ev); - bonobo_object_release_unref (req->get_completion_view.listener, &ev); - - if (ev._major != CORBA_NO_EXCEPTION) - g_message ("pas_book_free_request(GetCompletionView): could not release the listener"); - - CORBA_exception_free (&ev); - break; - case GetChanges: - g_free (req->get_changes.change_id); - CORBA_exception_init (&ev); - bonobo_object_release_unref (req->get_changes.listener, &ev); - - if (ev._major != CORBA_NO_EXCEPTION) - g_message ("pas_book_free_request(GetChanges): could not release the listener"); - - CORBA_exception_free (&ev); - break; - case CheckConnection: - /* nothing to free */ - break; - case AuthenticateUser: - g_free (req->auth_user.user); - g_free (req->auth_user.passwd); - g_free (req->auth_user.auth_method); - break; - case GetSupportedFields: - /* nothing to free */ - break; - case GetSupportedAuthMethods: - /* nothing to free */ - break; - } - - g_free (req); -} - -static void -pas_book_dispose (GObject *object) -{ - PASBook *book = PAS_BOOK (object); - - if (book->priv) { - GList *l; - CORBA_Environment ev; - - for (l = book->priv->request_queue; l != NULL; l = l->next) { - pas_book_free_request ((PASRequest *)l->data); - } - g_list_free (book->priv->request_queue); - - /* We should never ever have timeout_id == 0 when we - get destroyed, unless there is some sort of - reference counting bug. Still, we do this to try - to avoid horrible crashes in those situations. */ - if (book->priv->timeout_id) { - g_warning ("PASBook destroyed with non-zero timeout_id. This shouldn't happen."); - g_source_remove (book->priv->timeout_id); - book->priv->timeout_id = 0; - } - - CORBA_exception_init (&ev); - CORBA_Object_release (book->priv->listener, &ev); - - if (ev._major != CORBA_NO_EXCEPTION) - g_message ("pas_book_construct(): could not release the listener"); - - CORBA_exception_free (&ev); - - g_free (book->priv); - book->priv = NULL; - } - - if (G_OBJECT_CLASS (pas_book_parent_class)->dispose) - G_OBJECT_CLASS (pas_book_parent_class)->dispose (object); -} - -static void -pas_book_class_init (PASBookClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - POA_GNOME_Evolution_Addressbook_Book__epv *epv; - - pas_book_parent_class = g_type_class_peek_parent (klass); - - pas_book_signals [REQUESTS_QUEUED] = - g_signal_new ("requests_queued", - G_OBJECT_CLASS_TYPE(object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (PASBookClass, requests_queued), - NULL, NULL, - pas_marshal_NONE__NONE, - G_TYPE_NONE, 0); - - object_class->dispose = pas_book_dispose; - - epv = &klass->epv; - - epv->getVCard = impl_GNOME_Evolution_Addressbook_Book_getVCard; - epv->authenticateUser = impl_GNOME_Evolution_Addressbook_Book_authenticateUser; - epv->addCard = impl_GNOME_Evolution_Addressbook_Book_addCard; - epv->removeCards = impl_GNOME_Evolution_Addressbook_Book_removeCards; - epv->modifyCard = impl_GNOME_Evolution_Addressbook_Book_modifyCard; - epv->checkConnection = impl_GNOME_Evolution_Addressbook_Book_checkConnection; - epv->getStaticCapabilities = impl_GNOME_Evolution_Addressbook_Book_getStaticCapabilities; - epv->getSupportedFields = impl_GNOME_Evolution_Addressbook_Book_getSupportedFields; - epv->getSupportedAuthMethods = impl_GNOME_Evolution_Addressbook_Book_getSupportedAuthMethods; - epv->getCursor = impl_GNOME_Evolution_Addressbook_Book_getCursor; - epv->getBookView = impl_GNOME_Evolution_Addressbook_Book_getBookView; - epv->getCompletionView = impl_GNOME_Evolution_Addressbook_Book_getCompletionView; - epv->getChanges = impl_GNOME_Evolution_Addressbook_Book_getChanges; -} - -static void -pas_book_init (PASBook *book) -{ - book->priv = g_new0 (PASBookPrivate, 1); - book->priv->timeout_id = 0; - book->priv->request_queue = NULL; - book->priv->timeout_id = 0; - book->priv->timeout_lock = FALSE; -} - -BONOBO_TYPE_FUNC_FULL ( - PASBook, - GNOME_Evolution_Addressbook_Book, - BONOBO_TYPE_OBJECT, - pas_book); diff --git a/addressbook/backend/pas/pas-book.h b/addressbook/backend/pas/pas-book.h deleted file mode 100644 index 761f906437..0000000000 --- a/addressbook/backend/pas/pas-book.h +++ /dev/null @@ -1,194 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * A wrapper object which exports the GNOME_Evolution_Addressbook_Book CORBA interface - * and which maintains a request queue. - * - * Author: - * Nat Friedman (nat@ximian.com) - * - * Copyright 2000, Ximian, Inc. - */ - -#ifndef __PAS_BOOK_H__ -#define __PAS_BOOK_H__ - -#include <bonobo/bonobo-object.h> -#include <pas/addressbook.h> -#include <pas/pas-book-view.h> -#include "e-util/e-list.h" - -#include <pas/pas-backend.h> -#include <pas/pas-card-cursor.h> - -#define PAS_TYPE_BOOK (pas_book_get_type ()) -#define PAS_BOOK(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), PAS_TYPE_BOOK, PASBook)) -#define PAS_BOOK_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), PAS_BOOK_FACTORY_TYPE, PASBookClass)) -#define PAS_IS_BOOK(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), PAS_TYPE_BOOK)) -#define PAS_IS_BOOK_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), PAS_TYPE_BOOK)) -#define PAS_BOOK_GET_CLASS(k) (G_TYPE_INSTANCE_GET_CLASS ((obj), PAS_TYPE_BOOK, PASBookClass)) - -typedef struct _PASBook PASBook; -typedef struct _PASBookPrivate PASBookPrivate; - -typedef enum { - CreateCard, - RemoveCards, - ModifyCard, - GetVCard, - GetCursor, - GetBookView, - GetCompletionView, - GetChanges, - CheckConnection, - AuthenticateUser, - GetSupportedFields, - GetSupportedAuthMethods -} PASOperation; - -typedef struct { - PASOperation op; - char *id; - char *vcard; -} PASCreateCardRequest; - -typedef struct { - PASOperation op; - GList *ids; -} PASRemoveCardsRequest; - -typedef struct { - PASOperation op; - char *vcard; -} PASModifyCardRequest; - -typedef struct { - PASOperation op; - char *id; -} PASGetVCardRequest; - -typedef struct { - PASOperation op; - char *search; -} PASGetCursorRequest; - -typedef struct { - PASOperation op; - char *search; - GNOME_Evolution_Addressbook_BookViewListener listener; -} PASGetBookViewRequest; - -typedef struct { - PASOperation op; - char *search; - GNOME_Evolution_Addressbook_BookViewListener listener; -} PASGetCompletionViewRequest; - -typedef struct { - PASOperation op; - char *change_id; - GNOME_Evolution_Addressbook_BookViewListener listener; -} PASGetChangesRequest; - -typedef struct { - PASOperation op; -} PASCheckConnectionRequest; - -typedef struct { - PASOperation op; - char *user; - char *passwd; - char *auth_method; -} PASAuthenticateUserRequest; - -typedef struct { - PASOperation op; -} PASGetSupportedFieldsRequest; - -typedef struct { - PASOperation op; -} PASGetSupportedAuthMethodsRequest; - -typedef union { - PASOperation op; - - PASCreateCardRequest create; - PASRemoveCardsRequest remove; - PASModifyCardRequest modify; - PASGetVCardRequest get_vcard; - PASGetCursorRequest get_cursor; - PASGetBookViewRequest get_book_view; - PASGetCompletionViewRequest get_completion_view; - PASGetChangesRequest get_changes; - PASCheckConnectionRequest check_connection; - PASAuthenticateUserRequest auth_user; - PASGetSupportedFieldsRequest get_supported_fields; - PASGetSupportedAuthMethodsRequest get_supported_auth_methods; -} PASRequest; - -struct _PASBook { - BonoboObject parent_object; - PASBookPrivate *priv; -}; - -typedef struct { - BonoboObjectClass parent_class; - - POA_GNOME_Evolution_Addressbook_Book__epv epv; - - /* Signals */ - void (*requests_queued) (void); -} PASBookClass; - - -typedef gboolean (*PASBookCanWriteFn) (PASBook *book); -typedef gboolean (*PASBookCanWriteCardFn) (PASBook *book, const char *id); - -PASBook *pas_book_new (PASBackend *backend, - GNOME_Evolution_Addressbook_BookListener listener); -PASBackend *pas_book_get_backend (PASBook *book); -GNOME_Evolution_Addressbook_BookListener pas_book_get_listener (PASBook *book); -int pas_book_check_pending (PASBook *book); -PASRequest *pas_book_pop_request (PASBook *book); -void pas_book_free_request (PASRequest *request); -void pas_book_respond_open (PASBook *book, - GNOME_Evolution_Addressbook_BookListener_CallStatus status); -void pas_book_respond_create (PASBook *book, - GNOME_Evolution_Addressbook_BookListener_CallStatus status, - const char *id); -void pas_book_respond_remove (PASBook *book, - GNOME_Evolution_Addressbook_BookListener_CallStatus status); -void pas_book_respond_modify (PASBook *book, - GNOME_Evolution_Addressbook_BookListener_CallStatus status); -void pas_book_respond_authenticate_user (PASBook *book, - GNOME_Evolution_Addressbook_BookListener_CallStatus status); -void pas_book_respond_get_supported_fields (PASBook *book, - GNOME_Evolution_Addressbook_BookListener_CallStatus status, - EList *fields); -void pas_book_respond_get_supported_auth_methods (PASBook *book, - GNOME_Evolution_Addressbook_BookListener_CallStatus status, - EList *fields); - -void pas_book_respond_get_cursor (PASBook *book, - GNOME_Evolution_Addressbook_BookListener_CallStatus status, - PASCardCursor *cursor); -void pas_book_respond_get_book_view (PASBook *book, - GNOME_Evolution_Addressbook_BookListener_CallStatus status, - PASBookView *book_view); -void pas_book_respond_get_completion_view (PASBook *book, - GNOME_Evolution_Addressbook_BookListener_CallStatus status, - PASBookView *completion_view); -void pas_book_respond_get_vcard (PASBook *book, - GNOME_Evolution_Addressbook_BookListener_CallStatus status, - char *vcard); -void pas_book_respond_get_changes (PASBook *book, - GNOME_Evolution_Addressbook_BookListener_CallStatus status, - PASBookView *book_view); -void pas_book_report_connection (PASBook *book, - gboolean connected); - -void pas_book_report_writable (PASBook *book, - gboolean writable); - -GType pas_book_get_type (void); - -#endif /* ! __PAS_BOOK_H__ */ diff --git a/addressbook/backend/pas/pas-card-cursor.c b/addressbook/backend/pas/pas-card-cursor.c deleted file mode 100644 index 9637bb1fb7..0000000000 --- a/addressbook/backend/pas/pas-card-cursor.c +++ /dev/null @@ -1,139 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * pas-card-cursor.c: Implements card cursors. - * - * Author: - * Christopher James Lahey <clahey@ximian.com. - */ - -#include <config.h> -#include <bonobo/bonobo-main.h> -#include "addressbook.h" -#include "pas-card-cursor.h" - -struct _PASCardCursorPrivate { - long (*get_length) (PASCardCursor *cursor, gpointer data); - char * (*get_nth) (PASCardCursor *cursor, long n, gpointer data); - gpointer data; -}; - -/* - * A pointer to our parent object class - */ -static BonoboObjectClass *parent_class; - -/* - * Implemented GObject::dispose - */ -static void -pas_card_cursor_dispose (GObject *object) -{ - PASCardCursor *cursor = PAS_CARD_CURSOR (object); - - if ( cursor->priv ) { - g_free ( cursor->priv ); - cursor->priv = NULL; - } - - if (G_OBJECT_CLASS (parent_class)->dispose) - G_OBJECT_CLASS (parent_class)->dispose (object); -} - -/* - * CORBA Demo::Echo::echo method implementation - */ -static CORBA_long -impl_pas_card_cursor_get_length (PortableServer_Servant servant, - CORBA_Environment *ev) -{ - PASCardCursor *cursor = PAS_CARD_CURSOR (bonobo_object (servant)); - if ( cursor->priv->get_length ) - return cursor->priv->get_length( cursor, cursor->priv->data ); - else - return 0; -} - -/* - * CORBA Demo::Echo::echo method implementation - */ -static char * -impl_pas_card_cursor_get_nth (PortableServer_Servant servant, - const CORBA_long n, - CORBA_Environment *ev) -{ - PASCardCursor *cursor = PAS_CARD_CURSOR (bonobo_object (servant)); - if ( cursor->priv->get_nth ) { - char *vcard = cursor->priv->get_nth( cursor, n, cursor->priv->data ); - char *retval = CORBA_string_dup (vcard); - g_free (vcard); - return retval; - } else - return CORBA_string_dup (""); -} - -static void -pas_card_cursor_class_init (PASCardCursorClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - POA_GNOME_Evolution_Addressbook_CardCursor__epv *epv; - - parent_class = g_type_class_peek_parent (klass); - - object_class->dispose = pas_card_cursor_dispose; - - - epv = &klass->epv; - - epv->count = impl_pas_card_cursor_get_length; - epv->getNth = impl_pas_card_cursor_get_nth; -} - -static void -pas_card_cursor_init (PASCardCursor *cursor) -{ - cursor->priv = g_new0(PASCardCursorPrivate, 1); - cursor->priv->get_length = NULL; - cursor->priv->get_nth = NULL; - cursor->priv->data = NULL; -} - -static void -pas_card_cursor_construct (PASCardCursor *cursor, - PASCardCursorLengthFunc get_length, - PASCardCursorNthFunc get_nth, - gpointer data) -{ - PASCardCursorPrivate *priv; - - g_return_if_fail (cursor != NULL); - g_return_if_fail (PAS_IS_CARD_CURSOR (cursor)); - - priv = cursor->priv; - - priv->get_length = get_length; - priv->get_nth = get_nth; - priv->data = data; -} - -PASCardCursor * -pas_card_cursor_new (PASCardCursorLengthFunc get_length, - PASCardCursorNthFunc get_nth, - gpointer data) -{ - PASCardCursor *cursor; - - cursor = g_object_new (PAS_TYPE_CARD_CURSOR, NULL); - - pas_card_cursor_construct (cursor, - get_length, - get_nth, - data); - - return cursor; -} - -BONOBO_TYPE_FUNC_FULL ( - PASCardCursor, - GNOME_Evolution_Addressbook_CardCursor, - BONOBO_TYPE_OBJECT, - pas_card_cursor); diff --git a/addressbook/backend/pas/pas-card-cursor.h b/addressbook/backend/pas/pas-card-cursor.h deleted file mode 100644 index db5b05c0c2..0000000000 --- a/addressbook/backend/pas/pas-card-cursor.h +++ /dev/null @@ -1,56 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * - * Author: - * Nat Friedman (nat@ximian.com) - * - * Copyright 2000, Ximian, Inc. - */ - -#ifndef __PAS_CARD_CURSOR_H__ -#define __PAS_CARD_CURSOR_H__ - -#include <bonobo/bonobo-object.h> -#include <pas/addressbook.h> - -G_BEGIN_DECLS - -#define PAS_TYPE_CARD_CURSOR (pas_card_cursor_get_type ()) -#define PAS_CARD_CURSOR(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), PAS_TYPE_CARD_CURSOR, PASCardCursor)) -#define PAS_CARD_CURSOR_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), PAS_TYPE_CARD_CURSOR, PASCardCursorClass)) -#define PAS_IS_CARD_CURSOR(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), PAS_TYPE_CARD_CURSOR)) -#define PAS_IS_CARD_CURSOR_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), PAS_TYPE_CARD_CURSOR)) -#define PAS_CARD_CURSOR_GET_CLASS(k) (G_TYPE_INSTANCE_GET_CLASS ((obj), PAS_TYPE_CARD_CURSOR, PASCardCursorClass)) - -typedef struct _PASCardCursor PASCardCursor; -typedef struct _PASCardCursorPrivate PASCardCursorPrivate; -typedef struct _PASCardCursorClass PASCardCursorClass; - -typedef long (*PASCardCursorLengthFunc) (PASCardCursor *cursor, gpointer data); -typedef char * (*PASCardCursorNthFunc) (PASCardCursor *cursor, long n, gpointer data); - -struct _PASCardCursor { - BonoboObject parent; - PASCardCursorPrivate *priv; -}; - -struct _PASCardCursorClass { - BonoboObjectClass parent; - - POA_GNOME_Evolution_Addressbook_CardCursor__epv epv; -}; - - - -/* Creating a new addressbook. */ -PASCardCursor *pas_card_cursor_new (PASCardCursorLengthFunc get_length, - PASCardCursorNthFunc get_nth, - gpointer data); - -GType pas_card_cursor_get_type (void); -POA_GNOME_Evolution_Addressbook_CardCursor__epv * - pas_card_cursor_get_epv (void); - -G_END_DECLS - -#endif /* ! __PAS_CARD_CURSOR_H__ */ diff --git a/addressbook/backend/pas/pas-marshal.list b/addressbook/backend/pas/pas-marshal.list deleted file mode 100644 index fa33740eaa..0000000000 --- a/addressbook/backend/pas/pas-marshal.list +++ /dev/null @@ -1 +0,0 @@ -NONE:NONE |