1 /*----------------------------------------------------------------------------
2 --
3 --  Module:           xtmEdAclAfs
4 --
5 --  Project:          Xdiary
6 --  System:           xtm - X Desktop Calendar
7 --    Subsystem:      <>
8 --    Function block: <>
9 --
10 --  Description:
11 --    Edit the ACL list for a calendar in an AFS file system.
12 --
13 --  Filename:         xtmEdAclAfs.c
14 --
15 --  Authors:          Roger Larsson, Ulrika Bornetun
16 --  Creation date:    1992-10-30
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: xtmEdAclAfs.c, Version: 1.1, Date: 95/02/18 15:58:53";
32 
33 
34 /*----------------------------------------------------------------------------
35 --  Include files
36 ----------------------------------------------------------------------------*/
37 
38 #include <pwd.h>
39 #include <string.h>
40 #include <stdlib.h>
41 #include <stdio.h>
42 #include <sys/types.h>
43 #include <sys/stat.h>
44 
45 #include <X11/Intrinsic.h>
46 #include <X11/Shell.h>
47 
48 #include <Xm/Protocols.h>
49 
50 #include <Xm/Xm.h>
51 #include <Xm/List.h>
52 #include <Xm/RowColumn.h>
53 #include <Xm/Text.h>
54 
55 #include "System.h"
56 #include "LstLinked.h"
57 #include "Message.h"
58 
59 #include "msgXdiary.h"
60 #include "xtmGlobal.h"
61 #include "xtmAccBase.h"
62 #include "xtmAfsAclBs.h"
63 #include "xtmHelp.h"
64 #include "xitError.h"
65 #include "xitInfo.h"
66 #include "xitTools.h"
67 #include "xtmEdAclAfs.h"
68 
69 
70 /*----------------------------------------------------------------------------
71 --  Macro definitions
72 ----------------------------------------------------------------------------*/
73 
74 /* The number of ACLs we can handle. */
75 #define MAX_ACLS         200
76 
77 
78 /* Local widgets in the window. */
79 #define aclLi            dataLocalW[  0 ]
80 #define actionRc         dataLocalW[  1 ]
81 #define calLa            dataLocalW[  2 ]
82 #define flagMsgTb        dataLocalW[  3 ]
83 #define flagRc           dataLocalW[  4 ]
84 #define flagReadTb       dataLocalW[  5 ]
85 #define flagWriteTb      dataLocalW[  6 ]
86 #define idLa             dataLocalW[  7 ]
87 #define idTx             dataLocalW[  8 ]
88 
89 
90 /*----------------------------------------------------------------------------
91 --  Type declarations
92 ----------------------------------------------------------------------------*/
93 
94 /* Record describing one instance of the ACL window. */
95 typedef struct {
96 
97   /* Has any fields changed? */
98   Boolean  field_changed;
99 
100   /* Has any ACLs changed? */
101   Boolean  acl_changed;
102 
103   /* Location of the calendar to edit. */
104   char  cal_location[ XTM_GL_MAX_LOCATION + 1 ];
105 
106   /* Name of the calendar to edit. */
107   char  cal_name[ XTM_GL_MAX_CAL_NAME + 1 ];
108 
109   /* Default acl for the system administrators. */
110   char  *system_admin_acl;
111 
112   /* ACL window. */
113   Widget  aclW;
114 
115   /* Info reference. */
116   XIT_IN_HANDLE  info_handle;
117 
118   /* Customization data. */
119   XTM_GL_CUSTOM_DATA_REF  custom_data_ref;
120 
121   /* Callback and user data to inform our creator of specific actions. */
122   XTM_AA_ACTION_CB  actionCB;
123   void              *user_data;
124 
125 } ACL_REC, *ACL_REC_REF;
126 
127 
128 /*----------------------------------------------------------------------------
129 --  Global definitions
130 ----------------------------------------------------------------------------*/
131 
132 /* Name of module. */
133 static char  *module_name = "xtmEditAclAfs";
134 
135 /* IDs for the help windows. */
136 static char  *acl_window_id = "EditAclAfs";
137 
138 
139 /*----------------------------------------------------------------------------
140 --  Function prototypes
141 ----------------------------------------------------------------------------*/
142 
143 static void
144   accessListCB( Widget                widget,
145                 ACL_REC_REF           acl_ref,
146                 XmListCallbackStruct  *call_data );
147 
148 static void
149   addCB( Widget       widget,
150          ACL_REC_REF  acl_ref,
151          XtPointer    call_data );
152 
153 static void
154   cancelCB( Widget       widget,
155             ACL_REC_REF  acl_ref,
156             XtPointer    call_data );
157 
158 static void
159   closeCB( Widget       widget,
160            ACL_REC_REF  acl_ref,
161            XtPointer    call_data );
162 
163 static Widget
164   createAclWindow( ACL_REC_REF  acl_ref,
165                    Widget       parent );
166 
167 static void
168   deleteCB( Widget       widget,
169             ACL_REC_REF  acl_ref,
170             XtPointer    call_data );
171 
172 static void
173   destroyCB( Widget       widget,
174              ACL_REC_REF  acl_ref,
175              XtPointer    call_data );
176 
177 static void
178   fieldChangedCB( Widget       widget,
179                   ACL_REC_REF  acl_ref,
180                   XtPointer    call_data );
181 
182 static void
183   helpCB( Widget       widget,
184           ACL_REC_REF  acl_ref,
185           XtPointer    call_data );
186 
187 static void
188   okCB( Widget       widget,
189         ACL_REC_REF  acl_ref,
190         XtPointer    call_data );
191 
192 static void
193   saveAccessInfo( ACL_REC_REF  acl_ref );
194 
195 static void
196   saveAndCloseCB( Widget       widget,
197                   ACL_REC_REF  acl_ref,
198                   XtPointer    call_data );
199 
200 static void
201   setAccessData( ACL_REC_REF  acl_ref );
202 
203 static void
204   setAccessItem( ACL_REC_REF  acl_ref,
205                  char         *id,
206                  int          flags );
207 
208 static void
209   setAction( ACL_REC_REF  acl_ref,
210              Boolean      add_active,
211              Boolean      delete_active );
212 
213 static void
214   setEmptyItem( ACL_REC_REF  acl_ref );
215 
216 
217 
218 /*----------------------------------------------------------------------------
219 --  Functions
220 ----------------------------------------------------------------------------*/
221 
222 XTM_AA_HANDLE
xtmAaInitialize(XTM_GL_CUSTOM_DATA_REF custom_data_ref,XIT_IN_HANDLE info_handle,Widget parent,char * system_admin_acl,XTM_AA_ACTION_CB actionCB,void * user_data)223   xtmAaInitialize( XTM_GL_CUSTOM_DATA_REF  custom_data_ref,
224                    XIT_IN_HANDLE           info_handle,
225                    Widget                  parent,
226                    char                    *system_admin_acl,
227                    XTM_AA_ACTION_CB        actionCB,
228                    void                    *user_data )
229 {
230 
231   /* Variables. */
232   ACL_REC_REF  acl_ref;
233 
234 
235   /* Code. */
236 
237   /* Create and initialize our private data. */
238   acl_ref = SysNew( ACL_REC );
239   if( acl_ref == NULL )
240     return( NULL );
241 
242   acl_ref -> custom_data_ref = custom_data_ref;
243   acl_ref -> info_handle     = info_handle;
244   acl_ref -> field_changed   = False;
245   acl_ref -> actionCB        = actionCB;
246   acl_ref -> user_data       = user_data;
247   acl_ref -> aclW            = NULL;
248 
249   acl_ref -> system_admin_acl = SysNewString( system_admin_acl );
250 
251 
252   /* Create the base window. */
253   acl_ref -> aclW = createAclWindow( acl_ref, parent );
254   if( acl_ref -> aclW == NULL ) {
255     SysFree( acl_ref );
256 
257     return( NULL );
258   }
259 
260 
261   return( (XTM_AA_HANDLE) acl_ref );
262 
263 } /* xtmAaInitialize */
264 
265 
266 /*----------------------------------------------------------------------*/
267 
268 void
xtmAaDestroy(XTM_AA_HANDLE acl_handle)269   xtmAaDestroy( XTM_AA_HANDLE  acl_handle )
270 {
271 
272   /* Variables. */
273   ACL_REC_REF  acl_ref;
274 
275 
276   /* Code. */
277 
278   if( acl_handle == NULL )
279     return;
280 
281   /* Our private data. */
282   acl_ref = (ACL_REC_REF) acl_handle;
283 
284   /* Get rid of all windows. */
285   if( acl_ref -> aclW != NULL )
286     XtDestroyWidget( acl_ref -> aclW );
287 
288 
289   return;
290 
291 } /* xtmAaDestroy */
292 
293 
294 /*----------------------------------------------------------------------*/
295 
296 void
xtmAaEditAcl(XTM_AA_HANDLE acl_handle,char * cal_name,char * cal_location)297   xtmAaEditAcl( XTM_AA_HANDLE  acl_handle,
298                 char           *cal_name,
299                 char           *cal_location )
300 {
301 
302   /* Variables. */
303   Arg          args[ 10 ];
304   Cardinal     n;
305   ACL_REC_REF  acl_ref;
306 
307 
308   /* Code. */
309 
310   /* Our private data. */
311   acl_ref = (ACL_REC_REF) acl_handle;
312 
313 
314   /* Save the name and location of the calendar. */
315   strncpy( acl_ref -> cal_name, cal_name, XTM_GL_MAX_CAL_NAME );
316   acl_ref -> cal_name[ XTM_GL_MAX_CAL_NAME ] = '\0';
317 
318   strncpy( acl_ref -> cal_location, cal_location, XTM_GL_MAX_LOCATION );
319   acl_ref -> cal_location[ XTM_GL_MAX_LOCATION ] = '\0';
320 
321 
322   /* Make sure the window is visible. */
323   XtManageChild( acl_ref -> aclW );
324 
325 
326   /* Make sure our children don't spoil our size. */
327   n = 0;
328   XtSetArg( args[ n ], XmNallowShellResize, False ); n++;
329   XtSetValues( XtParent( acl_ref -> aclW ), args, n );
330 
331 
332   /* Set the window data. */
333   setAccessData( acl_ref );
334 
335   acl_ref -> acl_changed = False;
336 
337 
338   return;
339 
340 } /* xtmAaEditAcl */
341 
342 
343 /*----------------------------------------------------------------------*/
344 
345 static Widget
createAclWindow(ACL_REC_REF acl_ref,Widget parent)346   createAclWindow( ACL_REC_REF  acl_ref,
347                    Widget       parent )
348 {
349 
350   /* Variables. */
351   int       index;
352   Arg       args[ 10 ];
353   Cardinal  n;
354   Widget    actionBu[ 2 ];
355   Widget    aclFd;
356   Widget    dataLocalW[ 9 ];
357   Widget    workFo;
358 
359   static XIT_PUSH_STRUCT access_action_def[] = {
360     { "AddPb",     "", "", True, NULL },
361     { "DeletePb",  "", "", True, NULL },
362   };
363 
364   static XIT_TEXT_STRUCT text_buffer[] = {
365     { "IdTx",  NULL, 1, True },
366   };
367 
368   static XIT_ACTION_AREA_ITEM  action_buttons[] = {
369     { "",   okCB,     NULL },
370     { NULL, NULL,     NULL },
371     { "",   cancelCB, NULL },
372     { NULL, NULL,     NULL },
373     { "",   helpCB,   NULL },
374   };
375 
376 
377   /* Code. */
378 
379   action_buttons[ 0 ].label = msgGetText( MXDI_OK_BUTTON );
380   action_buttons[ 0 ].data  = acl_ref;
381   action_buttons[ 2 ].label = msgGetText( MXDI_CANCEL_BUTTON );
382   action_buttons[ 2 ].data  = acl_ref;
383   action_buttons[ 4 ].label = msgGetText( MXDI_HELP_BUTTON );
384   action_buttons[ 4 ].data  = acl_ref;
385 
386   access_action_def[ 0 ].title = msgGetText( MXDI_ADD_CHANGE_ITEM );
387   access_action_def[ 1 ].title = msgGetText( MXDI_DELETE_ITEM );
388 
389 
390   /* Create a form dialog with buttons. */
391   aclFd = xitCreateFormDialog( parent, "AclFd",
392                                1, 0,
393                                action_buttons,
394                                XtNumber( action_buttons ) );
395 
396   XtAddCallback( aclFd, XmNdestroyCallback,
397                  (XtCallbackProc) destroyCB, (XtPointer) acl_ref );
398 
399   /* We want to know when this window is closed. */
400   {
401     Atom  wm_delete_window;
402 
403     wm_delete_window = XmInternAtom( XtDisplay( aclFd ),
404                                      "WM_DELETE_WINDOW", False );
405 
406     XmAddWMProtocols( XtParent( aclFd ), &wm_delete_window, 1 );
407     XmAddWMProtocolCallback( XtParent( aclFd ), wm_delete_window,
408                              (XtCallbackProc) cancelCB, (XtPointer) acl_ref );
409   } /* block */
410 
411   n = 0;
412   XtSetArg( args[ n ], XmNtitle, msgGetText( MXDI_AFS_ACCESS_TITLE ) ); n++;
413   XtSetValues( XtParent( aclFd ), args, n );
414 
415 
416   /* Form to hold the information. */
417   workFo = XtNameToWidget( aclFd, "AclFdFo" );
418 
419 
420   /* The calendar we are editing. */
421   calLa = xitCreateLabel( workFo, "CalLa", "", -1 );
422 
423 
424   /* List with access information. */
425   n = 0;
426   XtSetArg( args[ n ], XmNlistSizePolicy,         XmCONSTANT ); n++;
427   XtSetArg( args[ n ], XmNscrollBarDisplayPolicy, XmSTATIC ); n++;
428   XtSetArg( args[ n ], XmNselectionPolicy,        XmSINGLE_SELECT ); n++;
429   XtSetArg( args[ n ], XmNlistMarginHeight,       5 ); n++;
430   XtSetArg( args[ n ], XmNlistMarginWidth,        5 ); n++;
431   aclLi = XmCreateScrolledList( workFo, "AclLi", args, n );
432 
433   XtAddCallback( aclLi, XmNsingleSelectionCallback,
434                  (XtCallbackProc) accessListCB, (XtPointer) acl_ref );
435   XtAddCallback( aclLi, XmNdefaultActionCallback,
436                  (XtCallbackProc) accessListCB, (XtPointer) acl_ref );
437 
438 
439   /* AFS ID. */
440   idLa = xitCreateLabel( workFo, "IdLa",
441                          msgGetText( MXDI_USER_LABEL ), -1 );
442 
443   idTx = xitCreateText( workFo, &text_buffer[ 0 ] );
444 
445   XtAddCallback( idTx, XmNvalueChangedCallback,
446                  (XtCallbackProc) fieldChangedCB, (XtPointer) acl_ref );
447 
448 
449   /* Access flags. */
450   n = 0;
451   XtSetArg( args[ n ], XmNorientation, XmHORIZONTAL ); n++;
452   flagRc = XmCreateRowColumn( workFo, "FlagRc", args, n );
453 
454   flagReadTb  = xitCreateToggleButton(
455                   flagRc, "FlagReadTb",
456                   msgGetText( MXDI_READ_LABEL ), False );
457 
458   flagWriteTb = xitCreateToggleButton(
459                   flagRc, "FlagWriteTb",
460                   msgGetText( MXDI_WRITE_LABEL ), False );
461 
462   flagMsgTb   = xitCreateToggleButton(
463                   flagRc, "FlagMsgTb",
464                   msgGetText( MXDI_MESSAGE_PRIV_LABEL ), False );
465 
466 
467   /* Action (add, delete and change). */
468   n = 0;
469   XtSetArg( args[ n ], XmNorientation,  XmHORIZONTAL ); n++;
470   XtSetArg( args[ n ], XmNspacing,      10 ); n++;
471   XtSetArg( args[ n ], XmNmarginHeight, 10 ); n++;
472   actionRc = XmCreateRowColumn( workFo, "ActionRc", args, n );
473 
474   for( index = 0; index < XtNumber( access_action_def ); index++ )
475     actionBu[ index ] = xitCreatePushButton( actionRc,
476                                              &access_action_def[ index ] );
477 
478   XtAddCallback( actionBu[ 0 ], XmNactivateCallback,
479                  (XtCallbackProc) addCB, (XtPointer) acl_ref );
480   XtAddCallback( actionBu[ 1 ], XmNactivateCallback,
481                  (XtCallbackProc) deleteCB, (XtPointer) acl_ref );
482 
483 
484   /* Place the various elements together. */
485   xitAttachWidget( calLa,
486                    XmATTACH_FORM, NULL, XmATTACH_FORM, NULL,
487                    XmATTACH_NONE, NULL, XmATTACH_NONE, NULL );
488   xitAttachWidget( XtParent( aclLi ),
489                    XmATTACH_WIDGET, calLa, XmATTACH_FORM, NULL,
490                    XmATTACH_NONE,   NULL,  XmATTACH_NONE, NULL );
491   xitAttachWidget( idLa,
492                    XmATTACH_WIDGET, XtParent( aclLi ), XmATTACH_FORM, NULL,
493                    XmATTACH_NONE,   NULL,              XmATTACH_NONE, NULL );
494   xitAttachWidget( idTx,
495                    XmATTACH_WIDGET, idLa, XmATTACH_FORM, NULL,
496                    XmATTACH_FORM,   NULL, XmATTACH_NONE, NULL );
497   xitAttachWidget( flagRc,
498                    XmATTACH_WIDGET, idTx, XmATTACH_FORM, NULL,
499                    XmATTACH_NONE,   NULL, XmATTACH_NONE, NULL );
500   xitAttachWidget( actionRc,
501                    XmATTACH_WIDGET, flagRc, XmATTACH_FORM, NULL,
502                    XmATTACH_NONE,   NULL,   XmATTACH_NONE, NULL );
503 
504   /* Make sure there is enough space between the children. */
505   n = 0;
506   XtSetArg( args[ n ], XmNtopOffset,    5 ); n++;
507   XtSetArg( args[ n ], XmNleftOffset,   5 ); n++;
508   XtSetArg( args[ n ], XmNrightOffset,  5 ); n++;
509   XtSetArg( args[ n ], XmNbottomOffset, 5 ); n++;
510   XtSetValues( calLa,             args, n );
511   XtSetValues( XtParent( aclLi ), args, n );
512   XtSetValues( idLa,              args, n );
513   XtSetValues( idTx,              args, n );
514   XtSetValues( flagRc,            args, n );
515   XtSetValues( actionRc,          args, n );
516 
517 
518   /* Manage the widgets. */
519   XtManageChildren( actionBu, XtNumber( actionBu ) );
520 
521   xitManageChildren( dataLocalW, XtNumber( dataLocalW ) );
522 
523   /* Set the size of the window. */
524   xitSetSizeFormDialog( aclFd, True );
525 
526 
527   /* Make the final attachments. */
528   xitAttachWidget( actionRc,
529                    XmATTACH_NONE, NULL, XmATTACH_FORM, NULL,
530                    XmATTACH_NONE, NULL, XmATTACH_FORM, NULL );
531   xitAttachWidget( flagRc,
532                    XmATTACH_NONE, NULL, XmATTACH_FORM,   NULL,
533                    XmATTACH_NONE, NULL, XmATTACH_WIDGET, actionRc );
534   xitAttachWidget( idTx,
535                    XmATTACH_NONE, NULL, XmATTACH_FORM,   NULL,
536                    XmATTACH_FORM, NULL, XmATTACH_WIDGET, flagRc );
537   xitAttachWidget( idLa,
538                    XmATTACH_NONE, NULL, XmATTACH_FORM,   NULL,
539                    XmATTACH_NONE, NULL, XmATTACH_WIDGET, idTx );
540   xitAttachWidget( XtParent( aclLi ),
541                    XmATTACH_WIDGET, calLa, XmATTACH_FORM,   NULL,
542                    XmATTACH_FORM,   NULL,  XmATTACH_WIDGET, idLa );
543 
544 
545   return( aclFd );
546 
547 } /* createAclWindow */
548 
549 
550 /*----------------------------------------------------------------------*/
551 
552 static void
saveAccessInfo(ACL_REC_REF acl_ref)553   saveAccessInfo( ACL_REC_REF  acl_ref )
554 {
555 
556   /* Variables. */
557   int                  index;
558   int                  item_count;
559   UINT32               diary_rights;
560   UINT32               message_rights;
561   char                 flags[ 30 ];
562   char                 *char_ref;
563   Arg                  args[ 3 ];
564   Cardinal             n;
565   Widget               mainW;
566   Widget               tempW;
567   XmString             *items;
568   LST_DESC_TYPE        access_info;
569   LST_DESC_TYPE        access_diary;
570   LST_DESC_TYPE        access_message;
571   LST_STATUS           lst_status;
572   XTM_AB_AFS_ACL_INFO  acl_id;
573   XTM_AB_STATUS        ab_status;
574   XTM_AF_ACL_INFO      afs_acl_entry;
575   XTM_AF_STATUS        af_status;
576 
577 
578   /* Code. */
579 
580   mainW = XtNameToWidget( acl_ref -> aclW, "AclFdFo" );
581 
582 
583   /* Create an new access list. */
584   access_info    = LstLinkNew( sizeof( XTM_AB_AFS_ACL_INFO ), NULL );
585   access_diary   = LstLinkNew( sizeof( XTM_AF_ACL_INFO ),     NULL );
586   access_message = LstLinkNew( sizeof( XTM_AF_ACL_INFO ),     NULL );
587 
588 
589   /* Fetch information from the access list. */
590   tempW = XtNameToWidget( mainW, "AclLiSW.AclLi" );
591 
592   n = 0;
593   XtSetArg( args[ n ], XmNitemCount, &item_count ); n++;
594   XtSetArg( args[ n ], XmNitems,     &items ); n++;
595   XtGetValues( tempW, args, n );
596 
597   for( index = 0; index < item_count; index++ ) {
598 
599     char_ref = xitStringGetString( *(items + index), CS );
600 
601     sscanf( char_ref, "%s %s", acl_id.id, flags );
602     SysFree( char_ref );
603 
604 
605     /* Check the flags. */
606     acl_id.flags   = 0;
607     diary_rights   = (XTM_AF_FLAG_LOOKUP | XTM_AF_FLAG_LOCK);
608     message_rights = XTM_AF_FLAG_LOOKUP;
609 
610     if( strchr( flags, 'r' ) != NULL ) {
611       flagSet( acl_id.flags, XTM_AB_FLAG_READ );
612       flagSet( diary_rights, XTM_AF_FLAG_READ );
613     }
614 
615     if( strchr( flags, 'w' ) != NULL ) {
616       flagSet( acl_id.flags, XTM_AB_FLAG_WRITE );
617       flagSet( acl_id.flags, XTM_AB_FLAG_READ );
618       flagSet( diary_rights, XTM_AF_FLAG_WRITE );
619       flagSet( diary_rights, XTM_AF_FLAG_READ );
620       flagSet( diary_rights, XTM_AF_FLAG_DELETE );
621       flagSet( diary_rights, XTM_AF_FLAG_INSERT );
622     }
623 
624     if( strchr( flags, 'm' ) != NULL ) {
625       flagSet( acl_id.flags, XTM_AB_FLAG_MSG );
626       flagSet( message_rights, (XTM_AF_FLAG_INSERT | XTM_AF_FLAG_LOCK) );
627     }
628 
629     /* Save the entry. */
630     lst_status = LstLinkInsertLast( access_info, &acl_id );
631 
632     /* AFS ACL definitions. */
633     afs_acl_entry.positive = True;
634     strcpy( afs_acl_entry.id, acl_id.id );
635 
636     /* Diary rights. */
637     afs_acl_entry.rights = diary_rights;
638     lst_status = LstLinkInsertLast( access_diary, &afs_acl_entry );
639 
640     /* Message rights. */
641     afs_acl_entry.rights = message_rights;
642     lst_status = LstLinkInsertLast( access_message, &afs_acl_entry );
643 
644   } /* loop */
645 
646 
647   /* The owner has all privileges. */
648   {
649     struct passwd  *password_ref;
650 
651     afs_acl_entry.rights = XTM_AF_FLAG_ALL;
652 
653     password_ref = getpwuid( getuid() );
654     strcpy( afs_acl_entry.id, password_ref -> pw_name );
655 
656     lst_status = LstLinkInsertFirst( access_diary,   &afs_acl_entry );
657     lst_status = LstLinkInsertFirst( access_message, &afs_acl_entry );
658   }
659 
660 
661   /* system:administrators privileges? */
662   if( strlen( acl_ref -> system_admin_acl ) > 0 ) {
663     strcpy( afs_acl_entry.id, "system:administrators" );
664 
665     afs_acl_entry.rights = xtmAfAclStringToFlag( acl_ref ->
666                                                  system_admin_acl );
667 
668     lst_status = LstLinkInsertFirst( access_diary,   &afs_acl_entry );
669     lst_status = LstLinkInsertFirst( access_message, &afs_acl_entry );
670   }
671 
672 
673   /* Save the access informatuon. */
674   ab_status = xtmAbSaveAfsAccessInfo( acl_ref -> cal_location, access_info );
675 
676   /* Set ACL for Diary directory. */
677   af_status = xtmAfSetAclForFile( acl_ref -> cal_location, access_diary );
678 
679   /* Set ACL for Message directory. */
680   char_ref = (char *) SysMalloc( strlen( acl_ref -> cal_location ) + 50 );
681   sprintf( char_ref, "%s/Message", acl_ref -> cal_location );
682 
683   af_status = xtmAfSetAclForFile( char_ref, access_message );
684   SysFree( char_ref );
685 
686 
687   /* Free access list. */
688   LstLinkClear( access_info );
689   LstLinkClear( access_diary );
690   LstLinkClear( access_message );
691 
692 
693   return;
694 
695 } /* saveAccessInfo */
696 
697 
698 /*----------------------------------------------------------------------*/
699 
700 static void
setAccessData(ACL_REC_REF acl_ref)701   setAccessData( ACL_REC_REF  acl_ref )
702 {
703 
704   /* Variables. */
705   int                  index;
706   int                  index1;
707   char                 flags_buffer[ 20 ];
708   char                 *char_ref;
709   Arg                  args[ 5 ];
710   Cardinal             n;
711   Widget               mainW;
712   Widget               tempW;
713   XmString             list_items[ MAX_ACLS ];
714   LST_DESC_TYPE        access_info;
715   LST_STATUS           lst_status;
716   XTM_AB_AFS_ACL_INFO  acl_info;
717 
718 
719   /* Code. */
720 
721   mainW = XtNameToWidget( acl_ref -> aclW, "AclFdFo" );
722 
723 
724   /* Name of the calendar we are using. */
725   char_ref = (char *) SysMalloc( strlen( acl_ref -> cal_name ) +
726                                  strlen( acl_ref -> cal_location ) + 10 );
727 
728   sprintf( char_ref, "%s (%s)",
729            acl_ref -> cal_name, acl_ref -> cal_location );
730 
731   tempW = XtNameToWidget( mainW, "CalLa" );
732   xitStringSetLabel( tempW, char_ref );
733 
734   SysFree( char_ref );
735 
736 
737   /* All is empty. */
738   setEmptyItem( acl_ref );
739 
740 
741   /* Fetch the access information for this database. */
742   xtmAbGetAfsAccessInfo( acl_ref -> cal_location, &access_info );
743 
744   /* Set access control info. */
745   if( LstLinkElements( access_info ) <= 0 )
746     return;
747 
748 
749   index = 0;
750 
751   lst_status = LstLinkCurrentFirst( access_info );
752 
753   while( lst_status == LST_OK ) {
754     lst_status = LstLinkGetCurrent( access_info, &acl_info );
755 
756     /* Fetch the flags values. */
757     flags_buffer[ 0 ] = '\0';
758 
759     if( flagIsSet( acl_info.flags, XTM_AB_FLAG_READ ) )
760       strcat( flags_buffer, "r" );
761     else
762       strcat( flags_buffer, "-" );
763 
764     if( flagIsSet( acl_info.flags, XTM_AB_FLAG_WRITE ) )
765       strcat( flags_buffer, "w" );
766     else
767       strcat( flags_buffer, "-" );
768 
769     if( flagIsSet( acl_info.flags, XTM_AB_FLAG_MSG ) )
770       strcat( flags_buffer, "m" );
771     else
772       strcat( flags_buffer, "-" );
773 
774     char_ref = (char *) SysMalloc( strlen( acl_info.id ) + 50 );
775     sprintf( char_ref, "%s  (%s)", acl_info.id, flags_buffer );
776 
777     list_items[ index ] = XmStringCreate( char_ref, CS );
778     SysFree( char_ref );
779 
780     index++;
781 
782     if( index >= MAX_ACLS )
783       break;
784 
785     /* Next entry. */
786     lst_status = LstLinkCurrentNext( access_info );
787 
788   } /* while */
789 
790 
791   tempW = XtNameToWidget( mainW, "AclLiSW.AclLi" );
792 
793   /* Assign the database locations to the list. */
794   n = 0;
795   XtSetArg( args[ n ], XmNitems, list_items ); n++;
796   XtSetArg( args[ n ], XmNitemCount, index ); n++;
797   XtSetArg( args[ n ], XmNselectedItemCount, 0 ); n++;
798   XtSetValues( tempW, args, n );
799 
800   /* Free allocated memory. */
801   for( index1 = 0; index1 < index; index1++ )
802     XmStringFree( list_items[ index1 ] );
803 
804 
805   return;
806 
807 } /* setAccessData */
808 
809 
810 /*----------------------------------------------------------------------*/
811 
812 static void
setAccessItem(ACL_REC_REF acl_ref,char * id,int flags)813   setAccessItem( ACL_REC_REF  acl_ref,
814                  char         *id,
815                  int          flags )
816 {
817 
818   /* Variables. */
819   int       found_position;
820   int       index;
821   int       item_count;
822   char      flags_buffer[ 20 ];
823   char      read_id[ XTM_AB_MAX_AFS_ID_LENGTH + 1 ];
824   char      *char_ref;
825   Arg       args[ 3 ];
826   Cardinal  n;
827   Widget    listW;
828   Widget    mainW;
829   XmString  *items;
830   XmString  xstr;
831 
832 
833   /* Code. */
834 
835   mainW = XtNameToWidget( acl_ref -> aclW, "AclFdFo" );
836 
837 
838   /* Fetch the flags values. */
839   flags_buffer[ 0 ] = '\0';
840 
841   if( flagIsSet( flags, XTM_AB_FLAG_READ ) )
842     strcat( flags_buffer, "r" );
843   else
844     strcat( flags_buffer, "-" );
845 
846   if( flagIsSet( flags, XTM_AB_FLAG_WRITE ) )
847     strcat( flags_buffer, "w" );
848   else
849     strcat( flags_buffer, "-" );
850 
851   if( flagIsSet( flags, XTM_AB_FLAG_MSG ) )
852     strcat( flags_buffer, "m" );
853   else
854     strcat( flags_buffer, "-" );
855 
856   if( flagIsSet( flags, XTM_AB_FLAG_PRIV ) )
857     strcat( flags_buffer, "p" );
858   else
859     strcat( flags_buffer, "-" );
860 
861   /* Line to add to list. */
862   char_ref = (char *) SysMalloc( strlen( id ) + 50 );
863   sprintf( char_ref, "%s  %s", id, flags_buffer );
864 
865   xstr = XmStringCreate( char_ref, CS );
866   SysFree( char_ref );
867 
868 
869   /* Check if we have this id before? */
870   listW = XtNameToWidget( mainW, "AclLiSW.AclLi" );
871 
872   n = 0;
873   XtSetArg( args[ n ], XmNitemCount, &item_count ); n++;
874   XtSetArg( args[ n ], XmNitems,     &items ); n++;
875   XtGetValues( listW, args, n );
876 
877   found_position = 0;
878 
879   for( index = 0; index < item_count; index++ ) {
880 
881     char_ref = xitStringGetString( *(items + index), CS );
882     sscanf( char_ref, "%s", read_id );
883     SysFree( char_ref );
884 
885     if( strcmp( read_id, id ) == 0 )
886       found_position = index + 1;
887 
888   } /* loop */
889 
890   /* Does the entry already exist? */
891   if( found_position > 0 )
892     XmListDeletePos( listW, found_position );
893 
894 
895   /* Store the new location. */
896   XmListAddItem( listW, xstr, 0 );
897   XmListSetBottomPos( listW, 0 );
898   XmListDeselectAllItems( listW );
899 
900   XmStringFree( xstr );
901 
902 
903   return;
904 
905 } /* setAccessItem */
906 
907 
908 /*----------------------------------------------------------------------*/
909 
910 static void
setAction(ACL_REC_REF acl_ref,Boolean add_active,Boolean delete_active)911   setAction( ACL_REC_REF  acl_ref,
912              Boolean      add_active,
913              Boolean      delete_active )
914 {
915 
916   /* Variables. */
917   Widget  mainW;
918   Widget  tempW;
919 
920 
921   /* Code. */
922 
923   mainW = XtNameToWidget( acl_ref -> aclW, "AclFdFo" );
924 
925   tempW = XtNameToWidget( mainW, "ActionRc.AddPb" );
926   XtSetSensitive( tempW, add_active );
927 
928   tempW = XtNameToWidget( mainW, "ActionRc.DeletePb" );
929   XtSetSensitive( tempW, delete_active );
930 
931 
932   return;
933 
934 } /* setAction */
935 
936 
937 /*----------------------------------------------------------------------*/
938 
939 static void
setEmptyItem(ACL_REC_REF acl_ref)940   setEmptyItem( ACL_REC_REF  acl_ref )
941 {
942 
943   /* Variables. */
944   Widget  mainW;
945   Widget  tempW;
946 
947 
948   /* Code. */
949 
950   mainW = XtNameToWidget( acl_ref -> aclW, "AclFdFo" );
951 
952   /* Empty the user, group and position field. */
953   tempW = XtNameToWidget( mainW, "IdTx" );
954   XmTextSetString( tempW, "" );
955 
956 
957   /* Set the flag values. */
958   tempW = XtNameToWidget( mainW, "FlagRc.FlagReadTb" );
959   XmToggleButtonSetState( tempW, False );
960 
961   tempW = XtNameToWidget( mainW, "FlagRc.FlagWriteTb" );
962   XmToggleButtonSetState( tempW, False );
963 
964   tempW = XtNameToWidget( mainW, "FlagRc.FlagMsgTb" );
965   XmToggleButtonSetState( tempW, False );
966 
967 
968   /* No items selected. */
969   setAction( acl_ref, True, False );
970 
971   tempW = XtNameToWidget( mainW, "AclLiSW.AclLi" );
972   XmListDeselectAllItems( tempW );
973 
974   acl_ref -> field_changed = False;
975 
976 
977   return;
978 
979 } /* setEmptyItem */
980 
981 
982 /*----------------------------------------------------------------------*/
983 
984 static void
accessListCB(Widget widget,ACL_REC_REF acl_ref,XmListCallbackStruct * call_data)985   accessListCB( Widget                widget,
986                 ACL_REC_REF           acl_ref,
987                 XmListCallbackStruct  *call_data )
988 {
989 
990   /* Variables. */
991   char    flags[ 20 ];
992   char    id[ XTM_AB_MAX_AFS_ID_LENGTH + 1 ];
993   char    *char_ref;
994   Widget  mainW;
995   Widget  tempW;
996 
997 
998   /* Code. */
999 
1000   mainW = XtNameToWidget( acl_ref -> aclW, "AclFdFo" );
1001 
1002 
1003   /* Fetch the selected name/directory line. */
1004   char_ref = xitStringGetString( call_data -> item, CS );
1005 
1006   flags[ 0 ] = '\0';
1007 
1008   sscanf( char_ref, "%s %s", id, flags );
1009   SysFree( char_ref );
1010 
1011 
1012   /* Set AFS id. */
1013   tempW = XtNameToWidget( mainW, "IdTx" );
1014   XmTextSetString( tempW, id );
1015 
1016 
1017   /* Set flags. */
1018   tempW = XtNameToWidget( mainW, "FlagRc.FlagReadTb" );
1019   if( strchr( flags, 'r' ) != NULL )
1020     XmToggleButtonSetState( tempW, True, False );
1021   else
1022     XmToggleButtonSetState( tempW, False, False );
1023 
1024 
1025   tempW = XtNameToWidget( mainW, "FlagRc.FlagWriteTb" );
1026   if( strchr( flags, 'w' ) != NULL )
1027     XmToggleButtonSetState( tempW, True, False );
1028   else
1029     XmToggleButtonSetState( tempW, False, False );
1030 
1031 
1032   tempW = XtNameToWidget( mainW, "FlagRc.FlagMsgTb" );
1033   if( strchr( flags, 'm' ) != NULL )
1034     XmToggleButtonSetState( tempW, True, False );
1035   else
1036     XmToggleButtonSetState( tempW, False, False );
1037 
1038 
1039   setAction( acl_ref, True, True );
1040 
1041   acl_ref -> field_changed = False;
1042 
1043 
1044   return;
1045 
1046 } /* accessListCB */
1047 
1048 
1049 /*----------------------------------------------------------------------*/
1050 
1051 static void
addCB(Widget widget,ACL_REC_REF acl_ref,XtPointer call_data)1052   addCB( Widget       widget,
1053          ACL_REC_REF  acl_ref,
1054          XtPointer    call_data )
1055 {
1056 
1057   /* Variables. */
1058   int     flags;
1059   int     items;
1060   int     num_id;
1061   char    id[ XTM_AB_MAX_AFS_ID_LENGTH + 1 ];
1062   char    *char_ref;
1063   Widget  mainW;
1064   Widget  tempW;
1065 
1066 
1067   /* Code. */
1068 
1069   mainW = XtNameToWidget( acl_ref -> aclW, "AclFdFo" );
1070 
1071 
1072   /* Fetch the AFS ID. */
1073   tempW = XtNameToWidget( mainW, "IdTx" );
1074 
1075   char_ref = xitStringGetText( tempW );
1076 
1077   items = sscanf( char_ref, "%s", id );
1078   SysFree( char_ref );
1079 
1080   if( items != 1 )
1081     return;
1082 
1083 
1084   /* Is this a valid id? */
1085   num_id = xtmAfFetchId( id );
1086   if( num_id == XTM_AF_NOID ) {
1087       xitErMessage( acl_ref -> aclW, XIT_ER_ERROR,
1088                     module_name, "addCB",
1089                     msgGetText( MXDI_NO_VALID_USERNAME ) );
1090     return;
1091   }
1092 
1093 
1094   /* Fetch the access flags. */
1095   flags = 0;
1096 
1097   tempW = XtNameToWidget( mainW, "FlagRc.FlagReadTb" );
1098   if( XmToggleButtonGetState( tempW ) )
1099     flagSet( flags, XTM_AB_FLAG_READ );
1100 
1101   tempW = XtNameToWidget( mainW, "FlagRc.FlagWriteTb" );
1102   if( XmToggleButtonGetState( tempW ) )
1103     flagSet( flags, XTM_AB_FLAG_WRITE | XTM_AB_FLAG_READ );
1104 
1105   tempW = XtNameToWidget( mainW, "FlagRc.FlagMsgTb" );
1106   if( XmToggleButtonGetState( tempW ) )
1107     flagSet( flags, XTM_AB_FLAG_MSG );
1108 
1109   /* Any flags given? */
1110   if( flags == 0 ) {
1111     xitErMessage( acl_ref -> aclW, XIT_ER_ERROR,
1112                   module_name, "addCB",
1113                   msgGetText( MXDI_NO_ACCESS_FLAGS ) );
1114     return;
1115   }
1116 
1117 
1118   /* Set the new database. */
1119   setAccessItem( acl_ref, id, flags );
1120 
1121   /* All is empty. */
1122   setEmptyItem( acl_ref );
1123 
1124   acl_ref -> acl_changed = True;
1125 
1126 
1127   return;
1128 
1129 } /* addCB */
1130 
1131 
1132 /*----------------------------------------------------------------------*/
1133 
1134 static void
cancelCB(Widget widget,ACL_REC_REF acl_ref,XtPointer call_data)1135   cancelCB( Widget       widget,
1136             ACL_REC_REF  acl_ref,
1137             XtPointer    call_data )
1138 {
1139 
1140   /* Variables. */
1141   Widget  tempW;
1142 
1143 
1144   /* Code. */
1145 
1146   /* Any ACL changes? */
1147   if( acl_ref -> acl_changed ) {
1148     tempW = xitCreateQuestionDialog(
1149               acl_ref -> aclW, "InformationDialog",
1150 	      msgGetText( MXDI_QUESTION_MESSAGE_LABEL ),
1151               msgGetText( MXDI_ALL_CHANGES_LOST ),
1152               closeCB, acl_ref,
1153               NULL, NULL );
1154 
1155     return;
1156   }
1157 
1158   closeCB( widget, acl_ref, NULL );
1159 
1160 
1161   return;
1162 
1163 } /* cancelCB */
1164 
1165 
1166 /*----------------------------------------------------------------------*/
1167 
1168 static void
deleteCB(Widget widget,ACL_REC_REF acl_ref,XtPointer call_data)1169   deleteCB( Widget       widget,
1170             ACL_REC_REF  acl_ref,
1171             XtPointer    call_data )
1172 {
1173 
1174   /* Variables. */
1175   int       item_count;
1176   Arg       args[ 3 ];
1177   Cardinal  n;
1178   Widget    mainW;
1179   Widget    tempW;
1180   XmString  *items;
1181 
1182 
1183   /* Code. */
1184 
1185   mainW = XtNameToWidget( acl_ref -> aclW, "AclFdFo" );
1186 
1187 
1188   tempW = XtNameToWidget( mainW, "AclLiSW.AclLi" );
1189 
1190   /* Fetch selected item from the list. */
1191   n = 0;
1192   XtSetArg( args[ n ], XmNselectedItemCount, &item_count ); n++;
1193   XtSetArg( args[ n ], XmNselectedItems, &items ); n++;
1194   XtGetValues( tempW, args, n );
1195 
1196   if( item_count != 1 )
1197     return;
1198 
1199   /* Delete the selected short name/directory. */
1200   XmListDeleteItem( tempW, *items );
1201 
1202   /* All is empty. */
1203   setEmptyItem( acl_ref );
1204 
1205   acl_ref -> acl_changed = True;
1206 
1207 
1208   return;
1209 
1210 } /* deleteCB */
1211 
1212 
1213 /*----------------------------------------------------------------------*/
1214 
1215 static void
destroyCB(Widget widget,ACL_REC_REF acl_ref,XtPointer call_data)1216   destroyCB( Widget       widget,
1217              ACL_REC_REF  acl_ref,
1218              XtPointer    call_data )
1219 {
1220 
1221   /* Code. */
1222 
1223   /* Call callback function? */
1224   if( acl_ref -> actionCB != NULL )
1225     (* acl_ref -> actionCB )( XTM_AA_REASON_DESTROY, acl_ref -> user_data );
1226 
1227   /* Release the user data. */
1228   if( acl_ref -> system_admin_acl != NULL )
1229     SysFree( acl_ref -> system_admin_acl );
1230 
1231   SysFree( acl_ref );
1232 
1233 
1234   return;
1235 
1236 } /* destroyCB */
1237 
1238 
1239 /*----------------------------------------------------------------------*/
1240 
1241 static void
closeCB(Widget widget,ACL_REC_REF acl_ref,XtPointer call_data)1242   closeCB( Widget       widget,
1243            ACL_REC_REF  acl_ref,
1244            XtPointer    call_data )
1245 {
1246 
1247   /* Code. */
1248 
1249   XtUnmanageChild( acl_ref -> aclW );
1250 
1251 
1252   return;
1253 
1254 } /* closeCB */
1255 
1256 
1257 /*----------------------------------------------------------------------*/
1258 
1259 static void
fieldChangedCB(Widget widget,ACL_REC_REF acl_ref,XtPointer call_data)1260   fieldChangedCB( Widget       widget,
1261                   ACL_REC_REF  acl_ref,
1262                   XtPointer    call_data )
1263 {
1264 
1265   /* Code. */
1266 
1267   acl_ref -> field_changed = True;
1268 
1269 
1270   return;
1271 
1272 } /* fieldChangedCB */
1273 
1274 
1275 /*----------------------------------------------------------------------*/
1276 
1277 static void
helpCB(Widget widget,ACL_REC_REF acl_ref,XtPointer call_data)1278   helpCB( Widget       widget,
1279           ACL_REC_REF  acl_ref,
1280           XtPointer    call_data )
1281 {
1282 
1283   /* Code. */
1284 
1285   xtmHlDisplayHelp( acl_ref -> info_handle, XTM_HL_WINDOW_INDEX,
1286                     acl_window_id, "" );
1287 
1288   return;
1289 
1290 } /* helpCB */
1291 
1292 
1293 /*----------------------------------------------------------------------*/
1294 
1295 static void
okCB(Widget widget,ACL_REC_REF acl_ref,XtPointer call_data)1296   okCB( Widget       widget,
1297         ACL_REC_REF  acl_ref,
1298         XtPointer    call_data )
1299 {
1300 
1301   /* Variables. */
1302   Widget   tempW;
1303 
1304 
1305   /* Code. */
1306 
1307   /* Warn the user that he/she might forget to add sometinhg. */
1308   if( acl_ref -> field_changed ) {
1309     tempW = xitCreateQuestionDialog(
1310               acl_ref -> aclW, "InformationDialog",
1311 	      msgGetText( MXDI_INFORMATION_LABEL ),
1312               msgGetText( MXDI_INFORMATION_NOT_SAVED ),
1313               saveAndCloseCB, acl_ref,
1314               NULL, NULL );
1315 
1316     return;
1317   }
1318 
1319   /* Save and close the window. */
1320   saveAndCloseCB( widget, acl_ref, call_data );
1321 
1322 
1323   return;
1324 
1325 } /* okCB */
1326 
1327 
1328 /*----------------------------------------------------------------------*/
1329 
1330 static void
saveAndCloseCB(Widget widget,ACL_REC_REF acl_ref,XtPointer call_data)1331   saveAndCloseCB( Widget       widget,
1332                   ACL_REC_REF  acl_ref,
1333                   XtPointer    call_data )
1334 {
1335 
1336   /* Code. */
1337 
1338   /* Save the access information. */
1339   saveAccessInfo( acl_ref );
1340 
1341 
1342   /* Call callback function? */
1343   if( acl_ref -> actionCB != NULL )
1344     (* acl_ref -> actionCB )( XTM_AA_REASON_OK, acl_ref -> user_data );
1345 
1346   XtUnmanageChild( acl_ref -> aclW );
1347 
1348 
1349   return;
1350 
1351 } /* saveAndCloseCB */
1352