1 /*----------------------------------------------------------------------------
2 --
3 --  Module:           xtmCalDb
4 --
5 --  Project:          XDiary
6 --  System:           xtm - X Desktop Calendar
7 --    Subsystem:      <>
8 --    Function block: <>
9 --
10 --  Description:
11 --    Routines for the calendar database.
12 --
13 --  Filename:         xtmCalDb.c
14 --
15 --  Authors:          Roger Larsson, Ulrika Bornetun
16 --  Creation date:    1992-07-18
17 --
18 --
19 --  (C) Copyright Ulrika Bornetun, Roger Larsson (1995)
20 --      All rights reserved
21 --
22 --  Permission to use, copy, modify, and distribute this software and its
23 --  documentation for any purpose and without fee is hereby granted,
24 --  provided that the above copyright notice appear in all copies. Ulrika
25 --  Bornetun and Roger Larsson make no representations about the usability
26 --  of this software for any purpose. It is provided "as is" without express
27 --  or implied warranty.
28 ----------------------------------------------------------------------------*/
29 
30 /* SCCS module identifier. */
31 static char SCCSID[] = "@(#) Module: xtmCalDb.c, Version: 1.1, Date: 95/02/18 15:51:57";
32 
33 
34 /*----------------------------------------------------------------------------
35 --  Include files
36 ----------------------------------------------------------------------------*/
37 
38 #include <stdio.h>
39 #include <string.h>
40 #include <sys/types.h>
41 #include <sys/stat.h>
42 
43 #include <X11/Intrinsic.h>
44 
45 #include "System.h"
46 #include "LstLinked.h"
47 #include "Message.h"
48 
49 #include "xtmGlobal.h"
50 #include "xtmCustBase.h"
51 #include "xtmDbTools.h"
52 #include "xtmCalDb.h"
53 
54 
55 /*----------------------------------------------------------------------------
56 --  Macro definitions
57 ----------------------------------------------------------------------------*/
58 
59 /* Prefix to use for shadow entries. */
60 #define  SHADOW_PREFIX  "@_"
61 
62 
63 /*----------------------------------------------------------------------------
64 --  Type declarations
65 ----------------------------------------------------------------------------*/
66 
67 /* Calendar database description. */
68 typedef struct {
69 
70   /* ID to use for shadow entries. */
71   int  shadow_id;
72 
73   /* Calendars from the customize file. */
74   LST_DESC_TYPE  cal_list;
75 
76   /* Shadow calendars. */
77   LST_DESC_TYPE  shadow_cal_list;
78 
79 } CAL_DB, *CAL_DB_REF;
80 
81 
82 /* Shadow record. */
83 typedef struct {
84 
85   /* Shadow name. */
86   char  shadow_name[ 10 ];
87 
88   /* Calendar record. */
89   XTM_CD_CAL_INFO  db_info;
90 
91 } SHADOW_REC, *SHADOW_REC_PTR;
92 
93 
94 
95 /*----------------------------------------------------------------------------
96 --  Global definitions
97 ----------------------------------------------------------------------------*/
98 
99 /* Name of module. */
100 static char  *module_name = "xtmCalDb";
101 
102 
103 
104 /*----------------------------------------------------------------------------
105 --  Function prototypes
106 ----------------------------------------------------------------------------*/
107 
108 static void
109   clearCalEntry( void  *data_ref );
110 
111 static void
112   clearShadowEntry( void  *data_ref );
113 
114 static void
115   copyIncludeDb( XTM_CD_HANDLE     cal_handle,
116                  Boolean           only_if_read,
117                  XTM_CD_INCL_CALS  *from_incl_ref,
118                  XTM_CD_INCL_CALS  **to_incl_ref );
119 
120 static LST_COMPARE
121   searchDbName( XTM_CD_CAL_INFO  *db_ref,
122                 char             *db_name );
123 
124 static LST_COMPARE
125   searchShadowDbName( SHADOW_REC  *db_ref,
126                       char        *db_name );
127 
128 
129 
130 /*----------------------------------------------------------------------------
131 --  Functions
132 ----------------------------------------------------------------------------*/
133 
134 void
xtmCdAddDatabase(XTM_CD_HANDLE cal_handle,char * cal_db_name,char * location,UINT32 flags)135   xtmCdAddDatabase( XTM_CD_HANDLE  cal_handle,
136                     char           *cal_db_name,
137                     char           *location,
138                     UINT32         flags )
139 {
140 
141   /* Variables. */
142   Boolean          status;
143   CAL_DB_REF       cal_db_ref;
144   XTM_CD_CAL_INFO  db_info;
145 
146 
147   /* Code. */
148 
149   if( cal_handle == NULL )
150     return;
151 
152   cal_db_ref = (CAL_DB_REF) cal_handle;
153 
154 
155   strcpy( db_info.short_name, cal_db_name );
156   strcpy( db_info.directory,  location );
157 
158   db_info.flags             = flags;
159   db_info.incl_bg_index     = 0;
160   db_info.normal_bg_index   = 0;
161   db_info.win_stack_order   = 0;
162   db_info.has_extern_pwd    = False;
163   db_info.alarm_tags[ 0 ]   = '\0';
164   db_info.extern_host[ 0 ]  = '\0';
165   db_info.extern_pwd[ 0 ]   = '\0';
166   db_info.extern_uid[ 0 ]   = '\0';
167   db_info.extern_type[ 0 ]  = '\0';
168   db_info.mail_address[ 0 ] = '\0';
169   db_info.view_tags[ 0 ]    = '\0';
170   db_info.include           = NULL;
171 
172 
173   /* Database operations possible. */
174   xtmDbCheckDbOperations( location, True, &db_info.operations );
175 
176 
177   /* Owner? */
178   {
179     int          ret;
180     struct stat  file_status;
181 
182     db_info.owner_uid = -1;
183 
184     ret = stat( db_info.directory, &file_status );
185     if( ret == 0 )
186       db_info.owner_uid = file_status.st_uid;
187   }
188 
189 
190   /* Add the calendar entry. */
191   status = xtmCdAddEntry( cal_handle, &db_info, NULL );
192 
193 
194   return;
195 
196 } /* xtmCdAddDatabase */
197 
198 
199 /*----------------------------------------------------------------------*/
200 
201 Boolean
xtmCdAddEntry(XTM_CD_HANDLE cal_handle,XTM_CD_CAL_INFO * db_info_ref,XTM_CD_INCL_CALS * db_incl_ref)202   xtmCdAddEntry( XTM_CD_HANDLE     cal_handle,
203                  XTM_CD_CAL_INFO   *db_info_ref,
204                  XTM_CD_INCL_CALS  *db_incl_ref )
205 {
206 
207   /* Variables. */
208   CAL_DB_REF  cal_db_ref;
209   LST_STATUS  lst_status;
210 
211 
212   /* Code. */
213 
214   if( cal_handle == NULL )
215     return( False );
216 
217   cal_db_ref = (CAL_DB_REF) cal_handle;
218 
219 
220   /* Remove any duplicates. */
221   (void) xtmCdDeleteEntry( cal_handle, db_info_ref -> short_name );
222 
223 
224   /* Any included calendars? */
225   db_info_ref -> include = NULL;
226 
227   if( db_incl_ref != NULL )
228     copyIncludeDb( cal_handle, False, db_incl_ref, &db_info_ref -> include );
229 
230 
231   /* Add the entry to the end of the list. */
232   lst_status = LstLinkInsertLast( cal_db_ref -> cal_list, db_info_ref );
233   if( lst_status != LST_OK )
234     return( False );
235 
236 
237   return( True );
238 
239 } /* xtmCdAddEntry */
240 
241 
242 /*----------------------------------------------------------------------*/
243 
244 Boolean
xtmCdChangeEntry(XTM_CD_HANDLE cal_handle,char * cal_db_name,XTM_CD_CAL_INFO * new_db_info_ref,XTM_CD_INCL_CALS * new_db_incl_ref)245   xtmCdChangeEntry( XTM_CD_HANDLE     cal_handle,
246                     char              *cal_db_name,
247                     XTM_CD_CAL_INFO   *new_db_info_ref,
248                     XTM_CD_INCL_CALS  *new_db_incl_ref )
249 {
250 
251   /* Variables. */
252   CAL_DB_REF       cal_db_ref;
253   LST_STATUS       lst_status;
254   SHADOW_REC       *shadow_rec_ref;
255   XTM_CD_CAL_INFO  *db_info_ref = NULL;
256 
257 
258   /* Code. */
259 
260   if( cal_handle == NULL )
261     return( False );
262 
263   cal_db_ref = (CAL_DB_REF) cal_handle;
264 
265 
266   /* Search the entry in the main list. */
267   lst_status = LstLinkSearchFirst( cal_db_ref -> cal_list,
268                                    (void *) cal_db_name,
269                                    (EQUALS_FUNC_TYPE) searchDbName );
270 
271   if( lst_status == LST_OK ) {
272     db_info_ref = (XTM_CD_CAL_INFO *) LstLinkGetCurrentRef(
273                                         cal_db_ref -> cal_list );
274 
275 
276   /* Search the entry in the shadow list. */
277   } else {
278     lst_status = LstLinkSearchFirst( cal_db_ref -> shadow_cal_list,
279                                      (void *) cal_db_name,
280                                      (EQUALS_FUNC_TYPE) searchShadowDbName );
281     if( lst_status == LST_OK ) {
282       shadow_rec_ref = (SHADOW_REC *) LstLinkGetCurrentRef(
283                                         cal_db_ref -> shadow_cal_list );
284 
285       db_info_ref = &shadow_rec_ref -> db_info;
286     }
287 
288   } /* if */
289 
290 
291   if( db_info_ref == NULL )
292     return( False );
293 
294 
295   /* Any old included calendars? */
296   if( db_info_ref -> include != NULL )
297     SysFree( db_info_ref -> include );
298 
299 
300   /* Copy the new entry. */
301   memcpy( (void *) db_info_ref, (void *) new_db_info_ref,
302           sizeof( XTM_CD_CAL_INFO ) );
303 
304 
305   /* Any included calendars? */
306   db_info_ref -> include = NULL;
307 
308   if( new_db_incl_ref != NULL )
309     copyIncludeDb( cal_handle, False,
310                    new_db_incl_ref, &db_info_ref -> include );
311 
312 
313   return( True );
314 
315 } /* xtmCdChangeEntry */
316 
317 
318 /*----------------------------------------------------------------------*/
319 
320 XTM_CD_HANDLE
xtmCdCopy(XTM_CD_HANDLE cal_handle)321   xtmCdCopy( XTM_CD_HANDLE  cal_handle )
322 {
323 
324   /* Variables. */
325   CAL_DB_REF       cal_db_ref;
326   CAL_DB_REF       new_cal_db_ref;
327   LST_STATUS       lst_status;
328   XTM_CD_HANDLE    new_cal_handle;
329   XTM_CD_CAL_INFO  *db_ref;
330   XTM_CD_CAL_INFO  *new_db_ref;
331 
332 
333   /* Code. */
334 
335   if( cal_handle == NULL )
336     return( NULL );
337 
338   cal_db_ref = (CAL_DB_REF) cal_handle;
339 
340 
341   /* Create a new calendar database. */
342   new_cal_handle = xtmCdInitialize();
343   if( new_cal_handle == NULL )
344     return( NULL );
345 
346   new_cal_db_ref = (XTM_CD_HANDLE) new_cal_handle;
347 
348 
349   /* Search all calendars and make a copy. */
350   lst_status = LstLinkCurrentFirst( cal_db_ref -> cal_list );
351 
352   while( lst_status == LST_OK ) {
353 
354     db_ref = (XTM_CD_CAL_INFO *)
355                LstLinkGetCurrentRef( cal_db_ref -> cal_list );
356 
357 
358     /* Copy the calendar record. */
359     new_db_ref = SysNew( XTM_CD_CAL_INFO );
360 
361     memcpy( (void *) new_db_ref, (void *) db_ref, sizeof( XTM_CD_CAL_INFO ) );
362 
363 
364     /* Included calendars? */
365     if( db_ref -> include != NULL ) {
366       new_db_ref -> include = SysNew( XTM_CD_INCL_CALS );
367 
368       memcpy( (void *) new_db_ref -> include,
369               (void *) db_ref -> include,
370               sizeof( XTM_CD_INCL_CALS ) );
371     }
372 
373     /* Calendar record. */
374     (void) LstLinkInsertLast( new_cal_db_ref -> cal_list, new_db_ref );
375 
376     lst_status = LstLinkCurrentNext( cal_db_ref -> cal_list );
377 
378   } /* while */
379 
380 
381   return( new_cal_handle );
382 
383 } /* xtmCdCopy */
384 
385 
386 /*----------------------------------------------------------------------*/
387 
388 Boolean
xtmCdCreateShadowEntry(XTM_CD_HANDLE cal_handle,char * cal_db_name,char * shadow_db_name)389   xtmCdCreateShadowEntry( XTM_CD_HANDLE  cal_handle,
390                           char           *cal_db_name,
391                           char           *shadow_db_name )
392 {
393 
394   /* Variables. */
395   Boolean           ok;
396   CAL_DB_REF        cal_db_ref;
397   LST_STATUS        lst_status;
398   SHADOW_REC        db_shadow_info;
399   XTM_CD_CAL_INFO   db_info;
400   XTM_CD_INCL_CALS  db_incl;
401 
402 
403   /* Code. */
404 
405   *shadow_db_name = '\0';
406 
407   if( cal_handle == NULL )
408     return( False );
409 
410   cal_db_ref = (CAL_DB_REF) cal_handle;
411 
412 
413   /* Fetch the original database. */
414   ok = xtmCdFetchNamedDb( cal_handle, cal_db_name,
415                           &db_info, &db_incl );
416   if( ! ok )
417     return( False );
418 
419 
420   /* A new unique name for the shadow entry. */
421   sprintf( db_shadow_info.shadow_name, "%s%d",
422            SHADOW_PREFIX, cal_db_ref -> shadow_id );
423 
424   cal_db_ref -> shadow_id++;
425   if( cal_db_ref -> shadow_id > 9999 )
426     cal_db_ref -> shadow_id = 0;
427 
428 
429   memcpy( (void *) &db_shadow_info.db_info,
430           (void *) &db_info,
431           sizeof( XTM_CD_CAL_INFO ) );
432 
433 
434   /* Any included calendars? */
435   db_shadow_info.db_info.include = NULL;
436 
437   if( db_incl.no > 0 )
438     copyIncludeDb( cal_handle, True,
439                    &db_incl, &db_shadow_info.db_info.include );
440 
441 
442   /* Add the entry to the end of the list. */
443   lst_status = LstLinkInsertLast( cal_db_ref -> shadow_cal_list,
444                                   &db_shadow_info );
445   if( lst_status != LST_OK )
446     return( False );
447 
448 
449   strcpy( shadow_db_name, db_shadow_info.shadow_name );
450 
451 
452   return( True );
453 
454 } /* xtmCdCreateShadowEntry */
455 
456 
457 /*----------------------------------------------------------------------*/
458 
459 Boolean
xtmCdDeleteEntry(XTM_CD_HANDLE cal_handle,char * cal_db_name)460   xtmCdDeleteEntry( XTM_CD_HANDLE  cal_handle,
461                     char           *cal_db_name )
462 {
463 
464   /* Variables. */
465   CAL_DB_REF       cal_db_ref;
466   LST_STATUS       lst_status;
467   SHADOW_REC       *shadow_rec_ref;
468   XTM_CD_CAL_INFO  *db_info_ref;
469 
470 
471   /* Code. */
472 
473   if( cal_handle == NULL )
474     return( False );
475 
476   cal_db_ref = (CAL_DB_REF) cal_handle;
477 
478 
479   /* Search the entry in the main list. */
480   lst_status = LstLinkSearchFirst( cal_db_ref -> cal_list,
481                                    (void *) cal_db_name,
482                                    (EQUALS_FUNC_TYPE) searchDbName );
483 
484   if( lst_status == LST_OK ) {
485     db_info_ref = (XTM_CD_CAL_INFO *) LstLinkGetCurrentRef(
486                                         cal_db_ref -> cal_list );
487 
488     if( db_info_ref -> include != NULL )
489       SysFree( db_info_ref -> include );
490 
491     (void) LstLinkDeleteCurrent( cal_db_ref -> cal_list );
492 
493     return( True );
494   }
495 
496 
497   /* Search the entry in the shadow list. */
498   lst_status = LstLinkSearchFirst( cal_db_ref -> shadow_cal_list,
499                                    (void *) cal_db_name,
500                                    (EQUALS_FUNC_TYPE) searchShadowDbName );
501   if( lst_status == LST_OK ) {
502     shadow_rec_ref = (SHADOW_REC *) LstLinkGetCurrentRef(
503                                       cal_db_ref -> shadow_cal_list );
504 
505     db_info_ref = &shadow_rec_ref -> db_info;
506 
507     if( db_info_ref -> include != NULL )
508       SysFree( db_info_ref -> include );
509 
510     (void) LstLinkDeleteCurrent( cal_db_ref -> shadow_cal_list );
511 
512     return( True );
513   }
514 
515 
516   return( False );
517 
518 } /* xtmCdDeleteEntry */
519 
520 
521 /*----------------------------------------------------------------------*/
522 
523 Boolean
xtmCdFetchDbNames(XTM_CD_HANDLE cal_handle,char ** db_names)524   xtmCdFetchDbNames( XTM_CD_HANDLE  cal_handle,
525                      char           **db_names )
526 {
527 
528   /* Variables. */
529   int              db_items;
530   CAL_DB_REF       cal_db_ref;
531   LST_STATUS       lst_status;
532   XTM_CD_CAL_INFO  *db_ref;
533 
534 
535   /* Code. */
536 
537   if( cal_handle == NULL )
538     return( False );
539 
540   cal_db_ref = (CAL_DB_REF) cal_handle;
541 
542 
543   db_items = LstLinkElements( cal_db_ref -> cal_list );
544 
545   if( db_items <= 0 ) {
546     *db_names = SysNewString( " " );
547     return( False );
548   }
549 
550   /* We know the length of string to return. */
551   *db_names  = (char *) SysMalloc( db_items * (XTM_GL_MAX_CAL_NAME + 1) + 5 );
552   **db_names = '\0';
553 
554 
555   /* Search all calendars. */
556   lst_status = LstLinkCurrentFirst( cal_db_ref -> cal_list );
557 
558   while( lst_status == LST_OK ) {
559 
560     db_ref = (XTM_CD_CAL_INFO *)
561                LstLinkGetCurrentRef( cal_db_ref -> cal_list );
562 
563     strcat( *db_names, db_ref -> short_name );
564     strcat( *db_names, " " );
565 
566     lst_status = LstLinkCurrentNext( cal_db_ref -> cal_list );
567 
568   } /* while */
569 
570 
571   return( True );
572 
573 } /* xtmCdFetchDbNames */
574 
575 
576 /*----------------------------------------------------------------------*/
577 
578 Boolean
xtmCdFetchDefaultDb(XTM_CD_HANDLE cal_handle,XTM_CD_CAL_INFO * db_info_ref,XTM_CD_INCL_CALS * db_incl_ref)579   xtmCdFetchDefaultDb( XTM_CD_HANDLE     cal_handle,
580                        XTM_CD_CAL_INFO   *db_info_ref,
581                        XTM_CD_INCL_CALS  *db_incl_ref )
582 {
583 
584   /* Variables. */
585   CAL_DB_REF       cal_db_ref;
586   LST_STATUS       lst_status;
587   XTM_CD_CAL_INFO  *db_ref;
588 
589 
590   /* Code. */
591 
592   if( cal_handle == NULL )
593     return( False );
594 
595   cal_db_ref = (CAL_DB_REF) cal_handle;
596 
597 
598   if( LstLinkElements( cal_db_ref -> cal_list ) <= 0 )
599     return( False );
600 
601 
602   /* Search all calendars. */
603   lst_status = LstLinkCurrentFirst( cal_db_ref -> cal_list );
604 
605   while( lst_status == LST_OK ) {
606 
607     db_ref = (XTM_CD_CAL_INFO *)
608                LstLinkGetCurrentRef( cal_db_ref -> cal_list );
609 
610     if( flagIsSet( db_ref -> flags, XTM_CD_FLAG_DEFAULT_DB ) ) {
611       memcpy( (void *) db_info_ref,
612               (void *) db_ref,
613               sizeof( XTM_CD_CAL_INFO ) );
614 
615       if( db_incl_ref != NULL && db_info_ref -> include != NULL )
616         memcpy( (void *) db_incl_ref,
617                 (void *) db_info_ref -> include,
618                 sizeof( XTM_CD_INCL_CALS ) );
619 
620       else if( db_incl_ref != NULL )
621         db_incl_ref -> no = 0;
622 
623       db_info_ref -> include = NULL;
624 
625       return( True );
626     }
627 
628     lst_status = LstLinkCurrentNext( cal_db_ref -> cal_list );
629 
630   } /* while */
631 
632 
633   return( False );
634 
635 } /* xtmCdFetchDefaultDb */
636 
637 
638 /*----------------------------------------------------------------------*/
639 
640 Boolean
xtmCdFetchNamedDb(XTM_CD_HANDLE cal_handle,char * cal_db_name,XTM_CD_CAL_INFO * db_info_ref,XTM_CD_INCL_CALS * db_incl_ref)641   xtmCdFetchNamedDb( XTM_CD_HANDLE     cal_handle,
642                      char              *cal_db_name,
643                      XTM_CD_CAL_INFO   *db_info_ref,
644                      XTM_CD_INCL_CALS  *db_incl_ref )
645 {
646 
647   /* Variables. */
648   CAL_DB_REF       cal_db_ref;
649   LST_STATUS       lst_status;
650   SHADOW_REC       *shadow_db_ref;
651   XTM_CD_CAL_INFO  *db_ref;
652 
653 
654   /* Code. */
655 
656   if( cal_handle == NULL )
657     return( False );
658 
659   cal_db_ref = (CAL_DB_REF) cal_handle;
660 
661 
662   /* Search the entry in the main list. */
663   lst_status = LstLinkSearchFirst( cal_db_ref -> cal_list,
664                                    (void *) cal_db_name,
665                                    (EQUALS_FUNC_TYPE) searchDbName );
666 
667   if( lst_status == LST_OK ) {
668     db_ref = (XTM_CD_CAL_INFO *)
669                LstLinkGetCurrentRef( cal_db_ref -> cal_list );
670 
671     memcpy( (void *) db_info_ref,
672             (void *) db_ref,
673             sizeof( XTM_CD_CAL_INFO ) );
674 
675     if( db_incl_ref != NULL && db_info_ref -> include != NULL )
676       memcpy( (void *) db_incl_ref,
677               (void *) db_info_ref -> include,
678               sizeof( XTM_CD_INCL_CALS ) );
679 
680     else if( db_incl_ref != NULL )
681       db_incl_ref -> no = 0;
682 
683     db_info_ref -> include = NULL;
684 
685     return( True );
686   }
687 
688 
689   /* Search the entry in the shadow list. */
690   lst_status = LstLinkSearchFirst( cal_db_ref -> shadow_cal_list,
691                                    (void *) cal_db_name,
692                                    (EQUALS_FUNC_TYPE) searchShadowDbName );
693   if( lst_status == LST_OK ) {
694     shadow_db_ref = (SHADOW_REC *)
695                       LstLinkGetCurrentRef( cal_db_ref -> shadow_cal_list );
696 
697     db_ref = &shadow_db_ref -> db_info;
698 
699     memcpy( (void *) db_info_ref,
700             (void *) db_ref,
701             sizeof( XTM_CD_CAL_INFO ) );
702 
703     if( db_incl_ref != NULL && db_info_ref -> include != NULL )
704       memcpy( (void *) db_incl_ref,
705               (void *) db_info_ref -> include,
706               sizeof( XTM_CD_INCL_CALS ) );
707 
708     else if( db_incl_ref != NULL )
709       db_incl_ref -> no = 0;
710 
711     db_info_ref -> include = NULL;
712 
713     return( True );
714   }
715 
716 
717   return( False );
718 
719 } /* xtmCdFetchNamedDb */
720 
721 
722 /*----------------------------------------------------------------------*/
723 
724 void
xtmCdFree(XTM_CD_HANDLE cal_handle)725   xtmCdFree( XTM_CD_HANDLE  cal_handle )
726 {
727 
728   /* Variables. */
729   CAL_DB_REF  cal_db_ref;
730 
731 
732   /* Code. */
733 
734   if( cal_handle == NULL )
735     return;
736 
737   cal_db_ref = (CAL_DB_REF) cal_handle;
738 
739 
740   /* Free the shadow list. */
741   if( cal_db_ref -> shadow_cal_list != NULL )
742     LstLinkClearDataAndList( cal_db_ref -> shadow_cal_list,
743                              clearShadowEntry );
744 
745   /* Free the calendar list. */
746   if( cal_db_ref -> cal_list != NULL )
747     LstLinkClearDataAndList( cal_db_ref -> cal_list, clearCalEntry );
748 
749 
750   /* Free the record itself. */
751   SysFree( cal_db_ref );
752 
753 
754   return;
755 
756 } /* xtmCdFree */
757 
758 
759 /*----------------------------------------------------------------------*/
760 
761 Boolean
xtmCdFreeShadowEntry(XTM_CD_HANDLE cal_handle,char * shadow_db_name)762   xtmCdFreeShadowEntry( XTM_CD_HANDLE  cal_handle,
763                         char           *shadow_db_name )
764 {
765 
766   /* Variables. */
767   Boolean  status;
768 
769 
770   /* Code. */
771 
772   if( cal_handle == NULL )
773     return( False );
774 
775   /* The standard delete can do this. */
776   status = xtmCdDeleteEntry( cal_handle, shadow_db_name );
777 
778 
779   return( status );
780 
781 } /* xtmCdFreeShadowEntry */
782 
783 
784 /*----------------------------------------------------------------------*/
785 
786 XTM_CD_HANDLE
xtmCdInitialize()787   xtmCdInitialize()
788 {
789 
790   /* Variables. */
791   CAL_DB_REF  cal_db_ref;
792 
793 
794   /* Code. */
795 
796   /* Allocate space for a new calendar database. */
797   cal_db_ref = SysNew( CAL_DB );
798 
799   cal_db_ref -> cal_list =
800    LstLinkNew( sizeof( XTM_CD_CAL_INFO ), NULL );
801   cal_db_ref -> shadow_cal_list =
802     LstLinkNew( sizeof( SHADOW_REC ), NULL );
803 
804   cal_db_ref -> shadow_id = 0;
805 
806 
807   return( (XTM_CD_HANDLE) cal_db_ref );
808 
809 } /* xtmCdInitialize */
810 
811 
812 /*----------------------------------------------------------------------*/
813 
814 Boolean
xtmCdSearchIncludeDb(XTM_CD_INCL_CALS * db_incl_ref,char * cal_db_name)815   xtmCdSearchIncludeDb( XTM_CD_INCL_CALS  *db_incl_ref,
816                         char              *cal_db_name )
817 {
818 
819   /* Variables. */
820   int  index;
821 
822 
823   /* Code. */
824 
825   if( db_incl_ref == NULL )
826     return( False );
827 
828   for( index = 0; index < db_incl_ref -> no; index++ ) {
829     if( strcmp( cal_db_name, db_incl_ref -> db[ index ].name ) == 0 )
830       return( True );
831   }
832 
833 
834   return( False );
835 
836 } /* xtmCdSearchIncludeDb */
837 
838 
839 /*----------------------------------------------------------------------*/
840 
841 static void
clearCalEntry(void * data_ref)842   clearCalEntry( void  *data_ref )
843 {
844 
845   /* Variables. */
846   XTM_CD_CAL_INFO  *db_ref;
847 
848 
849   /* Code. */
850 
851   db_ref = (XTM_CD_CAL_INFO *) data_ref;
852 
853   if( db_ref -> include != NULL ) {
854     SysFree( db_ref -> include );
855 
856     db_ref -> include = NULL;
857   }
858 
859 
860   return;
861 
862 } /* clearCalEntry */
863 
864 
865 /*----------------------------------------------------------------------*/
866 
867 static void
clearShadowEntry(void * data_ref)868   clearShadowEntry( void  *data_ref )
869 {
870 
871   /* Variables. */
872   SHADOW_REC  *db_shadow_ref;
873 
874 
875   /* Code. */
876 
877   db_shadow_ref = (SHADOW_REC *) data_ref;
878 
879   if( db_shadow_ref -> db_info.include != NULL ) {
880     SysFree( db_shadow_ref -> db_info.include );
881 
882     db_shadow_ref -> db_info.include = NULL;
883   }
884 
885 
886   return;
887 
888 } /* clearShadowEntry */
889 
890 
891 /*----------------------------------------------------------------------*/
892 
893 static void
copyIncludeDb(XTM_CD_HANDLE cal_handle,Boolean only_if_read,XTM_CD_INCL_CALS * from_incl_ref,XTM_CD_INCL_CALS ** to_incl_ref)894   copyIncludeDb( XTM_CD_HANDLE     cal_handle,
895                  Boolean           only_if_read,
896                  XTM_CD_INCL_CALS  *from_incl_ref,
897                  XTM_CD_INCL_CALS  **to_incl_ref )
898 {
899 
900   /* Variables. */
901   Boolean          ok;
902   int              index;
903   int              index1 = 0;
904   XTM_CD_CAL_INFO  db_info;
905 
906 
907   /* Code. */
908 
909   *to_incl_ref = NULL;
910 
911   if( from_incl_ref == NULL || from_incl_ref -> no <= 0 )
912     return;
913 
914   *to_incl_ref = SysNew( XTM_CD_INCL_CALS );
915 
916 
917   /* Copy the included databases. */
918   for( index = 0; index < from_incl_ref -> no; index++ ) {
919 
920     ok = True;
921     db_info.operations = 0;
922 
923     (void) xtmCdFetchNamedDb( cal_handle,
924                               from_incl_ref -> db[ index ].name,
925                               &db_info, NULL );
926 
927     if( only_if_read &&
928         flagIsClear( db_info.operations, XTM_DB_FLAG_MODE_READ ) )
929       ok = False;
930 
931     if( ok ) {
932 
933       strcpy( (*to_incl_ref) -> db[ index1 ].name,
934               from_incl_ref  -> db[ index ].name );
935 
936       index1++;
937 
938     } /* if */
939 
940   } /* loop */
941 
942 
943   (*to_incl_ref) -> no = index1;
944 
945 
946   return;
947 
948 } /* copyIncludeDb */
949 
950 
951 /*----------------------------------------------------------------------*/
952 
953 static LST_COMPARE
searchDbName(XTM_CD_CAL_INFO * db_ref,char * db_name)954   searchDbName( XTM_CD_CAL_INFO  *db_ref,
955                 char             *db_name )
956 {
957 
958   /* Code. */
959 
960   if( strcmp( db_ref -> short_name, db_name ) == 0 )
961     return( LST_EQUAL );
962 
963 
964   return( LST_NOT_EQUAL );
965 
966 } /* searchDbName */
967 
968 
969 /*----------------------------------------------------------------------*/
970 
971 static LST_COMPARE
searchShadowDbName(SHADOW_REC * db_ref,char * db_name)972   searchShadowDbName( SHADOW_REC  *db_ref,
973                       char        *db_name )
974 {
975 
976   /* Code. */
977 
978   if( strcmp( db_ref -> shadow_name, db_name ) == 0 )
979     return( LST_EQUAL );
980 
981 
982   return( LST_NOT_EQUAL );
983 
984 } /* searchShadowDbName */
985