From a5eae6b70e50574791fa4967a03141aa79e8f77f Mon Sep 17 00:00:00 2001 From: Michael Rasmussen Date: Thu, 25 Jul 2013 02:26:25 +0200 Subject: [PATCH] Initial upload --- Doxyfile | 1544 +++++ README | 15 + caldav/awl/AWLUtilities.php | 403 ++ caldav/awl/Translation.php | 105 + caldav/awl/XMLElement.php | 333 ++ caldav/awl/iCalendar.php | 1633 ++++++ caldav/caldav-client.php | 532 ++ caldav/caldavresource.class.php | 304 + caldav/calendar.class.php | 317 + caldav/ical.class.php | 648 +++ caldav/icomponent.class.php | 147 + caldav/rfc2445.html | 8411 +++++++++++++++++++++++++++ caldav/rfc4791.html | 6116 +++++++++++++++++++ caldav/rruleparser.class.php | 468 ++ caldav/vevent.class.php | 155 + css/top_level.css | 277 + error.html | 24 + events/delete_event.php | 64 + events/edit_event.php | 218 + events/eventgui.class.php | 354 ++ events/new_event.php | 49 + events/update.php | 33 + include/footer.inc.php | 31 + include/header.inc.php | 49 + include/menu.inc.php | 58 + include/user_settings.inc.php | 132 + index.php | 70 + install/config.inc.php.patch | 42 + install/config.inc.php1.patch | 15 + install/install.php | 667 +++ install/pgsql_db_upgrade_0_7_3.sql | 11 + install/pgsql_db_upgrade_0_7_4.sql | 5 + install/pgsql_db_upgrade_0_7_5.sql | 12 + install/pgsql_db_upgrade_0_8_0.sql | 5 + install/pgsql_db_upgrade_0_8_1.sql | 5 + install/setup | 168 + install/sqlite_db_upgrade_0_7_3.sql | 9 + install/sqlite_db_upgrade_0_7_4.sql | 5 + install/sqlite_db_upgrade_0_7_5.sql | 12 + install/sqlite_db_upgrade_0_8_0.sql | 5 + install/sqlite_db_upgrade_0_8_1.sql | 5 + install/timezone.txt | 560 ++ install/tz.pl | 26 + install/upgrade.sh | 81 + js/ajax_wrapper.js | 83 + js/calendar.css | 95 + js/calendar_db.js | 329 ++ js/helper.js | 152 + js/img/cal.gif | Bin 0 -> 127 bytes js/img/next_mon.gif | Bin 0 -> 60 bytes js/img/next_year.gif | Bin 0 -> 70 bytes js/img/no_cal.gif | Bin 0 -> 139 bytes js/img/pixel.gif | Bin 0 -> 67 bytes js/img/prev_mon.gif | Bin 0 -> 59 bytes js/img/prev_year.gif | Bin 0 -> 69 bytes js/img/shade_bl.png | Bin 0 -> 185 bytes js/img/shade_bm.png | Bin 0 -> 164 bytes js/img/shade_br.png | Bin 0 -> 204 bytes js/img/shade_mr.png | Bin 0 -> 155 bytes js/img/shade_tr.png | Bin 0 -> 200 bytes js/license.txt | 16 + license.txt | 28 + login.php | 79 + logout.php | 33 + makedoc | 30 + navigate/goto_today.php | 61 + navigate/show_day.php | 45 + navigate/show_month.php | 45 + navigate/show_week.php | 45 + pixmaps/add-event.png | Bin 0 -> 1030 bytes pixmaps/calendar.png | Bin 0 -> 4255 bytes pixmaps/configuration.png | Bin 0 -> 1041 bytes pixmaps/day.png | Bin 0 -> 665 bytes pixmaps/delete-event.png | Bin 0 -> 1401 bytes pixmaps/edit-event.png | Bin 0 -> 1118 bytes pixmaps/exit.png | Bin 0 -> 1915 bytes pixmaps/favicon.ico | Bin 0 -> 1150 bytes pixmaps/goto-today.png | Bin 0 -> 1025 bytes pixmaps/left.png | Bin 0 -> 832 bytes pixmaps/month.png | Bin 0 -> 828 bytes pixmaps/print.png | Bin 0 -> 1143 bytes pixmaps/reload.png | Bin 0 -> 1228 bytes pixmaps/right.png | Bin 0 -> 807 bytes pixmaps/stock_init.png | Bin 0 -> 3768 bytes pixmaps/week.png | Bin 0 -> 697 bytes templates/day_view.class.php | 202 + templates/month_view.class.php | 214 + templates/view.class.php | 313 + templates/week_view.class.php | 247 + user_exist_error.php | 29 + user_validate.php | 28 + utils/authenticate.php | 180 + utils/calendar.php | 188 + utils/configure.php | 257 + utils/dateformat.class.php | 58 + utils/db_create.postgresql.php | 59 + utils/db_create.sql | 94 + utils/db_create.sqlite.php | 105 + utils/helper.php | 615 ++ utils/ldap.php | 135 + utils/newuser.php | 98 + utils/persistens.php | 194 + utils/pgsql.php | 724 +++ utils/sqlite.php | 797 +++ utils/timezone.php | 500 ++ utils/upgrade_db.php | 23 + utils/users.php | 121 + 107 files changed, 30345 insertions(+) create mode 100644 Doxyfile create mode 100644 README create mode 100644 caldav/awl/AWLUtilities.php create mode 100644 caldav/awl/Translation.php create mode 100644 caldav/awl/XMLElement.php create mode 100644 caldav/awl/iCalendar.php create mode 100644 caldav/caldav-client.php create mode 100644 caldav/caldavresource.class.php create mode 100644 caldav/calendar.class.php create mode 100644 caldav/ical.class.php create mode 100644 caldav/icomponent.class.php create mode 100644 caldav/rfc2445.html create mode 100644 caldav/rfc4791.html create mode 100644 caldav/rruleparser.class.php create mode 100644 caldav/vevent.class.php create mode 100644 css/top_level.css create mode 100644 error.html create mode 100644 events/delete_event.php create mode 100644 events/edit_event.php create mode 100644 events/eventgui.class.php create mode 100644 events/new_event.php create mode 100644 events/update.php create mode 100644 include/footer.inc.php create mode 100644 include/header.inc.php create mode 100644 include/menu.inc.php create mode 100644 include/user_settings.inc.php create mode 100644 index.php create mode 100644 install/config.inc.php.patch create mode 100644 install/config.inc.php1.patch create mode 100644 install/install.php create mode 100644 install/pgsql_db_upgrade_0_7_3.sql create mode 100644 install/pgsql_db_upgrade_0_7_4.sql create mode 100644 install/pgsql_db_upgrade_0_7_5.sql create mode 100644 install/pgsql_db_upgrade_0_8_0.sql create mode 100644 install/pgsql_db_upgrade_0_8_1.sql create mode 100644 install/setup create mode 100644 install/sqlite_db_upgrade_0_7_3.sql create mode 100644 install/sqlite_db_upgrade_0_7_4.sql create mode 100644 install/sqlite_db_upgrade_0_7_5.sql create mode 100644 install/sqlite_db_upgrade_0_8_0.sql create mode 100644 install/sqlite_db_upgrade_0_8_1.sql create mode 100644 install/timezone.txt create mode 100644 install/tz.pl create mode 100644 install/upgrade.sh create mode 100644 js/ajax_wrapper.js create mode 100644 js/calendar.css create mode 100644 js/calendar_db.js create mode 100644 js/helper.js create mode 100644 js/img/cal.gif create mode 100644 js/img/next_mon.gif create mode 100644 js/img/next_year.gif create mode 100644 js/img/no_cal.gif create mode 100644 js/img/pixel.gif create mode 100644 js/img/prev_mon.gif create mode 100644 js/img/prev_year.gif create mode 100644 js/img/shade_bl.png create mode 100644 js/img/shade_bm.png create mode 100644 js/img/shade_br.png create mode 100644 js/img/shade_mr.png create mode 100644 js/img/shade_tr.png create mode 100644 js/license.txt create mode 100644 license.txt create mode 100644 login.php create mode 100644 logout.php create mode 100644 makedoc create mode 100644 navigate/goto_today.php create mode 100644 navigate/show_day.php create mode 100644 navigate/show_month.php create mode 100644 navigate/show_week.php create mode 100644 pixmaps/add-event.png create mode 100644 pixmaps/calendar.png create mode 100644 pixmaps/configuration.png create mode 100644 pixmaps/day.png create mode 100644 pixmaps/delete-event.png create mode 100644 pixmaps/edit-event.png create mode 100644 pixmaps/exit.png create mode 100644 pixmaps/favicon.ico create mode 100644 pixmaps/goto-today.png create mode 100644 pixmaps/left.png create mode 100644 pixmaps/month.png create mode 100644 pixmaps/print.png create mode 100644 pixmaps/reload.png create mode 100644 pixmaps/right.png create mode 100644 pixmaps/stock_init.png create mode 100644 pixmaps/week.png create mode 100644 templates/day_view.class.php create mode 100644 templates/month_view.class.php create mode 100644 templates/view.class.php create mode 100644 templates/week_view.class.php create mode 100644 user_exist_error.php create mode 100644 user_validate.php create mode 100644 utils/authenticate.php create mode 100644 utils/calendar.php create mode 100644 utils/configure.php create mode 100644 utils/dateformat.class.php create mode 100644 utils/db_create.postgresql.php create mode 100644 utils/db_create.sql create mode 100644 utils/db_create.sqlite.php create mode 100644 utils/helper.php create mode 100644 utils/ldap.php create mode 100644 utils/newuser.php create mode 100644 utils/persistens.php create mode 100644 utils/pgsql.php create mode 100644 utils/sqlite.php create mode 100644 utils/timezone.php create mode 100644 utils/upgrade_db.php create mode 100644 utils/users.php diff --git a/Doxyfile b/Doxyfile new file mode 100644 index 0000000..4f1ddae --- /dev/null +++ b/Doxyfile @@ -0,0 +1,1544 @@ +# $Id$ +# Doxyfile 1.5.9 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project +# +# All text after a hash (#) is considered a comment and will be ignored +# The format is: +# TAG = value [value, ...] +# For lists items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (" ") + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# This tag specifies the encoding used for all characters in the config file +# that follow. The default is UTF-8 which is also the encoding used for all +# text before the first occurrence of this tag. Doxygen uses libiconv (or the +# iconv built into libc) for the transcoding. See +# http://www.gnu.org/software/libiconv for the list of possible encodings. + +DOXYFILE_ENCODING = UTF-8 + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded +# by quotes) that should identify the project. + +PROJECT_NAME = webcal + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. +# This could be handy for archiving the generated documentation or +# if some version control system is used. + +PROJECT_NUMBER = 0.7.4 + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +# base path where the generated documentation will be put. +# If a relative path is entered, it will be relative to the location +# where doxygen was started. If left blank the current directory will be used. + +OUTPUT_DIRECTORY = doc + +# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create +# 4096 sub-directories (in 2 levels) under the output directory of each output +# format and will distribute the generated files over these directories. +# Enabling this option can be useful when feeding doxygen a huge amount of +# source files, where putting all generated files in the same directory would +# otherwise cause performance problems for the file system. + +CREATE_SUBDIRS = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# The default language is English, other supported languages are: +# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, +# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, +# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English +# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, +# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrilic, Slovak, +# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. + +OUTPUT_LANGUAGE = English + +# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will +# include brief member descriptions after the members that are listed in +# the file and class documentation (similar to JavaDoc). +# Set to NO to disable this. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend +# the brief description of a member or function before the detailed description. +# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator +# that is used to form the text in various listings. Each string +# in this list, if found as the leading text of the brief description, will be +# stripped from the text and the result after processing the whole list, is +# used as the annotated text. Otherwise, the brief description is used as-is. +# If left blank, the following values are used ("$name" is automatically +# replaced with the name of the entity): "The $name class" "The $name widget" +# "The $name file" "is" "provides" "specifies" "contains" +# "represents" "a" "an" "the" + +ABBREVIATE_BRIEF = "The $name class" \ + "The $name widget" \ + "The $name file" \ + is \ + provides \ + specifies \ + contains \ + represents \ + a \ + an \ + the + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# Doxygen will generate a detailed section even if there is only a brief +# description. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full +# path before files name in the file list and in the header files. If set +# to NO the shortest path that makes the file name unique will be used. + +FULL_PATH_NAMES = YES + +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +# can be used to strip a user-defined part of the path. Stripping is +# only done if one of the specified strings matches the left-hand part of +# the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the +# path to strip. + +STRIP_FROM_PATH = /Users/dimitri/doxygen/mail/1.5.7/doxywizard/ + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of +# the path mentioned in the documentation of a class, which tells +# the reader which header file to include in order to use a class. +# If left blank only the name of the header file containing the class +# definition is used. Otherwise one should specify the include paths that +# are normally passed to the compiler using the -I flag. + +STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter +# (but less readable) file names. This can be useful is your file systems +# doesn't support long names like on DOS, Mac, or CD-ROM. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen +# will interpret the first line (until the first dot) of a JavaDoc-style +# comment as the brief description. If set to NO, the JavaDoc +# comments will behave just like regular Qt-style comments +# (thus requiring an explicit @brief command for a brief description.) + +JAVADOC_AUTOBRIEF = NO + +# If the QT_AUTOBRIEF tag is set to YES then Doxygen will +# interpret the first line (until the first dot) of a Qt-style +# comment as the brief description. If set to NO, the comments +# will behave just like regular Qt-style comments (thus requiring +# an explicit \brief command for a brief description.) + +QT_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen +# treat a multi-line C++ special comment block (i.e. a block of //! or /// +# comments) as a brief description. This used to be the default behaviour. +# The new default is to treat a multi-line C++ comment block as a detailed +# description. Set this tag to YES if you prefer the old behaviour instead. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented +# member inherits the documentation from any documented member that it +# re-implements. + +INHERIT_DOCS = YES + +# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce +# a new page for each member. If set to NO, the documentation of a member will +# be part of the file/class/namespace that contains it. + +SEPARATE_MEMBER_PAGES = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. +# Doxygen uses this value to replace tabs by spaces in code fragments. + +TAB_SIZE = 8 + +# This tag can be used to specify a number of aliases that acts +# as commands in the documentation. An alias has the form "name=value". +# For example adding "sideeffect=\par Side Effects:\n" will allow you to +# put the command \sideeffect (or @sideeffect) in the documentation, which +# will result in a user-defined paragraph with heading "Side Effects:". +# You can put \n's in the value part of an alias to insert newlines. + +ALIASES = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C +# sources only. Doxygen will then generate output that is more tailored for C. +# For instance, some of the names that are used will be different. The list +# of all members will be omitted, etc. + +OPTIMIZE_OUTPUT_FOR_C = YES + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java +# sources only. Doxygen will then generate output that is more tailored for +# Java. For instance, namespaces will be presented as packages, qualified +# scopes will look different, etc. + +OPTIMIZE_OUTPUT_JAVA = NO + +# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran +# sources only. Doxygen will then generate output that is more tailored for +# Fortran. + +OPTIMIZE_FOR_FORTRAN = NO + +# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL +# sources. Doxygen will then generate output that is tailored for +# VHDL. + +OPTIMIZE_OUTPUT_VHDL = NO + +# Doxygen selects the parser to use depending on the extension of the files it parses. +# With this tag you can assign which parser to use for a given extension. +# Doxygen has a built-in mapping, but you can override or extend it using this tag. +# The format is ext=language, where ext is a file extension, and language is one of +# the parsers supported by doxygen: IDL, Java, Javascript, C#, C, C++, D, PHP, +# Objective-C, Python, Fortran, VHDL, C, C++. For instance to make doxygen treat +# .inc files as Fortran files (default is PHP), and .f files as C (default is Fortran), +# use: inc=Fortran f=C. Note that for custom extensions you also need to set +# FILE_PATTERNS otherwise the files are not read by doxygen. + +EXTENSION_MAPPING = + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want +# to include (a tag file for) the STL sources as input, then you should +# set this tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. +# func(std::string) {}). This also make the inheritance and collaboration +# diagrams that involve STL classes more complete and accurate. + +BUILTIN_STL_SUPPORT = NO + +# If you use Microsoft's C++/CLI language, you should set this option to YES to +# enable parsing support. + +CPP_CLI_SUPPORT = NO + +# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. +# Doxygen will parse them like normal C++ but will assume all classes use public +# instead of private inheritance when no explicit protection keyword is present. + +SIP_SUPPORT = NO + +# For Microsoft's IDL there are propget and propput attributes to indicate getter +# and setter methods for a property. Setting this option to YES (the default) +# will make doxygen to replace the get and set methods by a property in the +# documentation. This will only work if the methods are indeed getting or +# setting a simple type. If this is not the case, or you want to show the +# methods anyway, you should set this option to NO. + +IDL_PROPERTY_SUPPORT = YES + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. + +DISTRIBUTE_GROUP_DOC = NO + +# Set the SUBGROUPING tag to YES (the default) to allow class member groups of +# the same type (for instance a group of public functions) to be put as a +# subgroup of that type (e.g. under the Public Functions section). Set it to +# NO to prevent subgrouping. Alternatively, this can be done per class using +# the \nosubgrouping command. + +SUBGROUPING = YES + +# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum +# is documented as struct, union, or enum with the name of the typedef. So +# typedef struct TypeS {} TypeT, will appear in the documentation as a struct +# with name TypeT. When disabled the typedef will appear as a member of a file, +# namespace, or class. And the struct will be named TypeS. This can typically +# be useful for C code in case the coding convention dictates that all compound +# types are typedef'ed and only the typedef is referenced, never the tag name. + +TYPEDEF_HIDES_STRUCT = NO + +# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to +# determine which symbols to keep in memory and which to flush to disk. +# When the cache is full, less often used symbols will be written to disk. +# For small to medium size projects (<1000 input files) the default value is +# probably good enough. For larger projects a too small cache size can cause +# doxygen to be busy swapping symbols to and from disk most of the time +# causing a significant performance penality. +# If the system has enough physical memory increasing the cache will improve the +# performance by keeping more symbols in memory. Note that the value works on +# a logarithmic scale so increasing the size by one will rougly double the +# memory usage. The cache size is given by this formula: +# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, +# corresponding to a cache size of 2^16 = 65536 symbols + +SYMBOL_CACHE_SIZE = 0 + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless +# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES + +EXTRACT_ALL = YES + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# will be included in the documentation. + +EXTRACT_PRIVATE = NO + +# If the EXTRACT_STATIC tag is set to YES all static members of a file +# will be included in the documentation. + +EXTRACT_STATIC = NO + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) +# defined locally in source files will be included in the documentation. +# If set to NO only classes defined in header files are included. + +EXTRACT_LOCAL_CLASSES = YES + +# This flag is only useful for Objective-C code. When set to YES local +# methods, which are defined in the implementation section but not in +# the interface are included in the documentation. +# If set to NO (the default) only methods in the interface are included. + +EXTRACT_LOCAL_METHODS = NO + +# If this flag is set to YES, the members of anonymous namespaces will be +# extracted and appear in the documentation as a namespace called +# 'anonymous_namespace{file}', where file will be replaced with the base +# name of the file that contains the anonymous namespace. By default +# anonymous namespace are hidden. + +EXTRACT_ANON_NSPACES = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. +# This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these classes will be included in the various +# overviews. This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all +# friend (class|struct|union) declarations. +# If set to NO (the default) these declarations will be included in the +# documentation. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any +# documentation blocks found inside the body of a function. +# If set to NO (the default) these blocks will be appended to the +# function's detailed documentation block. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation +# that is typed after a \internal command is included. If the tag is set +# to NO (the default) then the documentation will be excluded. +# Set it to YES to include the internal documentation. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate +# file names in lower-case letters. If set to YES upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# and Mac users are advised to set this option to NO. + +CASE_SENSE_NAMES = NO + +# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen +# will show members with their full class and namespace scopes in the +# documentation. If set to YES the scope will be hidden. + +HIDE_SCOPE_NAMES = YES + +# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen +# will put a list of the files that are included by a file in the documentation +# of that file. + +SHOW_INCLUDE_FILES = YES + +# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] +# is inserted in the documentation for inline members. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen +# will sort the (detailed) documentation of file and class members +# alphabetically by member name. If set to NO the members will appear in +# declaration order. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the +# brief documentation of file, namespace and class members alphabetically +# by member name. If set to NO (the default) the members will appear in +# declaration order. + +SORT_BRIEF_DOCS = NO + +# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the +# hierarchy of group names into alphabetical order. If set to NO (the default) +# the group names will appear in their defined order. + +SORT_GROUP_NAMES = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be +# sorted by fully-qualified names, including namespaces. If set to +# NO (the default), the class list will be sorted only by class name, +# not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the +# alphabetical list. + +SORT_BY_SCOPE_NAME = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or +# disable (NO) the todo list. This list is created by putting \todo +# commands in the documentation. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or +# disable (NO) the test list. This list is created by putting \test +# commands in the documentation. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or +# disable (NO) the bug list. This list is created by putting \bug +# commands in the documentation. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or +# disable (NO) the deprecated list. This list is created by putting +# \deprecated commands in the documentation. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional +# documentation sections, marked by \if sectionname ... \endif. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines +# the initial value of a variable or define consists of for it to appear in +# the documentation. If the initializer consists of more lines than specified +# here it will be hidden. Use a value of 0 to hide initializers completely. +# The appearance of the initializer of individual variables and defines in the +# documentation can be controlled using \showinitializer or \hideinitializer +# command in the documentation regardless of this setting. + +MAX_INITIALIZER_LINES = 30 + +# If the sources in your project are distributed over multiple directories +# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy +# in the documentation. The default is NO. + +SHOW_DIRECTORIES = NO + +# Set the SHOW_FILES tag to NO to disable the generation of the Files page. +# This will remove the Files entry from the Quick Index and from the +# Folder Tree View (if specified). The default is YES. + +SHOW_FILES = YES + +# Set the SHOW_NAMESPACES tag to NO to disable the generation of the +# Namespaces page. This will remove the Namespaces entry from the Quick Index +# and from the Folder Tree View (if specified). The default is YES. + +SHOW_NAMESPACES = YES + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from +# the version control system). Doxygen will invoke the program by executing (via +# popen()) the command , where is the value of +# the FILE_VERSION_FILTER tag, and is the name of an input file +# provided by doxygen. Whatever the program writes to standard output +# is used as the file version. See the manual for examples. + +FILE_VERSION_FILTER = + +# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed by +# doxygen. The layout file controls the global structure of the generated output files +# in an output format independent way. The create the layout file that represents +# doxygen's defaults, run doxygen with the -l option. You can optionally specify a +# file name after the option, if omitted DoxygenLayout.xml will be used as the name +# of the layout file. + +LAYOUT_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated +# by doxygen. Possible values are YES and NO. If left blank NO is used. + +QUIET = NO + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated by doxygen. Possible values are YES and NO. If left blank +# NO is used. + +WARNINGS = YES + +# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings +# for undocumented members. If EXTRACT_ALL is set to YES then this flag will +# automatically be disabled. + +WARN_IF_UNDOCUMENTED = YES + +# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some +# parameters in a documented function, or documenting parameters that +# don't exist or using markup commands wrongly. + +WARN_IF_DOC_ERROR = YES + +# This WARN_NO_PARAMDOC option can be abled to get warnings for +# functions that are documented, but have no documentation for their parameters +# or return value. If set to NO (the default) doxygen will only warn about +# wrong or incomplete parameter documentation, but not about the absence of +# documentation. + +WARN_NO_PARAMDOC = NO + +# The WARN_FORMAT tag determines the format of the warning messages that +# doxygen can produce. The string should contain the $file, $line, and $text +# tags, which will be replaced by the file and line number from which the +# warning originated and the warning text. Optionally the format may contain +# $version, which will be replaced by the version of the file (if it could +# be obtained via FILE_VERSION_FILTER) + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning +# and error messages should be written. If left blank the output is written +# to stderr. + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag can be used to specify the files and/or directories that contain +# documented source files. You may enter file names like "myfile.cpp" or +# directories like "/usr/src/myproject". Separate the files or directories +# with spaces. + +INPUT = ./doc_source + +# This tag can be used to specify the character encoding of the source files +# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is +# also the default input encoding. Doxygen uses libiconv (or the iconv built +# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for +# the list of possible encodings. + +INPUT_ENCODING = UTF-8 + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank the following patterns are tested: +# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx +# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.f90 + +FILE_PATTERNS = *.c \ + *.cc \ + *.cxx \ + *.cpp \ + *.c++ \ + *.d \ + *.java \ + *.ii \ + *.ixx \ + *.ipp \ + *.i++ \ + *.inl \ + *.h \ + *.hh \ + *.hxx \ + *.hpp \ + *.h++ \ + *.idl \ + *.odl \ + *.cs \ + *.php \ + *.php3 \ + *.inc \ + *.m \ + *.mm \ + *.dox \ + *.py \ + *.f90 \ + *.f \ + *.vhd \ + *.vhdl + +# The RECURSIVE tag can be used to turn specify whether or not subdirectories +# should be searched for input files as well. Possible values are YES and NO. +# If left blank NO is used. + +RECURSIVE = YES + +# The EXCLUDE tag can be used to specify files and/or directories that should +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. + +EXCLUDE = + +# The EXCLUDE_SYMLINKS tag can be used select whether or not files or +# directories that are symbolic links (a Unix filesystem feature) are excluded +# from the input. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. Note that the wildcards are matched +# against the file with absolute path, so to exclude all test directories +# for example use the pattern */test/* + +EXCLUDE_PATTERNS = + +# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names +# (namespaces, classes, functions, etc.) that should be excluded from the +# output. The symbol name can be a fully qualified name, a word, or if the +# wildcard * is used, a substring. Examples: ANamespace, AClass, +# AClass::ANamespace, ANamespace::*Test + +EXCLUDE_SYMBOLS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or +# directories that contain example code fragments that are included (see +# the \include command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank all files are included. + +EXAMPLE_PATTERNS = * + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude +# commands irrespective of the value of the RECURSIVE tag. +# Possible values are YES and NO. If left blank NO is used. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or +# directories that contain image that are included in the documentation (see +# the \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command , where +# is the value of the INPUT_FILTER tag, and is the name of an +# input file. Doxygen will then use the output that the filter program writes +# to standard output. If FILTER_PATTERNS is specified, this tag will be +# ignored. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. The filters are a list of the form: +# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further +# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER +# is applied to all files. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will be used to filter the input files when producing source +# files to browse (i.e. when SOURCE_BROWSER is set to YES). + +FILTER_SOURCE_FILES = NO + +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will +# be generated. Documented entities will be cross-referenced with these sources. +# Note: To get rid of all source code in the generated output, make sure also +# VERBATIM_HEADERS is set to NO. + +SOURCE_BROWSER = YES + +# Setting the INLINE_SOURCES tag to YES will include the body +# of functions and classes directly in the documentation. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct +# doxygen to hide any special comment blocks from generated source code +# fragments. Normal C and C++ comments will always remain visible. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES +# then for each documented function all documented +# functions referencing it will be listed. + +REFERENCED_BY_RELATION = NO + +# If the REFERENCES_RELATION tag is set to YES +# then for each documented function all documented entities +# called/used by that function will be listed. + +REFERENCES_RELATION = NO + +# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) +# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from +# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will +# link to the source code. Otherwise they will link to the documentation. + +REFERENCES_LINK_SOURCE = YES + +# If the USE_HTAGS tag is set to YES then the references to source code +# will point to the HTML generated by the htags(1) tool instead of doxygen +# built-in source browser. The htags tool is part of GNU's global source +# tagging system (see http://www.gnu.org/software/global/global.html). You +# will need version 4.8.6 or higher. + +USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen +# will generate a verbatim copy of the header file for each class for +# which an include is specified. Set to NO to disable this. + +VERBATIM_HEADERS = YES + +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index +# of all compounds will be generated. Enable this if the project +# contains a lot of classes, structs, unions or interfaces. + +ALPHABETICAL_INDEX = NO + +# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then +# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns +# in which this list will be split (can be a number in the range [1..20]) + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all +# classes will be put under the same header in the alphabetical index. +# The IGNORE_PREFIX tag can be used to specify one or more prefixes that +# should be ignored while generating the index headers. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES (the default) Doxygen will +# generate HTML output. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `html' will be used as the default path. + +HTML_OUTPUT = html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for +# each generated HTML page (for example: .htm,.php,.asp). If it is left blank +# doxygen will generate files with .html extension. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a personal HTML header for +# each generated HTML page. If it is left blank doxygen will generate a +# standard header. + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a personal HTML footer for +# each generated HTML page. If it is left blank doxygen will generate a +# standard footer. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading +# style sheet that is used by each HTML page. It can be used to +# fine-tune the look of the HTML output. If the tag is left blank doxygen +# will generate a default style sheet. Note that doxygen will try to copy +# the style sheet file to the HTML output directory, so don't put your own +# stylesheet in the HTML output directory as well, or it will be erased! + +HTML_STYLESHEET = + +# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, +# files or namespaces will be aligned in HTML using tables. If set to +# NO a bullet list will be used. + +HTML_ALIGN_MEMBERS = YES + +# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML +# documentation will contain sections that can be hidden and shown after the +# page has loaded. For this to work a browser that supports +# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox +# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). + +HTML_DYNAMIC_SECTIONS = NO + +# If the GENERATE_DOCSET tag is set to YES, additional index files +# will be generated that can be used as input for Apple's Xcode 3 +# integrated development environment, introduced with OSX 10.5 (Leopard). +# To create a documentation set, doxygen will generate a Makefile in the +# HTML output directory. Running make will produce the docset in that +# directory and running "make install" will install the docset in +# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find +# it at startup. +# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html for more information. + +GENERATE_DOCSET = NO + +# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the +# feed. A documentation feed provides an umbrella under which multiple +# documentation sets from a single provider (such as a company or product suite) +# can be grouped. + +DOCSET_FEEDNAME = "Doxygen generated docs" + +# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that +# should uniquely identify the documentation set bundle. This should be a +# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen +# will append .docset to the name. + +DOCSET_BUNDLE_ID = org.doxygen.Project + +# If the GENERATE_HTMLHELP tag is set to YES, additional index files +# will be generated that can be used as input for tools like the +# Microsoft HTML help workshop to generate a compiled HTML help file (.chm) +# of the generated HTML documentation. + +GENERATE_HTMLHELP = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can +# be used to specify the file name of the resulting .chm file. You +# can add a path in front of the file if the result should not be +# written to the html output directory. + +CHM_FILE = + +# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can +# be used to specify the location (absolute path including file name) of +# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run +# the HTML help compiler on the generated index.hhp. + +HHC_LOCATION = + +# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag +# controls if a separate .chi index file is generated (YES) or that +# it should be included in the master .chm file (NO). + +GENERATE_CHI = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING +# is used to encode HtmlHelp index (hhk), content (hhc) and project file +# content. + +CHM_INDEX_ENCODING = + +# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag +# controls whether a binary table of contents is generated (YES) or a +# normal table of contents (NO) in the .chm file. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members +# to the contents of the HTML help documentation and to the tree view. + +TOC_EXPAND = NO + +# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and QHP_VIRTUAL_FOLDER +# are set, an additional index file will be generated that can be used as input for +# Qt's qhelpgenerator to generate a Qt Compressed Help (.qch) of the generated +# HTML documentation. + +GENERATE_QHP = NO + +# If the QHG_LOCATION tag is specified, the QCH_FILE tag can +# be used to specify the file name of the resulting .qch file. +# The path specified is relative to the HTML output folder. + +QCH_FILE = + +# The QHP_NAMESPACE tag specifies the namespace to use when generating +# Qt Help Project output. For more information please see +# http://doc.trolltech.com/qthelpproject.html#namespace + +QHP_NAMESPACE = + +# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating +# Qt Help Project output. For more information please see +# http://doc.trolltech.com/qthelpproject.html#virtual-folders + +QHP_VIRTUAL_FOLDER = doc + +# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to add. +# For more information please see +# http://doc.trolltech.com/qthelpproject.html#custom-filters + +QHP_CUST_FILTER_NAME = + +# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the custom filter to add.For more information please see +# Qt Help Project / Custom Filters. + +QHP_CUST_FILTER_ATTRS = + +# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this project's +# filter section matches. +# Qt Help Project / Filter Attributes. + +QHP_SECT_FILTER_ATTRS = + +# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can +# be used to specify the location of Qt's qhelpgenerator. +# If non-empty doxygen will try to run qhelpgenerator on the generated +# .qhp file. + +QHG_LOCATION = + +# The DISABLE_INDEX tag can be used to turn on/off the condensed index at +# top of each HTML page. The value NO (the default) enables the index and +# the value YES disables it. + +DISABLE_INDEX = NO + +# This tag can be used to set the number of enum values (range [1..20]) +# that doxygen will group on one line in the generated HTML documentation. + +ENUM_VALUES_PER_LINE = 4 + +# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index +# structure should be generated to display hierarchical information. +# If the tag value is set to FRAME, a side panel will be generated +# containing a tree-like index structure (just like the one that +# is generated for HTML Help). For this to work a browser that supports +# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, +# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are +# probably better off using the HTML help feature. Other possible values +# for this tag are: HIERARCHIES, which will generate the Groups, Directories, +# and Class Hierarchy pages using a tree view instead of an ordered list; +# ALL, which combines the behavior of FRAME and HIERARCHIES; and NONE, which +# disables this behavior completely. For backwards compatibility with previous +# releases of Doxygen, the values YES and NO are equivalent to FRAME and NONE +# respectively. + +GENERATE_TREEVIEW = ALL + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be +# used to set the initial width (in pixels) of the frame in which the tree +# is shown. + +TREEVIEW_WIDTH = 250 + +# Use this tag to change the font size of Latex formulas included +# as images in the HTML documentation. The default is 10. Note that +# when you change the font size after a successful doxygen run you need +# to manually remove any form_*.png images from the HTML output directory +# to force them to be regenerated. + +FORMULA_FONTSIZE = 10 + +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will +# generate Latex output. + +GENERATE_LATEX = YES + +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `latex' will be used as the default path. + +LATEX_OUTPUT = latex + +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be +# invoked. If left blank `latex' will be used as the default command name. + +LATEX_CMD_NAME = latex + +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to +# generate index for LaTeX. If left blank `makeindex' will be used as the +# default command name. + +MAKEINDEX_CMD_NAME = makeindex + +# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact +# LaTeX documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_LATEX = NO + +# The PAPER_TYPE tag can be used to set the paper type that is used +# by the printer. Possible values are: a4, a4wide, letter, legal and +# executive. If left blank a4wide will be used. + +PAPER_TYPE = a4 + +# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX +# packages that should be included in the LaTeX output. + +EXTRA_PACKAGES = + +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for +# the generated latex document. The header should contain everything until +# the first chapter. If it is left blank doxygen will generate a +# standard header. Notice: only use this tag if you know what you are doing! + +LATEX_HEADER = + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated +# is prepared for conversion to pdf (using ps2pdf). The pdf file will +# contain links (just like the HTML output) instead of page references +# This makes the output suitable for online browsing using a pdf viewer. + +PDF_HYPERLINKS = YES + +# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of +# plain latex in the generated Makefile. Set this option to YES to get a +# higher quality PDF documentation. + +USE_PDFLATEX = YES + +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. +# command to the generated LaTeX files. This will instruct LaTeX to keep +# running if errors occur, instead of asking the user for help. +# This option is also used when generating formulas in HTML. + +LATEX_BATCHMODE = NO + +# If LATEX_HIDE_INDICES is set to YES then doxygen will not +# include the index chapters (such as File Index, Compound Index, etc.) +# in the output. + +LATEX_HIDE_INDICES = NO + +# If LATEX_SOURCE_CODE is set to YES then doxygen will include +# source code with syntax highlighting in the LaTeX output. +# Note that which sources are shown also depends on other settings +# such as SOURCE_BROWSER. + +LATEX_SOURCE_CODE = NO + +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- + +# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output +# The RTF output is optimized for Word 97 and may not look very pretty with +# other RTF readers or editors. + +GENERATE_RTF = NO + +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `rtf' will be used as the default path. + +RTF_OUTPUT = rtf + +# If the COMPACT_RTF tag is set to YES Doxygen generates more compact +# RTF documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_RTF = NO + +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated +# will contain hyperlink fields. The RTF file will +# contain links (just like the HTML output) instead of page references. +# This makes the output suitable for online browsing using WORD or other +# programs which support those fields. +# Note: wordpad (write) and others do not support links. + +RTF_HYPERLINKS = NO + +# Load stylesheet definitions from file. Syntax is similar to doxygen's +# config file, i.e. a series of assignments. You only have to provide +# replacements, missing definitions are set to their default value. + +RTF_STYLESHEET_FILE = + +# Set optional variables used in the generation of an rtf document. +# Syntax is similar to doxygen's config file. + +RTF_EXTENSIONS_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- + +# If the GENERATE_MAN tag is set to YES (the default) Doxygen will +# generate man pages + +GENERATE_MAN = NO + +# The MAN_OUTPUT tag is used to specify where the man pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `man' will be used as the default path. + +MAN_OUTPUT = man + +# The MAN_EXTENSION tag determines the extension that is added to +# the generated man pages (default is the subroutine's section .3) + +MAN_EXTENSION = .3 + +# If the MAN_LINKS tag is set to YES and Doxygen generates man output, +# then it will generate one additional man file for each entity +# documented in the real man page(s). These additional files +# only source the real man page, but without them the man command +# would be unable to find the correct page. The default is NO. + +MAN_LINKS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- + +# If the GENERATE_XML tag is set to YES Doxygen will +# generate an XML file that captures the structure of +# the code including all documentation. + +GENERATE_XML = NO + +# The XML_OUTPUT tag is used to specify where the XML pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `xml' will be used as the default path. + +XML_OUTPUT = xml + +# The XML_SCHEMA tag can be used to specify an XML schema, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_SCHEMA = + +# The XML_DTD tag can be used to specify an XML DTD, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_DTD = + +# If the XML_PROGRAMLISTING tag is set to YES Doxygen will +# dump the program listings (including syntax highlighting +# and cross-referencing information) to the XML output. Note that +# enabling this will significantly increase the size of the XML output. + +XML_PROGRAMLISTING = YES + +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- + +# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will +# generate an AutoGen Definitions (see autogen.sf.net) file +# that captures the structure of the code including all +# documentation. Note that this feature is still experimental +# and incomplete at the moment. + +GENERATE_AUTOGEN_DEF = NO + +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- + +# If the GENERATE_PERLMOD tag is set to YES Doxygen will +# generate a Perl module file that captures the structure of +# the code including all documentation. Note that this +# feature is still experimental and incomplete at the +# moment. + +GENERATE_PERLMOD = NO + +# If the PERLMOD_LATEX tag is set to YES Doxygen will generate +# the necessary Makefile rules, Perl scripts and LaTeX code to be able +# to generate PDF and DVI output from the Perl module output. + +PERLMOD_LATEX = NO + +# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be +# nicely formatted so it can be parsed by a human reader. This is useful +# if you want to understand what is going on. On the other hand, if this +# tag is set to NO the size of the Perl module output will be much smaller +# and Perl will parse it just the same. + +PERLMOD_PRETTY = YES + +# The names of the make variables in the generated doxyrules.make file +# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. +# This is useful so different doxyrules.make files included by the same +# Makefile don't overwrite each other's variables. + +PERLMOD_MAKEVAR_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will +# evaluate all C-preprocessor directives found in the sources and include +# files. + +ENABLE_PREPROCESSING = YES + +# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro +# names in the source code. If set to NO (the default) only conditional +# compilation will be performed. Macro expansion can be done in a controlled +# way by setting EXPAND_ONLY_PREDEF to YES. + +MACRO_EXPANSION = NO + +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES +# then the macro expansion is limited to the macros specified with the +# PREDEFINED and EXPAND_AS_DEFINED tags. + +EXPAND_ONLY_PREDEF = NO + +# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files +# in the INCLUDE_PATH (see below) will be search if a #include is found. + +SEARCH_INCLUDES = YES + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by +# the preprocessor. + +INCLUDE_PATH = + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will +# be used. + +INCLUDE_FILE_PATTERNS = + +# The PREDEFINED tag can be used to specify one or more macro names that +# are defined before the preprocessor is started (similar to the -D option of +# gcc). The argument of the tag is a list of macros of the form: name +# or name=definition (no spaces). If the definition and the = are +# omitted =1 is assumed. To prevent a macro definition from being +# undefined via #undef or recursively expanded use the := operator +# instead of the = operator. + +PREDEFINED = + +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then +# this tag can be used to specify a list of macro names that should be expanded. +# The macro definition that is found in the sources will be used. +# Use the PREDEFINED tag if you want to use a different macro definition. + +EXPAND_AS_DEFINED = + +# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then +# doxygen's preprocessor will remove all function-like macros that are alone +# on a line, have an all uppercase name, and do not end with a semicolon. Such +# function macros are typically used for boiler-plate code, and will confuse +# the parser if not removed. + +SKIP_FUNCTION_MACROS = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- + +# The TAGFILES option can be used to specify one or more tagfiles. +# Optionally an initial location of the external documentation +# can be added for each tagfile. The format of a tag file without +# this location is as follows: +# TAGFILES = file1 file2 ... +# Adding location for the tag files is done as follows: +# TAGFILES = file1=loc1 "file2 = loc2" ... +# where "loc1" and "loc2" can be relative or absolute paths or +# URLs. If a location is present for each tag, the installdox tool +# does not have to be run to correct the links. +# Note that each tag file must have a unique name +# (where the name does NOT include the path) +# If a tag file is not located in the directory in which doxygen +# is run, you must also specify the path to the tagfile here. + +TAGFILES = + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create +# a tag file that is based on the input files it reads. + +GENERATE_TAGFILE = + +# If the ALLEXTERNALS tag is set to YES all external classes will be listed +# in the class index. If set to NO only the inherited external classes +# will be listed. + +ALLEXTERNALS = NO + +# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will +# be listed. + +EXTERNAL_GROUPS = YES + +# The PERL_PATH should be the absolute path and name of the perl script +# interpreter (i.e. the result of `which perl'). + +PERL_PATH = /usr/bin/perl + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will +# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base +# or super classes. Setting the tag to NO turns the diagrams off. Note that +# this option is superseded by the HAVE_DOT option below. This is only a +# fallback. It is recommended to install and use dot, since it yields more +# powerful graphs. + +CLASS_DIAGRAMS = NO + +# You can define message sequence charts within doxygen comments using the \msc +# command. Doxygen will then run the mscgen tool (see +# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the +# documentation. The MSCGEN_PATH tag allows you to specify the directory where +# the mscgen tool resides. If left empty the tool is assumed to be found in the +# default search path. + +MSCGEN_PATH = + +# If set to YES, the inheritance and collaboration graphs will hide +# inheritance and usage relations if the target is undocumented +# or is not a class. + +HIDE_UNDOC_RELATIONS = YES + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz, a graph visualization +# toolkit from AT&T and Lucent Bell Labs. The other options in this section +# have no effect if this option is set to NO (the default) + +HAVE_DOT = YES + +# By default doxygen will write a font called FreeSans.ttf to the output +# directory and reference it in all dot files that doxygen generates. This +# font does not include all possible unicode characters however, so when you need +# these (or just want a differently looking font) you can specify the font name +# using DOT_FONTNAME. You need need to make sure dot is able to find the font, +# which can be done by putting it in a standard location or by setting the +# DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory +# containing the font. + +DOT_FONTNAME = FreeSans + +# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. +# The default size is 10pt. + +DOT_FONTSIZE = 10 + +# By default doxygen will tell dot to use the output directory to look for the +# FreeSans.ttf font (which doxygen will put there itself). If you specify a +# different font using DOT_FONTNAME you can set the path where dot +# can find it using this tag. + +DOT_FONTPATH = + +# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect inheritance relations. Setting this tag to YES will force the +# the CLASS_DIAGRAMS tag to NO. + +CLASS_GRAPH = YES + +# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect implementation dependencies (inheritance, containment, and +# class references variables) of the class with other documented classes. + +COLLABORATION_GRAPH = YES + +# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for groups, showing the direct groups dependencies + +GROUP_GRAPHS = YES + +# If the UML_LOOK tag is set to YES doxygen will generate inheritance and +# collaboration diagrams in a style similar to the OMG's Unified Modeling +# Language. + +UML_LOOK = YES + +# If set to YES, the inheritance and collaboration graphs will show the +# relations between templates and their instances. + +TEMPLATE_RELATIONS = NO + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT +# tags are set to YES then doxygen will generate a graph for each documented +# file showing the direct and indirect include dependencies of the file with +# other documented files. + +INCLUDE_GRAPH = YES + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and +# HAVE_DOT tags are set to YES then doxygen will generate a graph for each +# documented header file showing the documented files that directly or +# indirectly include this file. + +INCLUDED_BY_GRAPH = YES + +# If the CALL_GRAPH and HAVE_DOT options are set to YES then +# doxygen will generate a call dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable call graphs +# for selected functions only using the \callgraph command. + +CALL_GRAPH = YES + +# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then +# doxygen will generate a caller dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable caller +# graphs for selected functions only using the \callergraph command. + +CALLER_GRAPH = YES + +# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen +# will graphical hierarchy of all classes instead of a textual one. + +GRAPHICAL_HIERARCHY = YES + +# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES +# then doxygen will show the dependencies a directory has on other directories +# in a graphical way. The dependency relations are determined by the #include +# relations between the files in the directories. + +DIRECTORY_GRAPH = YES + +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# generated by dot. Possible values are png, jpg, or gif +# If left blank png will be used. + +DOT_IMAGE_FORMAT = png + +# The tag DOT_PATH can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found in the path. + +DOT_PATH = + +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the +# \dotfile command). + +DOTFILE_DIRS = + +# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of +# nodes that will be shown in the graph. If the number of nodes in a graph +# becomes larger than this value, doxygen will truncate the graph, which is +# visualized by representing a node as a red box. Note that doxygen if the +# number of direct children of the root node in a graph is already larger than +# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note +# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. + +DOT_GRAPH_MAX_NODES = 50 + +# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the +# graphs generated by dot. A depth value of 3 means that only nodes reachable +# from the root by following a path via at most 3 edges will be shown. Nodes +# that lay further from the root node will be omitted. Note that setting this +# option to 1 or 2 may greatly reduce the computation time needed for large +# code bases. Also note that the size of a graph can be further restricted by +# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. + +MAX_DOT_GRAPH_DEPTH = 0 + +# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent +# background. This is disabled by default, because dot on Windows does not +# seem to support this out of the box. Warning: Depending on the platform used, +# enabling this option may lead to badly anti-aliased labels on the edges of +# a graph (i.e. they become hard to read). + +DOT_TRANSPARENT = YES + +# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output +# files in one run (i.e. multiple -o and -T options on the command line). This +# makes dot run faster, but since only newer versions of dot (>1.8.10) +# support this, this feature is disabled by default. + +DOT_MULTI_TARGETS = YES + +# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will +# generate a legend page explaining the meaning of the various boxes and +# arrows in the dot generated graphs. + +GENERATE_LEGEND = YES + +# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will +# remove the intermediate dot files that are used to generate +# the various graphs. + +DOT_CLEANUP = YES + +#--------------------------------------------------------------------------- +# Options related to the search engine +#--------------------------------------------------------------------------- + +# The SEARCHENGINE tag specifies whether or not a search engine should be +# used. If set to NO the values of all tags below this one will be ignored. + +SEARCHENGINE = NO diff --git a/README b/README new file mode 100644 index 0000000..07dd198 --- /dev/null +++ b/README @@ -0,0 +1,15 @@ +/* $Id$ */ + +There are two ways to install webcal. Outside web scope and inside web +scope. + +Inside web scope: +Untar the package in a web enabled directory and point your browser to +this directory. To install webcal simply follow the automatically +started wizard. + +Outside web scope: +Untar the package to any directory outside web scope and go to the +directory install and run the script setup as root or by using sudo. +Answer the question and follow the directions given. The script requires +Perl. diff --git a/caldav/awl/AWLUtilities.php b/caldav/awl/AWLUtilities.php new file mode 100644 index 0000000..5b11df1 --- /dev/null +++ b/caldav/awl/AWLUtilities.php @@ -0,0 +1,403 @@ + +* @copyright Catalyst IT Ltd +* @license http://gnu.org/copyleft/gpl.html GNU GPL v2 +*/ + +if ( !function_exists('dbg_error_log') ) { + /** + * Writes a debug message into the error log using printf syntax. If the first + * parameter is "ERROR" then the message will _always_ be logged. + * Otherwise, the first parameter is a "component" name, and will only be logged + * if $c->dbg["component"] is set to some non-null value. + * + * If you want to see every log message then $c->dbg["ALL"] can be set, to + * override the debugging status of the individual components. + * + * @var string $component The component to identify itself, or "ERROR", or "LOG:component" + * @var string $format A format string for the log message + * @var [string $parameter ...] Parameters for the format string. + */ + function dbg_error_log() { + global $c; + $argc = func_num_args(); + $args = func_get_args(); + $type = "DBG"; + $component = array_shift($args); + if ( substr( $component, 0, 3) == "LOG" ) { + // Special escape case for stuff that always gets logged. + $type = 'LOG'; + $component = substr($component,4); + } + else if ( $component == "ERROR" ) { + $type = "***"; + } + else if ( isset($c->dbg["ALL"]) ) { + $type = "ALL"; + } + else if ( !isset($c->dbg[strtolower($component)]) ) return; + + if ( 2 <= $argc ) { + $format = array_shift($args); + } + else { + $format = "%s"; + } + @error_log( $c->sysabbr.": $type: $component:". vsprintf( $format, $args ) ); + } +} + + + +if ( !function_exists('apache_request_headers') ) { + /** + * Forward compatibility so we can use the non-deprecated name in PHP4 + * @package awl + */ + function apache_request_headers() { + return getallheaders(); + } +} + + + +if ( !function_exists('dbg_log_array') ) { + /** + * Function to dump an array to the error log, possibly recursively + * + * @var string $component Which component should this log message identify itself from + * @var string $name What name should this array dump identify itself as + * @var array $arr The array to be dumped. + * @var boolean $recursive Should the dump recurse into arrays/objects in the array + */ + function dbg_log_array( $component, $name, $arr, $recursive = false ) { + if ( !isset($arr) || (gettype($arr) != 'array' && gettype($arr) != 'object') ) { + dbg_error_log( $component, "%s: array is not set, or is not an array!", $name); + return; + } + foreach ($arr as $key => $value) { + dbg_error_log( $component, "%s: >>%s<< = >>%s<<", $name, $key, + (gettype($value) == 'array' || gettype($value) == 'object' ? gettype($value) : $value) ); + if ( $recursive && (gettype($value) == 'array' || (gettype($value) == 'object' && "$key" != 'self' && "$key" != 'parent') ) ) { + dbg_log_array( $component, "$name"."[$key]", $value, $recursive ); + } + } + } +} + + + +if ( !function_exists("session_salted_md5") ) { + /** + * Make a salted MD5 string, given a string and (possibly) a salt. + * + * If no salt is supplied we will generate a random one. + * + * @param string $instr The string to be salted and MD5'd + * @param string $salt Some salt to sprinkle into the string to be MD5'd so we don't get the same PW always hashing to the same value. + * @return string The salt, a * and the MD5 of the salted string, as in SALT*SALTEDHASH + */ + function session_salted_md5( $instr, $salt = "" ) { + if ( $salt == "" ) $salt = substr( md5(rand(100000,999999)), 2, 8); + dbg_error_log( "Login", "Making salted MD5: salt=$salt, instr=$instr, md5($salt$instr)=".md5($salt . $instr) ); + return ( sprintf("*%s*%s", $salt, md5($salt . $instr) ) ); + } +} + + + +if ( !function_exists("session_salted_sha1") && version_compare(phpversion(), "4.9.9") > 0 ) { + /** + * Make a salted SHA1 string, given a string and (possibly) a salt. PHP5 only (although it + * could be made to work on PHP4 (@see http://www.openldap.org/faq/data/cache/347.html). The + * algorithm used here is compatible with OpenLDAP so passwords generated through this function + * should be able to be migrated to OpenLDAP by using the part following the second '*', i.e. + * the '{SSHA}....' part. + * + * If no salt is supplied we will generate a random one. + * + * @param string $instr The string to be salted and SHA1'd + * @param string $salt Some salt to sprinkle into the string to be SHA1'd so we don't get the same PW always hashing to the same value. + * @return string A *, the salt, a * and the SHA1 of the salted string, as in *SALT*SALTEDHASH + */ + function session_salted_sha1( $instr, $salt = "" ) { + if ( $salt == "" ) $salt = substr( str_replace('*','',base64_encode(sha1(rand(100000,9999999),true))), 2, 9); + dbg_error_log( "Login", "Making salted SHA1: salt=$salt, instr=$instr, encoded($instr$salt)=".base64_encode(sha1($instr . $salt, true).$salt) ); + return ( sprintf("*%s*{SSHA}%s", $salt, base64_encode(sha1($instr.$salt, true) . $salt ) ) ); + } +} + + +if ( !function_exists("session_validate_password") ) { + /** + * Checks what a user entered against the actual password on their account. + * @param string $they_sent What the user entered. + * @param string $we_have What we have in the database as their password. Which may (or may not) be a salted MD5. + * @return boolean Whether or not the users attempt matches what is already on file. + */ + function session_validate_password( $they_sent, $we_have ) { + if ( preg_match('/^\*\*.+$/', $we_have ) ) { + // The "forced" style of "**plaintext" to allow easier admin setting + return ( "**$they_sent" == $we_have ); + } + + if ( preg_match('/^\*(.+)\*{[A-Z]+}.+$/', $we_have, $regs ) ) { + if ( function_exists("session_salted_sha1") ) { + // A nicely salted sha1sum like "**{SSHA}" + $salt = $regs[1]; + $sha1_sent = session_salted_sha1( $they_sent, $salt ) ; + return ( $sha1_sent == $we_have ); + } + else { + dbg_error_log( "ERROR", "Password is salted SHA-1 but you are using PHP4!" ); + echo << + +Salted SHA1 Password format not supported with PHP4 + + +

Salted SHA1 Password format not supported with PHP4

+

At some point you have used PHP5 to set the password for this user and now you are + using PHP4. You will need to assign a new password to this user using PHP4, or ensure + you use PHP5 everywhere (recommended).

+

AWL has now switched to using salted SHA-1 passwords by preference in a format + compatible with OpenLDAP.

+ + +EOERRMSG; + exit; + } + } + + if ( preg_match('/^\*(.+)\*.+$/', $we_have, $regs ) ) { + // A nicely salted md5sum like "**" + $salt = $regs[1]; + $md5_sent = session_salted_md5( $they_sent, $salt ) ; + return ( $md5_sent == $we_have ); + } + + // Anything else is bad + return false; + + } +} + + + +if ( !function_exists("replace_uri_params") ) { + /** + * Given a URL (presumably the current one) and a parameter, replace the value of parameter, + * extending the URL as necessary if the parameter is not already there. + * @param string $uri The URI we will be replacing parameters in. + * @param array $replacements An array of replacement pairs array( "replace_this" => "with this" ) + * @return string The URI with the replacements done. + */ + function replace_uri_params( $uri, $replacements ) { + $replaced = $uri; + foreach( $replacements AS $param => $new_value ) { + $rxp = preg_replace( '/([\[\]])/', '\\\\$1', $param ); // Some parameters may be arrays. + $regex = "/([&?])($rxp)=([^&]+)/"; + dbg_error_log("core", "Looking for [%s] to replace with [%s] regex is %s and searching [%s]", $param, $new_value, $regex, $replaced ); + if ( preg_match( $regex, $replaced ) ) + $replaced = preg_replace( $regex, "\$1$param=$new_value", $replaced); + else + $replaced .= "&$param=$new_value"; + } + if ( ! preg_match( '/\?/', $replaced ) ) { + $replaced = preg_replace("/&(.+)$/", "?\$1", $replaced); + } + $replaced = str_replace("&", "--AmPeRsAnD--", $replaced); + $replaced = str_replace("&", "&", $replaced); + $replaced = str_replace("--AmPeRsAnD--", "&", $replaced); + dbg_error_log("core", "URI <<$uri>> morphed to <<$replaced>>"); + return $replaced; + } +} + + +if ( !function_exists("uuid") ) { +/** + * Generates a Universally Unique IDentifier, version 4. + * + * RFC 4122 (http://www.ietf.org/rfc/rfc4122.txt) defines a special type of Globally + * Unique IDentifiers (GUID), as well as several methods for producing them. One + * such method, described in section 4.4, is based on truly random or pseudo-random + * number generators, and is therefore implementable in a language like PHP. + * + * We choose to produce pseudo-random numbers with the Mersenne Twister, and to always + * limit single generated numbers to 16 bits (ie. the decimal value 65535). That is + * because, even on 32-bit systems, PHP's RAND_MAX will often be the maximum *signed* + * value, with only the equivalent of 31 significant bits. Producing two 16-bit random + * numbers to make up a 32-bit one is less efficient, but guarantees that all 32 bits + * are random. + * + * The algorithm for version 4 UUIDs (ie. those based on random number generators) + * states that all 128 bits separated into the various fields (32 bits, 16 bits, 16 bits, + * 8 bits and 8 bits, 48 bits) should be random, except : (a) the version number should + * be the last 4 bits in the 3rd field, and (b) bits 6 and 7 of the 4th field should + * be 01. We try to conform to that definition as efficiently as possible, generating + * smaller values where possible, and minimizing the number of base conversions. + * + * @copyright Copyright (c) CFD Labs, 2006. This function may be used freely for + * any purpose ; it is distributed without any form of warranty whatsoever. + * @author David Holmes + * + * @return string A UUID, made up of 32 hex digits and 4 hyphens. + */ + + function uuid() { + + // The field names refer to RFC 4122 section 4.1.2 + + return sprintf('%04x%04x-%04x-%03x4-%04x-%04x%04x%04x', + mt_rand(0, 65535), mt_rand(0, 65535), // 32 bits for "time_low" + mt_rand(0, 65535), // 16 bits for "time_mid" + mt_rand(0, 4095), // 12 bits before the 0100 of (version) 4 for "time_hi_and_version" + bindec(substr_replace(sprintf('%016b', mt_rand(0, 65535)), '01', 6, 2)), + // 8 bits, the last two of which (positions 6 and 7) are 01, for "clk_seq_hi_res" + // (hence, the 2nd hex digit after the 3rd hyphen can only be 1, 5, 9 or d) + // 8 bits for "clk_seq_low" + mt_rand(0, 65535), mt_rand(0, 65535), mt_rand(0, 65535) // 48 bits for "node" + ); + } +} + +if ( !function_exists("translate") ) { + require_once("Translation.php"); +} + + if ( !function_exists("clone") && version_compare(phpversion(), '5.0') < 0) { + /** + * PHP5 screws with the assignment operator changing so that $a = $b means that + * $a becomes a reference to $b. There is a clone() that we can use in PHP5, so + * we have to emulate that for PHP4. Bleargh. + */ + eval( 'function clone($object) { return $object; }' ); +} + +if ( !function_exists("quoted_printable_encode") ) { + /** + * Process a string to fit the requirements of RFC2045 section 6.7. Note that + * this works, but replaces more characters than the minimum set. For readability + * the spaces aren't encoded as =20 though. + */ + function quoted_printable_encode($string) { + return preg_replace('/[^\r\n]{73}[^=\r\n]{2}/', "$0=\r\n", str_replace("%","=",str_replace("%20"," ",rawurlencode($string)))); + } +} + + +if ( !function_exists("clean_by_regex") ) { + /** + * Clean a value by applying a regex to it. If it is an array apply it to + * each element in the array recursively. If it is an object we don't mess + * with it. + */ + function clean_by_regex( $val, $regex ) { + if ( is_null($val) ) return null; + switch( $regex ) { + case 'int': $regex = '#^\d+$#'; break; + } + if ( is_array($val) ) { + foreach( $val AS $k => $v ) { + $val[$k] = clean_by_regex($v,$regex); + } + } + else if ( ! is_object($val) ) { + if ( preg_match( $regex, $val, $matches) ) { + $val = $matches[0]; + } + else { + $val = ''; + } + } + return $val; + } +} + + +if ( !function_exists("param_to_global") ) { + /** + * Convert a parameter to a global. We first look in _POST and then in _GET, + * and if they passed in a bunch of valid characters, we will make sure the + * incoming is cleaned to only match that set. + * + * @param string $varname The name of the global variable to put the answer in + * @param string $match_regex The part of the parameter matching this regex will be returned + * @param string $alias1 An alias for the name that we should look for first. + * @param " ... More aliases, in the order which they should be examined. $varname will be appended to the end. + */ + function param_to_global( ) { + $args = func_get_args(); + + $varname = array_shift($args); + $GLOBALS[$varname] = null; + + $match_regex = null; + $argc = func_num_args(); + if ( $argc > 1 ) { + $match_regex = array_shift($args); + } + + $args[] = $varname; + foreach( $args AS $k => $name ) { + if ( isset($_POST[$name]) ) { + $result = $_POST[$name]; + break; + } + else if ( isset($_GET[$name]) ) { + $result = $_GET[$name]; + break; + } + } + if ( !isset($result) ) return null; + + if ( isset($match_regex) ) { + $result = clean_by_regex( $result, $match_regex ); + } + + $GLOBALS[$varname] = $result; + return $result; + } +} + + +if ( !function_exists("get_fields") ) { + /** + * @var array $_AWL_field_cache is a cache of the field names for a table + */ + $_AWL_field_cache = array(); + + + /** + * Get the names of the fields for a particular table + * @param string $tablename The name of the table. + * @return array of string The public fields in the table. + */ + function get_fields( $tablename ) { + global $_AWL_field_cache; + + if ( !isset($_AWL_field_cache[$tablename]) ) { + dbg_error_log( "DataUpdate", ":get_fields: Loaded fields for table '$tablename'" ); + $sql = "SELECT f.attname, t.typname FROM pg_attribute f "; + $sql .= "JOIN pg_class c ON ( f.attrelid = c.oid ) "; + $sql .= "JOIN pg_type t ON ( f.atttypid = t.oid ) "; + $sql .= "WHERE relname = ? AND attnum >= 0 order by f.attnum;"; + $qry = new PgQuery( $sql, $tablename ); + $qry->Exec("DataUpdate"); + $fields = array(); + while( $row = $qry->Fetch() ) { + $fields["$row->attname"] = $row->typname; + } + $_AWL_field_cache[$tablename] = $fields; + } + return $_AWL_field_cache[$tablename]; + } +} + diff --git a/caldav/awl/Translation.php b/caldav/awl/Translation.php new file mode 100644 index 0000000..913f3aa --- /dev/null +++ b/caldav/awl/Translation.php @@ -0,0 +1,105 @@ + +* @copyright Catalyst IT Ltd +* @license http://gnu.org/copyleft/gpl.html GNU GPL v2 +*/ +if ( !function_exists("i18n") ) { + /** + * Mark a string as being internationalized. This is a semaphore method; it + * does nothing but it allows us to easily identify strings that require + * translation. Generally this is used to mark strings that will be stored + * in the database (like descriptions of permissions). + * + * AWL uses GNU gettext for internationalization (i18n) and localization (l10n) of + * text presented to the user. Gettext needs to know about all places involving strings, + * that must be translated. Mark any place, where localization at runtime shall take place + * by using the function translate(). + * + * In the help I have used 'xlate' rather than 'translate' and 'x18n' rather than 'i18n' + * so that the tools skip this particular file for translation :-) + * + * E.g. instead of: + * print 'TEST to be displayed in different languages'; + * use: + * print xlate('TEST to be displayed in different languages'); + * and you are all set for pure literals. The translation teams will receive that literal + * string as a job to translate and will translate it (when the message is clear enough). + * At runtime the message is then localized when printed. + * The input string can contain a hint to assist translators: + * print xlate('TT '); + * The hint portion of the string will not be printed. + * + * But consider this case: + * $message_to_be_localized = 'TEST to be displayed in different languages'; + * print xlate($message_to_be_localized); + * + * The translate() function is called in the right place for runtime handling, but there + * is no message at gettext preprocessing time to be given to the translation teams, + * just a variable name. Translation of the variable name would break the code! So all + * places potentially feeding this variable have to be marked to be given to translation + * teams, but not translated at runtime! + * + * This method resolves all such cases. Simply mark the candidates: + * $message_to_be_localized = x18n('TEST to be displayed in different languages'); + * print xlate($message_to_be_localized); + * + * @param string the value + * @return string the same value + */ + function i18n($value) { + return $value; /* Just pass the value through */ + } +} + + +if ( !function_exists("translate") ) { + /** + * Convert a string in English to whatever this user's locale is + */ + function translate( $en ) { + $xl = gettext($en); + dbg_error_log("I18N","Translated =%s= into =%s=", $en, $xl ); + return $xl; + } +} + + +if ( !function_exists("init_gettext") ) { + /** + * Initialise our use of Gettext + */ + function init_gettext( $domain, $location ) { + bindtextdomain( $domain, $location ); + $codeset = bind_textdomain_codeset( $domain, "UTF-8" ); + textdomain( $domain ); + dbg_error_log("I18N","Bound domain =%s= to location =%s= using character set =%s=", $domain, $location, $codeset ); + } +} + + +if ( !function_exists("awl_set_locale") ) { + /** + * Set the translation to the user's locale. At this stage all we do is + * call the gettext function. + */ + function awl_set_locale( $locale ) { + global $c; + + if ( !is_array($locale) && ! preg_match('/^[a-z]{2}(_[A-Z]{2})?\./', $locale ) ) { + $locale = array( $locale, $locale.".UTF-8"); + } + if ( $newlocale = setlocale( LC_ALL, $locale) ) { + dbg_error_log("I18N","Set locale to =%s=", $newlocale ); + $c->current_locale = $newlocale; + } + else { + dbg_log_array("I18N","Unsupported locale: ", $locale, false ); + } + } +} + +?> \ No newline at end of file diff --git a/caldav/awl/XMLElement.php b/caldav/awl/XMLElement.php new file mode 100644 index 0000000..ffd4fce --- /dev/null +++ b/caldav/awl/XMLElement.php @@ -0,0 +1,333 @@ + +* @copyright Catalyst .Net Ltd, Morphoss Ltd +* @license http://gnu.org/copyleft/gpl.html GNU GPL v2 +*/ +require_once("AWLUtilities.php"); + +/** +* A class for XML elements which may have attributes, or contain +* other XML sub-elements +* +* @package awl +*/ +class XMLElement { + var $tagname; + var $xmlns; + var $attributes; + var $content; + var $_parent; + + /** + * Constructor - nothing fancy as yet. + * + * @param string $tagname The tag name of the new element + * @param mixed $content Either a string of content, or an array of sub-elements + * @param array $attributes An array of attribute name/value pairs + * @param array $xmlns An XML namespace specifier + */ + function XMLElement( $tagname, $content=false, $attributes=false, $xmlns=null ) { + $this->tagname=$tagname; + if ( gettype($content) == "object" ) { + // Subtree to be parented here + $this->content = array(&$content); + } + else { + // Array or text + $this->content = $content; + } + $this->attributes = $attributes; + if ( isset($this->attributes['xmlns']) ) { // Oversimplification to be removed + $this->xmlns = $this->attributes['xmlns']; + } + if ( isset($xmlns) ) { + $this->xmlns = $xmlns; + } + } + + + /** + * Count the number of elements + * @return int The number of elements + */ + function CountElements( ) { + if ( $this->content === false ) return 0; + if ( is_array($this->content) ) return count($this->content); + if ( $this->content == '' ) return 0; + return 1; + } + + /** + * Set an element attribute to a value + * + * @param string The attribute name + * @param string The attribute value + */ + function SetAttribute($k,$v) { + if ( gettype($this->attributes) != "array" ) $this->attributes = array(); + $this->attributes[$k] = $v; + if ( strtolower($k) == 'xmlns' ) { + $this->xmlns = $v; + } + } + + /** + * Set the whole content to a value + * + * @param mixed The element content, which may be text, or an array of sub-elements + */ + function SetContent($v) { + $this->content = $v; + } + + /** + * Accessor for the tag name + * + * @return string The tag name of the element + */ + function GetTag() { + return $this->tagname; + } + + /** + * Accessor for the full-namespaced tag name + * + * @return string The tag name of the element, prefixed by the namespace + */ + function GetNSTag() { + return $this->xmlns . ':' . $this->tagname; + } + + /** + * Accessor for a single attribute + * @param string $attr The name of the attribute. + * @return string The value of that attribute of the element + */ + function GetAttribute( $attr ) { + if ( isset($this->attributes[$attr]) ) return $this->attributes[$attr]; + } + + /** + * Accessor for the attributes + * + * @return array The attributes of this element + */ + function GetAttributes() { + return $this->attributes; + } + + /** + * Accessor for the content + * + * @return array The content of this element + */ + function GetContent() { + return $this->content; + } + + /** + * Return an array of elements matching the specified tag + * + * @return array The XMLElements within the tree which match this tag + */ + function GetElements( $tag, $recursive=false ) { + $elements = array(); + if ( gettype($this->content) == "array" ) { + foreach( $this->content AS $k => $v ) { + if ( $v->tagname == $tag ) { + $elements[] = $v; + } + if ( $recursive ) { + $elements = $elements + $v->GetElements($tag,true); + } + } + } + return $elements; + } + + + /** + * Return an array of elements matching the specified path + * + * @return array The XMLElements within the tree which match this tag + */ + function GetPath( $path ) { + $elements = array(); + // printf( "Querying within '%s' for path '%s'\n", $this->tagname, $path ); + if ( !preg_match( '#(/)?([^/]+)(/?.*)$#', $path, $matches ) ) return $elements; + // printf( "Matches: %s -- %s -- %s\n", $matches[1], $matches[2], $matches[3] ); + if ( $matches[2] == '*' || strtolower($matches[2]) == strtolower($this->tagname) ) { + if ( $matches[3] == '' ) { + /** + * That is the full path + */ + $elements[] = $this; + } + else if ( gettype($this->content) == "array" ) { + /** + * There is more to the path, so we recurse into that sub-part + */ + foreach( $this->content AS $k => $v ) { + $elements = array_merge( $elements, $v->GetPath($matches[3]) ); + } + } + } + + if ( $matches[1] != '/' && gettype($this->content) == "array" ) { + /** + * If our input $path was not rooted, we recurse further + */ + foreach( $this->content AS $k => $v ) { + $elements = array_merge( $elements, $v->GetPath($path) ); + } + } + // printf( "Found %d within '%s' for path '%s'\n", count($elements), $this->tagname, $path ); + return $elements; + } + + + /** + * Add a sub-element + * + * @param object An XMLElement to be appended to the array of sub-elements + */ + function AddSubTag(&$v) { + if ( gettype($this->content) != "array" ) $this->content = array(); + $this->content[] =& $v; + return count($this->content); + } + + /** + * Add a new sub-element + * + * @param string The tag name of the new element + * @param mixed Either a string of content, or an array of sub-elements + * @param array An array of attribute name/value pairs + * + * @return objectref A reference to the new XMLElement + */ + function &NewElement( $tagname, $content=false, $attributes=false, $xmlns=null ) { + if ( gettype($this->content) != "array" ) $this->content = array(); + $element =/*&*/ new XMLElement($tagname,$content,$attributes,$xmlns); + $this->content[] =/*&*/ $element; + return $element; + } + + + /** + * Render just the internal content + * + * @return string The content of this element, as a string without this element wrapping it. + */ + function RenderContent($indent=0, $nslist=null ) { + $r = ""; + if ( is_array($this->content) ) { + /** + * Render the sub-elements with a deeper indent level + */ + $r .= "\n"; + foreach( $this->content AS $k => $v ) { + if ( is_object($v) ) { + $r .= $v->Render($indent+1, "", $nslist); + } + } + $r .= substr(" ",0,$indent); + } + else { + /** + * Render the content, with special characters escaped + * + */ + $r .= htmlspecialchars($this->content, ENT_NOQUOTES ); + } + return $r; + } + + + /** + * Render the document tree into (nicely formatted) XML + * + * @param int The indenting level for the pretty formatting of the element + */ + function Render($indent=0, $xmldef="", $nslist=null) { + $r = ( $xmldef == "" ? "" : $xmldef."\n"); + + $attr = ""; + $tagname = $this->tagname; + if ( gettype($this->attributes) == "array" ) { + /** + * Render the element attribute values + */ + foreach( $this->attributes AS $k => $v ) { + if ( preg_match('#^xmlns(:?(.+))?$#', $k, $matches ) ) { + if ( !isset($nslist) ) $nslist = array(); + $prefix = (isset($matches[2]) ? $matches[2] : ''); + if ( isset($nslist[$v]) && $nslist[$v] == $prefix ) continue; // No need to include in list as it's in a wrapping element + $nslist[$v] = $prefix; + if ( !isset($this->xmlns) ) $this->xmlns = $v; + } + $attr .= sprintf( ' %s="%s"', $k, htmlspecialchars($v) ); + } + } + if ( isset($this->xmlns) && isset($nslist[$this->xmlns]) && $nslist[$this->xmlns] != '' ) { + $tagname = $nslist[$this->xmlns] . ':' . $tagname; + } + + $r .= substr(" ",0,$indent) . '<' . $tagname . $attr; + + if ( (is_array($this->content) && count($this->content) > 0) || (!is_array($this->content) && strlen($this->content) > 0) ) { + $r .= ">"; + $r .= $this->RenderContent($indent,$nslist); + $r .= '\n"; + } + else { + $r .= "/>\n"; + } + return $r; + } +} + + +/** +* Rebuild an XML tree in our own style from the parsed XML tags using +* a tail-recursive approach. +* +* @param array $xmltags An array of XML tags we get from using the PHP XML parser +* @param intref &$start_from A pointer to our current integer offset into $xmltags +* @return mixed Either a single XMLElement, or an array of XMLElement objects. +*/ +function BuildXMLTree( $xmltags, &$start_from ) { + $content = array(); + + if ( !isset($start_from) ) $start_from = 0; + + for( $i=0; $i < 50000 && isset($xmltags[$start_from]); $i++) { + $tagdata = $xmltags[$start_from++]; + if ( !isset($tagdata) || !isset($tagdata['tag']) || !isset($tagdata['type']) ) break; + if ( $tagdata['type'] == "close" ) break; + $attributes = ( isset($tagdata['attributes']) ? $tagdata['attributes'] : false ); + if ( $tagdata['type'] == "open" ) { + $subtree = BuildXMLTree( $xmltags, $start_from ); + $content[] = new XMLElement($tagdata['tag'], $subtree, $attributes ); + } + else if ( $tagdata['type'] == "complete" ) { + $value = ( isset($tagdata['value']) ? $tagdata['value'] : false ); + $content[] = new XMLElement($tagdata['tag'], $value, $attributes ); + } + } + + /** + * If there is only one element, return it directly, otherwise return the + * array of them + */ + if ( count($content) == 1 ) { + return $content[0]; + } + return $content; +} + diff --git a/caldav/awl/iCalendar.php b/caldav/awl/iCalendar.php new file mode 100644 index 0000000..055d120 --- /dev/null +++ b/caldav/awl/iCalendar.php @@ -0,0 +1,1633 @@ +component will point to the wrapping VCALENDAR component of +* the iCalendar. This will be fine for simple iCalendar usage as sampled below, +* but more complex iCalendar such as a VEVENT with RRULE which has repeat overrides +* will need quite a bit more thought to process correctly. +* +* @example +* To create a new iCalendar from several data values: +* $ical = new iCalendar( array('DTSTART' => $dtstart, 'SUMMARY' => $summary, 'DURATION' => $duration ) ); +* +* @example +* To render it as an iCalendar string: +* echo $ical->Render(); +* +* @example +* To render just the VEVENTs in the iCalendar with a restricted list of properties: +* echo $ical->Render( false, 'VEVENT', array( 'DTSTART', 'DURATION', 'DTEND', 'RRULE', 'SUMMARY') ); +* +* @example +* To parse an existing iCalendar string for manipulation: +* $ical = new iCalendar( array('icalendar' => $icalendar_text ) ); +* +* @example +* To clear any 'VALARM' components in an iCalendar object +* $ical->component->ClearComponents('VALARM'); +* +* @example +* To replace any 'RRULE' property in an iCalendar object +* $ical->component->SetProperties( 'RRULE', $rrule_definition ); +* +* @package awl +* @subpackage iCalendar +* @author Andrew McMillan +* @copyright Catalyst IT Ltd, Morphoss Ltd +* @license http://gnu.org/copyleft/gpl.html GNU GPL v2 or later +* +*/ +require_once("XMLElement.php"); + +/** +* A Class for representing properties within an iCalendar +* +* @package awl +*/ +class iCalProp { + /**#@+ + * @access private + */ + + /** + * The name of this property + * + * @var string + */ + var $name; + + /** + * An array of parameters to this property, represented as key/value pairs. + * + * @var array + */ + var $parameters; + + /** + * The value of this property. + * + * @var string + */ + var $content; + + /** + * The original value that this was parsed from, if that's the way it happened. + * + * @var string + */ + var $rendered; + + /**#@-*/ + + /** + * The constructor parses the incoming string, which is formatted as per RFC2445 as a + * propname[;param1=pval1[; ... ]]:propvalue + * however we allow ourselves to assume that the RFC2445 content unescaping has already + * happened when iCalComponent::ParseFrom() called iCalComponent::UnwrapComponent(). + * + * @param string $propstring The string from the iCalendar which contains this property. + */ + function iCalProp( $propstring = null ) { + $this->name = ""; + $this->content = ""; + $this->parameters = array(); + unset($this->rendered); + if ( $propstring != null && gettype($propstring) == 'string' ) { + $this->ParseFrom($propstring); + } + } + + + /** + * The constructor parses the incoming string, which is formatted as per RFC2445 as a + * propname[;param1=pval1[; ... ]]:propvalue + * however we allow ourselves to assume that the RFC2445 content unescaping has already + * happened when iCalComponent::ParseFrom() called iCalComponent::UnwrapComponent(). + * + * @param string $propstring The string from the iCalendar which contains this property. + */ + function ParseFrom( $propstring ) { + $this->rendered = (strlen($propstring) < 72 ? $propstring : null); // Only pre-rendered if we didn't unescape it + $pos = strpos( $propstring, ':'); + $start = substr( $propstring, 0, $pos); + + $unescaped = str_replace( '\\n', "\n", substr( $propstring, $pos + 1)); + $unescaped = str_replace( '\\N', "\n", $unescaped); + $this->content = preg_replace( "/\\\\([,;:\"\\\\])/", '$1', $unescaped); + + $parameters = explode(';',$start); + $this->name = array_shift( $parameters ); + $this->parameters = array(); + foreach( $parameters AS $k => $v ) { + $pos = strpos($v,'='); + $name = substr( $v, 0, $pos); + $value = substr( $v, $pos + 1); + $this->parameters[$name] = $value; + } + dbg_error_log("iCalendar", " iCalProp::ParseFrom found '%s' = '%s' with %d parameters", $this->name, $this->content, count($this->parameters) ); + } + + + /** + * Get/Set name property + * + * @param string $newname [optional] A new name for the property + * + * @return string The name for the property. + */ + function Name( $newname = null ) { + if ( $newname != null ) { + $this->name = $newname; + if ( isset($this->rendered) ) unset($this->rendered); + dbg_error_log("iCalendar", " iCalProp::Name(%s)", $this->name ); + } + return $this->name; + } + + + /** + * Get/Set the content of the property + * + * @param string $newvalue [optional] A new value for the property + * + * @return string The value of the property. + */ + function Value( $newvalue = null ) { + if ( $newvalue != null ) { + $this->content = $newvalue; + if ( isset($this->rendered) ) unset($this->rendered); + } + return $this->content; + } + + + /** + * Get/Set parameters in their entirety + * + * @param array $newparams An array of new parameter key/value pairs + * + * @return array The current array of parameters for the property. + */ + function Parameters( $newparams = null ) { + if ( $newparams != null ) { + $this->parameters = $newparams; + if ( isset($this->rendered) ) unset($this->rendered); + } + return $this->parameters; + } + + + /** + * Test if our value contains a string + * + * @param string $search The needle which we shall search the haystack for. + * + * @return string The name for the property. + */ + function TextMatch( $search ) { + if ( isset($this->content) ) return strstr( $this->content, $search ); + return false; + } + + + /** + * Get the value of a parameter + * + * @param string $name The name of the parameter to retrieve the value for + * + * @return string The value of the parameter + */ + function GetParameterValue( $name ) { + if ( isset($this->parameters[$name]) ) return $this->parameters[$name]; + } + + /** + * Set the value of a parameter + * + * @param string $name The name of the parameter to set the value for + * + * @param string $value The value of the parameter + */ + function SetParameterValue( $name, $value ) { + if ( isset($this->rendered) ) unset($this->rendered); + $this->parameters[$name] = $value; + } + + /** + * Render the set of parameters as key1=value1[;key2=value2[; ...]] with + * any colons or semicolons escaped. + */ + function RenderParameters() { + $rendered = ""; + foreach( $this->parameters AS $k => $v ) { + $escaped = preg_replace( "/([;:\"])/", '\\\\$1', $v); + $rendered .= sprintf( ";%s=%s", $k, $escaped ); + } + return $rendered; + } + + + /** + * Render a suitably escaped RFC2445 content string. + */ + function Render() { + // If we still have the string it was parsed in from, it hasn't been screwed with + // and we can just return that without modification. + if ( isset($this->rendered) ) return $this->rendered; + + $property = preg_replace( '/[;].*$/', '', $this->name ); + $escaped = $this->content; + switch( $property ) { + /** Content escaping does not apply to these properties culled from RFC2445 */ + case 'ATTACH': case 'GEO': case 'PERCENT-COMPLETE': case 'PRIORITY': + case 'DURATION': case 'FREEBUSY': case 'TZOFFSETFROM': case 'TZOFFSETTO': + case 'TZURL': case 'ATTENDEE': case 'ORGANIZER': case 'RECURRENCE-ID': + case 'URL': case 'EXRULE': case 'SEQUENCE': case 'CREATED': + case 'RRULE': case 'REPEAT': case 'TRIGGER': + break; + + case 'COMPLETED': case 'DTEND': + case 'DUE': case 'DTSTART': + case 'DTSTAMP': case 'LAST-MODIFIED': + case 'CREATED': case 'EXDATE': + case 'RDATE': + if ( isset($this->parameters['VALUE']) && $this->parameters['VALUE'] == 'DATE' ) { + $escaped = substr( $escaped, 0, 8); + } + break; + + /** Content escaping applies by default to other properties */ + default: + $escaped = str_replace( '\\', '\\\\', $escaped); + $escaped = preg_replace( '/\r?\n/', '\\n', $escaped); + $escaped = preg_replace( "/([,;\"])/", '\\\\$1', $escaped); + } + $property = sprintf( "%s%s:", $this->name, $this->RenderParameters() ); + if ( (strlen($property) + strlen($escaped)) <= 72 ) { + $this->rendered = $property . $escaped; + } + else if ( (strlen($property) + strlen($escaped)) > 72 && (strlen($property) < 72) && (strlen($escaped) < 72) ) { + $this->rendered = $property . " \r\n " . $escaped; + } + else { + $this->rendered = wordwrap( $property . $escaped, 72, " \r\n ", true ); + } + return $this->rendered; + } + +} + + +/** +* A Class for representing components within an iCalendar +* +* @package awl +*/ +class iCalComponent { + /**#@+ + * @access private + */ + + /** + * The type of this component, such as 'VEVENT', 'VTODO', 'VTIMEZONE', etc. + * + * @var string + */ + var $type; + + /** + * An array of properties, which are iCalProp objects + * + * @var array + */ + var $properties; + + /** + * An array of (sub-)components, which are iCalComponent objects + * + * @var array + */ + var $components; + + /** + * The rendered result (or what was originally parsed, if there have been no changes) + * + * @var array + */ + var $rendered; + + /**#@-*/ + + /** + * A basic constructor + */ + function iCalComponent( $content = null ) { + $this->type = ""; + $this->properties = array(); + $this->components = array(); + $this->rendered = ""; + if ( $content != null && gettype($content) == 'string' ) { + $this->ParseFrom($content); + } + } + + + /** + * Apply standard properties for a VCalendar + * @param array $extra_properties Key/value pairs of additional properties + */ + function VCalendar( $extra_properties = null ) { + $this->SetType('VCALENDAR'); + $this->AddProperty('PRODID', '-//davical.org//NONSGML AWL Calendar//EN'); + $this->AddProperty('VERSION', '2.0'); + $this->AddProperty('CALSCALE', 'GREGORIAN'); + if ( is_array($extra_properties) ) { + foreach( $extra_properties AS $k => $v ) { + $this->AddProperty($k,$v); + } + } + } + + /** + * Collect an array of all parameters of our properties which are the specified type + * Mainly used for collecting the full variety of references TZIDs + */ + function CollectParameterValues( $parameter_name ) { + $values = array(); + foreach( $this->components AS $k => $v ) { + $also = $v->CollectParameterValues($parameter_name); + $values = array_merge( $values, $also ); + } + foreach( $this->properties AS $k => $v ) { + $also = $v->GetParameterValue($parameter_name); + if ( isset($also) && $also != "" ) { + dbg_error_log( "iCalendar", "::CollectParameterValues(%s) : Found '%s'", $parameter_name, $also); + $values[$also] = 1; + } + } + return $values; + } + + + /** + * Parse the text $content into sets of iCalProp & iCalComponent within this iCalComponent + * @param string $content The raw RFC2445-compliant iCalendar component, including BEGIN:TYPE & END:TYPE + */ + function ParseFrom( $content ) { + $this->rendered = $content; + $content = $this->UnwrapComponent($content); + + $lines = preg_split('/\r?\n/', $content ); + + $type = false; + $subtype = false; + $finish = null; + $subfinish = null; + foreach( $lines AS $k => $v ) { + if ( preg_match('/^\s*$/', $v ) ) continue; + dbg_error_log( "iCalendar", "::ParseFrom: Parsing line: $v"); + if ( $type === false ) { + if ( preg_match( '/^BEGIN:(.+)$/', $v, $matches ) ) { + // We have found the start of the main component + $type = $matches[1]; + $finish = "END:$type"; + $this->type = $type; + dbg_error_log( "iCalendar", "::ParseFrom: Start component of type '%s'", $type); + } + else { + dbg_error_log( "iCalendar", "::ParseFrom: Ignoring crap before start of component"); + unset($lines[$k]); // The content has crap before the start + if ( $v != "" ) $this->rendered = null; + } + } + else if ( $type == null ) { + dbg_error_log( "iCalendar", "::ParseFrom: Ignoring crap after end of component"); + unset($lines[$k]); // The content has crap after the end + if ( $v != "" ) $this->rendered = null; + } + else if ( $v == $finish ) { + dbg_error_log( "iCalendar", "::ParseFrom: End of component"); + $type = null; // We have reached the end of our component + } + else { + if ( $subtype === false && preg_match( '/^BEGIN:(.+)$/', $v, $matches ) ) { + // We have found the start of a sub-component + $subtype = $matches[1]; + $subfinish = "END:$subtype"; + $subcomponent = "$v\r\n"; + dbg_error_log( "iCalendar", "::ParseFrom: Found a subcomponent '%s'", $subtype); + } + else if ( $subtype ) { + // We are inside a sub-component + $subcomponent .= $this->WrapComponent($v); + if ( $v == $subfinish ) { + dbg_error_log( "iCalendar", "::ParseFrom: End of subcomponent '%s'", $subtype); + // We have found the end of a sub-component + $this->components[] = new iCalComponent($subcomponent); + $subtype = false; + } + else + dbg_error_log( "iCalendar", "::ParseFrom: Inside a subcomponent '%s'", $subtype ); + } + else { + dbg_error_log( "iCalendar", "::ParseFrom: Parse property of component"); + // It must be a normal property line within a component. + $this->properties[] = new iCalProp($v); + } + } + } + } + + + /** + * This unescapes the (CRLF + linear space) wrapping specified in RFC2445. According + * to RFC2445 we should always end with CRLF but the CalDAV spec says that normalising + * XML parsers often muck with it and may remove the CR. We accept either case. + */ + function UnwrapComponent( $content ) { + return preg_replace('/\r?\n[ \t]/', '', $content ); + } + + /** + * This imposes the (CRLF + linear space) wrapping specified in RFC2445. According + * to RFC2445 we should always end with CRLF but the CalDAV spec says that normalising + * XML parsers often muck with it and may remove the CR. We output RFC2445 compliance. + * + * In order to preserve pre-existing wrapping in the component, we split the incoming + * string on line breaks before running wordwrap over each component of that. + */ + function WrapComponent( $content ) { + $strs = preg_split( "/\r?\n/", $content ); + $wrapped = ""; + foreach ($strs as $str) { + $wrapped .= wordwrap($str, 73, " \r\n ") . "\r\n"; + } + return $wrapped; + } + + /** + * Return the type of component which this is + */ + function GetType() { + return $this->type; + } + + + /** + * Set the type of component which this is + */ + function SetType( $type ) { + if ( isset($this->rendered) ) unset($this->rendered); + $this->type = $type; + return $this->type; + } + + + /** + * Get all properties, or the properties matching a particular type + */ + function GetProperties( $type = null ) { + $properties = array(); + foreach( $this->properties AS $k => $v ) { + if ( $type == null || $v->Name() == $type ) { + $properties[$k] = $v; + } + } + return $properties; + } + + + /** + * Get the value of the first property matching the name. Obviously this isn't + * so useful for properties which may occur multiply, but most don't. + * + * @param string $type The type of property we are after. + * @return string The value of the property, or null if there was no such property. + */ + function GetPValue( $type ) { + foreach( $this->properties AS $k => $v ) { + if ( $v->Name() == $type ) return $v->Value(); + } + return null; + } + + + /** + * Get the value of the specified parameter for the first property matching the + * name. Obviously this isn't so useful for properties which may occur multiply, but most don't. + * + * @param string $type The type of property we are after. + * @param string $type The name of the parameter we are after. + * @return string The value of the parameter for the property, or null in the case that there was no such property, or no such parameter. + */ + function GetPParamValue( $type, $parameter_name ) { + foreach( $this->properties AS $k => $v ) { + if ( $v->Name() == $type ) return $v->GetParameterValue($parameter_name); + } + return null; + } + + + /** + * Clear all properties, or the properties matching a particular type + * @param string $type The type of property - omit for all properties + */ + function ClearProperties( $type = null ) { + if ( $type != null ) { + // First remove all the existing ones of that type + foreach( $this->properties AS $k => $v ) { + if ( $v->Name() == $type ) { + unset($this->properties[$k]); + if ( isset($this->rendered) ) unset($this->rendered); + } + } + $this->properties = array_values($this->properties); + } + else { + if ( isset($this->rendered) ) unset($this->rendered); + $this->properties = array(); + } + } + + + /** + * Set all properties, or the ones matching a particular type + */ + function SetProperties( $new_properties, $type = null ) { + if ( isset($this->rendered) && count($new_properties) > 0 ) unset($this->rendered); + $this->ClearProperties($type); + foreach( $new_properties AS $k => $v ) { + $this->AddProperty($v); + } + } + + + /** + * Adds a new property + * + * @param iCalProp $new_property The new property to append to the set, or a string with the name + * @param string $value The value of the new property (default: param 1 is an iCalProp with everything + * @param array $parameters The key/value parameter pairs (default: none, or param 1 is an iCalProp with everything) + */ + function AddProperty( $new_property, $value = null, $parameters = null ) { + if ( isset($this->rendered) ) unset($this->rendered); + if ( isset($value) && gettype($new_property) == 'string' ) { + $new_prop = new iCalProp(); + $new_prop->Name($new_property); + $new_prop->Value($value); + if ( $parameters != null ) $new_prop->Parameters($parameters); + dbg_error_log("iCalendar"," Adding new property '%s'", $new_prop->Render() ); + $this->properties[] = $new_prop; + } + else if ( gettype($new_property) ) { + $this->properties[] = $new_property; + } + } + + + /** + * Get all sub-components, or at least get those matching a type + * @return array an array of the sub-components + */ + function &FirstNonTimezone( $type = null ) { + foreach( $this->components AS $k => $v ) { + if ( $v->GetType() != 'VTIMEZONE' ) return $this->components[$k]; + } + $result = false; + return $result; + } + + + /** + * Return true if the person identified by the email address is down as an + * organizer for this meeting. + * @param string $email The e-mail address of the person we're seeking. + * @return boolean true if we found 'em, false if we didn't. + */ + function IsOrganizer( $email ) { + if ( !preg_match( '#^mailto:#', $email ) ) $email = 'mailto:$email'; + $props = $this->GetPropertiesByPath('!VTIMEZONE/ORGANIZER'); + foreach( $props AS $k => $prop ) { + if ( $prop->Value() == $email ) return true; + } + return false; + } + + + /** + * Return true if the person identified by the email address is down as an + * attendee or organizer for this meeting. + * @param string $email The e-mail address of the person we're seeking. + * @return boolean true if we found 'em, false if we didn't. + */ + function IsAttendee( $email ) { + if ( !preg_match( '#^mailto:#', $email ) ) $email = 'mailto:$email'; + if ( $this->IsOrganizer($email) ) return true; /** an organizer is an attendee, as far as we're concerned */ + $props = $this->GetPropertiesByPath('!VTIMEZONE/ATTENDEE'); + foreach( $props AS $k => $prop ) { + if ( $prop->Value() == $email ) return true; + } + return false; + } + + + /** + * Get all sub-components, or at least get those matching a type, or failling to match, + * should the second parameter be set to false. + * + * @param string $type The type to match (default: All) + * @param boolean $normal_match Set to false to invert the match (default: true) + * @return array an array of the sub-components + */ + function GetComponents( $type = null, $normal_match = true ) { + $components = $this->components; + if ( $type != null ) { + foreach( $components AS $k => $v ) { + if ( ($v->GetType() != $type) === $normal_match ) { + unset($components[$k]); + } + } + $components = array_values($components); + } + return $components; + } + + + /** + * Clear all components, or the components matching a particular type + * @param string $type The type of component - omit for all components + */ + function ClearComponents( $type = null ) { + if ( $type != null ) { + // First remove all the existing ones of that type + foreach( $this->components AS $k => $v ) { + if ( $v->GetType() == $type ) { + unset($this->components[$k]); + if ( isset($this->rendered) ) unset($this->rendered); + } + else { + if ( ! $this->components[$k]->ClearComponents($type) ) { + if ( isset($this->rendered) ) unset($this->rendered); + } + } + } + return isset($this->rendered); + } + else { + if ( isset($this->rendered) ) unset($this->rendered); + $this->components = array(); + } + } + + + /** + * Sets some or all sub-components of the component to the supplied new components + * + * @param array of iCalComponent $new_components The new components to replace the existing ones + * @param string $type The type of components to be replaced. Defaults to null, which means all components will be replaced. + */ + function SetComponents( $new_component, $type = null ) { + if ( isset($this->rendered) ) unset($this->rendered); + if ( count($new_component) > 0 ) $this->ClearComponents($type); + foreach( $new_component AS $k => $v ) { + $this->components[] = $v; + } + } + + + /** + * Adds a new subcomponent + * + * @param iCalComponent $new_component The new component to append to the set + */ + function AddComponent( $new_component ) { + if ( is_array($new_component) && count($new_component) == 0 ) return; + if ( isset($this->rendered) ) unset($this->rendered); + if ( is_array($new_component) ) { + foreach( $new_component AS $k => $v ) { + $this->components[] = $v; + } + } + else { + $this->components[] = $new_component; + } + } + + + /** + * Mask components, removing any that are not of the types in the list + * @param array $keep An array of component types to be kept + */ + function MaskComponents( $keep ) { + foreach( $this->components AS $k => $v ) { + if ( ! in_array( $v->GetType(), $keep ) ) { + unset($this->components[$k]); + if ( isset($this->rendered) ) unset($this->rendered); + } + else { + $v->MaskComponents($keep); + } + } + } + + + /** + * Mask properties, removing any that are not in the list + * @param array $keep An array of property names to be kept + * @param array $component_list An array of component types to check within + */ + function MaskProperties( $keep, $component_list=null ) { + foreach( $this->components AS $k => $v ) { + $v->MaskProperties($keep, $component_list); + } + + if ( !isset($component_list) || in_array($this->GetType(),$component_list) ) { + foreach( $this->components AS $k => $v ) { + if ( ! in_array( $v->GetType(), $keep ) ) { + unset($this->components[$k]); + if ( isset($this->rendered) ) unset($this->rendered); + } + } + } + } + + + /** + * Clone this component (and subcomponents) into a confidential version of it. A confidential + * event will be scrubbed of any identifying characteristics other than time/date, repeat, uid + * and a summary which is just a translated 'Busy'. + */ + function CloneConfidential() { + $confidential = clone($this); + $keep_properties = array( 'DTSTAMP', 'DTSTART', 'RRULE', 'DURATION', 'DTEND', 'UID', 'CLASS', 'TRANSP' ); + $resource_components = array( 'VEVENT', 'VTODO', 'VJOURNAL' ); + $confidential->MaskComponents(array( 'VTIMEZONE', 'VEVENT', 'VTODO', 'VJOURNAL' )); + $confidential->MaskProperties($keep_properties, $resource_components ); + if ( in_array( $confidential->GetType(), $resource_components ) ) { + $confidential->AddProperty( 'SUMMARY', translate('Busy') ); + } + foreach( $confidential->components AS $k => $v ) { + if ( in_array( $v->GetType(), $resource_components ) ) { + $v->AddProperty( 'SUMMARY', translate('Busy') ); + } + } + + return $confidential; + } + + + /** + * Renders the component, possibly restricted to only the listed properties + */ + function Render( $restricted_properties = null) { + + $unrestricted = (!isset($restricted_properties) || count($restricted_properties) == 0); + + if ( isset($this->rendered) && $unrestricted ) + return $this->rendered; + + $rendered = "BEGIN:$this->type\r\n"; + foreach( $this->properties AS $k => $v ) { + if ( $unrestricted || isset($restricted_properties[$v]) ) $rendered .= $v->Render() . "\r\n"; + } + foreach( $this->components AS $v ) { $rendered .= $v->Render(); } + $rendered .= "END:$this->type\r\n"; +// $rendered = $this->WrapComponent($rendered); + + if ( $unrestricted ) $this->rendered = $rendered; + + return $rendered; + } + + /** + * Return an array of properties matching the specified path + * + * @return array An array of iCalProp within the tree which match the path given, in the form + * [/]COMPONENT[/...]/PROPERTY in a syntax kind of similar to our poor man's XML queries. We + * also allow COMPONENT and PROPERTY to be !COMPONENT and !PROPERTY for ++fun. + * + * @note At some point post PHP4 this could be re-done with an iterator, which should be more efficient for common use cases. + */ + function GetPropertiesByPath( $path ) { + $properties = array(); + dbg_error_log( "iCalendar", "GetPropertiesByPath: Querying within '%s' for path '%s'", $this->type, $path ); + if ( !preg_match( '#(/?)(!?)([^/]+)(/?.*)$#', $path, $matches ) ) return $properties; + + $adrift = ($matches[1] == ''); + $normal = ($matches[2] == ''); + $ourtest = $matches[3]; + $therest = $matches[4]; + dbg_error_log( "iCalendar", "GetPropertiesByPath: Matches: %s -- %s -- %s -- %s\n", $matches[1], $matches[2], $matches[3], $matches[4] ); + if ( $ourtest == '*' || (($ourtest == $this->type) === $normal) && $therest != '' ) { + if ( preg_match( '#^/(!?)([^/]+)$#', $therest, $matches ) ) { + $normmatch = ($matches[1] ==''); + $proptest = $matches[2]; + foreach( $this->properties AS $k => $v ) { + if ( $proptest = '*' || (($v->Name() == $proptest) === $normmatch ) ) { + $properties[] = $v; + } + } + } + else { + /** + * There is more to the path, so we recurse into that sub-part + */ + foreach( $this->components AS $k => $v ) { + $properties = array_merge( $properties, $v->GetPropertiesByPath($therest) ); + } + } + } + + if ( $adrift ) { + /** + * Our input $path was not rooted, so we recurse further + */ + foreach( $this->components AS $k => $v ) { + $properties = array_merge( $properties, $v->GetPropertiesByPath($path) ); + } + } + dbg_error_log("iCalendar", "GetPropertiesByPath: Found %d within '%s' for path '%s'\n", count($properties), $this->type, $path ); + return $properties; + } + +} + +/** +************************************************************************************ +* Pretty much everything below here is deprecated and should be avoided in favour +* of using, improving and enhancing the more sensible structures above. +************************************************************************************ +*/ + +/** +* A Class for handling Events on a calendar +* +* @package awl +*/ +class iCalendar { + /**#@+ + * @access private + */ + + /** + * The component-ised version of the iCalendar + * @var component iCalComponent + */ + var $component; + + /** + * An array of arbitrary properties, containing arbitrary arrays of arbitrary properties + * @var properties array + */ + var $properties; + + /** + * An array of the lines of this iCalendar resource + * @var lines array + */ + var $lines; + + /** + * The typical location name for the standard timezone such as "Pacific/Auckland" + * @var tz_locn string + */ + var $tz_locn; + + /** + * The type of iCalendar data VEVENT/VTODO/VJOURNAL + * @var type string + */ + var $type; + + /**#@-*/ + + /** + * The constructor takes an array of args. If there is an element called 'icalendar' + * then that will be parsed into the iCalendar object. Otherwise the array elements + * are converted into properties of the iCalendar object directly. + */ + function iCalendar( $args ) { + global $c; + + $this->tz_locn = ""; + if ( !isset($args) || !(is_array($args) || is_object($args)) ) return; + if ( is_object($args) ) { + settype($args,'array'); + } + + $this->component = new iCalComponent(); + if ( isset($args['icalendar']) ) { + $this->component->ParseFrom($args['icalendar']); + $this->lines = preg_split('/\r?\n/', $args['icalendar'] ); + $this->SaveTimeZones(); + $first =& $this->component->FirstNonTimezone(); + if ( $first ) { + $this->type = $first->GetType(); + $this->properties = $first->GetProperties(); + } + else { + $this->properties = array(); + } + $this->properties['VCALENDAR'] = array('***ERROR*** This class is being referenced in an unsupported way!'); + return; + } + + if ( isset($args['type'] ) ) { + $this->type = $args['type']; + unset( $args['type'] ); + } + else { + $this->type = 'VEVENT'; // Default to event + } + $this->component->SetType('VCALENDAR'); + $this->component->SetProperties( + array( + new iCalProp('PRODID:-//davical.org//NONSGML AWL Calendar//EN'), + new iCalProp('VERSION:2.0'), + new iCalProp('CALSCALE:GREGORIAN') + ) + ); + $first = new iCalComponent(); + $first->SetType($this->type); + $this->properties = array(); + + foreach( $args AS $k => $v ) { + dbg_error_log( "iCalendar", ":Initialise: %s to >>>%s<<<", $k, $v ); + $property = new iCalProp(); + $property->Name($k); + $property->Value($v); + $this->properties[] = $property; + } + $first->SetProperties($this->properties); + $this->component->SetComponents( array($first) ); + + $this->properties['VCALENDAR'] = array('***ERROR*** This class is being referenced in an unsupported way!'); + + /** + * @todo Need to handle timezones!!! + */ + if ( $this->tz_locn == "" ) { + $this->tz_locn = $this->Get("tzid"); + if ( (!isset($this->tz_locn) || $this->tz_locn == "") && isset($c->local_tzid) ) { + $this->tz_locn = $c->local_tzid; + } + } + } + + + /** + * Save any timezones by TZID in the PostgreSQL database for future re-use. + */ + function SaveTimeZones() { + global $c; + + $this->tzid_list = array_keys($this->component->CollectParameterValues('TZID')); + if ( ! isset($this->tzid) && count($this->tzid_list) > 0 ) { + dbg_error_log( "icalendar", "::TZID_List[0] = '%s', count=%d", $this->tzid_list[0], count($this->tzid_list) ); + $this->tzid = $this->tzid_list[0]; + } + + $timezones = $this->component->GetComponents('VTIMEZONE'); + if ( $timezones === false || count($timezones) == 0 ) return; + $this->vtimezone = $timezones[0]->Render(); // Backward compatibility + + $tzid = $this->Get('TZID'); + if ( isset($c->save_time_zone_defs) && $c->save_time_zone_defs ) { + foreach( $timezones AS $k => $tz ) { + $tzid = $tz->GetPValue('TZID'); + + $qry = new PgQuery( "SELECT tz_locn FROM time_zone WHERE tz_id = ?;", $tzid ); + if ( $qry->Exec('iCalendar') && $qry->rows == 1 ) { + $row = $qry->Fetch(); + if ( !isset($first_tzid) ) $first_tzid = $row->tz_locn; + continue; + } + + if ( $tzid != "" && $qry->rows == 0 ) { + + $tzname = $tz->GetPValue('X-LIC-LOCATION'); + if ( !isset($tzname) ) { + /** + * Try and convert the TZID to a string like "Pacific/Auckland" if possible. + */ + $tzname = preg_replace('#^(.*[^a-z])?([a-z]+/[a-z]+)$#i','$2',$tzid ); + } + + $qry2 = new PgQuery( "INSERT INTO time_zone (tz_id, tz_locn, tz_spec) VALUES( ?, ?, ? );", + $tzid, $tzname, $tz->Render() ); + $qry2->Exec("iCalendar"); + } + } + } + if ( ! isset($this->tzid) && isset($first_tzid) ) $this->tzid = $first_tzid; + + if ( (!isset($this->tz_locn) || $this->tz_locn == '') && isset($first_tzid) && $first_tzid != '' ) { + $tzname = preg_replace('#^(.*[^a-z])?([a-z]+/[a-z]+)$#i','$2', $first_tzid ); + if ( preg_match( '#\S+/\S+#', $tzname) ) { + $this->tz_locn = $tzname; + } + dbg_error_log( "icalendar", " TZCrap1: TZID '%s', Location '%s', Perhaps: %s", $tzid, $this->tz_locn, $tzname ); + } + + if ( (!isset($this->tz_locn) || $this->tz_locn == "") && isset($c->local_tzid) ) { + $this->tz_locn = $c->local_tzid; + } + if ( ! isset($this->tzid) && isset($this->tz_locn) ) $this->tzid = $this->tz_locn; + } + + + /** + * An array of property names that we should always want when rendering an iCalendar + * + * @deprecated This function is deprecated and will be removed eventually. + * @todo Remove this function. + */ + function DefaultPropertyList() { + dbg_error_log( "LOG", " iCalendar: Call to deprecated method '%s'", 'DefaultPropertyList' ); + return array( "UID" => 1, "DTSTAMP" => 1, "DTSTART" => 1, "DURATION" => 1, + "LAST-MODIFIED" => 1,"CLASS" => 1, "TRANSP" => 1, "SEQUENCE" => 1, + "DUE" => 1, "SUMMARY" => 1, "RRULE" => 1 ); + } + + /** + * A function to extract the contents of a BEGIN:SOMETHING to END:SOMETHING (perhaps multiply) + * and return just that bit (or, of course, those bits :-) + * + * @var string The type of thing(s) we want returned. + * @var integer The number of SOMETHINGS we want to get. + * + * @return string A string from BEGIN:SOMETHING to END:SOMETHING, possibly multiple of these + * + * @deprecated This function is deprecated and will be removed eventually. + * @todo Remove this function. + */ + function JustThisBitPlease( $type, $count=1 ) { + dbg_error_log( "LOG", " iCalendar: Call to deprecated method '%s'", 'JustThisBitPlease' ); + $answer = ""; + $intags = false; + $start = "BEGIN:$type"; + $finish = "END:$type"; + dbg_error_log( "iCalendar", ":JTBP: Looking for %d subsets of type %s", $count, $type ); + reset($this->lines); + foreach( $this->lines AS $k => $v ) { + if ( !$intags && $v == $start ) { + $answer .= $v . "\n"; + $intags = true; + } + else if ( $intags && $v == $finish ) { + $answer .= $v . "\n"; + $intags = false; + } + else if ( $intags ) { + $answer .= $v . "\n"; + } + } + return $answer; + } + + + /** + * Function to parse lines from BEGIN:SOMETHING to END:SOMETHING into a nested array structure + * + * @var string The "SOMETHING" from the BEGIN:SOMETHING line we just met + * @return arrayref An array of the things we found between (excluding) the BEGIN & END, some of which might be sub-arrays + * + * @deprecated This function is deprecated and will be removed eventually. + * @todo Remove this function. + */ + function &ParseSomeLines( $type ) { + dbg_error_log( "LOG", " iCalendar: Call to deprecated method '%s'", 'ParseSomeLines' ); + $props = array(); + $properties =& $props; + while( isset($this->lines[$this->_current_parse_line]) ) { + $i = $this->_current_parse_line++; + $line =& $this->lines[$i]; + dbg_error_log( "iCalendar", ":Parse:%s LINE %03d: >>>%s<<<", $type, $i, $line ); + if ( $this->parsing_vtimezone ) { + $this->vtimezone .= $line."\n"; + } + if ( preg_match( '/^(BEGIN|END):([^:]+)$/', $line, $matches ) ) { + if ( $matches[1] == 'END' && $matches[2] == $type ) { + if ( $type == 'VTIMEZONE' ) { + $this->parsing_vtimezone = false; + } + return $properties; + } + else if( $matches[1] == 'END' ) { + dbg_error_log("ERROR"," iCalendar: parse error: Unexpected END:%s when we were looking for END:%s", $matches[2], $type ); + return $properties; + } + else if( $matches[1] == 'BEGIN' ) { + $subtype = $matches[2]; + if ( $subtype == 'VTIMEZONE' ) { + $this->parsing_vtimezone = true; + $this->vtimezone = $line."\n"; + } + if ( !isset($properties['INSIDE']) ) $properties['INSIDE'] = array(); + $properties['INSIDE'][] = $subtype; + if ( !isset($properties[$subtype]) ) $properties[$subtype] = array(); + $properties[$subtype][] = $this->ParseSomeLines($subtype); + } + } + else { + // Parse the property + @list( $property, $value ) = preg_split('/:/', $line, 2 ); + if ( strpos( $property, ';' ) > 0 ) { + $parameterlist = preg_split('/;/', $property ); + $property = array_shift($parameterlist); + foreach( $parameterlist AS $pk => $pv ) { + if ( $pv == "VALUE=DATE" ) { + $value .= 'T000000'; + } + elseif ( preg_match('/^([^;:=]+)=([^;:=]+)$/', $pv, $matches) ) { + switch( $matches[1] ) { + case 'TZID': $properties['TZID'] = $matches[2]; break; + default: + dbg_error_log( "icalendar", " FYI: Ignoring Resource '%s', Property '%s', Parameter '%s', Value '%s'", $type, $property, $matches[1], $matches[2] ); + } + } + } + } + if ( $this->parsing_vtimezone && (!isset($this->tz_locn) || $this->tz_locn == "") && $property == 'X-LIC-LOCATION' ) { + $this->tz_locn = $value; + } + $properties[strtoupper($property)] = $this->RFC2445ContentUnescape($value); + } + } + return $properties; + } + + + /** + * Build the iCalendar object from a text string which is a single iCalendar resource + * + * @var string The RFC2445 iCalendar resource to be parsed + * + * @deprecated This function is deprecated and will be removed eventually. + * @todo Remove this function. + */ + function BuildFromText( $icalendar ) { + dbg_error_log( "LOG", " iCalendar: Call to deprecated method '%s'", 'BuildFromText' ); + /** + * This unescapes the (CRLF + linear space) wrapping specified in RFC2445. According + * to RFC2445 we should always end with CRLF but the CalDAV spec says that normalising + * XML parsers often muck with it and may remove the CR. + */ + $icalendar = preg_replace('/\r?\n[ \t]/', '', $icalendar ); + + $this->lines = preg_split('/\r?\n/', $icalendar ); + + $this->_current_parse_line = 0; + $this->properties = $this->ParseSomeLines(''); + + /** + * Our 'type' is the type of non-timezone inside a VCALENDAR + */ + if ( isset($this->properties['VCALENDAR'][0]['INSIDE']) ) { + foreach ( $this->properties['VCALENDAR'][0]['INSIDE'] AS $k => $v ) { + if ( $v == 'VTIMEZONE' ) continue; + $this->type = $v; + break; + } + } + + } + + + /** + * Returns a content string with the RFC2445 escaping removed + * + * @param string $escaped The incoming string to be escaped. + * @return string The string with RFC2445 content escaping removed. + * + * @deprecated This function is deprecated and will be removed eventually. + * @todo Remove this function. + */ + function RFC2445ContentUnescape( $escaped ) { + dbg_error_log( "LOG", " iCalendar: Call to deprecated method '%s'", 'RFC2445ContentUnescape' ); + $unescaped = str_replace( '\\n', "\n", $escaped); + $unescaped = str_replace( '\\N', "\n", $unescaped); + $unescaped = preg_replace( "/\\\\([,;:\"\\\\])/", '$1', $unescaped); + return $unescaped; + } + + + + /** + * Do what must be done with time zones from on file. Attempt to turn + * them into something that PostgreSQL can understand... + * + * @deprecated This function is deprecated and will be removed eventually. + * @todo Remove this function. + */ + function DealWithTimeZones() { + global $c; + + dbg_error_log( "LOG", " iCalendar: Call to deprecated method '%s'", 'DealWithTimeZones' ); + $tzid = $this->Get('TZID'); + if ( isset($c->save_time_zone_defs) && $c->save_time_zone_defs ) { + $qry = new PgQuery( "SELECT tz_locn FROM time_zone WHERE tz_id = ?;", $tzid ); + if ( $qry->Exec('iCalendar') && $qry->rows == 1 ) { + $row = $qry->Fetch(); + $this->tz_locn = $row->tz_locn; + } + dbg_error_log( "icalendar", " TZCrap2: TZID '%s', DB Rows=%d, Location '%s'", $tzid, $qry->rows, $this->tz_locn ); + } + + if ( (!isset($this->tz_locn) || $this->tz_locn == '') && $tzid != '' ) { + /** + * In case there was no X-LIC-LOCATION defined, let's hope there is something in the TZID + * that we can use. We are looking for a string like "Pacific/Auckland" if possible. + */ + $tzname = preg_replace('#^(.*[^a-z])?([a-z]+/[a-z]+)$#i','$1',$tzid ); + /** + * Unfortunately this kind of thing will never work well :-( + * + if ( strstr( $tzname, ' ' ) ) { + $words = preg_split('/\s/', $tzname ); + $tzabbr = ''; + foreach( $words AS $i => $word ) { + $tzabbr .= substr( $word, 0, 1); + } + $this->tz_locn = $tzabbr; + } + */ + if ( preg_match( '#\S+/\S+#', $tzname) ) { + $this->tz_locn = $tzname; + } + dbg_error_log( "icalendar", " TZCrap3: TZID '%s', Location '%s', Perhaps: %s", $tzid, $this->tz_locn, $tzname ); + } + + if ( $tzid != '' && isset($c->save_time_zone_defs) && $c->save_time_zone_defs && $qry->rows != 1 && isset($this->vtimezone) && $this->vtimezone != "" ) { + $qry2 = new PgQuery( "INSERT INTO time_zone (tz_id, tz_locn, tz_spec) VALUES( ?, ?, ? );", + $tzid, $this->tz_locn, $this->vtimezone ); + $qry2->Exec("iCalendar"); + } + + if ( (!isset($this->tz_locn) || $this->tz_locn == "") && isset($c->local_tzid) ) { + $this->tz_locn = $c->local_tzid; + } + } + + + /** + * Get the value of a property in the first non-VTIMEZONE + */ + function Get( $key ) { + if ( strtoupper($key) == 'TZID' ) { + // backward compatibility hack + dbg_error_log( "icalendar", " Get(TZID): TZID '%s', Location '%s'", (isset($this->tzid)?$this->tzid:"[not set]"), $this->tz_locn ); + if ( isset($this->tzid) ) return $this->tzid; + return $this->tz_locn; + } + /** + * The property we work on is the first non-VTIMEZONE we find. + */ + $component =& $this->component->FirstNonTimezone(); + if ( $component === false ) return null; + return $component->GetPValue(strtoupper($key)); + } + + + /** + * Set the value of a property + */ + function Set( $key, $value ) { + if ( $value == "" ) return; + $key = strtoupper($key); + $property = new iCalProp(); + $property->Name($key); + $property->Value($value); + if (isset($this->component->rendered) ) unset( $this->component->rendered ); + $component =& $this->component->FirstNonTimezone(); + $component->SetProperties( array($property), $key); + return $this->Get($key); + } + + + /** + * Add a new property/value, regardless of whether it exists already + * + * @param string $key The property key + * @param string $value The property value + * @param string $parameters Any parameters to set for the property, as an array of key/value pairs + */ + function Add( $key, $value, $parameters = null ) { + if ( $value == "" ) return; + $key = strtoupper($key); + $property = new iCalProp(); + $property->Name($key); + $property->Value($value); + if ( isset($parameters) && is_array($parameters) ) { + $property->parameters = $parameters; + } + $component =& $this->component->FirstNonTimezone(); + $component->AddProperty($property); + if (isset($this->component->rendered) ) unset( $this->component->rendered ); + } + + + /** + * Because I screwed up with the name originally... + * @DEPRECATED + * todo:: Remove this function after June 2008. + */ + function Put( $key, $value ) { + dbg_error_log( "LOG", " iCalendar: Call to deprecated method '%s'", 'Put' ); + $this->Set($key,$value); + } + + /** + * Returns a PostgreSQL Date Format string suitable for returning HTTP (RFC2068) dates + * Preferred is "Sun, 06 Nov 1994 08:49:37 GMT" so we do that. + */ + function HttpDateFormat() { + return "'Dy, DD Mon IYYY HH24:MI:SS \"GMT\"'"; + } + + + /** + * Returns a PostgreSQL Date Format string suitable for returning iCal dates + */ + function SqlDateFormat() { + return "'YYYYMMDD\"T\"HH24MISS'"; + } + + + /** + * Returns a PostgreSQL Date Format string suitable for returning dates which + * have been cast to UTC + */ + function SqlUTCFormat() { + return "'YYYYMMDD\"T\"HH24MISS\"Z\"'"; + } + + + /** + * Returns a PostgreSQL Date Format string suitable for returning iCal durations + * - this doesn't work for negative intervals, but events should not have such! + */ + function SqlDurationFormat() { + return "'\"PT\"HH24\"H\"MI\"M\"'"; + } + + /** + * Returns a suitably escaped RFC2445 content string. + * + * @param string $name The incoming name[;param] prefixing the string. + * @param string $value The incoming string to be escaped. + * + * @deprecated This function is deprecated and will be removed eventually. + * @todo Remove this function. + */ + function RFC2445ContentEscape( $name, $value ) { + dbg_error_log( "LOG", " iCalendar: Call to deprecated method '%s'", 'RFC2445ContentEscape' ); + $property = preg_replace( '/[;].*$/', '', $name ); + switch( $property ) { + /** Content escaping does not apply to these properties culled from RFC2445 */ + case 'ATTACH': case 'GEO': case 'PERCENT-COMPLETE': case 'PRIORITY': + case 'COMPLETED': case 'DTEND': case 'DUE': case 'DTSTART': + case 'DURATION': case 'FREEBUSY': case 'TZOFFSETFROM': case 'TZOFFSETTO': + case 'TZURL': case 'ATTENDEE': case 'ORGANIZER': case 'RECURRENCE-ID': + case 'URL': case 'EXDATE': case 'EXRULE': case 'RDATE': + case 'RRULE': case 'REPEAT': case 'TRIGGER': case 'CREATED': + case 'DTSTAMP': case 'LAST-MODIFIED': case 'SEQUENCE': + break; + + /** Content escaping applies by default to other properties */ + default: + $value = str_replace( '\\', '\\\\', $value); + $value = preg_replace( '/\r?\n/', '\\n', $value); + $value = preg_replace( "/([,;:\"])/", '\\\\$1', $value); + } + $result = wordwrap("$name:$value", 73, " \r\n ", true ) . "\r\n"; + return $result; + } + + /** + * Return all sub-components of the given type, which are part of the + * component we pass in as an array of lines. + * + * @param array $component The component to be parsed + * @param string $type The type of sub-components to be extracted + * @param int $count The number of sub-components to extract (default: 9999) + * + * @return array The sub-component lines + */ + function ExtractSubComponent( $component, $type, $count=9999 ) { + $answer = array(); + $intags = false; + $start = "BEGIN:$type"; + $finish = "END:$type"; + dbg_error_log( "iCalendar", ":ExtractSubComponent: Looking for %d subsets of type %s", $count, $type ); + reset($component); + foreach( $component AS $k => $v ) { + if ( !$intags && $v == $start ) { + $answer[] = $v; + $intags = true; + } + else if ( $intags && $v == $finish ) { + $answer[] = $v; + $intags = false; + } + else if ( $intags ) { + $answer[] = $v; + } + } + return $answer; + } + + + /** + * Extract a particular property from the provided component. In doing so we + * assume that the content was unescaped when iCalComponent::ParseFrom() + * called iCalComponent::UnwrapComponent(). + * + * @param array $component An array of lines of this component + * @param string $type The type of parameter + * + * @return array An array of iCalProperty objects + */ + function ExtractProperty( $component, $type, $count=9999 ) { + $answer = array(); + dbg_error_log( "iCalendar", ":ExtractProperty: Looking for %d properties of type %s", $count, $type ); + reset($component); + foreach( $component AS $k => $v ) { + if ( preg_match( "/$type"."[;:]/i", $v ) ) { + $answer[] = new iCalProp($v); + dbg_error_log( "iCalendar", ":ExtractProperty: Found property %s", $type ); + if ( --$count < 1 ) return $answer; + } + } + return $answer; + } + + + /** + * Applies the filter conditions, possibly recursively, to the value which will be either + * a single property, or an array of lines of the component under test. + * + * @todo Eventually we need to handle all of these possibilities, which will mean writing + * several routines: + * - Get Property from Component + * - Get Parameter from Property + * - Test TimeRange + * For the moment we will leave these, until there is a perceived need. + * + * @param array $filter An array of XMLElement defining the filter(s) + * @param mixed $value Either a string which is the single property, or an array of lines, for the component. + * @return boolean Whether the filter passed / failed. + */ + function ApplyFilter( $filter, $value ) { + foreach( $filter AS $k => $v ) { + $tag = $v->GetTag(); + $value_type = gettype($value); + $value_defined = (isset($value) && $value_type == 'string') || ($value_type == 'array' && count($value) > 0 ); + if ( $tag == 'urn:ietf:params:xml:ns:caldav:is-not-defined' && $value_defined ) { + dbg_error_log( "iCalendar", ":ApplyFilter: Value is set ('%s'), want unset, for filter %s", count($value), $tag ); + return false; + } + elseif ( $tag == 'urn:ietf:params:xml:ns:caldav:is-defined' && !$value_defined ) { + dbg_error_log( "iCalendar", ":ApplyFilter: Want value, but it is not set for filter %s", $tag ); + return false; + } + else { + switch( $tag ) { + case 'urn:ietf:params:xml:ns:caldav:time-range': + /** todo:: While this is unimplemented here at present, most time-range tests should occur at the SQL level. */ + break; + case 'urn:ietf:params:xml:ns:caldav:text-match': + $search = $v->GetContent(); + // In this case $value will either be a string, or an array of iCalProp objects + // since TEXT-MATCH does not apply to COMPONENT level - only property/parameter + if ( gettype($value) != 'string' ) { + if ( gettype($value) == 'array' ) { + $match = false; + foreach( $value AS $k1 => $v1 ) { + // $v1 could be an iCalProp object + if ( $match = $v1->TextMatch($search)) break; + } + } + else { + dbg_error_log( "iCalendar", ":ApplyFilter: TEXT-MATCH will only work on strings or arrays of iCalProp. %s unsupported", gettype($value) ); + return true; // We return _true_ in this case, so the client sees the item + } + } + else { + $match = strstr( $value, $search[0] ); + } + $negate = $v->GetAttribute("negate-condition"); + if ( isset($negate) && strtolower($negate) == "yes" && $match ) { + dbg_error_log( "iCalendar", ":ApplyFilter: TEXT-MATCH of %s'%s' against '%s'", (isset($negate) && strtolower($negate) == "yes"?'!':''), $search, $value ); + return false; + } + break; + case 'urn:ietf:params:xml:ns:caldav:comp-filter': + $subfilter = $v->GetContent(); + $component = $this->ExtractSubComponent($value,$v->GetAttribute("name")); + if ( ! $this->ApplyFilter($subfilter,$component) ) return false; + break; + case 'urn:ietf:params:xml:ns:caldav:prop-filter': + $subfilter = $v->GetContent(); + $properties = $this->ExtractProperty($value,$v->GetAttribute("name")); + if ( ! $this->ApplyFilter($subfilter,$properties) ) return false; + break; + case 'urn:ietf:params:xml:ns:caldav:param-filter': + $subfilter = $v->GetContent(); + $parameter = $this->ExtractParameter($value,$v->GetAttribute("NAME")); + if ( ! $this->ApplyFilter($subfilter,$parameter) ) return false; + break; + } + } + } + return true; + } + + /** + * Test a PROP-FILTER or COMP-FILTER and return a true/false + * COMP-FILTER (is-defined | is-not-defined | (time-range?, prop-filter*, comp-filter*)) + * PROP-FILTER (is-defined | is-not-defined | ((time-range | text-match)?, param-filter*)) + * + * @param array $filter An array of XMLElement defining the filter + * + * @return boolean Whether or not this iCalendar passes the test + */ + function TestFilter( $filters ) { + + foreach( $filters AS $k => $v ) { + $tag = $v->GetTag(); + $name = $v->GetAttribute("name"); + $filter = $v->GetContent(); + if ( $tag == "urn:ietf:params:xml:ns:caldav:prop-filter" ) { + $value = $this->ExtractProperty($this->lines,$name); + } + else { + $value = $this->ExtractSubComponent($this->lines,$v->GetAttribute("name")); + } + if ( count($value) == 0 ) unset($value); + if ( ! $this->ApplyFilter($filter,$value) ) return false; + } + return true; + } + + /** + * Returns the header we always use at the start of our iCalendar resources + * + * @deprecated This function is deprecated and will be removed eventually. + * @todo Remove this function. + */ + function iCalHeader() { + dbg_error_log( "LOG", " iCalendar: Call to deprecated method '%s'", 'iCalHeader' ); + return <<component->Render(); + } + else { + $components = $this->component->GetComponents($type); + $rendered = ""; + foreach( $components AS $k => $v ) { + $rendered .= $v->Render($restrict_properties); + } + return $rendered; + } + } + +} diff --git a/caldav/caldav-client.php b/caldav/caldav-client.php new file mode 100644 index 0000000..9269bb9 --- /dev/null +++ b/caldav/caldav-client.php @@ -0,0 +1,532 @@ + +* @copyright Andrew McMillan +* @license http://gnu.org/copyleft/gpl.html GNU GPL v2 +*/ + + +/** +* A class for accessing DAViCal via CalDAV, as a client +* +* @package awl +*/ +class CalDAVClient { + /** + * Server, username, password, calendar + * + * @var string + */ + var $base_url, $user, $pass, $calendar, $entry, $protocol, $server, $port; + + /** + * The useragent which is send to the caldav server + * + * @var string + */ + var $user_agent = 'DAViCalClient'; + + var $headers = array(); + var $body = ""; + var $requestMethod = "GET"; + var $httpRequest = ""; // for debugging http headers sent + var $xmlRequest = ""; // for debugging xml sent + var $httpResponse = ""; // for debugging http headers received + var $xmlResponse = ""; // for debugging xml received + + /** + * Constructor, initialises the class + * + * @param string $base_url The URL for the calendar server + * @param string $user The name of the user logging in + * @param string $pass The password for that user + * @param string $calendar The name of the calendar (not currently used) + */ + function CalDAVClient( $base_url, $user, $pass, $calendar ) { + $this->user = $user; + $this->pass = $pass; + $this->calendar = $calendar; + $this->headers = array(); + + if ( preg_match( '#^(https?)://([a-z0-9.-]+)(:([0-9]+))?(/.*)$#', $base_url, $matches ) ) { + $this->server = $matches[2]; + $this->base_url = $matches[5]; + if ( $matches[1] == 'https' ) { + $this->protocol = 'ssl'; + $this->port = 443; + } + else { + $this->protocol = 'tcp'; + $this->port = 80; + } + if ( $matches[4] != '' ) { + $this->port = intval($matches[4]); + } + } + else { + trigger_error("Invalid URL: '".$base_url."'", E_USER_ERROR); + } + } + + /** + * Adds an If-Match or If-None-Match header + * + * @param bool $match to Match or Not to Match, that is the question! + * @param string $etag The etag to match / not match against. + */ + function SetMatch( $match, $etag = '*' ) { + $this->headers[] = sprintf( "%s-Match: \"%s\"", ($match ? "If" : "If-None"), $etag); + } + + /** + * Add a Depth: header. Valid values are 1 or infinity + * + * @param int $depth The depth, default to infinity + */ + function SetDepth( $depth = 'infinity' ) { + $this->headers[] = "Depth: ". ($depth == 1 ? "1" : "infinity" ); + } + + /** + * Add a Depth: header. Valid values are 1 or infinity + * + * @param int $depth The depth, default to infinity + */ + function SetUserAgent( $user_agent = null ) { + if ( !isset($user_agent) ) $user_agent = $this->user_agent; + $this->user_agent = $user_agent; + } + + /** + * Add a Content-type: header. + * + * @param int $type The content type + */ + function SetContentType( $type ) { + $this->headers[] = "Content-type: $type"; + } + + /** + * Split response into httpResponse and xmlResponse + * + * @param string Response from server + */ + function ParseResponse( $response ) { + $pos = strpos($response, 'httpResponse = trim($response); + } + else { + $this->httpResponse = trim(substr($response, 0, $pos)); + $this->xmlResponse = trim(substr($response, $pos)); + } + } + + /** + * Output http request headers + * + * @return HTTP headers + */ + function GetHttpRequest() { + return $this->httpRequest; + } + /** + * Output http response headers + * + * @return HTTP headers + */ + function GetHttpResponse() { + return $this->httpResponse; + } + /** + * Output xml request + * + * @return raw xml + */ + function GetXmlRequest() { + return $this->xmlRequest; + } + /** + * Output xml response + * + * @return raw xml + */ + function GetXmlResponse() { + return $this->xmlResponse; + } + + /** + * Send a request to the server + * + * @param string $relative_url The URL to make the request to, relative to $base_url + * + * @return string The content of the response from the server + */ + function DoRequest( $relative_url = "" ) { + if(!defined("_FSOCK_TIMEOUT")){ define("_FSOCK_TIMEOUT", 10); } + $headers = array(); + + $headers[] = $this->requestMethod." ". $this->base_url . $relative_url . " HTTP/1.1"; + $headers[] = "Authorization: Basic ".base64_encode($this->user .":". $this->pass ); + $headers[] = "Host: ".$this->server .":".$this->port; + + foreach( $this->headers as $ii => $head ) { + $headers[] = $head; + } + $headers[] = "Content-Length: " . strlen($this->body); + $headers[] = "User-Agent: " . $this->user_agent; + $headers[] = 'Connection: close'; + $this->httpRequest = join("\r\n",$headers); + $this->xmlRequest = $this->body; + + $fip = fsockopen( $this->protocol . '://' . $this->server, $this->port, $errno, $errstr, _FSOCK_TIMEOUT); //error handling? + if ( !(get_resource_type($fip) == 'stream') ) return false; + if ( !fwrite($fip, $this->httpRequest."\r\n\r\n".$this->body) ) { fclose($fip); return false; } + $rsp = ""; + while( !feof($fip) ) { $rsp .= fgets($fip,8192); } + fclose($fip); + + $this->headers = array(); // reset the headers array for our next request + $this->ParseResponse($rsp); + return $rsp; + } + + + /** + * Send an OPTIONS request to the server + * + * @param string $relative_url The URL to make the request to, relative to $base_url + * + * @return array The allowed options + */ + function DoOptionsRequest( $relative_url = "" ) { + $this->requestMethod = "OPTIONS"; + $this->body = ""; + $headers = $this->DoRequest($relative_url); + $options_header = preg_replace( '/^.*Allow: ([a-z, ]+)\r?\n.*/is', '$1', $headers ); + $options = array_flip( preg_split( '/[, ]+/', $options_header )); + return $options; + } + + + + /** + * Send an XML request to the server (e.g. PROPFIND, REPORT, MKCALENDAR) + * + * @param string $method The method (PROPFIND, REPORT, etc) to use with the request + * @param string $xml The XML to send along with the request + * @param string $relative_url The URL to make the request to, relative to $base_url + * + * @return array An array of the allowed methods + */ + function DoXMLRequest( $request_method, $xml, $relative_url = '' ) { + $this->body = $xml; + $this->requestMethod = $request_method; + $this->SetContentType("text/xml"); + return $this->DoRequest($relative_url); + } + + + + /** + * Get a single item from the server. + * + * @param string $relative_url The part of the URL after the calendar + */ + function DoGETRequest( $relative_url ) { + $this->body = ""; + $this->requestMethod = "GET"; + return $this->DoRequest( $relative_url ); + } + + /** + * PUT a text/icalendar resource, returning the etag + * + * @param string $relative_url The URL to make the request to, relative to $base_url + * @param string $icalendar The iCalendar resource to send to the server + * @param string $etag The etag of an existing resource to be overwritten, or '*' for a new resource. + * + * @return string The content of the response from the server + */ + function DoPUTRequest( $relative_url, $icalendar, $etag = null ) { + $this->body = $icalendar; + + $this->requestMethod = "PUT"; + if ( $etag != null ) { + $this->SetMatch( ($etag != '*'), $etag ); + } + $this->SetContentType("text/calendar"); + $headers = $this->DoRequest($relative_url); + + /** + * RSCDS will always return the real etag on PUT. Other CalDAV servers may need + * more work, but we are assuming we are running against RSCDS in this case. + */ + preg_match('/^HTTP\/1\.[01]+\s+(\d+)\s+/i', $headers, $match); + if ($match) { + //print htmlentities($this->GetXmlResponse())."
"; + $xml = simplexml_load_string($this->GetXmlResponse()); + $xml->registerXPathNamespace('e', 'DAV:'); + $elems = $xml->xpath('//e:error'); + $error = $elems[0]; + switch ($match[1]) { + case 412: + //echo "$error
"; + preg_match('/^"?[^"]+"+([0-9a-zA-Z]+)"+.*"+([0-9a-zA-Z]+)"+/', $error, $m); + //print_r($m); + if ($m) { + if (strcasecmp($m[1], $m[2]) !== 0) { + $error = "Remote changes discovered.\n"; + $error .= "Enter changes again after reload\n"; + } + } + $etag = array($match[1] => "$error"); + //print_r($etag); + break; + default: break; + } + } + else + $etag = preg_replace( '/^.*Etag: "?([^"\r\n]+)"?\r?\n.*/is', '$1', $headers ); + return $etag; + } + + + /** + * DELETE a text/icalendar resource + * + * @param string $relative_url The URL to make the request to, relative to $base_url + * @param string $etag The etag of an existing resource to be deleted, or '*' for any resource at that URL. + * + * @return int The HTTP Result Code for the DELETE + */ + function DoDELETERequest( $relative_url, $etag = null ) { + $this->body = ""; + + $this->requestMethod = "DELETE"; + if ( $etag != null ) { + $this->SetMatch( true, $etag ); + } + $this->DoRequest($relative_url); + return $this->resultcode; + } + + + /** + * Given XML for a calendar query, return an array of the events (/todos) in the + * response. Each event in the array will have a 'href', 'etag' and '$response_type' + * part, where the 'href' is relative to the calendar and the '$response_type' contains the + * definition of the calendar data in iCalendar format. + * + * @param string $filter XML fragment which is the element of a calendar-query + * @param string $relative_url The URL relative to the base_url specified when the calendar was opened. Default ''. + * @param string $report_type Used as a name for the array element containing the calendar data. @deprecated + * + * @return array An array of the relative URLs, etags, and events from the server. Each element of the array will + * be an array with 'href', 'etag' and 'data' elements, corresponding to the URL, the server-supplied + * etag (which only varies when the data changes) and the calendar data in iCalendar format. + */ + function DoCalendarQuery( $filter, $relative_url = '' ) { + + $xml = << + + + + + +$filter + +EOXML; + + $this->DoXMLRequest( 'REPORT', $xml, $relative_url ); + $xml_parser = xml_parser_create_ns('UTF-8'); + $this->xml_tags = array(); + xml_parser_set_option ( $xml_parser, XML_OPTION_SKIP_WHITE, 1 ); + xml_parse_into_struct( $xml_parser, $this->xmlResponse, $this->xml_tags ); + xml_parser_free($xml_parser); + + $report = array(); + foreach( $this->xml_tags as $k => $v ) { + switch( $v['tag'] ) { + case 'DAV::RESPONSE': + if ( $v['type'] == 'open' ) { + $response = array(); + } + elseif ( $v['type'] == 'close' ) { + $report[] = $response; + } + break; + case 'DAV::HREF': + $response['href'] = basename( $v['value'] ); + break; + case 'DAV::GETETAG': + $response['etag'] = preg_replace('/^"?([^"]+)"?/', '$1', $v['value']); + break; + case 'URN:IETF:PARAMS:XML:NS:CALDAV:CALENDAR-DATA': + $response['data'] = $v['value']; + break; + } + } + return $report; + } + + + /** + * Get the events in a range from $start to $finish. The dates should be in the + * format yyyymmddThhmmssZ and should be in GMT. The events are returned as an + * array of event arrays. Each event array will have a 'href', 'etag' and 'event' + * part, where the 'href' is relative to the calendar and the event contains the + * definition of the event in iCalendar format. + * + * @param timestamp $start The start time for the period + * @param timestamp $finish The finish time for the period + * @param string $relative_url The URL relative to the base_url specified when the calendar was opened. Default ''. + * + * @return array An array of the relative URLs, etags, and events, returned from DoCalendarQuery() @see DoCalendarQuery() + */ + function GetEvents( $start = null, $finish = null, $relative_url = '' ) { + $filter = ""; + if ( isset($start) && isset($finish) ) + $range = ""; + else + $range = ''; + + $filter = << + + + $range + + + +EOFILTER; + + return $this->DoCalendarQuery($filter, $relative_url); + } + + + /** + * Get the todo's in a range from $start to $finish. The dates should be in the + * format yyyymmddThhmmssZ and should be in GMT. The events are returned as an + * array of event arrays. Each event array will have a 'href', 'etag' and 'event' + * part, where the 'href' is relative to the calendar and the event contains the + * definition of the event in iCalendar format. + * + * @param timestamp $start The start time for the period + * @param timestamp $finish The finish time for the period + * @param boolean $completed Whether to include completed tasks + * @param boolean $cancelled Whether to include cancelled tasks + * @param string $relative_url The URL relative to the base_url specified when the calendar was opened. Default ''. + * + * @return array An array of the relative URLs, etags, and events, returned from DoCalendarQuery() @see DoCalendarQuery() + */ + function GetTodos( $start, $finish, $completed = false, $cancelled = false, $relative_url = "" ) { + + if ( $start && $finish ) { +$time_range = << +EOTIME; + } + + // Warning! May contain traces of double negatives... + $neg_cancelled = ( $cancelled === true ? "no" : "yes" ); + $neg_completed = ( $cancelled === true ? "no" : "yes" ); + + $filter = << + + + + COMPLETED + + + CANCELLED + $time_range + + + +EOFILTER; + + return $this->DoCalendarQuery($filter, $relative_url); + } + + + /** + * Get the calendar entry by UID + * + * @param uid + * @param string $relative_url The URL relative to the base_url specified when the calendar was opened. Default ''. + * + * @return array An array of the relative URL, etag, and calendar data returned from DoCalendarQuery() @see DoCalendarQuery() + */ + function GetEntryByUid( $uid, $relative_url = '' ) { + $filter = ""; + if ( $uid ) { + $filter = << + + + + $uid + + + + +EOFILTER; + } + + return $this->DoCalendarQuery($filter, $relative_url); + } + + + /** + * Get the calendar entry by HREF + * + * @param string $href The href from a call to GetEvents or GetTodos etc. + * @param string $relative_url The URL relative to the base_url specified when the calendar was opened. Default ''. + * + * @return string The iCalendar of the calendar entry + */ + function GetEntryByHref( $href, $relative_url = '' ) { + return $this->DoGETRequest( $relative_url . $href ); + } + +} + +//$cal = new CalDAVClient( "https://www.google.com/calendar/dav/[mail id]/events/", "uid", "pwd", "calendar" ); +//$cal = new CalDAVClient( "http://calendar.datanom.net/caldav.php/[uid]/home", "uid", "pwd", "calendar" ); +//$cal->SetDepth(1); +/*$folder_xml = $cal->DoXMLRequest("PROPFIND", +' + + + + + + + +' );*/ +//print_r($folder_xml); + + +/*$events = $cal->GetEvents("20100616T000000Z", "20100616T235959Z"); +foreach ( $events AS $k => $event ) { + print_r( $event['data'] ); +}*/ + + +/* +print "Debug information\n"; +print "Headers sent:\n".$cal->GetHttpRequest()."\n". + "XML sent:\n".$cal->GetXmlRequest()."\n". + "Headers received:\n".$cal->GetHttpResponse()."\n". + "XML received:\n".$cal->GetXmlResponse()."\n"; + */ \ No newline at end of file diff --git a/caldav/caldavresource.class.php b/caldav/caldavresource.class.php new file mode 100644 index 0000000..4c1214e --- /dev/null +++ b/caldav/caldavresource.class.php @@ -0,0 +1,304 @@ +value = self::VEVENT; break; + case 'VTODO': $this->value = self::VTODO; break; + case 'VJOURNAL': $this->value = self::VJOURNAL; break; + case 'VFREEBUSY': $this->value = self::VFREEBUSY; break; + case 'VTIMEZONE': $this->value = self::VTIMEZONE; break; + case 'VALARM': $this->value = self::VALARM; break; + case self::VEVENT: + case self::VTODO: + case self::VJOURNAL: + case self::VFREEBUSY: + case self::VTIMEZONE: + case self::VALARM: $this->value = $value; break; + default: throw new Exception ("$value: Invalid VTYPE"); + } + } + + private function __clone() {} + + public function ordinal() { + return $this->value; + } + + public function __toString() { + switch ($this->value) { + case self::VEVENT: return 'VEVENT'; break; + case self::VTODO: return 'VTODO'; break; + case self::VJOURNAL: return 'VJOURNAL'; break; + case self::VFREEBUSY: return 'VFREEBUSY'; break; + case self::VTIMEZONE: return 'VTIMEZONE'; break; + case self::VALARM: return 'VALARM'; break; + } + } + + } + + abstract class CaldavRessource + implements ArrayAccess, IteratorAggregate { + + private $client; + + function __construct($url, $uid = '', $pwd = '', $cal = '') { + if (empty($url)) + throw new Exception("Missing URL"); + $this->client = new CalDAVClient($url, $uid, $pwd, $cal); + } + + /** + * abstract functions to be implemented by sub classes + */ + abstract function update($url, $etag = NULL); + abstract function newComponent($c_type); + abstract function getComponents($start, $end); + abstract function delete($url, $etag = NULL); + + protected function callServer($method, $param = array()) { + $error = TRUE; + $msg = "Unknown error"; + + if (! is_array($param)) + throw new Exception("Parameters must be inclosed in an array"); + switch (strtolower($method)) { + case 'getevents': + if (count($param) != 2) { + $error = TRUE; + $msg = "Expected 2 parameters"; + break; + } + if ($this->isDateTime($param[0]) && + $this->isDateTime($param[1])) { + $res = $this->client->GetEvents($param[0], $param[1]); + $error = FALSE; + } + else { + $msg = "[${param[0]},${param[1]}]: Invalid DateTime"; + $error = TRUE; + } + break; + case 'getbyuid': + if (count($param) != 1) { + $error = TRUE; + $msg = "Expected 1 parameter"; + break; + } + $res = $this->client->GetEntryByUid($param[0]); + $error = FALSE; + break; + case 'put': + if (count($param) < 2 || count($param) > 3) { + $error = TRUE; + $msg = "Syntax: URL, CalDAV_resource[, ETag]"; + break; + } + if (count($param) == 2) + $res = $this->client->DoPUTRequest($param[0], $param[1]); + else + $res = $this->client->DoPUTRequest($param[0], $param[1], $param[2]); + $error = FALSE; + break; + case 'delete': + if (count($param) < 1 || count($param) > 2) { + $error = TRUE; + $msg = "Syntax: URL[, ETag]"; + break; + } + if (count($param) == 1) + $res = $this->client->DoDELETERequest($param[0]); + else + $res = $this->client->DoDELETERequest($param[0], $param[1]); + $error = FALSE; + break; + default: + throw new Exception("$method: Unknown method"); + } + if ($error) + throw new Exception($msg); + else + return $res; + } + + static function isDateTime($var) { + return (preg_match("/^([0-9]{8})T([0-9]{6})Z?$/", $var) > 0); + } + + /** + * Returned date-time will always be in UTC + */ + static function timestamp2ICal($ts, $localtime = TRUE) { + $ts = (int) $ts; + if ($ts < 0) + throw new Exception("$ts: invalid timestamp"); + if ($localtime) { + $date = date('Ymd', $ts); + $time = date('His', $ts); + $res = sprintf("%sT%s", $date, $time); + } + else { + $date = gmdate('Ymd', $ts); + $time = gmdate('His', $ts); + $res = sprintf("%sT%sZ", $date, $time); + } + return $res; + } + + static function iCal2Timestamp($ical) { + if (! self::isDateTime($ical)) { + // test for badly formed all-day event + //print "$ical"; + $res = preg_match("/^([0-9]{4})([0-9]{2})([0-9]{2})$/", + $ical, $parts); + if ($res == 0) + throw new Exception("$ical: invalid CalDAV Date-Time"); + else { + $timepart = array('00', '00', '00'); + $parts = array_merge($parts, $timepart); + } + } + else { + $date = "([0-9]{4})([0-9]{2})([0-9]{2})"; + $time = "([0-9]{2})([0-9]{2})([0-9]{2})"; + preg_match("/^${date}T${time}(Z?)$/", $ical, $parts); + } + if (count($parts) == 8 && ! empty($parts[7])) + return gmmktime($parts[4], $parts[5], $parts[6], + $parts[2], $parts[3], $parts[1]); + else + return mktime($parts[4], $parts[5], $parts[6], + $parts[2], $parts[3], $parts[1]); + } + + private static function down_hour($date) { + //print "$date
"; + if (! self::isDateTime($date)) { + // test for badly formed all-day event + $res = preg_match("/^([0-9]{4})([0-9]{2})([0-9]{2})$/", + $date, $parts); + if ($res == 0) + throw new Exception("$date: invalid CalDAV Date-Time"); + else { + array_shift($parts); + $timepart = array('T', '00', '00', '00'); + $parts = array_merge($parts, $timepart); + return implode('', $parts); + } + } + else { + $a = explode('T', $date); + $a[1] = substr_replace($a[1], '0000', 2); + return $a[0].'T'.$a[1]; + } + } + + static function fix_allday_event(&$date_a, &$date_b) { + //print "$date_a : $date_b
"; + if ($date_a == $date_b) { + if (! self::isDateTime($date_a) && ! self::isDateTime($date_b)) { + $res1 = preg_match("/^([0-9]{4})([0-9]{2})([0-9]{2})$/", + $date_a); + $res2 = preg_match("/^([0-9]{4})([0-9]{2})([0-9]{2})$/", + $date_b); + if ($res1 == 0 || $res2 == 0) + throw new Exception("$date_a, $date_b: invalid CalDAV Date-Time"); + else { + $date_a .= "T000000"; + $date_b .= "T235959"; + } + } + else { + preg_match("/^([0-9]{4}[0-9]{2}[0-9]{2})T([0-9]{6})$/", + $date_a, $part_a); + preg_match("/^([0-9]{4}[0-9]{2}[0-9]{2})T([0-9]{6})$/", + $date_b, $part_b); + $date_a = $part_a[1]."T000000"; + $date_b = $part_b[1]."T235959"; + //print "$date_a : $date_b
"; + } + //print "$date_a : $date_b
"; + } + } + + static function datecmp($date_a, $date_b) { + $date_a = self::iCal2Timestamp($date_a); + $date_b = self::iCal2Timestamp(self::down_hour($date_b)); + if ($date_a < $date_b) + $res = -1; + else if ($date_a > $date_b) + $res = 1; + else + $res = 0; + return $res; + } + + private static function intcmpstr($a_str, $b_str) { + $a = (int) $a_str; + $b = (int) $b_str; + //print "$a:$b
"; + if ($a > $b) + return 1; + else if ($a < $b) + return -1; + else + return 0; + } + + static function cmpdate($date_a, $date_b) { + $datepart = explode('T', $date_a); + $d_a = $datepart[0]; + $datepart = explode('T', $date_b); + $d_b = $datepart[0]; + $y_cmp = self::intcmpstr(substr($d_a, 0, 4), substr($d_b, 0, 4)); + if ($y_cmp == 0) { + $m_cmp = self::intcmpstr(substr($d_a, 4, 2), substr($d_b, 4, 2)); + if ($m_cmp == 0) { + return self::intcmpstr(substr($d_a, 6, 2), substr($d_b, 6, 2)); + } + return $m_cmp; + } + return $y_cmp; + } + + static function cmptime($time_a, $time_b) { + $timepart = explode('T', $time_a); + $t_a = $timepart[1]; + $timepart = explode('T', $time_b); + $t_b = $timepart[1]; + //print "$t_a:$t_b
"; + $h_cmp = self::intcmpstr(substr($t_a, 0, 2), substr($t_b, 0, 2)); + if ($h_cmp == 0) { + $m_cmp = self::intcmpstr(substr($t_a, 2, 2), substr($t_b, 2, 2)); + if ($m_cmp == 0) { + return self::intcmpstr(substr($t_a, 4, 2), substr($t_b, 4, 2)); + } + return $m_cmp; + } + return $h_cmp; + } + + static function allDayEvent($time_a, $time_b) { + //echo $time_a.':'.$time_b.'
'; + $a = explode('T', $time_a); + if (count($a) < 2) + array_push($a, '0000'); + $b = explode('T', $time_b); + if (count($b) < 2) + array_push($b, '0000'); + $t = strtotime($time_b) - 3600; + $t = date("Ymd\THm", $t); + return (self::cmpdate($time_a, $t) == 0 && + $a[1] == '0000' && $b[1] == '0000'); + } + } diff --git a/caldav/calendar.class.php b/caldav/calendar.class.php new file mode 100644 index 0000000..7fdbd01 --- /dev/null +++ b/caldav/calendar.class.php @@ -0,0 +1,317 @@ +list = $list; + } + + function current() { + return current($this->list); + } + + function next() { + next($this->list); + } + + function key() { + return key($this->list); + } + + function rewind() { + reset($this->list); + } + + function valid() { + $obj = current($this->list); + return ($obj !== FALSE); + } + + } + + class Calendar extends CaldavRessource { + + private $calendar; + + function __construct($url, $uid = '', $pwd = '', $cal = '') { + //file_put_contents('/tmp/dump', "$url\n$uid\n$pwd\n$cal\n", FILE_APPEND); + if (empty($url)) + throw new Exception("Missing URL"); + parent::__construct($url, $uid, $pwd, $cal); + } + + private function setComponent(VTYPE $type, array $item, $new = FALSE) { + switch ($type) { + case VTYPE::VEVENT: + $ical = new VEvent( + $item['etag'], $item['href'], + $type, $item['ical'], $new); + break; + default: + throw new Exception( + "$thisType: Unsupported iCalendar component"); + } + $this->calendar[$item['etag']] = $ical; + //var_dump($this->calendar[$item['etag']]); + //print "-------------------------------
"; + } + + private function setResource($etag, $resource) { + if ($resource === NULL) + unset($this->calendar[$etag]); + else if (isset($this->calendar[$etag])) + $this->calendar[$etag]->setResource($resource); + else { + $type = new VTYPE($this->getType($resource)); + $this->setComponent($type, array( + 'etag' => $etag, + 'href' => NULL, + 'ical' => $resource), + TRUE + ); + } + } + + private function getType(iCalendar $iCalendar) { + $components = $iCalendar->component->GetComponents(); + // Find VCalender component + foreach($components as $type) { + try { + $vtype = new VTYPE($type->GetType()); + if ($vtype->ordinal() != VTYPE::VTIMEZONE) + break; + } + catch (Exception $ex) {} + } + return $vtype; + } + + private function wrapCalendar($component) { + $cal = "BEGIN:VCALENDAR\r\n"; + $cal .= "PRODID:-//datanom.net//NONSGML WEBCAL Calendar//EN\r\n"; + $cal .= "VERSION:2.0\r\n"; + $cal .= "CALSCALE:GREGORIAN\r\n"; + $cal .= $component; + $cal .= "END:VCALENDAR\r\n"; + + return $cal; + } + + function getComponents($start, $end) { + $this->calendar = array(); + + if (! $this->isDateTime($start) || ! $this->isDateTime($end)) + throw new Exception("[$start:$end]: Invalid DateTime format"); + //print "$start:$end
"; + //file_put_contents('/tmp/dump', "$start, $end\n", FILE_APPEND); + $events = $this->callServer('getEvents', array($start, $end)); + //var_export($events, FALSE); + //file_put_contents('/tmp/dump', var_export($events, TRUE), FILE_APPEND); + foreach ($events as $k => $event) { + $iCalendar = new iCalendar( + array('icalendar' => $event['data'])); + $vtype = $this->getType($iCalendar); + $this->setComponent($vtype, array( + 'etag' => $event['etag'], + 'href' => $event['href'], + 'ical' => $iCalendar + ) + ); + } + } + + function newComponent($c_type) { + switch (strtoupper($c_type)) { + case 'VEVENT': $type = 'VEVENT'; break; + default: + throw new Exception( + "$thisType: Unsupported iCalendar component"); + } + $start = gmdate("Ymd\THm\Z"); + $end = strtotime($start) + (60*60); + $end = gmdate("Ymd\THm\Z", $end); + //echo "$start:$end
"; + $uid = sha1(microtime() . $start . $end); + $iCalendar = new iCalendar(array( + 'type' => $type, + 'DTSTART' => $start, + 'DTEND' => $end, + 'UID' => $uid + ) + ); + $vtype = $this->getType($iCalendar); + $etag = sha1("This is a new component"); + $this->setComponent($vtype, array( + 'etag' => $etag, + 'href' => NULL, + 'ical' => $iCalendar + ) + ); + return $this->calendar[$etag]; + } +/* + function reload($start, $end) { + $res = $this->update(); + if (count($res) < 1) { + $this->getComponents($start, $end); + } + return $res; + } +*/ + private function updateEvent($url, $etag) { + $res = array(); + $resource = $this->calendar[$etag]; + if ($resource && $resource->isDirty()) { + // update (call put) + $component = $resource->getBaseComponent(); + //print "$etag: update\n"; + $uid = $component->GetPValue('UID'); + $ical = $this->wrapCalendar($component->Render()); + //echo "$uid
".nl2br($ical)."$etag
"; + $url = $resource->getUrl(); + if ($url) { + $newEtag = $this->callServer('put', + array("$uid.ics", $ical, $etag)); + } + else { + $newEtag = $this->callServer('put', + array("$uid.ics", $ical)); + } + if (is_array($newEtag)) + array_push($res, $newEtag); + else { + $resource->setEtag($newEtag); + } + } + return $res; + } + + function update($url, $etag = NULL) { + //var_dump($this->calendar); + if (! $etag) { + foreach($this->calendar as $id => $resource) { + //var_dump($resource); + $thisUrl = $resource->getUrl(); + if ($thisUrl && strcasecmp($url, $thisUrl) == 0) { + $etag = $id; + break; + } + } + } + if ($etag) + $res = $this->updateEvent($url, $etag); + else + $res = array($url => 'Event does not exist'); + return $res; + } + + function delete($url, $etag = NULL) { + if ($etag) { + $res = $this->callServer('delete', array($url, $etag)); + } + else { + $res = $this->callServer('delete', array($url)); + } + return $res; + } + + // inherited abstract methods from parent + function offsetExists($etag) { + return (is_object($this->calendar[$etag]) && + $this->calendar[$etag] instanceof IComponent); + } + + function offsetGet($etag) { + if ($this->offsetExists($etag)) + return $this->calendar[$etag]->getResource(); + } + + function offsetSet($etag, $ical) { + $this->setResource($etag, $ical); + } + + function offsetUnset($etag) { + $this->setResource($etag, NULL); + } + + function getIterator() { + return new CalendarIterator($this->calendar); + } + + } +/* +$cal = new Calendar( + 'http://calendar.datanom.net/caldav.php/mir/home/', + 'uid', + 'pwd' +); +$cal->getComponents("20030830T000000Z","20031201T000000Z"); +//print_r($cal); +$i = 0; +foreach($cal as $obj) { + $i++; + print "========= [$i] =========\n"; + //print_r($obj); + //print_r ($obj->getAlarm()); + print_r($obj->getActiveDates("20031014T000000Z","20031114T000000Z")); + //print "{$obj->isUTCTime()}\n"; + //$obj->getActiveDates(); +} +print "Found $i event(s)\n"; + +//print_r ($cal->getUrlByEtag($cal->getEtagFromUid('KOrganizer-1670268771.406'))); +$time = time(); +print "time: $time\n"; +$dt = $cal->timestamp2ICal($time, TRUE); +print "dt: $dt\n"; +$time = $cal->iCal2Timestamp($dt); +print "time: $time\n"; +$dt = $cal->timestamp2ICal($time, FALSE); +print "dt: $dt\n"; +$time = $cal->iCal2Timestamp(substr($dt, 0, strpos($dt, 'T'))); +$dt = $cal->timestamp2ICal($time, TRUE); +print "dt: $dt\n"; +$r = new RRuleParser( + 'FREQ=HOURLY;INTERVAL=3;UNTIL=20070101T170000Z', + '20070101T090000Z', '20070101T090000Z'); +$r = new RRuleParser( + 'FREQ=WEEKLY;COUNT=12;INTERVAL=2', + '20070101T140000Z', '20070101T120000Z'); +print "$r\n"; +print_r($r->getEventDates('20070301T140000Z','20070501T140000Z')); +$r = new RRuleParser( + 'FREQ=MONTHLY;BYDAY=MO,TU,WE,TH,FR;BYSETPOS=-1', + '20070101T000100Z', '20070101T001100Z'); +//DTSTART;TZID=US-Eastern:19970105T083000 +print "$r\n"; +$r = new RRuleParser( + 'FREQ=YEARLY;INTERVAL=2;BYMONTH=1;BYDAY=SU;BYHOUR=8,9;BYMINUTE=30', + '20070101T000100Z', '20070101T001100Z'); +print "$r\n"; +print_r ($r->getEventDates('20060101T000100Z', '20060101T001100Z')); +$r = new RRuleParser( + 'FREQ=DAILY;COUNT=10;INTERVAL=2', + '20070101T000100Z', '20070101T001100Z'); +print "$r\n"; +//foreach ($cal as $obj) +// var_dump($obj->getBaseComponent()); +//$bak = $cal['3ba46312e910765bf7059a53909d149b']; +//print_r($bak); +//print_r(new Icalendar(array('SUMMARY' => 'test'))); +//$cal['3ba46312e910765bf7059a53909d149b'] = new Icalendar(array('SUMMARY' => 'test')); +//print_r($cal['3ba46312e910765bf7059a53909d149b']); +//unset($cal['3ba46312e910765bf7059a53909d149b']); +//var_dump($cal['3ba46312e910765bf7059a53909d149b']); +//$cal['3ba46312e910765bf7059a53909d149b'] = $bak; +//var_dump($cal['3ba46312e910765bf7059a53909d149b']); +//$cal->update(); +//print_r($cal['3ba46312e910765bf7059a53909d149b']);*/ diff --git a/caldav/ical.class.php b/caldav/ical.class.php new file mode 100644 index 0000000..644a629 --- /dev/null +++ b/caldav/ical.class.php @@ -0,0 +1,648 @@ + 'last-modified', + 'xprop' => 'x-prop' + ); + private $changed; + + function __construct($values = array()) { + if (! is_array($values)) + throw new Exception("Attribute to constructor must be an array"); + $this->setProperties($values); + $this->changed = FALSE; + } + + private function setProperties(array $props) { + foreach ($props as $k => $v) { + switch (strtoupper($k)) { + case 'DTSTAMP': + $this->dtstamp = $v; + break; + case 'ORGANIZER': + $this->organizer = $v; + break; + case 'CREATED': + $this->created = $v; + break; + case 'UID': + $this->uid = $v; + break; + case 'SEQUENCE': + $this->sequence = $v; + break; + case 'LAST-MODIFIED': + $this->lastmodified = $v; + break; + case 'SUMMARY': + $this->summary = $v; + break; + case 'CLASS': + $this->class = $v; + break; + case 'PRIORITY': + $this->priority = $v; + break; + case 'RRULE': + $this->rrule = $v; + break; + case 'EXDATE': + $this->exdate = $v; + break; + case 'DTSTART': + $this->dtstart = $v; + break; + case 'DTEND': + $this->dtend = $v; + break; + case 'TRANSP': + $this->transp = $v; + break; + case 'ATTENDEE': + $this->attendee = $v; + break; + case 'DURATION': + $this->duration = $v; + break; + case 'LOCATION': + $this->location = $v; + break; + case 'STATUS': + $this->status = $v; + break; + case 'DESCRIPTION': + $this->description = $v; + break; + default: + if (($k[0] == 'x' || $k[0] == 'X') && $k[1] == '-') + $this->xprop[$k] = $v; + else + throw new Exception("[$k,$v]: Unknown attribute"); + } + } + } + + public function getProperty($name) { + $prop = strtolower($name); + if (($trans = array_search($prop, self::$translate)) !== false) + $prop = $trans; + if (! property_exists($this, $prop)) { + // Support for PHP 5 < 5.3 + $obj = new ReflectionClass(get_class($this)); + if (! $obj->hasProperty($prop)) + throw new Exception("$name: Unknown property"); + } + return $this->$prop; + } + + public function setProperty($name, $value) { + $prop = strtolower($name); + if (($trans = array_search($prop, self::$translate)) !== false) + $prop = $trans; + if (! property_exists($this, $prop)) { + // Support for PHP 5 < 5.3 + $obj = new ReflectionClass(get_class($this)); + if (! $obj->hasProperty($prop)) + throw new Exception("$name: Unknown property"); + } + $this->$prop = $value; + $this->changed = TRUE; + } + + function getAllProperties() { + $props = array(); + $p = get_object_vars($this); + foreach ($p as $k => $v){ + if ($k == 'changed') + continue; + if (array_key_exists($k, self::$translate)) + $k = strtoupper(self::$translate[$k]); + else + $k = strtoupper($k); + $props[$k] = $v; + } + return $props; + } + + function setAllProperties(array $assoc_array) { + $props = array(); + foreach ($assoc_array as $k => $v){ + $k = strtolower($k); + if (is_array($v)) { + foreach ($v as $k1 => $v1) + $props[$k1] = $v1; + } + else + $props[$k] = $v; + } + $this->setProperties($props); + $this->changed = TRUE; + } + + function isChanged() { + return $this->changed; + } + +} + +class VAlarm implements ICalendar { + private $action; + private $description; + private $duration; + private $repeat; + private $trigger; + // Properties must not contain hypens in their name + private static $translate = array(); + private $changed; + + function __construct($values = array()) { + if (! is_array($values)) + throw new Exception("Attribute to constructor must be an array"); + $this->setProperties($values); + $this->changed = FALSE; + } + + private function setProperties(array $props) { + foreach ($props as $k => $v) { + switch (strtoupper($k)) { + case 'ACTION': + $this->action = $v; + break; + case 'DESCRIPTION': + $this->description = $v; + break; + case 'DURATION': + $this->duration = $v; + break; + case 'REPEAT': + $this->repeat = $v; + break; + case 'TRIGGER': + $this->trigger = $v; + break; + default: + throw new Exception("$k: Unknown attribute"); + } + } + } + + public function getProperty($name) { + $prop = strtolower($name); + if (($trans = array_search($prop, self::$translate)) !== false) + $prop = $trans; + if (! property_exists($this, $prop)) { + // Support for PHP 5 < 5.3 + $obj = new ReflectionClass(get_class($this)); + if (! $obj->hasProperty($prop)) + throw new Exception("$name: Unknown property"); + } + return $this->$prop; + } + + public function setProperty($name, $value) { + $prop = strtolower($name); + if (($trans = array_search($prop, self::$translate)) !== false) + $prop = $trans; + if (! property_exists($this, $prop)) { + // Support for PHP 5 < 5.3 + $obj = new ReflectionClass(get_class($this)); + if (! $obj->hasProperty($prop)) + throw new Exception("$name: Unknown property"); + } + $this->$prop = $value; + $this->changed = TRUE; + } + + function getAllProperties() { + $props = array(); + $p = get_object_vars($this); + foreach ($p as $k => $v){ + if ($k == 'changed') + continue; + if (array_key_exists($k, self::$translate)) + $k = strtoupper(self::$translate[$k]); + else + $k = strtoupper($k); + $props[$k] = $v; + } + return $props; + } + + function setAllProperties(array $assoc_array) { + $props = array(); + foreach ($assoc_array as $k => $v){ + $k = strtolower($k); + if (is_array($v)) { + foreach ($v as $k1 => $v1) + $props[$k1] = $v1; + } + else + $props[$k] = $v; + } + $this->setProperties($props); + $this->changed = TRUE; + } + + function isChanged() { + return $this->changed; + } + +} + +class VTimezone implements ICalendar { + + private $tzid; + private $xprop; + private $standard; + private $daylight; + + // Properties must not contain hypens in their name + private static $translate = array(); + private $changed; + + function __construct($values = array()) { + if (! is_array($values)) + throw new Exception("Attribute to constructor must be an array"); + $this->setProperties($values); + $this->changed = FALSE; + } + + private function setProperties(array $props) { + foreach ($props as $k => $v) { + switch (strtoupper($k)) { + case 'TZID': + $this->tzid = $v; + break; + default: + if (($k[0] == 'x' || $k[0] == 'X') && $k[1] == '-') + $this->xprop[$k] = $v; + else + throw new Exception("[$k,$v]: Unknown attribute"); + } + } + } + + function getProperty($name){} + function setProperty($name, $value) { + $prop = strtolower($name); + if (($trans = array_search($prop, self::$translate)) !== false) + $prop = $trans; + if (! property_exists($this, $prop)) { + // Support for PHP 5 < 5.3 + $obj = new ReflectionClass(get_class($this)); + if (! $obj->hasProperty($prop)) + throw new Exception("$name: Unknown property"); + } + $this->$prop = $value; + if ( + $this->$prop == 'standard' && ! isset($this->standard) || + $this->$prop == 'daylight' && ! isset($this->daylight) + ) { + // we are constructing the object + } + else + $this->changed = TRUE; + } + function getAllProperties(){} + function setAllProperties(array $assoc_array){} + function isChanged(){} +} + +class VCalendar { + private $calscale; + private $prodid; + private $version; + private $objects; + + function __construct($values = array()) { + if (! is_array($values)) + throw new Exception("Attribute to constructor must be an array"); + $this->objects = array(); + //print_r($values); + foreach ($values as $k => $v) { + switch (strtoupper($k)) { + case 'CALSCALE': + $this->calscale = $v; + break; + case 'PRODID': + $this->prodid = $v; + break; + case 'VERSION': + $this->version = $v; + break; + default: + throw new Exception("$k: Unknown attribute"); + } + } + } + + public function addObject(ICalendar $object) { + $this->objects[get_class($object)] = $object; + } + + public function getObject($name) { + if (isset($this->objects[$name])) + return $this->objects[$name]; + else + return null; + } + + public function getObjects() { + return $this->objects; + } + +} + +class IcalParserIterator implements Iterator { + private $icalParser; + private $pos; + + function __construct(IcalParser $icalParser) { + if (! $icalParser instanceof IcalParser) + throw new Exception(get_class($icalParser) . ': Can only handle instances of class IcalParser'); + $this->icalParser = $icalParser; + $this->pos = 0; + } + + public function current() { + return $this->icalParser->getIcal($this->pos); + } + + public function key() { + return $this->pos; + } + + public function next() { + $this->pos++; + } + + public function rewind() { + $this->pos = 0; + } + + public function valid() { + return $this->icalParser->peek($this->pos); + } + +} + +class IcalParser implements IteratorAggregate { +// private $elements = array('VCALENDAR', 'VEVENT', 'VALARM', 'VTIMEZONE'); +// private $subelem = array('VTIMEZONE' => array('STANDARD', 'DAYLIGHT')); + private $items; + + function __construct($message = NULL) { + $this->items = array(); + if ($message) + $this->setMessage($message); + } + + function setMessage($message) { + $this->split_message($message); + } + + private function remove_value(array &$array, $key) { + $tmp = array(); + $val; + + foreach ($array as $k => $v) { + if ($k == $key) + $val = $v; + else + $tmp[$k] = $v; + } + $array = $tmp; + return $val; + } + + private function newObject($name, $props = array()) { + try { + $obj = new ReflectionClass($name); + } + catch (ReflectionException $ex) { + print $ex->getMessage(); + throw new Exception("$name: Class not found"); + } + $obj = NULL; + return new $name($props); + } + + private function split_message($message) { + $data = null; + $elem_data = array(); + $data_list = array(); + $elem_list = array(); + + if (empty($message)) + return; + //print "$message\n"; + $lines = explode("\n", $message); + foreach ($lines as $line) { + $a = explode(":", $line); + //print_r($a); + $item = strtoupper($a[0]); + if (count($a) > 2) { + $elem = ''; + for ($i = 1; $i < count($a); $i++) { + if ($elem != '') + $elem .= ':'; + $elem .= $a[$i]; + } + //print "elem: $elem\n"; + } + else + $elem = $a[1]; + switch ($item) { + case 'BEGIN': + /*if (! in_array($elem, $this->elements)) { + $found = TRUE; + if (($sub = end($elem_list)) !== FALSE) { + if (! array_key_exists($sub, $this->subelem)) + $found = FALSE; + } + else + $found = FALSE; + reset($elem_list); + if (! $found) + break; + }*/ + if (count($data) > 0) { + if (count($elem_list) > 0) { + /*$name = array_pop($elem_list); + if (array_key_exists($name, $this->subelem)) { + print "BEGIN: $name\n"; + print_r($data); + }*/ + $elem_data[array_pop($elem_list)] = $data; + } + else + $elem_data[$elem] = $data; + } + array_push($elem_list, $elem); + $data = array(); + break; + case 'END': + if (count($elem_list) > 0) { + /*$name = array_pop($elem_list); + if (array_key_exists($name, $this->subelem)) { + print "END: $name\n"; + print_r($data); + }*/ + $elem_data[array_pop($elem_list)] = $data; + } + $data = array(); + if ($elem == 'VCALENDAR' && count($elem_data) > 1) { + array_push($data_list, $elem_data); + $elem_data = array(); + $elem_list = array(); + } + break; + default: + if (! is_array($data)) + throw new Exception("Message is not valid [missing 'BEGIN']"); + if (($pos = strpos($item, ';')) !== false) { + $head = substr($item, 0, $pos); + $elem = substr($item, $pos + 1) . ';' . $elem; + $item = $head; + //print "Ny elem: $item:$elem\n"; + } + $data[$item] = $elem; + } + } + //print_r($data_list); + foreach ($data_list as $item) { + $c = $this->remove_value($item, 'VCALENDAR'); + $calendar = new VCalendar($c); + foreach ($item as $k => $v) { + if ($k == 'DAYLIGHT' || $k == 'STANDARD') { + $object = $calendar->getObject('VTimezone'); + if (! is_object($object)) { + $object = $this->newObject('VTimezone'); + $calendar->addObject($object); + } + $object->setProperty($k, $v); + } + else { + if (($object = $calendar->getObject($k)) == NULL) { + $object = $this->newObject($k, $v); + $calendar->addObject($object); + } + else { + $object->setAllProperties($v); + } + } + } + array_push($this->items, $calendar); + } + } + + public function getIterator() { + return new IcalParserIterator($this); + } + + public function getIcal($id) { + if ($this->peek($id)) + return $this->items[$id]; + else + throw new Exception("Index out of bounds"); + } + + public function peek($id) { + return isset($this->items[$id]); + } + +} + +?> diff --git a/caldav/icomponent.class.php b/caldav/icomponent.class.php new file mode 100644 index 0000000..ff7eefb --- /dev/null +++ b/caldav/icomponent.class.php @@ -0,0 +1,147 @@ +etag = $etag; + $this->url = $url; + $this->component = $component; + $this->type = $type; + $this->dirty = $new; + } + + public function isDirty() { + return $this->dirty; + } + + public function setDirty() { + $this->dirty = TRUE; + } + + public function getResource() { + return $this->component; + } + + public function setResource(iCalendar $component) { + $this->component = $component; + $this->dirty = TRUE; + } + + public function getBaseComponent() { + return $this->getComponent($this->type); + } + + public function getUrl() { + return $this->url; + } + + public function getEtag() { + return $this->etag; + } + + public function setEtag($etag) { + $this->etag = $etag; + } + + public function getComponent($type) { + $ref = $this->component; + //print_r($ref); + + if ($this->component === NULL) + $ical = NULL; + else if ($type instanceof VTYPE && $type->ordinal() == VTYPE::VTIMEZONE) { + $ical = $ref->component->GetComponents('VTIMEZONE'); + } + else { + //$theType = sprintf("%s", $this->type); + //print "self: $theType\n"; + $component = $ref->component->GetComponents($this->type); + //print_r($component); + if (! $type instanceof VTYPE) + $type = new VTYPE($type); + //$theType = sprintf("%s", $type); + //print "instance: $theType\n"; + if (count($component) > 0) + $ical = $component[0]; + if ($type->ordinal() != $this->type->ordinal() && $ical) { + $ical = $ical->GetComponents($type); + } + } + return $ical; + } + + public function isUTCTime() { + $event = $this->getBaseComponent(); + $start = $event->GetPValue('DTSTART'); + $end = $event->GetPValue('DTEND'); + + if (! ($start && $end)) + throw new Exception("Not a valid iCal component"); + return ($start[strlen($start) - 1] == 'Z' || + $nd[strlen($end) - 1] == 'Z'); + } + + public function getDetails() { + $event = $this->getBaseComponent(); + $start = strtotime($event->GetPValue('DTSTART')); + $start = date("Y-m-d H:m", $start); + $end = strtotime($event->GetPValue('DTEND')); + $end = date("Y-m-d H:m", $end); + $title = $event->GetPValue('SUMMARY'); + + return "$start-$end: $title"; + } + + public function getTZID() { + $res = 'UTC'; + + if (! $this->isUTCTime()) { + $timezone = $this->getTimeZone(); + if ($timezone) { + $res = $timezone->GetPValue('TZID'); + } + // timezone not given assume TZID = server's timezone + // servers default timezone is UTC + } + return $res; + } + + function getTimeZone() { + $timezone = $this->getComponent(VTYPE::VTIMEZONE); + if ($timezone) + $timezone = $timezone[0]; + return $timezone; + } + + public function __toString() { + return $this->type->__toString(); + } + + /** + * The following functions should be overloaded in + * the child classes if the have specific functionality + */ + + function isActive($start, $end) { + return FALSE; + } + + function getActiveDates() { + return array(); + } + + function getAlarm() { + return NULL; + } + + } diff --git a/caldav/rfc2445.html b/caldav/rfc2445.html new file mode 100644 index 0000000..26a54b7 --- /dev/null +++ b/caldav/rfc2445.html @@ -0,0 +1,8411 @@ + + + + + + + + + + RFC 2445 - Internet Calendaring and Scheduling Core Object Specification (iCalendar) + + + + + +
+
+ +
+[RFCs/IDs] [Plain] [From draft-ietf-calsch-ical]
+
+ PROPOSED STANDARD
+ Errata
+
Network Working Group                                         F. Dawson
+Request for Comments: 2445                                        Lotus
+Category: Standards Track                                  D. Stenerson
+                                                              Microsoft
+                                                          November 1998
+
+
+     

Internet Calendaring and Scheduling Core Object Specification

+

(iCalendar)

+ +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 + + There is a clear need to provide and deploy interoperable calendaring + and scheduling services for the Internet. Current group scheduling + and Personal Information Management (PIM) products are being extended + for use across the Internet, today, in proprietary ways. This memo + has been defined to provide the definition of a common format for + openly exchanging calendaring and scheduling information across the + Internet. + + This memo is formatted as a registration for a MIME media type per + [RFC 2048]. However, the format in this memo is equally applicable + for use outside of a MIME message content type. + + The proposed media type value is 'text/calendar'. This string would + label a media type containing calendaring and scheduling information + encoded as text characters formatted in a manner outlined below. + + This MIME media type provides a standard content type for capturing + calendar event, to-do and journal entry information. It also can be + used to convey free/busy time information. The content type is + suitable as a MIME message entity that can be transferred over MIME + based email systems, using HTTP or some other Internet transport. In + + + + + + +Dawson & Stenerson Standards Track [Page 1] +

+RFC 2445                       iCalendar                   November 1998
+
+
+   addition, the content type is useful as an object for interactions
+   between desktop applications using the operating system clipboard,
+   drag/drop or file systems capabilities.
+
+   This memo is based on the earlier work of the vCalendar specification
+   for the exchange of personal calendaring and scheduling information.
+   In order to avoid confusion with this referenced work, this memo is
+   to be known as the iCalendar specification.
+
+   This memo defines the format for specifying iCalendar object methods.
+   An iCalendar object method is a set of usage constraints for the
+   iCalendar object. For example, these methods might define scheduling
+   messages that request an event be scheduled, reply to an event
+   request, send a cancellation notice for an event, modify or replace
+   the definition of an event, provide a counter proposal for an
+   original event request, delegate an event request to another
+   individual, request free or busy time, reply to a free or busy time
+   request, or provide similar scheduling messages for a to-do or
+   journal entry calendar component. The iCalendar Transport-indendent
+   Interoperability Protocol (iTIP) defined in [ITIP] is one such
+   scheduling protocol.
+
+Table of Contents
+
+   1 Introduction.....................................................5
+   2 Basic Grammar and Conventions....................................6
+    2.1 Formatting Conventions .......................................7
+    2.2 Related Memos ................................................8
+    2.3 International Considerations .................................8
+   3 Registration Information.........................................8
+    3.1 Content Type .................................................8
+    3.2 Parameters ...................................................9
+    3.3 Content Header Fields .......................................10
+    3.4 Encoding Considerations .....................................10
+    3.5 Security Considerations .....................................10
+    3.6 Interoperability Considerations .............................11
+    3.7 Applications Which Use This Media Type ......................11
+    3.8 Additional Information ......................................11
+    3.9 Magic Numbers ...............................................11
+    3.10 File Extensions ............................................11
+    3.11 Contact for Further Information: ...........................12
+    3.12 Intended Usage .............................................12
+    3.13 Authors/Change Controllers .................................12
+   4 iCalendar Object Specification..................................13
+    4.1 Content Lines ...............................................13
+     4.1.1 List and Field Separators ................................16
+     4.1.2 Multiple Values ..........................................16
+     4.1.3 Binary Content ...........................................16
+
+
+
+Dawson & Stenerson          Standards Track                     [Page 2]
+

+RFC 2445                       iCalendar                   November 1998
+
+
+     4.1.4 Character Set ............................................17
+    4.2 Property Parameters .........................................17
+     4.2.1 Alternate Text Representation ............................18
+     4.2.2 Common Name ..............................................19
+     4.2.3 Calendar User Type .......................................20
+     4.2.4 Delegators ...............................................20
+     4.2.5 Delegatees ...............................................21
+     4.2.6 Directory Entry Reference ................................21
+     4.2.7 Inline Encoding ..........................................22
+     4.2.8 Format Type ..............................................23
+     4.2.9 Free/Busy Time Type ......................................23
+     4.2.10 Language ................................................24
+     4.2.11 Group or List Membership ................................25
+     4.2.12 Participation Status ....................................25
+     4.2.13 Recurrence Identifier Range .............................27
+     4.2.14 Alarm Trigger Relationship ..............................27
+     4.2.15 Relationship Type .......................................28
+     4.2.16 Participation Role ......................................29
+     4.2.17 RSVP Expectation ........................................29
+     4.2.18 Sent By .................................................30
+     4.2.19 Time Zone Identifier ....................................30
+     4.2.20 Value Data Types ........................................32
+    4.3 Property Value Data Types ...................................32
+     4.3.1 Binary ...................................................33
+     4.3.2 Boolean ..................................................33
+     4.3.3 Calendar User Address ....................................34
+     4.3.4 Date .....................................................34
+     4.3.5 Date-Time ................................................35
+     4.3.6 Duration .................................................37
+     4.3.7 Float ....................................................38
+     4.3.8 Integer ..................................................38
+     4.3.9 Period of Time ...........................................39
+     4.3.10 Recurrence Rule .........................................40
+     4.3.11 Text ....................................................45
+     4.3.12 Time ....................................................47
+     4.3.13 URI .....................................................49
+     4.3.14 UTC Offset ..............................................49
+    4.4 iCalendar Object ............................................50
+    4.5 Property ....................................................51
+    4.6 Calendar Components .........................................51
+     4.6.1 Event Component ..........................................52
+     4.6.2 To-do Component ..........................................55
+     4.6.3 Journal Component ........................................56
+     4.6.4 Free/Busy Component ......................................58
+     4.6.5 Time Zone Component ......................................60
+     4.6.6 Alarm Component ..........................................67
+    4.7 Calendar Properties .........................................73
+     4.7.1 Calendar Scale ...........................................73
+
+
+
+Dawson & Stenerson          Standards Track                     [Page 3]
+

+RFC 2445                       iCalendar                   November 1998
+
+
+     4.7.2 Method ...................................................74
+     4.7.3 Product Identifier .......................................75
+     4.7.4 Version ..................................................76
+    4.8 Component Properties ........................................77
+     4.8.1 Descriptive Component Properties .........................77
+       4.8.1.1 Attachment ...........................................77
+       4.8.1.2 Categories ...........................................78
+       4.8.1.3 Classification .......................................79
+       4.8.1.4 Comment ..............................................80
+       4.8.1.5 Description ..........................................81
+       4.8.1.6 Geographic Position ..................................82
+       4.8.1.7 Location .............................................84
+       4.8.1.8 Percent Complete .....................................85
+       4.8.1.9 Priority .............................................85
+       4.8.1.10 Resources ...........................................87
+       4.8.1.11 Status ..............................................88
+       4.8.1.12 Summary .............................................89
+     4.8.2 Date and Time Component Properties .......................90
+       4.8.2.1 Date/Time Completed ..................................90
+       4.8.2.2 Date/Time End ........................................91
+       4.8.2.3 Date/Time Due ........................................92
+       4.8.2.4 Date/Time Start ......................................93
+       4.8.2.5 Duration .............................................94
+       4.8.2.6 Free/Busy Time .......................................95
+       4.8.2.7 Time Transparency ....................................96
+     4.8.3 Time Zone Component Properties ...........................97
+       4.8.3.1 Time Zone Identifier .................................97
+       4.8.3.2 Time Zone Name .......................................98
+       4.8.3.3 Time Zone Offset From ................................99
+       4.8.3.4 Time Zone Offset To .................................100
+       4.8.3.5 Time Zone URL .......................................101
+     4.8.4 Relationship Component Properties .......................102
+       4.8.4.1 Attendee ............................................102
+       4.8.4.2 Contact .............................................104
+       4.8.4.3 Organizer ...........................................106
+       4.8.4.4 Recurrence ID .......................................107
+       4.8.4.5 Related To ..........................................109
+       4.8.4.6 Uniform Resource Locator ............................110
+       4.8.4.7 Unique Identifier ...................................111
+     4.8.5 Recurrence Component Properties .........................112
+       4.8.5.1 Exception Date/Times ................................112
+       4.8.5.2 Exception Rule ......................................114
+       4.8.5.3 Recurrence Date/Times ...............................115
+       4.8.5.4 Recurrence Rule .....................................117
+     4.8.6 Alarm Component Properties ..............................126
+       4.8.6.1 Action ..............................................126
+       4.8.6.2 Repeat Count ........................................126
+       4.8.6.3 Trigger .............................................127
+
+
+
+Dawson & Stenerson          Standards Track                     [Page 4]
+

+RFC 2445                       iCalendar                   November 1998
+
+
+     4.8.7 Change Management Component Properties ..................129
+       4.8.7.1 Date/Time Created ...................................129
+       4.8.7.2 Date/Time Stamp .....................................130
+       4.8.7.3 Last Modified .......................................131
+       4.8.7.4 Sequence Number .....................................131
+     4.8.8 Miscellaneous Component Properties ......................133
+       4.8.8.1 Non-standard Properties .............................133
+       4.8.8.2 Request Status ......................................134
+   5 iCalendar Object Examples......................................136
+   6 Recommended Practices..........................................140
+   7 Registration of Content Type Elements..........................141
+    7.1 Registration of New and Modified iCalendar Object Methods ..141
+    7.2 Registration of New Properties .............................141
+     7.2.1 Define the property .....................................142
+     7.2.2 Post the Property definition ............................143
+     7.2.3 Allow a comment period ..................................143
+     7.2.4 Submit the property for approval ........................143
+    7.3 Property Change Control ....................................143
+   8 References.....................................................144
+   9 Acknowledgments................................................145
+   10 Authors' and Chairs' Addresses................................146
+   11 Full Copyright Statement......................................148
+
+

1 Introduction

+ + The use of calendaring and scheduling has grown considerably in the + last decade. Enterprise and inter-enterprise business has become + dependent on rapid scheduling of events and actions using this + information technology. However, the longer term growth of + calendaring and scheduling, is currently limited by the lack of + Internet standards for the message content types that are central to + these knowledgeware applications. This memo is intended to progress + the level of interoperability possible between dissimilar calendaring + and scheduling applications. This memo defines a MIME content type + for exchanging electronic calendaring and scheduling information. The + Internet Calendaring and Scheduling Core Object Specification, or + iCalendar, allows for the capture and exchange of information + normally stored within a calendaring and scheduling application; such + as a Personal Information Manager (PIM) or a Group Scheduling + product. + + The iCalendar format is suitable as an exchange format between + applications or systems. The format is defined in terms of a MIME + content type. This will enable the object to be exchanged using + several transports, including but not limited to SMTP, HTTP, a file + system, desktop interactive protocols such as the use of a memory- + based clipboard or drag/drop interactions, point-to-point + asynchronous communication, wired-network transport, or some form of + + + +Dawson & Stenerson Standards Track [Page 5] +

+RFC 2445                       iCalendar                   November 1998
+
+
+   unwired transport such as infrared might also be used.
+
+   The memo also provides for the definition of iCalendar object methods
+   that will map this content type to a set of messages for supporting
+   calendaring and scheduling operations such as requesting, replying
+   to, modifying, and canceling meetings or appointments, to-dos and
+   journal entries. The iCalendar object methods can be used to define
+   other calendaring and scheduling operations such a requesting for and
+   replying with free/busy time data. Such a scheduling protocol is
+   defined in the iCalendar Transport-independent Interoperability
+   Protocol (iTIP) defined in [ITIP].
+
+   The memo also includes a formal grammar for the content type based on
+   the Internet ABNF defined in [RFC 2234]. This ABNF is required for
+   the implementation of parsers and to serve as the definitive
+   reference when ambiguities or questions arise in interpreting the
+   descriptive prose definition of the memo.
+
+

2 Basic Grammar and Conventions

+ + The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", + "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY" and + "OPTIONAL" in this document are to be interoperated as described in + [RFC 2119]. + + This memo makes use of both a descriptive prose and a more formal + notation for defining the calendaring and scheduling format. + + The notation used in this memo is the ABNF notation of [RFC 2234]. + Readers intending on implementing this format defined in this memo + should be familiar with this notation in order to properly interpret + the specifications of this memo. + + All numeric and hexadecimal values used in this memo are given in + decimal notation. + + All names of properties, property parameters, enumerated property + values and property parameter values are case-insensitive. However, + all other property values are case-sensitive, unless otherwise + stated. + + Note: All indented editorial notes, such as this one, are + intended to provide the reader with additional information. The + information is not essential to the building of an + implementation conformant with this memo. The information is + provided to highlight a particular feature or characteristic of + the memo. + + + + +Dawson & Stenerson Standards Track [Page 6] +

+RFC 2445                       iCalendar                   November 1998
+
+
+   The format for the iCalendar object is based on the syntax of the
+   [RFC 2425] content type. While the iCalendar object is not a profile
+   of the [RFC 2425] content type, it does reuse a number of the
+   elements from the [RFC 2425] specification.
+
+

2.1 Formatting Conventions

+ + The mechanisms defined in this memo are defined in prose. Many of the + terms used to describe these have common usage that is different than + the standards usage of this memo. In order to reference within this + memo elements of the calendaring and scheduling model, core object + (this memo) or interoperability protocol [ITIP] some formatting + conventions have been used. Calendaring and scheduling roles are + referred to in quoted-strings of text with the first character of + each word in upper case. For example, "Organizer" refers to a role of + a "Calendar User" within the scheduling protocol defined by [ITIP]. + Calendar components defined by this memo are referred to with + capitalized, quoted-strings of text. All calendar components start + with the letter "V". For example, "VEVENT" refers to the event + calendar component, "VTODO" refers to the to-do calendar component + and "VJOURNAL" refers to the daily journal calendar component. + Scheduling methods defined by [ITIP] are referred to with + capitalized, quoted-strings of text. For example, "REQUEST" refers to + the method for requesting a scheduling calendar component be created + or modified, "REPLY" refers to the method a recipient of a request + uses to update their status with the "Organizer" of the calendar + component. + + The properties defined by this memo are referred to with capitalized, + quoted-strings of text, followed by the word "property". For example, + "ATTENDEE" property refers to the iCalendar property used to convey + the calendar address of a calendar user. Property parameters defined + by this memo are referred to with lowercase, quoted-strings of text, + followed by the word "parameter". For example, "value" parameter + refers to the iCalendar property parameter used to override the + default data type for a property value. Enumerated values defined by + this memo are referred to with capitalized text, either alone or + followed by the word "value". For example, the "MINUTELY" value can + be used with the "FREQ" component of the "RECUR" data type to specify + repeating components based on an interval of one minute or more. + + + + + + + + + + + +Dawson & Stenerson Standards Track [Page 7] +

+RFC 2445                       iCalendar                   November 1998
+
+
+

2.2 Related Memos

+ + Implementers will need to be familiar with several other memos that, + along with this memo, form a framework for Internet calendaring and + scheduling standards. This memo, [ICAL], specifies a core + specification of objects, data types, properties and property + parameters. + + [ITIP] - specifies an interoperability protocol for scheduling + between different implementations; + + [IMIP] specifies an Internet email binding for [ITIP]. + + This memo does not attempt to repeat the specification of concepts or + definitions from these other memos. Where possible, references are + made to the memo that provides for the specification of these + concepts or definitions. + +

2.3 International Considerations

+ + In the rest of this document, descriptions of characters are of the + form "character name (codepoint)", where "codepoint" is from the US- + ASCII character set. The "character name" is the authoritative + description; (codepoint) is a reference to that character in US-ASCII + or US-ASCII compatible sets (for example the ISO-8859-x family, UTF- + 8, ISO-2022-xx, KOI8-R). If a non-US-ASCII compatible character set + is used, appropriate code-point from that character set MUST be + chosen instead. Use of non-US-ASCII-compatible character sets is NOT + recommended. + +

3 Registration Information

+ + The Calendaring and Scheduling Core Object Specification is intended + for use as a MIME content type. However, the implementation of the + memo is in no way limited solely as a MIME content type. + +

3.1 Content Type

+ + The following text is intended to register this memo as the MIME + content type "text/calendar". + + To: ietf-types@uninett.no + + Subject: Registration of MIME content type text/calendar. + + MIME media type name: text + + MIME subtype name: calendar + + + +Dawson & Stenerson Standards Track [Page 8] +

+RFC 2445                       iCalendar                   November 1998
+
+
+

3.2 Parameters

+ + Required parameters: none + + Optional parameters: charset, method, component and optinfo + + The "charset" parameter is defined in [RFC 2046] for other body + parts. It is used to identify the default character set used within + the body part. + + The "method" parameter is used to convey the iCalendar object method + or transaction semantics for the calendaring and scheduling + information. It also is an identifier for the restricted set of + properties and values that the iCalendar object consists of. The + parameter is to be used as a guide for applications interpreting the + information contained within the body part. It SHOULD NOT be used to + exclude or require particular pieces of information unless the + identified method definition specifically calls for this behavior. + Unless specifically forbidden by a particular method definition, a + text/calendar content type can contain any set of properties + permitted by the Calendaring and Scheduling Core Object + Specification. The "method" parameter MUST be the same value as that + specified in the "METHOD" component property in the iCalendar object. + If one is present, the other MUST also be present. + + The value for the "method" parameter is defined as follows: + + method = 1*(ALPHA / DIGIT / "-") + ; IANA registered iCalendar object method + + The "component" parameter conveys the type of iCalendar calendar + component within the body part. If the iCalendar object contains more + than one calendar component type, then multiple component parameters + MUST be specified. + + The value for the "component" parameter is defined as follows: + + component = ("VEVENT" / "VTODO" / "VJOURNAL" / "VFREEBUSY" + / "VTIMEZONE" / x-name / iana-token) + + The "optinfo" parameter conveys optional information about the + iCalendar object within the body part. This parameter can only + specify semantics already specified by the iCalendar object and that + can be otherwise determined by parsing the body part. In addition, + the optional information specified by this parameter MUST be + consistent with that information specified by the iCalendar object. + For example, it can be used to convey the "Attendee" response status + to a meeting request. The parameter value consists of a string value. + + + +Dawson & Stenerson Standards Track [Page 9] +

+RFC 2445                       iCalendar                   November 1998
+
+
+   The parameter can be specified multiple times.
+
+   This parameter MAY only specify semantics already specified by the
+   iCalendar object and that can be otherwise determined by parsing the
+   body part.
+
+   The value for the "optinfo" parameter is defined as follows:
+
+        optinfo = infovalue / qinfovalue
+
+        infovalue       = iana-token / x-name
+
+        qinfovalue      = DQUOTE (infovalue) DQUOTE
+
+

3.3 Content Header Fields

+ + Optional content header fields: Any header fields defined by [RFC + 2045]. + +

3.4 Encoding Considerations

+ + This MIME content type can contain 8bit characters, so the use of + quoted-printable or BASE64 MIME content-transfer-encodings might be + necessary when iCalendar objects are transferred across protocols + restricted to the 7bit repertoire. Note that a text valued property + in the content entity can also have content encoding of special + characters using a BACKSLASH character (US-ASCII decimal 92) + escapement technique. This means that content values can end up + encoded twice. + +

3.5 Security Considerations

+ + SPOOFING - - In this memo, the "Organizer" is the only person + authorized to make changes to an existing "VEVENT", "VTODO", + "VJOURNAL" calendar component and redistribute the updates to the + "Attendees". An iCalendar object that maliciously changes or cancels + an existing "VEVENT", "VTODO" or "VJOURNAL" or "VFREEBUSY" calendar + component might be constructed by someone other than the "Organizer" + and sent to the "Attendees". In addition in this memo, other than the + "Organizer", an "Attendee" of a "VEVENT", "VTODO", "VJOURNAL" + calendar component is the only other person authorized to update any + parameter associated with their "ATTENDEE" property and send it to + the "Organizer". An iCalendar object that maliciously changes the + "ATTENDEE" parameters can be constructed by someone other than the + real "Attendee" and sent to the "Organizer". + + + + + + +Dawson & Stenerson Standards Track [Page 10] +

+RFC 2445                       iCalendar                   November 1998
+
+
+   PROCEDURAL ALARMS - - An iCalendar object can be created that
+   contains a "VEVENT" and "VTODO" calendar component with "VALARM"
+   calendar components. The "VALARM" calendar component can be of type
+   PROCEDURE and can have an attachment containing some sort of
+   executable program. Implementations that incorporate these types of
+   alarms are subject to any virus or malicious attack that might occur
+   as a result of executing the attachment.
+
+   ATTACHMENTS - - An iCalendar object can include references to Uniform
+   Resource Locators that can be programmed resources.
+
+   Implementers and users of this memo should be aware of the network
+   security implications of accepting and parsing such information. In
+   addition, the security considerations observed by implementations of
+   electronic mail systems should be followed for this memo.
+
+

3.6 Interoperability Considerations

+ + This MIME content type is intended to define a common format for + conveying calendaring and scheduling information between different + systems. It is heavily based on the earlier [VCAL] industry + specification. + +

3.7 Applications Which Use This Media Type

+ + This content-type is designed for widespread use by Internet + calendaring and scheduling applications. In addition, applications in + the workflow and document management area might find this content- + type applicable. The [ITIP] and [IMIP] Internet protocols directly + use this content-type also. Future work on an Internet calendar + access protocol will utilize this content-type too. + +

3.8 Additional Information

+ + This memo defines this content-type. + +

3.9 Magic Numbers

+ + None. + +

3.10 File Extensions

+ + The file extension of "ics" is to be used to designate a file + containing (an arbitrary set of) calendaring and scheduling + information consistent with this MIME content type. + + + + + + +Dawson & Stenerson Standards Track [Page 11] +

+RFC 2445                       iCalendar                   November 1998
+
+
+   The file extension of "ifb" is to be used to designate a file
+   containing free or busy time information consistent with this MIME
+   content type.
+
+   Macintosh file type codes: The file type code of "iCal" is to be used
+   in Apple MacIntosh operating system environments to designate a file
+   containing calendaring and scheduling information consistent with
+   this MIME media type.
+
+   The file type code of "iFBf" is to be used in Apple MacIntosh
+   operating system environments to designate a file containing free or
+   busy time information consistent with this MIME media type.
+
+

3.11 Contact for Further Information:

+ + Frank Dawson + 6544 Battleford Drive + Raleigh, NC 27613-3502 + 919-676-9515 (Telephone) + 919-676-9564 (Data/Facsimile) + Frank_Dawson@Lotus.com (Internet Mail) + + Derik Stenerson + One Microsoft Way + Redmond, WA 98052-6399 + 425-936-5522 (Telephone) + 425-936-7329 (Facsimile) + deriks@microsoft.com (Internet Mail) + +

3.12 Intended Usage

+ + COMMON + +

3.13 Authors/Change Controllers

+ + Frank Dawson + 6544 Battleford Drive + Raleigh, NC 27613-3502 + 919-676-9515 (Telephone) + 919-676-9564 (Data/Facsimile) + Frank_Dawson@Lotus.com (Internet Mail) + + Derik Stenerson + One Microsoft Way + Redmond, WA 98052-6399 + 425-936-5522 (Telephone) + 425-936-7329 (Facsimile) + deriks@microsoft.com (Internet Mail) + + + +Dawson & Stenerson Standards Track [Page 12] +

+RFC 2445                       iCalendar                   November 1998
+
+
+

4 iCalendar Object Specification

+ + The following sections define the details of a Calendaring and + Scheduling Core Object Specification. This information is intended to + be an integral part of the MIME content type registration. In + addition, this information can be used independent of such content + registration. In particular, this memo has direct applicability for + use as a calendaring and scheduling exchange format in file-, memory- + or network-based transport mechanisms. + +

4.1 Content Lines

+ + The iCalendar object is organized into individual lines of text, + called content lines. Content lines are delimited by a line break, + which is a CRLF sequence (US-ASCII decimal 13, followed by US-ASCII + decimal 10). + + Lines of text SHOULD NOT be longer than 75 octets, excluding the line + break. Long content lines SHOULD be split into a multiple line + representations using a line "folding" technique. That is, a long + line can be split between any two characters by inserting a CRLF + immediately followed by a single linear white space character (i.e., + SPACE, US-ASCII decimal 32 or HTAB, US-ASCII decimal 9). Any sequence + of CRLF followed immediately by a single linear white space character + is ignored (i.e., 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: + + DESCRIPTION:This is a lo + ng description + that exists on a long line. + + The process of moving from this folded multiple line representation + to its single line representation is called "unfolding". Unfolding is + accomplished by removing the CRLF character and the linear white + space character that immediately follows. + + 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 octets SHOULD be folded + according to the folding procedure described above. + + + + + + +Dawson & Stenerson Standards Track [Page 13] +

+RFC 2445                       iCalendar                   November 1998
+
+
+   The content information associated with an iCalendar object is
+   formatted using a syntax similar to that defined by [RFC 2425]. That
+   is, the content information consists of CRLF-separated content lines.
+
+   The following notation defines the lines of content in an iCalendar
+   object:
+
+     contentline        = name *(";" param ) ":" value CRLF
+        ; This ABNF is just a general definition for an initial parsing
+        ; of the content line into its property name, parameter list,
+        ; and value string
+
+     ; 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 octets SHOULD be folded according to
+        ; the folding procedure described above.
+
+     name               = x-name / iana-token
+
+     iana-token = 1*(ALPHA / DIGIT / "-")
+     ; iCalendar identifier registered with IANA
+
+     x-name             = "X-" [vendorid "-"] 1*(ALPHA / DIGIT / "-")
+     ; Reservered for experimental use. Not intended for use in
+     ; released products.
+
+     vendorid   = 3*(ALPHA / DIGIT)     ;Vendor identification
+
+     param              = param-name "=" param-value
+                          *("," param-value)
+        ; Each property defines the specific ABNF for the parameters
+        ; allowed on the property. Refer to specific properties for
+        ; precise parameter ABNF.
+
+     param-name = iana-token / x-token
+
+     param-value        = paramtext / quoted-string
+
+     paramtext  = *SAFE-CHAR
+
+     value      = *VALUE-CHAR
+
+     quoted-string      = DQUOTE *QSAFE-CHAR DQUOTE
+
+     NON-US-ASCII       = %x80-F8
+     ; Use restricted by charset parameter
+     ; on outer MIME object (UTF-8 preferred)
+
+
+
+Dawson & Stenerson          Standards Track                    [Page 14]
+

+RFC 2445                       iCalendar                   November 1998
+
+
+     QSAFE-CHAR = WSP / %x21 / %x23-7E / NON-US-ASCII
+     ; Any character except CTLs and DQUOTE
+
+     SAFE-CHAR  = WSP / %x21 / %x23-2B / %x2D-39 / %x3C-7E
+                / NON-US-ASCII
+     ; Any character except CTLs, DQUOTE, ";", ":", ","
+
+     VALUE-CHAR = WSP / %x21-7E / NON-US-ASCII
+     ; Any textual character
+
+     CR = %x0D
+     ; carriage return
+
+     LF = %x0A
+     ; line feed
+
+     CRLF       = CR LF
+     ; Internet standard newline
+
+     CTL        = %x00-08 / %x0A-1F / %x7F
+        ; Controls
+
+     ALPHA      = %x41-5A / %x61-7A   ; A-Z / a-z
+
+     DIGIT      = %x30-39
+        ; 0-9
+
+     DQUOTE     = %x22
+        ; Quotation Mark
+
+     WSP        = SPACE / HTAB
+
+     SPACE      = %x20
+
+     HTAB       = %x09
+
+   The property value component of a content line has a format that is
+   property specific. Refer to the section describing each property for
+   a definition of this format.
+
+   All names of properties, property parameters, enumerated property
+   values and property parameter values are case-insensitive. However,
+   all other property values are case-sensitive, unless otherwise
+   stated.
+
+
+
+
+
+
+
+Dawson & Stenerson          Standards Track                    [Page 15]
+

+RFC 2445                       iCalendar                   November 1998
+
+
+

4.1.1 List and Field Separators

+ + Some properties and parameters allow a list of values. Values in a + list of values MUST be separated by a COMMA character (US-ASCII + decimal 44). There is no significance to the order of values in a + list. For those parameter values (such as those that specify URI + values) that are specified in quoted-strings, the individual quoted- + strings are separated by a COMMA character (US-ASCII decimal 44). + + Some property values are defined in terms of multiple parts. These + structured property values MUST have their value parts separated by a + SEMICOLON character (US-ASCII decimal 59). + + Some properties allow a list of parameters. Each property parameter + in a list of property parameters MUST be separated by a SEMICOLON + character (US-ASCII decimal 59). + + Property parameters with values containing a COLON, a SEMICOLON or a + COMMA character MUST be placed in quoted text. + + For example, in the following properties a SEMICOLON is used to + separate property parameters from each other, and a COMMA is used to + separate property values in a value list. + + ATTENDEE;RSVP=TRUE;ROLE=REQ-PARTICIPANT:MAILTO: + jsmith@host.com + + RDATE;VALUE=DATE:19970304,19970504,19970704,19970904 + +

4.1.2 Multiple Values

+ + Some properties defined in the iCalendar object can have multiple + values. The general rule for encoding multi-valued items is to simply + create a new content line for each value, including the property + name. However, it should be noted that some properties support + encoding multiple values in a single property by separating the + values with a COMMA character (US-ASCII decimal 44). Individual + property definitions should be consulted for determining whether a + specific property allows multiple values and in which of these two + forms. + +

4.1.3 Binary Content

+ + Binary content information in an iCalendar object SHOULD be + referenced using a URI within a property value. That is the binary + content information SHOULD be placed in an external MIME entity that + can be referenced by a URI from within the iCalendar object. In + applications where this is not feasible, binary content information + + + +Dawson & Stenerson Standards Track [Page 16] +

+RFC 2445                       iCalendar                   November 1998
+
+
+   can be included within an iCalendar object, but only after first
+   encoding it into text using the "BASE64" encoding method defined in
+   [RFC 2045]. Inline binary contact SHOULD only be used in applications
+   whose special circumstances demand that an iCalendar object be
+   expressed as a single entity. A property containing inline binary
+   content information MUST specify the "ENCODING" property parameter.
+   Binary content information placed external to the iCalendar object
+   MUST be referenced by a uniform resource identifier (URI).
+
+   The following example specifies an "ATTACH" property that references
+   an attachment external to the iCalendar object with a URI reference:
+
+     ATTACH:http://xyz.com/public/quarterly-report.doc
+
+   The following example specifies an "ATTACH" property with inline
+   binary encoded content information:
+
+     ATTACH;FMTTYPE=image/basic;ENCODING=BASE64;VALUE=BINARY:
+      MIICajCCAdOgAwIBAgICBEUwDQYJKoZIhvcNAQEEBQAwdzELMAkGA1U
+      EBhMCVVMxLDAqBgNVBAoTI05ldHNjYXBlIENvbW11bmljYXRpb25zIE
+        <...remainder of "BASE64" encoded binary data...>
+
+

4.1.4 Character Set

+ + There is not a property parameter to declare the character set used + in a property value. The default character set for an iCalendar + object is UTF-8 as defined in [RFC 2279]. + + The "charset" Content-Type parameter can be used in MIME transports + to specify any other IANA registered character set. + +

4.2 Property Parameters

+ + A property can have attributes associated with it. These "property + parameters" contain meta-information about the property or the + property value. Property parameters are provided to specify such + information as the location of an alternate text representation for a + property value, the language of a text property value, the data type + of the property value and other attributes. + + Property parameter values that contain the COLON (US-ASCII decimal + 58), SEMICOLON (US-ASCII decimal 59) or COMMA (US-ASCII decimal 44) + character separators MUST be specified as quoted-string text values. + Property parameter values MUST NOT contain the DOUBLE-QUOTE (US-ASCII + decimal 22) character. The DOUBLE-QUOTE (US-ASCII decimal 22) + character is used as a delimiter for parameter values that contain + restricted characters or URI text. For example: + + + + +Dawson & Stenerson Standards Track [Page 17] +

+RFC 2445                       iCalendar                   November 1998
+
+
+     DESCRIPTION;ALTREP="http://www.wiz.org":The Fall'98 Wild Wizards
+       Conference - - Las Vegas, NV, USA
+
+   Property parameter values that are not in quoted strings are case
+   insensitive.
+
+   The general property parameters defined by this memo are defined by
+   the following notation:
+
+     parameter  = altrepparam           ; Alternate text representation
+                / cnparam               ; Common name
+                / cutypeparam           ; Calendar user type
+                / delfromparam          ; Delegator
+                / deltoparam            ; Delegatee
+                / dirparam              ; Directory entry
+                / encodingparam         ; Inline encoding
+                / fmttypeparam          ; Format type
+                / fbtypeparam           ; Free/busy time type
+                / languageparam         ; Language for text
+                / memberparam           ; Group or list membership
+                / partstatparam         ; Participation status
+                / rangeparam            ; Recurrence identifier range
+                / trigrelparam          ; Alarm trigger relationship
+                / reltypeparam          ; Relationship type
+                / roleparam             ; Participation role
+                / rsvpparam             ; RSVP expectation
+                / sentbyparam           ; Sent by
+                / tzidparam             ; Reference to time zone object
+                / valuetypeparam        ; Property value data type
+                / ianaparam
+        ; Some other IANA registered iCalendar parameter.
+                / xparam
+        ; A non-standard, experimental parameter.
+
+     ianaparam  = iana-token "=" param-value *("," param-value)
+
+     xparam     =x-name "=" param-value *("," param-value)
+
+

4.2.1 Alternate Text Representation

+ + Parameter Name: ALTREP + + Purpose: To specify an alternate text representation for the property + value. + + Format Definition: The property parameter is defined by the following + notation: + + + + +Dawson & Stenerson Standards Track [Page 18] +

+RFC 2445                       iCalendar                   November 1998
+
+
+     altrepparam        = "ALTREP" "=" DQUOTE uri DQUOTE
+
+   Description: The parameter specifies a URI that points to an
+   alternate representation for a textual property value. A property
+   specifying this parameter MUST also include a value that reflects the
+   default representation of the text value. The individual URI
+   parameter values MUST each be specified in a quoted-string.
+
+   Example:
+
+     DESCRIPTION;ALTREP="CID:<part3.msg.970415T083000@host.com>":Project
+       XYZ Review Meeting will include the following agenda items: (a)
+       Market Overview, (b) Finances, (c) Project Management
+
+   The "ALTREP" property parameter value might point to a "text/html"
+   content portion.
+
+     Content-Type:text/html
+     Content-Id:<part3.msg.970415T083000@host.com>
+
+     <html><body>
+     <p><b>Project XYZ Review Meeting</b> will include the following
+     agenda items:<ol><li>Market
+     Overview</li><li>Finances</li><li>Project Management</li></ol></p>
+     </body></html>
+
+

4.2.2 Common Name

+ + Parameter Name: CN + + Purpose: To specify the common name to be associated with the + calendar user specified by the property. + + Format Definition: The property parameter is defined by the following + notation: + + cnparam = "CN" "=" param-value + + Description: This parameter can be specified on properties with a + CAL-ADDRESS value type. The parameter specifies the common name to be + associated with the calendar user specified by the property. The + parameter value is text. The parameter value can be used for display + text to be associated with the calendar address specified by the + property. + + + + + + + +Dawson & Stenerson Standards Track [Page 19] +

+RFC 2445                       iCalendar                   November 1998
+
+
+   Example:
+
+     ORGANIZER;CN="John Smith":MAILTO:jsmith@host.com
+
+

4.2.3 Calendar User Type

+ + Parameter Name: CUTYPE + + Purpose: To specify the type of calendar user specified by the + property. + + Format Definition: The property parameter is defined by the following + notation: + + cutypeparam = "CUTYPE" "=" + ("INDIVIDUAL" ; An individual + / "GROUP" ; A group of individuals + / "RESOURCE" ; A physical resource + / "ROOM" ; A room resource + / "UNKNOWN" ; Otherwise not known + / x-name ; Experimental type + / iana-token) ; Other IANA registered + ; type + ; Default is INDIVIDUAL + + Description: This parameter can be specified on properties with a + CAL-ADDRESS value type. The parameter identifies the type of calendar + user specified by the property. If not specified on a property that + allows this parameter, the default is INDIVIDUAL. + + Example: + + ATTENDEE;CUTYPE=GROUP:MAILTO:ietf-calsch@imc.org + +

4.2.4 Delegators

+ + Parameter Name: DELEGATED-FROM + + Purpose: To specify the calendar users that have delegated their + participation to the calendar user specified by the property. + + Format Definition: The property parameter is defined by the following + notation: + + delfromparam = "DELEGATED-FROM" "=" DQUOTE cal-address DQUOTE + *("," DQUOTE cal-address DQUOTE) + + + + + +Dawson & Stenerson Standards Track [Page 20] +

+RFC 2445                       iCalendar                   November 1998
+
+
+   Description: This parameter can be specified on properties with a
+   CAL-ADDRESS value type. This parameter can be specified on a property
+   that has a value type of calendar address. This parameter specifies
+   those calendar uses that have delegated their participation in a
+   group scheduled event or to-do to the calendar user specified by the
+   property. The value MUST be a MAILTO URI as defined in [RFC 1738].
+   The individual calendar address parameter values MUST each be
+   specified in a quoted-string.
+
+   Example:
+
+     ATTENDEE;DELEGATED-FROM="MAILTO:jsmith@host.com":MAILTO:
+      jdoe@host.com
+
+

4.2.5 Delegatees

+ + Parameter Name: DELEGATED-TO + + Purpose: To specify the calendar users to whom the calendar user + specified by the property has delegated participation. + + Format Definition: The property parameter is defined by the following + notation: + + deltoparam = "DELEGATED-TO" "=" DQUOTE cal-address DQUOTE + *("," DQUOTE cal-address DQUOTE) + + Description: This parameter can be specified on properties with a + CAL-ADDRESS value type. This parameter specifies those calendar users + whom have been delegated participation in a group scheduled event or + to-do by the calendar user specified by the property. The value MUST + be a MAILTO URI as defined in [RFC 1738]. The individual calendar + address parameter values MUST each be specified in a quoted-string. + + Example: + + ATTENDEE;DELEGATED-TO="MAILTO:jdoe@host.com","MAILTO:jqpublic@ + host.com":MAILTO:jsmith@host.com + +

4.2.6 Directory Entry Reference

+ + Parameter Name: DIR + + Purpose: To specify reference to a directory entry associated with + the calendar user specified by the property. + + Format Definition: The property parameter is defined by the following + notation: + + + +Dawson & Stenerson Standards Track [Page 21] +

+RFC 2445                       iCalendar                   November 1998
+
+
+     dirparam   = "DIR" "=" DQUOTE uri DQUOTE
+
+   Description: This parameter can be specified on properties with a
+   CAL-ADDRESS value type. The parameter specifies a reference to the
+   directory entry associated with the calendar user specified by the
+   property. The parameter value is a URI. The individual URI parameter
+   values MUST each be specified in a quoted-string.
+
+   Example:
+
+     ORGANIZER;DIR="ldap://host.com:6666/o=eDABC%20Industries,c=3DUS??
+      (cn=3DBJim%20Dolittle)":MAILTO:jimdo@host1.com
+
+

4.2.7 Inline Encoding

+ + Parameter Name: ENCODING + + Purpose: To specify an alternate inline encoding for the property + value. + + Format Definition: The property parameter is defined by the following + notation: + + encodingparam = "ENCODING" "=" + ("8BIT" + ; "8bit" text encoding is defined in [RFC 2045] + / "BASE64" + ; "BASE64" binary encoding format is defined in [RFC 2045] + / iana-token + ; Some other IANA registered iCalendar encoding type + / x-name) + ; A non-standard, experimental encoding type + + Description: The property parameter identifies the inline encoding + used in a property value. The default encoding is "8BIT", + corresponding to a property value consisting of text. The "BASE64" + encoding type corresponds to a property value encoded using the + "BASE64" encoding defined in [RFC 2045]. + + If the value type parameter is ";VALUE=BINARY", then the inline + encoding parameter MUST be specified with the value + ";ENCODING=BASE64". + + + + + + + + + +Dawson & Stenerson Standards Track [Page 22] +

+RFC 2445                       iCalendar                   November 1998
+
+
+   Example:
+
+     ATTACH;FMTYPE=IMAGE/JPEG;ENCODING=BASE64;VALUE=BINARY:MIICajC
+      CAdOgAwIBAgICBEUwDQYJKoZIhvcNAQEEBQAwdzELMAkGA1UEBhMCVVMxLDA
+      qBgNVBAoTI05ldHNjYXBlIENvbW11bmljYXRpb25zIENvcnBvcmF0aW9uMRw
+      <...remainder of "BASE64" encoded binary data...>
+
+

4.2.8 Format Type

+ + Parameter Name: FMTTYPE + + Purpose: To specify the content type of a referenced object. + + Format Definition: The property parameter is defined by the following + notation: + + fmttypeparam = "FMTTYPE" "=" iana-token + ; A IANA registered content type + / x-name + ; A non-standard content type + + Description: This parameter can be specified on properties that are + used to reference an object. The parameter specifies the content type + of the referenced object. For example, on the "ATTACH" property, a + FTP type URI value does not, by itself, necessarily convey the type + of content associated with the resource. The parameter value MUST be + the TEXT for either an IANA registered content type or a non-standard + content type. + + Example: + + ATTACH;FMTTYPE=application/binary:ftp://domain.com/pub/docs/ + agenda.doc + +

4.2.9 Free/Busy Time Type

+ + Parameter Name: FBTYPE + + Purpose: To specify the free or busy time type. + + Format Definition: The property parameter is defined by the following + notation: + + fbtypeparam = "FBTYPE" "=" ("FREE" / "BUSY" + / "BUSY-UNAVAILABLE" / "BUSY-TENTATIVE" + / x-name + ; Some experimental iCalendar data type. + / iana-token) + + + +Dawson & Stenerson Standards Track [Page 23] +

+RFC 2445                       iCalendar                   November 1998
+
+
+        ; Some other IANA registered iCalendar data type.
+
+   Description: The parameter specifies the free or busy time type. The
+   value FREE indicates that the time interval is free for scheduling.
+   The value BUSY indicates that the time interval is busy because one
+   or more events have been scheduled for that interval. The value
+   BUSY-UNAVAILABLE indicates that the time interval is busy and that
+   the interval can not be scheduled. The value BUSY-TENTATIVE indicates
+   that the time interval is busy because one or more events have been
+   tentatively scheduled for that interval. If not specified on a
+   property that allows this parameter, the default is BUSY.
+
+   Example: The following is an example of this parameter on a FREEBUSY
+   property.
+
+     FREEBUSY;FBTYPE=BUSY:19980415T133000Z/19980415T170000Z
+
+

4.2.10 Language

+ + Parameter Name: LANGUAGE + + Purpose: To specify the language for text values in a property or + property parameter. + + Format Definition: The property parameter is defined by the following + notation: + + languageparam = "LANGUAGE" "=" language + + language = <Text identifying a language, as defined in [RFC 1766]> + + Description: This parameter can be specified on properties with a + text value type. The parameter identifies the language of the text in + the property or property parameter value. The value of the "language" + property parameter is that defined in [RFC 1766]. + + For transport in a MIME entity, the Content-Language header field can + be used to set the default language for the entire body part. + Otherwise, no default language is assumed. + + Example: + + SUMMARY;LANGUAGE=us-EN:Company Holiday Party + + LOCATION;LANGUAGE=en:Germany + LOCATION;LANGUAGE=no:Tyskland + + + + + +Dawson & Stenerson Standards Track [Page 24] +

+RFC 2445                       iCalendar                   November 1998
+
+
+   The following example makes use of the Quoted-Printable encoding in
+   order to represent non-ASCII characters.
+
+     LOCATION;LANGUAGE=da:K=F8benhavn
+     LOCATION;LANGUAGE=en:Copenhagen
+
+

4.2.11 Group or List Membership

+ + Parameter Name: MEMBER + + Purpose: To specify the group or list membership of the calendar user + specified by the property. + + Format Definition: The property parameter is defined by the following + notation: + + memberparam = "MEMBER" "=" DQUOTE cal-address DQUOTE + *("," DQUOTE cal-address DQUOTE) + + Description: This parameter can be specified on properties with a + CAL-ADDRESS value type. The parameter identifies the groups or list + membership for the calendar user specified by the property. The + parameter value either a single calendar address in a quoted-string + or a COMMA character (US-ASCII decimal 44) list of calendar + addresses, each in a quoted-string. The individual calendar address + parameter values MUST each be specified in a quoted-string. + + Example: + + ATTENDEE;MEMBER="MAILTO:ietf-calsch@imc.org":MAILTO:jsmith@host.com + + ATTENDEE;MEMBER="MAILTO:projectA@host.com","MAILTO:projectB@host. + com":MAILTO:janedoe@host.com + +

4.2.12 Participation Status

+ + Parameter Name: PARTSTAT + + Purpose: To specify the participation status for the calendar user + specified by the property. + + Format Definition: The property parameter is defined by the following + notation: + + partstatparam = "PARTSTAT" "=" + ("NEEDS-ACTION" ; Event needs action + / "ACCEPTED" ; Event accepted + / "DECLINED" ; Event declined + + + +Dawson & Stenerson Standards Track [Page 25] +

+RFC 2445                       iCalendar                   November 1998
+
+
+                        / "TENTATIVE"           ; Event tentatively
+                                                ; accepted
+                        / "DELEGATED"           ; Event delegated
+                        / x-name                ; Experimental status
+                        / iana-token)           ; Other IANA registered
+                                                ; status
+     ; These are the participation statuses for a "VEVENT". Default is
+     ; NEEDS-ACTION
+     partstatparam      /= "PARTSTAT" "="
+                         ("NEEDS-ACTION"        ; To-do needs action
+                        / "ACCEPTED"            ; To-do accepted
+                        / "DECLINED"            ; To-do declined
+                        / "TENTATIVE"           ; To-do tentatively
+                                                ; accepted
+                        / "DELEGATED"           ; To-do delegated
+                        / "COMPLETED"           ; To-do completed.
+                                                ; COMPLETED property has
+                                                ;date/time completed.
+                        / "IN-PROCESS"          ; To-do in process of
+                                                ; being completed
+                        / x-name                ; Experimental status
+                        / iana-token)           ; Other IANA registered
+                                                ; status
+     ; These are the participation statuses for a "VTODO". Default is
+     ; NEEDS-ACTION
+
+     partstatparam      /= "PARTSTAT" "="
+                         ("NEEDS-ACTION"        ; Journal needs action
+                        / "ACCEPTED"            ; Journal accepted
+                        / "DECLINED"            ; Journal declined
+                        / x-name                ; Experimental status
+                        / iana-token)           ; Other IANA registered
+                                                ; status
+     ; These are the participation statuses for a "VJOURNAL". Default is
+     ; NEEDS-ACTION
+
+   Description: This parameter can be specified on properties with a
+   CAL-ADDRESS value type. The parameter identifies the participation
+   status for the calendar user specified by the property value. The
+   parameter values differ depending on whether they are associated with
+   a group scheduled "VEVENT", "VTODO" or "VJOURNAL". The values MUST
+   match one of the values allowed for the given calendar component. If
+   not specified on a property that allows this parameter, the default
+   value is NEEDS-ACTION.
+
+   Example:
+
+     ATTENDEE;PARTSTAT=DECLINED:MAILTO:jsmith@host.com
+
+
+
+Dawson & Stenerson          Standards Track                    [Page 26]
+

+RFC 2445                       iCalendar                   November 1998
+
+
+

4.2.13 Recurrence Identifier Range

+ + Parameter Name: RANGE + + Purpose: To specify the effective range of recurrence instances from + the instance specified by the recurrence identifier specified by the + property. + + Format Definition: The property parameter is defined by the following + notation: + + rangeparam = "RANGE" "=" ("THISANDPRIOR" + ; To specify all instances prior to the recurrence identifier + / "THISANDFUTURE") + ; To specify the instance specified by the recurrence identifier + ; and all subsequent recurrence instances + + Description: The parameter can be specified on a property that + specifies a recurrence identifier. The parameter specifies the + effective range of recurrence instances that is specified by the + property. The effective range is from the recurrence identified + specified by the property. If this parameter is not specified an + allowed property, then the default range is the single instance + specified by the recurrence identifier value of the property. The + parameter value can be "THISANDPRIOR" to indicate a range defined by + the recurrence identified value of the property and all prior + instances. The parameter value can also be "THISANDFUTURE" to + indicate a range defined by the recurrence identifier and all + subsequent instances. + + Example: + + RECURRENCE-ID;RANGE=THISANDPRIOR:19980401T133000Z + +

4.2.14 Alarm Trigger Relationship

+ + Parameter Name: RELATED + + Purpose: To specify the relationship of the alarm trigger with + respect to the start or end of the calendar component. + + Format Definition: The property parameter is defined by the following + notation: + + trigrelparam = "RELATED" "=" + ("START" ; Trigger off of start + / "END") ; Trigger off of end + + + + +Dawson & Stenerson Standards Track [Page 27] +

+RFC 2445                       iCalendar                   November 1998
+
+
+   Description: The parameter can be specified on properties that
+   specify an alarm trigger with a DURATION value type. The parameter
+   specifies whether the alarm will trigger relative to the start or end
+   of the calendar component. The parameter value START will set the
+   alarm to trigger off the start of the calendar component; the
+   parameter value END will set the alarm to trigger off the end of the
+   calendar component. If the parameter is not specified on an allowable
+   property, then the default is START.
+
+   Example:
+
+     TRIGGER;RELATED=END:PT5M
+
+

4.2.15 Relationship Type

+ + Parameter Name: RELTYPE + + Purpose: To specify the type of hierarchical relationship associated + with the calendar component specified by the property. + + Format Definition: The property parameter is defined by the following + notation: + + reltypeparam = "RELTYPE" "=" + ("PARENT" ; Parent relationship. Default. + / "CHILD" ; Child relationship + / "SIBLING ; Sibling relationship + / iana-token ; Some other IANA registered + ; iCalendar relationship type + / x-name) ; A non-standard, experimental + ; relationship type + + Description: This parameter can be specified on a property that + references another related calendar. The parameter specifies the + hierarchical relationship type of the calendar component referenced + by the property. The parameter value can be PARENT, to indicate that + the referenced calendar component is a superior of calendar + component; CHILD to indicate that the referenced calendar component + is a subordinate of the calendar component; SIBLING to indicate that + the referenced calendar component is a peer of the calendar + component. If this parameter is not specified on an allowable + property, the default relationship type is PARENT. + + Example: + + RELATED-TO;RELTYPE=SIBLING:<19960401-080045-4000F192713@host.com> + + + + + +Dawson & Stenerson Standards Track [Page 28] +

+RFC 2445                       iCalendar                   November 1998
+
+
+

4.2.16 Participation Role

+ + Parameter Name: ROLE + + Purpose: To specify the participation role for the calendar user + specified by the property. + + Format Definition: The property parameter is defined by the following + notation: + + roleparam = "ROLE" "=" + ("CHAIR" ; Indicates chair of the + ; calendar entity + / "REQ-PARTICIPANT" ; Indicates a participant whose + ; participation is required + / "OPT-PARTICIPANT" ; Indicates a participant whose + ; participation is optional + / "NON-PARTICIPANT" ; Indicates a participant who is + ; copied for information + ; purposes only + / x-name ; Experimental role + / iana-token) ; Other IANA role + ; Default is REQ-PARTICIPANT + + Description: This parameter can be specified on properties with a + CAL-ADDRESS value type. The parameter specifies the participation + role for the calendar user specified by the property in the group + schedule calendar component. If not specified on a property that + allows this parameter, the default value is REQ-PARTICIPANT. + + Example: + + ATTENDEE;ROLE=CHAIR:MAILTO:mrbig@host.com + +

4.2.17 RSVP Expectation

+ + Parameter Name: RSVP + + Purpose: To specify whether there is an expectation of a favor of a + reply from the calendar user specified by the property value. + + Format Definition: The property parameter is defined by the following + notation: + + rsvpparam = "RSVP" "=" ("TRUE" / "FALSE") + ; Default is FALSE + + + + + +Dawson & Stenerson Standards Track [Page 29] +

+RFC 2445                       iCalendar                   November 1998
+
+
+   Description: This parameter can be specified on properties with a
+   CAL-ADDRESS value type. The parameter identifies the expectation of a
+   reply from the calendar user specified by the property value. This
+   parameter is used by the "Organizer" to request a participation
+   status reply from an "Attendee" of a group scheduled event or to-do.
+   If not specified on a property that allows this parameter, the
+   default value is FALSE.
+
+   Example:
+
+     ATTENDEE;RSVP=TRUE:MAILTO:jsmith@host.com
+
+

4.2.18 Sent By

+ + Parameter Name: SENT-BY + + Purpose: To specify the calendar user that is acting on behalf of the + calendar user specified by the property. + + Format Definition: The property parameter is defined by the following + notation: + + sentbyparam = "SENT-BY" "=" DQUOTE cal-address DQUOTE + + Description: This parameter can be specified on properties with a + CAL-ADDRESS value type. The parameter specifies the calendar user + that is acting on behalf of the calendar user specified by the + property. The parameter value MUST be a MAILTO URI as defined in [RFC + 1738]. The individual calendar address parameter values MUST each be + specified in a quoted-string. + + Example: + + ORGANIZER;SENT-BY:"MAILTO:sray@host.com":MAILTO:jsmith@host.com + +

4.2.19 Time Zone Identifier

+ + Parameter Name: TZID + + Purpose: To specify the identifier for the time zone definition for a + time component in the property value. + + Format Definition: This property parameter is defined by the + following notation: + + tzidparam = "TZID" "=" [tzidprefix] paramtext CRLF + + tzidprefix = "/" + + + +Dawson & Stenerson Standards Track [Page 30] +

+RFC 2445                       iCalendar                   November 1998
+
+
+   Description: The parameter MUST be specified on the "DTSTART",
+   "DTEND", "DUE", "EXDATE" and "RDATE" properties when either a DATE-
+   TIME or TIME value type is specified and when the value is not either
+   a UTC or a "floating" time. Refer to the DATE-TIME or TIME value type
+   definition for a description of UTC and "floating time" formats. This
+   property parameter specifies a text value which uniquely identifies
+   the "VTIMEZONE" calendar component to be used when evaluating the
+   time portion of the property. The value of the TZID property
+   parameter will be equal to the value of the TZID property for the
+   matching time zone definition. An individual "VTIMEZONE" calendar
+   component MUST be specified for each unique "TZID" parameter value
+   specified in the iCalendar object.
+
+   The parameter MUST be specified on properties with a DATE-TIME value
+   if the DATE-TIME is not either a UTC or a "floating" time.
+
+   The presence of the SOLIDUS character (US-ASCII decimal 47) as a
+   prefix, indicates that this TZID represents a unique ID in a globally
+   defined time zone registry (when such registry is defined).
+
+        Note: This document does not define a naming convention for time
+        zone identifiers. Implementers may want to use the naming
+        conventions defined in existing time zone specifications such as
+        the public-domain Olson database [TZ]. The specification of
+        globally unique time zone identifiers is not addressed by this
+        document and is left for future study.
+
+   The following are examples of this property parameter:
+
+     DTSTART;TZID=US-Eastern:19980119T020000
+
+     DTEND;TZID=US-Eastern:19980119T030000
+
+   The TZID property parameter MUST NOT be applied to DATE-TIME or TIME
+   properties whose time values are specified in UTC.
+
+   The use of local time in a DATE-TIME or TIME value without the TZID
+   property parameter is to be interpreted as a local time value,
+   regardless of the existence of "VTIMEZONE" calendar components in the
+   iCalendar object.
+
+   For more information see the sections on the data types DATE-TIME and
+   TIME.
+
+
+
+
+
+
+
+
+Dawson & Stenerson          Standards Track                    [Page 31]
+

+RFC 2445                       iCalendar                   November 1998
+
+
+

4.2.20 Value Data Types

+ + Parameter Name: VALUE + + Purpose: To explicitly specify the data type format for a property + value. + + Format Definition: The "VALUE" property parameter is defined by the + following notation: + + valuetypeparam = "VALUE" "=" valuetype + + valuetype = ("BINARY" + / "BOOLEAN" + / "CAL-ADDRESS" + / "DATE" + / "DATE-TIME" + / "DURATION" + / "FLOAT" + / "INTEGER" + / "PERIOD" + / "RECUR" + / "TEXT" + / "TIME" + / "URI" + / "UTC-OFFSET" + / x-name + ; Some experimental iCalendar data type. + / iana-token) + ; Some other IANA registered iCalendar data type. + + Description: The parameter specifies the data type and format of the + property value. The property values MUST be of a single value type. + For example, a "RDATE" property cannot have a combination of DATE- + TIME and TIME value types. + + If the property's value is the default value type, then this + parameter need not be specified. However, if the property's default + value type is overridden by some other allowable value type, then + this parameter MUST be specified. + +

4.3 Property Value Data Types

+ + The properties in an iCalendar object are strongly typed. The + definition of each property restricts the value to be one of the + value data types, or simply value types, defined in this section. The + value type for a property will either be specified implicitly as the + default value type or will be explicitly specified with the "VALUE" + + + +Dawson & Stenerson Standards Track [Page 32] +

+RFC 2445                       iCalendar                   November 1998
+
+
+   parameter. If the value type of a property is one of the alternate
+   valid types, then it MUST be explicitly specified with the "VALUE"
+   parameter.
+
+

4.3.1 Binary

+ + Value Name: BINARY + + Purpose: This value type is used to identify properties that contain + a character encoding of inline binary data. For example, an inline + attachment of an object code might be included in an iCalendar + object. + + Formal Definition: The value type is defined by the following + notation: + + binary = *(4b-char) [b-end] + ; A "BASE64" encoded character string, as defined by [RFC 2045]. + + b-end = (2b-char "==") / (3b-char "=") + + b-char = ALPHA / DIGIT / "+" / "/" + + Description: Property values with this value type MUST also include + the inline encoding parameter sequence of ";ENCODING=BASE64". That + is, all inline binary data MUST first be character encoded using the + "BASE64" encoding method defined in [RFC 2045]. No additional content + value encoding (i.e., BACKSLASH character encoding) is defined for + this value type. + + Example: The following is an abridged example of a "BASE64" encoded + binary value data. + + ATTACH;VALUE=BINARY;ENCODING=BASE64:MIICajCCAdOgAwIBAgICBEUwDQY + JKoZIhvcNAQEEBQAwdzELMAkGA1UEBhMCVVMxLDAqBgNVBAoTI05ldHNjYXBlI + ENvbW11bmljYXRpb25zIENvcnBvcmF0aW9uMRwwGgYDVQQLExNJbmZv + <...remainder of "BASE64" encoded binary data...> + +

4.3.2 Boolean

+ + Value Name: BOOLEAN + + Purpose: This value type is used to identify properties that contain + either a "TRUE" or "FALSE" Boolean value. + + Formal Definition: The value type is defined by the following + notation: + + + + +Dawson & Stenerson Standards Track [Page 33] +

+RFC 2445                       iCalendar                   November 1998
+
+
+     boolean    = "TRUE" / "FALSE"
+
+   Description: These values are case insensitive text. No additional
+   content value encoding (i.e., BACKSLASH character encoding) is
+   defined for this value type.
+
+   Example: The following is an example of a hypothetical property that
+   has a BOOLEAN value type:
+
+   GIBBERISH:TRUE
+
+

4.3.3 Calendar User Address

+ + Value Name: CAL-ADDRESS + + Purpose: This value type is used to identify properties that contain + a calendar user address. + + Formal Definition: The value type is as defined by the following + notation: + + cal-address = uri + + Description: The value is a URI as defined by [RFC 1738] or any other + IANA registered form for a URI. When used to address an Internet + email transport address for a calendar user, the value MUST be a + MAILTO URI, as defined by [RFC 1738]. No additional content value + encoding (i.e., BACKSLASH character encoding) is defined for this + value type. + + Example: + + ATTENDEE:MAILTO:jane_doe@host.com + +

4.3.4 Date

+ + Value Name: DATE + + Purpose: This value type is used to identify values that contain a + calendar date. + + Formal Definition: The value type is defined by the following + notation: + + date = date-value + + date-value = date-fullyear date-month date-mday + date-fullyear = 4DIGIT + + + +Dawson & Stenerson Standards Track [Page 34] +

+RFC 2445                       iCalendar                   November 1998
+
+
+     date-month         = 2DIGIT        ;01-12
+     date-mday          = 2DIGIT        ;01-28, 01-29, 01-30, 01-31
+                                        ;based on month/year
+
+   Description: If the property permits, multiple "date" values are
+   specified as a COMMA character (US-ASCII decimal 44) separated list
+   of values. The format for the value type is expressed as the [ISO
+   8601] complete representation, basic format for a calendar date. The
+   textual format specifies a four-digit year, two-digit month, and
+   two-digit day of the month. There are no separator characters between
+   the year, month and day component text.
+
+   No additional content value encoding (i.e., BACKSLASH character
+   encoding) is defined for this value type.
+
+   Example: The following represents July 14, 1997:
+
+     19970714
+
+

4.3.5 Date-Time

+ + Value Name: DATE-TIME + + Purpose: This value type is used to identify values that specify a + precise calendar date and time of day. + + Formal Definition: The value type is defined by the following + notation: + + date-time = date "T" time ;As specified in the date and time + ;value definitions + + Description: If the property permits, multiple "date-time" values are + specified as a COMMA character (US-ASCII decimal 44) separated list + of values. No additional content value encoding (i.e., BACKSLASH + character encoding) is defined for this value type. + + The "DATE-TIME" data type is used to identify values that contain a + precise calendar date and time of day. The format is based on the + [ISO 8601] complete representation, basic format for a calendar date + and time of day. The text format is a concatenation of the "date", + followed by the LATIN CAPITAL LETTER T character (US-ASCII decimal + 84) time designator, followed by the "time" format. + + The "DATE-TIME" data type expresses time values in three forms: + + The form of date and time with UTC offset MUST NOT be used. For + example, the following is not valid for a date-time value: + + + +Dawson & Stenerson Standards Track [Page 35] +

+RFC 2445                       iCalendar                   November 1998
+
+
+     DTSTART:19980119T230000-0800       ;Invalid time format
+
+   FORM #1: DATE WITH LOCAL TIME
+
+   The date with local time form is simply a date-time value that does
+   not contain the UTC designator nor does it reference a time zone. For
+   example, the following represents Janurary 18, 1998, at 11 PM:
+
+     DTSTART:19980118T230000
+
+   Date-time values of this type are said to be "floating" and are not
+   bound to any time zone in particular. They are used to represent the
+   same hour, minute, and second value regardless of which time zone is
+   currently being observed. For example, an event can be defined that
+   indicates that an individual will be busy from 11:00 AM to 1:00 PM
+   every day, no matter which time zone the person is in. In these
+   cases, a local time can be specified. The recipient of an iCalendar
+   object with a property value consisting of a local time, without any
+   relative time zone information, SHOULD interpret the value as being
+   fixed to whatever time zone the ATTENDEE is in at any given moment.
+   This means that two ATTENDEEs, in different time zones, receiving the
+   same event definition as a floating time, may be participating in the
+   event at different actual times. Floating time SHOULD only be used
+   where that is the reasonable behavior.
+
+   In most cases, a fixed time is desired. To properly communicate a
+   fixed time in a property value, either UTC time or local time with
+   time zone reference MUST be specified.
+
+   The use of local time in a DATE-TIME value without the TZID property
+   parameter is to be interpreted as floating time, regardless of the
+   existence of "VTIMEZONE" calendar components in the iCalendar object.
+
+   FORM #2: DATE WITH UTC TIME
+
+   The date with UTC time, or absolute time, is identified by a LATIN
+   CAPITAL LETTER Z suffix character (US-ASCII decimal 90), the UTC
+   designator, appended to the time value. For example, the following
+   represents January 19, 1998, at 0700 UTC:
+
+     DTSTART:19980119T070000Z
+
+   The TZID property parameter MUST NOT be applied to DATE-TIME
+   properties whose time values are specified in UTC.
+
+   FORM #3: DATE WITH LOCAL TIME AND TIME ZONE REFERENCE
+
+
+
+
+
+Dawson & Stenerson          Standards Track                    [Page 36]
+

+RFC 2445                       iCalendar                   November 1998
+
+
+   The date and local time with reference to time zone information is
+   identified by the use the TZID property parameter to reference the
+   appropriate time zone definition. TZID is discussed in detail in the
+   section on Time Zone. For example, the following represents 2 AM in
+   New York on Janurary 19, 1998:
+
+          DTSTART;TZID=US-Eastern:19980119T020000
+
+   Example: The following represents July 14, 1997, at 1:30 PM in New
+   York City in each of the three time formats, using the "DTSTART"
+   property.
+
+     DTSTART:19970714T133000            ;Local time
+     DTSTART:19970714T173000Z           ;UTC time
+     DTSTART;TZID=US-Eastern:19970714T133000    ;Local time and time
+                        ; zone reference
+
+   A time value MUST ONLY specify 60 seconds when specifying the
+   periodic "leap second" in the time value. For example:
+
+     COMPLETED:19970630T235960Z
+
+

4.3.6 Duration

+ + Value Name: DURATION + + Purpose: This value type is used to identify properties that contain + a duration of time. + + Formal Definition: The value type is defined by the following + notation: + + dur-value = (["+"] / "-") "P" (dur-date / dur-time / dur-week) + + dur-date = dur-day [dur-time] + dur-time = "T" (dur-hour / dur-minute / dur-second) + dur-week = 1*DIGIT "W" + dur-hour = 1*DIGIT "H" [dur-minute] + dur-minute = 1*DIGIT "M" [dur-second] + dur-second = 1*DIGIT "S" + dur-day = 1*DIGIT "D" + + Description: If the property permits, multiple "duration" values are + specified by a COMMA character (US-ASCII decimal 44) separated list + of values. The format is expressed as the [ISO 8601] basic format for + the duration of time. The format can represent durations in terms of + weeks, days, hours, minutes, and seconds. + + + + +Dawson & Stenerson Standards Track [Page 37] +

+RFC 2445                       iCalendar                   November 1998
+
+
+   No additional content value encoding (i.e., BACKSLASH character
+   encoding) are defined for this value type.
+
+   Example: A duration of 15 days, 5 hours and 20 seconds would be:
+
+     P15DT5H0M20S
+
+   A duration of 7 weeks would be:
+
+     P7W
+
+

4.3.7 Float

+ + Value Name: FLOAT + + Purpose: This value type is used to identify properties that contain + a real number value. + + Formal Definition: The value type is defined by the following + notation: + + float = (["+"] / "-") 1*DIGIT ["." 1*DIGIT] + + Description: If the property permits, multiple "float" values are + specified by a COMMA character (US-ASCII decimal 44) separated list + of values. + + No additional content value encoding (i.e., BACKSLASH character + encoding) is defined for this value type. + + Example: + + 1000000.0000001 + 1.333 + -3.14 + +

4.3.8 Integer

+ + Value Name:INTEGER + + Purpose: This value type is used to identify properties that contain + a signed integer value. + + Formal Definition: The value type is defined by the following + notation: + + integer = (["+"] / "-") 1*DIGIT + + + + +Dawson & Stenerson Standards Track [Page 38] +

+RFC 2445                       iCalendar                   November 1998
+
+
+     Description: If the property permits, multiple "integer" values are
+     specified by a COMMA character (US-ASCII decimal 44) separated list
+     of values. The valid range for "integer" is -2147483648 to
+     2147483647. If the sign is not specified, then the value is assumed
+     to be positive.
+
+     No additional content value encoding (i.e., BACKSLASH character
+     encoding) is defined for this value type.
+
+     Example:
+
+     1234567890
+     -1234567890
+     +1234567890
+     432109876
+
+

4.3.9 Period of Time

+ + Value Name: PERIOD + + Purpose: This value type is used to identify values that contain a + precise period of time. + + Formal Definition: The data type is defined by the following + notation: + + period = period-explicit / period-start + + period-explicit = date-time "/" date-time + ; [ISO 8601] complete representation basic format for a period of + ; time consisting of a start and end. The start MUST be before the + ; end. + + period-start = date-time "/" dur-value + ; [ISO 8601] complete representation basic format for a period of + ; time consisting of a start and positive duration of time. + + Description: If the property permits, multiple "period" values are + specified by a COMMA character (US-ASCII decimal 44) separated list + of values. There are two forms of a period of time. First, a period + of time is identified by its start and its end. This format is + expressed as the [ISO 8601] complete representation, basic format for + "DATE-TIME" start of the period, followed by a SOLIDUS character + (US-ASCII decimal 47), followed by the "DATE-TIME" of the end of the + period. The start of the period MUST be before the end of the period. + Second, a period of time can also be defined by a start and a + positive duration of time. The format is expressed as the [ISO 8601] + complete representation, basic format for the "DATE-TIME" start of + + + +Dawson & Stenerson Standards Track [Page 39] +

+RFC 2445                       iCalendar                   November 1998
+
+
+   the period, followed by a SOLIDUS character (US-ASCII decimal 47),
+   followed by the [ISO 8601] basic format for "DURATION" of the period.
+
+   Example: The period starting at 18:00:00 UTC, on January 1, 1997 and
+   ending at 07:00:00 UTC on January 2, 1997 would be:
+
+     19970101T180000Z/19970102T070000Z
+
+   The period start at 18:00:00 on January 1, 1997 and lasting 5 hours
+   and 30 minutes would be:
+
+     19970101T180000Z/PT5H30M
+
+   No additional content value encoding (i.e., BACKSLASH character
+   encoding) is defined for this value type.
+
+

4.3.10 Recurrence Rule

+ + Value Name: RECUR + + Purpose: This value type is used to identify properties that contain + a recurrence rule specification. + + Formal Definition: The value type is defined by the following + notation: + + recur = "FREQ"=freq *( + + ; either UNTIL or COUNT may appear in a 'recur', + ; but UNTIL and COUNT MUST NOT occur in the same 'recur' + + ( ";" "UNTIL" "=" enddate ) / + ( ";" "COUNT" "=" 1*DIGIT ) / + + ; the rest of these keywords are optional, + ; but MUST NOT occur more than once + + ( ";" "INTERVAL" "=" 1*DIGIT ) / + ( ";" "BYSECOND" "=" byseclist ) / + ( ";" "BYMINUTE" "=" byminlist ) / + ( ";" "BYHOUR" "=" byhrlist ) / + ( ";" "BYDAY" "=" bywdaylist ) / + ( ";" "BYMONTHDAY" "=" bymodaylist ) / + ( ";" "BYYEARDAY" "=" byyrdaylist ) / + ( ";" "BYWEEKNO" "=" bywknolist ) / + ( ";" "BYMONTH" "=" bymolist ) / + ( ";" "BYSETPOS" "=" bysplist ) / + ( ";" "WKST" "=" weekday ) / + + + +Dawson & Stenerson Standards Track [Page 40] +

+RFC 2445                       iCalendar                   November 1998
+
+
+                ( ";" x-name "=" text )
+                )
+
+     freq       = "SECONDLY" / "MINUTELY" / "HOURLY" / "DAILY"
+                / "WEEKLY" / "MONTHLY" / "YEARLY"
+
+     enddate    = date
+     enddate    =/ date-time            ;An UTC value
+
+     byseclist  = seconds / ( seconds *("," seconds) )
+
+     seconds    = 1DIGIT / 2DIGIT       ;0 to 59
+
+     byminlist  = minutes / ( minutes *("," minutes) )
+
+     minutes    = 1DIGIT / 2DIGIT       ;0 to 59
+
+     byhrlist   = hour / ( hour *("," hour) )
+
+     hour       = 1DIGIT / 2DIGIT       ;0 to 23
+
+     bywdaylist = weekdaynum / ( weekdaynum *("," weekdaynum) )
+
+     weekdaynum = [([plus] ordwk / minus ordwk)] weekday
+
+     plus       = "+"
+
+     minus      = "-"
+
+     ordwk      = 1DIGIT / 2DIGIT       ;1 to 53
+
+     weekday    = "SU" / "MO" / "TU" / "WE" / "TH" / "FR" / "SA"
+     ;Corresponding to SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY,
+     ;FRIDAY, SATURDAY and SUNDAY days of the week.
+
+     bymodaylist = monthdaynum / ( monthdaynum *("," monthdaynum) )
+
+     monthdaynum = ([plus] ordmoday) / (minus ordmoday)
+
+     ordmoday   = 1DIGIT / 2DIGIT       ;1 to 31
+
+     byyrdaylist = yeardaynum / ( yeardaynum *("," yeardaynum) )
+
+     yeardaynum = ([plus] ordyrday) / (minus ordyrday)
+
+     ordyrday   = 1DIGIT / 2DIGIT / 3DIGIT      ;1 to 366
+
+     bywknolist = weeknum / ( weeknum *("," weeknum) )
+
+
+
+Dawson & Stenerson          Standards Track                    [Page 41]
+

+RFC 2445                       iCalendar                   November 1998
+
+
+     weeknum    = ([plus] ordwk) / (minus ordwk)
+
+     bymolist   = monthnum / ( monthnum *("," monthnum) )
+
+     monthnum   = 1DIGIT / 2DIGIT       ;1 to 12
+
+     bysplist   = setposday / ( setposday *("," setposday) )
+
+     setposday  = yeardaynum
+
+   Description: If the property permits, multiple "recur" values are
+   specified by a COMMA character (US-ASCII decimal 44) separated list
+   of values. The value type is a structured value consisting of a list
+   of one or more recurrence grammar parts. Each rule part is defined by
+   a NAME=VALUE pair. The rule parts are separated from each other by
+   the SEMICOLON character (US-ASCII decimal 59). The rule parts are not
+   ordered in any particular sequence. Individual rule parts MUST only
+   be specified once.
+
+   The FREQ rule part identifies the type of recurrence rule. This rule
+   part MUST be specified in the recurrence rule. Valid values include
+   SECONDLY, to specify repeating events based on an interval of a
+   second or more; MINUTELY, to specify repeating events based on an
+   interval of a minute or more; HOURLY, to specify repeating events
+   based on an interval of an hour or more; DAILY, to specify repeating
+   events based on an interval of a day or more; WEEKLY, to specify
+   repeating events based on an interval of a week or more; MONTHLY, to
+   specify repeating events based on an interval of a month or more; and
+   YEARLY, to specify repeating events based on an interval of a year or
+   more.
+
+   The INTERVAL rule part contains a positive integer representing how
+   often the recurrence rule repeats. The default value is "1", meaning
+   every second for a SECONDLY rule, or every minute for a MINUTELY
+   rule, every hour for an HOURLY rule, every day for a DAILY rule,
+   every week for a WEEKLY rule, every month for a MONTHLY rule and
+   every year for a YEARLY rule.
+
+   The UNTIL rule part defines a date-time value which bounds the
+   recurrence rule in an inclusive manner. If the value specified by
+   UNTIL is synchronized with the specified recurrence, this date or
+   date-time becomes the last instance of the recurrence. If specified
+   as a date-time value, then it MUST be specified in an UTC time
+   format. If not present, and the COUNT rule part is also not present,
+   the RRULE is considered to repeat forever.
+
+   The COUNT rule part defines the number of occurrences at which to
+   range-bound the recurrence. The "DTSTART" property value, if
+
+
+
+Dawson & Stenerson          Standards Track                    [Page 42]
+

+RFC 2445                       iCalendar                   November 1998
+
+
+   specified, counts as the first occurrence.
+
+   The BYSECOND rule part specifies a COMMA character (US-ASCII decimal
+   44) separated list of seconds within a minute. Valid values are 0 to
+   59. The BYMINUTE rule part specifies a COMMA character (US-ASCII
+   decimal 44) separated list of minutes within an hour. Valid values
+   are 0 to 59. The BYHOUR rule part specifies a COMMA character (US-
+   ASCII decimal 44) separated list of hours of the day. Valid values
+   are 0 to 23.
+
+   The BYDAY rule part specifies a COMMA character (US-ASCII decimal 44)
+   separated list of days of the week; MO indicates Monday; TU indicates
+   Tuesday; WE indicates Wednesday; TH indicates Thursday; FR indicates
+   Friday; SA indicates Saturday; SU indicates Sunday.
+
+   Each BYDAY value can also be preceded by a positive (+n) or negative
+   (-n) integer. If present, this indicates the nth occurrence of the
+   specific day within the MONTHLY or YEARLY RRULE. For example, within
+   a MONTHLY rule, +1MO (or simply 1MO) represents the first Monday
+   within the month, whereas -1MO represents the last Monday of the
+   month. If an integer modifier is not present, it means all days of
+   this type within the specified frequency. For example, within a
+   MONTHLY rule, MO represents all Mondays within the month.
+
+   The BYMONTHDAY rule part specifies a COMMA character (ASCII decimal
+   44) separated list of days of the month. Valid values are 1 to 31 or
+   -31 to -1. For example, -10 represents the tenth to the last day of
+   the month.
+
+   The BYYEARDAY rule part specifies a COMMA character (US-ASCII decimal
+   44) separated list of days of the year. Valid values are 1 to 366 or
+   -366 to -1. For example, -1 represents the last day of the year
+   (December 31st) and -306 represents the 306th to the last day of the
+   year (March 1st).
+
+   The BYWEEKNO rule part specifies a COMMA character (US-ASCII decimal
+   44) separated list of ordinals specifying weeks of the year. Valid
+   values are 1 to 53 or -53 to -1. This corresponds to weeks according
+   to week numbering as defined in [ISO 8601]. A week is defined as a
+   seven day period, starting on the day of the week defined to be the
+   week start (see WKST). Week number one of the calendar year is the
+   first week which contains at least four (4) days in that calendar
+   year. This rule part is only valid for YEARLY rules. For example, 3
+   represents the third week of the year.
+
+        Note: Assuming a Monday week start, week 53 can only occur when
+        Thursday is January 1 or if it is a leap year and Wednesday is
+        January 1.
+
+
+
+Dawson & Stenerson          Standards Track                    [Page 43]
+

+RFC 2445                       iCalendar                   November 1998
+
+
+   The BYMONTH rule part specifies a COMMA character (US-ASCII decimal
+   44) separated list of months of the year. Valid values are 1 to 12.
+
+   The WKST rule part specifies the day on which the workweek starts.
+   Valid values are MO, TU, WE, TH, FR, SA and SU. This is significant
+   when a WEEKLY RRULE has an interval greater than 1, and a BYDAY rule
+   part is specified. This is also significant when in a YEARLY RRULE
+   when a BYWEEKNO rule part is specified. The default value is MO.
+
+   The BYSETPOS rule part specifies a COMMA character (US-ASCII decimal
+   44) separated list of values which corresponds to the nth occurrence
+   within the set of events specified by the rule. Valid values are 1 to
+   366 or -366 to -1. It MUST only be used in conjunction with another
+   BYxxx rule part. For example "the last work day of the month" could
+   be represented as:
+
+     RRULE:FREQ=MONTHLY;BYDAY=MO,TU,WE,TH,FR;BYSETPOS=-1
+
+   Each BYSETPOS value can include a positive (+n) or negative (-n)
+   integer. If present, this indicates the nth occurrence of the
+   specific occurrence within the set of events specified by the rule.
+
+   If BYxxx rule part values are found which are beyond the available
+   scope (ie, BYMONTHDAY=30 in February), they are simply ignored.
+
+   Information, not contained in the rule, necessary to determine the
+   various recurrence instance start time and dates are derived from the
+   Start Time (DTSTART) entry attribute. For example,
+   "FREQ=YEARLY;BYMONTH=1" doesn't specify a specific day within the
+   month or a time. This information would be the same as what is
+   specified for DTSTART.
+
+   BYxxx rule parts modify the recurrence in some manner. BYxxx rule
+   parts for a period of time which is the same or greater than the
+   frequency generally reduce or limit the number of occurrences of the
+   recurrence generated. For example, "FREQ=DAILY;BYMONTH=1" reduces the
+   number of recurrence instances from all days (if BYMONTH tag is not
+   present) to all days in January. BYxxx rule parts for a period of
+   time less than the frequency generally increase or expand the number
+   of occurrences of the recurrence. For example,
+   "FREQ=YEARLY;BYMONTH=1,2" increases the number of days within the
+   yearly recurrence set from 1 (if BYMONTH tag is not present) to 2.
+
+   If multiple BYxxx rule parts are specified, then after evaluating the
+   specified FREQ and INTERVAL rule parts, the BYxxx rule parts are
+   applied to the current set of evaluated occurrences in the following
+   order: BYMONTH, BYWEEKNO, BYYEARDAY, BYMONTHDAY, BYDAY, BYHOUR,
+   BYMINUTE, BYSECOND and BYSETPOS; then COUNT and UNTIL are evaluated.
+
+
+
+Dawson & Stenerson          Standards Track                    [Page 44]
+

+RFC 2445                       iCalendar                   November 1998
+
+
+   Here is an example of evaluating multiple BYxxx rule parts.
+
+     DTSTART;TZID=US-Eastern:19970105T083000
+     RRULE:FREQ=YEARLY;INTERVAL=2;BYMONTH=1;BYDAY=SU;BYHOUR=8,9;
+      BYMINUTE=30
+
+   First, the "INTERVAL=2" would be applied to "FREQ=YEARLY" to arrive
+   at "every other year". Then, "BYMONTH=1" would be applied to arrive
+   at "every January, every other year". Then, "BYDAY=SU" would be
+   applied to arrive at "every Sunday in January, every other year".
+   Then, "BYHOUR=8,9" would be applied to arrive at "every Sunday in
+   January at 8 AM and 9 AM, every other year". Then, "BYMINUTE=30"
+   would be applied to arrive at "every Sunday in January at 8:30 AM and
+   9:30 AM, every other year". Then, lacking information from RRULE, the
+   second is derived from DTSTART, to end up in "every Sunday in January
+   at 8:30:00 AM and 9:30:00 AM, every other year". Similarly, if the
+   BYMINUTE, BYHOUR, BYDAY, BYMONTHDAY or BYMONTH rule part were
+   missing, the appropriate minute, hour, day or month would have been
+   retrieved from the "DTSTART" property.
+
+   No additional content value encoding (i.e., BACKSLASH character
+   encoding) is defined for this value type.
+
+   Example: The following is a rule which specifies 10 meetings which
+   occur every other day:
+
+     FREQ=DAILY;COUNT=10;INTERVAL=2
+
+   There are other examples specified in the "RRULE" specification.
+
+

4.3.11 Text

+ + Value Name: TEXT + + Purpose This value type is used to identify values that contain human + readable text. + + Formal Definition: The character sets supported by this revision of + iCalendar are UTF-8 and US ASCII thereof. The applicability to other + character sets is for future work. The value type is defined by the + following notation. + + text = *(TSAFE-CHAR / ":" / DQUOTE / ESCAPED-CHAR) + ; Folded according to description above + + ESCAPED-CHAR = "\\" / "\;" / "\," / "\N" / "\n") + ; \\ encodes \, \N or \n encodes newline + ; \; encodes ;, \, encodes , + + + +Dawson & Stenerson Standards Track [Page 45] +

+RFC 2445                       iCalendar                   November 1998
+
+
+     TSAFE-CHAR = %x20-21 / %x23-2B / %x2D-39 / %x3C-5B
+                  %x5D-7E / NON-US-ASCII
+        ; Any character except CTLs not needed by the current
+        ; character set, DQUOTE, ";", ":", "\", ","
+
+     Note: Certain other character sets may require modification of the
+     above definitions, but this is beyond the scope of this document.
+
+   Description: If the property permits, multiple "text" values are
+   specified by a COMMA character (US-ASCII decimal 44) separated list
+   of values.
+
+   The language in which the text is represented can be controlled by
+   the "LANGUAGE" property parameter.
+
+   An intentional formatted text line break MUST only be included in a
+   "TEXT" property value by representing the line break with the
+   character sequence of BACKSLASH (US-ASCII decimal 92), followed by a
+   LATIN SMALL LETTER N (US-ASCII decimal 110) or a LATIN CAPITAL LETTER
+   N (US-ASCII decimal 78), that is "\n" or "\N".
+
+   The "TEXT" property values may also contain special characters that
+   are used to signify delimiters, such as a COMMA character for lists
+   of values or a SEMICOLON character for structured values. In order to
+   support the inclusion of these special characters in "TEXT" property
+   values, they MUST be escaped with a BACKSLASH character. A BACKSLASH
+   character (US-ASCII decimal 92) in a "TEXT" property value MUST be
+   escaped with another BACKSLASH character. A COMMA character in a
+   "TEXT" property value MUST be escaped with a BACKSLASH character
+   (US-ASCII decimal 92). A SEMICOLON character in a "TEXT" property
+   value MUST be escaped with a BACKSLASH character (US-ASCII decimal
+   92).  However, a COLON character in a "TEXT" property value SHALL NOT
+   be escaped with a BACKSLASH character.Example: A multiple line value
+   of:
+
+     Project XYZ Final Review
+     Conference Room - 3B
+     Come Prepared.
+
+   would be represented as:
+
+     Project XYZ Final Review\nConference Room - 3B\nCome Prepared.
+
+
+
+
+
+
+
+
+
+Dawson & Stenerson          Standards Track                    [Page 46]
+

+RFC 2445                       iCalendar                   November 1998
+
+
+

4.3.12 Time

+ + Value Name: TIME + + Purpose: This value type is used to identify values that contain a + time of day. + + Formal Definition: The data type is defined by the following + notation: + + time = time-hour time-minute time-second [time-utc] + + time-hour = 2DIGIT ;00-23 + time-minute = 2DIGIT ;00-59 + time-second = 2DIGIT ;00-60 + ;The "60" value is used to account for "leap" seconds. + + time-utc = "Z" + + Description: If the property permits, multiple "time" values are + specified by a COMMA character (US-ASCII decimal 44) separated list + of values. No additional content value encoding (i.e., BACKSLASH + character encoding) is defined for this value type. + + The "TIME" data type is used to identify values that contain a time + of day. The format is based on the [ISO 8601] complete + representation, basic format for a time of day. The text format + consists of a two-digit 24-hour of the day (i.e., values 0-23), two- + digit minute in the hour (i.e., values 0-59), and two-digit seconds + in the minute (i.e., values 0-60). The seconds value of 60 MUST only + to be used to account for "leap" seconds. Fractions of a second are + not supported by this format. + + In parallel to the "DATE-TIME" definition above, the "TIME" data type + expresses time values in three forms: + + The form of time with UTC offset MUST NOT be used. For example, the + following is NOT VALID for a time value: + + 230000-0800 ;Invalid time format + + FORM #1 LOCAL TIME + + The local time form is simply a time value that does not contain the + UTC designator nor does it reference a time zone. For example, 11:00 + PM: + + 230000 + + + +Dawson & Stenerson Standards Track [Page 47] +

+RFC 2445                       iCalendar                   November 1998
+
+
+   Time values of this type are said to be "floating" and are not bound
+   to any time zone in particular. They are used to represent the same
+   hour, minute, and second value regardless of which time zone is
+   currently being observed. For example, an event can be defined that
+   indicates that an individual will be busy from 11:00 AM to 1:00 PM
+   every day, no matter which time zone the person is in. In these
+   cases, a local time can be specified. The recipient of an iCalendar
+   object with a property value consisting of a local time, without any
+   relative time zone information, SHOULD interpret the value as being
+   fixed to whatever time zone the ATTENDEE is in at any given moment.
+   This means that two ATTENDEEs may participate in the same event at
+   different UTC times; floating time SHOULD only be used where that is
+   reasonable behavior.
+
+   In most cases, a fixed time is desired. To properly communicate a
+   fixed time in a property value, either UTC time or local time with
+   time zone reference MUST be specified.
+
+   The use of local time in a TIME value without the TZID property
+   parameter is to be interpreted as a local time value, regardless of
+   the existence of "VTIMEZONE" calendar components in the iCalendar
+   object.
+
+   FORM #2: UTC TIME
+
+   UTC time, or absolute time, is identified by a LATIN CAPITAL LETTER Z
+   suffix character (US-ASCII decimal 90), the UTC designator, appended
+   to the time value. For example, the following represents 07:00 AM
+   UTC:
+
+     070000Z
+
+   The TZID property parameter MUST NOT be applied to TIME properties
+   whose time values are specified in UTC.
+
+   FORM #3: LOCAL TIME AND TIME ZONE REFERENCE
+
+   The local time with reference to time zone information form is
+   identified by the use the TZID property parameter to reference the
+   appropriate time zone definition. TZID is discussed in detail in the
+   section on Time Zone.
+
+   Example: The following represents 8:30 AM in New York in Winter, five
+   hours behind UTC, in each of the three formats using the "X-
+   TIMEOFDAY" non-standard property:
+
+
+
+
+
+
+Dawson & Stenerson          Standards Track                    [Page 48]
+

+RFC 2445                       iCalendar                   November 1998
+
+
+     X-TIMEOFDAY:083000
+
+     X-TIMEOFDAY:133000Z
+
+     X-TIMEOFDAY;TZID=US-Eastern:083000
+
+

4.3.13 URI

+ + Value Name: URI + + Purpose: This value type is used to identify values that contain a + uniform resource identifier (URI) type of reference to the property + value. + + Formal Definition: The data type is defined by the following + notation: + + uri = <As defined by any IETF RFC> + + Description: This data type might be used to reference binary + information, for values that are large, or otherwise undesirable to + include directly in the iCalendar object. + + The URI value formats in RFC 1738, RFC 2111 and any other IETF + registered value format can be specified. + + Any IANA registered URI format can be used. These include, but are + not limited to, those defined in RFC 1738 and RFC 2111. + + When a property parameter value is a URI value type, the URI MUST be + specified as a quoted-string value. + + No additional content value encoding (i.e., BACKSLASH character + encoding) is defined for this value type. + + Example: The following is a URI for a network file: + + http://host1.com/my-report.txt + +

4.3.14 UTC Offset

+ + Value Name: UTC-OFFSET + + Purpose: This value type is used to identify properties that contain + an offset from UTC to local time. + + Formal Definition: The data type is defined by the following + notation: + + + +Dawson & Stenerson Standards Track [Page 49] +

+RFC 2445                       iCalendar                   November 1998
+
+
+     utc-offset = time-numzone  ;As defined above in time data type
+
+     time-numzone       = ("+" / "-") time-hour time-minute [time-
+     second]
+
+   Description: The PLUS SIGN character MUST be specified for positive
+   UTC offsets (i.e., ahead of UTC). The value of "-0000" and "-000000"
+   are not allowed. The time-second, if present, may not be 60; if
+   absent, it defaults to zero.
+
+   No additional content value encoding (i.e., BACKSLASH character
+   encoding) is defined for this value type.
+
+   Example: The following UTC offsets are given for standard time for
+   New York (five hours behind UTC) and Geneva (one hour ahead of UTC):
+
+     -0500
+
+     +0100
+
+

4.4 iCalendar Object

+ + The Calendaring and Scheduling Core Object is a collection of + calendaring and scheduling information. Typically, this information + will consist of a single iCalendar object. However, multiple + iCalendar objects can be sequentially grouped together. The first + line and last line of the iCalendar object MUST contain a pair of + iCalendar object delimiter strings. The syntax for an iCalendar + object is as follows: + + icalobject = 1*("BEGIN" ":" "VCALENDAR" CRLF + icalbody + "END" ":" "VCALENDAR" CRLF) + + The following is a simple example of an iCalendar object: + + BEGIN:VCALENDAR + VERSION:2.0 + PRODID:-//hacksw/handcal//NONSGML v1.0//EN + BEGIN:VEVENT + DTSTART:19970714T170000Z + DTEND:19970715T035959Z + SUMMARY:Bastille Day Party + END:VEVENT + END:VCALENDAR + + + + + + +Dawson & Stenerson Standards Track [Page 50] +

+RFC 2445                       iCalendar                   November 1998
+
+
+

4.5 Property

+ + A property is the definition of an individual attribute describing a + calendar or a calendar component. A property takes the form defined + by the "contentline" notation defined in section 4.1.1. + + The following is an example of a property: + + DTSTART:19960415T133000Z + + This memo imposes no ordering of properties within an iCalendar + object. + + Property names, parameter names and enumerated parameter values are + case insensitive. For example, the property name "DUE" is the same as + "due" and "Due", DTSTART;TZID=US-Eastern:19980714T120000 is the same + as DtStart;TzID=US-Eastern:19980714T120000. + +

4.6 Calendar Components

+ + The body of the iCalendar object consists of a sequence of calendar + properties and one or more calendar components. The calendar + properties are attributes that apply to the calendar as a whole. The + calendar components are collections of properties that express a + particular calendar semantic. For example, the calendar component can + specify an event, a to-do, a journal entry, time zone information, or + free/busy time information, or an alarm. + + The body of the iCalendar object is defined by the following + notation: + + icalbody = calprops component + + calprops = 2*( + + ; 'prodid' and 'version' are both REQUIRED, + ; but MUST NOT occur more than once + + prodid /version / + + ; 'calscale' and 'method' are optional, + ; but MUST NOT occur more than once + + calscale / + method / + + x-prop + + + + +Dawson & Stenerson Standards Track [Page 51] +

+RFC 2445                       iCalendar                   November 1998
+
+
+                )
+
+     component  = 1*(eventc / todoc / journalc / freebusyc /
+                / timezonec / iana-comp / x-comp)
+
+     iana-comp  = "BEGIN" ":" iana-token CRLF
+
+                  1*contentline
+
+                  "END" ":" iana-token CRLF
+
+     x-comp     = "BEGIN" ":" x-name CRLF
+
+                  1*contentline
+
+                  "END" ":" x-name CRLF
+
+   An iCalendar object MUST include the "PRODID" and "VERSION" calendar
+   properties. In addition, it MUST include at least one calendar
+   component. Special forms of iCalendar objects are possible to publish
+   just busy time (i.e., only a "VFREEBUSY" calendar component) or time
+   zone (i.e., only a "VTIMEZONE" calendar component) information. In
+   addition, a complex iCalendar object is possible that is used to
+   capture a complete snapshot of the contents of a calendar (e.g.,
+   composite of many different calendar components). More commonly, an
+   iCalendar object will consist of just a single "VEVENT", "VTODO" or
+   "VJOURNAL" calendar component.
+
+

4.6.1 Event Component

+ + Component Name: "VEVENT" + + Purpose: Provide a grouping of component properties that describe an + event. + + Format Definition: A "VEVENT" calendar component is defined by the + following notation: + + eventc = "BEGIN" ":" "VEVENT" CRLF + eventprop *alarmc + "END" ":" "VEVENT" CRLF + + eventprop = *( + + ; the following are optional, + ; but MUST NOT occur more than once + + class / created / description / dtstart / geo / + + + +Dawson & Stenerson Standards Track [Page 52] +

+RFC 2445                       iCalendar                   November 1998
+
+
+                last-mod / location / organizer / priority /
+                dtstamp / seq / status / summary / transp /
+                uid / url / recurid /
+
+                ; either 'dtend' or 'duration' may appear in
+                ; a 'eventprop', but 'dtend' and 'duration'
+                ; MUST NOT occur in the same 'eventprop'
+
+                dtend / duration /
+
+                ; the following are optional,
+                ; and MAY occur more than once
+
+                attach / attendee / categories / comment /
+                contact / exdate / exrule / rstatus / related /
+                resources / rdate / rrule / x-prop
+
+                )
+
+   Description: A "VEVENT" calendar component is a grouping of component
+   properties, and possibly including "VALARM" calendar components, that
+   represents a scheduled amount of time on a calendar. For example, it
+   can be an activity; such as a one-hour long, department meeting from
+   8:00 AM to 9:00 AM, tomorrow. Generally, an event will take up time
+   on an individual calendar. Hence, the event will appear as an opaque
+   interval in a search for busy time. Alternately, the event can have
+   its Time Transparency set to "TRANSPARENT" in order to prevent
+   blocking of the event in searches for busy time.
+
+   The "VEVENT" is also the calendar component used to specify an
+   anniversary or daily reminder within a calendar. These events have a
+   DATE value type for the "DTSTART" property instead of the default
+   data type of DATE-TIME. If such a "VEVENT" has a "DTEND" property, it
+   MUST be specified as a DATE value also. The anniversary type of
+   "VEVENT" can span more than one date (i.e, "DTEND" property value is
+   set to a calendar date after the "DTSTART" property value).
+
+   The "DTSTART" property for a "VEVENT" specifies the inclusive start
+   of the event. For recurring events, it also specifies the very first
+   instance in the recurrence set. The "DTEND" property for a "VEVENT"
+   calendar component specifies the non-inclusive end of the event. For
+   cases where a "VEVENT" calendar component specifies a "DTSTART"
+   property with a DATE data type but no "DTEND" property, the events
+   non-inclusive end is the end of the calendar date specified by the
+   "DTSTART" property. For cases where a "VEVENT" calendar component
+   specifies a "DTSTART" property with a DATE-TIME data type but no
+   "DTEND" property, the event ends on the same calendar date and time
+   of day specified by the "DTSTART" property.
+
+
+
+Dawson & Stenerson          Standards Track                    [Page 53]
+

+RFC 2445                       iCalendar                   November 1998
+
+
+   The "VEVENT" calendar component cannot be nested within another
+   calendar component. However, "VEVENT" calendar components can be
+   related to each other or to a "VTODO" or to a "VJOURNAL" calendar
+   component with the "RELATED-TO" property.
+
+   Example: The following is an example of the "VEVENT" calendar
+   component used to represent a meeting that will also be opaque to
+   searches for busy time:
+
+     BEGIN:VEVENT
+     UID:19970901T130000Z-123401@host.com
+     DTSTAMP:19970901T1300Z
+     DTSTART:19970903T163000Z
+     DTEND:19970903T190000Z
+     SUMMARY:Annual Employee Review
+     CLASS:PRIVATE
+     CATEGORIES:BUSINESS,HUMAN RESOURCES
+     END:VEVENT
+
+   The following is an example of the "VEVENT" calendar component used
+   to represent a reminder that will not be opaque, but rather
+   transparent, to searches for busy time:
+
+     BEGIN:VEVENT
+     UID:19970901T130000Z-123402@host.com
+     DTSTAMP:19970901T1300Z
+     DTSTART:19970401T163000Z
+     DTEND:19970402T010000Z
+     SUMMARY:Laurel is in sensitivity awareness class.
+     CLASS:PUBLIC
+     CATEGORIES:BUSINESS,HUMAN RESOURCES
+     TRANSP:TRANSPARENT
+     END:VEVENT
+
+   The following is an example of the "VEVENT" calendar component used
+   to represent an anniversary that will occur annually. Since it takes
+   up no time, it will not appear as opaque in a search for busy time;
+   no matter what the value of the "TRANSP" property indicates:
+
+     BEGIN:VEVENT
+     UID:19970901T130000Z-123403@host.com
+     DTSTAMP:19970901T1300Z
+     DTSTART:19971102
+     SUMMARY:Our Blissful Anniversary
+     CLASS:CONFIDENTIAL
+     CATEGORIES:ANNIVERSARY,PERSONAL,SPECIAL OCCASION
+     RRULE:FREQ=YEARLY
+     END:VEVENT
+
+
+
+Dawson & Stenerson          Standards Track                    [Page 54]
+

+RFC 2445                       iCalendar                   November 1998
+
+
+

4.6.2 To-do Component

+ + Component Name: VTODO + + Purpose: Provide a grouping of calendar properties that describe a + to-do. + + Formal Definition: A "VTODO" calendar component is defined by the + following notation: + + todoc = "BEGIN" ":" "VTODO" CRLF + todoprop *alarmc + "END" ":" "VTODO" CRLF + + todoprop = *( + + ; the following are optional, + ; but MUST NOT occur more than once + + class / completed / created / description / dtstamp / + dtstart / geo / last-mod / location / organizer / + percent / priority / recurid / seq / status / + summary / uid / url / + + ; either 'due' or 'duration' may appear in + ; a 'todoprop', but 'due' and 'duration' + ; MUST NOT occur in the same 'todoprop' + + due / duration / + + ; the following are optional, + ; and MAY occur more than once + attach / attendee / categories / comment / contact / + exdate / exrule / rstatus / related / resources / + rdate / rrule / x-prop + + ) + + Description: A "VTODO" calendar component is a grouping of component + properties and possibly "VALARM" calendar components that represent + an action-item or assignment. For example, it can be used to + represent an item of work assigned to an individual; such as "turn in + travel expense today". + + The "VTODO" calendar component cannot be nested within another + calendar component. However, "VTODO" calendar components can be + related to each other or to a "VTODO" or to a "VJOURNAL" calendar + component with the "RELATED-TO" property. + + + +Dawson & Stenerson Standards Track [Page 55] +

+RFC 2445                       iCalendar                   November 1998
+
+
+   A "VTODO" calendar component without the "DTSTART" and "DUE" (or
+   "DURATION") properties specifies a to-do that will be associated with
+   each successive calendar date, until it is completed.
+
+   Example: The following is an example of a "VTODO" calendar component:
+
+     BEGIN:VTODO
+     UID:19970901T130000Z-123404@host.com
+     DTSTAMP:19970901T1300Z
+     DTSTART:19970415T133000Z
+     DUE:19970416T045959Z
+     SUMMARY:1996 Income Tax Preparation
+     CLASS:CONFIDENTIAL
+     CATEGORIES:FAMILY,FINANCE
+     PRIORITY:1
+     STATUS:NEEDS-ACTION
+     END:VTODO
+
+

4.6.3 Journal Component

+ + Component Name: VJOURNAL + + Purpose: Provide a grouping of component properties that describe a + journal entry. + + Formal Definition: A "VJOURNAL" calendar component is defined by the + following notation: + + journalc = "BEGIN" ":" "VJOURNAL" CRLF + jourprop + "END" ":" "VJOURNAL" CRLF + + jourprop = *( + + ; the following are optional, + ; but MUST NOT occur more than once + + class / created / description / dtstart / dtstamp / + last-mod / organizer / recurid / seq / status / + summary / uid / url / + + ; the following are optional, + ; and MAY occur more than once + + attach / attendee / categories / comment / + contact / exdate / exrule / related / rdate / + rrule / rstatus / x-prop + + + + +Dawson & Stenerson Standards Track [Page 56] +

+RFC 2445                       iCalendar                   November 1998
+
+
+                )
+
+   Description: A "VJOURNAL" calendar component is a grouping of
+   component properties that represent one or more descriptive text
+   notes associated with a particular calendar date. The "DTSTART"
+   property is used to specify the calendar date that the journal entry
+   is associated with. Generally, it will have a DATE value data type,
+   but it can also be used to specify a DATE-TIME value data type.
+   Examples of a journal entry include a daily record of a legislative
+   body or a journal entry of individual telephone contacts for the day
+   or an ordered list of accomplishments for the day. The "VJOURNAL"
+   calendar component can also be used to associate a document with a
+   calendar date.
+
+   The "VJOURNAL" calendar component does not take up time on a
+   calendar. Hence, it does not play a role in free or busy time
+   searches - - it is as though it has a time transparency value of
+   TRANSPARENT. It is transparent to any such searches.
+
+   The "VJOURNAL" calendar component cannot be nested within another
+   calendar component. However, "VJOURNAL" calendar components can be
+   related to each other or to a "VEVENT" or to a "VTODO" calendar
+   component, with the "RELATED-TO" property.
+
+   Example: The following is an example of the "VJOURNAL" calendar
+   component:
+
+     BEGIN:VJOURNAL
+     UID:19970901T130000Z-123405@host.com
+     DTSTAMP:19970901T1300Z
+     DTSTART;VALUE=DATE:19970317
+     SUMMARY:Staff meeting minutes
+     DESCRIPTION:1. Staff meeting: Participants include Joe\, Lisa
+       and Bob. Aurora project plans were reviewed. There is currently
+       no budget reserves for this project. Lisa will escalate to
+       management. Next meeting on Tuesday.\n
+       2. Telephone Conference: ABC Corp. sales representative called
+       to discuss new printer. Promised to get us a demo by Friday.\n
+       3. Henry Miller (Handsoff Insurance): Car was totaled by tree.
+       Is looking into a loaner car. 654-2323 (tel).
+     END:VJOURNAL
+
+
+
+
+
+
+
+
+
+
+Dawson & Stenerson          Standards Track                    [Page 57]
+

+RFC 2445                       iCalendar                   November 1998
+
+
+

4.6.4 Free/Busy Component

+ + Component Name: VFREEBUSY + + Purpose: Provide a grouping of component properties that describe + either a request for free/busy time, describe a response to a request + for free/busy time or describe a published set of busy time. + + Formal Definition: A "VFREEBUSY" calendar component is defined by the + following notation: + + freebusyc = "BEGIN" ":" "VFREEBUSY" CRLF + fbprop + "END" ":" "VFREEBUSY" CRLF + + fbprop = *( + + ; the following are optional, + ; but MUST NOT occur more than once + + contact / dtstart / dtend / duration / dtstamp / + organizer / uid / url / + + ; the following are optional, + ; and MAY occur more than once + + attendee / comment / freebusy / rstatus / x-prop + + ) + + Description: A "VFREEBUSY" calendar component is a grouping of + component properties that represents either a request for, a reply to + a request for free or busy time information or a published set of + busy time information. + + When used to request free/busy time information, the "ATTENDEE" + property specifies the calendar users whose free/busy time is being + requested; the "ORGANIZER" property specifies the calendar user who + is requesting the free/busy time; the "DTSTART" and "DTEND" + properties specify the window of time for which the free/busy time is + being requested; the "UID" and "DTSTAMP" properties are specified to + assist in proper sequencing of multiple free/busy time requests. + + When used to reply to a request for free/busy time, the "ATTENDEE" + property specifies the calendar user responding to the free/busy time + request; the "ORGANIZER" property specifies the calendar user that + originally requested the free/busy time; the "FREEBUSY" property + specifies the free/busy time information (if it exists); and the + + + +Dawson & Stenerson Standards Track [Page 58] +

+RFC 2445                       iCalendar                   November 1998
+
+
+   "UID" and "DTSTAMP" properties are specified to assist in proper
+   sequencing of multiple free/busy time replies.
+
+   When used to publish busy time, the "ORGANIZER" property specifies
+   the calendar user associated with the published busy time; the
+   "DTSTART" and "DTEND" properties specify an inclusive time window
+   that surrounds the busy time information; the "FREEBUSY" property
+   specifies the published busy time information; and the "DTSTAMP"
+   property specifies the date/time that iCalendar object was created.
+
+   The "VFREEBUSY" calendar component cannot be nested within another
+   calendar component. Multiple "VFREEBUSY" calendar components can be
+   specified within an iCalendar object. This permits the grouping of
+   Free/Busy information into logical collections, such as monthly
+   groups of busy time information.
+
+   The "VFREEBUSY" calendar component is intended for use in iCalendar
+   object methods involving requests for free time, requests for busy
+   time, requests for both free and busy, and the associated replies.
+
+   Free/Busy information is represented with the "FREEBUSY" property.
+   This property provides a terse representation of time periods. One or
+   more "FREEBUSY" properties can be specified in the "VFREEBUSY"
+   calendar component.
+
+   When present in a "VFREEBUSY" calendar component, the "DTSTART" and
+   "DTEND" properties SHOULD be specified prior to any "FREEBUSY"
+   properties. In a free time request, these properties can be used in
+   combination with the "DURATION" property to represent a request for a
+   duration of free time within a specified window of time.
+
+   The recurrence properties ("RRULE", "EXRULE", "RDATE", "EXDATE") are
+   not permitted within a "VFREEBUSY" calendar component. Any recurring
+   events are resolved into their individual busy time periods using the
+   "FREEBUSY" property.
+
+   Example: The following is an example of a "VFREEBUSY" calendar
+   component used to request free or busy time information:
+
+     BEGIN:VFREEBUSY
+     ORGANIZER:MAILTO:jane_doe@host1.com
+     ATTENDEE:MAILTO:john_public@host2.com
+     DTSTART:19971015T050000Z
+     DTEND:19971016T050000Z
+     DTSTAMP:19970901T083000Z
+     END:VFREEBUSY
+
+
+
+
+
+Dawson & Stenerson          Standards Track                    [Page 59]
+

+RFC 2445                       iCalendar                   November 1998
+
+
+   The following is an example of a "VFREEBUSY" calendar component used
+   to reply to the request with busy time information:
+
+     BEGIN:VFREEBUSY
+     ORGANIZER:MAILTO:jane_doe@host1.com
+     ATTENDEE:MAILTO:john_public@host2.com
+     DTSTAMP:19970901T100000Z
+     FREEBUSY;VALUE=PERIOD:19971015T050000Z/PT8H30M,
+      19971015T160000Z/PT5H30M,19971015T223000Z/PT6H30M
+     URL:http://host2.com/pub/busy/jpublic-01.ifb
+     COMMENT:This iCalendar file contains busy time information for
+       the next three months.
+     END:VFREEBUSY
+
+   The following is an example of a "VFREEBUSY" calendar component used
+   to publish busy time information.
+
+     BEGIN:VFREEBUSY
+     ORGANIZER:jsmith@host.com
+     DTSTART:19980313T141711Z
+     DTEND:19980410T141711Z
+     FREEBUSY:19980314T233000Z/19980315T003000Z
+     FREEBUSY:19980316T153000Z/19980316T163000Z
+     FREEBUSY:19980318T030000Z/19980318T040000Z
+     URL:http://www.host.com/calendar/busytime/jsmith.ifb
+     END:VFREEBUSY
+
+

4.6.5 Time Zone Component

+ + Component Name: VTIMEZONE + + Purpose: Provide a grouping of component properties that defines a + time zone. + + Formal Definition: A "VTIMEZONE" calendar component is defined by the + following notation: + + timezonec = "BEGIN" ":" "VTIMEZONE" CRLF + + 2*( + + ; 'tzid' is required, but MUST NOT occur more + ; than once + + tzid / + + ; 'last-mod' and 'tzurl' are optional, + but MUST NOT occur more than once + + + +Dawson & Stenerson Standards Track [Page 60] +

+RFC 2445                       iCalendar                   November 1998
+
+
+                last-mod / tzurl /
+
+                  ; one of 'standardc' or 'daylightc' MUST occur
+                ..; and each MAY occur more than once.
+
+                standardc / daylightc /
+
+                ; the following is optional,
+                ; and MAY occur more than once
+
+                  x-prop
+
+                  )
+
+                  "END" ":" "VTIMEZONE" CRLF
+
+     standardc  = "BEGIN" ":" "STANDARD" CRLF
+
+                  tzprop
+
+                  "END" ":" "STANDARD" CRLF
+
+     daylightc  = "BEGIN" ":" "DAYLIGHT" CRLF
+
+                  tzprop
+
+                  "END" ":" "DAYLIGHT" CRLF
+
+     tzprop     = 3*(
+
+                ; the following are each REQUIRED,
+                ; but MUST NOT occur more than once
+
+                dtstart / tzoffsetto / tzoffsetfrom /
+
+                ; the following are optional,
+                ; and MAY occur more than once
+
+                comment / rdate / rrule / tzname / x-prop
+
+                )
+
+   Description: A time zone is unambiguously defined by the set of time
+   measurement rules determined by the governing body for a given
+   geographic area. These rules describe at a minimum the base  offset
+   from UTC for the time zone, often referred to as the Standard Time
+   offset. Many locations adjust their Standard Time forward or backward
+   by one hour, in order to accommodate seasonal changes in number of
+
+
+
+Dawson & Stenerson          Standards Track                    [Page 61]
+

+RFC 2445                       iCalendar                   November 1998
+
+
+   daylight hours, often referred to as Daylight  Saving Time. Some
+   locations adjust their time by a fraction of an hour. Standard Time
+   is also known as Winter Time. Daylight Saving Time is also known as
+   Advanced Time, Summer Time, or Legal Time in certain countries. The
+   following table shows the changes in time zone rules in effect for
+   New York City starting from 1967. Each line represents a description
+   or rule for a particular observance.
+
+     Effective Observance Rule
+
+     Date       (Date/Time)             Offset  Abbreviation
+
+     1967-*     last Sun in Oct, 02:00  -0500   EST
+
+     1967-1973  last Sun in Apr, 02:00  -0400   EDT
+
+     1974-1974  Jan 6,  02:00           -0400   EDT
+
+     1975-1975  Feb 23, 02:00           -0400   EDT
+
+     1976-1986  last Sun in Apr, 02:00  -0400   EDT
+
+     1987-*     first Sun in Apr, 02:00 -0400   EDT
+
+        Note: The specification of a global time zone registry is not
+        addressed by this document and is left for future study.
+        However, implementers may find the Olson time zone database [TZ]
+        a useful reference. It is an informal, public-domain collection
+        of time zone information, which is currently being maintained by
+        volunteer Internet participants, and is used in several
+        operating systems. This database contains current and historical
+        time zone information for a wide variety of locations around the
+        globe; it provides a time zone identifier for every unique time
+        zone rule set in actual use since 1970, with historical data
+        going back to the introduction of standard time.
+
+   Interoperability between two calendaring and scheduling applications,
+   especially for recurring events, to-dos or journal entries, is
+   dependent on the ability to capture and convey date and time
+   information in an unambiguous format. The specification of current
+   time zone information is integral to this behavior.
+
+   If present, the "VTIMEZONE" calendar component defines the set of
+   Standard Time and Daylight Saving Time observances (or rules) for a
+   particular time zone for a given interval of time. The "VTIMEZONE"
+   calendar component cannot be nested within other calendar components.
+   Multiple "VTIMEZONE" calendar components can exist in an iCalendar
+   object. In this situation, each "VTIMEZONE" MUST represent a unique
+
+
+
+Dawson & Stenerson          Standards Track                    [Page 62]
+

+RFC 2445                       iCalendar                   November 1998
+
+
+   time zone definition. This is necessary for some classes of events,
+   such as airline flights, that start in one time zone and end in
+   another.
+
+   The "VTIMEZONE" calendar component MUST be present if the iCalendar
+   object contains an RRULE that generates dates on both sides of a time
+   zone shift (e.g. both in Standard Time and Daylight Saving Time)
+   unless the iCalendar object intends to convey a floating time (See
+   the section "4.1.10.11 Time" for proper interpretation of floating
+   time). It can be present if the iCalendar object does not contain
+   such a RRULE. In addition, if a RRULE is present, there MUST be valid
+   time zone information for all recurrence instances.
+
+   The "VTIMEZONE" calendar component MUST include the "TZID" property
+   and at least one definition of a standard or daylight component. The
+   standard or daylight component MUST include the "DTSTART",
+   "TZOFFSETFROM" and "TZOFFSETTO" properties.
+
+   An individual "VTIMEZONE" calendar component MUST be specified for
+   each unique "TZID" parameter value specified in the iCalendar object.
+
+   Each "VTIMEZONE" calendar component consists of a collection of one
+   or more sub-components that describe the rule for a particular
+   observance (either a Standard Time or a Daylight Saving Time
+   observance). The "STANDARD" sub-component consists of a collection of
+   properties that describe Standard Time. The "DAYLIGHT" sub-component
+   consists of a collection of properties that describe Daylight Saving
+   Time. In general this collection of properties consists of:
+
+        - the first onset date-time for the observance
+
+        - the last onset date-time for the observance, if a last onset
+          is known.
+
+        - the offset to be applied for the observance
+
+        - a rule that describes the day and time when the observance
+          takes effect
+
+        - an optional name for the observance
+
+   For a given time zone, there may be multiple unique definitions of
+   the observances over a period of time. Each observance is described
+   using either a "STANDARD" or "DAYLIGHT" sub-component. The collection
+   of these sub-components is used to describe the time zone for a given
+   period of time. The offset to apply at any given time is found by
+   locating the observance that has the last onset date and time before
+   the time in question, and using the offset value from that
+
+
+
+Dawson & Stenerson          Standards Track                    [Page 63]
+

+RFC 2445                       iCalendar                   November 1998
+
+
+   observance.
+
+   The top-level properties in a "VTIMEZONE" calendar component are:
+
+   The mandatory "TZID" property is a text value that uniquely
+   identifies the VTIMZONE calendar component within the scope of an
+   iCalendar object.
+
+   The optional "LAST-MODIFIED" property is a UTC value that specifies
+   the date and time that this time zone definition was last updated.
+
+   The optional "TZURL" property is url value that points to a published
+   VTIMEZONE definition. TZURL SHOULD refer to a resource that is
+   accessible by anyone who might need to interpret the object. This
+   SHOULD NOT normally be a file: URL or other URL that is not widely-
+   accessible.
+
+   The collection of properties that are used to define the STANDARD and
+   DAYLIGHT sub-components include:
+
+   The mandatory "DTSTART" property gives the effective onset date and
+   local time for the time zone sub-component definition. "DTSTART" in
+   this usage MUST be specified as a local DATE-TIME value.
+
+   The mandatory "TZOFFSETFROM" property gives the UTC offset which is
+   in use when the onset of this time zone observance begins.
+   "TZOFFSETFROM" is combined with "DTSTART" to define the effective
+   onset for the time zone sub-component definition. For example, the
+   following represents the time at which the observance of Standard
+   Time took effect in Fall 1967 for New York City:
+
+     DTSTART:19671029T020000
+
+     TZOFFSETFROM:-0400
+
+   The mandatory "TZOFFSETTO " property gives the UTC offset for the
+   time zone sub-component (Standard Time or Daylight Saving Time) when
+   this observance is in use.
+
+   The optional "TZNAME" property is the customary name for the time
+   zone. It may be specified multiple times, to allow for specifying
+   multiple language variants of the time zone names. This could be used
+   for displaying dates.
+
+   If specified, the onset for the observance defined by the time zone
+   sub-component is defined by either the "RRULE" or "RDATE" property.
+   If neither is specified, only one sub-component can be specified in
+   the "VTIMEZONE" calendar component and it is assumed that the single
+
+
+
+Dawson & Stenerson          Standards Track                    [Page 64]
+

+RFC 2445                       iCalendar                   November 1998
+
+
+   observance specified is always in effect.
+
+   The "RRULE" property defines the recurrence rule for the onset of the
+   observance defined by this time zone sub-component. Some specific
+   requirements for the usage of RRULE for this purpose include:
+
+        - If observance is known to have an effective end date, the
+        "UNTIL" recurrence rule parameter MUST be used to specify the
+        last valid onset of this observance (i.e., the UNTIL date-time
+        will be equal to the last instance generated by the recurrence
+        pattern). It MUST be specified in UTC time.
+
+        - The "DTSTART" and the "TZOFFSETTO" properties MUST be used
+        when generating the onset date-time values (instances) from the
+        RRULE.
+
+   Alternatively, the "RDATE" property can be used to define the onset
+   of the observance by giving the individual onset date and times.
+   "RDATE" in this usage MUST be specified as a local DATE-TIME value in
+   UTC time.
+
+   The optional "COMMENT" property is also allowed for descriptive
+   explanatory text.
+
+   Example: The following are examples of the "VTIMEZONE" calendar
+   component:
+
+   This is an example showing time zone information for the Eastern
+   United States using "RDATE" property. Note that this is only suitable
+   for a recurring event that starts on or later than April 6, 1997 at
+   03:00:00 EDT (i.e., the earliest effective transition date and time)
+   and ends no later than April 7, 1998 02:00:00 EST (i.e., latest valid
+   date and time for EST in this scenario). For example, this can be
+   used for a recurring event that occurs every Friday, 8am-9:00 AM,
+   starting June 1, 1997, ending December 31, 1997.
+
+     BEGIN:VTIMEZONE
+     TZID:US-Eastern
+     LAST-MODIFIED:19870101T000000Z
+     BEGIN:STANDARD
+     DTSTART:19971026T020000
+     RDATE:19971026T020000
+     TZOFFSETFROM:-0400
+     TZOFFSETTO:-0500
+     TZNAME:EST
+     END:STANDARD
+     BEGIN:DAYLIGHT
+     DTSTART:19971026T020000
+
+
+
+Dawson & Stenerson          Standards Track                    [Page 65]
+

+RFC 2445                       iCalendar                   November 1998
+
+
+     RDATE:19970406T020000
+     TZOFFSETFROM:-0500
+     TZOFFSETTO:-0400
+     TZNAME:EDT
+     END:DAYLIGHT
+     END:VTIMEZONE
+
+   This is a simple example showing the current time zone rules for the
+   Eastern United States using a RRULE recurrence pattern. Note that
+   there is no effective end date to either of the Standard Time or
+   Daylight Time rules. This information would be valid for a recurring
+   event starting today and continuing indefinitely.
+
+     BEGIN:VTIMEZONE
+     TZID:US-Eastern
+     LAST-MODIFIED:19870101T000000Z
+     TZURL:http://zones.stds_r_us.net/tz/US-Eastern
+     BEGIN:STANDARD
+     DTSTART:19671029T020000
+     RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
+     TZOFFSETFROM:-0400
+     TZOFFSETTO:-0500
+     TZNAME:EST
+     END:STANDARD
+     BEGIN:DAYLIGHT
+     DTSTART:19870405T020000
+     RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
+     TZOFFSETFROM:-0500
+     TZOFFSETTO:-0400
+     TZNAME:EDT
+     END:DAYLIGHT
+     END:VTIMEZONE
+
+   This is an example showing a fictitious set of rules for the Eastern
+   United States, where the Daylight Time rule has an effective end date
+   (i.e., after that date, Daylight Time is no longer observed).
+
+     BEGIN:VTIMEZONE
+     TZID:US--Fictitious-Eastern
+     LAST-MODIFIED:19870101T000000Z
+     BEGIN:STANDARD
+     DTSTART:19671029T020000
+     RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
+     TZOFFSETFROM:-0400
+     TZOFFSETTO:-0500
+     TZNAME:EST
+     END:STANDARD
+
+
+
+
+Dawson & Stenerson          Standards Track                    [Page 66]
+

+RFC 2445                       iCalendar                   November 1998
+
+
+     BEGIN:DAYLIGHT
+     DTSTART:19870405T020000
+     RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4;UNTIL=19980404T070000Z
+     TZOFFSETFROM:-0500
+     TZOFFSETTO:-0400
+     TZNAME:EDT
+     END:DAYLIGHT
+     END:VTIMEZONE
+
+   This is an example showing a fictitious set of rules for the Eastern
+   United States, where the first Daylight Time rule has an effective
+   end date. There is a second Daylight Time rule that picks up where
+   the other left off.
+
+     BEGIN:VTIMEZONE
+     TZID:US--Fictitious-Eastern
+     LAST-MODIFIED:19870101T000000Z
+     BEGIN:STANDARD
+     DTSTART:19671029T020000
+     RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
+     TZOFFSETFROM:-0400
+     TZOFFSETTO:-0500
+     TZNAME:EST
+     END:STANDARD
+     BEGIN:DAYLIGHT
+     DTSTART:19870405T020000
+     RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4;UNTIL=19980404T070000Z
+     TZOFFSETFROM:-0500
+     TZOFFSETTO:-0400
+     TZNAME:EDT
+     END:DAYLIGHT
+     BEGIN:DAYLIGHT
+     DTSTART:19990424T020000
+     RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=4
+     TZOFFSETFROM:-0500
+     TZOFFSETTO:-0400
+     TZNAME:EDT
+     END:DAYLIGHT
+     END:VTIMEZONE
+
+

4.6.6 Alarm Component

+ + Component Name: VALARM + + Purpose: Provide a grouping of component properties that define an + alarm. + + + + + +Dawson & Stenerson Standards Track [Page 67] +

+RFC 2445                       iCalendar                   November 1998
+
+
+   Formal Definition: A "VALARM" calendar component is defined by the
+   following notation:
+
+          alarmc     = "BEGIN" ":" "VALARM" CRLF
+                       (audioprop / dispprop / emailprop / procprop)
+                       "END" ":" "VALARM" CRLF
+
+     audioprop  = 2*(
+
+                ; 'action' and 'trigger' are both REQUIRED,
+                ; but MUST NOT occur more than once
+
+                action / trigger /
+
+                ; 'duration' and 'repeat' are both optional,
+                ; and MUST NOT occur more than once each,
+                ; but if one occurs, so MUST the other
+
+                duration / repeat /
+
+                ; the following is optional,
+                ; but MUST NOT occur more than once
+
+                attach /
+
+                ; the following is optional,
+                ; and MAY occur more than once
+
+                x-prop
+
+                )
+
+
+
+     dispprop   = 3*(
+
+                ; the following are all REQUIRED,
+                ; but MUST NOT occur more than once
+
+                action / description / trigger /
+
+                ; 'duration' and 'repeat' are both optional,
+                ; and MUST NOT occur more than once each,
+                ; but if one occurs, so MUST the other
+
+                duration / repeat /
+
+                ; the following is optional,
+
+
+
+Dawson & Stenerson          Standards Track                    [Page 68]
+

+RFC 2445                       iCalendar                   November 1998
+
+
+                ; and MAY occur more than once
+
+                *x-prop
+
+                )
+
+
+
+     emailprop  = 5*(
+
+                ; the following are all REQUIRED,
+                ; but MUST NOT occur more than once
+
+                action / description / trigger / summary
+
+                ; the following is REQUIRED,
+                ; and MAY occur more than once
+
+                attendee /
+
+                ; 'duration' and 'repeat' are both optional,
+                ; and MUST NOT occur more than once each,
+                ; but if one occurs, so MUST the other
+
+                duration / repeat /
+
+                ; the following are optional,
+                ; and MAY occur more than once
+
+                attach / x-prop
+
+                )
+
+
+
+     procprop   = 3*(
+
+                ; the following are all REQUIRED,
+                ; but MUST NOT occur more than once
+
+                action / attach / trigger /
+
+                ; 'duration' and 'repeat' are both optional,
+                ; and MUST NOT occur more than once each,
+                ; but if one occurs, so MUST the other
+
+                duration / repeat /
+
+
+
+
+Dawson & Stenerson          Standards Track                    [Page 69]
+

+RFC 2445                       iCalendar                   November 1998
+
+
+                ; 'description' is optional,
+                ; and MUST NOT occur more than once
+
+                description /
+
+                ; the following is optional,
+                ; and MAY occur more than once
+
+                x-prop
+
+                )
+
+   Description: A "VALARM" calendar component is a grouping of component
+   properties that is a reminder or alarm for an event or a to-do. For
+   example, it may be used to define a reminder for a pending event or
+   an overdue to-do.
+
+   The "VALARM" calendar component MUST include the "ACTION" and
+   "TRIGGER" properties. The "ACTION" property further constrains the
+   "VALARM" calendar component in the following ways:
+
+   When the action is "AUDIO", the alarm can also include one and only
+   one "ATTACH" property, which MUST point to a sound resource, which is
+   rendered when the alarm is triggered.
+
+   When the action is "DISPLAY", the alarm MUST also include a
+   "DESCRIPTION" property, which contains the text to be displayed when
+   the alarm is triggered.
+
+   When the action is "EMAIL", the alarm MUST include a "DESCRIPTION"
+   property, which contains the text to be used as the message body, a
+   "SUMMARY" property, which contains the text to be used as the message
+   subject, and one or more "ATTENDEE" properties, which contain the
+   email address of attendees to receive the message. It can also
+   include one or more "ATTACH" properties, which are intended to be
+   sent as message attachments. When the alarm is triggered, the email
+   message is sent.
+
+   When the action is "PROCEDURE", the alarm MUST include one and only
+   one "ATTACH" property, which MUST point to a procedure resource,
+   which is invoked when the alarm is triggered.
+
+   The "VALARM" calendar component MUST only appear within either a
+   "VEVENT" or "VTODO" calendar component. "VALARM" calendar components
+   cannot be nested. Multiple mutually independent "VALARM" calendar
+   components can be specified for a single "VEVENT" or "VTODO" calendar
+   component.
+
+
+
+
+Dawson & Stenerson          Standards Track                    [Page 70]
+

+RFC 2445                       iCalendar                   November 1998
+
+
+   The "TRIGGER" property specifies when the alarm will be triggered.
+   The "TRIGGER" property specifies a duration prior to the start of an
+   event or a to-do. The "TRIGGER" edge may be explicitly set to be
+   relative to the "START" or "END" of the event or to-do with the
+   "RELATED" parameter of the "TRIGGER" property. The "TRIGGER" property
+   value type can alternatively be set to an absolute calendar date and
+   time of day value.
+
+   In an alarm set to trigger on the "START" of an event or to-do, the
+   "DTSTART" property MUST be present in the associated event or to-do.
+   In an alarm in a "VEVENT" calendar component set to trigger on the
+   "END" of the event, either the "DTEND" property MUST be present, or
+   the "DTSTART" and "DURATION" properties MUST both be present. In an
+   alarm in a "VTODO" calendar component set to trigger on the "END" of
+   the to-do, either the "DUE" property MUST be present, or the
+   "DTSTART" and "DURATION" properties MUST both be present.
+
+   The alarm can be defined such that it triggers repeatedly. A
+   definition of an alarm with a repeating trigger MUST include both the
+   "DURATION" and "REPEAT" properties. The "DURATION" property specifies
+   the delay period, after which the alarm will repeat. The "REPEAT"
+   property specifies the number of additional repetitions that the
+   alarm will triggered. This repitition count is in addition to the
+   initial triggering of the alarm. Both of these properties MUST be
+   present in order to specify a repeating alarm. If one of these two
+   properties is absent, then the alarm will not repeat beyond the
+   initial trigger.
+
+   The "ACTION" property is used within the "VALARM" calendar component
+   to specify the type of action invoked when the alarm is triggered.
+   The "VALARM" properties provide enough information for a specific
+   action to be invoked. It is typically the responsibility of a
+   "Calendar User Agent" (CUA) to deliver the alarm in the specified
+   fashion. An "ACTION" property value of AUDIO specifies an alarm that
+   causes a sound to be played to alert the user; DISPLAY specifies an
+   alarm that causes a text message to be displayed to the user; EMAIL
+   specifies an alarm that causes an electronic email message to be
+   delivered to one or more email addresses; and PROCEDURE specifies an
+   alarm that causes a procedure to be executed. The "ACTION" property
+   MUST specify one and only one of these values.
+
+   In an AUDIO alarm, if the optional "ATTACH" property is included, it
+   MUST specify an audio sound resource. The intention is that the sound
+   will be played as the alarm effect. If an "ATTACH" property is
+   specified that does not refer to a sound resource, or if the
+   specified sound resource cannot be rendered (because its format is
+   unsupported, or because it cannot be retrieved), then the CUA or
+   other entity responsible for playing the sound may choose a fallback
+
+
+
+Dawson & Stenerson          Standards Track                    [Page 71]
+

+RFC 2445                       iCalendar                   November 1998
+
+
+   action, such as playing a built-in default sound, or playing no sound
+   at all.
+
+   In a DISPLAY alarm, the intended alarm effect is for the text value
+   of the "DESCRIPTION" property to be displayed to the user.
+
+   In an EMAIL alarm, the intended alarm effect is for an email message
+   to be composed and delivered to all the addresses specified by the
+   "ATTENDEE" properties in the "VALARM" calendar component. The
+   "DESCRIPTION" property of the "VALARM" calendar component MUST be
+   used as the body text of the message, and the "SUMMARY" property MUST
+   be used as the subject text. Any "ATTACH" properties in the "VALARM"
+   calendar component SHOULD be sent as attachments to the message.
+
+   In a PROCEDURE alarm, the "ATTACH" property in the "VALARM" calendar
+   component MUST specify a procedure or program that is intended to be
+   invoked as the alarm effect. If the procedure or program is in a
+   format that cannot be rendered, then no procedure alarm will be
+   invoked. If the "DESCRIPTION" property is present, its value
+   specifies the argument string to be passed to the procedure or
+   program. "Calendar User Agents" that receive an iCalendar object with
+   this category of alarm, can disable or allow the "Calendar User" to
+   disable, or otherwise ignore this type of alarm. While a very useful
+   alarm capability, the PROCEDURE type of alarm SHOULD be treated by
+   the "Calendar User Agent" as a potential security risk.
+
+   Example: The following example is for a "VALARM" calendar component
+   that specifies an audio alarm that will sound at a precise time and
+   repeat 4 more times at 15 minute intervals:
+
+     BEGIN:VALARM
+     TRIGGER;VALUE=DATE-TIME:19970317T133000Z
+     REPEAT:4
+     DURATION:PT15M
+     ACTION:AUDIO
+     ATTACH;FMTTYPE=audio/basic:ftp://host.com/pub/sounds/bell-01.aud
+     END:VALARM
+
+   The following example is for a "VALARM" calendar component that
+   specifies a display alarm that will trigger 30 minutes before the
+   scheduled start of the event or the due date/time of the to-do it is
+   associated with and will repeat 2 more times at 15 minute intervals:
+
+     BEGIN:VALARM
+     TRIGGER:-PT30M
+     REPEAT:2
+     DURATION:PT15M
+     ACTION:DISPLAY
+
+
+
+Dawson & Stenerson          Standards Track                    [Page 72]
+

+RFC 2445                       iCalendar                   November 1998
+
+
+     DESCRIPTION:Breakfast meeting with executive\n
+      team at 8:30 AM EST.
+     END:VALARM
+
+   The following example is for a "VALARM" calendar component that
+   specifies an email alarm that will trigger 2 days before the
+   scheduled due date/time of a to-do it is associated with. It does not
+   repeat. The email has a subject, body and attachment link.
+
+     BEGIN:VALARM
+     TRIGGER:-P2D
+     ACTION:EMAIL
+     ATTENDEE:MAILTO:john_doe@host.com
+     SUMMARY:*** REMINDER: SEND AGENDA FOR WEEKLY STAFF MEETING ***
+     DESCRIPTION:A draft agenda needs to be sent out to the attendees
+       to the weekly managers meeting (MGR-LIST). Attached is a
+       pointer the document template for the agenda file.
+     ATTACH;FMTTYPE=application/binary:http://host.com/templates/agen
+      da.doc
+     END:VALARM
+
+   The following example is for a "VALARM" calendar component that
+   specifies a procedural alarm that will trigger at a precise date/time
+   and will repeat 23 more times at one hour intervals. The alarm will
+   invoke a procedure file.
+
+     BEGIN:VALARM
+     TRIGGER;VALUE=DATE-TIME:19980101T050000Z
+     REPEAT:23
+     DURATION:PT1H
+     ACTION:PROCEDURE
+     ATTACH;FMTTYPE=application/binary:ftp://host.com/novo-
+      procs/felizano.exe
+     END:VALARM
+
+

4.7 Calendar Properties

+ + The Calendar Properties are attributes that apply to the iCalendar + object, as a whole. These properties do not appear within a calendar + component. They SHOULD be specified after the "BEGIN:VCALENDAR" + property and prior to any calendar component. + +

4.7.1 Calendar Scale

+ + Property Name: CALSCALE + + Purpose: This property defines the calendar scale used for the + calendar information specified in the iCalendar object. + + + +Dawson & Stenerson Standards Track [Page 73] +

+RFC 2445                       iCalendar                   November 1998
+
+
+   Value Type: TEXT
+
+   Property Parameters: Non-standard property parameters can be
+   specified on this property.
+
+   Conformance: Property can be specified in an iCalendar object. The
+   default value is "GREGORIAN".
+
+   Description: This memo is based on the Gregorian calendar scale. The
+   Gregorian calendar scale is assumed if this property is not specified
+   in the iCalendar object. It is expected that other calendar scales
+   will be defined in other specifications or by future versions of this
+   memo.
+
+   Format Definition: The property is defined by the following notation:
+
+     calscale   = "CALSCALE" calparam ":" calvalue CRLF
+
+     calparam   = *(";" xparam)
+
+     calvalue   = "GREGORIAN" / iana-token
+
+   Example: The following is an example of this property:
+
+     CALSCALE:GREGORIAN
+
+

4.7.2 Method

+ + Property Name: METHOD + + Purpose: This property defines the iCalendar object method associated + with the calendar object. + + Value Type: TEXT + + Property Parameters: Non-standard property parameters can be + specified on this property. + + Conformance: The property can be specified in an iCalendar object. + + Description: When used in a MIME message entity, the value of this + property MUST be the same as the Content-Type "method" parameter + value. This property can only appear once within the iCalendar + object. If either the "METHOD" property or the Content-Type "method" + parameter is specified, then the other MUST also be specified. + + No methods are defined by this specification. This is the subject of + other specifications, such as the iCalendar Transport-independent + + + +Dawson & Stenerson Standards Track [Page 74] +

+RFC 2445                       iCalendar                   November 1998
+
+
+   Interoperability Protocol (iTIP) defined by [ITIP].
+
+   If this property is not present in the iCalendar object, then a
+   scheduling transaction MUST NOT be assumed. In such cases, the
+   iCalendar object is merely being used to transport a snapshot of some
+   calendar information; without the intention of conveying a scheduling
+   semantic.
+
+   Format Definition: The property is defined by the following notation:
+
+     method     = "METHOD" metparam ":" metvalue CRLF
+
+     metparam   = *(";" xparam)
+
+     metvalue   = iana-token
+
+   Example: The following is a hypothetical example of this property to
+   convey that the iCalendar object is a request for a meeting:
+
+     METHOD:REQUEST
+
+

4.7.3 Product Identifier

+ + Property Name: PRODID + + Purpose: This property specifies the identifier for the product that + created the iCalendar object. + + Value Type: TEXT + + Property Parameters: Non-standard property parameters can be + specified on this property. + + Conformance: The property MUST be specified once in an iCalendar + object. + + Description: The vendor of the implementation SHOULD assure that this + is a globally unique identifier; using some technique such as an FPI + value, as defined in [ISO 9070]. + + This property SHOULD not be used to alter the interpretation of an + iCalendar object beyond the semantics specified in this memo. For + example, it is not to be used to further the understanding of non- + standard properties. + + Format Definition: The property is defined by the following notation: + + prodid = "PRODID" pidparam ":" pidvalue CRLF + + + +Dawson & Stenerson Standards Track [Page 75] +

+RFC 2445                       iCalendar                   November 1998
+
+
+     pidparam   = *(";" xparam)
+
+     pidvalue   = text
+     ;Any text that describes the product and version
+     ;and that is generally assured of being unique.
+
+   Example: The following is an example of this property. It does not
+   imply that English is the default language.
+
+     PRODID:-//ABC Corporation//NONSGML My Product//EN
+
+

4.7.4 Version

+ + Property Name: VERSION + + Purpose: This property specifies the identifier corresponding to the + highest version number or the minimum and maximum range of the + iCalendar specification that is required in order to interpret the + iCalendar object. + + Value Type: TEXT + + Property Parameters: Non-standard property parameters can be + specified on this property. + + Conformance: This property MUST be specified by an iCalendar object, + but MUST only be specified once. + + Description: A value of "2.0" corresponds to this memo. + + Format Definition: The property is defined by the following notation: + + version = "VERSION" verparam ":" vervalue CRLF + + verparam = *(";" xparam) + + vervalue = "2.0" ;This memo + / maxver + / (minver ";" maxver) + + minver = <A IANA registered iCalendar version identifier> + ;Minimum iCalendar version needed to parse the iCalendar object + + maxver = <A IANA registered iCalendar version identifier> + ;Maximum iCalendar version needed to parse the iCalendar object + + Example: The following is an example of this property: + + + + +Dawson & Stenerson Standards Track [Page 76] +

+RFC 2445                       iCalendar                   November 1998
+
+
+     VERSION:2.0
+
+

4.8 Component Properties

+ + The following properties can appear within calendar components, as + specified by each component property definition. + +

4.8.1 Descriptive Component Properties

+ + The following properties specify descriptive information about + calendar components. + +
4.8.1.1 Attachment
+ + Property Name: ATTACH + + Purpose: The property provides the capability to associate a document + object with a calendar component. + + Value Type: The default value type for this property is URI. The + value type can also be set to BINARY to indicate inline binary + encoded content information. + + Property Parameters: Non-standard, inline encoding, format type and + value data type property parameters can be specified on this + property. + + Conformance: The property can be specified in a "VEVENT", "VTODO", + "VJOURNAL" or "VALARM" calendar components. + + Description: The property can be specified within "VEVENT", "VTODO", + "VJOURNAL", or "VALARM" calendar components. This property can be + specified multiple times within an iCalendar object. + + Format Definition: The property is defined by the following notation: + + attach = "ATTACH" attparam ":" uri CRLF + + attach =/ "ATTACH" attparam ";" "ENCODING" "=" "BASE64" + ";" "VALUE" "=" "BINARY" ":" binary + + attparam = *( + + ; the following is optional, + ; but MUST NOT occur more than once + + (";" fmttypeparam) / + + + + +Dawson & Stenerson Standards Track [Page 77] +

+RFC 2445                       iCalendar                   November 1998
+
+
+                ; the following is optional,
+                ; and MAY occur more than once
+
+                (";" xparam)
+
+                )
+
+   Example: The following are examples of this property:
+
+     ATTACH:CID:jsmith.part3.960817T083000.xyzMail@host1.com
+
+     ATTACH;FMTTYPE=application/postscript:ftp://xyzCorp.com/pub/
+      reports/r-960812.ps
+
+
4.8.1.2 Categories
+ + Property Name: CATEGORIES + + Purpose: This property defines the categories for a calendar + component. + + Value Type: TEXT + + Property Parameters: Non-standard and language property parameters + can be specified on this property. + + Conformance: The property can be specified within "VEVENT", "VTODO" + or "VJOURNAL" calendar components. + + Description: This property is used to specify categories or subtypes + of the calendar component. The categories are useful in searching for + a calendar component of a particular type and category. Within the + "VEVENT", "VTODO" or "VJOURNAL" calendar components, more than one + category can be specified as a list of categories separated by the + COMMA character (US-ASCII decimal 44). + + Format Definition: The property is defined by the following notation: + + categories = "CATEGORIES" catparam ":" text *("," text) + CRLF + + catparam = *( + + ; the following is optional, + ; but MUST NOT occur more than once + + (";" languageparam ) / + + + + +Dawson & Stenerson Standards Track [Page 78] +

+RFC 2445                       iCalendar                   November 1998
+
+
+                ; the following is optional,
+                ; and MAY occur more than once
+
+                (";" xparam)
+
+                )
+
+   Example: The following are examples of this property:
+
+     CATEGORIES:APPOINTMENT,EDUCATION
+
+     CATEGORIES:MEETING
+
+
4.8.1.3 Classification
+ + Property Name: CLASS + + Purpose: This property defines the access classification for a + calendar component. + + Value Type: TEXT + + Property Parameters: Non-standard property parameters can be + specified on this property. + + Conformance: The property can be specified once in a "VEVENT", + "VTODO" or "VJOURNAL" calendar components. + + Description: An access classification is only one component of the + general security system within a calendar application. It provides a + method of capturing the scope of the access the calendar owner + intends for information within an individual calendar entry. The + access classification of an individual iCalendar component is useful + when measured along with the other security components of a calendar + system (e.g., calendar user authentication, authorization, access + rights, access role, etc.). Hence, the semantics of the individual + access classifications cannot be completely defined by this memo + alone. Additionally, due to the "blind" nature of most exchange + processes using this memo, these access classifications cannot serve + as an enforcement statement for a system receiving an iCalendar + object. Rather, they provide a method for capturing the intention of + the calendar owner for the access to the calendar component. + + Format Definition: The property is defined by the following notation: + + class = "CLASS" classparam ":" classvalue CRLF + + classparam = *(";" xparam) + + + +Dawson & Stenerson Standards Track [Page 79] +

+RFC 2445                       iCalendar                   November 1998
+
+
+     classvalue = "PUBLIC" / "PRIVATE" / "CONFIDENTIAL" / iana-token
+                / x-name
+     ;Default is PUBLIC
+
+   Example: The following is an example of this property:
+
+     CLASS:PUBLIC
+
+
4.8.1.4 Comment
+ + Property Name: COMMENT + + Purpose: This property specifies non-processing information intended + to provide a comment to the calendar user. + + Value Type: TEXT + + Property Parameters: Non-standard, alternate text representation and + language property parameters can be specified on this property. + + Conformance: This property can be specified in "VEVENT", "VTODO", + "VJOURNAL", "VTIMEZONE" or "VFREEBUSY" calendar components. + + Description: The property can be specified multiple times. + + Format Definition: The property is defined by the following notation: + + comment = "COMMENT" commparam ":" text CRLF + + commparam = *( + + ; the following are optional, + ; but MUST NOT occur more than once + + (";" altrepparam) / (";" languageparam) / + + ; the following is optional, + ; and MAY occur more than once + + (";" xparam) + + ) + + Example: The following is an example of this property: + + COMMENT:The meeting really needs to include both ourselves + and the customer. We can't hold this meeting without them. + As a matter of fact\, the venue for the meeting ought to be at + + + +Dawson & Stenerson Standards Track [Page 80] +

+RFC 2445                       iCalendar                   November 1998
+
+
+       their site. - - John
+
+   The data type for this property is TEXT.
+
+
4.8.1.5 Description
+ + Property Name: DESCRIPTION + + Purpose: This property provides a more complete description of the + calendar component, than that provided by the "SUMMARY" property. + + Value Type: TEXT + + Property Parameters: Non-standard, alternate text representation and + language property parameters can be specified on this property. + + Conformance: The property can be specified in the "VEVENT", "VTODO", + "VJOURNAL" or "VALARM" calendar components. The property can be + specified multiple times only within a "VJOURNAL" calendar component. + + Description: This property is used in the "VEVENT" and "VTODO" to + capture lengthy textual decriptions associated with the activity. + + This property is used in the "VJOURNAL" calendar component to capture + one more textual journal entries. + + This property is used in the "VALARM" calendar component to capture + the display text for a DISPLAY category of alarm, to capture the body + text for an EMAIL category of alarm and to capture the argument + string for a PROCEDURE category of alarm. + + Format Definition: The property is defined by the following notation: + + description = "DESCRIPTION" descparam ":" text CRLF + + descparam = *( + + ; the following are optional, + ; but MUST NOT occur more than once + + (";" altrepparam) / (";" languageparam) / + + ; the following is optional, + ; and MAY occur more than once + + (";" xparam) + + ) + + + +Dawson & Stenerson Standards Track [Page 81] +

+RFC 2445                       iCalendar                   November 1998
+
+
+   Example: The following is an example of the property with formatted
+   line breaks in the property value:
+
+     DESCRIPTION:Meeting to provide technical review for "Phoenix"
+       design.\n Happy Face Conference Room. Phoenix design team
+       MUST attend this meeting.\n RSVP to team leader.
+
+   The following is an example of the property with folding of long
+   lines:
+
+     DESCRIPTION:Last draft of the new novel is to be completed
+       for the editor's proof today.
+
+
4.8.1.6 Geographic Position
+ + Property Name: GEO + + Purpose: This property specifies information related to the global + position for the activity specified by a calendar component. + + Value Type: FLOAT. The value MUST be two SEMICOLON separated FLOAT + values. + + Property Parameters: Non-standard property parameters can be + specified on this property. + + Conformance: This property can be specified in "VEVENT" or "VTODO" + calendar components. + + Description: The property value specifies latitude and longitude, in + that order (i.e., "LAT LON" ordering). The longitude represents the + location east or west of the prime meridian as a positive or negative + real number, respectively. The longitude and latitude values MAY be + specified up to six decimal places, which will allow for accuracy to + within one meter of geographical position. Receiving applications + MUST accept values of this precision and MAY truncate values of + greater precision. + + Values for latitude and longitude shall be expressed as decimal + fractions of degrees. Whole degrees of latitude shall be represented + by a two-digit decimal number ranging from 0 through 90. Whole + degrees of longitude shall be represented by a decimal number ranging + from 0 through 180. When a decimal fraction of a degree is specified, + it shall be separated from the whole number of degrees by a decimal + point. + + + + + + +Dawson & Stenerson Standards Track [Page 82] +

+RFC 2445                       iCalendar                   November 1998
+
+
+   Latitudes north of the equator shall be specified by a plus sign (+),
+   or by the absence of a minus sign (-), preceding the digits
+   designating degrees. Latitudes south of the Equator shall be
+   designated by a minus sign (-) preceding the digits designating
+   degrees. A point on the Equator shall be assigned to the Northern
+   Hemisphere.
+
+   Longitudes east of the prime meridian shall be specified by a plus
+   sign (+), or by the absence of a minus sign (-), preceding the digits
+   designating degrees. Longitudes west of the meridian shall be
+   designated by minus sign (-) preceding the digits designating
+   degrees. A point on the prime meridian shall be assigned to the
+   Eastern Hemisphere. A point on the 180th meridian shall be assigned
+   to the Western Hemisphere. One exception to this last convention is
+   permitted. For the special condition of describing a band of latitude
+   around the earth, the East Bounding Coordinate data element shall be
+   assigned the value +180 (180) degrees.
+
+   Any spatial address with a latitude of +90 (90) or -90 degrees will
+   specify the position at the North or South Pole, respectively. The
+   component for longitude may have any legal value.
+
+   With the exception of the special condition described above, this
+   form is specified in Department of Commerce, 1986, Representation of
+   geographic point locations for information interchange (Federal
+   Information Processing Standard 70-1):  Washington,  Department of
+   Commerce, National Institute of Standards and Technology.
+
+   The simple formula for converting degrees-minutes-seconds into
+   decimal degrees is:
+
+     decimal = degrees + minutes/60 + seconds/3600.
+
+   Format Definition: The property is defined by the following notation:
+
+     geo        = "GEO" geoparam ":" geovalue CRLF
+
+     geoparam   = *(";" xparam)
+
+     geovalue   = float ";" float
+     ;Latitude and Longitude components
+
+   Example: The following is an example of this property:
+
+     GEO:37.386013;-122.082932
+
+
+
+
+
+
+Dawson & Stenerson          Standards Track                    [Page 83]
+

+RFC 2445                       iCalendar                   November 1998
+
+
+
4.8.1.7 Location
+ + Property Name: LOCATION + + Purpose: The property defines the intended venue for the activity + defined by a calendar component. + + Value Type: TEXT + + Property Parameters: Non-standard, alternate text representation and + language property parameters can be specified on this property. + + Conformance: This property can be specified in "VEVENT" or "VTODO" + calendar component. + + Description: Specific venues such as conference or meeting rooms may + be explicitly specified using this property. An alternate + representation may be specified that is a URI that points to + directory information with more structured specification of the + location. For example, the alternate representation may specify + either an LDAP URI pointing to an LDAP server entry or a CID URI + pointing to a MIME body part containing a vCard [RFC 2426] for the + location. + + Format Definition: The property is defined by the following notation: + + location = "LOCATION locparam ":" text CRLF + + locparam = *( + + ; the following are optional, + ; but MUST NOT occur more than once + + (";" altrepparam) / (";" languageparam) / + + ; the following is optional, + ; and MAY occur more than once + + (";" xparam) + + ) + + Example: The following are some examples of this property: + + LOCATION:Conference Room - F123, Bldg. 002 + + LOCATION;ALTREP="http://xyzcorp.com/conf-rooms/f123.vcf": + Conference Room - F123, Bldg. 002 + + + +Dawson & Stenerson Standards Track [Page 84] +

+RFC 2445                       iCalendar                   November 1998
+
+
+
4.8.1.8 Percent Complete
+ + Property Name: PERCENT-COMPLETE + + Purpose: This property is used by an assignee or delegatee of a to-do + to convey the percent completion of a to-do to the Organizer. + + Value Type: INTEGER + + Property Parameters: Non-standard property parameters can be + specified on this property. + + Conformance: This property can be specified in a "VTODO" calendar + component. + + Description: The property value is a positive integer between zero + and one hundred. A value of "0" indicates the to-do has not yet been + started. A value of "100" indicates that the to-do has been + completed. Integer values in between indicate the percent partially + complete. + + When a to-do is assigned to multiple individuals, the property value + indicates the percent complete for that portion of the to-do assigned + to the assignee or delegatee. For example, if a to-do is assigned to + both individuals "A" and "B". A reply from "A" with a percent + complete of "70" indicates that "A" has completed 70% of the to-do + assigned to them. A reply from "B" with a percent complete of "50" + indicates "B" has completed 50% of the to-do assigned to them. + + Format Definition: The property is defined by the following notation: + + percent = "PERCENT-COMPLETE" pctparam ":" integer CRLF + + pctparam = *(";" xparam) + + Example: The following is an example of this property to show 39% + completion: + + PERCENT-COMPLETE:39 + +
4.8.1.9 Priority
+ + Property Name: PRIORITY + + Purpose: The property defines the relative priority for a calendar + component. + + Value Type: INTEGER + + + +Dawson & Stenerson Standards Track [Page 85] +

+RFC 2445                       iCalendar                   November 1998
+
+
+   Property Parameters: Non-standard property parameters can be
+   specified on this property.
+
+   Conformance: The property can be specified in a "VEVENT" or "VTODO"
+   calendar component.
+
+   Description: The priority is specified as an integer in the range
+   zero to nine. A value of zero (US-ASCII decimal 48) specifies an
+   undefined priority. A value of one (US-ASCII decimal 49) is the
+   highest priority. A value of two (US-ASCII decimal 50) is the second
+   highest priority. Subsequent numbers specify a decreasing ordinal
+   priority. A value of nine (US-ASCII decimal 58) is the lowest
+   priority.
+
+   A CUA with a three-level priority scheme of "HIGH", "MEDIUM" and
+   "LOW" is mapped into this property such that a property value in the
+   range of one (US-ASCII decimal 49) to four (US-ASCII decimal 52)
+   specifies "HIGH" priority. A value of five (US-ASCII decimal 53) is
+   the normal or "MEDIUM" priority. A value in the range of six (US-
+   ASCII decimal 54) to nine (US-ASCII decimal 58) is "LOW" priority.
+
+   A CUA with a priority schema of "A1", "A2", "A3", "B1", "B2", ...,
+   "C3" is mapped into this property such that a property value of one
+   (US-ASCII decimal 49) specifies "A1", a property value of two (US-
+   ASCII decimal 50) specifies "A2", a property value of three (US-ASCII
+   decimal 51) specifies "A3", and so forth up to a property value of 9
+   (US-ASCII decimal 58) specifies "C3".
+
+   Other integer values are reserved for future use.
+
+   Within a "VEVENT" calendar component, this property specifies a
+   priority for the event. This property may be useful when more than
+   one event is scheduled for a given time period.
+
+   Within a "VTODO" calendar component, this property specified a
+   priority for the to-do. This property is useful in prioritizing
+   multiple action items for a given time period.
+
+   Format Definition: The property is specified by the following
+   notation:
+
+     priority   = "PRIORITY" prioparam ":" privalue CRLF
+     ;Default is zero
+
+     prioparam  = *(";" xparam)
+
+     privalue   = integer       ;Must be in the range [0..9]
+        ; All other values are reserved for future use
+
+
+
+Dawson & Stenerson          Standards Track                    [Page 86]
+

+RFC 2445                       iCalendar                   November 1998
+
+
+   The following is an example of a property with the highest priority:
+
+     PRIORITY:1
+
+   The following is an example of a property with a next highest
+   priority:
+
+     PRIORITY:2
+
+   Example: The following is an example of a property with no priority.
+   This is equivalent to not specifying the "PRIORITY" property:
+
+     PRIORITY:0
+
+
4.8.1.10 Resources
+ + Property Name: RESOURCES + + Purpose: This property defines the equipment or resources anticipated + for an activity specified by a calendar entity.. + + Value Type: TEXT + + Property Parameters: Non-standard, alternate text representation and + language property parameters can be specified on this property. + + Conformance: This property can be specified in "VEVENT" or "VTODO" + calendar component. + + Description: The property value is an arbitrary text. More than one + resource can be specified as a list of resources separated by the + COMMA character (US-ASCII decimal 44). + + Format Definition: The property is defined by the following notation: + + resources = "RESOURCES" resrcparam ":" text *("," text) CRLF + + resrcparam = *( + + ; the following are optional, + ; but MUST NOT occur more than once + + (";" altrepparam) / (";" languageparam) / + + ; the following is optional, + ; and MAY occur more than once + + + + + +Dawson & Stenerson Standards Track [Page 87] +

+RFC 2445                       iCalendar                   November 1998
+
+
+                (";" xparam)
+
+                )
+
+   Example: The following is an example of this property:
+
+     RESOURCES:EASEL,PROJECTOR,VCR
+
+     RESOURCES;LANGUAGE=fr:1 raton-laveur
+
+
4.8.1.11 Status
+ + Property Name: STATUS + + Purpose: This property defines the overall status or confirmation for + the calendar component. + + Value Type: TEXT + + Property Parameters: Non-standard property parameters can be + specified on this property. + + Conformance: This property can be specified in "VEVENT", "VTODO" or + "VJOURNAL" calendar components. + + Description: In a group scheduled calendar component, the property is + used by the "Organizer" to provide a confirmation of the event to the + "Attendees". For example in a "VEVENT" calendar component, the + "Organizer" can indicate that a meeting is tentative, confirmed or + cancelled. In a "VTODO" calendar component, the "Organizer" can + indicate that an action item needs action, is completed, is in + process or being worked on, or has been cancelled. In a "VJOURNAL" + calendar component, the "Organizer" can indicate that a journal entry + is draft, final or has been cancelled or removed. + + Format Definition: The property is defined by the following notation: + + status = "STATUS" statparam] ":" statvalue CRLF + + statparam = *(";" xparam) + + statvalue = "TENTATIVE" ;Indicates event is + ;tentative. + / "CONFIRMED" ;Indicates event is + ;definite. + / "CANCELLED" ;Indicates event was + ;cancelled. + ;Status values for a "VEVENT" + + + +Dawson & Stenerson Standards Track [Page 88] +

+RFC 2445                       iCalendar                   November 1998
+
+
+     statvalue  =/ "NEEDS-ACTION"       ;Indicates to-do needs action.
+                / "COMPLETED"           ;Indicates to-do completed.
+                / "IN-PROCESS"          ;Indicates to-do in process of
+                / "CANCELLED"           ;Indicates to-do was cancelled.
+        ;Status values for "VTODO".
+
+     statvalue  =/ "DRAFT"              ;Indicates journal is draft.
+                / "FINAL"               ;Indicates journal is final.
+                / "CANCELLED"           ;Indicates journal is removed.
+        ;Status values for "VJOURNAL".
+
+   Example: The following is an example of this property for a "VEVENT"
+   calendar component:
+
+     STATUS:TENTATIVE
+
+   The following is an example of this property for a "VTODO" calendar
+   component:
+
+     STATUS:NEEDS-ACTION
+
+   The following is an example of this property for a "VJOURNAL"
+   calendar component:
+
+     STATUS:DRAFT
+
+
4.8.1.12 Summary
+ + Property Name: SUMMARY + + Purpose: This property defines a short summary or subject for the + calendar component. + + Value Type: TEXT + + Property Parameters: Non-standard, alternate text representation and + language property parameters can be specified on this property. + + Conformance: The property can be specified in "VEVENT", "VTODO", + "VJOURNAL" or "VALARM" calendar components. + + Description: This property is used in the "VEVENT", "VTODO" and + "VJOURNAL" calendar components to capture a short, one line summary + about the activity or journal entry. + + This property is used in the "VALARM" calendar component to capture + the subject of an EMAIL category of alarm. + + + + +Dawson & Stenerson Standards Track [Page 89] +

+RFC 2445                       iCalendar                   November 1998
+
+
+   Format Definition: The property is defined by the following notation:
+
+     summary    = "SUMMARY" summparam ":" text CRLF
+
+     summparam  = *(
+
+                ; the following are optional,
+                ; but MUST NOT occur more than once
+
+                (";" altrepparam) / (";" languageparam) /
+
+                ; the following is optional,
+                ; and MAY occur more than once
+
+                (";" xparam)
+
+                )
+
+   Example: The following is an example of this property:
+
+     SUMMARY:Department Party
+
+

4.8.2 Date and Time Component Properties

+ + The following properties specify date and time related information in + calendar components. + +
4.8.2.1 Date/Time Completed
+ + Property Name: COMPLETED + + Purpose: This property defines the date and time that a to-do was + actually completed. + + Value Type: DATE-TIME + + Property Parameters: Non-standard property parameters can be + specified on this property. + + Conformance: The property can be specified in a "VTODO" calendar + component. + + Description: The date and time MUST be in a UTC format. + + Format Definition: The property is defined by the following notation: + + completed = "COMPLETED" compparam ":" date-time CRLF + + + + +Dawson & Stenerson Standards Track [Page 90] +

+RFC 2445                       iCalendar                   November 1998
+
+
+     compparam  = *(";" xparam)
+
+   Example: The following is an example of this property:
+
+     COMPLETED:19960401T235959Z
+
+
4.8.2.2 Date/Time End
+ + Property Name: DTEND + + Purpose: This property specifies the date and time that a calendar + component ends. + + Value Type: The default value type is DATE-TIME. The value type can + be set to a DATE value type. + + Property Parameters: Non-standard, value data type, time zone + identifier property parameters can be specified on this property. + + Conformance: This property can be specified in "VEVENT" or + "VFREEBUSY" calendar components. + + Description: Within the "VEVENT" calendar component, this property + defines the date and time by which the event ends. The value MUST be + later in time than the value of the "DTSTART" property. + + Within the "VFREEBUSY" calendar component, this property defines the + end date and time for the free or busy time information. The time + MUST be specified in the UTC time format. The value MUST be later in + time than the value of the "DTSTART" property. + + Format Definition: The property is defined by the following notation: + + dtend = "DTEND" dtendparam":" dtendval CRLF + + dtendparam = *( + + ; the following are optional, + ; but MUST NOT occur more than once + + (";" "VALUE" "=" ("DATE-TIME" / "DATE")) / + (";" tzidparam) / + + ; the following is optional, + ; and MAY occur more than once + + + + + + +Dawson & Stenerson Standards Track [Page 91] +

+RFC 2445                       iCalendar                   November 1998
+
+
+                (";" xparam)
+
+                )
+
+
+
+     dtendval   = date-time / date
+     ;Value MUST match value type
+
+   Example: The following is an example of this property:
+
+     DTEND:19960401T235959Z
+
+     DTEND;VALUE=DATE:19980704
+
+
4.8.2.3 Date/Time Due
+ + Property Name: DUE + + Purpose: This property defines the date and time that a to-do is + expected to be completed. + + Value Type: The default value type is DATE-TIME. The value type can + be set to a DATE value type. + + Property Parameters: Non-standard, value data type, time zone + identifier property parameters can be specified on this property. + + Conformance: The property can be specified once in a "VTODO" calendar + component. + + Description: The value MUST be a date/time equal to or after the + DTSTART value, if specified. + + Format Definition: The property is defined by the following notation: + + due = "DUE" dueparam":" dueval CRLF + + dueparam = *( + ; the following are optional, + ; but MUST NOT occur more than once + + (";" "VALUE" "=" ("DATE-TIME" / "DATE")) / + (";" tzidparam) / + + ; the following is optional, + ; and MAY occur more than once + + + + +Dawson & Stenerson Standards Track [Page 92] +

+RFC 2445                       iCalendar                   November 1998
+
+
+                  *(";" xparam)
+
+                )
+
+
+
+     dueval     = date-time / date
+     ;Value MUST match value type
+
+   Example: The following is an example of this property:
+
+     DUE:19980430T235959Z
+
+
4.8.2.4 Date/Time Start
+ + Property Name: DTSTART + + Purpose: This property specifies when the calendar component begins. + + Value Type: The default value type is DATE-TIME. The time value MUST + be one of the forms defined for the DATE-TIME value type. The value + type can be set to a DATE value type. + + Property Parameters: Non-standard, value data type, time zone + identifier property parameters can be specified on this property. + + Conformance: This property can be specified in the "VEVENT", "VTODO", + "VFREEBUSY", or "VTIMEZONE" calendar components. + + Description: Within the "VEVENT" calendar component, this property + defines the start date and time for the event. The property is + REQUIRED in "VEVENT" calendar components. Events can have a start + date/time but no end date/time. In that case, the event does not take + up any time. + + Within the "VFREEBUSY" calendar component, this property defines the + start date and time for the free or busy time information. The time + MUST be specified in UTC time. + + Within the "VTIMEZONE" calendar component, this property defines the + effective start date and time for a time zone specification. This + property is REQUIRED within each STANDARD and DAYLIGHT part included + in "VTIMEZONE" calendar components and MUST be specified as a local + DATE-TIME without the "TZID" property parameter. + + Format Definition: The property is defined by the following notation: + + dtstart = "DTSTART" dtstparam ":" dtstval CRLF + + + +Dawson & Stenerson Standards Track [Page 93] +

+RFC 2445                       iCalendar                   November 1998
+
+
+     dtstparam  = *(
+
+                ; the following are optional,
+                ; but MUST NOT occur more than once
+
+                (";" "VALUE" "=" ("DATE-TIME" / "DATE")) /
+                (";" tzidparam) /
+
+                ; the following is optional,
+                ; and MAY occur more than once
+
+                  *(";" xparam)
+
+                )
+
+
+
+     dtstval    = date-time / date
+     ;Value MUST match value type
+
+   Example: The following is an example of this property:
+
+     DTSTART:19980118T073000Z
+
+
4.8.2.5 Duration
+ + Property Name: DURATION + + Purpose: The property specifies a positive duration of time. + + Value Type: DURATION + + Property Parameters: Non-standard property parameters can be + specified on this property. + + Conformance: The property can be specified in "VEVENT", "VTODO", + "VFREEBUSY" or "VALARM" calendar components. + + Description: In a "VEVENT" calendar component the property may be + used to specify a duration of the event, instead of an explicit end + date/time. In a "VTODO" calendar component the property may be used + to specify a duration for the to-do, instead of an explicit due + date/time. In a "VFREEBUSY" calendar component the property may be + used to specify the interval of free time being requested. In a + "VALARM" calendar component the property may be used to specify the + delay period prior to repeating an alarm. + + Format Definition: The property is defined by the following notation: + + + +Dawson & Stenerson Standards Track [Page 94] +

+RFC 2445                       iCalendar                   November 1998
+
+
+     duration   = "DURATION" durparam ":" dur-value CRLF
+                  ;consisting of a positive duration of time.
+
+     durparam   = *(";" xparam)
+
+   Example: The following is an example of this property that specifies
+   an interval of time of 1 hour and zero minutes and zero seconds:
+
+     DURATION:PT1H0M0S
+
+   The following is an example of this property that specifies an
+   interval of time of 15 minutes.
+
+     DURATION:PT15M
+
+
4.8.2.6 Free/Busy Time
+ + Property Name: FREEBUSY + + Purpose: The property defines one or more free or busy time + intervals. + + Value Type: PERIOD. The date and time values MUST be in an UTC time + format. + + Property Parameters: Non-standard or free/busy time type property + parameters can be specified on this property. + + Conformance: The property can be specified in a "VFREEBUSY" calendar + component. + + Property Parameter: "FBTYPE" and non-standard parameters can be + specified on this property. + + Description: These time periods can be specified as either a start + and end date-time or a start date-time and duration. The date and + time MUST be a UTC time format. + + "FREEBUSY" properties within the "VFREEBUSY" calendar component + SHOULD be sorted in ascending order, based on start time and then end + time, with the earliest periods first. + + The "FREEBUSY" property can specify more than one value, separated by + the COMMA character (US-ASCII decimal 44). In such cases, the + "FREEBUSY" property values SHOULD all be of the same "FBTYPE" + property parameter type (e.g., all values of a particular "FBTYPE" + listed together in a single property). + + + + +Dawson & Stenerson Standards Track [Page 95] +

+RFC 2445                       iCalendar                   November 1998
+
+
+   Format Definition: The property is defined by the following notation:
+
+     freebusy   = "FREEBUSY" fbparam ":" fbvalue
+                  CRLF
+
+     fbparam    = *(
+                ; the following is optional,
+                ; but MUST NOT occur more than once
+
+                (";" fbtypeparam) /
+
+                ; the following is optional,
+                ; and MAY occur more than once
+
+                (";" xparam)
+
+                )
+
+     fbvalue    = period *["," period]
+     ;Time value MUST be in the UTC time format.
+
+   Example: The following are some examples of this property:
+
+     FREEBUSY;FBTYPE=BUSY-UNAVAILABLE:19970308T160000Z/PT8H30M
+
+     FREEBUSY;FBTYPE=FREE:19970308T160000Z/PT3H,19970308T200000Z/PT1H
+
+     FREEBUSY;FBTYPE=FREE:19970308T160000Z/PT3H,19970308T200000Z/PT1H,
+      19970308T230000Z/19970309T000000Z
+
+
4.8.2.7 Time Transparency
+ + Property Name: TRANSP + + Purpose: This property defines whether an event is transparent or not + to busy time searches. + + Value Type: TEXT + + Property Parameters: Non-standard property parameters can be + specified on this property. + + Conformance: This property can be specified once in a "VEVENT" + calendar component. + + Description: Time Transparency is the characteristic of an event that + determines whether it appears to consume time on a calendar. Events + that consume actual time for the individual or resource associated + + + +Dawson & Stenerson Standards Track [Page 96] +

+RFC 2445                       iCalendar                   November 1998
+
+
+   with the calendar SHOULD be recorded as OPAQUE, allowing them to be
+   detected by free-busy time searches. Other events, which do not take
+   up the individual's (or resource's) time SHOULD be recorded as
+   TRANSPARENT, making them invisible to free-busy time searches.
+
+   Format Definition: The property is specified by the following
+   notation:
+
+     transp     = "TRANSP" tranparam ":" transvalue CRLF
+
+     tranparam  = *(";" xparam)
+
+     transvalue = "OPAQUE"      ;Blocks or opaque on busy time searches.
+                / "TRANSPARENT" ;Transparent on busy time searches.
+        ;Default value is OPAQUE
+
+   Example: The following is an example of this property for an event
+   that is transparent or does not block on free/busy time searches:
+
+     TRANSP:TRANSPARENT
+
+   The following is an example of this property for an event that is
+   opaque or blocks on free/busy time searches:
+
+     TRANSP:OPAQUE
+
+

4.8.3 Time Zone Component Properties

+ + The following properties specify time zone information in calendar + components. + +
4.8.3.1 Time Zone Identifier
+ + Property Name: TZID + + Purpose: This property specifies the text value that uniquely + identifies the "VTIMEZONE" calendar component. + + Value Type: TEXT + + Property Parameters: Non-standard property parameters can be + specified on this property. + + Conformance: This property MUST be specified in a "VTIMEZONE" + calendar component. + + + + + + +Dawson & Stenerson Standards Track [Page 97] +

+RFC 2445                       iCalendar                   November 1998
+
+
+   Description: This is the label by which a time zone calendar
+   component is referenced by any iCalendar properties whose data type
+   is either DATE-TIME or TIME and not intended to specify a UTC or a
+   "floating" time. The presence of the SOLIDUS character (US-ASCII
+   decimal 47) as a prefix, indicates that this TZID represents an
+   unique ID in a globally defined time zone registry (when such
+   registry is defined).
+
+        Note: This document does not define a naming convention for time
+        zone identifiers. Implementers may want to use the naming
+        conventions defined in existing time zone specifications such as
+        the public-domain Olson database [TZ]. The specification of
+        globally unique time zone identifiers is not addressed by this
+        document and is left for future study.
+
+   Format Definition: This property is defined by the following
+   notation:
+
+     tzid       = "TZID" tzidpropparam ":" [tzidprefix] text CRLF
+
+     tzidpropparam      = *(";" xparam)
+
+     ;tzidprefix        = "/"
+     ; Defined previously. Just listed here for reader convenience.
+
+   Example: The following are examples of non-globally unique time zone
+   identifiers:
+
+     TZID:US-Eastern
+
+     TZID:California-Los_Angeles
+
+   The following is an example of a fictitious globally unique time zone
+   identifier:
+
+     TZID:/US-New_York-New_York
+
+
4.8.3.2 Time Zone Name
+ + Property Name: TZNAME + + Purpose: This property specifies the customary designation for a time + zone description. + + Value Type: TEXT + + Property Parameters: Non-standard and language property parameters + can be specified on this property. + + + +Dawson & Stenerson Standards Track [Page 98] +

+RFC 2445                       iCalendar                   November 1998
+
+
+   Conformance: This property can be specified in a "VTIMEZONE" calendar
+   component.
+
+   Description: This property may be specified in multiple languages; in
+   order to provide for different language requirements.
+
+   Format Definition: This property is defined by the following
+   notation:
+
+     tzname     = "TZNAME" tznparam ":" text CRLF
+
+     tznparam   = *(
+
+                ; the following is optional,
+                ; but MUST NOT occur more than once
+
+                (";" languageparam) /
+
+                ; the following is optional,
+                ; and MAY occur more than once
+
+                (";" xparam)
+
+                )
+
+   Example: The following are example of this property:
+
+     TZNAME:EST
+
+   The following is an example of this property when two different
+   languages for the time zone name are specified:
+
+     TZNAME;LANGUAGE=en:EST
+     TZNAME;LANGUAGE=fr-CA:HNE
+
+
4.8.3.3 Time Zone Offset From
+ + Property Name: TZOFFSETFROM + + Purpose: This property specifies the offset which is in use prior to + this time zone observance. + + Value Type: UTC-OFFSET + + Property Parameters: Non-standard property parameters can be + specified on this property. + + + + + +Dawson & Stenerson Standards Track [Page 99] +

+RFC 2445                       iCalendar                   November 1998
+
+
+   Conformance: This property MUST be specified in a "VTIMEZONE"
+   calendar component.
+
+   Description: This property specifies the offset which is in use prior
+   to this time observance. It is used to calculate the absolute time at
+   which the transition to a given observance takes place. This property
+   MUST only be specified in a "VTIMEZONE" calendar component. A
+   "VTIMEZONE" calendar component MUST include this property. The
+   property value is a signed numeric indicating the number of hours and
+   possibly minutes from UTC. Positive numbers represent time zones east
+   of the prime meridian, or ahead of UTC. Negative numbers represent
+   time zones west of the prime meridian, or behind UTC.
+
+   Format Definition: The property is defined by the following notation:
+
+     tzoffsetfrom       = "TZOFFSETFROM" frmparam ":" utc-offset
+                          CRLF
+
+     frmparam   = *(";" xparam)
+
+   Example: The following are examples of this property:
+
+     TZOFFSETFROM:-0500
+
+     TZOFFSETFROM:+1345
+
+
4.8.3.4 Time Zone Offset To
+ + Property Name: TZOFFSETTO + + Purpose: This property specifies the offset which is in use in this + time zone observance. + + Value Type: UTC-OFFSET + + Property Parameters: Non-standard property parameters can be + specified on this property. + + Conformance: This property MUST be specified in a "VTIMEZONE" + calendar component. + + Description: This property specifies the offset which is in use in + this time zone observance. It is used to calculate the absolute time + for the new observance. The property value is a signed numeric + indicating the number of hours and possibly minutes from UTC. + Positive numbers represent time zones east of the prime meridian, or + ahead of UTC. Negative numbers represent time zones west of the prime + meridian, or behind UTC. + + + +Dawson & Stenerson Standards Track [Page 100] +

+RFC 2445                       iCalendar                   November 1998
+
+
+   Format Definition: The property is defined by the following notation:
+
+     tzoffsetto = "TZOFFSETTO" toparam ":" utc-offset CRLF
+
+     toparam    = *(";" xparam)
+
+   Example: The following are examples of this property:
+
+     TZOFFSETTO:-0400
+
+     TZOFFSETTO:+1245
+
+
4.8.3.5 Time Zone URL
+ + Property Name: TZURL + + Purpose: The TZURL provides a means for a VTIMEZONE component to + point to a network location that can be used to retrieve an up-to- + date version of itself. + + Value Type: URI + + Property Parameters: Non-standard property parameters can be + specified on this property. + + Conformance: This property can be specified in a "VTIMEZONE" calendar + component. + + Description: The TZURL provides a means for a VTIMEZONE component to + point to a network location that can be used to retrieve an up-to- + date version of itself. This provides a hook to handle changes + government bodies impose upon time zone definitions. Retrieval of + this resource results in an iCalendar object containing a single + VTIMEZONE component and a METHOD property set to PUBLISH. + + Format Definition: The property is defined by the following notation: + + tzurl = "TZURL" tzurlparam ":" uri CRLF + + tzurlparam = *(";" xparam) + + Example: The following is an example of this property: + + TZURL:http://timezones.r.us.net/tz/US-California-Los_Angeles + + + + + + + +Dawson & Stenerson Standards Track [Page 101] +

+RFC 2445                       iCalendar                   November 1998
+
+
+

4.8.4 Relationship Component Properties

+ + The following properties specify relationship information in calendar + components. + +
4.8.4.1 Attendee
+ + Property Name: ATTENDEE + + Purpose: The property defines an "Attendee" within a calendar + component. + + Value Type: CAL-ADDRESS + + Property Parameters: Non-standard, language, calendar user type, + group or list membership, participation role, participation status, + RSVP expectation, delegatee, delegator, sent by, common name or + directory entry reference property parameters can be specified on + this property. + + Conformance: This property MUST be specified in an iCalendar object + that specifies a group scheduled calendar entity. This property MUST + NOT be specified in an iCalendar object when publishing the calendar + information (e.g., NOT in an iCalendar object that specifies the + publication of a calendar user's busy time, event, to-do or journal). + This property is not specified in an iCalendar object that specifies + only a time zone definition or that defines calendar entities that + are not group scheduled entities, but are entities only on a single + user's calendar. + + Description: The property MUST only be specified within calendar + components to specify participants, non-participants and the chair of + a group scheduled calendar entity. The property is specified within + an "EMAIL" category of the "VALARM" calendar component to specify an + email address that is to receive the email type of iCalendar alarm. + + The property parameter CN is for the common or displayable name + associated with the calendar address; ROLE, for the intended role + that the attendee will have in the calendar component; PARTSTAT, for + the status of the attendee's participation; RSVP, for indicating + whether the favor of a reply is requested; CUTYPE, to indicate the + type of calendar user; MEMBER, to indicate the groups that the + attendee belongs to; DELEGATED-TO, to indicate the calendar users + that the original request was delegated to; and DELEGATED-FROM, to + indicate whom the request was delegated from; SENT-BY, to indicate + whom is acting on behalf of the ATTENDEE; and DIR, to indicate the + URI that points to the directory information corresponding to the + attendee. These property parameters can be specified on an "ATTENDEE" + + + +Dawson & Stenerson Standards Track [Page 102] +

+RFC 2445                       iCalendar                   November 1998
+
+
+   property in either a "VEVENT", "VTODO" or "VJOURNAL" calendar
+   component. They MUST not be specified in an "ATTENDEE" property in a
+   "VFREEBUSY" or "VALARM" calendar component. If the LANGUAGE property
+   parameter is specified, the identified language applies to the CN
+   parameter.
+
+   A recipient delegated a request MUST inherit the RSVP and ROLE values
+   from the attendee that delegated the request to them.
+
+   Multiple attendees can be specified by including multiple "ATTENDEE"
+   properties within the calendar component.
+
+   Format Definition: The property is defined by the following notation:
+
+     attendee   = "ATTENDEE" attparam ":" cal-address CRLF
+
+     attparam   = *(
+
+                ; the following are optional,
+                ; but MUST NOT occur more than once
+
+                (";" cutypeparam) / (";"memberparam) /
+                (";" roleparam) / (";" partstatparam) /
+                (";" rsvpparam) / (";" deltoparam) /
+                (";" delfromparam) / (";" sentbyparam) /
+                (";"cnparam) / (";" dirparam) /
+                (";" languageparam) /
+
+                ; the following is optional,
+                ; and MAY occur more than once
+
+                (";" xparam)
+
+                )
+
+   Example: The following are examples of this property's use for a to-
+   do:
+
+     ORGANIZER:MAILTO:jsmith@host1.com
+     ATTENDEE;MEMBER="MAILTO:DEV-GROUP@host2.com":
+      MAILTO:joecool@host2.com
+     ATTENDEE;DELEGATED-FROM="MAILTO:immud@host3.com":
+      MAILTO:ildoit@host1.com
+
+   The following is an example of this property used for specifying
+   multiple attendees to an event:
+
+
+
+
+
+Dawson & Stenerson          Standards Track                   [Page 103]
+

+RFC 2445                       iCalendar                   November 1998
+
+
+     ORGANIZER:MAILTO:jsmith@host1.com
+     ATTENDEE;ROLE=REQ-PARTICIPANT;PARTSTAT=TENTATIVE;CN=Henry Cabot
+      :MAILTO:hcabot@host2.com
+     ATTENDEE;ROLE=REQ-PARTICIPANT;DELEGATED-FROM="MAILTO:bob@host.com"
+      ;PARTSTAT=ACCEPTED;CN=Jane Doe:MAILTO:jdoe@host1.com
+
+   The following is an example of this property with a URI to the
+   directory information associated with the attendee:
+
+     ATTENDEE;CN=John Smith;DIR="ldap://host.com:6666/o=eDABC%
+      20Industries,c=3DUS??(cn=3DBJim%20Dolittle)":MAILTO:jimdo@
+      host1.com
+
+   The following is an example of this property with "delegatee" and
+   "delegator" information for an event:
+
+     ORGANIZER;CN=John Smith:MAILTO:jsmith@host.com
+     ATTENDEE;ROLE=REQ-PARTICIPANT;PARTSTAT=TENTATIVE;DELEGATED-FROM=
+      "MAILTO:iamboss@host2.com";CN=Henry Cabot:MAILTO:hcabot@
+      host2.com
+     ATTENDEE;ROLE=NON-PARTICIPANT;PARTSTAT=DELEGATED;DELEGATED-TO=
+      "MAILTO:hcabot@host2.com";CN=The Big Cheese:MAILTO:iamboss
+      @host2.com
+     ATTENDEE;ROLE=REQ-PARTICIPANT;PARTSTAT=ACCEPTED;CN=Jane Doe
+      :MAILTO:jdoe@host1.com
+
+   Example: The following is an example of this property's use when
+   another calendar user is acting on behalf of the "Attendee":
+
+     ATTENDEE;SENT-BY=MAILTO:jan_doe@host1.com;CN=John Smith:MAILTO:
+      jsmith@host1.com
+
+
4.8.4.2 Contact
+ + Property Name: CONTACT + + Purpose: The property is used to represent contact information or + alternately a reference to contact information associated with the + calendar component. + + Value Type: TEXT + + Property Parameters: Non-standard, alternate text representation and + language property parameters can be specified on this property. + + Conformance: The property can be specified in a "VEVENT", "VTODO", + "VJOURNAL" or "VFREEBUSY" calendar component. + + + + +Dawson & Stenerson Standards Track [Page 104] +

+RFC 2445                       iCalendar                   November 1998
+
+
+   Description: The property value consists of textual contact
+   information. An alternative representation for the property value can
+   also be specified that refers to a URI pointing to an alternate form,
+   such as a vCard [RFC 2426], for the contact information.
+
+   Format Definition: The property is defined by the following notation:
+
+     contact    = "CONTACT" contparam ":" text CRLF
+
+     contparam  = *(
+                ; the following are optional,
+                ; but MUST NOT occur more than once
+
+                (";" altrepparam) / (";" languageparam) /
+
+                ; the following is optional,
+                ; and MAY occur more than once
+
+                (";" xparam)
+
+                )
+
+   Example: The following is an example of this property referencing
+   textual contact information:
+
+     CONTACT:Jim Dolittle\, ABC Industries\, +1-919-555-1234
+
+   The following is an example of this property with an alternate
+   representation of a LDAP URI to a directory entry containing the
+   contact information:
+
+     CONTACT;ALTREP="ldap://host.com:6666/o=3DABC%20Industries\,
+      c=3DUS??(cn=3DBJim%20Dolittle)":Jim Dolittle\, ABC Industries\,
+      +1-919-555-1234
+
+   The following is an example of this property with an alternate
+   representation of a MIME body part containing the contact
+   information, such as a vCard [RFC 2426] embedded in a [MIME-DIR]
+   content-type:
+
+     CONTACT;ALTREP="CID=<part3.msg970930T083000SILVER@host.com>":Jim
+       Dolittle\, ABC Industries\, +1-919-555-1234
+
+   The following is an example of this property referencing a network
+   resource, such as a vCard [RFC 2426] object containing the contact
+   information:
+
+
+
+
+
+Dawson & Stenerson          Standards Track                   [Page 105]
+

+RFC 2445                       iCalendar                   November 1998
+
+
+     CONTACT;ALTREP="http://host.com/pdi/jdoe.vcf":Jim
+       Dolittle\, ABC Industries\, +1-919-555-1234
+
+
4.8.4.3 Organizer
+ + Property Name: ORGANIZER + + Purpose: The property defines the organizer for a calendar component. + + Value Type: CAL-ADDRESS + + Property Parameters: Non-standard, language, common name, directory + entry reference, sent by property parameters can be specified on this + property. + + Conformance: This property MUST be specified in an iCalendar object + that specifies a group scheduled calendar entity. This property MUST + be specified in an iCalendar object that specifies the publication of + a calendar user's busy time. This property MUST NOT be specified in + an iCalendar object that specifies only a time zone definition or + that defines calendar entities that are not group scheduled entities, + but are entities only on a single user's calendar. + + Description: The property is specified within the "VEVENT", "VTODO", + "VJOURNAL calendar components to specify the organizer of a group + scheduled calendar entity. The property is specified within the + "VFREEBUSY" calendar component to specify the calendar user + requesting the free or busy time. When publishing a "VFREEBUSY" + calendar component, the property is used to specify the calendar that + the published busy time came from. + + The property has the property parameters CN, for specifying the + common or display name associated with the "Organizer", DIR, for + specifying a pointer to the directory information associated with the + "Organizer", SENT-BY, for specifying another calendar user that is + acting on behalf of the "Organizer". The non-standard parameters may + also be specified on this property. If the LANGUAGE property + parameter is specified, the identified language applies to the CN + parameter value. + + Format Definition: The property is defined by the following notation: + + organizer = "ORGANIZER" orgparam ":" + cal-address CRLF + + orgparam = *( + + ; the following are optional, + + + +Dawson & Stenerson Standards Track [Page 106] +

+RFC 2445                       iCalendar                   November 1998
+
+
+                ; but MUST NOT occur more than once
+
+                (";" cnparam) / (";" dirparam) / (";" sentbyparam) /
+                (";" languageparam) /
+
+                ; the following is optional,
+                ; and MAY occur more than once
+
+                (";" xparam)
+
+                )
+
+   Example: The following is an example of this property:
+
+     ORGANIZER;CN=John Smith:MAILTO:jsmith@host1.com
+
+   The following is an example of this property with a pointer to the
+   directory information associated with the organizer:
+
+     ORGANIZER;CN=JohnSmith;DIR="ldap://host.com:6666/o=3DDC%20Associ
+      ates,c=3DUS??(cn=3DJohn%20Smith)":MAILTO:jsmith@host1.com
+
+   The following is an example of this property used by another calendar
+   user who is acting on behalf of the organizer, with responses
+   intended to be sent back to the organizer, not the other calendar
+   user:
+
+     ORGANIZER;SENT-BY="MAILTO:jane_doe@host.com":
+      MAILTO:jsmith@host1.com
+
+
4.8.4.4 Recurrence ID
+ + Property Name: RECURRENCE-ID + + Purpose: This property is used in conjunction with the "UID" and + "SEQUENCE" property to identify a specific instance of a recurring + "VEVENT", "VTODO" or "VJOURNAL" calendar component. The property + value is the effective value of the "DTSTART" property of the + recurrence instance. + + Value Type: The default value type for this property is DATE-TIME. + The time format can be any of the valid forms defined for a DATE-TIME + value type. See DATE-TIME value type definition for specific + interpretations of the various forms. The value type can be set to + DATE. + + + + + + +Dawson & Stenerson Standards Track [Page 107] +

+RFC 2445                       iCalendar                   November 1998
+
+
+   Property Parameters: Non-standard property, value data type, time
+   zone identifier and recurrence identifier range parameters can be
+   specified on this property.
+
+   Conformance: This property can be specified in an iCalendar object
+   containing a recurring calendar component.
+
+   Description: The full range of calendar components specified by a
+   recurrence set is referenced by referring to just the "UID" property
+   value corresponding to the calendar component. The "RECURRENCE-ID"
+   property allows the reference to an individual instance within the
+   recurrence set.
+
+   If the value of the "DTSTART" property is a DATE type value, then the
+   value MUST be the calendar date for the recurrence instance.
+
+   The date/time value is set to the time when the original recurrence
+   instance would occur; meaning that if the intent is to change a
+   Friday meeting to Thursday, the date/time is still set to the
+   original Friday meeting.
+
+   The "RECURRENCE-ID" property is used in conjunction with the "UID"
+   and "SEQUENCE" property to identify a particular instance of a
+   recurring event, to-do or journal. For a given pair of "UID" and
+   "SEQUENCE" property values, the "RECURRENCE-ID" value for a
+   recurrence instance is fixed. When the definition of the recurrence
+   set for a calendar component changes, and hence the "SEQUENCE"
+   property value changes, the "RECURRENCE-ID" for a given recurrence
+   instance might also change.The "RANGE" parameter is used to specify
+   the effective range of recurrence instances from the instance
+   specified by the "RECURRENCE-ID" property value. The default value
+   for the range parameter is the single recurrence instance only. The
+   value can also be "THISANDPRIOR" to indicate a range defined by the
+   given recurrence instance and all prior instances or the value can be
+   "THISANDFUTURE" to indicate a range defined by the given recurrence
+   instance and all subsequent instances.
+
+   Format Definition: The property is defined by the following notation:
+
+     recurid    = "RECURRENCE-ID" ridparam ":" ridval CRLF
+
+     ridparam   = *(
+
+                ; the following are optional,
+                ; but MUST NOT occur more than once
+
+                (";" "VALUE" "=" ("DATE-TIME" / "DATE)) /
+                (";" tzidparam) / (";" rangeparam) /
+
+
+
+Dawson & Stenerson          Standards Track                   [Page 108]
+

+RFC 2445                       iCalendar                   November 1998
+
+
+                ; the following is optional,
+                ; and MAY occur more than once
+
+                (";" xparam)
+
+                )
+
+     ridval     = date-time / date
+     ;Value MUST match value type
+
+   Example: The following are examples of this property:
+
+     RECURRENCE-ID;VALUE=DATE:19960401
+
+     RECURRENCE-ID;RANGE=THISANDFUTURE:19960120T120000Z
+
+
4.8.4.5 Related To
+ + Property Name: RELATED-TO + + Purpose: The property is used to represent a relationship or + reference between one calendar component and another. + + Value Type: TEXT + + Property Parameters: Non-standard and relationship type property + parameters can be specified on this property. + + Conformance: The property can be specified one or more times in the + "VEVENT", "VTODO" or "VJOURNAL" calendar components. + + Description: The property value consists of the persistent, globally + unique identifier of another calendar component. This value would be + represented in a calendar component by the "UID" property. + + By default, the property value points to another calendar component + that has a PARENT relationship to the referencing object. The + "RELTYPE" property parameter is used to either explicitly state the + default PARENT relationship type to the referenced calendar component + or to override the default PARENT relationship type and specify + either a CHILD or SIBLING relationship. The PARENT relationship + indicates that the calendar component is a subordinate of the + referenced calendar component. The CHILD relationship indicates that + the calendar component is a superior of the referenced calendar + component. The SIBLING relationship indicates that the calendar + component is a peer of the referenced calendar component. + + + + + +Dawson & Stenerson Standards Track [Page 109] +

+RFC 2445                       iCalendar                   November 1998
+
+
+   Changes to a calendar component referenced by this property can have
+   an implicit impact on the related calendar component. For example, if
+   a group event changes its start or end date or time, then the
+   related, dependent events will need to have their start and end dates
+   changed in a corresponding way. Similarly, if a PARENT calendar
+   component is canceled or deleted, then there is an implied impact to
+   the related CHILD calendar components. This property is intended only
+   to provide information on the relationship of calendar components. It
+   is up to the target calendar system to maintain any property
+   implications of this relationship.
+
+   Format Definition: The property is defined by the following notation:
+
+     related    = "RELATED-TO" [relparam] ":" text CRLF
+
+     relparam   = *(
+
+                ; the following is optional,
+                ; but MUST NOT occur more than once
+
+                (";" reltypeparam) /
+
+                ; the following is optional,
+                ; and MAY occur more than once
+
+                (";" xparm)
+
+                )
+
+   The following is an example of this property:
+
+     RELATED-TO:<jsmith.part7.19960817T083000.xyzMail@host3.com>
+
+     RELATED-TO:<19960401-080045-4000F192713-0052@host1.com>
+
+
4.8.4.6 Uniform Resource Locator
+ + Property Name: URL + + Purpose: This property defines a Uniform Resource Locator (URL) + associated with the iCalendar object. + + Value Type: URI + + Property Parameters: Non-standard property parameters can be + specified on this property. + + + + + +Dawson & Stenerson Standards Track [Page 110] +

+RFC 2445                       iCalendar                   November 1998
+
+
+   Conformance: This property can be specified once in the "VEVENT",
+   "VTODO", "VJOURNAL" or "VFREEBUSY" calendar components.
+
+   Description: This property may be used in a calendar component to
+   convey a location where a more dynamic rendition of the calendar
+   information associated with the calendar component can be found. This
+   memo does not attempt to standardize the form of the URI, nor the
+   format of the resource pointed to by the property value. If the URL
+   property and Content-Location MIME header are both specified, they
+   MUST point to the same resource.
+
+   Format Definition: The property is defined by the following notation:
+
+     url        = "URL" urlparam ":" uri CRLF
+
+     urlparam   = *(";" xparam)
+
+   Example: The following is an example of this property:
+
+     URL:http://abc.com/pub/calendars/jsmith/mytime.ics
+
+
4.8.4.7 Unique Identifier
+ + Property Name: UID + + Purpose: This property defines the persistent, globally unique + identifier for the calendar component. + + Value Type: TEXT + + Property Parameters: Non-standard property parameters can be + specified on this property. + + Conformance: The property MUST be specified in the "VEVENT", "VTODO", + "VJOURNAL" or "VFREEBUSY" calendar components. + + Description: The UID itself MUST be a globally unique identifier. The + generator of the identifier MUST guarantee that the identifier is + unique. There are several algorithms that can be used to accomplish + this. The identifier is RECOMMENDED to be the identical syntax to the + [RFC 822] addr-spec. A good method to assure uniqueness is to put the + domain name or a domain literal IP address of the host on which the + identifier was created on the right hand side of the "@", and on the + left hand side, put a combination of the current calendar date and + time of day (i.e., formatted in as a DATE-TIME value) along with some + other currently unique (perhaps sequential) identifier available on + the system (for example, a process id number). Using a date/time + value on the left hand side and a domain name or domain literal on + + + +Dawson & Stenerson Standards Track [Page 111] +

+RFC 2445                       iCalendar                   November 1998
+
+
+   the right hand side makes it possible to guarantee uniqueness since
+   no two hosts should be using the same domain name or IP address at
+   the same time. Though other algorithms will work, it is RECOMMENDED
+   that the right hand side contain some domain identifier (either of
+   the host itself or otherwise) such that the generator of the message
+   identifier can guarantee the uniqueness of the left hand side within
+   the scope of that domain.
+
+   This is the method for correlating scheduling messages with the
+   referenced "VEVENT", "VTODO", or "VJOURNAL" calendar component.
+
+   The full range of calendar components specified by a recurrence set
+   is referenced by referring to just the "UID" property value
+   corresponding to the calendar component. The "RECURRENCE-ID" property
+   allows the reference to an individual instance within the recurrence
+   set.
+
+   This property is an important method for group scheduling
+   applications to match requests with later replies, modifications or
+   deletion requests. Calendaring and scheduling applications MUST
+   generate this property in "VEVENT", "VTODO" and "VJOURNAL" calendar
+   components to assure interoperability with other group scheduling
+   applications. This identifier is created by the calendar system that
+   generates an iCalendar object.
+
+   Implementations MUST be able to receive and persist values of at
+   least 255 characters for this property.
+
+   Format Definition: The property is defined by the following notation:
+
+     uid        = "UID" uidparam ":" text CRLF
+
+     uidparam   = *(";" xparam)
+
+   Example: The following is an example of this property:
+
+     UID:19960401T080045Z-4000F192713-0052@host1.com
+
+

4.8.5 Recurrence Component Properties

+ + The following properties specify recurrence information in calendar + components. + +
4.8.5.1 Exception Date/Times
+ + Property Name: EXDATE + + + + + +Dawson & Stenerson Standards Track [Page 112] +

+RFC 2445                       iCalendar                   November 1998
+
+
+   Purpose: This property defines the list of date/time exceptions for a
+   recurring calendar component.
+
+   Value Type: The default value type for this property is DATE-TIME.
+   The value type can be set to DATE.
+
+   Property Parameters: Non-standard, value data type and time zone
+   identifier property parameters can be specified on this property.
+
+   Conformance: This property can be specified in an iCalendar object
+   that includes a recurring calendar component.
+
+   Description: The exception dates, if specified, are used in computing
+   the recurrence set. The recurrence set is the complete set of
+   recurrence instances for a calendar component. The recurrence set is
+   generated by considering the initial "DTSTART" property along with
+   the "RRULE", "RDATE", "EXDATE" and "EXRULE" properties contained
+   within the iCalendar object. The "DTSTART" property defines the first
+   instance in the recurrence set. Multiple instances of the "RRULE" and
+   "EXRULE" properties can also be specified to define more
+   sophisticated recurrence sets. The final recurrence set is generated
+   by gathering all of the start date-times generated by any of the
+   specified "RRULE" and "RDATE" properties, and then excluding any
+   start date and times which fall within the union of start date and
+   times generated by any specified "EXRULE" and "EXDATE" properties.
+   This implies that start date and times within exclusion related
+   properties (i.e., "EXDATE" and "EXRULE") take precedence over those
+   specified by inclusion properties (i.e., "RDATE" and "RRULE"). Where
+   duplicate instances are generated by the "RRULE" and "RDATE"
+   properties, only one recurrence is considered. Duplicate instances
+   are ignored.
+
+   The "EXDATE" property can be used to exclude the value specified in
+   "DTSTART". However, in such cases the original "DTSTART" date MUST
+   still be maintained by the calendaring and scheduling system because
+   the original "DTSTART" value has inherent usage dependencies by other
+   properties such as the "RECURRENCE-ID".
+
+   Format Definition: The property is defined by the following notation:
+
+     exdate     = "EXDATE" exdtparam ":" exdtval *("," exdtval) CRLF
+
+     exdtparam  = *(
+
+                ; the following are optional,
+                ; but MUST NOT occur more than once
+
+                (";" "VALUE" "=" ("DATE-TIME" / "DATE")) /
+
+
+
+Dawson & Stenerson          Standards Track                   [Page 113]
+

+RFC 2445                       iCalendar                   November 1998
+
+
+                (";" tzidparam) /
+
+                ; the following is optional,
+                ; and MAY occur more than once
+
+                (";" xparam)
+
+                )
+
+     exdtval    = date-time / date
+     ;Value MUST match value type
+
+   Example: The following is an example of this property:
+
+     EXDATE:19960402T010000Z,19960403T010000Z,19960404T010000Z
+
+
4.8.5.2 Exception Rule
+ + Property Name: EXRULE + + Purpose: This property defines a rule or repeating pattern for an + exception to a recurrence set. + + Value Type: RECUR + + Property Parameters: Non-standard property parameters can be + specified on this property. + + Conformance: This property can be specified in "VEVENT", "VTODO" or + "VJOURNAL" calendar components. + + Description: The exception rule, if specified, is used in computing + the recurrence set. The recurrence set is the complete set of + recurrence instances for a calendar component. The recurrence set is + generated by considering the initial "DTSTART" property along with + the "RRULE", "RDATE", "EXDATE" and "EXRULE" properties contained + within the iCalendar object. The "DTSTART" defines the first instance + in the recurrence set. Multiple instances of the "RRULE" and "EXRULE" + properties can also be specified to define more sophisticated + recurrence sets. The final recurrence set is generated by gathering + all of the start date-times generated by any of the specified "RRULE" + and "RDATE" properties, and excluding any start date and times which + fall within the union of start date and times generated by any + specified "EXRULE" and "EXDATE" properties. This implies that start + date and times within exclusion related properties (i.e., "EXDATE" + and "EXRULE") take precedence over those specified by inclusion + + + + + +Dawson & Stenerson Standards Track [Page 114] +

+RFC 2445                       iCalendar                   November 1998
+
+
+   properties (i.e., "RDATE" and "RRULE"). Where duplicate instances are
+   generated by the "RRULE" and "RDATE" properties, only one recurrence
+   is considered. Duplicate instances are ignored.
+
+   The "EXRULE" property can be used to exclude the value specified in
+   "DTSTART". However, in such cases the original "DTSTART" date MUST
+   still be maintained by the calendaring and scheduling system because
+   the original "DTSTART" value has inherent usage dependencies by other
+   properties such as the "RECURRENCE-ID".
+
+   Format Definition: The property is defined by the following notation:
+
+     exrule     = "EXRULE" exrparam ":" recur CRLF
+
+     exrparam   = *(";" xparam)
+
+   Example: The following are examples of this property. Except every
+   other week, on Tuesday and Thursday for 4 occurrences:
+
+     EXRULE:FREQ=WEEKLY;COUNT=4;INTERVAL=2;BYDAY=TU,TH
+
+   Except daily for 10 occurrences:
+
+     EXRULE:FREQ=DAILY;COUNT=10
+
+   Except yearly in June and July for 8 occurrences:
+
+     EXRULE:FREQ=YEARLY;COUNT=8;BYMONTH=6,7
+
+
4.8.5.3 Recurrence Date/Times
+ + Property Name: RDATE + + Purpose: This property defines the list of date/times for a + recurrence set. + + Value Type: The default value type for this property is DATE-TIME. + The value type can be set to DATE or PERIOD. + + Property Parameters: Non-standard, value data type and time zone + identifier property parameters can be specified on this property. + + Conformance: The property can be specified in "VEVENT", "VTODO", + "VJOURNAL" or "VTIMEZONE" calendar components. + + + + + + + +Dawson & Stenerson Standards Track [Page 115] +

+RFC 2445                       iCalendar                   November 1998
+
+
+   Description: This property can appear along with the "RRULE" property
+   to define an aggregate set of repeating occurrences. When they both
+   appear in an iCalendar object, the recurring events are defined by
+   the union of occurrences defined by both the "RDATE" and "RRULE".
+
+   The recurrence dates, if specified, are used in computing the
+   recurrence set. The recurrence set is the complete set of recurrence
+   instances for a calendar component. The recurrence set is generated
+   by considering the initial "DTSTART" property along with the "RRULE",
+   "RDATE", "EXDATE" and "EXRULE" properties contained within the
+   iCalendar object. The "DTSTART" property defines the first instance
+   in the recurrence set. Multiple instances of the "RRULE" and "EXRULE"
+   properties can also be specified to define more sophisticated
+   recurrence sets. The final recurrence set is generated by gathering
+   all of the start date/times generated by any of the specified "RRULE"
+   and "RDATE" properties, and excluding any start date/times which fall
+   within the union of start date/times generated by any specified
+   "EXRULE" and "EXDATE" properties. This implies that start date/times
+   within exclusion related properties (i.e., "EXDATE" and "EXRULE")
+   take precedence over those specified by inclusion properties (i.e.,
+   "RDATE" and "RRULE"). Where duplicate instances are generated by the
+   "RRULE" and "RDATE" properties, only one recurrence is considered.
+   Duplicate instances are ignored.
+
+   Format Definition: The property is defined by the following notation:
+
+     rdate      = "RDATE" rdtparam ":" rdtval *("," rdtval) CRLF
+
+     rdtparam   = *(
+
+                ; the following are optional,
+                ; but MUST NOT occur more than once
+
+                (";" "VALUE" "=" ("DATE-TIME" / "DATE" / "PERIOD")) /
+                (";" tzidparam) /
+
+                ; the following is optional,
+                ; and MAY occur more than once
+
+                (";" xparam)
+
+                )
+
+     rdtval     = date-time / date / period
+     ;Value MUST match value type
+
+   Example: The following are examples of this property:
+
+
+
+
+Dawson & Stenerson          Standards Track                   [Page 116]
+

+RFC 2445                       iCalendar                   November 1998
+
+
+     RDATE:19970714T123000Z
+
+     RDATE;TZID=US-EASTERN:19970714T083000
+
+     RDATE;VALUE=PERIOD:19960403T020000Z/19960403T040000Z,
+      19960404T010000Z/PT3H
+
+     RDATE;VALUE=DATE:19970101,19970120,19970217,19970421
+      19970526,19970704,19970901,19971014,19971128,19971129,19971225
+
+
4.8.5.4 Recurrence Rule
+ + Property Name: RRULE + + Purpose: This property defines a rule or repeating pattern for + recurring events, to-dos, or time zone definitions. + + Value Type: RECUR + + Property Parameters: Non-standard property parameters can be + specified on this property. + + Conformance: This property can be specified one or more times in + recurring "VEVENT", "VTODO" and "VJOURNAL" calendar components. It + can also be specified once in each STANDARD or DAYLIGHT sub-component + of the "VTIMEZONE" calendar component. + + Description: The recurrence rule, if specified, is used in computing + the recurrence set. The recurrence set is the complete set of + recurrence instances for a calendar component. The recurrence set is + generated by considering the initial "DTSTART" property along with + the "RRULE", "RDATE", "EXDATE" and "EXRULE" properties contained + within the iCalendar object. The "DTSTART" property defines the first + instance in the recurrence set. Multiple instances of the "RRULE" and + "EXRULE" properties can also be specified to define more + sophisticated recurrence sets. The final recurrence set is generated + by gathering all of the start date/times generated by any of the + specified "RRULE" and "RDATE" properties, and excluding any start + date/times which fall within the union of start date/times generated + by any specified "EXRULE" and "EXDATE" properties. This implies that + start date/times within exclusion related properties (i.e., "EXDATE" + and "EXRULE") take precedence over those specified by inclusion + properties (i.e., "RDATE" and "RRULE"). Where duplicate instances are + generated by the "RRULE" and "RDATE" properties, only one recurrence + is considered. Duplicate instances are ignored. + + + + + + +Dawson & Stenerson Standards Track [Page 117] +

+RFC 2445                       iCalendar                   November 1998
+
+
+   The "DTSTART" and "DTEND" property pair or "DTSTART" and "DURATION"
+   property pair, specified within the iCalendar object defines the
+   first instance of the recurrence. When used with a recurrence rule,
+   the "DTSTART" and "DTEND" properties MUST be specified in local time
+   and the appropriate set of "VTIMEZONE" calendar components MUST be
+   included. For detail on the usage of the "VTIMEZONE" calendar
+   component, see the "VTIMEZONE" calendar component definition.
+
+   Any duration associated with the iCalendar object applies to all
+   members of the generated recurrence set. Any modified duration for
+   specific recurrences MUST be explicitly specified using the "RDATE"
+   property.
+
+   Format Definition: This property is defined by the following
+   notation:
+
+     rrule      = "RRULE" rrulparam ":" recur CRLF
+
+     rrulparam  = *(";" xparam)
+
+   Example: All examples assume the Eastern United States time zone.
+
+   Daily for 10 occurrences:
+
+     DTSTART;TZID=US-Eastern:19970902T090000
+     RRULE:FREQ=DAILY;COUNT=10
+
+     ==> (1997 9:00 AM EDT)September 2-11
+
+   Daily until December 24, 1997:
+
+     DTSTART;TZID=US-Eastern:19970902T090000
+     RRULE:FREQ=DAILY;UNTIL=19971224T000000Z
+
+     ==> (1997 9:00 AM EDT)September 2-30;October 1-25
+         (1997 9:00 AM EST)October 26-31;November 1-30;December 1-23
+
+   Every other day - forever:
+
+     DTSTART;TZID=US-Eastern:19970902T090000
+     RRULE:FREQ=DAILY;INTERVAL=2
+     ==> (1997 9:00 AM EDT)September2,4,6,8...24,26,28,30;
+          October 2,4,6...20,22,24
+         (1997 9:00 AM EST)October 26,28,30;November 1,3,5,7...25,27,29;
+          Dec 1,3,...
+
+   Every 10 days, 5 occurrences:
+
+
+
+
+Dawson & Stenerson          Standards Track                   [Page 118]
+

+RFC 2445                       iCalendar                   November 1998
+
+
+     DTSTART;TZID=US-Eastern:19970902T090000
+     RRULE:FREQ=DAILY;INTERVAL=10;COUNT=5
+
+     ==> (1997 9:00 AM EDT)September 2,12,22;October 2,12
+
+   Everyday in January, for 3 years:
+
+     DTSTART;TZID=US-Eastern:19980101T090000
+     RRULE:FREQ=YEARLY;UNTIL=20000131T090000Z;
+      BYMONTH=1;BYDAY=SU,MO,TU,WE,TH,FR,SA
+     or
+     RRULE:FREQ=DAILY;UNTIL=20000131T090000Z;BYMONTH=1
+
+     ==> (1998 9:00 AM EDT)January 1-31
+         (1999 9:00 AM EDT)January 1-31
+         (2000 9:00 AM EDT)January 1-31
+
+   Weekly for 10 occurrences
+
+     DTSTART;TZID=US-Eastern:19970902T090000
+     RRULE:FREQ=WEEKLY;COUNT=10
+
+     ==> (1997 9:00 AM EDT)September 2,9,16,23,30;October 7,14,21
+         (1997 9:00 AM EST)October 28;November 4
+
+   Weekly until December 24, 1997
+
+     DTSTART;TZID=US-Eastern:19970902T090000
+     RRULE:FREQ=WEEKLY;UNTIL=19971224T000000Z
+
+     ==> (1997 9:00 AM EDT)September 2,9,16,23,30;October 7,14,21
+         (1997 9:00 AM EST)October 28;November 4,11,18,25;
+                           December 2,9,16,23
+   Every other week - forever:
+
+     DTSTART;TZID=US-Eastern:19970902T090000
+     RRULE:FREQ=WEEKLY;INTERVAL=2;WKST=SU
+
+     ==> (1997 9:00 AM EDT)September 2,16,30;October 14
+         (1997 9:00 AM EST)October 28;November 11,25;December 9,23
+         (1998 9:00 AM EST)January 6,20;February
+     ...
+
+   Weekly on Tuesday and Thursday for 5 weeks:
+
+    DTSTART;TZID=US-Eastern:19970902T090000
+    RRULE:FREQ=WEEKLY;UNTIL=19971007T000000Z;WKST=SU;BYDAY=TU,TH
+    or
+
+
+
+Dawson & Stenerson          Standards Track                   [Page 119]
+

+RFC 2445                       iCalendar                   November 1998
+
+
+    RRULE:FREQ=WEEKLY;COUNT=10;WKST=SU;BYDAY=TU,TH
+
+    ==> (1997 9:00 AM EDT)September 2,4,9,11,16,18,23,25,30;October 2
+
+   Every other week on Monday, Wednesday and Friday until December 24,
+   1997, but starting on Tuesday, September 2, 1997:
+
+     DTSTART;TZID=US-Eastern:19970902T090000
+     RRULE:FREQ=WEEKLY;INTERVAL=2;UNTIL=19971224T000000Z;WKST=SU;
+      BYDAY=MO,WE,FR
+     ==> (1997 9:00 AM EDT)September 2,3,5,15,17,19,29;October
+     1,3,13,15,17
+         (1997 9:00 AM EST)October 27,29,31;November 10,12,14,24,26,28;
+                           December 8,10,12,22
+
+   Every other week on Tuesday and Thursday, for 8 occurrences:
+
+     DTSTART;TZID=US-Eastern:19970902T090000
+     RRULE:FREQ=WEEKLY;INTERVAL=2;COUNT=8;WKST=SU;BYDAY=TU,TH
+
+     ==> (1997 9:00 AM EDT)September 2,4,16,18,30;October 2,14,16
+
+   Monthly on the 1st Friday for ten occurrences:
+
+     DTSTART;TZID=US-Eastern:19970905T090000
+     RRULE:FREQ=MONTHLY;COUNT=10;BYDAY=1FR
+
+     ==> (1997 9:00 AM EDT)September 5;October 3
+         (1997 9:00 AM EST)November 7;Dec 5
+         (1998 9:00 AM EST)January 2;February 6;March 6;April 3
+         (1998 9:00 AM EDT)May 1;June 5
+
+   Monthly on the 1st Friday until December 24, 1997:
+
+     DTSTART;TZID=US-Eastern:19970905T090000
+     RRULE:FREQ=MONTHLY;UNTIL=19971224T000000Z;BYDAY=1FR
+
+     ==> (1997 9:00 AM EDT)September 5;October 3
+         (1997 9:00 AM EST)November 7;December 5
+
+   Every other month on the 1st and last Sunday of the month for 10
+   occurrences:
+
+     DTSTART;TZID=US-Eastern:19970907T090000
+     RRULE:FREQ=MONTHLY;INTERVAL=2;COUNT=10;BYDAY=1SU,-1SU
+
+     ==> (1997 9:00 AM EDT)September 7,28
+         (1997 9:00 AM EST)November 2,30
+
+
+
+Dawson & Stenerson          Standards Track                   [Page 120]
+

+RFC 2445                       iCalendar                   November 1998
+
+
+         (1998 9:00 AM EST)January 4,25;March 1,29
+         (1998 9:00 AM EDT)May 3,31
+
+   Monthly on the second to last Monday of the month for 6 months:
+
+     DTSTART;TZID=US-Eastern:19970922T090000
+     RRULE:FREQ=MONTHLY;COUNT=6;BYDAY=-2MO
+
+     ==> (1997 9:00 AM EDT)September 22;October 20
+         (1997 9:00 AM EST)November 17;December 22
+         (1998 9:00 AM EST)January 19;February 16
+
+   Monthly on the third to the last day of the month, forever:
+
+     DTSTART;TZID=US-Eastern:19970928T090000
+     RRULE:FREQ=MONTHLY;BYMONTHDAY=-3
+
+     ==> (1997 9:00 AM EDT)September 28
+         (1997 9:00 AM EST)October 29;November 28;December 29
+         (1998 9:00 AM EST)January 29;February 26
+     ...
+
+   Monthly on the 2nd and 15th of the month for 10 occurrences:
+
+     DTSTART;TZID=US-Eastern:19970902T090000
+     RRULE:FREQ=MONTHLY;COUNT=10;BYMONTHDAY=2,15
+
+     ==> (1997 9:00 AM EDT)September 2,15;October 2,15
+         (1997 9:00 AM EST)November 2,15;December 2,15
+         (1998 9:00 AM EST)January 2,15
+
+   Monthly on the first and last day of the month for 10 occurrences:
+
+     DTSTART;TZID=US-Eastern:19970930T090000
+     RRULE:FREQ=MONTHLY;COUNT=10;BYMONTHDAY=1,-1
+
+     ==> (1997 9:00 AM EDT)September 30;October 1
+         (1997 9:00 AM EST)October 31;November 1,30;December 1,31
+         (1998 9:00 AM EST)January 1,31;February 1
+
+   Every 18 months on the 10th thru 15th of the month for 10
+   occurrences:
+
+     DTSTART;TZID=US-Eastern:19970910T090000
+     RRULE:FREQ=MONTHLY;INTERVAL=18;COUNT=10;BYMONTHDAY=10,11,12,13,14,
+      15
+
+     ==> (1997 9:00 AM EDT)September 10,11,12,13,14,15
+
+
+
+Dawson & Stenerson          Standards Track                   [Page 121]
+

+RFC 2445                       iCalendar                   November 1998
+
+
+         (1999 9:00 AM EST)March 10,11,12,13
+
+   Every Tuesday, every other month:
+
+     DTSTART;TZID=US-Eastern:19970902T090000
+     RRULE:FREQ=MONTHLY;INTERVAL=2;BYDAY=TU
+
+     ==> (1997 9:00 AM EDT)September 2,9,16,23,30
+         (1997 9:00 AM EST)November 4,11,18,25
+         (1998 9:00 AM EST)January 6,13,20,27;March 3,10,17,24,31
+     ...
+
+   Yearly in June and July for 10 occurrences:
+
+     DTSTART;TZID=US-Eastern:19970610T090000
+     RRULE:FREQ=YEARLY;COUNT=10;BYMONTH=6,7
+     ==> (1997 9:00 AM EDT)June 10;July 10
+         (1998 9:00 AM EDT)June 10;July 10
+         (1999 9:00 AM EDT)June 10;July 10
+         (2000 9:00 AM EDT)June 10;July 10
+         (2001 9:00 AM EDT)June 10;July 10
+     Note: Since none of the BYDAY, BYMONTHDAY or BYYEARDAY components
+     are specified, the day is gotten from DTSTART
+
+   Every other year on January, February, and March for 10 occurrences:
+
+     DTSTART;TZID=US-Eastern:19970310T090000
+     RRULE:FREQ=YEARLY;INTERVAL=2;COUNT=10;BYMONTH=1,2,3
+
+     ==> (1997 9:00 AM EST)March 10
+         (1999 9:00 AM EST)January 10;February 10;March 10
+         (2001 9:00 AM EST)January 10;February 10;March 10
+         (2003 9:00 AM EST)January 10;February 10;March 10
+
+   Every 3rd year on the 1st, 100th and 200th day for 10 occurrences:
+
+     DTSTART;TZID=US-Eastern:19970101T090000
+     RRULE:FREQ=YEARLY;INTERVAL=3;COUNT=10;BYYEARDAY=1,100,200
+
+     ==> (1997 9:00 AM EST)January 1
+         (1997 9:00 AM EDT)April 10;July 19
+         (2000 9:00 AM EST)January 1
+         (2000 9:00 AM EDT)April 9;July 18
+         (2003 9:00 AM EST)January 1
+         (2003 9:00 AM EDT)April 10;July 19
+         (2006 9:00 AM EST)January 1
+
+   Every 20th Monday of the year, forever:
+
+
+
+Dawson & Stenerson          Standards Track                   [Page 122]
+

+RFC 2445                       iCalendar                   November 1998
+
+
+     DTSTART;TZID=US-Eastern:19970519T090000
+     RRULE:FREQ=YEARLY;BYDAY=20MO
+
+     ==> (1997 9:00 AM EDT)May 19
+         (1998 9:00 AM EDT)May 18
+         (1999 9:00 AM EDT)May 17
+     ...
+
+   Monday of week number 20 (where the default start of the week is
+   Monday), forever:
+
+     DTSTART;TZID=US-Eastern:19970512T090000
+     RRULE:FREQ=YEARLY;BYWEEKNO=20;BYDAY=MO
+
+     ==> (1997 9:00 AM EDT)May 12
+         (1998 9:00 AM EDT)May 11
+         (1999 9:00 AM EDT)May 17
+     ...
+
+   Every Thursday in March, forever:
+
+     DTSTART;TZID=US-Eastern:19970313T090000
+     RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=TH
+
+     ==> (1997 9:00 AM EST)March 13,20,27
+         (1998 9:00 AM EST)March 5,12,19,26
+         (1999 9:00 AM EST)March 4,11,18,25
+     ...
+
+   Every Thursday, but only during June, July, and August, forever:
+
+     DTSTART;TZID=US-Eastern:19970605T090000
+     RRULE:FREQ=YEARLY;BYDAY=TH;BYMONTH=6,7,8
+
+     ==> (1997 9:00 AM EDT)June 5,12,19,26;July 3,10,17,24,31;
+                       August 7,14,21,28
+         (1998 9:00 AM EDT)June 4,11,18,25;July 2,9,16,23,30;
+                       August 6,13,20,27
+         (1999 9:00 AM EDT)June 3,10,17,24;July 1,8,15,22,29;
+                       August 5,12,19,26
+     ...
+
+   Every Friday the 13th, forever:
+
+     DTSTART;TZID=US-Eastern:19970902T090000
+     EXDATE;TZID=US-Eastern:19970902T090000
+     RRULE:FREQ=MONTHLY;BYDAY=FR;BYMONTHDAY=13
+
+
+
+
+Dawson & Stenerson          Standards Track                   [Page 123]
+

+RFC 2445                       iCalendar                   November 1998
+
+
+     ==> (1998 9:00 AM EST)February 13;March 13;November 13
+         (1999 9:00 AM EDT)August 13
+         (2000 9:00 AM EDT)October 13
+     ...
+
+   The first Saturday that follows the first Sunday of the month,
+    forever:
+
+     DTSTART;TZID=US-Eastern:19970913T090000
+     RRULE:FREQ=MONTHLY;BYDAY=SA;BYMONTHDAY=7,8,9,10,11,12,13
+
+     ==> (1997 9:00 AM EDT)September 13;October 11
+         (1997 9:00 AM EST)November 8;December 13
+         (1998 9:00 AM EST)January 10;February 7;March 7
+         (1998 9:00 AM EDT)April 11;May 9;June 13...
+     ...
+
+   Every four years, the first Tuesday after a Monday in November,
+   forever (U.S. Presidential Election day):
+
+     DTSTART;TZID=US-Eastern:19961105T090000
+     RRULE:FREQ=YEARLY;INTERVAL=4;BYMONTH=11;BYDAY=TU;BYMONTHDAY=2,3,4,
+      5,6,7,8
+
+     ==> (1996 9:00 AM EST)November 5
+         (2000 9:00 AM EST)November 7
+         (2004 9:00 AM EST)November 2
+     ...
+
+   The 3rd instance into the month of one of Tuesday, Wednesday or
+   Thursday, for the next 3 months:
+
+     DTSTART;TZID=US-Eastern:19970904T090000
+     RRULE:FREQ=MONTHLY;COUNT=3;BYDAY=TU,WE,TH;BYSETPOS=3
+
+     ==> (1997 9:00 AM EDT)September 4;October 7
+         (1997 9:00 AM EST)November 6
+
+   The 2nd to last weekday of the month:
+
+     DTSTART;TZID=US-Eastern:19970929T090000
+     RRULE:FREQ=MONTHLY;BYDAY=MO,TU,WE,TH,FR;BYSETPOS=-2
+
+     ==> (1997 9:00 AM EDT)September 29
+         (1997 9:00 AM EST)October 30;November 27;December 30
+         (1998 9:00 AM EST)January 29;February 26;March 30
+     ...
+
+
+
+
+Dawson & Stenerson          Standards Track                   [Page 124]
+

+RFC 2445                       iCalendar                   November 1998
+
+
+   Every 3 hours from 9:00 AM to 5:00 PM on a specific day:
+
+     DTSTART;TZID=US-Eastern:19970902T090000
+     RRULE:FREQ=HOURLY;INTERVAL=3;UNTIL=19970902T170000Z
+
+     ==> (September 2, 1997 EDT)09:00,12:00,15:00
+
+   Every 15 minutes for 6 occurrences:
+
+     DTSTART;TZID=US-Eastern:19970902T090000
+     RRULE:FREQ=MINUTELY;INTERVAL=15;COUNT=6
+
+     ==> (September 2, 1997 EDT)09:00,09:15,09:30,09:45,10:00,10:15
+
+   Every hour and a half for 4 occurrences:
+
+     DTSTART;TZID=US-Eastern:19970902T090000
+     RRULE:FREQ=MINUTELY;INTERVAL=90;COUNT=4
+
+     ==> (September 2, 1997 EDT)09:00,10:30;12:00;13:30
+
+   Every 20 minutes from 9:00 AM to 4:40 PM every day:
+
+     DTSTART;TZID=US-Eastern:19970902T090000
+     RRULE:FREQ=DAILY;BYHOUR=9,10,11,12,13,14,15,16;BYMINUTE=0,20,40
+     or
+     RRULE:FREQ=MINUTELY;INTERVAL=20;BYHOUR=9,10,11,12,13,14,15,16
+
+     ==> (September 2, 1997 EDT)9:00,9:20,9:40,10:00,10:20,
+                                ... 16:00,16:20,16:40
+         (September 3, 1997 EDT)9:00,9:20,9:40,10:00,10:20,
+                               ...16:00,16:20,16:40
+     ...
+
+   An example where the days generated makes a difference because of
+   WKST:
+
+     DTSTART;TZID=US-Eastern:19970805T090000
+     RRULE:FREQ=WEEKLY;INTERVAL=2;COUNT=4;BYDAY=TU,SU;WKST=MO
+
+     ==> (1997 EDT)Aug 5,10,19,24
+
+     changing only WKST from MO to SU, yields different results...
+
+     DTSTART;TZID=US-Eastern:19970805T090000
+     RRULE:FREQ=WEEKLY;INTERVAL=2;COUNT=4;BYDAY=TU,SU;WKST=SU
+     ==> (1997 EDT)August 5,17,19,31
+
+
+
+
+Dawson & Stenerson          Standards Track                   [Page 125]
+

+RFC 2445                       iCalendar                   November 1998
+
+
+

4.8.6 Alarm Component Properties

+ + The following properties specify alarm information in calendar + components. + +
4.8.6.1 Action
+ + Property Name: ACTION + + Purpose: This property defines the action to be invoked when an alarm + is triggered. + + Value Type: TEXT + + Property Parameters: Non-standard property parameters can be + specified on this property. + + Conformance: This property MUST be specified once in a "VALARM" + calendar component. + + Description: Each "VALARM" calendar component has a particular type + of action associated with it. This property specifies the type of + action + + Format Definition: The property is defined by the following notation: + + action = "ACTION" actionparam ":" actionvalue CRLF + + actionparam = *(";" xparam) + + actionvalue = "AUDIO" / "DISPLAY" / "EMAIL" / "PROCEDURE" + / iana-token / x-name + + Example: The following are examples of this property in a "VALARM" + calendar component: + + ACTION:AUDIO + + ACTION:DISPLAY + + ACTION:PROCEDURE + +
4.8.6.2 Repeat Count
+ + Property Name: REPEAT + + Purpose: This property defines the number of time the alarm should be + repeated, after the initial trigger. + + + +Dawson & Stenerson Standards Track [Page 126] +

+RFC 2445                       iCalendar                   November 1998
+
+
+   Value Type: INTEGER
+
+   Property Parameters: Non-standard property parameters can be
+   specified on this property.
+
+   Conformance: This property can be specified in a "VALARM" calendar
+   component.
+
+   Description: If the alarm triggers more than once, then this property
+   MUST be specified along with the "DURATION" property.
+
+   Format Definition: The property is defined by the following notation:
+
+     repeatcnt  = "REPEAT" repparam ":" integer CRLF
+     ;Default is "0", zero.
+
+     repparam   = *(";" xparam)
+
+   Example: The following is an example of this property for an alarm
+   that repeats 4 additional times with a 5 minute delay after the
+   initial triggering of the alarm:
+
+     REPEAT:4
+     DURATION:PT5M
+
+
4.8.6.3 Trigger
+ + Property Name: TRIGGER + + Purpose: This property specifies when an alarm will trigger. + + Value Type: The default value type is DURATION. The value type can be + set to a DATE-TIME value type, in which case the value MUST specify a + UTC formatted DATE-TIME value. + + Property Parameters: Non-standard, value data type, time zone + identifier or trigger relationship property parameters can be + specified on this property. The trigger relationship property + parameter MUST only be specified when the value type is DURATION. + + Conformance: This property MUST be specified in the "VALARM" calendar + component. + + Description: Within the "VALARM" calendar component, this property + defines when the alarm will trigger. The default value type is + DURATION, specifying a relative time for the trigger of the alarm. + The default duration is relative to the start of an event or to-do + that the alarm is associated with. The duration can be explicitly set + + + +Dawson & Stenerson Standards Track [Page 127] +

+RFC 2445                       iCalendar                   November 1998
+
+
+   to trigger from either the end or the start of the associated event
+   or to-do with the "RELATED" parameter. A value of START will set the
+   alarm to trigger off the start of the associated event or to-do. A
+   value of END will set the alarm to trigger off the end of the
+   associated event or to-do.
+
+   Either a positive or negative duration may be specified for the
+   "TRIGGER" property. An alarm with a positive duration is triggered
+   after the associated start or end of the event or to-do. An alarm
+   with a negative duration is triggered before the associated start or
+   end of the event or to-do.
+
+   The "RELATED" property parameter is not valid if the value type of
+   the property is set to DATE-TIME (i.e., for an absolute date and time
+   alarm trigger). If a value type of DATE-TIME is specified, then the
+   property value MUST be specified in the UTC time format. If an
+   absolute trigger is specified on an alarm for a recurring event or
+   to-do, then the alarm will only trigger for the specified absolute
+   date/time, along with any specified repeating instances.
+
+   If the trigger is set relative to START, then the "DTSTART" property
+   MUST be present in the associated "VEVENT" or "VTODO" calendar
+   component. If an alarm is specified for an event with the trigger set
+   relative to the END, then the "DTEND" property or the "DSTART" and
+   "DURATION' properties MUST be present in the associated "VEVENT"
+   calendar component. If the alarm is specified for a to-do with a
+   trigger set relative to the END, then either the "DUE" property or
+   the "DSTART" and "DURATION' properties MUST be present in the
+   associated "VTODO" calendar component.
+
+   Alarms specified in an event or to-do which is defined in terms of a
+   DATE value type will be triggered relative to 00:00:00 UTC on the
+   specified date. For example, if "DTSTART:19980205, then the duration
+   trigger will be relative to19980205T000000Z.
+
+   Format Definition: The property is defined by the following notation:
+
+     trigger    = "TRIGGER" (trigrel / trigabs)
+
+     trigrel    = *(
+
+                ; the following are optional,
+                ; but MUST NOT occur more than once
+
+                  (";" "VALUE" "=" "DURATION") /
+                  (";" trigrelparam) /
+
+                ; the following is optional,
+
+
+
+Dawson & Stenerson          Standards Track                   [Page 128]
+

+RFC 2445                       iCalendar                   November 1998
+
+
+                ; and MAY occur more than once
+
+                  (";" xparam)
+                  ) ":"  dur-value
+
+     trigabs    = 1*(
+
+                ; the following is REQUIRED,
+                ; but MUST NOT occur more than once
+
+                  (";" "VALUE" "=" "DATE-TIME") /
+
+                ; the following is optional,
+                ; and MAY occur more than once
+
+                  (";" xparam)
+
+                  ) ":" date-time
+
+   Example: A trigger set 15 minutes prior to the start of the event or
+   to-do.
+
+     TRIGGER:-P15M
+
+   A trigger set 5 minutes after the end of the event or to-do.
+
+     TRIGGER;RELATED=END:P5M
+
+   A trigger set to an absolute date/time.
+
+     TRIGGER;VALUE=DATE-TIME:19980101T050000Z
+
+

4.8.7 Change Management Component Properties

+ + The following properties specify change management information in + calendar components. + +
4.8.7.1 Date/Time Created
+ + Property Name: CREATED + + Purpose: This property specifies the date and time that the calendar + information was created by the calendar user agent in the calendar + store. + + Note: This is analogous to the creation date and time for a file + in the file system. + + + + +Dawson & Stenerson Standards Track [Page 129] +

+RFC 2445                       iCalendar                   November 1998
+
+
+   Value Type: DATE-TIME
+
+   Property Parameters: Non-standard property parameters can be
+   specified on this property.
+
+   Conformance: The property can be specified once in "VEVENT", "VTODO"
+   or "VJOURNAL" calendar components.
+
+   Description: The date and time is a UTC value.
+
+   Format Definition: The property is defined by the following notation:
+
+     created    = "CREATED" creaparam ":" date-time CRLF
+
+     creaparam  = *(";" xparam)
+
+   Example: The following is an example of this property:
+
+     CREATED:19960329T133000Z
+
+
4.8.7.2 Date/Time Stamp
+ + Property Name: DTSTAMP + + Purpose: The property indicates the date/time that the instance of + the iCalendar object was created. + + Value Type: DATE-TIME + + Property Parameters: Non-standard property parameters can be + specified on this property. + + Conformance: This property MUST be included in the "VEVENT", "VTODO", + "VJOURNAL" or "VFREEBUSY" calendar components. + + Description: The value MUST be specified in the UTC time format. + + This property is also useful to protocols such as [IMIP] that have + inherent latency issues with the delivery of content. This property + will assist in the proper sequencing of messages containing iCalendar + objects. + + This property is different than the "CREATED" and "LAST-MODIFIED" + properties. These two properties are used to specify when the + particular calendar data in the calendar store was created and last + modified. This is different than when the iCalendar object + representation of the calendar service information was created or + last modified. + + + +Dawson & Stenerson Standards Track [Page 130] +

+RFC 2445                       iCalendar                   November 1998
+
+
+   Format Definition: The property is defined by the following notation:
+
+     dtstamp    = "DTSTAMP" stmparam ":" date-time CRLF
+
+     stmparam   = *(";" xparam)
+
+   Example:
+
+     DTSTAMP:19971210T080000Z
+
+
4.8.7.3 Last Modified
+ + Property Name: LAST-MODIFIED + + Purpose: The property specifies the date and time that the + information associated with the calendar component was last revised + in the calendar store. + + Note: This is analogous to the modification date and time for a + file in the file system. + + Value Type: DATE-TIME + + Property Parameters: Non-standard property parameters can be + specified on this property. + + Conformance: This property can be specified in the "EVENT", "VTODO", + "VJOURNAL" or "VTIMEZONE" calendar components. + + Description: The property value MUST be specified in the UTC time + format. + + Format Definition: The property is defined by the following notation: + + last-mod = "LAST-MODIFIED" lstparam ":" date-time CRLF + + lstparam = *(";" xparam) + + Example: The following is are examples of this property: + + LAST-MODIFIED:19960817T133000Z + +
4.8.7.4 Sequence Number
+ + Property Name: SEQUENCE + + Purpose: This property defines the revision sequence number of the + calendar component within a sequence of revisions. + + + +Dawson & Stenerson Standards Track [Page 131] +

+RFC 2445                       iCalendar                   November 1998
+
+
+   Value Type: integer
+
+   Property Parameters: Non-standard property parameters can be
+   specified on this property.
+
+   Conformance: The property can be specified in "VEVENT", "VTODO" or
+   "VJOURNAL" calendar component.
+
+   Description: When a calendar component is created, its sequence
+   number is zero (US-ASCII decimal 48). It is monotonically incremented
+   by the "Organizer's" CUA each time the "Organizer" makes a
+   significant revision to the calendar component. When the "Organizer"
+   makes changes to one of the following properties, the sequence number
+   MUST be incremented:
+
+     .  "DTSTART"
+
+     .  "DTEND"
+
+     .  "DUE"
+
+     .  "RDATE"
+
+     .  "RRULE"
+
+     .  "EXDATE"
+
+     .  "EXRULE"
+
+     .  "STATUS"
+
+   In addition, changes made by the "Organizer" to other properties can
+   also force the sequence number to be incremented. The "Organizer" CUA
+   MUST increment the sequence number when ever it makes changes to
+   properties in the calendar component that the "Organizer" deems will
+   jeopardize the validity of the participation status of the
+   "Attendees". For example, changing the location of a meeting from one
+   locale to another distant locale could effectively impact the
+   participation status of the "Attendees".
+
+   The "Organizer" includes this property in an iCalendar object that it
+   sends to an "Attendee" to specify the current version of the calendar
+   component.
+
+   The "Attendee" includes this property in an iCalendar object that it
+   sends to the "Organizer" to specify the version of the calendar
+   component that the "Attendee" is referring to.
+
+
+
+
+Dawson & Stenerson          Standards Track                   [Page 132]
+

+RFC 2445                       iCalendar                   November 1998
+
+
+   A change to the sequence number is not the mechanism that an
+   "Organizer" uses to request a response from the "Attendees". The
+   "RSVP" parameter on the "ATTENDEE" property is used by the
+   "Organizer" to indicate that a response from the "Attendees" is
+   requested.
+
+   Format Definition: This property is defined by the following
+   notation:
+
+     seq = "SEQUENCE" seqparam ":" integer CRLF
+     ; Default is "0"
+
+     seqparam   = *(";" xparam)
+
+   Example: The following is an example of this property for a calendar
+   component that was just created by the "Organizer".
+
+     SEQUENCE:0
+
+   The following is an example of this property for a calendar component
+   that has been revised two different times by the "Organizer".
+
+     SEQUENCE:2
+
+

4.8.8 Miscellaneous Component Properties

+ + The following properties specify information about a number of + miscellaneous features of calendar components. + +
4.8.8.1 Non-standard Properties
+ + Property Name: Any property name with a "X-" prefix + + Purpose: This class of property provides a framework for defining + non-standard properties. + + Value Type: TEXT + + Property Parameters: Non-standard and language property parameters + can be specified on this property. + + Conformance: This property can be specified in any calendar + component. + + Description: The MIME Calendaring and Scheduling Content Type + 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 memo. Extension properties are + + + +Dawson & Stenerson Standards Track [Page 133] +

+RFC 2445                       iCalendar                   November 1998
+
+
+   specified by property and/or property parameter names that have the
+   prefix text of "X-" (the two character sequence: LATIN CAPITAL LETTER
+   X character followed by the HYPEN-MINUS character). It is recommended
+   that vendors concatenate onto this sentinel another short prefix text
+   to identify the vendor. This will facilitate readability of the
+   extensions and minimize possible collision of names between different
+   vendors. User agents that support this content type are expected to
+   be able to parse the extension properties and property parameters but
+   can ignore them.
+
+   At present, there is no registration authority for names of extension
+   properties and property parameters. The data type for this property
+   is TEXT. Optionally, the data type can be any of the other valid data
+   types.
+
+   Format Definition: The property is defined by the following notation:
+
+     x-prop     = x-name *(";" xparam) [";" languageparam] ":" text CRLF
+        ; Lines longer than 75 octets should be folded
+
+   Example: The following might be the ABC vendor's extension for an
+   audio-clip form of subject property:
+
+     X-ABC-MMSUBJ;X-ABC-MMSUBJTYPE=wave:http://load.noise.org/mysubj.wav
+
+
4.8.8.2 Request Status
+ + Property Name: REQUEST-STATUS + + Purpose: This property defines the status code returned for a + scheduling request. + + Value Type: TEXT + + Property Parameters: Non-standard and language property parameters + can be specified on this property. + + Conformance: The property can be specified in "VEVENT", "VTODO", + "VJOURNAL" or "VFREEBUSY" calendar component. + + Description: This property is used to return status code information + related to the processing of an associated iCalendar object. The data + type for this property is TEXT. + + The value consists of a short return status component, a longer + return status description component, and optionally a status-specific + data component. The components of the value are separated by the + SEMICOLON character (US-ASCII decimal 59). + + + +Dawson & Stenerson Standards Track [Page 134] +

+RFC 2445                       iCalendar                   November 1998
+
+
+   The short return status is a PERIOD character (US-ASCII decimal 46)
+   separated 3-tuple of integers. For example, "3.1.1". The successive
+   levels of integers provide for a successive level of status code
+   granularity.
+
+   The following are initial classes for the return status code.
+   Individual iCalendar object methods will define specific return
+   status codes for these classes. In addition, other classes for the
+   return status code may be defined using the registration process
+   defined later in this memo.
+
+     |==============+===============================================|
+     | Short Return | Longer Return Status Description              |
+     | Status Code  |                                               |
+     |==============+===============================================|
+     |    1.xx      | Preliminary success. This class of status     |
+     |              | of status code indicates that the request has |
+     |              | request has been initially processed but that |
+     |              | completion is pending.                        |
+     |==============+===============================================|
+     |    2.xx      | Successful. This class of status code         |
+     |              | indicates that the request was completed      |
+     |              | successfuly. However, the exact status code   |
+     |              | can indicate that a fallback has been taken.  |
+     |==============+===============================================|
+     |    3.xx      | Client Error. This class of status code       |
+     |              | indicates that the request was not successful.|
+     |              | The error is the result of either a syntax or |
+     |              | a semantic error in the client formatted      |
+     |              | request. Request should not be retried until  |
+     |              | the condition in the request is corrected.    |
+     |==============+===============================================|
+     |    4.xx      | Scheduling Error. This class of status code   |
+     |              | indicates that the request was not successful.|
+     |              | Some sort of error occurred within the        |
+     |              | calendaring and scheduling service, not       |
+     |              | directly related to the request itself.       |
+     |==============+===============================================|
+
+   Format Definition: The property is defined by the following notation:
+
+     rstatus    = "REQUEST-STATUS" rstatparam ":"
+                  statcode ";" statdesc [";" extdata]
+
+     rstatparam = *(
+
+                ; the following is optional,
+                ; but MUST NOT occur more than once
+
+
+
+Dawson & Stenerson          Standards Track                   [Page 135]
+

+RFC 2445                       iCalendar                   November 1998
+
+
+                (";" languageparm) /
+
+                ; the following is optional,
+                ; and MAY occur more than once
+
+                (";" xparam)
+
+                )
+
+     statcode   = 1*DIGIT *("." 1*DIGIT)
+     ;Hierarchical, numeric return status code
+
+     statdesc   = text
+     ;Textual status description
+
+     extdata    = text
+     ;Textual exception data. For example, the offending property
+     ;name and value or complete property line.
+
+   Example: The following are some possible examples of this property.
+   The COMMA and SEMICOLON separator characters in the property value
+   are BACKSLASH character escaped because they appear in a  text value.
+
+     REQUEST-STATUS:2.0;Success
+
+     REQUEST-STATUS:3.1;Invalid property value;DTSTART:96-Apr-01
+
+     REQUEST-STATUS:2.8; Success\, repeating event ignored. Scheduled
+      as a single event.;RRULE:FREQ=WEEKLY\;INTERVAL=2
+
+     REQUEST-STATUS:4.1;Event conflict. Date/time is busy.
+
+     REQUEST-STATUS:3.7;Invalid calendar user;ATTENDEE:
+      MAILTO:jsmith@host.com
+
+

5 iCalendar Object Examples

+ + The following examples are provided as an informational source of + illustrative iCalendar objects consistent with this content type. + + The following example specifies a three-day conference that begins at + 8:00 AM EDT, September 18, 1996 and end at 6:00 PM EDT, September 20, + 1996. + + BEGIN:VCALENDAR PRODID:-//xyz Corp//NONSGML PDA Calendar Verson + 1.0//EN VERSION:2.0 BEGIN:VEVENT DTSTAMP:19960704T120000Z + UID:uid1@host.com ORGANIZER:MAILTO:jsmith@host.com + DTSTART:19960918T143000Z DTEND:19960920T220000Z STATUS:CONFIRMED + + + +Dawson & Stenerson Standards Track [Page 136] +

+RFC 2445                       iCalendar                   November 1998
+
+
+     CATEGORIES:CONFERENCE SUMMARY:Networld+Interop Conference
+     DESCRIPTION:Networld+Interop Conference
+       and Exhibit\nAtlanta World Congress Center\n
+      Atlanta, Georgia END:VEVENT END:VCALENDAR
+
+   The following example specifies a group scheduled meeting that begin
+   at 8:30 AM EST on March 12, 1998 and end at 9:30 AM EST on March 12,
+   1998. The "Organizer" has scheduled the meeting with one or more
+   calendar users in a group. A time zone specification for Eastern
+   United States has been specified.
+
+     BEGIN:VCALENDAR
+     PRODID:-//RDU Software//NONSGML HandCal//EN
+     VERSION:2.0
+     BEGIN:VTIMEZONE
+     TZID:US-Eastern
+     BEGIN:STANDARD
+     DTSTART:19981025T020000
+     RDATE:19981025T020000
+     TZOFFSETFROM:-0400
+     TZOFFSETTO:-0500
+     TZNAME:EST
+     END:STANDARD
+     BEGIN:DAYLIGHT
+     DTSTART:19990404T020000
+     RDATE:19990404T020000
+     TZOFFSETFROM:-0500
+     TZOFFSETTO:-0400
+     TZNAME:EDT
+     END:DAYLIGHT
+     END:VTIMEZONE
+     BEGIN:VEVENT
+     DTSTAMP:19980309T231000Z
+     UID:guid-1.host1.com
+     ORGANIZER;ROLE=CHAIR:MAILTO:mrbig@host.com
+     ATTENDEE;RSVP=TRUE;ROLE=REQ-PARTICIPANT;CUTYPE=GROUP:
+      MAILTO:employee-A@host.com
+     DESCRIPTION:Project XYZ Review Meeting
+     CATEGORIES:MEETING
+     CLASS:PUBLIC
+     CREATED:19980309T130000Z
+     SUMMARY:XYZ Project Review
+     DTSTART;TZID=US-Eastern:19980312T083000
+     DTEND;TZID=US-Eastern:19980312T093000
+     LOCATION:1CP Conference Room 4350
+     END:VEVENT
+     END:VCALENDAR
+
+
+
+
+Dawson & Stenerson          Standards Track                   [Page 137]
+

+RFC 2445                       iCalendar                   November 1998
+
+
+   The following is an example of an iCalendar object passed in a MIME
+   message with a single body part consisting of a "text/calendar"
+   Content Type.
+
+     TO:jsmith@host1.com
+     FROM:jdoe@host1.com
+     MIME-VERSION:1.0
+     MESSAGE-ID:<id3@host1.com>
+     CONTENT-TYPE:text/calendar
+
+     BEGIN:VCALENDAR
+     METHOD:xyz
+     VERSION:2.0
+     PRODID:-//ABC Corporation//NONSGML My Product//EN
+     BEGIN:VEVENT
+     DTSTAMP:19970324T1200Z
+     SEQUENCE:0
+     UID:uid3@host1.com
+     ORGANIZER:MAILTO:jdoe@host1.com
+     ATTENDEE;RSVP=TRUE:MAILTO:jsmith@host1.com
+     DTSTART:19970324T123000Z
+     DTEND:19970324T210000Z
+     CATEGORIES:MEETING,PROJECT
+     CLASS:PUBLIC
+     SUMMARY:Calendaring Interoperability Planning Meeting
+     DESCRIPTION:Discuss how we can test c&s interoperability\n
+      using iCalendar and other IETF standards.
+     LOCATION:LDB Lobby
+     ATTACH;FMTTYPE=application/postscript:ftp://xyzCorp.com/pub/
+      conf/bkgrnd.ps
+     END:VEVENT
+     END:VCALENDAR
+
+   The following is an example of a to-do due on April 15, 1998. An
+   audio alarm has been specified to remind the calendar user at noon,
+   the day before the to-do is expected to be completed and repeat
+   hourly, four additional times. The to-do definition has been modified
+   twice since it was initially created.
+
+     BEGIN:VCALENDAR
+     VERSION:2.0
+     PRODID:-//ABC Corporation//NONSGML My Product//EN
+     BEGIN:VTODO
+     DTSTAMP:19980130T134500Z
+     SEQUENCE:2
+     UID:uid4@host1.com
+     ORGANIZER:MAILTO:unclesam@us.gov
+     ATTENDEE;PARTSTAT=ACCEPTED:MAILTO:jqpublic@host.com
+
+
+
+Dawson & Stenerson          Standards Track                   [Page 138]
+

+RFC 2445                       iCalendar                   November 1998
+
+
+     DUE:19980415T235959
+     STATUS:NEEDS-ACTION
+     SUMMARY:Submit Income Taxes
+     BEGIN:VALARM
+     ACTION:AUDIO
+     TRIGGER:19980403T120000
+     ATTACH;FMTTYPE=audio/basic:http://host.com/pub/audio-
+      files/ssbanner.aud
+     REPEAT:4
+     DURATION:PT1H
+     END:VALARM
+     END:VTODO
+     END:VCALENDAR
+
+   The following is an example of a journal entry.
+
+     BEGIN:VCALENDAR
+     VERSION:2.0
+     PRODID:-//ABC Corporation//NONSGML My Product//EN
+     BEGIN:VJOURNAL
+     DTSTAMP:19970324T120000Z
+     UID:uid5@host1.com
+     ORGANIZER:MAILTO:jsmith@host.com
+     STATUS:DRAFT
+     CLASS:PUBLIC
+     CATEGORY:Project Report, XYZ, Weekly Meeting
+     DESCRIPTION:Project xyz Review Meeting Minutes\n
+      Agenda\n1. Review of project version 1.0 requirements.\n2.
+     Definition
+      of project processes.\n3. Review of project schedule.\n
+      Participants: John Smith, Jane Doe, Jim Dandy\n-It was
+       decided that the requirements need to be signed off by
+       product marketing.\n-Project processes were accepted.\n
+      -Project schedule needs to account for scheduled holidays
+       and employee vacation time. Check with HR for specific
+       dates.\n-New schedule will be distributed by Friday.\n-
+      Next weeks meeting is cancelled. No meeting until 3/23.
+     END:VJOURNAL
+     END:VCALENDAR
+
+   The following is an example of published busy time information. The
+   iCalendar object might be placed in the network resource
+   www.host.com/calendar/busytime/jsmith.ifb.
+
+     BEGIN:VCALENDAR
+     VERSION:2.0
+     PRODID:-//RDU Software//NONSGML HandCal//EN
+     BEGIN:VFREEBUSY
+
+
+
+Dawson & Stenerson          Standards Track                   [Page 139]
+

+RFC 2445                       iCalendar                   November 1998
+
+
+     ORGANIZER:MAILTO:jsmith@host.com
+     DTSTART:19980313T141711Z
+     DTEND:19980410T141711Z
+     FREEBUSY:19980314T233000Z/19980315T003000Z
+     FREEBUSY:19980316T153000Z/19980316T163000Z
+     FREEBUSY:19980318T030000Z/19980318T040000Z
+     URL:http://www.host.com/calendar/busytime/jsmith.ifb
+     END:VFREEBUSY
+     END:VCALENDAR
+
+

6 Recommended Practices

+ + These recommended practices should be followed in order to assure + consistent handling of the following cases for an iCalendar object. + + 1. Content lines longer than 75 octets SHOULD be folded. + + 2. A calendar entry with a "DTSTART" property but no "DTEND" + property does not take up any time. It is intended to represent + an event that is associated with a given calendar date and time + of day, such as an anniversary. Since the event does not take up + any time, it MUST NOT be used to record busy time no matter what + the value for the "TRANSP" property. + + 3. When the "DTSTART" and "DTEND", for "VEVENT", "VJOURNAL" and + "VFREEBUSY" calendar components, and "DTSTART" and "DUE", for + "VTODO" calendar components, have the same value data type (e.g., + DATE-TIME), they SHOULD specify values in the same time format + (e.g., UTC time format). + + 4. When the combination of the "RRULE" and "RDATE" properties on an + iCalendar object produces multiple instances having the same + start date/time, they should be collapsed to, and considered as, + a single instance. + + 5. When a calendar user receives multiple requests for the same + calendar component (e.g., REQUEST for a "VEVENT" calendar + component) as a result of being on multiple mailing lists + specified by "ATTENDEE" properties in the request, they SHOULD + respond to only one of the requests. The calendar user SHOULD + also specify (using the "MEMBER" parameter of the "ATTENDEE" + property) which mailing list they are a member of. + + 6. An implementation can truncate a "SUMMARY" property value to 255 + characters. + + + + + + +Dawson & Stenerson Standards Track [Page 140] +

+RFC 2445                       iCalendar                   November 1998
+
+
+   7.  If seconds of the minute are not supported by an implementation,
+       then a value of "00" SHOULD be specified for the seconds
+       component in a time value.
+
+   8.  If the value type parameter (VALUE=) contains an unknown value
+       type, it SHOULD be treated as TEXT.
+
+   9.  TZURL values SHOULD NOT be specified as a FILE URI type. This URI
+       form can be useful within an organization, but is problematic in
+       the Internet.
+
+   10.  Some possible English values for CATEGORIES property include
+        "ANNIVERSARY", "APPOINTMENT", "BUSINESS", "EDUCATION",
+        "HOLIDAY", "MEETING", "MISCELLANEOUS", "NON-WORKING HOURS", "NOT
+        IN OFFICE", "PERSONAL", "PHONE CALL", "SICK DAY", "SPECIAL
+        OCCASION", "TRAVEL", "VACATION". Categories can be specified in
+        any registered language.
+
+   11.  Some possible English values for RESOURCES property include
+        "CATERING", "CHAIRS", "COMPUTER PROJECTOR", "EASEL", "OVERHEAD
+        PROJECTOR", "SPEAKER PHONE", "TABLE", "TV", "VCR", "VIDEO
+        PHONE", "VEHICLE". Resources can be specified in any registered
+        language.
+
+

7 Registration of Content Type Elements

+ + This section provides the process for registration of MIME + Calendaring and Scheduling Content Type iCalendar object methods and + new or modified properties. + +

7.1 Registration of New and Modified iCalendar Object Methods

+ + New MIME Calendaring and Scheduling Content Type iCalendar object + methods are registered by the publication of an IETF Request for + Comments (RFC). Changes to an iCalendar object method are registered + by the publication of a revision of the RFC defining the method. + +

7.2 Registration of New Properties

+ + This section defines procedures by which new properties or enumerated + property values for the MIME Calendaring and Scheduling Content Type + can be registered with the IANA. Non-IANA properties can be used by + bilateral agreement, provided the associated properties names follow + the "X-" convention. + + The procedures defined here are designed to allow public comment and + review of new properties, while posing only a small impediment to the + definition of new properties. + + + +Dawson & Stenerson Standards Track [Page 141] +

+RFC 2445                       iCalendar                   November 1998
+
+
+   Registration of a new property is accomplished by the following
+   steps.
+
+

7.2.1 Define the property

+ + A property is defined by completing the following template. + + To: ietf-calendar@imc.org + + Subject: Registration of text/calendar MIME property XXX + + Property name: + + Property purpose: + + Property value type(s): + + Property parameter (s): + + Conformance: + + Description: + + Format definition: + + Examples: + + The meaning of each field in the template is as follows. + + Property name: The name of the property, as it will appear in the + body of an text/calendar MIME Content-Type "property: value" line to + the left of the colon ":". + + Property purpose: The purpose of the property (e.g., to indicate a + delegate for the event or to-do, etc.). Give a short but clear + description. + + Property value type (s): Any of the valid value types for the + property value needs to be specified. The default value type also + needs to be specified. If a new value type is specified, it needs to + be declared in this section. + + Property parameter (s): Any of the valid property parameters for the + property needs to be specified. + + Conformance: The calendar components that the property can appear in + needs to be specified. + + + + +Dawson & Stenerson Standards Track [Page 142] +

+RFC 2445                       iCalendar                   November 1998
+
+
+   Description: Any special notes about the property, how it is to be
+   used, etc.
+
+   Format definition: The ABNF for the property definition needs to be
+   specified.
+
+   Examples: One or more examples of instances of the property needs to
+   be specified.
+
+

7.2.2 Post the Property definition

+ + The property description MUST be posted to the new property + discussion list, ietf-calendar@imc.org. + +

7.2.3 Allow a comment period

+ + Discussion on the new property MUST be allowed to take place on the + list for a minimum of two weeks. Consensus MUST be reached on the + property before proceeding to the next step. + +

7.2.4 Submit the property for approval

+ + Once the two-week comment period has elapsed, and the proposer is + convinced consensus has been reached on the property, the + registration application should be submitted to the Method Reviewer + for approval. The Method Reviewer is appointed to the Application + Area Directors and can either accept or reject the property + registration. An accepted registration should be passed on by the + Method Reviewer to the IANA for inclusion in the official IANA method + 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 Method Reviewer's decision to reject a property can be + appealed by the proposer to the IESG, or the objections raised can be + addressed by the proposer and the property resubmitted. + +

7.3 Property Change Control

+ + Existing properties can be changed using the same process by which + they were registered. + + 1. Define the change + + 2. Post the change + + 3. Allow a comment period + + 4. Submit the property for approval + + + +Dawson & Stenerson Standards Track [Page 143] +

+RFC 2445                       iCalendar                   November 1998
+
+
+   Note that the original author or any other interested party can
+   propose a change to an existing property, but that such changes
+   should only be proposed when there are serious omissions or errors in
+   the published memo. The Method Reviewer can object to a change if it
+   is not backward compatible, but is not required to do so.
+
+   Property definitions can never be deleted from the IANA registry, but
+   properties which are no longer believed to be useful can be declared
+   OBSOLETE by a change to their "intended use" field.
+
+

8 References

+ + [IMIP] Dawson, F., Mansour, S. and S. Silverberg, "iCalendar + Message-based Interoperability Protocol (IMIP)", RFC 2447, + November 1998. + + [ITIP] Silverberg, S., Mansour, S., Dawson, F. and R. Hopson, + "iCalendar Transport-Independent Interoperability Protocol + (iTIP) : Scheduling Events, Busy Time, To-dos and Journal + Entries", RFC 2446, November 1998. + + [ISO 8601] ISO 8601, "Data elements and interchange formats- + Information interchange--Representation of dates and + times", International Organization for Standardization, + June, 1988. + + [ISO 9070] ISO/IEC 9070, "Information Technology_SGML Support + Facilities--Registration Procedures for Public Text Owner + Identifiers", Second Edition, International Organization + for Standardization, April 1991. + + [RFC 822] Crocker, D., "Standard for the Format of ARPA Internet + Text Messages", STD 11, RFC 822, August 1982. + + [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. + + [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. + + + + +Dawson & Stenerson Standards Track [Page 144] +

+RFC 2445                       iCalendar                   November 1998
+
+
+   [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.
+
+   [RFC 2279] Yergeau, F., "UTF-8, a transformation format of ISO
+              10646", RFC 2279, January 1998.
+
+   [RFC 2425] Howes, T., Smith, M. and F. Dawson, "A MIME Content-Type
+              for Directory Information", RFC 2425, September 1998.
+
+   [RFC 2426] Dawson, F. and T. Howes, "vCard MIME Directory Profile",
+              RFC 2426, September 1998.
+
+   [TZ]       Olson, A.D., et al, Time zone code and data,
+              ftp://elsie.nci.nih.gov/pub/, updated periodically.
+
+   [VCAL]     Internet Mail Consortium, "vCalendar - The Electronic
+              Calendaring and Scheduling Exchange Format",
+              http://www.imc.org/pdi/vcal-10.txt, September 18, 1996.
+
+

9 Acknowledgments

+ + A hearty thanks to the IETF Calendaring and Scheduling Working Group + and also the following individuals who have participated in the + drafting, review and discussion of this memo: + + Roland Alden, Harald T. Alvestrand, Eric Berman, Denis Bigorgne, John + Binici, Bill Bliss, Philippe Boucher, Steve Carter, Andre + Courtemanche, Dave Crocker, David Curley, Alec Dun, John Evans, Ross + Finlayson, Randell Flint, Ned Freed, Patrik Faltstrom, Chuck + Grandgent, Mark Handley, Steve Hanna, Paul B. Hill, Paul Hoffman, + Ross Hopson, Mark Horton, Daryl Huff, Bruce Kahn, C. Harald Koch, + Ryan Jansen, Don Lavange, Antoine Leca, Theodore Lorek, Steve + Mansour, Skip Montanaro, Keith Moore, Cecil Murray, Chris Newman, + John Noerenberg, Ralph Patterson, Pete Resnick, Keith Rhodes, Robert + Ripberger, John Rose, Doug Royer, Andras Salamar, Ted Schuh, Vinod + Seraphin, Derrick Shadel, Ken Shan, Andrew Shuman, Steve Silverberg, + William P. Spencer, John Sun, Mark Towfiq, Yvonne Tso, Robert Visnov, + James L. Weiner, Mike Weston, William Wyatt. + + + + + + +Dawson & Stenerson Standards Track [Page 145] +

+RFC 2445                       iCalendar                   November 1998
+
+
+

10 Authors' and Chairs' Addresses

+ + The following address information is provided in a MIME-VCARD, + Electronic Business Card, format. + + The authors of this memo are: + + BEGIN:VCARD + VERSION:3.0 + N:Dawson;Frank + FN:Frank Dawson + ORG:Lotus Development Corporation + ADR;TYPE=WORK,POSTAL,PARCEL:;;6544 Battleford Drive; + Raleigh;NC;27613-3502;USA + TEL;TYPE=WORK,MSG:+1-919-676-9515 + TEL;TYPE=WORK,FAX:+1-919-676-9564 + EMAIL;TYPE=PREF,INTERNET:Frank_Dawson@Lotus.com + EMAIL;TYPE=INTERNET:fdawson@earthlink.net + URL:http://home.earthlink.net/~fdawson + END:VCARD + + BEGIN:VCARD + VERSION:3.0 + N:Stenerson;Derik + FN:Derik Stenerson + ORG:Microsoft Corporation + ADR;TYPE=WORK,POSTAL,PARCEL:;;One Microsoft Way; + Redmond;WA;98052-6399;USA + TEL;TYPE=WORK,MSG:+1-425-936-5522 + TEL;TYPE=WORK,FAX:+1-425-936-7329 + EMAIL;TYPE=INTERNET:deriks@Microsoft.com + END:VCARD + + The iCalendar object is a result of the work of the Internet + Engineering Task Force Calendaring and Scheduling Working Group. The + chairmen of that working group are: + + BEGIN:VCARD + VERSION:3.0 + N:Ganguly;Anik + FN:Anik Ganguly + ORG: Open Text Inc. + ADR;TYPE=WORK,POSTAL,PARCEL:;Suite 101;38777 West Six Mile Road; + Livonia;MI;48152;USA + TEL;TYPE=WORK,MSG:+1-734-542-5955 + EMAIL;TYPE=INTERNET:ganguly@acm.org + END:VCARD + + + + +Dawson & Stenerson Standards Track [Page 146] +

+RFC 2445                       iCalendar                   November 1998
+
+
+   The co-chairman of that working group is:
+
+   BEGIN:VCARD
+   VERSION:3.0
+   N:Moskowitz;Robert
+   FN:Robert Moskowitz
+   EMAIL;TYPE=INTERNET:rgm-ietf@htt-consult.com
+   END:VCARD
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Dawson & Stenerson          Standards Track                   [Page 147]
+

+RFC 2445                       iCalendar                   November 1998
+
+
+

11. 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 & Stenerson Standards Track [Page 148] +
+

+Html markup produced by rfcmarkup 1.74, available from +http://tools.ietf.org/tools/rfcmarkup/ + + \ No newline at end of file diff --git a/caldav/rfc4791.html b/caldav/rfc4791.html new file mode 100644 index 0000000..eb59ed8 --- /dev/null +++ b/caldav/rfc4791.html @@ -0,0 +1,6116 @@ + + + + + + + + + + RFC 4791 - Calendaring Extensions to WebDAV (CalDAV) + + + + + +
+
+ +
+[RFCs/IDs] [Plain] [From draft-dusseault-caldav]
+
+ PROPOSED STANDARD
+ Errata
+
Network Working Group                                           C. Daboo
+Request for Comments: 4791                                         Apple
+Category: Standards Track                                B. Desruisseaux
+                                                                  Oracle
+                                                            L. Dusseault
+                                                             CommerceNet
+                                                              March 2007
+
+
+               

Calendaring Extensions to WebDAV (CalDAV)

+ +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 IETF Trust (2007). + +Abstract + + This document defines extensions to the Web Distributed Authoring and + Versioning (WebDAV) protocol to specify a standard way of accessing, + managing, and sharing calendaring and scheduling information based on + the iCalendar format. This document defines the "calendar-access" + feature of CalDAV. + + + + + + + + + + + + + + + + + + + + + +Daboo, et al. Standards Track [Page 1] +

+RFC 4791                         CalDAV                       March 2007
+
+
+Table of Contents
+
+   1.  Introduction . . . . . . . . . . . . . . . . . . . . . . . . .  5
+     1.1.  Notational Conventions . . . . . . . . . . . . . . . . . .  5
+     1.2.  XML Namespaces and Processing  . . . . . . . . . . . . . .  5
+     1.3.  Method Preconditions and Postconditions  . . . . . . . . .  6
+   2.  Requirements Overview  . . . . . . . . . . . . . . . . . . . .  6
+   3.  Calendaring Data Model . . . . . . . . . . . . . . . . . . . .  7
+     3.1.  Calendar Server  . . . . . . . . . . . . . . . . . . . . .  7
+     3.2.  Recurrence and the Data Model  . . . . . . . . . . . . . .  8
+   4.  Calendar Resources . . . . . . . . . . . . . . . . . . . . . .  9
+     4.1.  Calendar Object Resources  . . . . . . . . . . . . . . . .  9
+     4.2.  Calendar Collection  . . . . . . . . . . . . . . . . . . . 10
+   5.  Calendar Access Feature  . . . . . . . . . . . . . . . . . . . 11
+     5.1.  Calendar Access Support  . . . . . . . . . . . . . . . . . 11
+       5.1.1.  Example: Using OPTIONS for the Discovery of
+               Calendar Access Support  . . . . . . . . . . . . . . . 12
+     5.2.  Calendar Collection Properties . . . . . . . . . . . . . . 12
+       5.2.1.  CALDAV:calendar-description Property . . . . . . . . . 12
+       5.2.2.  CALDAV:calendar-timezone Property  . . . . . . . . . . 13
+       5.2.3.  CALDAV:supported-calendar-component-set Property . . . 14
+       5.2.4.  CALDAV:supported-calendar-data Property  . . . . . . . 15
+       5.2.5.  CALDAV:max-resource-size Property  . . . . . . . . . . 16
+       5.2.6.  CALDAV:min-date-time Property  . . . . . . . . . . . . 17
+       5.2.7.  CALDAV:max-date-time Property  . . . . . . . . . . . . 18
+       5.2.8.  CALDAV:max-instances Property  . . . . . . . . . . . . 19
+       5.2.9.  CALDAV:max-attendees-per-instance Property . . . . . . 19
+       5.2.10. Additional Precondition for PROPPATCH  . . . . . . . . 20
+     5.3.  Creating Resources . . . . . . . . . . . . . . . . . . . . 20
+       5.3.1.  MKCALENDAR Method  . . . . . . . . . . . . . . . . . . 20
+         5.3.1.1.  Status Codes . . . . . . . . . . . . . . . . . . . 22
+         5.3.1.2.  Example: Successful MKCALENDAR Request . . . . . . 23
+       5.3.2.  Creating Calendar Object Resources . . . . . . . . . . 25
+         5.3.2.1.  Additional Preconditions for PUT, COPY, and
+                   MOVE . . . . . . . . . . . . . . . . . . . . . . . 26
+       5.3.3.  Non-Standard Components, Properties, and Parameters  . 28
+       5.3.4.  Calendar Object Resource Entity Tag  . . . . . . . . . 28
+   6.  Calendaring Access Control . . . . . . . . . . . . . . . . . . 29
+     6.1.  Calendaring Privilege  . . . . . . . . . . . . . . . . . . 29
+       6.1.1.  CALDAV:read-free-busy Privilege  . . . . . . . . . . . 29
+     6.2.  Additional Principal Property  . . . . . . . . . . . . . . 30
+       6.2.1.  CALDAV:calendar-home-set Property  . . . . . . . . . . 30
+   7.  Calendaring Reports  . . . . . . . . . . . . . . . . . . . . . 31
+     7.1.  REPORT Method  . . . . . . . . . . . . . . . . . . . . . . 31
+     7.2.  Ordinary Collections . . . . . . . . . . . . . . . . . . . 31
+     7.3.  Date and Floating Time . . . . . . . . . . . . . . . . . . 32
+     7.4.  Time Range Filtering . . . . . . . . . . . . . . . . . . . 32
+     7.5.  Searching Text: Collations . . . . . . . . . . . . . . . . 33
+
+
+
+Daboo, et al.               Standards Track                     [Page 2]
+

+RFC 4791                         CalDAV                       March 2007
+
+
+       7.5.1.  CALDAV:supported-collation-set Property  . . . . . . . 34
+     7.6.  Partial Retrieval  . . . . . . . . . . . . . . . . . . . . 34
+     7.7.  Non-Standard Components, Properties, and Parameters  . . . 35
+     7.8.  CALDAV:calendar-query REPORT . . . . . . . . . . . . . . . 36
+       7.8.1.  Example: Partial Retrieval of Events by Time Range . . 38
+       7.8.2.  Example: Partial Retrieval of Recurring Events . . . . 42
+       7.8.3.  Example: Expanded Retrieval of Recurring Events  . . . 45
+       7.8.4.  Example: Partial Retrieval of Stored Free Busy
+               Components . . . . . . . . . . . . . . . . . . . . . . 48
+       7.8.5.  Example: Retrieval of To-Dos by Alarm Time Range . . . 50
+       7.8.6.  Example: Retrieval of Event by UID . . . . . . . . . . 51
+       7.8.7.  Example: Retrieval of Events by PARTSTAT . . . . . . . 53
+       7.8.8.  Example: Retrieval of Events Only  . . . . . . . . . . 55
+       7.8.9.  Example: Retrieval of All Pending To-Dos . . . . . . . 59
+       7.8.10. Example: Attempt to Query Unsupported Property . . . . 62
+     7.9.  CALDAV:calendar-multiget REPORT  . . . . . . . . . . . . . 63
+       7.9.1.  Example: Successful CALDAV:calendar-multiget REPORT  . 64
+     7.10. CALDAV:free-busy-query REPORT  . . . . . . . . . . . . . . 66
+       7.10.1. Example: Successful CALDAV:free-busy-query REPORT  . . 68
+   8.  Guidelines . . . . . . . . . . . . . . . . . . . . . . . . . . 69
+     8.1.  Client-to-Client Interoperability  . . . . . . . . . . . . 69
+     8.2.  Synchronization Operations . . . . . . . . . . . . . . . . 69
+       8.2.1.  Use of Reports . . . . . . . . . . . . . . . . . . . . 69
+         8.2.1.1.  Restrict the Time Range  . . . . . . . . . . . . . 69
+         8.2.1.2.  Synchronize by Time Range  . . . . . . . . . . . . 70
+         8.2.1.3.  Synchronization Process  . . . . . . . . . . . . . 70
+       8.2.2.  Restrict the Properties Returned . . . . . . . . . . . 72
+     8.3.  Use of Locking . . . . . . . . . . . . . . . . . . . . . . 72
+     8.4.  Finding Calendars  . . . . . . . . . . . . . . . . . . . . 72
+     8.5.  Storing and Using Attachments  . . . . . . . . . . . . . . 74
+       8.5.1.  Inline Attachments . . . . . . . . . . . . . . . . . . 74
+       8.5.2.  External Attachments . . . . . . . . . . . . . . . . . 75
+     8.6.  Storing and Using Alarms . . . . . . . . . . . . . . . . . 76
+   9.  XML Element Definitions  . . . . . . . . . . . . . . . . . . . 77
+     9.1.  CALDAV:calendar XML Element  . . . . . . . . . . . . . . . 77
+     9.2.  CALDAV:mkcalendar XML Element  . . . . . . . . . . . . . . 77
+     9.3.  CALDAV:mkcalendar-response XML Element . . . . . . . . . . 78
+     9.4.  CALDAV:supported-collation XML Element . . . . . . . . . . 78
+     9.5.  CALDAV:calendar-query XML Element  . . . . . . . . . . . . 78
+     9.6.  CALDAV:calendar-data XML Element . . . . . . . . . . . . . 79
+       9.6.1.  CALDAV:comp XML Element  . . . . . . . . . . . . . . . 80
+       9.6.2.  CALDAV:allcomp XML Element . . . . . . . . . . . . . . 81
+       9.6.3.  CALDAV:allprop XML Element . . . . . . . . . . . . . . 81
+       9.6.4.  CALDAV:prop XML Element  . . . . . . . . . . . . . . . 82
+       9.6.5.  CALDAV:expand XML Element  . . . . . . . . . . . . . . 82
+       9.6.6.  CALDAV:limit-recurrence-set XML Element  . . . . . . . 83
+       9.6.7.  CALDAV:limit-freebusy-set XML Element  . . . . . . . . 84
+     9.7.  CALDAV:filter XML Element  . . . . . . . . . . . . . . . . 85
+
+
+
+Daboo, et al.               Standards Track                     [Page 3]
+

+RFC 4791                         CalDAV                       March 2007
+
+
+       9.7.1.  CALDAV:comp-filter XML Element . . . . . . . . . . . . 85
+       9.7.2.  CALDAV:prop-filter XML Element . . . . . . . . . . . . 86
+       9.7.3.  CALDAV:param-filter XML Element  . . . . . . . . . . . 87
+       9.7.4.  CALDAV:is-not-defined XML Element  . . . . . . . . . . 88
+       9.7.5.  CALDAV:text-match XML Element  . . . . . . . . . . . . 88
+     9.8.  CALDAV:timezone XML Element  . . . . . . . . . . . . . . . 89
+     9.9.  CALDAV:time-range XML Element  . . . . . . . . . . . . . . 90
+     9.10. CALDAV:calendar-multiget XML Element . . . . . . . . . . . 94
+     9.11. CALDAV:free-busy-query XML Element . . . . . . . . . . . . 95
+   10. Internationalization Considerations  . . . . . . . . . . . . . 95
+   11. Security Considerations  . . . . . . . . . . . . . . . . . . . 95
+   12. IANA Considerations  . . . . . . . . . . . . . . . . . . . . . 96
+     12.1. Namespace Registration . . . . . . . . . . . . . . . . . . 96
+   13. Acknowledgements . . . . . . . . . . . . . . . . . . . . . . . 96
+   14. References . . . . . . . . . . . . . . . . . . . . . . . . . . 97
+     14.1. Normative References . . . . . . . . . . . . . . . . . . . 97
+     14.2. Informative References . . . . . . . . . . . . . . . . . . 98
+   Appendix A.  CalDAV Method Privilege Table (Normative) . . . . . . 99
+   Appendix B.  Calendar Collections Used in the Examples . . . . . . 99
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Daboo, et al.               Standards Track                     [Page 4]
+

+RFC 4791                         CalDAV                       March 2007
+
+
+

1. Introduction

+ + The concept of using HTTP [RFC2616] and WebDAV [RFC2518] as a basis + for a calendar access protocol is by no means a new concept: it was + discussed in the IETF CALSCH working group as early as 1997 or 1998. + Several companies have implemented calendar access protocols using + HTTP to upload and download iCalendar [RFC2445] objects, and using + WebDAV to get listings of resources. However, those implementations + do not interoperate because there are many small and big decisions to + be made in how to model calendaring data as WebDAV resources, as well + as how to implement required features that aren't already part of + WebDAV. This document proposes a way to model calendar data in + WebDAV, with additional features to make an interoperable calendar + access protocol. + +

1.1. Notational Conventions

+ + 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 [RFC2119]. + + The term "protected" is used in the Conformance field of property + definitions as defined in Section 1.4.2 of [RFC3253]. + + When XML element types in the namespaces "DAV:" and + "urn:ietf:params:xml:ns:caldav" are referenced in this document + outside of the context of an XML fragment, the string "DAV:" and + "CALDAV:" will be prefixed to the element type names, respectively. + +

1.2. XML Namespaces and Processing

+ + Definitions of XML elements in this document use XML element type + declarations (as found in XML Document Type Declarations), described + in Section 3.2 of [W3C.REC-xml-20060816]. + + The namespace "urn:ietf:params:xml:ns:caldav" is reserved for the XML + elements defined in this specification, its revisions, and related + CalDAV specifications. XML elements defined by individual + implementations MUST NOT use the "urn:ietf:params:xml:ns:caldav" + namespace, and instead should use a namespace that they control. + + The XML declarations used in this document do not include namespace + information. Thus, implementers must not use these declarations as + the only way to create valid CalDAV properties or to validate CalDAV + XML element types. Some of the declarations refer to XML elements + defined by WebDAV [RFC2518], which use the "DAV:" namespace. + Wherever such XML elements appear, they are explicitly prefixed with + "DAV:" to avoid confusion. + + + +Daboo, et al. Standards Track [Page 5] +

+RFC 4791                         CalDAV                       March 2007
+
+
+   Also note that some CalDAV XML element names are identical to WebDAV
+   XML element names, though their namespace differs.  Care must be
+   taken not to confuse the two sets of names.
+
+   Processing of XML by CalDAV clients and servers MUST follow the rules
+   described in [RFC2518]; in particular, Section 14, and Appendix 3 of
+   that specification.
+
+

1.3. Method Preconditions and Postconditions

+ + A "precondition" of a method describes the state of the server that + must be true for that method to be performed. A "postcondition" of a + method describes the state of the server that must be true after that + method has been completed. If a method precondition or postcondition + for a request is not satisfied, the response status of the request + MUST either be 403 (Forbidden), if the request should not be repeated + because it will always fail, or 409 (Conflict), if it is expected + that the user might be able to resolve the conflict and resubmit the + request. + + In order to allow better client handling of 403 and 409 responses, a + distinct XML element type is associated with each method precondition + and postcondition of a request. When a particular precondition is + not satisfied or a particular postcondition cannot be achieved, the + appropriate XML element MUST be returned as the child of a top-level + DAV:error element in the response body, unless otherwise negotiated + by the request. + +

2. Requirements Overview

+ + This section lists what functionality is required of a CalDAV server. + To advertise support for CalDAV, a server: + + o MUST support iCalendar [RFC2445] as a media type for the calendar + object resource format; + + o MUST support WebDAV Class 1 [RFC2518] (note that [rfc2518bis] + describes clarifications to [RFC2518] that aid interoperability); + + o MUST support WebDAV ACL [RFC3744] with the additional privilege + defined in Section 6.1 of this document; + + o MUST support transport over TLS [RFC2246] as defined in [RFC2818] + (note that [RFC2246] has been obsoleted by [RFC4346]); + + o MUST support ETags [RFC2616] with additional requirements + specified in Section 5.3.4 of this document; + + + + +Daboo, et al. Standards Track [Page 6] +

+RFC 4791                         CalDAV                       March 2007
+
+
+   o  MUST support all calendaring reports defined in Section 7 of this
+      document; and
+
+   o  MUST advertise support on all calendar collections and calendar
+      object resources for the calendaring reports in the DAV:supported-
+      report-set property, as defined in Versioning Extensions to WebDAV
+      [RFC3253].
+
+   In addition, a server:
+
+   o  SHOULD support the MKCALENDAR method defined in Section 5.3.1 of
+      this document.
+
+

3. Calendaring Data Model

+ + One of the features that has made WebDAV a successful protocol is its + firm data model. This makes it a useful framework for other + applications such as calendaring. This specification follows the + same pattern by developing all features based on a well-described + data model. + + As a brief overview, a CalDAV calendar is modeled as a WebDAV + collection with a defined structure; each calendar collection + contains a number of resources representing calendar objects as its + direct child resource. Each resource representing a calendar object + (event, to-do, journal entry, or other calendar components) is called + a "calendar object resource". Each calendar object resource and each + calendar collection can be individually locked and have individual + WebDAV properties. Requirements derived from this model are provided + in Section 4.1 and Section 4.2. + +

3.1. Calendar Server

+ + A CalDAV server is a calendaring-aware engine combined with a WebDAV + repository. A WebDAV repository is a set of WebDAV collections, + containing other WebDAV resources, within a unified URL namespace. + For example, the repository "http://www.example.com/webdav/" may + contain WebDAV collections and resources, all of which have URLs + beginning with "http://www.example.com/webdav/". Note that the root + URL, "http://www.example.com/", may not itself be a WebDAV repository + (for example, if the WebDAV support is implemented through a servlet + or other Web server extension). + + A WebDAV repository MAY include calendar data in some parts of its + URL namespace, and non-calendaring data in other parts. + + A WebDAV repository can advertise itself as a CalDAV server if it + supports the functionality defined in this specification at any point + + + +Daboo, et al. Standards Track [Page 7] +

+RFC 4791                         CalDAV                       March 2007
+
+
+   within the root of the repository.  That might mean that calendaring
+   data is spread throughout the repository and mixed with non-calendar
+   data in nearby collections (e.g., calendar data may be found in
+   /home/lisa/calendars/ as well as in /home/bernard/calendars/, and
+   non-calendar data in /home/lisa/contacts/).  Or, it might mean that
+   calendar data can be found only in certain sections of the repository
+   (e.g., /calendar/).  Calendaring features are only required in the
+   repository sections that are or contain calendar object resources.
+   Therefore, a repository confining calendar data to the /calendar/
+   collection would only need to support the CalDAV required features
+   within that collection.
+
+   The CalDAV server or repository is the canonical location for
+   calendar data and state information.  Clients may submit requests to
+   change data or download data.  Clients may store calendar objects
+   offline and attempt to synchronize at a later time.  However, clients
+   MUST be prepared for calendar data on the server to change between
+   the time of last synchronization and when attempting an update, as
+   calendar collections may be shared and accessible via multiple
+   clients.  Entity tags and other features make this possible.
+
+

3.2. Recurrence and the Data Model

+ + Recurrence is an important part of the data model because it governs + how many resources are expected to exist. This specification models + a recurring calendar component and its recurrence exceptions as a + single resource. In this model, recurrence rules, recurrence dates, + exception rules, and exception dates are all part of the data in a + single calendar object resource. This model avoids problems of + limiting how many recurrence instances to store in the repository, + how to keep recurrence instances in sync with the recurring calendar + component, and how to link recurrence exceptions with the recurring + calendar component. It also results in less data to synchronize + between client and server, and makes it easier to make changes to all + recurrence instances or to a recurrence rule. It makes it easier to + create a recurring calendar component and to delete all recurrence + instances. + + Clients are not forced to retrieve information about all recurrence + instances of a recurring component. The CALDAV:calendar-query and + CALDAV:calendar-multiget reports defined in this document allow + clients to retrieve only recurrence instances that overlap a given + time range. + + + + + + + + +Daboo, et al. Standards Track [Page 8] +

+RFC 4791                         CalDAV                       March 2007
+
+
+

4. Calendar Resources

+ +

4.1. Calendar Object Resources

+ + Calendar object resources contained in calendar collections MUST NOT + contain more than one type of calendar component (e.g., VEVENT, + VTODO, VJOURNAL, VFREEBUSY, etc.) with the exception of VTIMEZONE + components, which MUST be specified for each unique TZID parameter + value specified in the iCalendar object. For instance, a calendar + object resource can contain one VEVENT component and one VTIMEZONE + component, but it cannot contain one VEVENT component and one VTODO + component. Instead, the VEVENT and VTODO components would have to be + stored in separate calendar object resources in the same collection. + + Calendar object resources contained in calendar collections MUST NOT + specify the iCalendar METHOD property. + + The UID property value of the calendar components contained in a + calendar object resource MUST be unique in the scope of the calendar + collection in which they are stored. + + Calendar components in a calendar collection that have different UID + property values MUST be stored in separate calendar object resources. + + Calendar components with the same UID property value, in a given + calendar collection, MUST be contained in the same calendar object + resource. This ensures that all components in a recurrence "set" are + contained in the same calendar object resource. It is possible for a + calendar object resource to just contain components that represent + "overridden" instances (ones that modify the behavior of a regular + instance, and thus include a RECURRENCE-ID property) without also + including the "master" recurring component (the one that defines the + recurrence "set" and does not contain any RECURRENCE-ID property). + + + + + + + + + + + + + + + + + + +Daboo, et al. Standards Track [Page 9] +

+RFC 4791                         CalDAV                       March 2007
+
+
+   For example, given the following iCalendar object:
+
+   BEGIN:VCALENDAR
+   PRODID:-//Example Corp.//CalDAV Client//EN
+   VERSION:2.0
+   BEGIN:VEVENT
+   UID:1@example.com
+   SUMMARY:One-off Meeting
+   DTSTAMP:20041210T183904Z
+   DTSTART:20041207T120000Z
+   DTEND:20041207T130000Z
+   END:VEVENT
+   BEGIN:VEVENT
+   UID:2@example.com
+   SUMMARY:Weekly Meeting
+   DTSTAMP:20041210T183838Z
+   DTSTART:20041206T120000Z
+   DTEND:20041206T130000Z
+   RRULE:FREQ=WEEKLY
+   END:VEVENT
+   BEGIN:VEVENT
+   UID:2@example.com
+   SUMMARY:Weekly Meeting
+   RECURRENCE-ID:20041213T120000Z
+   DTSTAMP:20041210T183838Z
+   DTSTART:20041213T130000Z
+   DTEND:20041213T140000Z
+   END:VEVENT
+   END:VCALENDAR
+
+   The VEVENT component with the UID value "1@example.com" would be
+   stored in its own calendar object resource.  The two VEVENT
+   components with the UID value "2@example.com", which represent a
+   recurring event where one recurrence instance has been overridden,
+   would be stored in the same calendar object resource.
+
+

4.2. Calendar Collection

+ + A calendar collection contains calendar object resources that + represent calendar components within a calendar. A calendar + collection is manifested to clients as a WebDAV resource collection + identified by a URL. A calendar collection MUST report the DAV: + collection and CALDAV:calendar XML elements in the value of the DAV: + resourcetype property. The element type declaration for CALDAV: + calendar is: + + <!ELEMENT calendar EMPTY> + + + + +Daboo, et al. Standards Track [Page 10] +

+RFC 4791                         CalDAV                       March 2007
+
+
+   A calendar collection can be created through provisioning (i.e.,
+   automatically created when a user's account is provisioned), or it
+   can be created with the MKCALENDAR method (see Section 5.3.1).  This
+   method can be useful for a user to create additional calendars (e.g.,
+   soccer schedule) or for users to share a calendar (e.g., team events
+   or conference rooms).  However, note that this document doesn't
+   define the purpose of extra calendar collections.  Users must rely on
+   non-standard cues to find out what a calendar collection is for, or
+   use the CALDAV:calendar-description property defined in Section 5.2.1
+   to provide such a cue.
+
+   The following restrictions are applied to the resources within a
+   calendar collection:
+
+   a.  Calendar collections MUST only contain calendar object resources
+       and collections that are not calendar collections, i.e., the only
+       "top-level" non-collection resources allowed in a calendar
+       collection are calendar object resources.  This ensures that
+       calendar clients do not have to deal with non-calendar data in a
+       calendar collection, though they do have to distinguish between
+       calendar object resources and collections when using standard
+       WebDAV techniques to examine the contents of a collection.
+
+   b.  Collections contained in calendar collections MUST NOT contain
+       calendar collections at any depth, i.e., "nesting" of calendar
+       collections within other calendar collections at any depth is not
+       allowed.  This specification does not define how collections
+       contained in a calendar collection are used or how they relate to
+       any calendar object resources contained in the calendar
+       collection.
+
+   Multiple calendar collections MAY be children of the same collection.
+
+

5. Calendar Access Feature

+ +

5.1. Calendar Access Support

+ + A server supporting the features described in this document MUST + include "calendar-access" as a field in the DAV response header from + an OPTIONS request on any resource that supports any calendar + properties, reports, method, or privilege. A value of "calendar- + access" in the DAV response header MUST indicate that the server + supports all MUST level requirements specified in this document. + + + + + + + + +Daboo, et al. Standards Track [Page 11] +

+RFC 4791                         CalDAV                       March 2007
+
+
+

5.1.1. Example: Using OPTIONS for the Discovery of Calendar Access

+ Support + + >> Request << + + OPTIONS /home/bernard/calendars/ HTTP/1.1 + Host: cal.example.com + + >> Response << + + HTTP/1.1 200 OK + Allow: OPTIONS, GET, HEAD, POST, PUT, DELETE, TRACE, COPY, MOVE + Allow: PROPFIND, PROPPATCH, LOCK, UNLOCK, REPORT, ACL + DAV: 1, 2, access-control, calendar-access + Date: Sat, 11 Nov 2006 09:32:12 GMT + Content-Length: 0 + + In this example, the OPTIONS method returns the value "calendar- + access" in the DAV response header to indicate that the collection + "/home/bernard/calendars/" supports the properties, reports, method, + or privilege defined in this specification. + +

5.2. Calendar Collection Properties

+ + This section defines properties for calendar collections. + +

5.2.1. CALDAV:calendar-description Property

+ + Name: calendar-description + + Namespace: urn:ietf:params:xml:ns:caldav + + Purpose: Provides a human-readable description of the calendar + collection. + + Conformance: This property MAY be defined on any calendar + collection. If defined, it MAY be protected and SHOULD NOT be + returned by a PROPFIND DAV:allprop request (as defined in Section + 12.14.1 of [RFC2518]). An xml:lang attribute indicating the human + language of the description SHOULD be set for this property by + clients or through server provisioning. Servers MUST return any + xml:lang attribute if set for the property. + + Description: If present, the property contains a description of the + calendar collection that is suitable for presentation to a user. + If not present, the client should assume no description for the + calendar collection. + + + + +Daboo, et al. Standards Track [Page 12] +

+RFC 4791                         CalDAV                       March 2007
+
+
+   Definition:
+
+         <!ELEMENT calendar-description (#PCDATA)>
+         PCDATA value: string
+
+   Example:
+
+         <C:calendar-description xml:lang="fr-CA"
+            xmlns:C="urn:ietf:params:xml:ns:caldav"
+         >Calendrier de Mathilde Desruisseaux</C:calendar-description>
+
+

5.2.2. CALDAV:calendar-timezone Property

+ + Name: calendar-timezone + + Namespace: urn:ietf:params:xml:ns:caldav + + Purpose: Specifies a time zone on a calendar collection. + + Conformance: This property SHOULD be defined on all calendar + collections. If defined, it SHOULD NOT be returned by a PROPFIND + DAV:allprop request (as defined in Section 12.14.1 of [RFC2518]). + + Description: The CALDAV:calendar-timezone property is used to + specify the time zone the server should rely on to resolve "date" + values and "date with local time" values (i.e., floating time) to + "date with UTC time" values. The server will require this + information to determine if a calendar component scheduled with + "date" values or "date with local time" values overlaps a CALDAV: + time-range specified in a CALDAV:calendar-query REPORT. The + server will also require this information to compute the proper + FREEBUSY time period as "date with UTC time" in the VFREEBUSY + component returned in a response to a CALDAV:free-busy-query + REPORT request that takes into account calendar components + scheduled with "date" values or "date with local time" values. In + the absence of this property, the server MAY rely on the time zone + of their choice. + + Note: The iCalendar data embedded within the CALDAV:calendar- + timezone XML element MUST follow the standard XML character data + encoding rules, including use of &lt;, &gt;, &amp; etc. entity + encoding or the use of a <![CDATA[ ... ]]> construct. In the + later case, the iCalendar data cannot contain the character + sequence "]]>", which is the end delimiter for the CDATA section. + + + + + + + +Daboo, et al. Standards Track [Page 13] +

+RFC 4791                         CalDAV                       March 2007
+
+
+   Definition:
+
+         <!ELEMENT calendar-timezone (#PCDATA)>
+         PCDATA value: an iCalendar object with exactly one VTIMEZONE
+               component.
+
+   Example:
+
+   <C:calendar-timezone
+       xmlns:C="urn:ietf:params:xml:ns:caldav">BEGIN:VCALENDAR
+   PRODID:-//Example Corp.//CalDAV Client//EN
+   VERSION:2.0
+   BEGIN:VTIMEZONE
+   TZID:US-Eastern
+   LAST-MODIFIED:19870101T000000Z
+   BEGIN:STANDARD
+   DTSTART:19671029T020000
+   RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
+   TZOFFSETFROM:-0400
+   TZOFFSETTO:-0500
+   TZNAME:Eastern Standard Time (US &amp; Canada)
+   END:STANDARD
+   BEGIN:DAYLIGHT
+   DTSTART:19870405T020000
+   RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
+   TZOFFSETFROM:-0500
+   TZOFFSETTO:-0400
+   TZNAME:Eastern Daylight Time (US &amp; Canada)
+   END:DAYLIGHT
+   END:VTIMEZONE
+   END:VCALENDAR
+   </C:calendar-timezone>
+
+

5.2.3. CALDAV:supported-calendar-component-set Property

+ + Name: supported-calendar-component-set + + Namespace: urn:ietf:params:xml:ns:caldav + + Purpose: Specifies the calendar component types (e.g., VEVENT, + VTODO, etc.) that calendar object resources can contain in the + calendar collection. + + Conformance: This property MAY be defined on any calendar + collection. If defined, it MUST be protected and SHOULD NOT be + returned by a PROPFIND DAV:allprop request (as defined in Section + 12.14.1 of [RFC2518]). + + + + +Daboo, et al. Standards Track [Page 14] +

+RFC 4791                         CalDAV                       March 2007
+
+
+   Description:  The CALDAV:supported-calendar-component-set property is
+      used to specify restrictions on the calendar component types that
+      calendar object resources may contain in a calendar collection.
+      Any attempt by the client to store calendar object resources with
+      component types not listed in this property, if it exists, MUST
+      result in an error, with the CALDAV:supported-calendar-component
+      precondition (Section 5.3.2.1) being violated.  Since this
+      property is protected, it cannot be changed by clients using a
+      PROPPATCH request.  However, clients can initialize the value of
+      this property when creating a new calendar collection with
+      MKCALENDAR.  The empty-element tag <C:comp name="VTIMEZONE"/> MUST
+      only be specified if support for calendar object resources that
+      only contain VTIMEZONE components is provided or desired.  Support
+      for VTIMEZONE components in calendar object resources that contain
+      VEVENT or VTODO components is always assumed.  In the absence of
+      this property, the server MUST accept all component types, and the
+      client can assume that all component types are accepted.
+
+   Definition:
+
+         <!ELEMENT supported-calendar-component-set (comp+)>
+
+   Example:
+
+         <C:supported-calendar-component-set
+             xmlns:C="urn:ietf:params:xml:ns:caldav">
+           <C:comp name="VEVENT"/>
+           <C:comp name="VTODO"/>
+         </C:supported-calendar-component-set>
+
+

5.2.4. CALDAV:supported-calendar-data Property

+ + Name: supported-calendar-data + + Namespace: urn:ietf:params:xml:ns:caldav + + Purpose: Specifies what media types are allowed for calendar object + resources in a calendar collection. + + Conformance: This property MAY be defined on any calendar + collection. If defined, it MUST be protected and SHOULD NOT be + returned by a PROPFIND DAV:allprop request (as defined in Section + 12.14.1 of [RFC2518]). + + Description: The CALDAV:supported-calendar-data property is used to + specify the media type supported for the calendar object resources + contained in a given calendar collection (e.g., iCalendar version + 2.0). Any attempt by the client to store calendar object + + + +Daboo, et al. Standards Track [Page 15] +

+RFC 4791                         CalDAV                       March 2007
+
+
+      resources with a media type not listed in this property MUST
+      result in an error, with the CALDAV:supported-calendar-data
+      precondition (Section 5.3.2.1) being violated.  In the absence of
+      this property, the server MUST only accept data with the media
+      type "text/calendar" and iCalendar version 2.0, and clients can
+      assume that the server will only accept this data.
+
+   Definition:
+
+         <!ELEMENT supported-calendar-data (calendar-data+)>
+
+   Example:
+
+         <C:supported-calendar-data
+            xmlns:C="urn:ietf:params:xml:ns:caldav">
+           <C:calendar-data content-type="text/calendar" version="2.0"/>
+         </C:supported-calendar-data>
+
+

5.2.5. CALDAV:max-resource-size Property

+ + Name: max-resource-size + + Namespace: urn:ietf:params:xml:ns:caldav + + Purpose: Provides a numeric value indicating the maximum size of a + resource in octets that the server is willing to accept when a + calendar object resource is stored in a calendar collection. + + Conformance: This property MAY be defined on any calendar + collection. If defined, it MUST be protected and SHOULD NOT be + returned by a PROPFIND DAV:allprop request (as defined in Section + 12.14.1 of [RFC2518]). + + Description: The CALDAV:max-resource-size is used to specify a + numeric value that represents the maximum size in octets that the + server is willing to accept when a calendar object resource is + stored in a calendar collection. Any attempt to store a calendar + object resource exceeding this size MUST result in an error, with + the CALDAV:max-resource-size precondition (Section 5.3.2.1) being + violated. In the absence of this property, the client can assume + that the server will allow storing a resource of any reasonable + size. + + Definition: + + <!ELEMENT max-resource-size (#PCDATA)> + PCDATA value: a numeric value (positive integer) + + + + +Daboo, et al. Standards Track [Page 16] +

+RFC 4791                         CalDAV                       March 2007
+
+
+   Example:
+
+         <C:max-resource-size xmlns:C="urn:ietf:params:xml:ns:caldav"
+         >102400</C:max-resource-size>
+
+

5.2.6. CALDAV:min-date-time Property

+ + Name: min-date-time + + Namespace: urn:ietf:params:xml:ns:caldav + + Purpose: Provides a DATE-TIME value indicating the earliest date and + time (in UTC) that the server is willing to accept for any DATE or + DATE-TIME value in a calendar object resource stored in a calendar + collection. + + Conformance: This property MAY be defined on any calendar + collection. If defined, it MUST be protected and SHOULD NOT be + returned by a PROPFIND DAV:allprop request (as defined in Section + 12.14.1 of [RFC2518]). + + Description: The CALDAV:min-date-time is used to specify an + iCalendar DATE-TIME value in UTC that indicates the earliest + inclusive date that the server is willing to accept for any + explicit DATE or DATE-TIME value in a calendar object resource + stored in a calendar collection. Any attempt to store a calendar + object resource using a DATE or DATE-TIME value earlier than this + value MUST result in an error, with the CALDAV:min-date-time + precondition (Section 5.3.2.1) being violated. Note that servers + MUST accept recurring components that specify instances beyond + this limit, provided none of those instances have been overridden. + In that case, the server MAY simply ignore those instances outside + of the acceptable range when processing reports on the calendar + object resource. In the absence of this property, the client can + assume any valid iCalendar date may be used at least up to the + CALDAV:max-date-time value, if that is defined. + + Definition: + + <!ELEMENT min-date-time (#PCDATA)> + PCDATA value: an iCalendar format DATE-TIME value in UTC + + Example: + + <C:min-date-time xmlns:C="urn:ietf:params:xml:ns:caldav" + >19000101T000000Z</C:min-date-time> + + + + + +Daboo, et al. Standards Track [Page 17] +

+RFC 4791                         CalDAV                       March 2007
+
+
+

5.2.7. CALDAV:max-date-time Property

+ + Name: max-date-time + + Namespace: urn:ietf:params:xml:ns:caldav + + Purpose: Provides a DATE-TIME value indicating the latest date and + time (in UTC) that the server is willing to accept for any DATE or + DATE-TIME value in a calendar object resource stored in a calendar + collection. + + Conformance: This property MAY be defined on any calendar + collection. If defined, it MUST be protected and SHOULD NOT be + returned by a PROPFIND DAV:allprop request (as defined in Section + 12.14.1 of [RFC2518]). + + Description: The CALDAV:max-date-time is used to specify an + iCalendar DATE-TIME value in UTC that indicates the inclusive + latest date that the server is willing to accept for any date or + time value in a calendar object resource stored in a calendar + collection. Any attempt to store a calendar object resource using + a DATE or DATE-TIME value later than this value MUST result in an + error, with the CALDAV:max-date-time precondition + (Section 5.3.2.1) being violated. Note that servers MUST accept + recurring components that specify instances beyond this limit, + provided none of those instances have been overridden. In that + case, the server MAY simply ignore those instances outside of the + acceptable range when processing reports on the calendar object + resource. In the absence of this property, the client can assume + any valid iCalendar date may be used at least down to the CALDAV: + min-date-time value, if that is defined. + + Definition: + + <!ELEMENT max-date-time (#PCDATA)> + PCDATA value: an iCalendar format DATE-TIME value in UTC + + Example: + + <C:max-date-time xmlns:C="urn:ietf:params:xml:ns:caldav" + >20491231T235959Z</C:max-date-time> + + + + + + + + + + +Daboo, et al. Standards Track [Page 18] +

+RFC 4791                         CalDAV                       March 2007
+
+
+

5.2.8. CALDAV:max-instances Property

+ + Name: max-instances + + Namespace: urn:ietf:params:xml:ns:caldav + + Purpose: Provides a numeric value indicating the maximum number of + recurrence instances that a calendar object resource stored in a + calendar collection can generate. + + Conformance: This property MAY be defined on any calendar + collection. If defined, it MUST be protected and SHOULD NOT be + returned by a PROPFIND DAV:allprop request (as defined in Section + 12.14.1 of [RFC2518]). + + Description: The CALDAV:max-instances is used to specify a numeric + value that indicates the maximum number of recurrence instances + that a calendar object resource stored in a calendar collection + can generate. Any attempt to store a calendar object resource + with a recurrence pattern that generates more instances than this + value MUST result in an error, with the CALDAV:max-instances + precondition (Section 5.3.2.1) being violated. In the absence of + this property, the client can assume that the server has no limits + on the number of recurrence instances it can handle or expand. + + Definition: + + <!ELEMENT max-instances (#PCDATA)> + PCDATA value: a numeric value (integer greater than zero) + + Example: + + <C:max-instances xmlns:C="urn:ietf:params:xml:ns:caldav" + >100</C:max-instances> + +

5.2.9. CALDAV:max-attendees-per-instance Property

+ + Name: max-attendees-per-instance + + Namespace: urn:ietf:params:xml:ns:caldav + + Purpose: Provides a numeric value indicating the maximum number of + ATTENDEE properties in any instance of a calendar object resource + stored in a calendar collection. + + Conformance: This property MAY be defined on any calendar + collection. If defined, it MUST be protected and SHOULD NOT be + + + + +Daboo, et al. Standards Track [Page 19] +

+RFC 4791                         CalDAV                       March 2007
+
+
+      returned by a PROPFIND DAV:allprop request (as defined in Section
+      12.14.1 of [RFC2518]).
+
+   Description:  The CALDAV:max-attendees-per-instance is used to
+      specify a numeric value that indicates the maximum number of
+      iCalendar ATTENDEE properties on any one instance of a calendar
+      object resource stored in a calendar collection.  Any attempt to
+      store a calendar object resource with more ATTENDEE properties per
+      instance than this value MUST result in an error, with the CALDAV:
+      max-attendees-per-instance precondition (Section 5.3.2.1) being
+      violated.  In the absence of this property, the client can assume
+      that the server can handle any number of ATTENDEE properties in a
+      calendar component.
+
+   Definition:
+
+         <!ELEMENT max-attendees-per-instance (#PCDATA)>
+         PCDATA value: a numeric value (integer greater than zero)
+
+   Example:
+
+         <C:max-attendees-per-instance
+              xmlns:C="urn:ietf:params:xml:ns:caldav"
+         >25</C:max-attendees-per-instance>
+
+

5.2.10. Additional Precondition for PROPPATCH

+ + This specification requires an additional Precondition for the + PROPPATCH method. The precondition is: + + (CALDAV:valid-calendar-data): The time zone specified in CALDAV: + calendar-timezone property MUST be a valid iCalendar object + containing a single valid VTIMEZONE component. + +

5.3. Creating Resources

+ + Calendar collections and calendar object resources may be created by + either a CalDAV client or by the CalDAV server. This specification + defines restrictions and a data model that both clients and servers + MUST adhere to when manipulating such calendar data. + +

5.3.1. MKCALENDAR Method

+ + An HTTP request using the MKCALENDAR method creates a new calendar + collection resource. A server MAY restrict calendar collection + creation to particular collections. + + + + + +Daboo, et al. Standards Track [Page 20] +

+RFC 4791                         CalDAV                       March 2007
+
+
+   Support for MKCALENDAR on the server is only RECOMMENDED and not
+   REQUIRED because some calendar stores only support one calendar per
+   user (or principal), and those are typically pre-created for each
+   account.  However, servers and clients are strongly encouraged to
+   support MKCALENDAR whenever possible to allow users to create
+   multiple calendar collections to help organize their data better.
+
+   Clients SHOULD use the DAV:displayname property for a human-readable
+   name of the calendar.  Clients can either specify the value of the
+   DAV:displayname property in the request body of the MKCALENDAR
+   request, or alternatively issue a PROPPATCH request to change the
+   DAV:displayname property to the appropriate value immediately after
+   issuing the MKCALENDAR request.  Clients SHOULD NOT set the DAV:
+   displayname property to be the same as any other calendar collection
+   at the same URI "level".  When displaying calendar collections to
+   users, clients SHOULD check the DAV:displayname property and use that
+   value as the name of the calendar.  In the event that the DAV:
+   displayname property is empty, the client MAY use the last part of
+   the calendar collection URI as the name; however, that path segment
+   may be "opaque" and not represent any meaningful human-readable text.
+
+   If a MKCALENDAR request fails, the server state preceding the request
+   MUST be restored.
+
+   Marshalling:
+      If a request body is included, it MUST be a CALDAV:mkcalendar XML
+      element.  Instruction processing MUST occur in the order
+      instructions are received (i.e., from top to bottom).
+      Instructions MUST either all be executed or none executed.  Thus,
+      if any error occurs during processing, all executed instructions
+      MUST be undone and a proper error result returned.  Instruction
+      processing details can be found in the definition of the DAV:set
+      instruction in Section 12.13.2 of [RFC2518].
+
+         <!ELEMENT mkcalendar (DAV:set)>
+
+      If a response body for a successful request is included, it MUST
+      be a CALDAV:mkcalendar-response XML element.
+
+         <!ELEMENT mkcalendar-response ANY>
+
+      The response MUST include a Cache-Control:no-cache header.
+
+   Preconditions:
+
+      (DAV:resource-must-be-null): A resource MUST NOT exist at the
+      Request-URI;
+
+
+
+
+Daboo, et al.               Standards Track                    [Page 21]
+

+RFC 4791                         CalDAV                       March 2007
+
+
+      (CALDAV:calendar-collection-location-ok): The Request-URI MUST
+      identify a location where a calendar collection can be created;
+
+      (CALDAV:valid-calendar-data): The time zone specified in the
+      CALDAV:calendar-timezone property MUST be a valid iCalendar object
+      containing a single valid VTIMEZONE component;
+
+      (DAV:needs-privilege): The DAV:bind privilege MUST be granted to
+      the current user on the parent collection of the Request-URI.
+
+   Postconditions:
+
+      (CALDAV:initialize-calendar-collection): A new calendar collection
+      exists at the Request-URI.  The DAV:resourcetype of the calendar
+      collection MUST contain both DAV:collection and CALDAV:calendar
+      XML elements.
+
+
5.3.1.1. Status Codes
+ + The following are examples of response codes one would expect to get + in a response to a MKCALENDAR request. Note that this list is by no + means exhaustive. + + 201 (Created) - The calendar collection resource was created in + its entirety; + + 207 (Multi-Status) - The calendar collection resource was not + created since one or more DAV:set instructions specified in the + request body could not be processed successfully. The following + are examples of response codes one would expect to be used in a + 207 (Multi-Status) response in this situation: + + 403 (Forbidden) - The client, for reasons the server chooses + not to specify, cannot alter one of the properties; + + 409 (Conflict) - The client has provided a value whose + semantics are not appropriate for the property. This includes + trying to set read-only properties; + + 424 (Failed Dependency) - The DAV:set instruction on the + specified resource would have succeeded if it were not for the + failure of another DAV:set instruction specified in the request + body; + + 423 (Locked) - The specified resource is locked and the client + either is not a lock owner or the lock type requires a lock + token to be submitted and the client did not submit it; and + + + + +Daboo, et al. Standards Track [Page 22] +

+RFC 4791                         CalDAV                       March 2007
+
+
+         507 (Insufficient Storage) - The server did not have sufficient
+         space to record the property;
+
+      403 (Forbidden) - This indicates at least one of two conditions:
+      1) the server does not allow the creation of calendar collections
+      at the given location in its namespace, or 2) the parent
+      collection of the Request-URI exists but cannot accept members;
+
+      409 (Conflict) - A collection cannot be made at the Request-URI
+      until one or more intermediate collections have been created;
+
+      415 (Unsupported Media Type) - The server does not support the
+      request type of the body; and
+
+      507 (Insufficient Storage) - The resource does not have sufficient
+      space to record the state of the resource after the execution of
+      this method.
+
+
5.3.1.2. Example: Successful MKCALENDAR Request
+ + This example creates a calendar collection called /home/lisa/ + calendars/events/ on the server cal.example.com with specific values + for the properties DAV:displayname, CALDAV:calendar-description, + CALDAV:supported-calendar-component-set, and CALDAV:calendar- + timezone. + + + + + + + + + + + + + + + + + + + + + + + + + + +Daboo, et al. Standards Track [Page 23] +

+RFC 4791                         CalDAV                       March 2007
+
+
+   >> Request <<
+
+   MKCALENDAR /home/lisa/calendars/events/ HTTP/1.1
+   Host: cal.example.com
+   Content-Type: application/xml; charset="utf-8"
+   Content-Length: xxxx
+
+   <?xml version="1.0" encoding="utf-8" ?>
+   <C:mkcalendar xmlns:D="DAV:"
+                 xmlns:C="urn:ietf:params:xml:ns:caldav">
+     <D:set>
+       <D:prop>
+         <D:displayname>Lisa's Events</D:displayname>
+         <C:calendar-description xml:lang="en"
+   >Calendar restricted to events.</C:calendar-description>
+         <C:supported-calendar-component-set>
+           <C:comp name="VEVENT"/>
+         </C:supported-calendar-component-set>
+         <C:calendar-timezone><![CDATA[BEGIN:VCALENDAR
+   PRODID:-//Example Corp.//CalDAV Client//EN
+   VERSION:2.0
+   BEGIN:VTIMEZONE
+   TZID:US-Eastern
+   LAST-MODIFIED:19870101T000000Z
+   BEGIN:STANDARD
+   DTSTART:19671029T020000
+   RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
+   TZOFFSETFROM:-0400
+   TZOFFSETTO:-0500
+   TZNAME:Eastern Standard Time (US & Canada)
+   END:STANDARD
+   BEGIN:DAYLIGHT
+   DTSTART:19870405T020000
+   RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
+   TZOFFSETFROM:-0500
+   TZOFFSETTO:-0400
+   TZNAME:Eastern Daylight Time (US & Canada)
+   END:DAYLIGHT
+   END:VTIMEZONE
+   END:VCALENDAR
+   ]]></C:calendar-timezone>
+       </D:prop>
+     </D:set>
+   </C:mkcalendar>
+
+
+
+
+
+
+
+Daboo, et al.               Standards Track                    [Page 24]
+

+RFC 4791                         CalDAV                       March 2007
+
+
+   >> Response <<
+
+   HTTP/1.1 201 Created
+   Cache-Control: no-cache
+   Date: Sat, 11 Nov 2006 09:32:12 GMT
+   Content-Length: 0
+
+

5.3.2. Creating Calendar Object Resources

+ + Clients populate calendar collections with calendar object resources. + The URL for each calendar object resource is entirely arbitrary and + does not need to bear a specific relationship to the calendar object + resource's iCalendar properties or other metadata. New calendar + object resources MUST be created with a PUT request targeted at an + unmapped URI. A PUT request targeted at a mapped URI updates an + existing calendar object resource. + + When servers create new resources, it's not hard for the server to + choose an unmapped URI. It's slightly tougher for clients, because a + client might not want to examine all resources in the collection and + might not want to lock the entire collection to ensure that a new + resource isn't created with a name collision. However, there is an + HTTP feature to mitigate this. If the client intends to create a new + non-collection resource, such as a new VEVENT, the client SHOULD use + the HTTP request header "If-None-Match: *" on the PUT request. The + Request-URI on the PUT request MUST include the target collection, + where the resource is to be created, plus the name of the resource in + the last path segment. The "If-None-Match: *" request header ensures + that the client will not inadvertently overwrite an existing resource + if the last path segment turned out to already be used. + + + + + + + + + + + + + + + + + + + + + +Daboo, et al. Standards Track [Page 25] +

+RFC 4791                         CalDAV                       March 2007
+
+
+   >> Request <<
+
+   PUT /home/lisa/calendars/events/qwue23489.ics HTTP/1.1
+   If-None-Match: *
+   Host: cal.example.com
+   Content-Type: text/calendar
+   Content-Length: xxxx
+
+   BEGIN:VCALENDAR
+   VERSION:2.0
+   PRODID:-//Example Corp.//CalDAV Client//EN
+   BEGIN:VEVENT
+   UID:20010712T182145Z-123401@example.com
+   DTSTAMP:20060712T182145Z
+   DTSTART:20060714T170000Z
+   DTEND:20060715T040000Z
+   SUMMARY:Bastille Day Party
+   END:VEVENT
+   END:VCALENDAR
+
+   >> Response <<
+
+   HTTP/1.1 201 Created
+   Content-Length: 0
+   Date: Sat, 11 Nov 2006 09:32:12 GMT
+   ETag: "123456789-000-111"
+
+   The request to change an existing event is the same, but with a
+   specific ETag in the "If-Match" header, rather than the "If-None-
+   Match" header.
+
+   As indicated in Section 3.10 of [RFC2445], the URL of calendar object
+   resources containing (an arbitrary set of) calendaring and scheduling
+   information may be suffixed by ".ics", and the URL of calendar object
+   resources containing free or busy time information may be suffixed by
+   ".ifb".
+
+
5.3.2.1. Additional Preconditions for PUT, COPY, and MOVE
+ + This specification creates additional Preconditions for PUT, COPY, + and MOVE methods. These preconditions apply when a PUT operation of + a calendar object resource into a calendar collection occurs, or when + a COPY or MOVE operation of a calendar object resource into a + calendar collection occurs, or when a COPY or MOVE operation occurs + on a calendar collection. + + + + + + +Daboo, et al. Standards Track [Page 26] +

+RFC 4791                         CalDAV                       March 2007
+
+
+   The new preconditions are:
+
+      (CALDAV:supported-calendar-data): The resource submitted in the
+      PUT request, or targeted by a COPY or MOVE request, MUST be a
+      supported media type (i.e., iCalendar) for calendar object
+      resources;
+
+      (CALDAV:valid-calendar-data): The resource submitted in the PUT
+      request, or targeted by a COPY or MOVE request, MUST be valid data
+      for the media type being specified (i.e., MUST contain valid
+      iCalendar data);
+
+      (CALDAV:valid-calendar-object-resource): The resource submitted in
+      the PUT request, or targeted by a COPY or MOVE request, MUST obey
+      all restrictions specified in Section 4.1 (e.g., calendar object
+      resources MUST NOT contain more than one type of calendar
+      component, calendar object resources MUST NOT specify the
+      iCalendar METHOD property, etc.);
+
+      (CALDAV:supported-calendar-component): The resource submitted in
+      the PUT request, or targeted by a COPY or MOVE request, MUST
+      contain a type of calendar component that is supported in the
+      targeted calendar collection;
+
+      (CALDAV:no-uid-conflict): The resource submitted in the PUT
+      request, or targeted by a COPY or MOVE request, MUST NOT specify
+      an iCalendar UID property value already in use in the targeted
+      calendar collection or overwrite an existing calendar object
+      resource with one that has a different UID property value.
+      Servers SHOULD report the URL of the resource that is already
+      making use of the same UID property value in the DAV:href element;
+
+                <!ELEMENT no-uid-conflict (DAV:href)>
+
+      (CALDAV:calendar-collection-location-ok): In a COPY or MOVE
+      request, when the Request-URI is a calendar collection, the
+      Destination-URI MUST identify a location where a calendar
+      collection can be created;
+
+      (CALDAV:max-resource-size): The resource submitted in the PUT
+      request, or targeted by a COPY or MOVE request, MUST have an octet
+      size less than or equal to the value of the CALDAV:max-resource-
+      size property value (Section 5.2.5) on the calendar collection
+      where the resource will be stored;
+
+      (CALDAV:min-date-time): The resource submitted in the PUT request,
+      or targeted by a COPY or MOVE request, MUST have all of its
+      iCalendar DATE or DATE-TIME property values (for each recurring
+
+
+
+Daboo, et al.               Standards Track                    [Page 27]
+

+RFC 4791                         CalDAV                       March 2007
+
+
+      instance) greater than or equal to the value of the CALDAV:min-
+      date-time property value (Section 5.2.6) on the calendar
+      collection where the resource will be stored;
+
+      (CALDAV:max-date-time): The resource submitted in the PUT request,
+      or targeted by a COPY or MOVE request, MUST have all of its
+      iCalendar DATE or DATE-TIME property values (for each recurring
+      instance) less than the value of the CALDAV:max-date-time property
+      value (Section 5.2.7) on the calendar collection where the
+      resource will be stored;
+
+      (CALDAV:max-instances): The resource submitted in the PUT request,
+      or targeted by a COPY or MOVE request, MUST generate a number of
+      recurring instances less than or equal to the value of the CALDAV:
+      max-instances property value (Section 5.2.8) on the calendar
+      collection where the resource will be stored;
+
+      (CALDAV:max-attendees-per-instance): The resource submitted in the
+      PUT request, or targeted by a COPY or MOVE request, MUST have a
+      number of ATTENDEE properties on any one instance less than or
+      equal to the value of the CALDAV:max-attendees-per-instance
+      property value (Section 5.2.9) on the calendar collection where
+      the resource will be stored;
+
+

5.3.3. Non-Standard Components, Properties, and Parameters

+ + iCalendar provides a "standard mechanism for doing non-standard + things". This extension support allows implementers to make use of + non-standard components, properties, and parameters whose names are + prefixed with the text "X-". + + Servers MUST support the use of non-standard components, properties, + and parameters in calendar object resources stored via the PUT + method. + + Servers may need to enforce rules for their own "private" components, + properties, or parameters, so servers MAY reject any attempt by the + client to change those or use values for those outside of any + restrictions the server may have. Servers SHOULD ensure that any + "private" components, properties, or parameters it uses follow the + convention of including a vendor id in the "X-" name, as described in + Section 4.2 of [RFC2445], e.g., "X-ABC-PRIVATE". + +

5.3.4. Calendar Object Resource Entity Tag

+ + The DAV:getetag property MUST be defined and set to a strong entity + tag on all calendar object resources. + + + + +Daboo, et al. Standards Track [Page 28] +

+RFC 4791                         CalDAV                       March 2007
+
+
+   A response to a GET request targeted at a calendar object resource
+   MUST contain an ETag response header field indicating the current
+   value of the strong entity tag of the calendar object resource.
+
+   Servers SHOULD return a strong entity tag (ETag header) in a PUT
+   response when the stored calendar object resource is equivalent by
+   octet equality to the calendar object resource submitted in the body
+   of the PUT request.  This allows clients to reliably use the returned
+   strong entity tag for data synchronization purposes.  For instance,
+   the client can do a PROPFIND request on the stored calendar object
+   resource and have the DAV:getetag property returned, and compare that
+   value with the strong entity tag it received on the PUT response, and
+   know that if they are equal, then the calendar object resource on the
+   server has not been changed.
+
+   In the case where the data stored by a server as a result of a PUT
+   request is not equivalent by octet equality to the submitted calendar
+   object resource, the behavior of the ETag response header is not
+   specified here, with the exception that a strong entity tag MUST NOT
+   be returned in the response.  As a result, clients may need to
+   retrieve the modified calendar object resource (and ETag) as a basis
+   for further changes, rather than use the calendar object resource it
+   had sent with the PUT request.
+
+

6. Calendaring Access Control

+ +

6.1. Calendaring Privilege

+ + CalDAV servers MUST support and adhere to the requirements of WebDAV + ACL [RFC3744]. WebDAV ACL provides a framework for an extensible set + of privileges that can be applied to WebDAV collections and ordinary + resources. CalDAV servers MUST also support the calendaring + privilege defined in this section. + +

6.1.1. CALDAV:read-free-busy Privilege

+ + Calendar users often wish to allow other users to see their busy time + information, without viewing the other details of the calendar + components (e.g., location, summary, attendees). This allows a + significant amount of privacy while still allowing other users to + schedule meetings at times when the user is likely to be free. + + The CALDAV:read-free-busy privilege controls which calendar + collections, regular collections, and calendar object resources are + examined when a CALDAV:free-busy-query REPORT request is processed + (see Section 7.10). This privilege can be granted on calendar + collections, regular collections, or calendar object resources. + + + + +Daboo, et al. Standards Track [Page 29] +

+RFC 4791                         CalDAV                       March 2007
+
+
+   Servers MUST support this privilege on all calendar collections,
+   regular collections, and calendar object resources.
+
+
+           <!ELEMENT read-free-busy EMPTY>
+
+   The CALDAV:read-free-busy privilege MUST be aggregated in the DAV:
+   read privilege.  Servers MUST allow the CALDAV:read-free-busy to be
+   granted without the DAV:read privilege being granted.
+
+   Clients should note that when only the CALDAV:read-free-busy
+   privilege has been granted on a resource, access to GET, HEAD,
+   OPTIONS, and PROPFIND on the resource is not implied (those
+   operations are governed by the DAV:read privilege).
+
+

6.2. Additional Principal Property

+ + This section defines an additional property for WebDAV principal + resources, as defined in [RFC3744]. + +

6.2.1. CALDAV:calendar-home-set Property

+ + Name: calendar-home-set + + Namespace: urn:ietf:params:xml:ns:caldav + + Purpose: Identifies the URL of any WebDAV collections that contain + calendar collections owned by the associated principal resource. + + Conformance: This property SHOULD be defined on a principal + resource. If defined, it MAY be protected and SHOULD NOT be + returned by a PROPFIND DAV:allprop request (as defined in Section + 12.14.1 of [RFC2518]). + + Description: The CALDAV:calendar-home-set property is meant to allow + users to easily find the calendar collections owned by the + principal. Typically, users will group all the calendar + collections that they own under a common collection. This + property specifies the URL of collections that are either calendar + collections or ordinary collections that have child or descendant + calendar collections owned by the principal. + + Definition: + + <!ELEMENT calendar-home-set (DAV:href*)> + + + + + + +Daboo, et al. Standards Track [Page 30] +

+RFC 4791                         CalDAV                       March 2007
+
+
+   Example:
+
+       <C:calendar-home-set xmlns:D="DAV:"
+                            xmlns:C="urn:ietf:params:xml:ns:caldav">
+         <D:href>http://cal.example.com/home/bernard/calendars/</D:href>
+       </C:calendar-home-set>
+
+

7. Calendaring Reports

+ + This section defines the reports that CalDAV servers MUST support on + calendar collections and calendar object resources. + + CalDAV servers MUST advertise support for these reports on all + calendar collections and calendar object resources with the DAV: + supported-report-set property, defined in Section 3.1.5 of [RFC3253]. + CalDAV servers MAY also advertise support for these reports on + ordinary collections. + + Some of these reports allow calendar data (from possibly multiple + resources) to be returned. + +

7.1. REPORT Method

+ + The REPORT method (defined in Section 3.6 of [RFC3253]) provides an + extensible mechanism for obtaining information about one or more + resources. Unlike the PROPFIND method, which returns the value of + one or more named properties, the REPORT method can involve more + complex processing. REPORT is valuable in cases where the server has + access to all of the information needed to perform the complex + request (such as a query), and where it would require multiple + requests for the client to retrieve the information needed to perform + the same request. + + CalDAV servers MUST support the DAV:expand-property REPORT defined in + Section 3.8 of [RFC3253]. + +

7.2. Ordinary Collections

+ + Servers MAY support the reports defined in this document on ordinary + collections (collections that are not calendar collections), in + addition to calendar collections or calendar object resources. In + computing responses to the reports on ordinary collections, servers + MUST only consider calendar object resources contained in calendar + collections that are targeted by the REPORT request, based on the + value of the Depth request header. + + + + + + +Daboo, et al. Standards Track [Page 31] +

+RFC 4791                         CalDAV                       March 2007
+
+
+

7.3. Date and Floating Time

+ + iCalendar provides a way to specify DATE and DATE-TIME values that + are not bound to any time zone in particular, hereafter called + "floating date" and "floating time", respectively. These values are + used to represent the same day, hour, minute, and second value, + regardless of which time zone is being observed. For instance, the + DATE value "20051111", represents November 11, 2005 in no specific + time zone, while the DATE-TIME value "20051111T111100" represents + November 11, 2005, at 11:11 A.M. in no specific time zone. + + CalDAV servers may need to convert "floating date" and "floating + time" values in date with UTC time values in the processing of + calendaring REPORT requests. + + For the CALDAV:calendar-query REPORT, CalDAV servers MUST rely on the + value of the CALDAV:timezone XML element, if specified as part of the + request body, to perform the proper conversion of "floating date" and + "floating time" values to date with UTC time values. If the CALDAV: + timezone XML element is not specified in the request body, CalDAV + servers MUST rely on the value of the CALDAV:calendar-timezone + property, if defined, or else the CalDAV servers MAY rely on the time + zone of their choice. + + For the CALDAV:free-busy-query REPORT, CalDAV servers MUST rely on + the value of the CALDAV:calendar-timezone property, if defined, to + compute the proper FREEBUSY time period value as date with UTC time + for calendar components scheduled with "floating date" or "floating + time". If the CALDAV:calendar-timezone property is not defined, + CalDAV servers MAY rely on the time zone of their choice. + +

7.4. Time Range Filtering

+ + Some of the reports defined in this section can include a time range + filter that is used to restrict the set of calendar object resources + returned to just those that overlap the specified time range. The + time range filter can be applied to a calendar component as a whole, + or to specific calendar component properties with DATE or DATE-TIME + value types. + + To determine whether a calendar object resource matches the time + range filter element, the start and end times for the targeted + component or property are determined and then compared to the + requested time range. If there is an overlap with the requested time + range, then the calendar object resource matches the filter element. + The rules defined in [RFC2445] for determining the actual start and + end times of calendar components MUST be used, and these are fully + enumerated in Section 9.9 of this document. + + + +Daboo, et al. Standards Track [Page 32] +

+RFC 4791                         CalDAV                       March 2007
+
+
+   When such time range filtering is used, special consideration must be
+   given to recurring calendar components, such as VEVENT and VTODO.
+   The server MUST expand recurring components to determine whether any
+   recurrence instances overlap the specified time range.  If one or
+   more recurrence instances overlap the time range, then the calendar
+   object resource matches the filter element.
+
+

7.5. Searching Text: Collations

+ + Some of the reports defined in this section do text matches of + character strings provided by the client and are compared to stored + calendar data. Since iCalendar data is, by default, encoded in the + UTF-8 charset and may include characters outside the US-ASCII charset + range in some property and parameter values, there is a need to + ensure that text matching follows well-defined rules. + + To deal with this, this specification makes use of the IANA Collation + Registry defined in [RFC4790] to specify collations that may be used + to carry out the text comparison operations with a well-defined rule. + + The comparisons used in CalDAV are all "substring" matches, as per + [RFC4790], Section 4.2. Collations supported by the server MUST + support "substring" match operations. + + CalDAV servers are REQUIRED to support the "i;ascii-casemap" and + "i;octet" collations, as described in [RFC4790], and MAY support + other collations. + + Servers MUST advertise the set of collations that they support via + the CALDAV:supported-collation-set property defined on any resource + that supports reports that use collations. + + Clients MUST only use collations from the list advertised by the + server. + + In the absence of a collation explicitly specified by the client, or + if the client specifies the "default" collation identifier (as + defined in [RFC4790], Section 3.1), the server MUST default to using + "i;ascii-casemap" as the collation. + + Wildcards (as defined in [RFC4790], Section 3.2) MUST NOT be used in + the collation identifier. + + If the client chooses a collation not supported by the server, the + server MUST respond with a CALDAV:supported-collation precondition + error response. + + + + + +Daboo, et al. Standards Track [Page 33] +

+RFC 4791                         CalDAV                       March 2007
+
+
+

7.5.1. CALDAV:supported-collation-set Property

+ + Name: supported-collation-set + + Namespace: urn:ietf:params:xml:ns:caldav + + Purpose: Identifies the set of collations supported by the server + for text matching operations. + + Conformance: This property MUST be defined on any resource that + supports a report that does text matching. If defined, it MUST be + protected and SHOULD NOT be returned by a PROPFIND DAV:allprop + request (as defined in Section 12.14.1 of [RFC2518]). + + Description: The CALDAV:supported-collation-set property contains + zero or more CALDAV:supported-collation elements, which specify + the collection identifiers of the collations supported by the + server. + + Definition: + + <!ELEMENT supported-collation-set (supported-collation*)> + + <!ELEMENT supported-collation (#PCDATA)> + + Example: + + <C:supported-collation-set + xmlns:C="urn:ietf:params:xml:ns:caldav"> + <C:supported-collation>i;ascii-casemap</C:supported-collation> + <C:supported-collation>i;octet</C:supported-collation> + </C:supported-collation-set> + +

7.6. Partial Retrieval

+ + Some calendaring reports defined in this document allow partial + retrieval of calendar object resources. A CalDAV client can specify + what information to return in the body of a calendaring REPORT + request. + + A CalDAV client can request particular WebDAV property values, all + WebDAV property values, or a list of the names of the resource's + WebDAV properties. A CalDAV client can also request calendar data to + be returned and specify whether all calendar components and + properties should be returned, or only particular ones. See CALDAV: + calendar-data in Section 9.6. + + + + + +Daboo, et al. Standards Track [Page 34] +

+RFC 4791                         CalDAV                       March 2007
+
+
+   By default, the returned calendar data will include the component
+   that defines the recurrence set, referred to as the "master
+   component", as well as the components that define exceptions to the
+   recurrence set, referred to as the "overridden components".
+
+   A CalDAV client that is only interested in the recurrence instances
+   that overlap a specified time range can request to receive only the
+   "master component", along with the "overridden components" that
+   impact the specified time range, and thus, limit the data returned by
+   the server (see CALDAV:limit-recurrence-set in Section 9.6.6).  An
+   overridden component impacts a time range if its current start and
+   end times overlap the time range, or if the original start and end
+   times -- the ones that would have been used if the instance were not
+   overridden -- overlap the time range, or if it affects other
+   instances that overlap the time range.
+
+   A CalDAV client with no support for recurrence properties (i.e.,
+   EXDATE, EXRULE, RDATE, and RRULE) and possibly VTIMEZONE components,
+   or a client unwilling to perform recurrence expansion because of
+   limited processing capability, can request to receive only the
+   recurrence instances that overlap a specified time range as separate
+   calendar components that each define exactly one recurrence instance
+   (see CALDAV:expand in Section 9.6.5.)
+
+   Finally, in the case of VFREEBUSY components, a CalDAV client can
+   request to receive only the FREEBUSY property values that overlap a
+   specified time range (see CALDAV:limit-freebusy-set in
+   Section 9.6.7.)
+
+

7.7. Non-Standard Components, Properties, and Parameters

+ + Servers MUST support the use of non-standard component, property, or + parameter names in the CALDAV:calendar-data XML element in + calendaring REPORT requests to allow clients to request that non- + standard components, properties, and parameters be returned in the + calendar data provided in the response. + + Servers MAY support the use of non-standard component, property, or + parameter names in the CALDAV:comp-filter, CALDAV:prop-filter, and + CALDAV:param-filter XML elements specified in the CALDAV:filter XML + element of calendaring REPORT requests. + + Servers MUST fail with the CALDAV:supported-filter precondition if a + calendaring REPORT request uses a CALDAV:comp-filter, CALDAV:prop- + filter, or CALDAV:param-filter XML element that makes reference to a + non-standard component, property, or parameter name on which the + server does not support queries. + + + + +Daboo, et al. Standards Track [Page 35] +

+RFC 4791                         CalDAV                       March 2007
+
+
+

7.8. CALDAV:calendar-query REPORT

+ + The CALDAV:calendar-query REPORT performs a search for all calendar + object resources that match a specified filter. The response of this + report will contain all the WebDAV properties and calendar object + resource data specified in the request. In the case of the CALDAV: + calendar-data XML element, one can explicitly specify the calendar + components and properties that should be returned in the calendar + object resource data that matches the filter. + + The format of this report is modeled on the PROPFIND method. The + request and response bodies of the CALDAV:calendar-query REPORT use + XML elements that are also used by PROPFIND. In particular, the + request can include XML elements to request WebDAV properties to be + returned. When that occurs, the response should follow the same + behavior as PROPFIND with respect to the DAV:multistatus response + elements used to return specific property results. For instance, a + request to retrieve the value of a property that does not exist is an + error and MUST be noted with a response XML element that contains a + 404 (Not Found) status value. + + Support for the CALDAV:calendar-query REPORT is REQUIRED. + + Marshalling: + + The request body MUST be a CALDAV:calendar-query XML element, as + defined in Section 9.5. + + The request MAY include a Depth header. If no Depth header is + included, Depth:0 is assumed. + + The response body for a successful request MUST be a DAV: + multistatus XML element (i.e., the response uses the same format + as the response for PROPFIND). In the case where there are no + response elements, the returned DAV:multistatus XML element is + empty. + + The response body for a successful CALDAV:calendar-query REPORT + request MUST contain a DAV:response element for each iCalendar + object that matched the search filter. Calendar data is being + returned in the CALDAV:calendar-data XML element inside the DAV: + propstat XML element. + + Preconditions: + + (CALDAV:supported-calendar-data): The attributes "content-type" + and "version" of the CALDAV:calendar-data XML element (see + + + + +Daboo, et al. Standards Track [Page 36] +

+RFC 4791                         CalDAV                       March 2007
+
+
+      Section 9.6) specify a media type supported by the server for
+      calendar object resources.
+
+      (CALDAV:valid-filter): The CALDAV:filter XML element (see
+      Section 9.7) specified in the REPORT request MUST be valid.  For
+      instance, a CALDAV:filter cannot nest a <C:comp name="VEVENT">
+      element in a <C:comp name="VTODO"> element, and a CALDAV:filter
+      cannot nest a <C:time-range start="..." end="..."> element in a
+      <C:prop name="SUMMARY"> element.
+
+      (CALDAV:supported-filter): The CALDAV:comp-filter (see
+      Section 9.7.1), CALDAV:prop-filter (see Section 9.7.2), and
+      CALDAV:param-filter (see Section 9.7.3) XML elements used in the
+      CALDAV:filter XML element (see Section 9.7) in the REPORT request
+      only make reference to components, properties, and parameters for
+      which queries are supported by the server, i.e., if the CALDAV:
+      filter element attempts to reference an unsupported component,
+      property, or parameter, this precondition is violated.  Servers
+      SHOULD report the CALDAV:comp-filter, CALDAV:prop-filter, or
+      CALDAV:param-filter for which it does not provide support.
+
+            <!ELEMENT supported-filter (comp-filter*,
+                                        prop-filter*,
+                                        param-filter*)>
+
+      (CALDAV:valid-calendar-data): The time zone specified in the
+      REPORT request MUST be a valid iCalendar object containing a
+      single valid VTIMEZONE component.
+
+      (CALDAV:min-date-time): Any XML element specifying a range of time
+      MUST have its start or end DATE or DATE-TIME values greater than
+      or equal to the value of the CALDAV:min-date-time property value
+      (Section 5.2.6) on the calendar collections being targeted by the
+      REPORT request;
+
+      (CALDAV:max-date-time): Any XML element specifying a range of time
+      MUST have its start or end DATE or DATE-TIME values less than or
+      equal to the value of the CALDAV:max-date-time property value
+      (Section 5.2.7) on the calendar collections being targeted by the
+      REPORT request;
+
+      (CALDAV:supported-collation): Any XML attribute specifying a
+      collation MUST specify a collation supported by the server as
+      described in Section 7.5.
+
+
+
+
+
+
+
+Daboo, et al.               Standards Track                    [Page 37]
+

+RFC 4791                         CalDAV                       March 2007
+
+
+   Postconditions:
+
+      (DAV:number-of-matches-within-limits): The number of matching
+      calendar object resources must fall within server-specific,
+      predefined limits.  For example, this condition might be triggered
+      if a search specification would cause the return of an extremely
+      large number of responses.
+
+

7.8.1. Example: Partial Retrieval of Events by Time Range

+ + In this example, the client requests the server to return specific + components and properties of the VEVENT components that overlap the + time range from January 4, 2006, at 00:00:00 A.M. UTC to January 5, + 2006, at 00:00:00 A.M. UTC. In addition, the DAV:getetag property is + also requested and returned as part of the response. Note that the + first calendar object returned is a recurring event whose first + instance lies outside the requested time range, but whose third + instance does overlap the time range. Note that due to the CALDAV: + calendar-data element restrictions, the DTSTAMP property in VEVENT + components has not been returned, and the only property returned in + the VCALENDAR object is VERSION. + + See Appendix B for the calendar data being targeted by this example. + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Daboo, et al. Standards Track [Page 38] +

+RFC 4791                         CalDAV                       March 2007
+
+
+   >> Request <<
+
+   REPORT /bernard/work/ HTTP/1.1
+   Host: cal.example.com
+   Depth: 1
+   Content-Type: application/xml; charset="utf-8"
+   Content-Length: xxxx
+
+   <?xml version="1.0" encoding="utf-8" ?>
+   <C:calendar-query xmlns:D="DAV:"
+                 xmlns:C="urn:ietf:params:xml:ns:caldav">
+     <D:prop>
+       <D:getetag/>
+       <C:calendar-data>
+         <C:comp name="VCALENDAR">
+           <C:prop name="VERSION"/>
+           <C:comp name="VEVENT">
+             <C:prop name="SUMMARY"/>
+             <C:prop name="UID"/>
+             <C:prop name="DTSTART"/>
+             <C:prop name="DTEND"/>
+             <C:prop name="DURATION"/>
+             <C:prop name="RRULE"/>
+             <C:prop name="RDATE"/>
+             <C:prop name="EXRULE"/>
+             <C:prop name="EXDATE"/>
+             <C:prop name="RECURRENCE-ID"/>
+           </C:comp>
+           <C:comp name="VTIMEZONE"/>
+         </C:comp>
+       </C:calendar-data>
+     </D:prop>
+     <C:filter>
+       <C:comp-filter name="VCALENDAR">
+         <C:comp-filter name="VEVENT">
+           <C:time-range start="20060104T000000Z"
+                         end="20060105T000000Z"/>
+         </C:comp-filter>
+       </C:comp-filter>
+     </C:filter>
+   </C:calendar-query>
+
+   >> Response <<
+
+   HTTP/1.1 207 Multi-Status
+   Date: Sat, 11 Nov 2006 09:32:12 GMT
+   Content-Type: application/xml; charset="utf-8"
+   Content-Length: xxxx
+
+
+
+Daboo, et al.               Standards Track                    [Page 39]
+

+RFC 4791                         CalDAV                       March 2007
+
+
+   <?xml version="1.0" encoding="utf-8" ?>
+   <D:multistatus xmlns:D="DAV:"
+              xmlns:C="urn:ietf:params:xml:ns:caldav">
+     <D:response>
+       <D:href>http://cal.example.com/bernard/work/abcd2.ics</D:href>
+       <D:propstat>
+         <D:prop>
+           <D:getetag>"fffff-abcd2"</D:getetag>
+           <C:calendar-data>BEGIN:VCALENDAR
+   VERSION:2.0
+   BEGIN:VTIMEZONE
+   LAST-MODIFIED:20040110T032845Z
+   TZID:US/Eastern
+   BEGIN:DAYLIGHT
+   DTSTART:20000404T020000
+   RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
+   TZNAME:EDT
+   TZOFFSETFROM:-0500
+   TZOFFSETTO:-0400
+   END:DAYLIGHT
+   BEGIN:STANDARD
+   DTSTART:20001026T020000
+   RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
+   TZNAME:EST
+   TZOFFSETFROM:-0400
+   TZOFFSETTO:-0500
+   END:STANDARD
+   END:VTIMEZONE
+   BEGIN:VEVENT
+   DTSTART;TZID=US/Eastern:20060102T120000
+   DURATION:PT1H
+   RRULE:FREQ=DAILY;COUNT=5
+   SUMMARY:Event #2
+   UID:00959BC664CA650E933C892C@example.com
+   END:VEVENT
+   BEGIN:VEVENT
+   DTSTART;TZID=US/Eastern:20060104T140000
+   DURATION:PT1H
+   RECURRENCE-ID;TZID=US/Eastern:20060104T120000
+   SUMMARY:Event #2 bis
+   UID:00959BC664CA650E933C892C@example.com
+   END:VEVENT
+   BEGIN:VEVENT
+   DTSTART;TZID=US/Eastern:20060106T140000
+   DURATION:PT1H
+   RECURRENCE-ID;TZID=US/Eastern:20060106T120000
+   SUMMARY:Event #2 bis bis
+   UID:00959BC664CA650E933C892C@example.com
+
+
+
+Daboo, et al.               Standards Track                    [Page 40]
+

+RFC 4791                         CalDAV                       March 2007
+
+
+   END:VEVENT
+   END:VCALENDAR
+   </C:calendar-data>
+         </D:prop>
+         <D:status>HTTP/1.1 200 OK</D:status>
+       </D:propstat>
+     </D:response>
+     <D:response>
+       <D:href>http://cal.example.com/bernard/work/abcd3.ics</D:href>
+       <D:propstat>
+         <D:prop>
+           <D:getetag>"fffff-abcd3"</D:getetag>
+           <C:calendar-data>BEGIN:VCALENDAR
+   VERSION:2.0
+   PRODID:-//Example Corp.//CalDAV Client//EN
+   BEGIN:VTIMEZONE
+   LAST-MODIFIED:20040110T032845Z
+   TZID:US/Eastern
+   BEGIN:DAYLIGHT
+   DTSTART:20000404T020000
+   RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
+   TZNAME:EDT
+   TZOFFSETFROM:-0500
+   TZOFFSETTO:-0400
+   END:DAYLIGHT
+   BEGIN:STANDARD
+   DTSTART:20001026T020000
+   RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
+   TZNAME:EST
+   TZOFFSETFROM:-0400
+   TZOFFSETTO:-0500
+   END:STANDARD
+   END:VTIMEZONE
+   BEGIN:VEVENT
+   DTSTART;TZID=US/Eastern:20060104T100000
+   DURATION:PT1H
+   SUMMARY:Event #3
+   UID:DC6C50A017428C5216A2F1CD@example.com
+   END:VEVENT
+   END:VCALENDAR
+   </C:calendar-data>
+         </D:prop>
+         <D:status>HTTP/1.1 200 OK</D:status>
+       </D:propstat>
+     </D:response>
+   </D:multistatus>
+
+
+
+
+
+Daboo, et al.               Standards Track                    [Page 41]
+

+RFC 4791                         CalDAV                       March 2007
+
+
+

7.8.2. Example: Partial Retrieval of Recurring Events

+ + In this example, the client requests the server to return VEVENT + components that overlap the time range from January 3, 2006, at 00: + 00:00 A.M. UTC to January 5, 2006, at 00:00:00 A.M. UTC. Use of the + CALDAV:limit-recurrence-set element causes the server to only return + overridden recurrence components that overlap the time range + specified in that element or that affect other instances that overlap + the time range (e.g., in the case of a THISANDFUTURE behavior). In + this example, the first overridden component in the matching resource + is returned, but the second one is not. + + See Appendix B for the calendar data being targeted by this example. + + >> Request << + + REPORT /bernard/work/ HTTP/1.1 + Host: cal.example.com + Depth: 1 + Content-Type: application/xml; charset="utf-8" + Content-Length: xxxx + + <?xml version="1.0" encoding="utf-8" ?> + <C:calendar-query xmlns:D="DAV:" + xmlns:C="urn:ietf:params:xml:ns:caldav"> + <D:prop> + <C:calendar-data> + <C:limit-recurrence-set start="20060103T000000Z" + end="20060105T000000Z"/> + </C:calendar-data> + </D:prop> + <C:filter> + <C:comp-filter name="VCALENDAR"> + <C:comp-filter name="VEVENT"> + <C:time-range start="20060103T000000Z" + end="20060105T000000Z"/> + </C:comp-filter> + </C:comp-filter> + </C:filter> + </C:calendar-query> + + >> Response << + + HTTP/1.1 207 Multi-Status + Date: Sat, 11 Nov 2006 09:32:12 GMT + Content-Type: application/xml; charset="utf-8" + Content-Length: xxxx + + + + +Daboo, et al. Standards Track [Page 42] +

+RFC 4791                         CalDAV                       March 2007
+
+
+   <?xml version="1.0" encoding="utf-8" ?>
+   <D:multistatus xmlns:D="DAV:"
+              xmlns:C="urn:ietf:params:xml:ns:caldav">
+     <D:response>
+       <D:href>http://cal.example.com/bernard/work/abcd2.ics</D:href>
+       <D:propstat>
+         <D:prop>
+           <D:getetag>"fffff-abcd2"</D:getetag>
+           <C:calendar-data>BEGIN:VCALENDAR
+   VERSION:2.0
+   PRODID:-//Example Corp.//CalDAV Client//EN
+   BEGIN:VTIMEZONE
+   LAST-MODIFIED:20040110T032845Z
+   TZID:US/Eastern
+   BEGIN:DAYLIGHT
+   DTSTART:20000404T020000
+   RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
+   TZNAME:EDT
+   TZOFFSETFROM:-0500
+   TZOFFSETTO:-0400
+   END:DAYLIGHT
+   BEGIN:STANDARD
+   DTSTART:20001026T020000
+   RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
+   TZNAME:EST
+   TZOFFSETFROM:-0400
+   TZOFFSETTO:-0500
+   END:STANDARD
+   END:VTIMEZONE
+   BEGIN:VEVENT
+   DTSTAMP:20060206T001121Z
+   DTSTART;TZID=US/Eastern:20060102T120000
+   DURATION:PT1H
+   RRULE:FREQ=DAILY;COUNT=5
+   SUMMARY:Event #2
+   UID:00959BC664CA650E933C892C@example.com
+   END:VEVENT
+   BEGIN:VEVENT
+   DTSTAMP:20060206T001121Z
+   DTSTART;TZID=US/Eastern:20060104T140000
+   DURATION:PT1H
+   RECURRENCE-ID;TZID=US/Eastern:20060104T120000
+   SUMMARY:Event #2 bis
+   UID:00959BC664CA650E933C892C@example.com
+   END:VEVENT
+   END:VCALENDAR
+   </C:calendar-data>
+         </D:prop>
+
+
+
+Daboo, et al.               Standards Track                    [Page 43]
+

+RFC 4791                         CalDAV                       March 2007
+
+
+         <D:status>HTTP/1.1 200 OK</D:status>
+       </D:propstat>
+     </D:response>
+     <D:response>
+       <D:href>http://cal.example.com/bernard/work/abcd3.ics</D:href>
+       <D:propstat>
+         <D:prop>
+           <D:getetag>"fffff-abcd3"</D:getetag>
+           <C:calendar-data>BEGIN:VCALENDAR
+   VERSION:2.0
+   PRODID:-//Example Corp.//CalDAV Client//EN
+   BEGIN:VTIMEZONE
+   LAST-MODIFIED:20040110T032845Z
+   TZID:US/Eastern
+   BEGIN:DAYLIGHT
+   DTSTART:20000404T020000
+   RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
+   TZNAME:EDT
+   TZOFFSETFROM:-0500
+   TZOFFSETTO:-0400
+   END:DAYLIGHT
+   BEGIN:STANDARD
+   DTSTART:20001026T020000
+   RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
+   TZNAME:EST
+   TZOFFSETFROM:-0400
+   TZOFFSETTO:-0500
+   END:STANDARD
+   END:VTIMEZONE
+   BEGIN:VEVENT
+   ATTENDEE;PARTSTAT=ACCEPTED;ROLE=CHAIR:mailto:cyrus@example.com
+   ATTENDEE;PARTSTAT=NEEDS-ACTION:mailto:lisa@example.com
+   DTSTAMP:20060206T001220Z
+   DTSTART;TZID=US/Eastern:20060104T100000
+   DURATION:PT1H
+   LAST-MODIFIED:20060206T001330Z
+   ORGANIZER:mailto:cyrus@example.com
+   SEQUENCE:1
+   STATUS:TENTATIVE
+   SUMMARY:Event #3
+   UID:DC6C50A017428C5216A2F1CD@example.com
+   X-ABC-GUID:E1CX5Dr-0007ym-Hz@example.com
+   END:VEVENT
+   END:VCALENDAR
+   </C:calendar-data>
+         </D:prop>
+         <D:status>HTTP/1.1 200 OK</D:status>
+       </D:propstat>
+
+
+
+Daboo, et al.               Standards Track                    [Page 44]
+

+RFC 4791                         CalDAV                       March 2007
+
+
+     </D:response>
+   </D:multistatus>
+
+

7.8.3. Example: Expanded Retrieval of Recurring Events

+ + In this example, the client requests the server to return VEVENT + components that overlap the time range from January 2, 2006, at 00: + 00:00 A.M. UTC to January 5, 2006, at 00:00:00 A.M. UTC and to return + recurring calendar components expanded into individual recurrence + instance calendar components. Use of the CALDAV:expand element + causes the server to only return overridden recurrence instances that + overlap the time range specified in that element. + + See Appendix B for the calendar data being targeted by this example. + + >> Request << + + REPORT /bernard/work/ HTTP/1.1 + Host: cal.example.com + Depth: 1 + Content-Type: application/xml; charset="utf-8" + Content-Length: xxxx + + <?xml version="1.0" encoding="utf-8" ?> + <C:calendar-query xmlns:D="DAV:" + xmlns:C="urn:ietf:params:xml:ns:caldav"> + <D:prop> + <C:calendar-data> + <C:expand start="20060103T000000Z" + end="20060105T000000Z"/> + </C:calendar-data> + </D:prop> + <C:filter> + <C:comp-filter name="VCALENDAR"> + <C:comp-filter name="VEVENT"> + <C:time-range start="20060103T000000Z" + end="20060105T000000Z"/> + </C:comp-filter> + </C:comp-filter> + </C:filter> + </C:calendar-query> + + >> Response << + + HTTP/1.1 207 Multi-Status + Date: Sat, 11 Nov 2006 09:32:12 GMT + Content-Type: application/xml; charset="utf-8" + Content-Length: xxxx + + + +Daboo, et al. Standards Track [Page 45] +

+RFC 4791                         CalDAV                       March 2007
+
+
+   <?xml version="1.0" encoding="utf-8" ?>
+   <D:multistatus xmlns:D="DAV:"
+              xmlns:C="urn:ietf:params:xml:ns:caldav">
+     <D:response>
+       <D:href>http://cal.example.com/bernard/work/abcd2.ics</D:href>
+       <D:propstat>
+         <D:prop>
+           <D:getetag>"fffff-abcd2"</D:getetag>
+           <C:calendar-data>BEGIN:VCALENDAR
+   VERSION:2.0
+   PRODID:-//Example Corp.//CalDAV Client//EN
+   BEGIN:VEVENT
+   DTSTAMP:20060206T001121Z
+   DTSTART:20060103T170000
+   DURATION:PT1H
+   RECURRENCE-ID:20060103T170000
+   SUMMARY:Event #2
+   UID:00959BC664CA650E933C892C@example.com
+   END:VEVENT
+   BEGIN:VEVENT
+   DTSTAMP:20060206T001121Z
+   DTSTART:20060104T190000
+   DURATION:PT1H
+   RECURRENCE-ID:20060104T170000
+   SUMMARY:Event #2 bis
+   UID:00959BC664CA650E933C892C@example.com
+   END:VEVENT
+   END:VCALENDAR
+   </C:calendar-data>
+         </D:prop>
+         <D:status>HTTP/1.1 200 OK</D:status>
+       </D:propstat>
+     </D:response>
+     <D:response>
+       <D:href>http://cal.example.com/bernard/work/abcd3.ics</D:href>
+       <D:propstat>
+         <D:prop>
+           <D:getetag>"fffff-abcd3"</D:getetag>
+           <C:calendar-data>BEGIN:VCALENDAR
+   VERSION:2.0
+   PRODID:-//Example Corp.//CalDAV Client//EN
+   BEGIN:VEVENT
+   ATTENDEE;PARTSTAT=ACCEPTED;ROLE=CHAIR:mailto:cyrus@example.com
+   ATTENDEE;PARTSTAT=NEEDS-ACTION:mailto:lisa@example.com
+   DTSTAMP:20060206T001220Z
+   DTSTART:20060104T150000
+   DURATION:PT1H
+   LAST-MODIFIED:20060206T001330Z
+
+
+
+Daboo, et al.               Standards Track                    [Page 46]
+

+RFC 4791                         CalDAV                       March 2007
+
+
+   ORGANIZER:mailto:cyrus@example.com
+   SEQUENCE:1
+   STATUS:TENTATIVE
+   SUMMARY:Event #3
+   UID:DC6C50A017428C5216A2F1CD@example.com
+   X-ABC-GUID:E1CX5Dr-0007ym-Hz@example.com
+   END:VEVENT
+   END:VCALENDAR
+   </C:calendar-data>
+         </D:prop>
+         <D:status>HTTP/1.1 200 OK</D:status>
+       </D:propstat>
+     </D:response>
+   </D:multistatus>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Daboo, et al.               Standards Track                    [Page 47]
+

+RFC 4791                         CalDAV                       March 2007
+
+
+

7.8.4. Example: Partial Retrieval of Stored Free Busy Components

+ + In this example, the client requests the server to return the + VFREEBUSY components that have free busy information that overlap the + time range from January 2, 2006, at 00:00:00 A.M. UTC (inclusively) + to January 3, 2006, at 00:00:00 A.M. UTC (exclusively). Use of the + CALDAV:limit-freebusy-set element causes the server to only return + the FREEBUSY property values that overlap the time range specified in + that element. Note that this is not an example of discovering when + the calendar owner is busy. + + See Appendix B for the calendar data being targeted by this example. + + >> Request << + + REPORT /bernard/work/ HTTP/1.1 + Host: cal.example.com + Depth: 1 + Content-Type: application/xml; charset="utf-8" + Content-Length: xxxx + + <?xml version="1.0" encoding="utf-8" ?> + <C:calendar-query xmlns:D="DAV:" + xmlns:C="urn:ietf:params:xml:ns:caldav"> + <D:prop> + <C:calendar-data> + <C:limit-freebusy-set start="20060102T000000Z" + end="20060103T000000Z"/> + </C:calendar-data> + </D:prop> + <C:filter> + <C:comp-filter name="VCALENDAR"> + <C:comp-filter name="VFREEBUSY"> + <C:time-range start="20060102T000000Z" + end="20060103T000000Z"/> + </C:comp-filter> + </C:comp-filter> + </C:filter> + </C:calendar-query> + + + + + + + + + + + + +Daboo, et al. Standards Track [Page 48] +

+RFC 4791                         CalDAV                       March 2007
+
+
+   >> Response <<
+
+   HTTP/1.1 207 Multi-Status
+   Date: Sat, 11 Nov 2006 09:32:12 GMT
+   Content-Type: application/xml; charset="utf-8"
+   Content-Length: xxxx
+
+   <?xml version="1.0" encoding="utf-8" ?>
+   <D:multistatus xmlns:D="DAV:"
+                  xmlns:C="urn:ietf:params:xml:ns:caldav">
+     <D:response>
+       <D:href>http://cal.example.com/bernard/work/abcd8.ics</D:href>
+       <D:propstat>
+         <D:prop>
+           <D:getetag>"fffff-abcd8"</D:getetag>
+           <C:calendar-data>BEGIN:VCALENDAR
+   VERSION:2.0
+   PRODID:-//Example Corp.//CalDAV Client//EN
+   BEGIN:VFREEBUSY
+   ORGANIZER;CN="Bernard Desruisseaux":mailto:bernard@example.com
+   UID:76ef34-54a3d2@example.com
+   DTSTAMP:20050530T123421Z
+   DTSTART:20060101T100000Z
+   DTEND:20060108T100000Z
+   FREEBUSY;FBTYPE=BUSY-TENTATIVE:20060102T100000Z/20060102T120000Z
+   END:VFREEBUSY
+   END:VCALENDAR
+   </C:calendar-data>
+         </D:prop>
+         <D:status>HTTP/1.1 200 OK</D:status>
+       </D:propstat>
+     </D:response>
+   </D:multistatus>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Daboo, et al.               Standards Track                    [Page 49]
+

+RFC 4791                         CalDAV                       March 2007
+
+
+

7.8.5. Example: Retrieval of To-Dos by Alarm Time Range

+ + In this example, the client requests the server to return the VTODO + components that have an alarm trigger scheduled in the specified time + range. + + See Appendix B for the calendar data being targeted by this example. + + >> Request << + + REPORT /bernard/work/ HTTP/1.1 + Host: cal.example.com + Depth: 1 + Content-Type: application/xml; charset="utf-8" + Content-Length: xxxx + + <?xml version="1.0" encoding="utf-8" ?> + <C:calendar-query xmlns:C="urn:ietf:params:xml:ns:caldav"> + <D:prop xmlns:D="DAV:"> + <D:getetag/> + <C:calendar-data/> + </D:prop> + <C:filter> + <C:comp-filter name="VCALENDAR"> + <C:comp-filter name="VTODO"> + <C:comp-filter name="VALARM"> + <C:time-range start="20060106T100000Z" + end="20060107T100000Z"/> + </C:comp-filter> + </C:comp-filter> + </C:comp-filter> + </C:filter> + </C:calendar-query> + + + + + + + + + + + + + + + + + + +Daboo, et al. Standards Track [Page 50] +

+RFC 4791                         CalDAV                       March 2007
+
+
+   >> Response <<
+
+   HTTP/1.1 207 Multi-Status
+   Date: Sat, 11 Nov 2006 09:32:12 GMT
+   Content-Type: application/xml; charset="utf-8"
+   Content-Length: xxxx
+
+   <?xml version="1.0" encoding="utf-8" ?>
+   <D:multistatus xmlns:D="DAV:"
+                  xmlns:C="urn:ietf:params:xml:ns:caldav">
+     <D:response>
+       <D:href>http://cal.example.com/bernard/work/abcd4.ics</D:href>
+       <D:propstat>
+         <D:prop>
+           <D:getetag>"fffff-abcd4"</D:getetag>
+           <C:calendar-data>BEGIN:VCALENDAR
+   VERSION:2.0
+   PRODID:-//Example Corp.//CalDAV Client//EN
+   BEGIN:VTODO
+   DTSTAMP:20060205T235300Z
+   DUE;TZID=US/Eastern:20060106T120000
+   LAST-MODIFIED:20060205T235308Z
+   SEQUENCE:1
+   STATUS:NEEDS-ACTION
+   SUMMARY:Task #2
+   UID:E10BA47467C5C69BB74E8720@example.com
+   BEGIN:VALARM
+   ACTION:AUDIO
+   TRIGGER;RELATED=START:-PT10M
+   END:VALARM
+   END:VTODO
+   END:VCALENDAR
+   </C:calendar-data>
+         </D:prop>
+         <D:status>HTTP/1.1 200 OK</D:status>
+       </D:propstat>
+     </D:response>
+   </D:multistatus>
+
+

7.8.6. Example: Retrieval of Event by UID

+ + In this example, the client requests the server to return the VEVENT + component that has the UID property set to + "DC6C50A017428C5216A2F1CD@example.com". + + See Appendix B for the calendar data being targeted by this example. + + + + + +Daboo, et al. Standards Track [Page 51] +

+RFC 4791                         CalDAV                       March 2007
+
+
+   >> Request <<
+
+   REPORT /bernard/work/ HTTP/1.1
+   Host: cal.example.com
+   Depth: 1
+   Content-Type: application/xml; charset="utf-8"
+   Content-Length: xxxx
+
+   <?xml version="1.0" encoding="utf-8" ?>
+   <C:calendar-query xmlns:C="urn:ietf:params:xml:ns:caldav">
+     <D:prop xmlns:D="DAV:">
+       <D:getetag/>
+       <C:calendar-data/>
+     </D:prop>
+     <C:filter>
+       <C:comp-filter name="VCALENDAR">
+         <C:comp-filter name="VEVENT">
+           <C:prop-filter name="UID">
+             <C:text-match collation="i;octet"
+             >DC6C50A017428C5216A2F1CD@example.com</C:text-match>
+           </C:prop-filter>
+         </C:comp-filter>
+       </C:comp-filter>
+     </C:filter>
+   </C:calendar-query>
+
+   >> Response <<
+
+   HTTP/1.1 207 Multi-Status
+   Date: Sat, 11 Nov 2006 09:32:12 GMT
+   Content-Type: application/xml; charset="utf-8"
+   Content-Length: xxxx
+
+   <?xml version="1.0" encoding="utf-8" ?>
+   <D:multistatus xmlns:D="DAV:"
+                  xmlns:C="urn:ietf:params:xml:ns:caldav">
+     <D:response>
+       <D:href>http://cal.example.com/bernard/work/abcd3.ics</D:href>
+       <D:propstat>
+         <D:prop>
+           <D:getetag>"fffff-abcd3"</D:getetag>
+           <C:calendar-data>BEGIN:VCALENDAR
+   VERSION:2.0
+   PRODID:-//Example Corp.//CalDAV Client//EN
+   BEGIN:VTIMEZONE
+   LAST-MODIFIED:20040110T032845Z
+   TZID:US/Eastern
+   BEGIN:DAYLIGHT
+
+
+
+Daboo, et al.               Standards Track                    [Page 52]
+

+RFC 4791                         CalDAV                       March 2007
+
+
+   DTSTART:20000404T020000
+   RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
+   TZNAME:EDT
+   TZOFFSETFROM:-0500
+   TZOFFSETTO:-0400
+   END:DAYLIGHT
+   BEGIN:STANDARD
+   DTSTART:20001026T020000
+   RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
+   TZNAME:EST
+   TZOFFSETFROM:-0400
+   TZOFFSETTO:-0500
+   END:STANDARD
+   END:VTIMEZONE
+   BEGIN:VEVENT
+   ATTENDEE;PARTSTAT=ACCEPTED;ROLE=CHAIR:mailto:cyrus@example.com
+   ATTENDEE;PARTSTAT=NEEDS-ACTION:mailto:lisa@example.com
+   DTSTAMP:20060206T001220Z
+   DTSTART;TZID=US/Eastern:20060104T100000
+   DURATION:PT1H
+   LAST-MODIFIED:20060206T001330Z
+   ORGANIZER:mailto:cyrus@example.com
+   SEQUENCE:1
+   STATUS:TENTATIVE
+   SUMMARY:Event #3
+   UID:DC6C50A017428C5216A2F1CD@example.com
+   X-ABC-GUID:E1CX5Dr-0007ym-Hz@example.com
+   END:VEVENT
+   END:VCALENDAR
+   </C:calendar-data>
+         </D:prop>
+         <D:status>HTTP/1.1 200 OK</D:status>
+       </D:propstat>
+     </D:response>
+   </D:multistatus>
+
+

7.8.7. Example: Retrieval of Events by PARTSTAT

+ + In this example, the client requests the server to return the VEVENT + components that have the ATTENDEE property with the value + "mailto:lisa@example.com" and for which the PARTSTAT parameter is set + to NEEDS-ACTION. + + See Appendix B for the calendar data being targeted by this example. + + + + + + + +Daboo, et al. Standards Track [Page 53] +

+RFC 4791                         CalDAV                       March 2007
+
+
+   >> Request <<
+
+   REPORT /bernard/work/ HTTP/1.1
+   Host: cal.example.com
+   Depth: 1
+   Content-Type: application/xml; charset="utf-8"
+   Content-Length: xxxx
+
+   <?xml version="1.0" encoding="utf-8" ?>
+   <C:calendar-query xmlns:C="urn:ietf:params:xml:ns:caldav">
+     <D:prop xmlns:D="DAV:">
+       <D:getetag/>
+       <C:calendar-data/>
+     </D:prop>
+     <C:filter>
+       <C:comp-filter name="VCALENDAR">
+         <C:comp-filter name="VEVENT">
+           <C:prop-filter name="ATTENDEE">
+             <C:text-match collation="i;ascii-casemap"
+              >mailto:lisa@example.com</C:text-match>
+             <C:param-filter name="PARTSTAT">
+               <C:text-match collation="i;ascii-casemap"
+                >NEEDS-ACTION</C:text-match>
+             </C:param-filter>
+           </C:prop-filter>
+         </C:comp-filter>
+       </C:comp-filter>
+     </C:filter>
+   </C:calendar-query>
+
+   >> Response <<
+
+   HTTP/1.1 207 Multi-Status
+   Date: Sat, 11 Nov 2006 09:32:12 GMT
+   Content-Type: application/xml; charset="utf-8"
+   Content-Length: xxxx
+
+   <?xml version="1.0" encoding="utf-8" ?>
+   <D:multistatus xmlns:D="DAV:"
+                  xmlns:C="urn:ietf:params:xml:ns:caldav">
+     <D:response>
+       <D:href>http://cal.example.com/bernard/work/abcd3.ics</D:href>
+       <D:propstat>
+         <D:prop>
+           <D:getetag>"fffff-abcd3"</D:getetag>
+           <C:calendar-data>BEGIN:VCALENDAR
+   VERSION:2.0
+   PRODID:-//Example Corp.//CalDAV Client//EN
+
+
+
+Daboo, et al.               Standards Track                    [Page 54]
+

+RFC 4791                         CalDAV                       March 2007
+
+
+   BEGIN:VTIMEZONE
+   LAST-MODIFIED:20040110T032845Z
+   TZID:US/Eastern
+   BEGIN:DAYLIGHT
+   DTSTART:20000404T020000
+   RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
+   TZNAME:EDT
+   TZOFFSETFROM:-0500
+   TZOFFSETTO:-0400
+   END:DAYLIGHT
+   BEGIN:STANDARD
+   DTSTART:20001026T020000
+   RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
+   TZNAME:EST
+   TZOFFSETFROM:-0400
+   TZOFFSETTO:-0500
+   END:STANDARD
+   END:VTIMEZONE
+   BEGIN:VEVENT
+   ATTENDEE;PARTSTAT=ACCEPTED;ROLE=CHAIR:mailto:cyrus@example.com
+   ATTENDEE;PARTSTAT=NEEDS-ACTION:mailto:lisa@example.com
+   DTSTAMP:20060206T001220Z
+   DTSTART;TZID=US/Eastern:20060104T100000
+   DURATION:PT1H
+   LAST-MODIFIED:20060206T001330Z
+   ORGANIZER:mailto:cyrus@example.com
+   SEQUENCE:1
+   STATUS:TENTATIVE
+   SUMMARY:Event #3
+   UID:DC6C50A017428C5216A2F1CD@example.com
+   X-ABC-GUID:E1CX5Dr-0007ym-Hz@example.com
+   END:VEVENT
+   END:VCALENDAR
+   </C:calendar-data>
+         </D:prop>
+         <D:status>HTTP/1.1 200 OK</D:status>
+       </D:propstat>
+     </D:response>
+   </D:multistatus>
+
+

7.8.8. Example: Retrieval of Events Only

+ + In this example, the client requests the server to return all VEVENT + components. + + See Appendix B for the calendar data being targeted by this example. + + + + + +Daboo, et al. Standards Track [Page 55] +

+RFC 4791                         CalDAV                       March 2007
+
+
+   >> Request <<
+
+   REPORT /bernard/work/ HTTP/1.1
+   Host: cal.example.com
+   Depth: 1
+   Content-Type: application/xml; charset="utf-8"
+   Content-Length: xxxx
+
+   <?xml version="1.0" encoding="utf-8" ?>
+   <C:calendar-query xmlns:C="urn:ietf:params:xml:ns:caldav">
+     <D:prop xmlns:D="DAV:">
+       <D:getetag/>
+       <C:calendar-data/>
+     </D:prop>
+     <C:filter>
+       <C:comp-filter name="VCALENDAR">
+         <C:comp-filter name="VEVENT"/>
+       </C:comp-filter>
+     </C:filter>
+   </C:calendar-query>
+
+   >> Response <<
+
+   HTTP/1.1 207 Multi-Status
+   Date: Sat, 11 Nov 2006 09:32:12 GMT
+   Content-Type: application/xml; charset="utf-8"
+   Content-Length: xxxx
+
+   <?xml version="1.0" encoding="utf-8" ?>
+   <D:multistatus xmlns:D="DAV:"
+                  xmlns:C="urn:ietf:params:xml:ns:caldav">
+     <D:response>
+       <D:href>http://cal.example.com/bernard/work/abcd1.ics</D:href>
+       <D:propstat>
+         <D:prop>
+           <D:getetag>"fffff-abcd1"</D:getetag>
+           <C:calendar-data>BEGIN:VCALENDAR
+   VERSION:2.0
+   PRODID:-//Example Corp.//CalDAV Client//EN
+   BEGIN:VTIMEZONE
+   LAST-MODIFIED:20040110T032845Z
+   TZID:US/Eastern
+   BEGIN:DAYLIGHT
+   DTSTART:20000404T020000
+   RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
+   TZNAME:EDT
+   TZOFFSETFROM:-0500
+   TZOFFSETTO:-0400
+
+
+
+Daboo, et al.               Standards Track                    [Page 56]
+

+RFC 4791                         CalDAV                       March 2007
+
+
+   END:DAYLIGHT
+   BEGIN:STANDARD
+   DTSTART:20001026T020000
+   RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
+   TZNAME:EST
+   TZOFFSETFROM:-0400
+   TZOFFSETTO:-0500
+   END:STANDARD
+   END:VTIMEZONE
+   BEGIN:VEVENT
+   DTSTAMP:20060206T001102Z
+   DTSTART;TZID=US/Eastern:20060102T100000
+   DURATION:PT1H
+   SUMMARY:Event #1
+   Description:Go Steelers!
+   UID:74855313FA803DA593CD579A@example.com
+   END:VEVENT
+   END:VCALENDAR
+   </C:calendar-data>
+         </D:prop>
+         <D:status>HTTP/1.1 200 OK</D:status>
+       </D:propstat>
+     </D:response>
+     <D:response>
+       <D:href>http://cal.example.com/bernard/work/abcd2.ics</D:href>
+       <D:propstat>
+         <D:prop>
+           <D:getetag>"fffff-abcd2"</D:getetag>
+           <C:calendar-data>BEGIN:VCALENDAR
+   VERSION:2.0
+   PRODID:-//Example Corp.//CalDAV Client//EN
+   BEGIN:VTIMEZONE
+   LAST-MODIFIED:20040110T032845Z
+   TZID:US/Eastern
+   BEGIN:DAYLIGHT
+   DTSTART:20000404T020000
+   RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
+   TZNAME:EDT
+   TZOFFSETFROM:-0500
+   TZOFFSETTO:-0400
+   END:DAYLIGHT
+   BEGIN:STANDARD
+   DTSTART:20001026T020000
+   RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
+   TZNAME:EST
+   TZOFFSETFROM:-0400
+   TZOFFSETTO:-0500
+   END:STANDARD
+
+
+
+Daboo, et al.               Standards Track                    [Page 57]
+

+RFC 4791                         CalDAV                       March 2007
+
+
+   END:VTIMEZONE
+   BEGIN:VEVENT
+   DTSTAMP:20060206T001121Z
+   DTSTART;TZID=US/Eastern:20060102T120000
+   DURATION:PT1H
+   RRULE:FREQ=DAILY;COUNT=5
+   SUMMARY:Event #2
+   UID:00959BC664CA650E933C892C@example.com
+   END:VEVENT
+   BEGIN:VEVENT
+   DTSTAMP:20060206T001121Z
+   DTSTART;TZID=US/Eastern:20060104T140000
+   DURATION:PT1H
+   RECURRENCE-ID;TZID=US/Eastern:20060104T120000
+   SUMMARY:Event #2 bis
+   UID:00959BC664CA650E933C892C@example.com
+   END:VEVENT
+   BEGIN:VEVENT
+   DTSTAMP:20060206T001121Z
+   DTSTART;TZID=US/Eastern:20060106T140000
+   DURATION:PT1H
+   RECURRENCE-ID;TZID=US/Eastern:20060106T120000
+   SUMMARY:Event #2 bis bis
+   UID:00959BC664CA650E933C892C@example.com
+   END:VEVENT
+   END:VCALENDAR
+   </C:calendar-data>
+         </D:prop>
+         <D:status>HTTP/1.1 200 OK</D:status>
+       </D:propstat>
+     </D:response>
+     <D:response>
+       <D:href>http://cal.example.com/bernard/work/abcd3.ics</D:href>
+       <D:propstat>
+         <D:prop>
+           <D:getetag>"fffff-abcd3"</D:getetag>
+           <C:calendar-data>BEGIN:VCALENDAR
+   VERSION:2.0
+   PRODID:-//Example Corp.//CalDAV Client//EN
+   BEGIN:VTIMEZONE
+   LAST-MODIFIED:20040110T032845Z
+   TZID:US/Eastern
+   BEGIN:DAYLIGHT
+   DTSTART:20000404T020000
+   RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
+   TZNAME:EDT
+   TZOFFSETFROM:-0500
+   TZOFFSETTO:-0400
+
+
+
+Daboo, et al.               Standards Track                    [Page 58]
+

+RFC 4791                         CalDAV                       March 2007
+
+
+   END:DAYLIGHT
+   BEGIN:STANDARD
+   DTSTART:20001026T020000
+   RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
+   TZNAME:EST
+   TZOFFSETFROM:-0400
+   TZOFFSETTO:-0500
+   END:STANDARD
+   END:VTIMEZONE
+   BEGIN:VEVENT
+   ATTENDEE;PARTSTAT=ACCEPTED;ROLE=CHAIR:mailto:cyrus@example.com
+   ATTENDEE;PARTSTAT=NEEDS-ACTION:mailto:lisa@example.com
+   DTSTAMP:20060206T001220Z
+   DTSTART;TZID=US/Eastern:20060104T100000
+   DURATION:PT1H
+   LAST-MODIFIED:20060206T001330Z
+   ORGANIZER:mailto:cyrus@example.com
+   SEQUENCE:1
+   STATUS:TENTATIVE
+   SUMMARY:Event #3
+   UID:DC6C50A017428C5216A2F1CD@example.com
+   X-ABC-GUID:E1CX5Dr-0007ym-Hz@example.com
+   END:VEVENT
+   END:VCALENDAR
+   </C:calendar-data>
+         </D:prop>
+         <D:status>HTTP/1.1 200 OK</D:status>
+       </D:propstat>
+     </D:response>
+   </D:multistatus>
+
+

7.8.9. Example: Retrieval of All Pending To-Dos

+ + In this example, the client requests the server to return all VTODO + components that do not include a COMPLETED property and do not have a + STATUS property value matching CANCELLED, i.e., VTODOs that still + need to be worked on. + + See Appendix B for the calendar data being targeted by this example. + + + + + + + + + + + + +Daboo, et al. Standards Track [Page 59] +

+RFC 4791                         CalDAV                       March 2007
+
+
+   >> Request <<
+
+   REPORT /bernard/work/ HTTP/1.1
+   Host: cal.example.com
+   Depth: 1
+   Content-Type: application/xml; charset="utf-8"
+   Content-Length: xxxx
+
+   <?xml version="1.0" encoding="utf-8" ?>
+   <C:calendar-query xmlns:C="urn:ietf:params:xml:ns:caldav">
+     <D:prop xmlns:D="DAV:">
+       <D:getetag/>
+       <C:calendar-data/>
+     </D:prop>
+     <C:filter>
+       <C:comp-filter name="VCALENDAR">
+         <C:comp-filter name="VTODO">
+           <C:prop-filter name="COMPLETED">
+             <C:is-not-defined/>
+           </C:prop-filter>
+           <C:prop-filter name="STATUS">
+             <C:text-match
+                negate-condition="yes">CANCELLED</C:text-match>
+           </C:prop-filter>
+         </C:comp-filter>
+       </C:comp-filter>
+     </C:filter>
+   </C:calendar-query>
+
+   >> Response <<
+
+   HTTP/1.1 207 Multi-Status
+   Date: Sat, 11 Nov 2006 09:32:12 GMT
+   Content-Type: application/xml; charset="utf-8"
+   Content-Length: xxxx
+
+   <?xml version="1.0" encoding="utf-8" ?>
+   <D:multistatus xmlns:D="DAV:"
+                  xmlns:C="urn:ietf:params:xml:ns:caldav">
+     <D:response>
+       <D:href>http://cal.example.com/bernard/work/abcd4.ics</D:href>
+       <D:propstat>
+         <D:prop>
+           <D:getetag>"fffff-abcd4"</D:getetag>
+           <C:calendar-data>BEGIN:VCALENDAR
+   VERSION:2.0
+   PRODID:-//Example Corp.//CalDAV Client//EN
+   BEGIN:VTODO
+
+
+
+Daboo, et al.               Standards Track                    [Page 60]
+

+RFC 4791                         CalDAV                       March 2007
+
+
+   DTSTAMP:20060205T235335Z
+   DUE;VALUE=DATE:20060104
+   STATUS:NEEDS-ACTION
+   SUMMARY:Task #1
+   UID:DDDEEB7915FA61233B861457@example.com
+   BEGIN:VALARM
+   ACTION:AUDIO
+   TRIGGER;RELATED=START:-PT10M
+   END:VALARM
+   END:VTODO
+   END:VCALENDAR
+   </C:calendar-data>
+         </D:prop>
+         <D:status>HTTP/1.1 200 OK</D:status>
+       </D:propstat>
+     </D:response>
+
+     <D:response>
+       <D:href>http://cal.example.com/bernard/work/abcd5.ics</D:href>
+       <D:propstat>
+         <D:prop>
+           <D:getetag>"fffff-abcd5"</D:getetag>
+           <C:calendar-data>BEGIN:VCALENDAR
+   VERSION:2.0
+   PRODID:-//Example Corp.//CalDAV Client//EN
+   BEGIN:VTODO
+   DTSTAMP:20060205T235300Z
+   DUE;VALUE=DATE:20060106
+   LAST-MODIFIED:20060205T235308Z
+   SEQUENCE:1
+   STATUS:NEEDS-ACTION
+   SUMMARY:Task #2
+   UID:E10BA47467C5C69BB74E8720@example.com
+   BEGIN:VALARM
+   ACTION:AUDIO
+   TRIGGER;RELATED=START:-PT10M
+   END:VALARM
+   END:VTODO
+   END:VCALENDAR
+   </C:calendar-data>
+         </D:prop>
+         <D:status>HTTP/1.1 200 OK</D:status>
+       </D:propstat>
+     </D:response>
+   </D:multistatus>
+
+
+
+
+
+
+Daboo, et al.               Standards Track                    [Page 61]
+

+RFC 4791                         CalDAV                       March 2007
+
+
+

7.8.10. Example: Attempt to Query Unsupported Property

+ + In this example, the client requests the server to return all VEVENT + components that include an X-ABC-GUID property with a value matching + "ABC". However, the server does not support querying that non- + standard property, and instead returns an error response. + + See Appendix B for the calendar data being targeted by this example. + + >> Request << + + REPORT /bernard/work/ HTTP/1.1 + Host: cal.example.com + Depth: 1 + Content-Type: application/xml; charset="utf-8" + Content-Length: xxxx + + <?xml version="1.0" encoding="utf-8" ?> + <C:calendar-query xmlns:C="urn:ietf:params:xml:ns:caldav"> + <D:prop xmlns:D="DAV:"> + <D:getetag/> + <C:calendar-data/> + </D:prop> + <C:filter> + <C:comp-filter name="VCALENDAR"> + <C:comp-filter name="VEVENT"> + <C:prop-filter name="X-ABC-GUID"> + <C:text-match>ABC</C:text-match> + </C:prop-filter> + </C:comp-filter> + </C:comp-filter> + </C:filter> + </C:calendar-query> + + >> Response << + + HTTP/1.1 403 Forbidden + Date: Sat, 11 Nov 2005 09:32:12 GMT + Content-Type: application/xml; charset="utf-8" + Content-Length: xxxx + + <?xml version="1.0" encoding="utf-8" ?> + <D:error> + <C:supported-filter> + <C:prop-filter name="X-ABC-GUID"/> + </C:supported-filter> + </D:error> + + + + +Daboo, et al. Standards Track [Page 62] +

+RFC 4791                         CalDAV                       March 2007
+
+
+

7.9. CALDAV:calendar-multiget REPORT

+ + The CALDAV:calendar-multiget REPORT is used to retrieve specific + calendar object resources from within a collection, if the Request- + URI is a collection, or to retrieve a specific calendar object + resource, if the Request-URI is a calendar object resource. This + report is similar to the CALDAV:calendar-query REPORT (see + Section 7.8), except that it takes a list of DAV:href elements, + instead of a CALDAV:filter element, to determine which calendar + object resources to return. + + Support for the CALDAV:calendar-multiget REPORT is REQUIRED. + + Marshalling: + + The request body MUST be a CALDAV:calendar-multiget XML element + (see Section 9.10). If the Request-URI is a collection resource, + then the DAV:href elements MUST refer to calendar object resources + within that collection, and they MAY refer to calendar object + resources at any depth within the collection. As a result, the + "Depth" header MUST be ignored by the server and SHOULD NOT be + sent by the client. If the Request-URI refers to a non-collection + resource, then there MUST be a single DAV:href element that is + equivalent to the Request-URI. + + The response body for a successful request MUST be a DAV: + multistatus XML element. + + The response body for a successful CALDAV:calendar-multiget REPORT + request MUST contain a DAV:response element for each calendar + object resource referenced by the provided set of DAV:href + elements. Calendar data is being returned in the CALDAV:calendar- + data element inside the DAV:prop element. + + In the case of an error accessing any of the provided DAV:href + resources, the server MUST return the appropriate error status + code in the DAV:status element of the corresponding DAV:response + element. + + Preconditions: + + (CALDAV:supported-calendar-data): The attributes "content-type" + and "version" of the CALDAV:calendar-data XML elements (see + Section 9.6) specify a media type supported by the server for + calendar object resources. + + (CALDAV:min-date-time): Any XML element specifying a range of time + MUST have its start or end DATE or DATE-TIME values greater than + + + +Daboo, et al. Standards Track [Page 63] +

+RFC 4791                         CalDAV                       March 2007
+
+
+      or equal to the value of the CALDAV:min-date-time property value
+      (Section 5.2.6) on the calendar collections being targeted by the
+      REPORT request;
+
+      (CALDAV:max-date-time): Any XML element specifying a range of time
+      MUST have its start or end DATE or DATE-TIME values less than or
+      equal to the value of the CALDAV:max-date-time property value
+      (Section 5.2.7) on the calendar collections being targeted by the
+      REPORT request;
+
+   Postconditions:
+
+      None.
+
+

7.9.1. Example: Successful CALDAV:calendar-multiget REPORT

+ + In this example, the client requests the server to return specific + properties of the VEVENT components referenced by specific URIs. In + addition, the DAV:getetag property is also requested and returned as + part of the response. Note that in this example, the resource at + http://cal.example.com/bernard/work/mtg1.ics does not exist, + resulting in an error status response. + + See Appendix B for the calendar data being targeted by this example. + + >> Request << + + REPORT /bernard/work/ HTTP/1.1 + Host: cal.example.com + Content-Type: application/xml; charset="utf-8" + Content-Length: xxxx + + <?xml version="1.0" encoding="utf-8" ?> + <C:calendar-multiget xmlns:D="DAV:" + xmlns:C="urn:ietf:params:xml:ns:caldav"> + <D:prop> + <D:getetag/> + <C:calendar-data/> + </D:prop> + <D:href>/bernard/work/abcd1.ics</D:href> + <D:href>/bernard/work/mtg1.ics</D:href> + </C:calendar-multiget> + + >> Response << + + HTTP/1.1 207 Multi-Status + Date: Sat, 11 Nov 2006 09:32:12 GMT + Content-Type: application/xml; charset="utf-8" + + + +Daboo, et al. Standards Track [Page 64] +

+RFC 4791                         CalDAV                       March 2007
+
+
+   Content-Length: xxxx
+
+   <?xml version="1.0" encoding="utf-8" ?>
+   <D:multistatus xmlns:D="DAV:"
+                  xmlns:C="urn:ietf:params:xml:ns:caldav">
+     <D:response>
+       <D:href>http://cal.example.com/bernard/work/abcd1.ics</D:href>
+       <D:propstat>
+         <D:prop>
+           <D:getetag>"fffff-abcd1"</D:getetag>
+           <C:calendar-data>BEGIN:VCALENDAR
+   VERSION:2.0
+   PRODID:-//Example Corp.//CalDAV Client//EN
+   BEGIN:VTIMEZONE
+   LAST-MODIFIED:20040110T032845Z
+   TZID:US/Eastern
+   BEGIN:DAYLIGHT
+   DTSTART:20000404T020000
+   RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
+   TZNAME:EDT
+   TZOFFSETFROM:-0500
+   TZOFFSETTO:-0400
+   END:DAYLIGHT
+   BEGIN:STANDARD
+   DTSTART:20001026T020000
+   RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
+   TZNAME:EST
+   TZOFFSETFROM:-0400
+   TZOFFSETTO:-0500
+   END:STANDARD
+   END:VTIMEZONE
+   BEGIN:VEVENT
+   DTSTAMP:20060206T001102Z
+   DTSTART;TZID=US/Eastern:20060102T100000
+   DURATION:PT1H
+   SUMMARY:Event #1
+   Description:Go Steelers!
+   UID:74855313FA803DA593CD579A@example.com
+   END:VEVENT
+   END:VCALENDAR
+   </C:calendar-data>
+         </D:prop>
+         <D:status>HTTP/1.1 200 OK</D:status>
+       </D:propstat>
+     </D:response>
+     <D:response>
+       <D:href>http://cal.example.com/bernard/work/mtg1.ics</D:href>
+       <D:status>HTTP/1.1 404 Not Found</D:status>
+
+
+
+Daboo, et al.               Standards Track                    [Page 65]
+

+RFC 4791                         CalDAV                       March 2007
+
+
+     </D:response>
+   </D:multistatus>
+
+

7.10. CALDAV:free-busy-query REPORT

+ + The CALDAV:free-busy-query REPORT generates a VFREEBUSY component + containing free busy information for all the calendar object + resources targeted by the request and that have the CALDAV:read-free- + busy or DAV:read privilege granted to the current user. + + Only VEVENT components without a TRANSP property or with the TRANSP + property set to OPAQUE, and VFREEBUSY components SHOULD be considered + in generating the free busy time information. + + In the case of VEVENT components, the free or busy time type (FBTYPE) + of the FREEBUSY properties in the returned VFREEBUSY component SHOULD + be derived from the value of the TRANSP and STATUS properties, as + outlined in the table below: + + +---------------------------++------------------+ + | VEVENT || VFREEBUSY | + +-------------+-------------++------------------+ + | TRANSP | STATUS || FBTYPE | + +=============+=============++==================+ + | | CONFIRMED || BUSY | + | | (default) || | + | OPAQUE +-------------++------------------+ + | (default) | CANCELLED || FREE | + | +-------------++------------------+ + | | TENTATIVE || BUSY-TENTATIVE | + | +-------------++------------------+ + | | x-name || BUSY or | + | | || x-name | + +-------------+-------------++------------------+ + | | CONFIRMED || | + | TRANSPARENT | CANCELLED || FREE | + | | TENTATIVE || | + | | x-name || | + +-------------+-------------++------------------+ + + Duplicate busy time periods with the same FBTYPE parameter value + SHOULD NOT be specified in the returned VFREEBUSY component. Servers + SHOULD coalesce consecutive or overlapping busy time periods of the + same type. Busy time periods with different FBTYPE parameter values + MAY overlap. + + Support for the CALDAV:free-busy-query REPORT is REQUIRED. + + + + +Daboo, et al. Standards Track [Page 66] +

+RFC 4791                         CalDAV                       March 2007
+
+
+   Marshalling:
+
+      The request body MUST be a CALDAV:free-busy-query XML element (see
+      Section 9.11), which MUST contain exactly one CALDAV:time-range
+      XML element, as defined in Section 9.9.
+
+      The request MAY include a Depth header.  If no Depth header is
+      included, Depth:0 is assumed.
+
+      The response body for a successful request MUST be an iCalendar
+      object that contains exactly one VFREEBUSY component that
+      describes the busy time intervals for the calendar object
+      resources containing VEVENT, or VFREEBUSY components that satisfy
+      the Depth value and for which the current user is at least granted
+      the CALDAV:read-free-busy privilege.  If no calendar object
+      resources are found to satisfy these conditions, a VFREEBUSY
+      component with no FREEBUSY property MUST be returned.  This report
+      only returns busy time information.  Free time information can be
+      inferred from the returned busy time information.
+
+      If the current user is not granted the CALDAV:read-free-busy or
+      DAV:read privileges on the Request-URI, the CALDAV:free-busy-query
+      REPORT request MUST fail and return a 404 (Not Found) status
+      value.  This restriction will prevent users from discovering URLs
+      of resources for which they are only granted the CALDAV:read-free-
+      busy privilege.
+
+      The CALDAV:free-busy-query REPORT request can only be run against
+      a collection (either a regular collection or a calendar
+      collection).  An attempt to run the report on a calendar object
+      resource MUST fail and return a 403 (Forbidden) status value.
+
+   Preconditions:
+
+      None.
+
+   Postconditions:
+
+      (DAV:number-of-matches-within-limits): The number of matching
+      calendar object resources must fall within server-specific,
+      predefined limits.  For example, this postcondition might fail if
+      the specified CALDAV:time-range would cause an extremely large
+      number of calendar object resources to be considered in computing
+      the response.
+
+
+
+
+
+
+
+Daboo, et al.               Standards Track                    [Page 67]
+

+RFC 4791                         CalDAV                       March 2007
+
+
+

7.10.1. Example: Successful CALDAV:free-busy-query REPORT

+ + In this example, the client requests the server to return free busy + information on the calendar collection /bernard/work/, between 9:00 + A.M. and 5:00 P.M. EST (2:00 P.M. and 10:00 P.M. UTC) on the January + 4, 2006. The server responds, indicating two busy time intervals of + one hour, one of which is tentative. + + See Appendix B for the calendar data being targeted by this example. + + >> Request << + + REPORT /bernard/work/ HTTP/1.1 + Host: cal.example.com + Depth: 1 + Content-Type: application/xml; charset="utf-8" + Content-Length: xxxx + + <?xml version="1.0" encoding="utf-8" ?> + <C:free-busy-query xmlns:C="urn:ietf:params:xml:ns:caldav"> + <C:time-range start="20060104T140000Z" + end="20060105T220000Z"/> + </C:free-busy-query> + + >> Response << + + HTTP/1.1 200 OK + Date: Sat, 11 Nov 2006 09:32:12 GMT + Content-Type: text/calendar + Content-Length: xxxx + + BEGIN:VCALENDAR + VERSION:2.0 + PRODID:-//Example Corp.//CalDAV Server//EN + BEGIN:VFREEBUSY + DTSTAMP:20050125T090000Z + DTSTART:20060104T140000Z + DTEND:20060105T220000Z + FREEBUSY;FBTYPE=BUSY-TENTATIVE:20060104T150000Z/PT1H + FREEBUSY:20060104T190000Z/PT1H + END:VFREEBUSY + END:VCALENDAR + + + + + + + + + +Daboo, et al. Standards Track [Page 68] +

+RFC 4791                         CalDAV                       March 2007
+
+
+

8. Guidelines

+ +

8.1. Client-to-Client Interoperability

+ + There are a number of actions clients can take that will be legal + (the server will not return errors), but that can degrade + interoperability with other client implementations accessing the same + data. For example, a recurrence rule could be replaced with a set of + recurrence dates, a single recurring event could be replaced with a + set of independent resources to represent each recurrence, or the + start/end time values can be translated from the original time zone + to another time zone. Although this advice amounts to iCalendar + interoperability best practices and is not limited only to CalDAV + usage, interoperability problems are likely to be more evident in + CalDAV use cases. + +

8.2. Synchronization Operations

+ + WebDAV already provides functionality required to synchronize a + collection or set of collections, to make changes offline, and + provides a simple way to resolve conflicts when reconnected. ETags + are the key to making this work, but these are not required of all + WebDAV servers. Since offline functionality is more important to + calendar applications than to some other WebDAV applications, CalDAV + servers MUST support ETags, as specified in Section 5.3.4. + +

8.2.1. Use of Reports

+ +
8.2.1.1. Restrict the Time Range
+ + The reports provided in CalDAV can be used by clients to optimize + their performance in terms of network bandwidth usage and resource + consumption on the local client machine. Both are certainly major + considerations for mobile or handheld devices with limited capacity, + but they are also relevant to desktop client applications in cases + where the calendar collections contain large amounts of data. + + Typically, clients present calendar data to users in views that span + a finite time interval, so whenever possible, clients should only + retrieve calendar components from the server using CALDAV:calendar- + query REPORT, combined with a CALDAV:time-range element, to limit the + set of returned components to just those needed to populate the + current view. + + + + + + + + +Daboo, et al. Standards Track [Page 69] +

+RFC 4791                         CalDAV                       March 2007
+
+
+
8.2.1.2. Synchronize by Time Range
+ + Typically in a calendar, historical data (events, to-dos, etc. that + have completed prior to the current date) do not change, though they + may be deleted. As a result, a client can speed up the + synchronization process by only considering data for the present time + and the future up to a reasonable limit (e.g., one week, one month). + If the user then tries to examine a portion of the calendar outside + the range that has been synchronized, the client can perform another + synchronization operation on the new time interval being examined. + This "just-in-time" synchronization can minimize bandwidth for common + user interaction behaviors. + +
8.2.1.3. Synchronization Process
+ + If a client wants to support calendar data synchronization, as + opposed to downloading calendar data each time it is needed, the + client needs to cache the calendar object resource's URI and ETag, + along with the actual calendar data. While the URI remains static + for the lifetime of the calendar object resource, the ETag will + change with each successive change to the calendar object resource. + Thus, to synchronize a local data cache with the server, the client + can first fetch the URI/ETag pairs for the time interval being + considered, and compare those results with the cached data. Any + cached component whose ETag differs from that on the server needs to + be refreshed. + + In order to properly detect the changes between the server and client + data, the client will need to keep a record of which calendar object + resources have been created, changed, or deleted since the last + synchronization operation so that it can reconcile those changes with + the data on the server. + + Here's an example of how to do that: + + The client issues a CALDAV:calendar-query REPORT request for a + specific time range and asks for only the DAV:getetag property to be + returned: + + + + + + + + + + + + + +Daboo, et al. Standards Track [Page 70] +

+RFC 4791                         CalDAV                       March 2007
+
+
+   REPORT /bernard/work/ HTTP/1.1
+   Host: cal.example.com
+   Depth: 1
+   Content-Type: application/xml; charset="utf-8"
+   Content-Length: xxxx
+
+   <?xml version="1.0" encoding="utf-8" ?>
+   <C:calendar-query xmlns:D="DAV:"
+                     xmlns:C="urn:ietf:params:xml:ns:caldav">
+     <D:prop>
+       <D:getetag/>
+     </D:prop>
+     <C:filter>
+       <C:comp-filter name="VCALENDAR">
+         <C:comp-filter name="VEVENT">
+           <C:time-range start="20040902T000000Z"
+                           end="20040903T000000Z"/>
+         </C:comp-filter>
+       </C:comp-filter>
+     </C:filter>
+   </C:calendar-query>
+
+   The client then uses the results to determine which calendar object
+   resources have changed, been created, or deleted on the server, and
+   how those relate to locally cached calendar object resources that may
+   have changed, been created, or deleted.  If the client determines
+   that there are calendar object resources on the server that need to
+   be fetched, the client issues a CALDAV:calendar-multiget REPORT
+   request to fetch its calendar data:
+
+   REPORT /bernard/work/ HTTP/1.1
+   Host: cal.example.com
+   Content-Type: application/xml; charset="utf-8"
+   Content-Length: xxxx
+
+   <?xml version="1.0" encoding="utf-8" ?>
+   <C:calendar-multiget xmlns:D="DAV:"
+                        xmlns:C="urn:ietf:params:xml:ns:caldav">
+     <D:prop>
+       <D:getetag/>
+       <C:calendar-data/>
+     </D:prop>
+     <D:href>/bernard/work/abcd1.ics</D:href>
+     <D:href>/bernard/work/mtg1.ics</D:href>
+   </C:calendar-multiget>
+
+
+
+
+
+
+Daboo, et al.               Standards Track                    [Page 71]
+

+RFC 4791                         CalDAV                       March 2007
+
+
+

8.2.2. Restrict the Properties Returned

+ + A client may not need all the calendar properties of a calendar + object resource when presenting information to the user. Since some + calendar property values can be large (e.g., ATTACH or ATTENDEE), a + client can choose to restrict the calendar properties to be returned + in a calendaring REPORT request to those it knows it will use. + + However, if a client needs to make a change to a calendar object + resource, it can only change the entire calendar object resource via + a PUT request. There is currently no way to incrementally make a + change to a set of calendar properties of a calendar object resource. + As a result, the client will have to get the entire calendar object + resource that is being changed. + +

8.3. Use of Locking

+ + WebDAV locks can be used to prevent two clients that are modifying + the same resource from either overwriting each others' changes + (though that problem can also be solved by using ETags) or wasting + time making changes that will conflict with another set of changes. + In a multi-user calendar system, an interactive calendar client could + lock an event while the user is editing the event, and unlock the + event when the user finishes or cancels. Locks can also be used to + prevent changes while data is being reorganized. For example, a + calendar client might lock two calendar collections prior to moving a + bunch of calendar resources from one to another. + + Clients are responsible for requesting a lock timeout period that is + appropriate to the use case. When the user explicitly decides to + reserve a resource and prevent other changes, a long timeout might be + appropriate, but in cases where the client automatically decides to + lock the resource, the timeout should be short (and the client can + always refresh the lock should it need to). A short lock timeout + means that if the client is unable to remove the lock, the other + calendar users aren't prevented from making changes. + +

8.4. Finding Calendars

+ + Much of the time, a calendar client (or agent) will discover a new + calendar's location by being provided directly with the URL. For + example, a user will type his or her own calendar location into + client configuration information or copy and paste a URL from email + into the calendar application. The client need only confirm that the + URL points to a resource that is a calendar collection. The client + may also be able to browse WebDAV collections to find calendar + collections. + + + + +Daboo, et al. Standards Track [Page 72] +

+RFC 4791                         CalDAV                       March 2007
+
+
+   The choice of HTTP URLs means that calendar object resources are
+   backward compatible with existing software, but does have the
+   disadvantage that existing software does not usually know to look at
+   the OPTIONS response to that URL to determine what can be done with
+   it.  This is somewhat of a barrier for WebDAV usage as well as with
+   CalDAV usage.  This specification does not offer a way through this
+   other than making the information available in the OPTIONS response
+   should this be requested.
+
+   For calendar sharing and scheduling use cases, one might wish to find
+   the calendar belonging to another user.  If the other user has a
+   calendar in the same repository, that calendar can be found by using
+   the principal namespace required by WebDAV ACL support.  For other
+   cases, the authors have no universal solution, but implementers can
+   consider whether to use vCard [RFC2426] or LDAP [RFC4511] standards
+   together with calendar attributes [RFC2739].
+
+   Because CalDAV requires servers to support WebDAV ACL [RFC3744],
+   including principal namespaces, and with the addition of the CALDAV:
+   calendar-home-set property, there are a couple options for CalDAV
+   clients to find one's own calendar or another user's calendar.
+
+   In this case, a DAV:principal-match REPORT is used to find a named
+   property (the CALDAV:calendar-home-set) on the Principal-URL of the
+   current user.  Using this, a WebDAV client can learn "who am I" and
+   "where are my calendars".  The REPORT request body looks like this:
+
+   <?xml version="1.0" encoding="utf-8" ?>
+   <D:principal-match xmlns:D="DAV:">
+     <D:self/>
+     <D:prop>
+       <C:calendar-home-set
+          xmlns:C="urn:ietf:params:xml:ns:caldav"/>
+     </D:prop>
+   </D:principal-match>
+
+   To find other users' calendars, the DAV:principal-property-search
+   REPORT can be used to filter on some properties and return others.
+   To search for a calendar owned by a user named "Laurie", the REPORT
+   request body would look like this:
+
+
+
+
+
+
+
+
+
+
+
+Daboo, et al.               Standards Track                    [Page 73]
+

+RFC 4791                         CalDAV                       March 2007
+
+
+   <?xml version="1.0" encoding="utf-8" ?>
+   <D:principal-property-search xmlns:D="DAV:">
+     <D:property-search>
+       <D:prop>
+         <D:displayname/>
+       </D:prop>
+       <D:match>Laurie</D:match>
+     </D:property-search>
+     <D:prop>
+       <C:calendar-home-set
+          xmlns:C="urn:ietf:params:xml:ns:caldav"/>
+       <D:displayname/>
+     </D:prop>
+   </D:principal-property-search>
+
+   The server performs a case-sensitive or caseless search for a
+   matching string subset of "Laurie" within the DAV:displayname
+   property.  Thus, the server might return "Laurie Dusseault", "Laurier
+   Desruisseaux", or "Wilfrid Laurier" as matching DAV:displayname
+   values, and return the calendars for each of these.
+
+

8.5. Storing and Using Attachments

+ + CalDAV clients MAY create attachments in calendar components either + as inline or external. This section contains some guidelines for + creating and managing attachments. + +

8.5.1. Inline Attachments

+ + CalDAV clients MUST support inline attachments as specified in + iCalendar [RFC2445]. CalDAV servers MUST support inline attachments, + so clients can rely on being able to create attachments this way. On + the other hand, inline attachments have some drawbacks: + + o Servers MAY impose limitations on the size of calendar object + resources (i.e., refusing PUT requests of very large iCalendar + objects). Servers that impose such limitations MUST use the + CALDAV:max-resource-size property on a calendar collection to + inform the client as to what the limitation is (see + Section 5.2.5). + + o Servers MAY impose storage quota limitations on calendar + collections (See [RFC4331]). + + o Any change to a calendar object resource containing an inline + attachment requires the entire inline attachment to be re- + uploaded. + + + + +Daboo, et al. Standards Track [Page 74] +

+RFC 4791                         CalDAV                       March 2007
+
+
+   o  Clients synchronizing a changed calendar object resource have to
+      download the entire calendar object resource, even if the
+      attachment is unchanged.
+
+

8.5.2. External Attachments

+ + CalDAV clients SHOULD support downloading of external attachments + referenced by arbitrary URI schemes, by either processing them + directly, or by passing the attachment URI to a suitable "helper + application" for processing, if such an application exists. CalDAV + clients MUST support downloading of external attachments referenced + by the "http" or "https" URI schemes. An external attachment could + be: + + o In a collection in the calendar collection containing the calendar + object resource; + + o Somewhere else in the same repository that hosts the calendar + collection; or + + o On an HTTP or FTP server elsewhere. + + CalDAV servers MAY provide support for child collections in calendar + collections. CalDAV servers MAY allow the MKCOL method to create + child collections in calendar collections. Child collections of + calendar collections MAY contain any type of resource except calendar + collections that they MUST NOT contain. Some CalDAV servers won't + allow child collections in calendar collections, and it may be + possible on such a server to discover other locations where + attachments can be stored. + + Clients are entirely responsible for maintaining reference + consistency with calendar components that link to external + attachments. A client deleting a calendar component with an external + attachment might therefore also delete the attachment if that's + appropriate; however, appropriateness can be very hard to determine. + A new component might easily reference some pre-existing Web resource + that is intended to have independent existence from the calendar + component (the "attachment" could be a major proposal to be discussed + in a meeting, for instance). Best practices will probably emerge and + should probably be documented, but for now, clients should be wary of + engaging in aggressive "cleanup" of external attachments. A client + could involve the user in making decisions about removing + unreferenced documents, or a client could be conservative in only + deleting attachments it had created. + + Also, clients are responsible for consistency of permissions when + using external attachments. One reason for servers to support the + + + +Daboo, et al. Standards Track [Page 75] +

+RFC 4791                         CalDAV                       March 2007
+
+
+   storage of attachments within child collections of calendar
+   collections is that ACL inheritance might make it easier to grant the
+   same permissions to attachments that are granted on the calendar
+   collection.  Otherwise, it can be very difficult to keep permissions
+   synchronized.  With attachments stored on separate repositories, it
+   can be impossible to keep permissions consistent -- the two
+   repositories may not support the same permissions or have the same
+   set of principals.  Some systems have used tickets or other anonymous
+   access control mechanisms to provide partially satisfactory solutions
+   to these kinds of problems.
+
+

8.6. Storing and Using Alarms

+ + Note that all CalDAV calendar collections (including those the user + might treat as public or group calendars) can contain alarm + information on events and to-dos. Users can synchronize a calendar + between multiple devices and decide to have alarms execute on a + different device than the device that created the alarm. Not all + alarm action types are completely interoperable (e.g., those that + name a sound file to play). + + When the action is AUDIO and the client is configured to execute + the alarm, the client SHOULD play the suggested sound if it's + available or play another sound, but SHOULD NOT rewrite the alarm + just to replace the suggested sound with a sound that's locally + available. + + When the action is DISPLAY and the client is configured to execute + the alarm, the client SHOULD execute a display alarm by displaying + according to the suggested description or some reasonable + replacement, but SHOULD NOT rewrite the alarm for its own + convenience. + + When the action is EMAIL and the client is incapable of sending + email, it SHOULD ignore the alarm, but it MUST continue to + synchronize the alarm itself. + + This specification makes no recommendations about executing alarms + of type PROCEDURE, except to note that clients are advised to take + care to avoid creating security holes by executing these. + + Non-interoperable alarm information (e.g., should somebody define a + color to be used in a display alarm) should be put in non-standard + properties inside the VALARM component in order to keep the basic + alarm usable on all devices. + + Clients that allow changes to calendar object resources MUST + synchronize the alarm data that already exists in the resources. + + + +Daboo, et al. Standards Track [Page 76] +

+RFC 4791                         CalDAV                       March 2007
+
+
+   Clients MAY execute alarms that are downloaded in this fashion,
+   possibly based on user preference.  If a client is only doing read
+   operations on a calendar and there is no risk of losing alarm
+   information, then the client MAY discard alarm information.
+
+   This specification makes no attempt to provide multi-user alarms on
+   group calendars or to find out for whom an alarm is intended.
+   Addressing those issues might require extensions to iCalendar; for
+   example, to store alarms per-user, or to indicate for which user a
+   VALARM was intended.  In the meantime, clients might maximize
+   interoperability by generally not uploading alarm information to
+   public, group, or resource calendars.
+
+

9. XML Element Definitions

+ +

9.1. CALDAV:calendar XML Element

+ + Name: calendar + + Namespace: urn:ietf:params:xml:ns:caldav + + Purpose: Specifies the resource type of a calendar collection. + + Description: See Section 4.2. + + Definition: + + <!ELEMENT calendar EMPTY> + +

9.2. CALDAV:mkcalendar XML Element

+ + Name: mkcalendar + + Namespace: urn:ietf:params:xml:ns:caldav + + Purpose: Specifies a request that includes the WebDAV property + values to be set for a calendar collection resource when it is + created. + + Description: See Section 5.3.1. + + Definition: + + <!ELEMENT mkcalendar (DAV:set)> + + + + + + + +Daboo, et al. Standards Track [Page 77] +

+RFC 4791                         CalDAV                       March 2007
+
+
+

9.3. CALDAV:mkcalendar-response XML Element

+ + Name: mkcalendar-response + + Namespace: urn:ietf:params:xml:ns:caldav + + Purpose: Specifies a response body for a successful MKCALENDAR + request. + + Description: See Section 5.3.1. + + Definition: + + <!ELEMENT mkcalendar-response ANY> + +

9.4. CALDAV:supported-collation XML Element

+ + Name: supported-collation + + Namespace: urn:ietf:params:xml:ns:caldav + + Purpose: Identifies a single collation via its collation identifier, + as defined by [RFC4790]. + + Description: The CALDAV:supported-collation contains the text of a + collation identifier, as described in Section 7.5.1. + + Definition: + + <!ELEMENT supported-collation (#PCDATA)> + PCDATA value: collation identifier + +

9.5. CALDAV:calendar-query XML Element

+ + Name: calendar-query + + Namespace: urn:ietf:params:xml:ns:caldav + + Purpose: Defines a report for querying calendar object resources. + + Description: See Section 7.8. + + Definition: + + <!ELEMENT calendar-query ((DAV:allprop | + DAV:propname | + DAV:prop)?, filter, timezone?)> + + + + +Daboo, et al. Standards Track [Page 78] +

+RFC 4791                         CalDAV                       March 2007
+
+
+

9.6. CALDAV:calendar-data XML Element

+ + Name: calendar-data + + Namespace: urn:ietf:params:xml:ns:caldav + + Purpose: Specified one of the following: + + 1. A supported media type for calendar object resources when + nested in the CALDAV:supported-calendar-data property; + + 2. The parts of a calendar object resource should be returned by + a calendaring report; + + 3. The content of a calendar object resource in a response to a + calendaring report. + + Description: When nested in the CALDAV:supported-calendar-data + property, the CALDAV:calendar-data XML element specifies a media + type supported by the CalDAV server for calendar object resources. + + When used in a calendaring REPORT request, the CALDAV:calendar- + data XML element specifies which parts of calendar object + resources need to be returned in the response. If the CALDAV: + calendar-data XML element doesn't contain any CALDAV:comp element, + calendar object resources will be returned in their entirety. + + Finally, when used in a calendaring REPORT response, the CALDAV: + calendar-data XML element specifies the content of a calendar + object resource. Given that XML parsers normalize the two- + character sequence CRLF (US-ASCII decimal 13 and US-ASCII decimal + 10) to a single LF character (US-ASCII decimal 10), the CR + character (US-ASCII decimal 13) MAY be omitted in calendar object + resources specified in the CALDAV:calendar-data XML element. + Furthermore, calendar object resources specified in the CALDAV: + calendar-data XML element MAY be invalid per their media type + specification if the CALDAV:calendar-data XML element part of the + calendaring REPORT request did not specify required properties + (e.g., UID, DTSTAMP, etc.), or specified a CALDAV:prop XML element + with the "novalue" attribute set to "yes". + + Note: The CALDAV:calendar-data XML element is specified in requests + and responses inside the DAV:prop XML element as if it were a + WebDAV property. However, the CALDAV:calendar-data XML element is + not a WebDAV property and, as such, is not returned in PROPFIND + responses, nor used in PROPPATCH requests. + + + + + +Daboo, et al. Standards Track [Page 79] +

+RFC 4791                         CalDAV                       March 2007
+
+
+   Note:  The iCalendar data embedded within the CALDAV:calendar-data
+      XML element MUST follow the standard XML character data encoding
+      rules, including use of &lt;, &gt;, &amp; etc. entity encoding or
+      the use of a <![CDATA[ ... ]]> construct.  In the later case, the
+      iCalendar data cannot contain the character sequence "]]>", which
+      is the end delimiter for the CDATA section.
+
+   Definition:
+
+         <!ELEMENT calendar-data EMPTY>
+
+         when nested in the CALDAV:supported-calendar-data property
+         to specify a supported media type for calendar object
+         resources;
+
+         <!ELEMENT calendar-data (comp?,
+                                  (expand | limit-recurrence-set)?,
+                                  limit-freebusy-set?)>
+
+         when nested in the DAV:prop XML element in a calendaring
+         REPORT request to specify which parts of calendar object
+         resources should be returned in the response;
+
+         <!ELEMENT calendar-data (#PCDATA)>
+         PCDATA value: iCalendar object
+
+         when nested in the DAV:prop XML element in a calendaring
+         REPORT response to specify the content of a returned
+         calendar object resource.
+
+         <!ATTLIST calendar-data content-type CDATA "text/calendar"
+                                 version CDATA "2.0">
+         content-type value: a MIME media type
+         version value: a version string
+
+         attributes can be used on all three variants of the
+         CALDAV:calendar-data XML element.
+
+

9.6.1. CALDAV:comp XML Element

+ + Name: comp + + Namespace: urn:ietf:params:xml:ns:caldav + + Purpose: Defines which component types to return. + + + + + + +Daboo, et al. Standards Track [Page 80] +

+RFC 4791                         CalDAV                       March 2007
+
+
+   Description:  The name value is a calendar component name (e.g.,
+      VEVENT).
+
+   Definition:
+
+         <!ELEMENT comp ((allprop | prop*), (allcomp | comp*))>
+
+         <!ATTLIST comp name CDATA #REQUIRED>
+         name value: a calendar component name
+
+   Note:  The CALDAV:prop and CALDAV:allprop elements have the same name
+      as the DAV:prop and DAV:allprop elements defined in [RFC2518].
+      However, the CALDAV:prop and CALDAV:allprop elements are defined
+      in the "urn:ietf:params:xml:ns:caldav" namespace instead of the
+      "DAV:" namespace.
+
+

9.6.2. CALDAV:allcomp XML Element

+ + Name: allcomp + + Namespace: urn:ietf:params:xml:ns:caldav + + Purpose: Specifies that all components shall be returned. + + Description: The CALDAV:allcomp XML element can be used when the + client wants all types of components returned by a calendaring + REPORT request. + + Definition: + + <!ELEMENT allcomp EMPTY> + +

9.6.3. CALDAV:allprop XML Element

+ + Name: allprop + + Namespace: urn:ietf:params:xml:ns:caldav + + Purpose: Specifies that all properties shall be returned. + + Description: The CALDAV:allprop XML element can be used when the + client wants all properties of components returned by a + calendaring REPORT request. + + Definition: + + <!ELEMENT allprop EMPTY> + + + + +Daboo, et al. Standards Track [Page 81] +

+RFC 4791                         CalDAV                       March 2007
+
+
+   Note:  The CALDAV:allprop element has the same name as the DAV:
+      allprop element defined in [RFC2518].  However, the CALDAV:allprop
+      element is defined in the "urn:ietf:params:xml:ns:caldav"
+      namespace instead of the "DAV:" namespace.
+
+

9.6.4. CALDAV:prop XML Element

+ + Name: prop + + Namespace: urn:ietf:params:xml:ns:caldav + + Purpose: Defines which properties to return in the response. + + Description: The "name" attribute specifies the name of the calendar + property to return (e.g., ATTENDEE). The "novalue" attribute can + be used by clients to request that the actual value of the + property not be returned (if the "novalue" attribute is set to + "yes"). In that case, the server will return just the iCalendar + property name and any iCalendar parameters and a trailing ":" + without the subsequent value data. + + Definition: + + <!ELEMENT prop EMPTY> + + <!ATTLIST prop name CDATA #REQUIRED + novalue (yes | no) "no"> + name value: a calendar property name + novalue value: "yes" or "no" + + Note: The CALDAV:prop element has the same name as the DAV:prop + element defined in [RFC2518]. However, the CALDAV:prop element is + defined in the "urn:ietf:params:xml:ns:caldav" namespace instead + of the "DAV:" namespace. + +

9.6.5. CALDAV:expand XML Element

+ + Name: expand + + Namespace: urn:ietf:params:xml:ns:caldav + + Purpose: Forces the server to expand recurring components into + individual recurrence instances. + + Description: The CALDAV:expand XML element specifies that for a + given calendaring REPORT request, the server MUST expand the + recurrence set into calendar components that define exactly one + + + + +Daboo, et al. Standards Track [Page 82] +

+RFC 4791                         CalDAV                       March 2007
+
+
+      recurrence instance, and MUST return only those whose scheduled
+      time intersect a specified time range.
+
+      The "start" attribute specifies the inclusive start of the time
+      range, and the "end" attribute specifies the non-inclusive end of
+      the time range.  Both attributes are specified as date with UTC
+      time value.  The value of the "end" attribute MUST be greater than
+      the value of the "start" attribute.
+
+      The server MUST use the same logic as defined for CALDAV:time-
+      range to determine if a recurrence instance intersects the
+      specified time range.
+
+      Recurring components, other than the initial instance, MUST
+      include a RECURRENCE-ID property indicating which instance they
+      refer to.
+
+      The returned calendar components MUST NOT use recurrence
+      properties (i.e., EXDATE, EXRULE, RDATE, and RRULE) and MUST NOT
+      have reference to or include VTIMEZONE components.  Date and local
+      time with reference to time zone information MUST be converted
+      into date with UTC time.
+
+   Definition:
+
+         <!ELEMENT expand EMPTY>
+
+         <!ATTLIST expand start CDATA #REQUIRED
+                          end   CDATA #REQUIRED>
+         start value: an iCalendar "date with UTC time"
+         end value: an iCalendar "date with UTC time"
+
+

9.6.6. CALDAV:limit-recurrence-set XML Element

+ + Name: limit-recurrence-set + + Namespace: urn:ietf:params:xml:ns:caldav + + Purpose: Specifies a time range to limit the set of "overridden + components" returned by the server. + + Description: The CALDAV:limit-recurrence-set XML element specifies + that for a given calendaring REPORT request, the server MUST + return, in addition to the "master component", only the + "overridden components" that impact a specified time range. An + overridden component impacts a time range if its current start and + end times overlap the time range, or if the original start and end + + + + +Daboo, et al. Standards Track [Page 83] +

+RFC 4791                         CalDAV                       March 2007
+
+
+      times -- the ones that would have been used if the instance were
+      not overridden -- overlap the time range.
+
+      The "start" attribute specifies the inclusive start of the time
+      range, and the "end" attribute specifies the non-inclusive end of
+      the time range.  Both attributes are specified as date with UTC
+      time value.  The value of the "end" attribute MUST be greater than
+      the value of the "start" attribute.
+
+      The server MUST use the same logic as defined for CALDAV:time-
+      range to determine if the current or original scheduled time of an
+      "overridden" recurrence instance intersects the specified time
+      range.
+
+      Overridden components that have a RANGE parameter on their
+      RECURRENCE-ID property may specify one or more instances in the
+      recurrence set, and some of those instances may fall within the
+      specified time range or may have originally fallen within the
+      specified time range prior to being overridden.  If that is the
+      case, the overridden component MUST be included in the results, as
+      it has a direct impact on the interpretation of instances within
+      the specified time range.
+
+   Definition:
+
+         <!ELEMENT limit-recurrence-set EMPTY>
+
+         <!ATTLIST limit-recurrence-set start CDATA #REQUIRED
+                                        end   CDATA #REQUIRED>
+         start value: an iCalendar "date with UTC time"
+         end value: an iCalendar "date with UTC time"
+
+

9.6.7. CALDAV:limit-freebusy-set XML Element

+ + Name: limit-freebusy-set + + Namespace: urn:ietf:params:xml:ns:caldav + + Purpose: Specifies a time range to limit the set of FREEBUSY values + returned by the server. + + Description: The CALDAV:limit-freebusy-set XML element specifies + that for a given calendaring REPORT request, the server MUST only + return the FREEBUSY property values of a VFREEBUSY component that + intersects a specified time range. + + The "start" attribute specifies the inclusive start of the time + range, and the "end" attribute specifies the non-inclusive end of + + + +Daboo, et al. Standards Track [Page 84] +

+RFC 4791                         CalDAV                       March 2007
+
+
+      the time range.  Both attributes are specified as "date with UTC
+      time" value.  The value of the "end" attribute MUST be greater
+      than the value of the "start" attribute.
+
+      The server MUST use the same logic as defined for CALDAV:time-
+      range to determine if a FREEBUSY property value intersects the
+      specified time range.
+
+   Definition:
+
+         <!ELEMENT limit-freebusy-set EMPTY>
+
+         <!ATTLIST limit-freebusy-set start CDATA #REQUIRED
+                                      end   CDATA #REQUIRED>
+         start value: an iCalendar "date with UTC time"
+         end value: an iCalendar "date with UTC time"
+
+

9.7. CALDAV:filter XML Element

+ + Name: filter + + Namespace: urn:ietf:params:xml:ns:caldav + + Purpose: Specifies a filter to limit the set of calendar components + returned by the server. + + Description: The CALDAV:filter XML element specifies the search + filter used to limit the calendar components returned by a + calendaring REPORT request. + + Definition: + + <!ELEMENT filter (comp-filter)> + +

9.7.1. CALDAV:comp-filter XML Element

+ + Name: comp-filter + + Namespace: urn:ietf:params:xml:ns:caldav + + Purpose: Specifies search criteria on calendar components. + + Description: The CALDAV:comp-filter XML element specifies a query + targeted at the calendar object (i.e., VCALENDAR) or at a specific + calendar component type (e.g., VEVENT). The scope of the + CALDAV:comp-filter XML element is the calendar object when used as + a child of the CALDAV:filter XML element. The scope of the + CALDAV:comp-filter XML element is the enclosing calendar component + + + +Daboo, et al. Standards Track [Page 85] +

+RFC 4791                         CalDAV                       March 2007
+
+
+      when used as a child of another CALDAV:comp-filter XML element.  A
+      CALDAV:comp-filter is said to match if:
+
+      *  The CALDAV:comp-filter XML element is empty and the calendar
+         object or calendar component type specified by the "name"
+         attribute exists in the current scope;
+
+      or:
+
+      *  The CALDAV:comp-filter XML element contains a CALDAV:is-not-
+         defined XML element and the calendar object or calendar
+         component type specified by the "name" attribute does not exist
+         in the current scope;
+
+      or:
+
+      *  The CALDAV:comp-filter XML element contains a CALDAV:time-range
+         XML element and at least one recurrence instance in the
+         targeted calendar component is scheduled to overlap the
+         specified time range, and all specified CALDAV:prop-filter and
+         CALDAV:comp-filter child XML elements also match the targeted
+         calendar component;
+
+      or:
+
+      *  The CALDAV:comp-filter XML element only contains CALDAV:prop-
+         filter and CALDAV:comp-filter child XML elements that all match
+         the targeted calendar component.
+
+   Definition:
+
+         <!ELEMENT comp-filter (is-not-defined | (time-range?,
+                                prop-filter*, comp-filter*))>
+
+         <!ATTLIST comp-filter name CDATA #REQUIRED>
+         name value: a calendar object or calendar component
+                     type (e.g., VEVENT)
+
+

9.7.2. CALDAV:prop-filter XML Element

+ + Name: prop-filter + + Namespace: urn:ietf:params:xml:ns:caldav + + Purpose: Specifies search criteria on calendar properties. + + Description: The CALDAV:prop-filter XML element specifies a query + targeted at a specific calendar property (e.g., CATEGORIES) in the + + + +Daboo, et al. Standards Track [Page 86] +

+RFC 4791                         CalDAV                       March 2007
+
+
+      scope of the enclosing calendar component.  A calendar property is
+      said to match a CALDAV:prop-filter if:
+
+      *  The CALDAV:prop-filter XML element is empty and a property of
+         the type specified by the "name" attribute exists in the
+         enclosing calendar component;
+
+      or:
+
+      *  The CALDAV:prop-filter XML element contains a CALDAV:is-not-
+         defined XML element and no property of the type specified by
+         the "name" attribute exists in the enclosing calendar
+         component;
+
+      or:
+
+      *  The CALDAV:prop-filter XML element contains a CALDAV:time-range
+         XML element and the property value overlaps the specified time
+         range, and all specified CALDAV:param-filter child XML elements
+         also match the targeted property;
+
+      or:
+
+      *  The CALDAV:prop-filter XML element contains a CALDAV:text-match
+         XML element and the property value matches it, and all
+         specified CALDAV:param-filter child XML elements also match the
+         targeted property;
+
+   Definition:
+
+         <!ELEMENT prop-filter (is-not-defined |
+                                ((time-range | text-match)?,
+                                 param-filter*))>
+
+         <!ATTLIST prop-filter name CDATA #REQUIRED>
+         name value: a calendar property name (e.g., ATTENDEE)
+
+

9.7.3. CALDAV:param-filter XML Element

+ + Name: param-filter + + Namespace: urn:ietf:params:xml:ns:caldav + + Purpose: Limits the search to specific parameter values. + + Description: The CALDAV:param-filter XML element specifies a query + targeted at a specific calendar property parameter (e.g., + PARTSTAT) in the scope of the calendar property on which it is + + + +Daboo, et al. Standards Track [Page 87] +

+RFC 4791                         CalDAV                       March 2007
+
+
+      defined.  A calendar property parameter is said to match a CALDAV:
+      param-filter if:
+
+      *  The CALDAV:param-filter XML element is empty and a parameter of
+         the type specified by the "name" attribute exists on the
+         calendar property being examined;
+
+      or:
+
+      *  The CALDAV:param-filter XML element contains a CALDAV:is-not-
+         defined XML element and no parameter of the type specified by
+         the "name" attribute exists on the calendar property being
+         examined;
+
+   Definition:
+
+         <!ELEMENT param-filter (is-not-defined | text-match?)>
+
+         <!ATTLIST param-filter name CDATA #REQUIRED>
+         name value: a property parameter name (e.g., PARTSTAT)
+
+

9.7.4. CALDAV:is-not-defined XML Element

+ + Name: is-not-defined + + Namespace: urn:ietf:params:xml:ns:caldav + + Purpose: Specifies that a match should occur if the enclosing + component, property, or parameter does not exist. + + Description: The CALDAV:is-not-defined XML element specifies that a + match occurs if the enclosing component, property, or parameter + value specified in a calendaring REPORT request does not exist in + the calendar data being tested. + + Definition: + + <!ELEMENT is-not-defined EMPTY> + +

9.7.5. CALDAV:text-match XML Element

+ + Name: text-match + + Namespace: urn:ietf:params:xml:ns:caldav + + Purpose: Specifies a substring match on a property or parameter + value. + + + + +Daboo, et al. Standards Track [Page 88] +

+RFC 4791                         CalDAV                       March 2007
+
+
+   Description:  The CALDAV:text-match XML element specifies text used
+      for a substring match against the property or parameter value
+      specified in a calendaring REPORT request.
+
+      The "collation" attribute is used to select the collation that the
+      server MUST use for character string matching.  In the absence of
+      this attribute, the server MUST use the "i;ascii-casemap"
+      collation.
+
+      The "negate-condition" attribute is used to indicate that this
+      test returns a match if the text matches when the attribute value
+      is set to "no", or return a match if the text does not match, if
+      the attribute value is set to "yes".  For example, this can be
+      used to match components with a STATUS property not set to
+      CANCELLED.
+
+   Definition:
+
+         <!ELEMENT text-match (#PCDATA)>
+         PCDATA value: string
+
+         <!ATTLIST text-match collation        CDATA "i;ascii-casemap"
+                              negate-condition (yes | no) "no">
+
+

9.8. CALDAV:timezone XML Element

+ + Name: timezone + + Namespace: urn:ietf:params:xml:ns:caldav + + Purpose: Specifies the time zone component to use when determining + the results of a report. + + Description: The CALDAV:timezone XML element specifies that for a + given calendaring REPORT request, the server MUST rely on the + specified VTIMEZONE component instead of the CALDAV:calendar- + timezone property of the calendar collection, in which the + calendar object resource is contained to resolve "date" values and + "date with local time" values (i.e., floating time) to "date with + UTC time" values. The server will require this information to + determine if a calendar component scheduled with "date" values or + "date with local time" values intersects a CALDAV:time-range + specified in a CALDAV:calendar-query REPORT. + + Note: The iCalendar data embedded within the CALDAV:timezone XML + element MUST follow the standard XML character data encoding + rules, including use of &lt;, &gt;, &amp; etc. entity encoding or + the use of a <![CDATA[ ... ]]> construct. In the later case, the + + + +Daboo, et al. Standards Track [Page 89] +

+RFC 4791                         CalDAV                       March 2007
+
+
+      iCalendar data cannot contain the character sequence "]]>", which
+      is the end delimiter for the CDATA section.
+
+   Definition:
+
+         <!ELEMENT timezone (#PCDATA)>
+         PCDATA value: an iCalendar object with exactly one VTIMEZONE
+
+

9.9. CALDAV:time-range XML Element

+ + Name: time-range + + Namespace: urn:ietf:params:xml:ns:caldav + + Purpose: Specifies a time range to limit the set of calendar + components returned by the server. + + Description: The CALDAV:time-range XML element specifies that for a + given calendaring REPORT request, the server MUST only return the + calendar object resources that, depending on the context, have a + component or property whose value intersects a specified time + range. + + The "start" attribute specifies the inclusive start of the time + range, and the "end" attribute specifies the non-inclusive end of + the time range. Both attributes MUST be specified as "date with + UTC time" value. Time ranges open at one end can be specified by + including only one attribute; however, at least one attribute MUST + always be present in the CALDAV:time-range element. If either the + "start" or "end" attribute is not specified in the CALDAV:time- + range XML element, assume "-infinity" and "+infinity" as their + value, respectively. If both "start" and "end" are present, the + value of the "end" attribute MUST be greater than the value of the + "start" attribute. + + Time range tests MUST consider every recurrence instance when + testing the time range condition; if any one instance matches, + then the test returns true. Testing recurrence instances requires + the server to infer an effective value for DTSTART, DTEND, + DURATION, and DUE properties for an instance based on the + recurrence patterns and any overrides. + + A VEVENT component overlaps a given time range if the condition + for the corresponding component state specified in the table below + is satisfied. Note that, as specified in [RFC2445], the DTSTART + property is REQUIRED in the VEVENT component. The conditions + depend on the presence of the DTEND and DURATION properties in the + VEVENT component. Furthermore, the value of the DTEND property + + + +Daboo, et al. Standards Track [Page 90] +

+RFC 4791                         CalDAV                       March 2007
+
+
+      MUST be later in time than the value of the DTSTART property.  The
+      duration of a VEVENT component with no DTEND and DURATION
+      properties is 1 day (+P1D) when the DTSTART is a DATE value, and 0
+      seconds when the DTSTART is a DATE-TIME value.
+
+      +---------------------------------------------------------------+
+      | VEVENT has the DTEND property?                                |
+      |   +-----------------------------------------------------------+
+      |   | VEVENT has the DURATION property?                         |
+      |   |   +-------------------------------------------------------+
+      |   |   | DURATION property value is greater than 0 seconds?    |
+      |   |   |   +---------------------------------------------------+
+      |   |   |   | DTSTART property is a DATE-TIME value?            |
+      |   |   |   |   +-----------------------------------------------+
+      |   |   |   |   | Condition to evaluate                         |
+      +---+---+---+---+-----------------------------------------------+
+      | Y | N | N | * | (start <  DTEND AND end > DTSTART)            |
+      +---+---+---+---+-----------------------------------------------+
+      | N | Y | Y | * | (start <  DTSTART+DURATION AND end > DTSTART) |
+      |   |   +---+---+-----------------------------------------------+
+      |   |   | N | * | (start <= DTSTART AND end > DTSTART)          |
+      +---+---+---+---+-----------------------------------------------+
+      | N | N | N | Y | (start <= DTSTART AND end > DTSTART)          |
+      +---+---+---+---+-----------------------------------------------+
+      | N | N | N | N | (start <  DTSTART+P1D AND end > DTSTART)      |
+      +---+---+---+---+-----------------------------------------------+
+
+      A VTODO component is said to overlap a given time range if the
+      condition for the corresponding component state specified in the
+      table below is satisfied.  The conditions depend on the presence
+      of the DTSTART, DURATION, DUE, COMPLETED, and CREATED properties
+      in the VTODO component.  Note that, as specified in [RFC2445], the
+      DUE value MUST be a DATE-TIME value equal to or after the DTSTART
+      value if specified.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Daboo, et al.               Standards Track                    [Page 91]
+

+RFC 4791                         CalDAV                       March 2007
+
+
+   +-------------------------------------------------------------------+
+   | VTODO has the DTSTART property?                                   |
+   |   +---------------------------------------------------------------+
+   |   |   VTODO has the DURATION property?                            |
+   |   |   +-----------------------------------------------------------+
+   |   |   | VTODO has the DUE property?                               |
+   |   |   |   +-------------------------------------------------------+
+   |   |   |   | VTODO has the COMPLETED property?                     |
+   |   |   |   |   +---------------------------------------------------+
+   |   |   |   |   | VTODO has the CREATED property?                   |
+   |   |   |   |   |   +-----------------------------------------------+
+   |   |   |   |   |   | Condition to evaluate                         |
+   +---+---+---+---+---+-----------------------------------------------+
+   | Y | Y | N | * | * | (start  <= DTSTART+DURATION)  AND             |
+   |   |   |   |   |   | ((end   >  DTSTART)  OR                       |
+   |   |   |   |   |   |  (end   >= DTSTART+DURATION))                 |
+   +---+---+---+---+---+-----------------------------------------------+
+   | Y | N | Y | * | * | ((start <  DUE)      OR  (start <= DTSTART))  |
+   |   |   |   |   |   | AND                                           |
+   |   |   |   |   |   | ((end   >  DTSTART)  OR  (end   >= DUE))      |
+   +---+---+---+---+---+-----------------------------------------------+
+   | Y | N | N | * | * | (start  <= DTSTART)  AND (end >  DTSTART)     |
+   +---+---+---+---+---+-----------------------------------------------+
+   | N | N | Y | * | * | (start  <  DUE)      AND (end >= DUE)         |
+   +---+---+---+---+---+-----------------------------------------------+
+   | N | N | N | Y | Y | ((start <= CREATED)  OR  (start <= COMPLETED))|
+   |   |   |   |   |   | AND                                           |
+   |   |   |   |   |   | ((end   >= CREATED)  OR  (end   >= COMPLETED))|
+   +---+---+---+---+---+-----------------------------------------------+
+   | N | N | N | Y | N | (start  <= COMPLETED) AND (end  >= COMPLETED) |
+   +---+---+---+---+---+-----------------------------------------------+
+   | N | N | N | N | Y | (end    >  CREATED)                           |
+   +---+---+---+---+---+-----------------------------------------------+
+   | N | N | N | N | N | TRUE                                          |
+   +---+---+---+---+---+-----------------------------------------------+
+
+      A VJOURNAL component overlaps a given time range if the condition
+      for the corresponding component state specified in the table below
+      is satisfied.  The conditions depend on the presence of the
+      DTSTART property in the VJOURNAL component and on whether the
+      DTSTART is a DATE-TIME or DATE value.  The effective "duration" of
+      a VJOURNAL component is 1 day (+P1D) when the DTSTART is a DATE
+      value, and 0 seconds when the DTSTART is a DATE-TIME value.
+
+
+
+
+
+
+
+
+Daboo, et al.               Standards Track                    [Page 92]
+

+RFC 4791                         CalDAV                       March 2007
+
+
+      +----------------------------------------------------+
+      | VJOURNAL has the DTSTART property?                 |
+      |   +------------------------------------------------+
+      |   | DTSTART property is a DATE-TIME value?         |
+      |   |   +--------------------------------------------+
+      |   |   | Condition to evaluate                      |
+      +---+---+--------------------------------------------+
+      | Y | Y | (start <= DTSTART)     AND (end > DTSTART) |
+      +---+---+--------------------------------------------+
+      | Y | N | (start <  DTSTART+P1D) AND (end > DTSTART) |
+      +---+---+--------------------------------------------+
+      | N | * | FALSE                                      |
+      +---+---+--------------------------------------------+
+
+      A VFREEBUSY component overlaps a given time range if the condition
+      for the corresponding component state specified in the table below
+      is satisfied.  The conditions depend on the presence in the
+      VFREEBUSY component of the DTSTART and DTEND properties, and any
+      FREEBUSY properties in the absence of DTSTART and DTEND.  Any
+      DURATION property is ignored, as it has a special meaning when
+      used in a VFREEBUSY component.
+
+      When only FREEBUSY properties are used, each period in each
+      FREEBUSY property is compared against the time range, irrespective
+      of the type of free busy information (free, busy, busy-tentative,
+      busy-unavailable) represented by the property.
+
+
+      +------------------------------------------------------+
+      | VFREEBUSY has both the DTSTART and DTEND properties? |
+      |   +--------------------------------------------------+
+      |   | VFREEBUSY has the FREEBUSY property?             |
+      |   |   +----------------------------------------------+
+      |   |   | Condition to evaluate                        |
+      +---+---+----------------------------------------------+
+      | Y | * | (start <= DTEND) AND (end > DTSTART)         |
+      +---+---+----------------------------------------------+
+      | N | Y | (start <  freebusy-period-end) AND           |
+      |   |   | (end   >  freebusy-period-start)             |
+      +---+---+----------------------------------------------+
+      | N | N | FALSE                                        |
+      +---+---+----------------------------------------------+
+
+      A VALARM component is said to overlap a given time range if the
+      following condition holds:
+
+         (start <= trigger-time) AND (end > trigger-time)
+
+
+
+
+Daboo, et al.               Standards Track                    [Page 93]
+

+RFC 4791                         CalDAV                       March 2007
+
+
+   A VALARM component can be defined such that it triggers repeatedly.
+   Such a VALARM component is said to overlap a given time range if at
+   least one of its triggers overlaps the time range.
+
+      The calendar properties COMPLETED, CREATED, DTEND, DTSTAMP,
+      DTSTART, DUE, and LAST-MODIFIED overlap a given time range if the
+      following condition holds:
+
+          (start <= date-time) AND (end > date-time)
+
+   Note that if DTEND is not present in a VEVENT, but DURATION is, then
+   the test should instead operate on the 'effective' DTEND, i.e.,
+   DTSTART+DURATION.  Similarly, if DUE is not present in a VTODO, but
+   DTSTART and DURATION are, then the test should instead operate on the
+   'effective' DUE, i.e., DTSTART+DURATION.
+
+      The semantic of CALDAV:time-range is not defined for any other
+      calendar components and properties.
+
+   Definition:
+
+         <!ELEMENT time-range EMPTY>
+
+         <!ATTLIST time-range start CDATA #IMPLIED
+                              end   CDATA #IMPLIED>
+         start value: an iCalendar "date with UTC time"
+         end value: an iCalendar "date with UTC time"
+
+

9.10. CALDAV:calendar-multiget XML Element

+ + Name: calendar-multiget + + Namespace: urn:ietf:params:xml:ns:caldav + + Purpose: CalDAV report used to retrieve specific calendar object + resources. + + Description: See Section 7.9. + + Definition: + + <!ELEMENT calendar-multiget ((DAV:allprop | + DAV:propname | + DAV:prop)?, DAV:href+)> + + + + + + + +Daboo, et al. Standards Track [Page 94] +

+RFC 4791                         CalDAV                       March 2007
+
+
+

9.11. CALDAV:free-busy-query XML Element

+ + Name: free-busy-query + + Namespace: urn:ietf:params:xml:ns:caldav + + Purpose: CalDAV report used to generate a VFREEBUSY to determine + busy time over a specific time range. + + Description: See Section 7.10. + + Definition: + + <!ELEMENT free-busy-query (time-range)> + +

10. Internationalization Considerations

+ + CalDAV allows internationalized strings to be stored and retrieved + for the description of calendar collections (see Section 5.2.1). + + The CALDAV:calendar-query REPORT (Section 7.8) includes a text + searching option controlled by the CALDAV:text-match element, and + details of character handling are covered in the description of that + element (see Section 9.7.5). + +

11. Security Considerations

+ + HTTP protocol transactions are sent in the clear over the network + unless protection from snooping is negotiated. This can be + accomplished by use of TLS, as defined in [RFC2818]. In particular, + HTTP Basic authentication MUST NOT be used unless TLS is in effect. + + Servers MUST take adequate precautions to ensure that malicious + clients cannot consume excessive server resources (CPU, memory, disk, + etc.) through carefully crafted reports. For example, a client could + upload an event with a recurrence rule that specifies a recurring + event occurring every second for the next 100 years, which would + result in approximately 3 x 10^9 instances! A report that asks for + recurrences to be expanded over that range would likely constitute a + denial-of-service attack on the server. + + When creating new resources (including calendar collections), clients + MUST ensure that the resource name (the last path segment of the + resource URI) assigned to the new resource does not expose any data + from within the iCalendar resource itself or information about the + nature of a calendar collection. This is required to ensure that the + presence of a specific iCalendar component or nature of components in + a collection cannot be inferred based on the name of a resource. + + + +Daboo, et al. Standards Track [Page 95] +

+RFC 4791                         CalDAV                       March 2007
+
+
+   When rolling up free-busy information, more information about a
+   user's events is exposed if busy periods overlap or are adjacent
+   (this tells the client requesting the free-busy information that the
+   calendar owner has at least two events, rather than knowing only that
+   the calendar owner has one or more events during the busy period).
+   Thus, a conservative approach to calendar data privacy would have
+   servers always coalesce such busy periods when they are the same
+   type.
+
+   Procedure alarms are a known security risk for either clients or
+   servers to handle, particularly when the alarm was created by another
+   agent.  Clients and servers are not required to execute such
+   procedure alarms.
+
+   Security considerations described in iCalendar [RFC2445] and iTIP
+   [RFC2446] are also applicable to CalDAV.
+
+   Beyond these, CalDAV does not raise any security considerations that
+   are not present in HTTP [RFC2616] and WebDAV [RFC2518], [RFC3253],
+   [RFC3744].
+
+

12. IANA Considerations

+ + This document uses one new URN to identify a new XML namespace. The + URN conforms to a registry mechanism described in [RFC3688]. + +

12.1. Namespace Registration

+ + Registration request for the CalDAV namespace: + + URI: urn:ietf:params:xml:ns:caldav + + Registrant Contact: See the "Authors' Addresses" section of this + document. + + XML: None. Namespace URIs do not represent an XML specification. + +

13. Acknowledgements

+ + The authors would like to thank the following individuals for + contributing their ideas and support for writing this specification: + Michael Arick, Mario Bonin, Chris Bryant, Scott Carr, Andre + Courtemanche, Mike Douglass, Ted Hardie, Marten den Haring, Jeffrey + Harris, Sam Hartman, Helge Hess, Jeff McCullough, Alexey Melnikov, + Dan Mosedale, Brian Moseley, Francois Perrault, Kervin L. Pierre, + Julian F. Reschke, Wilfredo Sanchez Vega, Mike Shaver, Jari + Urpalainen, Simon Vaillancourt, and Jim Whitehead. + + + + +Daboo, et al. Standards Track [Page 96] +

+RFC 4791                         CalDAV                       March 2007
+
+
+   The authors would also like to thank the Calendaring and Scheduling
+   Consortium for advice with this specification, and for organizing
+   interoperability testing events to help refine it.
+
+

14. References

+ +

14.1. Normative References

+ + [RFC2119] Bradner, S., "Key words for use in RFCs to + Indicate Requirement Levels", BCP 14, + RFC 2119, March 1997. + + [RFC2246] Dierks, T. and C. Allen, "The TLS Protocol + Version 1.0", RFC 2246, January 1999. + + [RFC2445] Dawson, F. and Stenerson, D., "Internet + Calendaring and Scheduling Core Object + Specification (iCalendar)", RFC 2445, + November 1998. + + [RFC2446] Silverberg, S., Mansour, S., Dawson, F., and + R. Hopson, "iCalendar Transport-Independent + Interoperability Protocol (iTIP) Scheduling + Events, BusyTime, To-dos and Journal + Entries", RFC 2446, November 1998. + + [RFC2518] Goland, Y., Whitehead, E., Faizi, A., Carter, + S., and D. Jensen, "HTTP Extensions for + Distributed Authoring -- WEBDAV", RFC 2518, + February 1999. + + [RFC2616] Fielding, R., Gettys, J., Mogul, J., Frystyk, + H., Masinter, L., Leach, P., and T. Berners- + Lee, "Hypertext Transfer Protocol -- + HTTP/1.1", RFC 2616, June 1999. + + [RFC2818] Rescorla, E., "HTTP Over TLS", RFC 2818, + May 2000. + + [RFC3253] Clemm, G., Amsden, J., Ellison, T., Kaler, + C., and J. Whitehead, "Versioning Extensions + to WebDAV (Web Distributed Authoring and + Versioning)", RFC 3253, March 2002. + + [RFC3688] Mealling, M., "The IETF XML Registry", + BCP 81, RFC 3688, January 2004. + + + + + +Daboo, et al. Standards Track [Page 97] +

+RFC 4791                         CalDAV                       March 2007
+
+
+   [RFC3744]               Clemm, G., Reschke, J., Sedlar, E., and J.
+                           Whitehead, "Web Distributed Authoring and
+                           Versioning (WebDAV) Access Control Protocol",
+                           RFC 3744, May 2004.
+
+   [RFC4346]               Dierks, T. and E. Rescorla, "The Transport
+                           Layer Security (TLS) Protocol Version 1.1",
+                           RFC 4346, April 2006.
+
+   [RFC4790]               Newman, C., Duerst, M., and A. Gulbrandsen,
+                           "Internet Application Protocol Collation
+                           Registry", RFC 4790, March 2007.
+
+   [W3C.REC-xml-20060816]  Paoli, J., Maler, E., Yergeau, F., Sperberg-
+                           McQueen, C., and T. Bray, "Extensible Markup
+                           Language (XML) 1.0 (Fourth Edition)", World
+                           Wide Web Consortium Recommendation REC-xml-
+                           20060816, August 2006,
+                           <http://www.w3.org/TR/2006/REC-xml-20060816>.
+
+

14.2. Informative References

+ + [RFC2426] Dawson, F. and T. Howes, "vCard MIME + Directory Profile", RFC 2426, September 1998. + + [RFC2739] Small, T., Hennessy, D., and F. Dawson, + "Calendar Attributes for vCard and LDAP", + RFC 2739, January 2000. + + [RFC4331] Korver, B. and L. Dusseault, "Quota and Size + Properties for Distributed Authoring and + Versioning (DAV) Collections", RFC 4331, + February 2006. + + [RFC4511] Sermersheim, J., "Lightweight Directory + Access Protocol (LDAP): The Protocol", + RFC 4511, June 2006. + + [rfc2518bis] Dusseault, L., "HTTP Extensions for + Distributed Authoring - WebDAV", Work + in Progress, December 2006. + + + + + + + + + + +Daboo, et al. Standards Track [Page 98] +

+RFC 4791                         CalDAV                       March 2007
+
+
+

Appendix A. CalDAV Method Privilege Table (Normative)

+ + The following table extends the WebDAV Method Privilege Table + specified in Appendix B of [RFC3744]. + + +------------+------------------------------------------------------+ + | METHOD | PRIVILEGES | + +------------+------------------------------------------------------+ + | MKCALENDAR | DAV:bind | + | REPORT | DAV:read or CALDAV:read-free-busy (on all referenced | + | | resources) | + +------------+------------------------------------------------------+ + +

Appendix B. Calendar Collections Used in the Examples

+ + This appendix shows the calendar object resources contained in the + calendar collection queried in the examples throughout this document. + + The content of the calendar collection is being shown as if it were + returned by a CALDAV:calendar-query REPORT request designed to return + all the calendar data in the collection: + + >> Request << + + REPORT /bernard/work/ HTTP/1.1 + Host: cal.example.com + Depth: 1 + Content-Type: application/xml; charset="utf-8" + Content-Length: xxxx + + <?xml version="1.0" encoding="utf-8" ?> + <C:calendar-query xmlns:D="DAV:" + xmlns:C="urn:ietf:params:xml:ns:caldav"> + <D:prop> + <D:getetag/> + <C:calendar-data/> + </D:prop> + <C:filter> + <C:comp-filter name="VCALENDAR"/> + </C:filter> + </C:calendar-query> + + >> Response << + + HTTP/1.1 207 Multi-Status + Content-Type: application/xml; charset="utf-8" + Content-Length: xxxx + + + + +Daboo, et al. Standards Track [Page 99] +

+RFC 4791                         CalDAV                       March 2007
+
+
+   <?xml version="1.0" encoding="utf-8" ?>
+   <D:multistatus xmlns:D="DAV:"
+                 xmlns:C="urn:ietf:params:xml:ns:caldav">
+
+     <D:response>
+       <D:href>http://cal.example.com/bernard/work/abcd1.ics</D:href>
+       <D:propstat>
+         <D:prop>
+           <D:getetag>"fffff-abcd1"</D:getetag>
+           <C:calendar-data>BEGIN:VCALENDAR
+   VERSION:2.0
+   PRODID:-//Example Corp.//CalDAV Client//EN
+   BEGIN:VTIMEZONE
+   LAST-MODIFIED:20040110T032845Z
+   TZID:US/Eastern
+   BEGIN:DAYLIGHT
+   DTSTART:20000404T020000
+   RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
+   TZNAME:EDT
+   TZOFFSETFROM:-0500
+   TZOFFSETTO:-0400
+   END:DAYLIGHT
+   BEGIN:STANDARD
+   DTSTART:20001026T020000
+   RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
+   TZNAME:EST
+   TZOFFSETFROM:-0400
+   TZOFFSETTO:-0500
+   END:STANDARD
+   END:VTIMEZONE
+   BEGIN:VEVENT
+   DTSTAMP:20060206T001102Z
+   DTSTART;TZID=US/Eastern:20060102T100000
+   DURATION:PT1H
+   SUMMARY:Event #1
+   Description:Go Steelers!
+   UID:74855313FA803DA593CD579A@example.com
+   END:VEVENT
+   END:VCALENDAR
+   </C:calendar-data>
+         </D:prop>
+         <D:status>HTTP/1.1 200 OK</D:status>
+       </D:propstat>
+     </D:response>
+
+     <D:response>
+       <D:href>http://cal.example.com/bernard/work/abcd2.ics</D:href>
+       <D:propstat>
+
+
+
+Daboo, et al.               Standards Track                   [Page 100]
+

+RFC 4791                         CalDAV                       March 2007
+
+
+         <D:prop>
+           <D:getetag>"fffff-abcd2"</D:getetag>
+           <C:calendar-data>BEGIN:VCALENDAR
+   VERSION:2.0
+   PRODID:-//Example Corp.//CalDAV Client//EN
+   BEGIN:VTIMEZONE
+   LAST-MODIFIED:20040110T032845Z
+   TZID:US/Eastern
+   BEGIN:DAYLIGHT
+   DTSTART:20000404T020000
+   RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
+   TZNAME:EDT
+   TZOFFSETFROM:-0500
+   TZOFFSETTO:-0400
+   END:DAYLIGHT
+   BEGIN:STANDARD
+   DTSTART:20001026T020000
+   RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
+   TZNAME:EST
+   TZOFFSETFROM:-0400
+   TZOFFSETTO:-0500
+   END:STANDARD
+   END:VTIMEZONE
+   BEGIN:VEVENT
+   DTSTAMP:20060206T001121Z
+   DTSTART;TZID=US/Eastern:20060102T120000
+   DURATION:PT1H
+   RRULE:FREQ=DAILY;COUNT=5
+   SUMMARY:Event #2
+   UID:00959BC664CA650E933C892C@example.com
+   END:VEVENT
+   BEGIN:VEVENT
+   DTSTAMP:20060206T001121Z
+   DTSTART;TZID=US/Eastern:20060104T140000
+   DURATION:PT1H
+   RECURRENCE-ID;TZID=US/Eastern:20060104T120000
+   SUMMARY:Event #2 bis
+   UID:00959BC664CA650E933C892C@example.com
+   END:VEVENT
+   END:VCALENDAR
+   </C:calendar-data>
+         </D:prop>
+         <D:status>HTTP/1.1 200 OK</D:status>
+       </D:propstat>
+     </D:response>
+
+     <D:response>
+       <D:href>http://cal.example.com/bernard/work/abcd3.ics</D:href>
+
+
+
+Daboo, et al.               Standards Track                   [Page 101]
+

+RFC 4791                         CalDAV                       March 2007
+
+
+       <D:propstat>
+         <D:prop>
+           <D:getetag>"fffff-abcd3"</D:getetag>
+           <C:calendar-data>BEGIN:VCALENDAR
+   VERSION:2.0
+   PRODID:-//Example Corp.//CalDAV Client//EN
+   BEGIN:VTIMEZONE
+   LAST-MODIFIED:20040110T032845Z
+   TZID:US/Eastern
+   BEGIN:DAYLIGHT
+   DTSTART:20000404T020000
+   RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
+   TZNAME:EDT
+   TZOFFSETFROM:-0500
+   TZOFFSETTO:-0400
+   END:DAYLIGHT
+   BEGIN:STANDARD
+   DTSTART:20001026T020000
+   RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
+   TZNAME:EST
+   TZOFFSETFROM:-0400
+   TZOFFSETTO:-0500
+   END:STANDARD
+   END:VTIMEZONE
+   BEGIN:VEVENT
+   ATTENDEE;PARTSTAT=ACCEPTED;ROLE=CHAIR:mailto:cyrus@example.com
+   ATTENDEE;PARTSTAT=NEEDS-ACTION:mailto:lisa@example.com
+   DTSTAMP:20060206T001220Z
+   DTSTART;TZID=US/Eastern:20060104T100000
+   DURATION:PT1H
+   LAST-MODIFIED:20060206T001330Z
+   ORGANIZER:mailto:cyrus@example.com
+   SEQUENCE:1
+   STATUS:TENTATIVE
+   SUMMARY:Event #3
+   UID:DC6C50A017428C5216A2F1CD@example.com
+   END:VEVENT
+   END:VCALENDAR
+   </C:calendar-data>
+         </D:prop>
+         <D:status>HTTP/1.1 200 OK</D:status>
+       </D:propstat>
+     </D:response>
+
+     <D:response>
+       <D:href>http://cal.example.com/bernard/work/abcd4.ics</D:href>
+       <D:propstat>
+         <D:prop>
+
+
+
+Daboo, et al.               Standards Track                   [Page 102]
+

+RFC 4791                         CalDAV                       March 2007
+
+
+           <D:getetag>"fffff-abcd4"</D:getetag>
+           <C:calendar-data>BEGIN:VCALENDAR
+   VERSION:2.0
+   PRODID:-//Example Corp.//CalDAV Client//EN
+   BEGIN:VTODO
+   DTSTAMP:20060205T235335Z
+   DUE;VALUE=DATE:20060104
+   STATUS:NEEDS-ACTION
+   SUMMARY:Task #1
+   UID:DDDEEB7915FA61233B861457@example.com
+   BEGIN:VALARM
+   ACTION:AUDIO
+   TRIGGER;RELATED=START:-PT10M
+   END:VALARM
+   END:VTODO
+   END:VCALENDAR
+   </C:calendar-data>
+         </D:prop>
+         <D:status>HTTP/1.1 200 OK</D:status>
+       </D:propstat>
+     </D:response>
+
+     <D:response>
+       <D:href>http://cal.example.com/bernard/work/abcd5.ics</D:href>
+       <D:propstat>
+         <D:prop>
+           <D:getetag>"fffff-abcd5"</D:getetag>
+           <C:calendar-data>BEGIN:VCALENDAR
+   VERSION:2.0
+   PRODID:-//Example Corp.//CalDAV Client//EN
+   BEGIN:VTODO
+   DTSTAMP:20060205T235300Z
+   DUE;VALUE=DATE:20060106
+   LAST-MODIFIED:20060205T235308Z
+   SEQUENCE:1
+   STATUS:NEEDS-ACTION
+   SUMMARY:Task #2
+   UID:E10BA47467C5C69BB74E8720@example.com
+   BEGIN:VALARM
+   ACTION:AUDIO
+   TRIGGER;RELATED=START:-PT10M
+   END:VALARM
+   END:VTODO
+   END:VCALENDAR
+   </C:calendar-data>
+         </D:prop>
+         <D:status>HTTP/1.1 200 OK</D:status>
+       </D:propstat>
+
+
+
+Daboo, et al.               Standards Track                   [Page 103]
+

+RFC 4791                         CalDAV                       March 2007
+
+
+     </D:response>
+
+     <D:response>
+       <D:href>http://cal.example.com/bernard/work/abcd6.ics</D:href>
+       <D:propstat>
+         <D:prop>
+           <D:getetag>"fffff-abcd6"</D:getetag>
+           <C:calendar-data>BEGIN:VCALENDAR
+   VERSION:2.0
+   PRODID:-//Example Corp.//CalDAV Client//EN
+   BEGIN:VTODO
+   COMPLETED:20051223T122322Z
+   DTSTAMP:20060205T235400Z
+   DUE;VALUE=DATE:20051225
+   LAST-MODIFIED:20060205T235308Z
+   SEQUENCE:1
+   STATUS:COMPLETED
+   SUMMARY:Task #3
+   UID:E10BA47467C5C69BB74E8722@example.com
+   END:VTODO
+   END:VCALENDAR
+   </C:calendar-data>
+         </D:prop>
+         <D:status>HTTP/1.1 200 OK</D:status>
+       </D:propstat>
+     </D:response>
+
+     <D:response>
+       <D:href>http://cal.example.com/bernard/work/abcd7.ics</D:href>
+       <D:propstat>
+         <D:prop>
+           <D:getetag>"fffff-abcd7"</D:getetag>
+           <C:calendar-data>BEGIN:VCALENDAR
+   VERSION:2.0
+   PRODID:-//Example Corp.//CalDAV Client//EN
+   BEGIN:VTODO
+   DTSTAMP:20060205T235600Z
+   DUE;VALUE=DATE:20060101
+   LAST-MODIFIED:20060205T235308Z
+   SEQUENCE:1
+   STATUS:CANCELLED
+   SUMMARY:Task #4
+   UID:E10BA47467C5C69BB74E8725@example.com
+   END:VTODO
+   END:VCALENDAR
+   </C:calendar-data>
+         </D:prop>
+         <D:status>HTTP/1.1 200 OK</D:status>
+
+
+
+Daboo, et al.               Standards Track                   [Page 104]
+

+RFC 4791                         CalDAV                       March 2007
+
+
+       </D:propstat>
+     </D:response>
+
+     <D:response>
+       <D:href>http://cal.example.com/bernard/work/abcd8.ics</D:href>
+       <D:propstat>
+         <D:prop>
+           <D:getetag>"fffff-abcd8"</D:getetag>
+           <C:calendar-data>BEGIN:VCALENDAR
+   VERSION:2.0
+   PRODID:-//Example Corp.//CalDAV Client//EN
+   BEGIN:VFREEBUSY
+   ORGANIZER;CN="Bernard Desruisseaux":mailto:bernard@example.com
+   UID:76ef34-54a3d2@example.com
+   DTSTAMP:20050530T123421Z
+   DTSTART:20060101T000000Z
+   DTEND:20060108T000000Z
+   FREEBUSY:20050531T230000Z/20050601T010000Z
+   FREEBUSY;FBTYPE=BUSY-TENTATIVE:20060102T100000Z/20060102T120000Z
+   FREEBUSY:20060103T100000Z/20060103T120000Z
+   FREEBUSY:20060104T100000Z/20060104T120000Z
+   FREEBUSY;FBTYPE=BUSY-UNAVAILABLE:20060105T100000Z/20060105T120000Z
+   FREEBUSY:20060106T100000Z/20060106T120000Z
+   END:VFREEBUSY
+   END:VCALENDAR
+   </C:calendar-data>
+         </D:prop>
+         <D:status>HTTP/1.1 200 OK</D:status>
+       </D:propstat>
+     </D:response>
+
+   </D:multistatus>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Daboo, et al.               Standards Track                   [Page 105]
+

+RFC 4791                         CalDAV                       March 2007
+
+
+Authors' Addresses
+
+   Cyrus Daboo
+   Apple Inc.
+   1 Infinite Loop
+   Cupertino, CA  95014
+   USA
+
+   EMail: cyrus@daboo.name
+   URI:   http://www.apple.com/
+
+
+   Bernard Desruisseaux
+   Oracle Corporation
+   600 Blvd. de Maisonneuve West
+   Suite 1900
+   Montreal, QC  H3A 3J2
+   CANADA
+
+   EMail: bernard.desruisseaux@oracle.com
+   URI:   http://www.oracle.com/
+
+
+   Lisa Dusseault
+   CommerceNet
+   169 University Ave.
+   Palo Alto, CA  94301
+   USA
+
+   EMail: ldusseault@commerce.net
+   URI:   http://commerce.net/
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Daboo, et al.               Standards Track                   [Page 106]
+

+RFC 4791                         CalDAV                       March 2007
+
+
+Full Copyright Statement
+
+   Copyright (C) The IETF Trust (2007).
+
+   This document is subject to the rights, licenses and restrictions
+   contained in BCP 78, and except as set forth therein, the authors
+   retain all their rights.
+
+   This document and the information contained herein are provided on an
+   "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS
+   OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY, THE IETF TRUST AND
+   THE INTERNET ENGINEERING TASK FORCE DISCLAIM 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.
+
+Intellectual Property
+
+   The IETF takes no position regarding the validity or scope of any
+   Intellectual Property Rights or other rights that might be claimed to
+   pertain to the implementation or use of the technology described in
+   this document or the extent to which any license under such rights
+   might or might not be available; nor does it represent that it has
+   made any independent effort to identify any such rights.  Information
+   on the procedures with respect to rights in RFC documents can be
+   found in BCP 78 and BCP 79.
+
+   Copies of IPR disclosures made to the IETF Secretariat and any
+   assurances of licenses to be made available, or the result of an
+   attempt made to obtain a general license or permission for the use of
+   such proprietary rights by implementers or users of this
+   specification can be obtained from the IETF on-line IPR repository at
+   http://www.ietf.org/ipr.
+
+   The IETF invites any interested party to bring to its attention any
+   copyrights, patents or patent applications, or other proprietary
+   rights that may cover technology that may be required to implement
+   this standard.  Please address the information to the IETF at
+   ietf-ipr@ietf.org.
+
+Acknowledgement
+
+   Funding for the RFC Editor function is currently provided by the
+   Internet Society.
+
+
+
+
+
+
+
+Daboo, et al.               Standards Track                   [Page 107]
+
+

+Html markup produced by rfcmarkup 1.74, available from +http://tools.ietf.org/tools/rfcmarkup/ + + \ No newline at end of file diff --git a/caldav/rruleparser.class.php b/caldav/rruleparser.class.php new file mode 100644 index 0000000..1eadf49 --- /dev/null +++ b/caldav/rruleparser.class.php @@ -0,0 +1,468 @@ +freq = preg_split("/[\s,]+/", FREQUENCE); + if ($rrule) + $this->setRule($rrule, $start, $end); + } + + function setRule($rrule, $start, $end) { + if (!($start && $end)) + throw new Exception("Missing values for DTSTART and/or DTEND"); + //print "$start:$end
"; + //print var_export($rrule, TRUE) . "
"; + $this->start = CaldavRessource::iCal2Timestamp($start); + $this->end = CaldavRessource::iCal2Timestamp($end); + //print CaldavRessource::timestamp2ICal($this->start, TRUE).":".CaldavRessource::timestamp2ICal($this->end, TRUE)."
"; + $rules = explode(';', $rrule); + //print_r($rules); + if (count($rules) < 2) { + foreach ($rules as $rule) { + $pair = explode('=', $rule); + if (count($pair) < 2 || !in_array($pair[1], $this->freq)) { + $this->rules = array(); + throw new Exception("$rrule: Invalid RRULE"); + } + $this->rules[strtolower($pair[0])] = explode(',', $pair[1]); + } + } + else { + foreach ($rules as $rule) { + $pair = explode('=', $rule); + $this->rules[strtolower($pair[0])] = explode(',', $pair[1]); + } + } + if ($this->rules['until'][0] && $this->rules['count'][0]) { + $this->rules = array(); + throw new Exception("COUNT and UNTIL cannot be present at the same time"); + } + if (!in_array($this->rules['freq'][0], $this->freq)) { + trigger_error( + "[{$this->rules['freq'][0]}] Unsupported FREQ", + E_USER_NOTICE); + $this->rules = array(); + } + } + + private function getEnd($freq) { + $count = $this->getCount(); + $until = $this->getUntil(); + //print "$until
"; + if ($count) { + $int = $this->getInterval(); + $count = ($int) ? $int * $count : $count; + switch ($freq) { + case 'HOURLY': $str = "+$count hour"; break; + case 'DAILY': $str = "+$count day"; break; + case 'WEEKLY': $str = "+$count week"; break; + case 'MONTHLY': $str = "+$count month"; break; + case 'YEARLY': $str = "+$count year"; break; + } + $end = strtotime($str, $this->start); + return ($this->range_end && $this->range_end < $end) ? + $this->range_end : $end; + } + else if ($until) { + /* + * UNTIL has first occurrence at end time and + * last ocurrence ending at start time + */ + //print "$until:".$this->start."
"; + $u_s = explode("T", CaldavRessource::timestamp2ICal($this->end)); + $time_s = (int) substr($u_s[1], 0, 2); + $u_e = explode("T", $until); + $time_e = (int) substr($u_e[1], 0, 2); + $until = ($time_s != $time_e) ? "{$u_e[0]}T{$u_s[1]}" : $until; + //print "$time_s:$time_e:$until
"; + $end = CaldavRessource::iCal2Timestamp($until); + //print CaldavRessource::timestamp2ICal($end)."
"; + return ($this->range_end && $this->range_end < $end) ? + $this->range_end : $end; + } + else + return $this->range_end; + } + + private function except($ts) { + $byhour = $this->getByHour(); + if ($byhour) { + $res = TRUE; + $match = gmdate('G', $ts); + foreach ($byhour as $hour) { + if ($match == $hour) + $res = FALSE; + if (! $res) + return FALSE; + } + return TRUE; + } + $byday = $this->getByDay(); + if ($byday) { + $res = TRUE; + $match = substr(strtolower(gmdate('D', $ts)), 0, 2); + foreach ($byday as $day) { + //print "$match:$day\n"; + if ($match == strtolower($day)) + $res = FALSE; + if (! $res) + return FALSE; + } + return TRUE; + } + $bymonth = $this->getByMonth(); + if ($bymonth) { + $res = TRUE; + $match = gmdate('n', $ts); + foreach ($bymonth as $month) { + if ($match == $month) + $res = FALSE; + if (! $res) + return FALSE; + } + return TRUE; + } + $bymonthday = $this->getByMonthDay(); + if ($bymonthday) { + $res = TRUE; + $match = gmdate('j', $ts); + foreach ($bymonthday as $monthday) { + if ($match + 1 == $monthday) + $res = FALSE; + if (! $res) + return FALSE; + } + return TRUE; + } + $byweekno = $this->getByWeekNo(); + if ($byweekno) { + $res = TRUE; + // Missing to handle Anglo week numbers + // (week start on Sunday) + $match = gmdate('W', $ts); + foreach ($byweekno as $weekno) { + if ($match == $weekno) + $res = FALSE; + if (! $res) + return FALSE; + } + return TRUE; + } + $byyearday = $this->getByYearDay(); + if ($byyearday) { + $res = TRUE; + $match = gmdate('z', $ts); + foreach ($byyearday as $yearday) { + if ($match == $yearday) + $res = FALSE; + if (! $res) + return FALSE; + } + return TRUE; + } + return FALSE; + } + + private function hourly() { + $res = array(); + $end = $this->getEnd('HOURLY'); + if (! $end) { + /** + * we will maximum handle one month at a time unless + * a specific end date specifies otherwise + */ + $end = strtotime('+1 month', $this->start); + } + $int = ($this->getInterval()) ? $this->getInterval() : 1; + $c = $this->start; + for (; $c < $end; $c = strtotime("+$int hour", $c)) { + if (! $this->except($c)) + array_push($res, CaldavRessource::timestamp2ICal($c)); + } + return $res; + } + + private function daily() { + $res = array(); + $end = $this->getEnd('DAILY'); + if (! $end) { + /** + * we will maximum handle one month at a time unless + * a specific end date specifies otherwise + */ + $end = strtotime('+1 month', $this->start); + } + $int = ($this->getInterval()) ? $this->getInterval() : 1; + $c = $this->start; + for (; $c < $end; $c = strtotime("+$int day", $c)) { + if (! $this->except($c)) + array_push($res, CaldavRessource::timestamp2ICal($c)); + } + return $res; + } + + private function weekly() { + $res = array(); + $end = $this->getEnd('WEEKLY'); + //print "start: ".CaldavRessource::timestamp2ICal($this->start)." end: ".CaldavRessource::timestamp2ICal($end)."\n"; + if (! $end) { + /** + * we will maximum handle 12 weeks at a time unless + * a specific end date specifies otherwise + */ + $end = strtotime('+12 week', $this->start); + } + $int = ($this->getInterval()) ? $this->getInterval() : 1; + $c = $this->start; + for (; $c < $end; $c = strtotime("+$int week", $c)) { + //print CaldavRessource::timestamp2ICal($c)."
"; + if (! $this->except($c)) + array_push($res, CaldavRessource::timestamp2ICal($c)); + } + //print_r($res); + return $res; + } + + private function monthly() { + $res = array(); + $end = $this->getEnd('MONTHLY'); + if (! $end) { + /** + * we will maximum handle 12 months at a time unless + * a specific end date specifies otherwise + */ + $end = strtotime('+12 month', $this->start); + } + $int = ($this->getInterval()) ? $this->getInterval() : 1; + $c = $this->start; + for (; $c < $end; $c = strtotime("+$int month", $c)) { + if (! $this->except($c)) + array_push($res, CaldavRessource::timestamp2ICal($c)); + } + return $res; + } + + private function yearly() { + $res = array(); + $end = $this->getEnd('YEARLY'); + if (! $end) { + /** + * we will maximum handle 12 years at a time unless + * a specific end date specifies otherwise + */ + $end = strtotime('+12 year', $this->start); + } + $int = ($this->getInterval()) ? $this->getInterval() : 1; + $c = $this->start; + for (; $c < $end; $c = strtotime("+$int year", $c)) { + if (! $this->except($c)) + array_push($res, CaldavRessource::timestamp2ICal($c)); + } + return $res; + } + + private function limitRange($dates) { + $res = array(); + if (!$this->range_start && !$this->range_end) { + $res = $dates; + } + else if ($this->range_start && !$this->range_end) { + $start = CaldavRessource::timestamp2ICal($this->range_start); + foreach ($dates as $date) { + if (CaldavRessource::datecmp($start, $date) < 0) + array_push($res, $date); + } + } + else { + $start = CaldavRessource::timestamp2ICal($this->range_start); + $end = CaldavRessource::timestamp2ICal($this->range_end); + foreach ($dates as $date) { + if (CaldavRessource::datecmp($start, $date) < 0 && + CaldavRessource::datecmp($end, $date) > 0) + array_push($res, $date); + } + } + return $res; + } + + function getFreq() { + return strtoupper($this->rules['freq'][0]); + } + + function getUntil() { + return strtoupper($this->rules['until'][0]); + } + + function getCount() { + return strtoupper($this->rules['count'][0]); + } + + function getInterval() { + return strtoupper($this->rules['interval'][0]); + } + + function getBySecond() { + $l = $this->rules['bysecond']; + if ($l) { + foreach ($l as $val) + $list[] = strtoupper($val); + } + return $list; + } + + function getByMinute() { + $l = $this->rules['byminute']; + if ($l) { + foreach ($l as $val) + $list[] = strtoupper($val); + } + return $list; + } + + function getByHour() { + $l = $this->rules['byhour']; + if ($l) { + foreach ($l as $val) + $list[] = strtoupper($val); + } + return $list; + } + + function getByDay() { + $l = $this->rules['byday']; + if ($l) { + foreach ($l as $val) + $list[] = strtoupper($val); + } + return $list; + } + + function getByMonthDay() { + $l = $this->rules['bymonthday']; + if ($l) { + foreach ($l as $val) + $list[] = strtoupper($val); + } + return $list; + } + + function getByYearDay() { + $l = $this->rules['byyearday']; + if ($l) { + foreach ($l as $val) + $list[] = strtoupper($val); + } + return $list; + } + + function getByWeekNo() { + $l = $this->rules['byweekno']; + if ($l) { + foreach ($l as $val) + $list[] = strtoupper($val); + } + return $list; + } + + function getByMonth() { + $l = $this->rules['bymonth']; + if ($l) { + foreach ($l as $val) + $list[] = strtoupper($val); + } + return $list; + } + + function getBySetPos() { + return strtoupper($this->rules['bysetpos'][0]); + } + + function getWKST() { + return strtoupper($this->rules['wkst'][0]); + } + + function getAll() { + return $this->rules; + } + + function getEventDates($startDate = NULL, $endDate = NULL) { + $dates = array(); + + $freq = $this->getFreq(); + //print "$freq\n"; + if (! in_array($freq, $this->freq)) + return $dates; + if ($startDate && $endDate) { + $this->range_start = CaldavRessource::iCal2Timestamp($startDate); + $this->range_end = CaldavRessource::iCal2Timestamp($endDate); + if ($this->start > $this->range_end) + return $dates; + } + else if ($startDate) { + $this->range_start = CaldavRessource::iCal2Timestamp($startDate); + $this->range_end = NULL; + } + else { + $this->range_start = NULL; + $this->range_end = NULL; + } + switch ($freq) { + case 'HOURLY': $dates = $this->hourly(); break; + case 'DAILY': $dates = $this->daily(); break; + case 'WEEKLY': $dates = $this->weekly(); break; + case 'MONTHLY': $dates = $this->monthly(); break; + case 'YEARLY': $dates = $this->yearly(); break; + default: break; + } + //print_r($dates); + return (count($dates) > 0) ? $this->limitRange($dates) : $dates; + } + + function getStartAndEnd() { + $res['start'] = $this->start; + $res['end'] = $this->end; + + return $res; + } + + function __toString() { + $str = "FREQ=" . $this->getFreq(); + $until = $this->getUntil(); + $count = $this->getCount(); + if ($until) + $str .= ';UNTIL=' . $until; + if ($count) + $str .= ';COUNT=' . $count; + foreach ($this->rules as $k => $v) { + if ($k == 'freq' || $k == 'count' || $k == 'until') + continue; + $str .= ';' . strtoupper($k) . '='; + foreach($v as $rule) { + if ($str[strlen($str) - 1] != '=') + $str .= ','; + $str .= strtoupper($rule); + } + } + return $str; + } + + } diff --git a/caldav/vevent.class.php b/caldav/vevent.class.php new file mode 100644 index 0000000..45b6b04 --- /dev/null +++ b/caldav/vevent.class.php @@ -0,0 +1,155 @@ +rulesParser = new RRuleParser(); + } + + function isActive($start, $end) { + $res = FALSE; + if (!($start && $end)) + return TRUE; + if (! CaldavRessource::isDateTime($start) || + ! CaldavRessource::isDateTime($end)) + throw new Exception( + "[$start,$end] Invalid CalDAV DateTime format"); + $event = $this->getBaseComponent(); + if ($start && !$end) { + if (CaldavRessource::datecmp( + $start, $event->GetPValue('DTSTART')) < 0) + $res = TRUE; + } + else { + if (CaldavRessource::datecmp( + $start, $event->GetPValue('DTSTART')) < 0 && + CaldavRessource::datecmp( + $end, $event->GetPValue('DTEND')) > 0) + $res = TRUE; + } + return $res; + } + + function getActiveDates($range_start = NULL, $range_end = NULL) { + $res = array(); + $event = $this->getBaseComponent(); + //print_r($event); + $start = $event->GetPValue('DTSTART'); + $end = $event->GetPValue('DTEND'); + //print "$start:$end
"; + if (! ($start && $end)) + return $res; + $rrule = $event->GetPValue('RRULE'); + if ($rrule) { + $this->rulesParser->setRule($rrule, $start, $end); + //print $this->rulesParser->__toString()."\n"; + $res = $this->rulesParser->getEventDates( + $range_start, $range_end); + //print_r($res); + } + else { + if ($this->isActive($range_start, $range_end)) + array_push($res, $start); + } + //var_dump($res); + return $res; + } + + function getRRule() { + return $this->rulesParser; + } + + function getAlarm() { + $alarm = $this->getComponent(VTYPE::VALARM); +// print_r($alarm); + if ($alarm) + $alarm = $alarm[0]; + return $alarm; + } + + function setProperty($name, $value) { + $component = $this->getBaseComponent(); + $properties = $component->GetProperties(); + $match = FALSE; + $update = FALSE; + + if (count($properties) > 0) { + foreach ($properties as $property) { + //echo "B: " . $property->Name(). ":" . $property->Value() . "
"; + $test1 = explode(';', $name); + $test2 = explode(';', $property->Name()); + if (strcasecmp($test1[0], $test2[0]) === 0) { + if (strcmp($property->Value(), $value) !== 0) { + $property->Value($value); + //echo "B: " . $property->Name(). ":" . $property->Value() . "
"; + $update = TRUE; + } + $match = TRUE; + } + } + } + if ($match == FALSE) { + $component->AddProperty(strtoupper($name), $value); + $update = TRUE; + } + else { + if ($update) + $component->SetProperties($properties); + } + if ($update) { + $this->addDefault($component); + $this->setDirty(); + } + //$properties = $component->GetProperties(); + //foreach ($properties as $property) { + // echo "A: " . $property->Name(). ":" . $property->Value() . "
"; + //} + //echo "
"; + //exit; + } + + private function AddDefault(iCalComponent $component) { + $properties = $component->GetProperties();; + $now = gmdate("Ymd\THis\Z"); + $a = array(1,1,1); + foreach ($properties as $property) { + //echo "D: " . $property->Name(). ":" . $property->Value() . "
"; + if (strcasecmp('DTSTAMP', $property->Name()) === 0) { + $property->Value($now); + $a[0] = 0; + } + if (strcasecmp('LAST-MODIFIED', $property->Name()) === 0) { + $property->Value($now); + $a[1] = 0; + } + if (strcasecmp('X-WEBCAL-GENERATION', $property->Name()) === 0) { + $property->Value('1'); + $a[2] = 0; + } + } + for ($i = 0; $i < count($a); $i++) { + //echo $i.':'.$a[$i]."
"; + if ($a[$i]) { + switch ($i) { + case 0: $c['DTSTAMP'] = $now; break; + case 1: $c['LAST-MODIFIED'] = $now; break; + case 2: $c['X-WEBCAL-GENERATION'] = 1; break; + default: continue; + } + $key = key($c); + $val = $c[$key]; + $component->AddProperty($key, $val); + $c = NULL; + } + } + } + } diff --git a/css/top_level.css b/css/top_level.css new file mode 100644 index 0000000..eac8ffa --- /dev/null +++ b/css/top_level.css @@ -0,0 +1,277 @@ +/* $Id$ */ + +body { + background-color: #FAFAFA; + color: #000000; + font-family: 'bitstream vera sans', 'vera sans', sans-serif; + font-size: 0.8em; +} + +a:link { + color: #000099; + text-decoration: none; +} + +a:visited { + color: #000099; + text-decoration: none; +} + +a:active { + color: black; + text-decoration: none; +} + +a:hover { + color: #000099; +} + +img.floatleft { + float: left; + margin: 2px; +} + +img.floatright { + float: right; + margin: 2px; +} + +#menu { + background-color: #FFFFC4; + color: inherit; + margin-top: 0px; + font-size: 0.8em; +} + +#menu table { + width: 100%; +} + +#menu td { + width: 25px; + text-align: center; +} + +#menu img { + border: 0; + display: block; + margin-right: auto; + margin-left: auto; +} + +#ui { +/* background-color: transparent;*/ + background-color: #F1F9FF; + color: #000000; + margin: 20px; + border: 2px ridge #1D388C; + padding: 1%; + min-height: 450px; + height: auto; +/* */ +} + +#ui a:link { + color: green; + text-decoration: none; +} + +#ui a:visited { + color: green; + text-decoration: none; +} + +#ui a:active { + color: green; + text-decoration: none; +} + +#ui a:hover { + color: green; + text-decoration: underline; +} + +#ui table.config { + border-width: 1px; + border-style: solid; + margin-right: auto; + margin-left: auto; +} + +#ui th { + border-bottom: 3px solid; +} + +#ui td.config { + padding: 2px; +} + +#ui p.usermanage { + text-align: center; +} + +#footer { + text-align: left; + font-size: 0.8em; +} + +#footer img { + border: 0; + float: right; +} + +#cal { + font-family: 'bitstream vera sans', 'vera sans', sans-serif; + font-size: 1em; +} + +#cal input { + font-size: 1em; +} + +#cal td { + font-size: 1em; +} + +#cal table { + border-width: 1px; + border-style: solid; + margin-right: auto; + margin-left: auto; +} + +#events { +} + +#events th { + text-align: center; + border-width: 1px 1px 1px 1px; + padding: 2px 2px 2px 2px; + border-style: solid solid solid solid; + border-color: #2C9185 #2C9185 #2C9185 #2C9185; + background-color: #CEFFFA; +} + +#events th.event { + width: 13.5%; +} + +#events th.day_event { + width: 90%; +} + +#events td { + border-width: 1px 1px 1px 1px; + padding: 2px 2px 2px 2px; + border-style: solid solid solid solid; + border-color: #2C9185 #2C9185 #2C9185 #2C9185; + background-color: #FFFFFF; +} + +#events td.weeknum, td.time { + background-color: #8FCDC7; + text-align: center; + font-weight: bold; +} + +#events td.notused { + background-color: #BFBFBF; +} + +#events td.today { + background-color: #FAF8D2; +} + +#events .date { + border-left-width: 1px; + border-bottom-width: 0px; + border-right-width: 0px; + border-top-width: 1px; + border-style: solid; + padding: 1px; + font-size: x-small; + float: right; +} + +#events table { + width: 100%; + border-width: 2px 2px 2px 2px; + border-spacing: 0px; + border-style: solid solid solid solid; + border-color: #2C9185 #2C9185 #2C9185 #2C9185; + border-collapse: separate; + background-color: transparent; +} + +#error_msg { + display: block; + margin-right: auto; + margin-left: auto; + margin-top: 10%; + padding: 5px; + width: 400px; + border-width: 5px; + border-spacing: 0px; + border-style: solid solid solid solid; + border-color: black; + border-collapse: separate; + background-color: red; + color: black; +} + +#update_msg { + display: block; + margin-right: auto; + margin-left: auto; + margin-top: 10%; + padding: 5px; + width: 400px; + border-width: 5px; + border-spacing: 0px; + border-style: solid solid solid solid; + border-color: black; + border-collapse: separate; + background-color: yellow; + color: black; +} + +#login_msg { + display: block; + margin-right: auto; + margin-left: auto; + margin-top: 10%; + padding: 5px; + width: 400px; + border-width: 5px; + border-spacing: 0px; + border-style: solid solid solid solid; + border-color: black; + border-collapse: separate; + background-color: #F1F9FF; + color: black; +} + +#login_msg table { + margin-right: auto; + margin-left: auto; +} + +#event { + padding: 1%; +} + +#event input, select { + font-family: 'bitstream vera sans', 'vera sans', sans-serif; + font-size: 1.0em; +} + +#event table { + margin-right: auto; + margin-left: auto; +} + +.bold { + font-weight: bold; +} \ No newline at end of file diff --git a/error.html b/error.html new file mode 100644 index 0000000..09ec9ed --- /dev/null +++ b/error.html @@ -0,0 +1,24 @@ + + + + + + Web Calendar + + + + +
+

Redirecting Error occured

+

+ Your session has expired
+ or you have tried to by-pass the login system.
+ You can increase your session timeout in the config menu. +

+

+ Please login here +

+
+ + diff --git a/events/delete_event.php b/events/delete_event.php new file mode 100644 index 0000000..3fbc045 --- /dev/null +++ b/events/delete_event.php @@ -0,0 +1,64 @@ +'; +//print_r($_SESSION['all_events']); +//exit; +if (isset($query['cal']) && ! empty($query['cal']) && + isset($query['etag']) && ! empty($query['etag'])) { + $_SESSION['calendar'] = $_SESSION['all_events'][$query['cal']]; + if (! is_object($_SESSION['calendar'])) + throw new Exception("Missing calendar object"); + + foreach ($_SESSION['calendar'] as $vevent) { + if ($vevent->getEtag() == $query['etag']) { + $res = $_SESSION['calendar']->delete($vevent->getUrl(), $vevent->getEtag()); + } + } + //print $query['referer']; + header('Location: '. urldecode($query['referer'])); + exit; +} +else { + $text = '

Choose an event from one of the listed calendars

'; + $text .= '

'; + $text .= '

'; + $text .= ''; + $text .= ''; + $calendar = ''; + foreach ($_SESSION['all_events'] as $name => $cal) { + //$calendar .= "$name
".var_export($cal, true)."
"; + $text .= $name.':

'; + } + $text .= ''; + $text .= '

'; + //print urldecode($query['referer']); + //exit; + print popup_window($text, $query['referer']); + exit; +} +?> \ No newline at end of file diff --git a/events/edit_event.php b/events/edit_event.php new file mode 100644 index 0000000..2fd52f8 --- /dev/null +++ b/events/edit_event.php @@ -0,0 +1,218 @@ +validUser()) { + $view_style = ($_SESSION['user_settings']->getViewStyle()) ? + $_SESSION['user_settings']->getViewStyle() : VIEW_STYLE; +// $timeout = ($_SESSION['user_settings']->getTimeout()) ? +// (int) $_SESSION['user_settings']->getTimeout() : TIMEOUT; + $week_start_sunday = ($_SESSION['user_settings']->getStartWeek() !== NULL) ? + $_SESSION['user_settings']->getStartWeek() : WEEK_START_SUNDAY; + $start_hour = ($_SESSION['user_settings']->getStartHour()) ? + (int) $_SESSION['user_settings']->getStartHour() : START_HOUR; + $end_hour = ($_SESSION['user_settings']->getEndHour()) ? + (int) $_SESSION['user_settings']->getEndHour() : END_HOUR; +} + +$pwd = WEB_ROOT; +if ($pwd[strlen($pwd)-1] == '/') + $pwd = substr($pwd, 0, -1); + +if (isset($_POST) && count($_POST) > 0) { + $exclude = array('tzid','range','times','untildate'); + $start = array('date' => NULL, 'time' => NULL); + $end = array('date' => NULL, 'time' => NULL); + $referer = $_POST['referer']; + $allDay = false; + + foreach ($_POST as $key => $value) { + //echo "$key => $value
"; + if (strcmp($key, 'referer') == 0) + continue; + if (in_array($key, $exclude)) + continue; + if (strcasecmp($key, 'startdate') == 0) { + $start['date'] = join('', explode('-',$value)); + continue; + } + if (strcasecmp($key, 'starttime') == 0) { + $start['time'] = $value; + if (strlen($start['time']) < 5) + $start['time'] .= '00'; + continue; + } + if (strcasecmp($key, 'enddate') == 0) { + $end['date'] = join('', explode('-',$value)); + continue; + } + if (strcasecmp($key, 'endtime') == 0) { + $end['time'] = $value; + if (strlen($end['time']) < 5) + $end['time'] .= '00'; + continue; + } + if (strcasecmp("allDay", $key) == 0) { + $allDay = true; + continue; + } + if (strcasecmp("recurrence", $key) == 0) { + $value = "FREQ=$value"; + $key = "RRULE"; + } + //echo "$key => $value
"; + $_SESSION['current_event']->setProperty($key, $value); + } + //echo 'DTSTART: '. $start['date'].'T'.$start['time']; + //echo '
DTEND: '. $end['date'].'T'.$end['time']; + //exit; + if ($allDay) { + $_SESSION['current_event']->setProperty( + 'DTSTART;VALUE=DATE', $start['date']); + $_SESSION['current_event']->setProperty( + 'DTEND;VALUE=DATE', $end['date']); + //echo "
".$start['date']."
"; + //echo $end['date']."
"; + } + else { + $start = strtotime($start['date'].'T'.$start['time']); + $end = strtotime($end['date'].'T'.$end['time']); + //echo "
".Calendar::timestamp2ICal($start, FALSE)."
"; + //echo Calendar::timestamp2ICal($end, FALSE)."
"; + //exit; + $_SESSION['current_event']->setProperty('DTSTART', + Calendar::timestamp2ICal($start, FALSE)); + $_SESSION['current_event']->setProperty('DTEND', + Calendar::timestamp2ICal($end, FALSE)); + } + //exit; + if (isset($_SESSION['calendar'])) { + $res = $_SESSION['calendar']->update( + $_SESSION['current_event']->getUrl(), + $_SESSION['current_event']->getEtag()); + //print_r($res); + //exit; + unset($_SESSION['current_event']); + unset($_SESSION['calendar']); + unset($_SESSION['EVENT_ACTION']); + if (count($res) == 0) { + header('Location: ' . $referer); + exit; + } + $msg = ''; + foreach ($res as $elem) { + $k = key($elem); + $msg .= "$k: " . $elem[$k]; + } + } + else + throw new Exception("Error updating event"); + //print "$msg\n"; + $msg = join("", explode("\n", $msg)); + $title = TITLE; + $pwd = WEB_ROOT; +$head = <<<__HEAD + + + + +$title + + + + + + + + + + + + + +
calendar.pngLogout
Logout
DAViCal Web Calendar
- A Web Interface for DAViCal
+__HEAD; + print "$head"; + include TOP_FOLDER.'/include/menu.inc.php'; + print "
"; + include TOP_FOLDER.'/include/footer.inc.php'; + exit; +} +else { + $query = construct_URL($_SERVER['QUERY_STRING'], + array('etag', 'referer', 'cal')); + //print_r($_SESSION['all_events'][$query['cal']]); + //exit; + if (isset($query['cal']) && ! empty($query['cal'])) { + $_SESSION['calendar'] = $_SESSION['all_events'][$query['cal']]; + if (! is_object($_SESSION['calendar'])) + throw new Exception("Missing calendar object"); + + if ($_SESSION['EVENT_ACTION'] == 'NEW') { + $event = $_SESSION['calendar']->newComponent('VEVENT'); + $_SESSION['current_event'] = $event; + } + else { + foreach ($_SESSION['calendar'] as $vevent) { + if ($vevent->getEtag() == $query['etag']) { + $event = $vevent; + break; + } + } + $_SESSION['current_event'] = $event; + } + //print $query['referer']; + //exit; + $gui = new EventGUI($event, $query['referer'], $query['cal']); + //unset($_GET['referer']); + $calendar = $gui->getView(); + } + else { + $text = '

Choose an event from one of the listed calendars

'; + $text .= '

'; + $text .= '

'; + $text .= ''; + $text .= ''; + $calendar = ''; + foreach ($_SESSION['all_events'] as $name => $cal) { + //$calendar .= "$name
".var_export($cal, true)."
"; + $text .= $name.':

'; + } + $text .= ''; + $text .= '

'; + //print "{$_GET['referer']}"; + //exit; + print popup_window($text, $query['referer']); + exit; + } +} +include TOP_FOLDER.'/include/header.inc.php'; +include TOP_FOLDER.'/include/menu.inc.php'; + +print "
$calendar
"; +include TOP_FOLDER.'/include/footer.inc.php'; +?> diff --git a/events/eventgui.class.php b/events/eventgui.class.php new file mode 100644 index 0000000..db2df37 --- /dev/null +++ b/events/eventgui.class.php @@ -0,0 +1,354 @@ +event = $event; + $this->referer = urldecode($referer); + $this->cal = $cal; + //print $this->referer; + //exit; + $this->summary = ''; + $this->location = ''; + $this->description = ''; + $this->start = ''; + $this->end = ''; + $this->timezone = ''; + $this->localtime = ($_SESSION['user_settings']->getTimeZone() !== NULL) ? + $_SESSION['user_settings']->getTimeZone() : TIMEZONE; + $root = WEB_ROOT; + $week_start_sunday = ($_SESSION['user_settings']->getStartWeek() !== NULL) ? + $_SESSION['user_settings']->getStartWeek() : WEEK_START_SUNDAY; + $week_start_sunday = ($week_start_sunday) ? 0 : 1; + $this->startdate = <<< __CAL1 + +__CAL1; + $this->enddate = <<< __CAL1 + +__CAL1; + $this->until = <<< __CAL1 + +__CAL1; + } + + private function parseEvent() { + if (! $this->event) + return FALSE; + $comp = $this->event->getBaseComponent(); + $this->summary = $comp->GetPValue('SUMMARY'); + $this->location = $comp->GetPValue('LOCATION'); + $this->description = $comp->GetPValue('DESCRIPTION'); + $this->start = $comp->GetPValue('DTSTART'); + $this->end = $comp->GetPValue('DTEND'); + $this->timezone = $this->event->getTZID(); + $rrule = $this->event->getRRule(); + $this->dates = $rrule->getEventDates(); + $this->rrule = $rrule->getAll(); + //echo $this->start .':'. $this->end .'
'; + return TRUE; + } + + private function createDT($elem, $name) { + $res = array(); + + //print_r($elem); + //echo '
'; + if (count($elem) > 1) { + $date = $elem[0]; + $time = substr($elem[1], 0, 4); + } + else { + $date = $elem[0]; + $time = '2359'; + } + for ($i = 0; $i < substr($time, 2); $i += 15); + if ($i < 10) + $i = "0$i"; + $time = substr($time, 0, 2) . $i; + //echo "$time
"; + $options = array(); + for ($i = 0; $i < 24; $i++) { + $h = ($i < 10) ? "0$i" : $i; + $stop = ($i == 23) ? 61 : 60; + for ($j = 0; $j < $stop; $j += 15) { + $m = ($j < 10) ? "0$j" : $j; + if ($m == 60) + $m = 59; + $hm = "$h$m"; + //echo "$hm
"; + $option = ""; + } + return $colors; +} + +$user = $_SESSION['user_settings']; +if (count($_POST) > 0 && isset($_POST['action'])) { + $db = Persistens::getInstance(DBDRIVER); + $calconf = $_POST['calendar']; + if ($_POST['action'] == 'new') { + $row = $calconf; + $text = "url={$row['url']}\nuid={$row['uid']}\npwd={$row['pwd']}"; + $text = encode($text); + $calendar = new CalendarInfo(); + $calendar->name = $row['name']; + $calendar->color = $row['color']; + $calendar->config = $text; + $id = $db->addCalendar($user->getUid(), $calendar); + if (is_numeric($id)) { + $user->addCalendar($id, $calendar); + $pageView = "

Calendar was added with id $id

"; + } + else { + $pageView = "

$id

"; + } + } + else { + foreach ($calconf as $id => $row) { + if (! isset($row[check])) + continue; + if ($_POST['action'] == 'update') { + $text = "url={$row['url']}\nuid={$row['uid']}\npwd={$row['pwd']}"; + $text = encode($text); + $calendar = new CalendarInfo(); + $calendar->name = $row['name']; + $calendar->color = $row['color']; + $calendar->config = $text; + $res = $db->updateCalendar($user->getUid(), $id, $calendar); + if ($res === TRUE) { + $user->addCalendar($id, $calendar); + $pageView = "

Calendar with id $id was updated

"; + } + else { + $pageView = "

$id

"; + } + } + else { + $res = $db->deleteCalendar($user->getUid(), $id); + if ($res === TRUE) { + $user->removeCalendar($id); + $pageView = "

Calendar with id $id was removed

"; + } + else { + $pageView = "

$id

"; + } + } + } + } + $pageView .= ''; +} +else if (count($_POST) > 0 && isset($_POST['new'])) { + $colors = colors(); + $pageView = '
+ '; + $pageView .= " + + + + + + + + + + + + + + + + + + "; + $pageView .= ' + + '; + $pageView .= '
Name
Color + +
URL
Username
Password
+ + +
'; +} +else { + //var_dump($_SESSION['authenticate']); + //var_dump($user); + //exit(); + $calendars = $user->getCalendars(); + //var_dump($calendars); + //exit(); + $pageView = '
+ '; + + if (count($calendars) > 0) { + foreach ($calendars as $id => $cal) { + $text = decode($cal->config); + $color = colors($cal->color); + $info = implode_cal($text); + $pageView .= " + + + + + + + + + + + "; + } + $pageView .= ' + + + + + '; + } + else { + $pageView .= ' + + '; + } + $pageView .= '
Namename}\"/>Color + + URL + UsernamePassword
+ Delete + Update +
+ + +
+ +
'; +} +print "
$pageView
"; + +include TOP_FOLDER.'/include/footer.inc.php'; +?> diff --git a/utils/configure.php b/utils/configure.php new file mode 100644 index 0000000..efaa2f2 --- /dev/null +++ b/utils/configure.php @@ -0,0 +1,257 @@ + 0 && isset($_POST['action'])) { + $db = Persistens::getInstance(DBDRIVER); + + if ($_POST['action'] == "password") { + if ($_POST['pwd1'] == $_POST['pwd2']) { + $res = $db->changePassword($user->getUid(), sha1($_POST['pwd1'])); + if ($res === TRUE) { + header("Location: " . WEB_ROOT . "logout.php"); + exit(); + } + //else { + // $res = "uid: ".$user->getUid()." ".$_POST['pwd1']." ".$_POST['pwd2']." -> $res"; + //} + } + else { + $res = "Passwords did not compare"; + } + $pageView = "

$res

"; + } + else if ($_POST['action'] == "settings") { + file_put_contents('/tmp/davical.log', + __FILE__ . ": " . var_export($_POST, TRUE), FILE_APPEND); + $conf = array(); + if ($_POST['endDay'] > $_POST['startDay']) { + $conf['daystart'] = $_POST['startDay']; + $conf['dayend'] = $_POST['endDay']; + } + else { + $conf['daystart'] = $user->getStartHour(); + $conf['dayend'] = $user->getEndHour(); + } + $conf['timeout'] = + ($_POST['timeout'] > 0) ? $_POST['timeout'] * 60 : + $user->getTimeout() / 60; + $conf['userview'] = $_POST['viewStyle']; + $conf['weekstart'] = ($_POST['startWeek'] == 'SU') ? 1 : 0; + $conf['timezone'] = $_POST['timezone']; + $conf['userrole'] = $user->getRole(); + $res = $db->setUserSettings($user->getUid(), $conf); + if ($res === TRUE) { + $user->setSettings(array($conf)); + header("Location: " . $_SERVER['PHP_SELF']); + exit(); + } + $pageView = "

$res

"; + } +} +else { + $timeout = $user->getTimeout() / 60; + $viewStyle = $user->getViewStyle(); + switch ($viewStyle) { + case 'day': + $viewStyle = <<<_SELECT + +_SELECT; + break; + case 'week': + $viewStyle = <<<_SELECT + +_SELECT; + break; + case 'month': + $viewStyle = <<<_SELECT + +_SELECT; + break; + } + $weekStart = $user->getStartWeek(); + if ($weekStart) + $weekStart = <<<_SELECT + +_SELECT; + else + $weekStart = <<<_SELECT + +_SELECT; + + $dayStart = (int) $user->getStartHour(); + $start = ''; + for ($i = 0; $i < 25; $i++) { + $hour = ($i < 10) ? "0$i:00" : "$i:00"; + $end .= "