Back to index

courier  0.68.2
pcp.h
Go to the documentation of this file.
00001 #ifndef pcp_h
00002 #define pcp_h
00003 
00004 /*
00005 ** Copyright 2001-2002 Double Precision, Inc.  See COPYING for
00006 ** distribution information.
00007 */
00008 
00009 
00010 #include "config.h"
00011 
00012 #if TIME_WITH_SYS_TIME
00013 # include <sys/time.h>
00014 # include <time.h>
00015 #else
00016 # if HAVE_SYS_TIME_H
00017 #  include <sys/time.h>
00018 # else
00019 #  include <time.h>
00020 # endif
00021 #endif
00022 
00023 #include <time.h>
00024 
00025 struct PCP_new_eventid {
00026        char *eventid;
00027 } ;
00028 
00029 struct PCP_event_participant {
00030        const char *address;
00031        const char *eventid;
00032 } ;
00033 
00034 struct PCP_save_event {
00035 
00036        const struct PCP_event_participant *event_participants;
00037        unsigned n_event_participants;
00038 
00039        int write_event_fd;    /* ... read from this file descriptor, or ... */
00040        char *write_event_buf; /* ... read from this 0-terminated buffer, */
00041 
00042        int flags;           /* flags - see below in PCP_commit */
00043 
00044        int (*write_event_func)(char *, int, void *);
00045        void *write_event_func_misc_ptr;
00046 } ;
00047 
00048 /*
00049 ** Structure passed to pcp_commit() and pcp_book().
00050 */
00051 
00052 struct PCP_commit {
00053        int flags;
00054 #define PCP_OK_CONFLICT     1      /* Ok if time conflict with existing events */
00055 #define PCP_OK_PROXY_ERRORS 2      /*
00056                             ** Force through the commit even if there is
00057                             ** an error from the proxy server.
00058                             */
00059 
00060 #define PCP_BYPROXY 4              /*
00061                             ** This event is placed on the calendar by
00062                             ** proxy (basically, this event has the
00063                             ** LIST_PROXY bit set by pcp_retr.
00064                             */
00065 
00066        const struct PCP_event_time *event_times;
00067        unsigned n_event_times;
00068 
00069        int errcode;         /* Extended error code */
00070 /*
00071 ** PCP error codes:
00072 */
00073 #define PCP_ERR_SYSERR          0  /* See errno */
00074 #define PCP_ERR_LOCK        1
00075 #define PCP_ERR_CONFLICT    2
00076 #define PCP_ERR_EVENTNOTFOUND      3
00077 #define PCP_ERR_EVENTLOCKED 4
00078 
00079        int (*add_conflict_callback)(const char *, time_t, time_t,
00080                                  const char *, void *);
00081        void *add_conflict_callback_ptr;
00082 
00083        /*
00084        ** Callback function invoked to specify participant userids whose
00085        ** calendars were updated.
00086        */
00087 
00088        void (*proxy_callback)(const char *,      /* "NEW" or "DELETE" */
00089                             const char *, /* userid */
00090                             void *);             /* callback ptr */
00091        void *proxy_callback_ptr;
00092 } ;
00093 
00094 struct PCP_delete {
00095        const char *id;
00096        int errcode;
00097        void (*proxy_callback)(const char *,      /* "NEW" or "DELETE" */
00098                             const char *, /* userid */
00099                             void *);             /* callback ptr */
00100        void *proxy_callback_ptr;
00101 } ;
00102 
00103 struct PCP_event_time {
00104        time_t start;
00105        time_t end;
00106 } ;
00107 
00108 struct PCP_uncancel {
00109        int errcode;
00110        int (*uncancel_conflict_callback)(const char *, time_t, time_t,
00111                                      const char *, void *);
00112        void *uncancel_conflict_callback_ptr;
00113 } ;
00114 
00115 /*
00116 ** Structure used by pcp_list_all().  List all events within the specified
00117 ** time range.
00118 */
00119 
00120 
00121 struct PCP_list_all {
00122 
00123        time_t list_from, list_to;  /* 0, or time_t */
00124 
00125        int (*callback_func)(struct PCP_list_all *, void *);
00126        void *callback_arg;
00127 
00128        /* The following fields will be initialized */
00129 
00130        time_t event_from, event_to;
00131        const char *event_id;
00132 
00133 #define LIST_CANCELLED      1
00134 #define LIST_BOOKED     2
00135 #define       LIST_PROXY    4
00136 
00137 } ;
00138 
00139 struct PCP_retr {
00140 
00141        int (*callback_func)(struct PCP_retr *, void *);
00142        void *callback_arg;
00143 
00144        const char * const * event_id_list;
00145        /* List of event-ids to retrieve */
00146 
00147        const char *event_id;       /* Event-id being retrieved */
00148        int errcode;
00149 
00150        int (*callback_retr_status)(struct PCP_retr *, int, void *);
00151        /* Initialize to retrieve the status of the events */
00152 
00153        int (*callback_retr_date)(struct PCP_retr *, time_t, time_t, void *);
00154        /* Initialize to retrieve starting/ending times */
00155 
00156        int (*callback_retr_participants)(struct PCP_retr *, const char *,
00157                                      const char *, void *);
00158        /* Initialize to retrieve other participants */
00159 
00160 
00161        /*
00162        ** If callback_headers_func is set callback_begin_func will be
00163        ** followed by 0 or more callback_headers_func(), followed by
00164        ** callback_end_func().
00165        **
00166        ** If callback_rfc822_func is set, callback_begin_func will be
00167        ** followed by 0 or more callback_rfc822_func(), followed by
00168        ** callback_end_func().
00169        */
00170 
00171        int (*callback_begin_func)(struct PCP_retr *, void *);
00172        int (*callback_headers_func)(struct PCP_retr *,
00173                                  const char *, const char *, void *);
00174        int (*callback_rfc822_func)(struct PCP_retr *, const char *, int,
00175                                 void *);
00176        int (*callback_end_func)(struct PCP_retr *, void *);
00177 } ;
00178 
00179 /* Calendar metastructure returned by driver-specific open function */
00180 
00181 struct PCP {
00182        void (*close_func)(struct PCP *);
00183        const char *(*authtoken_func)(struct PCP *);
00184        int (*cleanup_func)(struct PCP *);
00185 
00186        void (*noop_func)(struct PCP *);
00187        struct PCP_new_eventid *
00188        (*create_new_eventid_func)(struct PCP *,
00189                                const char *,
00190                                struct PCP_save_event *);
00191        void (*destroy_new_eventid_func)(struct PCP *,
00192                                     struct PCP_new_eventid *);
00193 
00194        int (*commit_func)(struct PCP *, struct PCP_new_eventid *,
00195                         struct PCP_commit *);
00196        int (*book_func)(struct PCP *, struct PCP_new_eventid *,
00197                       struct PCP_commit *);
00198 
00199        int (*list_all_func)(struct PCP *, struct PCP_list_all *);
00200        int (*cancel_func)(struct PCP *, const char *, int *);
00201        int (*uncancel_func)(struct PCP *, const char *, int,
00202                           struct PCP_uncancel *);
00203        int (*delete_func)(struct PCP *, struct PCP_delete *);
00204        int (*retr_func)(struct PCP *, struct PCP_retr *);
00205        const char *(*errmsg_func)(struct PCP *);
00206 
00207        int (*acl_func)(struct PCP *, const char *, int);
00208        int (*listacl_func)(struct PCP *,
00209                          int (*)(const char *, int, void *),
00210                          void *);
00211 } ;
00212 
00213 /******** Generic functions ********/
00214 
00215 #define pcp_errmsg(s) ( (*(s)->errmsg_func)(s))
00216 
00217 #define pcp_noop(s)   ( (*(s)->noop_func)(s))
00218 
00219 #define pcp_authtoken(s) ( (*(s)->authtoken_func)(s))
00220 /* Return authentication token, after open */
00221 
00222 #define pcp_cleanup(s) ( (*(s)->cleanup_func)(s))
00223 /* Miscellaneous cleanup, should be called after login */
00224 
00225 #define pcp_new_eventid(s,e,a) ( (*(s)->create_new_eventid_func)((s),(e),(a)))
00226 /* Allocate a new eventid. (e) - old eventid we're updating, or NULL */
00227 
00228 #define pcp_destroy_eventid(s,e) ( (*(s)->destroy_new_eventid_func)((s),(e)))
00229 /* Destroy the new eventid */
00230 
00231 /* Commit/book event */
00232 #define pcp_commit(s,e,f) ( (*(s)->commit_func)((s),(e),(f)))
00233 #define pcp_book(s,e,f) ( (*(s)->book_func)((s),(e),(f)))
00234 
00235 /* List events */
00236 #define pcp_list_all(s,f) ( (*(s)->list_all_func)((s),(f)))
00237 #define pcp_retr(s,f) ( (*(s)->retr_func)((s),(f)))
00238 
00239 /* Cancel/Uncancel/Delete events */
00240 #define pcp_cancel(s, n, e) ( (*(s)->cancel_func)((s), (n), (e)))
00241 #define pcp_uncancel(s, n, f, e) ( (*(s)->uncancel_func)((s), (n), (f), (e)))
00242 #define pcp_delete(s, p) ( (*(s)->delete_func)((s), (p)))
00243 
00244 /* Close the driver */
00245 #define pcp_close(s) ((*(s)->close_func)((s)))
00246 
00247 /* Set/Get ACL list */
00248 #define pcp_acl(s,w,f) ((*(s)->acl_func)((s), (w), (f)))
00249 #define pcp_list_acl(s,f,v) ((*(s)->listacl_func)((s), (f), (v)))
00250 #define pcp_has_acl(s) ((s)->acl_func != 0)
00251 
00252 #define PCP_ACL_MODIFY             1
00253 #define PCP_ACL_CONFLICT    2
00254 #define PCP_ACL_LIST        4
00255 #define PCP_ACL_RETR        8
00256 #define PCP_ACL_NONE        16
00257 
00258 /* DRIVER: Simple directory-based storage, with dot-locking */
00259 
00260 struct PCP *pcp_open_dir(const char *,    /* Directory name */
00261                       const char *);      /* User name */
00262 
00263 /* DRIVER: establish a connection to a server. */
00264 
00265 struct PCP *pcp_open_server(const char *, /* userid */
00266                          const char *,    /* password */
00267                          char **);        /* Return parameter: err msg */
00268 
00269 /*
00270 ** If pcp_open_server fails it returns NULL.  If errmsg arg is not null,
00271 ** it MAY be initialized to an error message (bad password, etc...)  A null
00272 ** errmsg indicates a connection failure (check errno).  The err msg buffer
00273 ** must be checked, and discarded with free().
00274 */
00275 
00276 struct PCP *pcp_reopen_server(const char *,      /* userid */
00277                            const char *,  /* authtoken from prev open */
00278                            char **);             /* Return parameter: err msg */
00279 
00280 /*
00281 ** DRIVER: open a proxy connection
00282 */
00283 
00284 struct PCP *pcp_find_proxy(const char *,  /* userid */
00285                         const char *,     /* Cluster name */
00286                         char **);         /* Return parameter: err msg */
00287 
00288 /*
00289 ** Must call pcp_set_proxy immediatelly after a succesfull return from
00290 ** pcp_find_proxy().
00291 */
00292 
00293 int pcp_set_proxy(struct PCP *,
00294                 const char *);     /* proxy from */
00295 
00296 /*
00297 ** Provide for localization of error messages.
00298 **
00299 ** PCP_STRERROR defines a function that returns a description for a PCP
00300 ** error code.  This is done in an obvious way that allows gettext() to
00301 ** be used (hint: override PCP_ERRMSG).
00302 */
00303 
00304 #ifndef PCP_ERRMSG
00305 #define PCP_ERRMSG(s) (s)
00306 #endif
00307 
00308 #define PCP_STRERROR_N(n,s) if (i == n) return (PCP_ERRMSG(s));
00309 
00310 #define PCP_STRERROR const char *pcp_strerror(int i) { \
00311        PCP_STRERROR_N(PCP_ERR_LOCK, "Unable to lock the calendar.") \
00312        PCP_STRERROR_N(PCP_ERR_CONFLICT, "Event conflict.") \
00313        PCP_STRERROR_N(PCP_ERR_EVENTNOTFOUND, "Event not found.") \
00314        PCP_STRERROR_N(PCP_ERR_EVENTLOCKED, "Event locked.") \
00315 return (0); }
00316 
00317 const char *pcp_strerror(int);
00318 
00319 /*
00320 ** Default locale-specific generic functions.
00321 ** Should be overridden to return locale-specific strings.
00322 */
00323 
00324 const char *pcp_am();       /* AM */
00325 const char *pcp_pm();       /* PM */
00326 const char *pcp_wdayname(unsigned);       /* Sun, Mon, Tue... */
00327 const char *pcp_wdayname_long(unsigned); /* Sunday, Monday, ... */
00328 const char *pcp_monthname(unsigned);      /* Jan, Feb, Mar... */
00329 const char *pcp_monthname_long(unsigned); /* January, February... */
00330 int pcp_wday(const char *); /* Sun, Mon, Tue... -> 0..7, -1 if no match */ 
00331 int pcp_month(const char *);       /* Ditto for Jan, Feb, Mar */
00332 
00333 int pcp_fmttime(char *, size_t, time_t, int);    /* Format date+time */
00334 
00335 #define FMTTIME_DATE 1
00336 #define FMTTIME_TIME 2
00337 #define FMTTIME_TIMEDROP 4
00338 
00339 int pcp_fmttimerange(char *, size_t, time_t, time_t); /* Format time range */
00340 
00341 
00342 /*-------------------------------------------------------------------------
00343 ** Parse a list of words into a time_t, i.e. "tomorrow" "8pm"...
00344 **-------------------------------------------------------------------------*/
00345 
00346 struct pcp_parse_datetime_info {
00347        const char *today_name;
00348        const char *tomorrow_name;
00349 } ;
00350 
00351 time_t pcp_parse_datetime(int *argn,
00352                        int argc,
00353                        char **argv,
00354                        struct pcp_parse_datetime_info *info);
00355 
00356 /*-------------------------------------------------------------------------
00357 ** We already have starting/ending time.  Parse "until" day, and generate
00358 ** weekly events until the given day.
00359 **-------------------------------------------------------------------------*/
00360 
00361 int pcp_parse_datetime_until(time_t start, time_t end,
00362                           /* Parsed start/time times */
00363 
00364                           int *argn,
00365                           int argc,
00366                           char **argv,
00367                          
00368                           int recurring_time,
00369 
00370                           /* Callback function receives times */
00371 
00372                           int (*save_date_time)(time_t, time_t, void *),
00373                           void *voidfunc);
00374 
00375 #define PCP_RECURRING_WEEKLY   0
00376 #define PCP_RECURRING_MONTHLY  1
00377 #define PCP_RECURRING_ANNUALLY 2
00378 
00379 /*-------------------------------------------------------------------------
00380 ** Convert year/month/day to time_t (midnight-midnight)
00381 **------------------------------------------------------------------------*/
00382 
00383 int pcp_parse_ymd(unsigned, unsigned, unsigned, time_t *, time_t *);
00384 
00385 /*-------------------------------------------------------------------------
00386 ** Convert yyyymmddhhmmss in GMT to time_t
00387 **------------------------------------------------------------------------*/
00388 
00389 time_t pcp_gmtime(int y, int m, int d, int hh, int mm, int ss);
00390 time_t pcp_gmtime_s(const char *p);
00391 
00392 
00393 void pcp_gmtimestr(time_t t, char *); /* time_t to yyyymmddhhmmss */
00394 
00395 /* --- INTERNAL FUNCTIONS --- */
00396 
00397 const struct PCP_event_time **pcp_add_sort_times(const struct PCP_event_time *,
00398                                            unsigned);
00399 int pcp_read_saveevent(struct PCP_save_event *, char *, int);
00400 
00401 extern int pcp_mksocket(const char *, const char *);
00402 
00403 void pcp_acl_name(int, char *);
00404 int pcp_acl_num(const char *);
00405 
00406 const char *pcpuid();
00407 const char *pcpgid();
00408 
00409 #endif