dtcm/server/: just return NULL, not the address of a dummy local variable. Geez.
[oweals/cde.git] / cde / programs / dtcm / server / parser.y
1 /* $XConsortium: parser.y /main/6 1996/11/11 11:50:41 drk $ */
2 /*
3  *  (c) Copyright 1993, 1994 Hewlett-Packard Company
4  *  (c) Copyright 1993, 1994 International Business Machines Corp.
5  *  (c) Copyright 1993, 1994 Novell, Inc.
6  *  (c) Copyright 1993, 1994 Sun Microsystems, Inc.
7  */
8
9
10 %{
11 #include <EUSCompat.h>
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <string.h>
15 #if (defined(sun) && defined(_XOPEN_SOURCE)) || defined(linux)
16 #include <time.h>
17 #endif
18 #include "csa.h"
19 #include "rtable4.h"
20 #include "cm.h"
21 #include "lexer.h"
22 #include "cmscalendar.h"
23 #include "appt4.h"
24 #include "cmsdata.h"
25 #include "attr.h"
26 #include "v4ops.h"
27 #include "v5ops.h"
28 #include "delete.h"
29 #include "log.h"
30 #include "iso8601.h"
31
32 extern char *pgname;
33 extern _DtCmsCalendar *currentCalendar;
34 extern int yylineno;
35 extern void yyerror(char*);
36 extern void report_err(char*);
37 extern char *str_to_cr(char*);
38 extern time_t convert_2_tick(char *);
39
40 typedef struct {
41         int     total;
42         int     current;
43         cms_attribute *attrs;
44 } _attr_array;
45
46 static int              currentVersion;
47 static _attr_array      currentAttrs;
48
49
50 /*****************************************************************************
51  * forward declaration of static functions used within the file
52  *****************************************************************************/
53 static void add_hashed_attr_to_array(_attr_array *attrs, int num, char *value);
54 static void add_to_attr_array(_attr_array *attrs, char *name,
55                 char *tag, char *value);
56 static void grow_attr_array(_attr_array *attrs);
57 static CSA_enum get_tag_from_string(char *tagstr);
58 static CSA_return_code get_attr_value(int type, char *valstr,
59                 cms_attribute_value **attrval);
60 static CSA_return_code get_access_list_value(char *valstr,
61                 cms_attribute_value **attrval);
62 static CSA_return_code get_user_access_entry(char *string,
63                 cms_access_entry **a);
64 static CSA_return_code get_date_time_list_value(char *valstr,
65                 cms_attribute_value **attrval);
66 static int extend_entry_table(int hashednum, char *name, char *typestr);
67
68 %}
69
70 %start calendar
71
72 %union  {
73         int number;
74         char *s;
75         Interval_4 periodVal;
76         Appt_4 *appointment;
77         Attribute_4 *attributelist_4;
78         Except_4 *exceptionlist;
79         Access_Entry_4 *accesslist;
80         Event_Type_4 tagsVal;
81         Tag_4 *taglist;
82         Appt_Status_4 apptstatVal;
83         Privacy_Level_4 privacyVal;
84         void *entry;
85         }
86
87 %token VERSION COLON NUMBER QUOTEDSTRING DETAILS DURATION PERIODVAL NTIMES COMMA
88 %token OPENPAREN CLOSEPAREN WHAT REMOVE ADD ADDENTRY PERIOD EXCEPTION MAILTO NTH ENDDATE
89 %token AUTHOR ATTRIBUTES_4 ACCESS DENY PRIVACY PRIVACYENUM
90 %token KEY READ WRITE DELETE EXEC CONNECT BROWSE INSERT UPDATE
91 %token TAGS TAGSVAL
92 %token APPTSTATUS APPTSTATUSVAL
93 %token PRIVACYLEVEL PRIVACYVAL
94 %token ATTRIBUTES_5 CALATTRS
95 %token HASHEDATTRS TABLE
96
97 %type <s> quotedString what details mailto author
98 %type <number> number tick key ntimes duration accesstype nth enddate
99 %type <entry> appointmentBody 
100 %type <attributelist_4> attributes_4 attributelist_4 attributeitem_4
101 %type <periodVal> period 
102 %type <exceptionlist> exceptions exceptionlist exceptitem
103 %type <accesslist> accesses accesslist accessitem
104 %type <taglist> tags taglist tagitem 
105 %type <apptstatVal> apptstat
106 %type <privacyVal> privacy
107
108 %% /* Begining of rules section */
109
110 calendar        : versionStamp eventlist
111                 | versionStamp
112                 ;
113
114 versionStamp    : VERSION COLON number
115                         {
116                                 if ($3 > _DtCMS_VERSION4) { 
117                                         report_err("Unable to read callog file, unsupported version\n");
118                                         return -1;
119                                 } else {
120                                         currentVersion = $3;
121                                         if (_DtCmsSetFileVersion(
122                                             currentCalendar, $3))
123                                                 return -1;
124                                 }
125                         }
126                 | error OPENPAREN
127                         {
128                                 yyerror("Error reading callog file");
129                                 return -1;
130                         }
131                 ;
132
133 number          : NUMBER
134                         {
135                                 $$ = externNumberVal;
136                         }
137                 ;
138
139 eventlist       : event
140                 | eventlist event
141                 ;
142
143 event           : name_type_table
144                 | add 
145                 | remove 
146                 | access
147                 | calendar_attrs
148                 ;
149
150 add             : OPENPAREN ADD appointmentBody CLOSEPAREN
151                         {
152                                 if (currentVersion == _DtCMS_VERSION1) {
153                                         if (_DtCmsInsertAppt(currentCalendar,
154                                             (Appt_4 *)$3) != CSA_SUCCESS) {
155                                                 _DtCm_free_appt4((Appt_4 *)$3);
156
157                                                 fprintf(stderr,
158                                                         "Failed to insert appt at line %d\n",
159                                                         yylineno);
160                                                 return (-1);
161                                         }
162                                 } else {
163                                         if (_DtCmsInsertEntry4Parser(
164                                             currentCalendar, (cms_entry *)$3)
165                                             != CSA_SUCCESS) {
166
167                                                 fprintf(stderr, "Failed to insert entry at line %d\n",
168                                                         yylineno);
169                                                 return (-1);
170                                         }
171                                         _DtCm_free_cms_attributes(
172                                                 ((cms_entry *)$3)->num_attrs,
173                                                 ((cms_entry *)$3)->attrs);
174                                         free($3);
175                                 }
176                         }
177                 ;
178
179 remove          : OPENPAREN REMOVE tick key CLOSEPAREN
180                         {
181                                 Appt_4 *appt4;
182                                 Id_4 key;
183                                 cms_key ckey;
184
185                                 if (currentVersion == _DtCMS_VERSION1) {
186                                         key.tick = $3;
187                                         key.key = $4;
188                                         _DtCmsDeleteAppt(currentCalendar,
189                                                 NULL, 0, &key, &appt4);
190                                         if (appt4)
191                                                 _DtCm_free_appt4(appt4);
192                                 } else {
193                                         ckey.time = $3;
194                                         ckey.id = $4;
195                                         _DtCmsDeleteEntry(currentCalendar, NULL,
196                                                 0, &ckey, NULL);
197                                 }
198                         }
199                 ;
200
201 access          : OPENPAREN ACCESS accesstype accesses CLOSEPAREN
202                         {
203                                 _DtCmsSetAccess4Parser(currentCalendar, $4, $3);
204                         }
205                 ;
206
207 calendar_attrs: OPENPAREN CALATTRS attributelist_5 CLOSEPAREN
208                         {
209                                 _DtCmsSetCalendarAttrs4Parser(currentCalendar,
210                                         currentAttrs.current,
211                                         currentAttrs.attrs);
212
213                                 _DtCm_free_cms_attributes(currentAttrs.current,
214                                         currentAttrs.attrs);
215                                 currentAttrs.total = 0;
216                                 currentAttrs.current = 0;
217                                 currentAttrs.attrs = NULL;
218                         }
219                 ;
220
221 /*
222  * The attribute name and type hash table, each item contains
223  * the hash number for the corresponding attribute, the attribute name,
224  * and the value type of the attribute.
225  */
226 name_type_table : OPENPAREN TABLE name_type_list CLOSEPAREN
227                         {
228                                 currentCalendar->hashed = B_TRUE;
229                         }
230                 ;
231
232 name_type_list  : name_type_item
233                 | name_type_item name_type_list
234                 ;
235
236 name_type_item  : OPENPAREN number quotedString quotedString CLOSEPAREN
237                         {
238                                 if (extend_entry_table($2, $3, $4)) {
239                                         fprintf(stderr, "Failed to parse entry table at line # %d\n",
240                                                 yylineno);
241                                         return (-1);
242                                 }
243                         }
244                 ;
245
246 /*                1     2   3   4       5        6      7       8       9  10
247         11   12         13       14     15      16      17
248 */
249 appointmentBody : tick key what details duration period nth enddate ntimes exceptions mailto author attributes_4 tags apptstat privacy attributes_5 hashedattrs
250                         {
251                                 char *temp=NULL;
252                                 Attr_4 item;
253                                 Appt_4 *newp;
254                                 cms_entry *newe;
255                                 void    *aptr;
256
257                                 if (currentVersion == _DtCMS_VERSION1) {
258                                         newp = _DtCm_make_appt4(B_TRUE);
259                                         newp->appt_id.tick = $1;
260                                         newp->appt_id.key = $2;
261                                         newp->what = $3;
262                                         newp->client_data = $4;
263                                         newp->duration = $5;
264                                         newp->period.period = $6;
265                                         newp->period.nth = $7;
266                                         newp->period.enddate = $8;
267                                         newp->ntimes = $9;
268                                         newp->exception = $10;  
269
270                                         temp = $11;
271
272                                         newp->author = $12;
273                                         newp->attr = $13;
274
275                                         if (temp != NULL && (*temp)!=NULL) {
276                                                 item = newp->attr;
277                                                 while(item!=NULL) {
278                                                         if(strcmp(item->attr, "ml")==0) {
279                                                                 item->clientdata= temp;
280                                                                 break;
281                                                         }
282                                                         item = item->next;
283                                                 }
284                                         }
285
286                                         newp->tag = $14;
287                                         newp->appt_status = $15;
288                                         newp->privacy = $16;
289                                         newp->next=NULL;
290                                         aptr = (void *)newp;
291                                 } else {
292                                         newe = (cms_entry *)calloc(1,
293                                                 sizeof(cms_entry));
294                                         newe->key.time = $1;
295                                         newe->key.id = $2;
296                                         newe->num_attrs = currentAttrs.current;
297                                         newe->attrs = currentAttrs.attrs;
298                                         currentAttrs.total = 0;
299                                         currentAttrs.current = 0;
300                                         currentAttrs.attrs = NULL;
301                                         aptr = (void *)newe;
302                                 }
303
304                                 $$ = aptr;
305                         }
306                 ;
307
308 tick            : /* empty */
309                         {
310                                 $$ = 0;
311                         }
312                 | quotedString 
313                         {
314                                 time_t  time;
315
316                                 if (strlen($1) == 24)
317                                         $$ = convert_2_tick($1);
318                                 else {
319                                         _csa_iso8601_to_tick($1, &time);
320                                         $$ = time;
321                                 }
322                                         
323                         }
324                 ;
325
326 quotedString    : QUOTEDSTRING
327                         {
328                                 $$ = externQuotedString;
329                         }
330                 ;
331
332 key             : /* empty */
333                         {
334                                 $$ = 0;
335                         }
336                 | KEY COLON number
337                         {
338                                 $$ = $3;
339                         }
340                 ;
341
342 what            : /* empty */
343                         {
344                                 $$ = strdup("");
345                         }
346                 | WHAT COLON quotedString
347                         {
348                                 $$ = str_to_cr($3);
349                                 free($3);
350                         }
351                 ;
352                                 
353 details         : /* empty */
354                         {
355                                 $$ = "";
356                         }
357                 | DETAILS COLON quotedString
358                         {
359                                 $$ = $3;
360                         }
361                 ;
362
363 mailto          : /* empty */
364                         {
365                                 $$ = "";
366                         }
367                 | MAILTO COLON quotedString
368                         {
369                                 $$ = $3;
370                         }
371                 ;
372
373 duration        : /* empty */
374                         {
375                                 $$ = NULL;
376                         }
377                 | DURATION COLON number
378                         {
379                                 $$ = $3;
380                         }
381                 ;
382
383 period          : /* empty */
384                         {
385                                 $$ = single_4;
386                         }
387                 | PERIOD COLON PERIODVAL
388                         {
389                                 $$ = externPeriod.period;
390                         }
391                 ;
392
393 nth             : /* empty */
394                         {
395                                 $$ = 0;
396                         }
397                 | NTH COLON number
398                         {
399                                 $$ = $3;
400                         }
401                 ;
402
403 enddate         : /* empty */
404                         {
405                                 $$ = 0;
406                         }
407                 | ENDDATE COLON quotedString
408                         {
409                                 $$ = convert_2_tick($3);
410                                 free($3);
411                         }
412                 ;
413                                 
414 privacy         : /* empty */
415                         {
416                                 $$ = public_4;
417                         }
418                 | PRIVACY COLON PRIVACYVAL
419                         {
420                                 $$ = externPrivacy;
421                         }
422                 ;
423
424 apptstat        : /* empty */
425                         {
426                                 $$ = active_4;
427                         }
428                 | APPTSTATUS COLON APPTSTATUSVAL
429                         {
430                                 $$ = externApptStatus;
431                         }
432                 ;
433
434 ntimes          : /* empty */
435                         {
436                                 $$ = 0;
437                         }
438                 | NTIMES COLON number
439                         {
440                                 $$ = $3;
441                         }
442                 ;
443
444 author          : /* empty */
445                         {
446                                 $$ = "";
447                         }
448                 | AUTHOR COLON quotedString
449                         {
450                                 $$ = $3;
451                         }
452                 ;
453
454 accesstype      : READ
455                         {
456                                 $$ = access_read_4;
457                         }
458                 | WRITE
459                         {
460                                 $$ = access_write_4;
461                         }
462                 | DELETE
463                         {
464                                 $$ = access_delete_4;
465                         }
466                 | EXEC
467                         {
468                                 $$ = access_exec_4;
469                         }
470                 ;
471
472 accesses        : /* empty */
473                         {
474                                 $$ = NULL;
475                         }
476                 | accesslist
477                         {
478                                 $$ = $1;
479                         }
480                 ;
481
482 accesslist      : accessitem
483                         {
484                                 $$ = $1;
485                         }
486
487                 | accessitem accesslist
488                         {
489                                 Access_Entry_4 *e = $1;
490                                 e->next = $2;
491                                 $$ = e;
492                         }
493                 ;
494
495 accessitem      : quotedString 
496                         {
497                                 Access_Entry_4 *e =
498                                         (Access_Entry_4 *)malloc(
499                                                 sizeof(Access_Entry_4));
500                                 e->who = $1;
501                                 e->next = (Access_Entry_4 *)NULL;
502                                 $$ = e;
503                         }
504                 ;
505
506 hashedattrs     : /* empty */
507                 | HASHEDATTRS COLON OPENPAREN hashedattrlist CLOSEPAREN
508                 ;
509
510 hashedattrlist : hashedattritem
511                 | hashedattritem hashedattrlist
512                 ;
513
514 hashedattritem :OPENPAREN number quotedString CLOSEPAREN
515                         {       
516                                 add_hashed_attr_to_array(&currentAttrs, $2, $3);
517                         }
518                 ;
519
520 attributes_5    : /* empty */
521                 | ATTRIBUTES_5 COLON OPENPAREN attributelist_5 CLOSEPAREN
522                 ;
523
524 attributelist_5 : attributeitem_5
525                 | attributeitem_5 attributelist_5
526                 ;
527
528 attributeitem_5 :OPENPAREN quotedString COMMA quotedString COMMA quotedString CLOSEPAREN
529                         {       
530                                 if (currentAttrs.total == currentAttrs.current)
531                                 {
532                                         grow_attr_array(&currentAttrs);
533                                 }
534                                 add_to_attr_array(&currentAttrs, $2, $4, $6);
535                         }
536                 ;
537
538 attributes_4    : /* empty */
539                         {
540                                 $$ = NULL;
541                         }
542                 | ATTRIBUTES_4 COLON OPENPAREN attributelist_4 CLOSEPAREN
543                         {
544                                 $$ = $4;
545                         }
546                 ;
547
548 attributelist_4  : attributeitem_4
549                         {
550                                 $$ = $1;
551                         }
552                 | attributeitem_4 attributelist_4
553                         {
554                                 Attr_4 p = $1;
555                                 p->next = $2;
556                                 $$ = p;
557                         }
558                 ;
559 attributeitem_4 :OPENPAREN quotedString COMMA quotedString COMMA quotedString CLOSEPAREN
560                         {       
561                                 Attr_4 newattr = _DtCm_make_attr4();
562                                 newattr->next = (Attr_4)NULL;
563                                 newattr->attr = $2;
564                                 newattr->value = $4;
565                                 newattr->clientdata = $6;
566                                 $$ = newattr;
567                         }
568                 | OPENPAREN quotedString COMMA quotedString CLOSEPAREN
569                         {
570                                 Attr_4 newattr = _DtCm_make_attr4();
571                                 newattr->next = (Attr_4)NULL;
572                                 newattr->attr = $2;
573                                 newattr->value = $4;
574                                 $$ = newattr;
575                         }
576                 ;
577
578 tags            : /* empty */
579                         {
580                                 Tag_4 *t = (Tag_4 *)malloc(sizeof(Tag_4));
581                                 t->next = (Tag_4 *)NULL;
582                                 t->tag = appointment_4;
583                                 t->showtime = 1;
584                                 $$ = t;
585                         }
586                 | TAGS COLON OPENPAREN taglist CLOSEPAREN
587                         {
588                                 $$ = $4;
589                         }
590                 ;
591
592 taglist         : tagitem
593                         {
594                                 $$ = $1;
595                         }
596                 | tagitem taglist
597                         {
598                                 Tag_4 *t = $1;
599                                 t->next = $2;
600                                 $$ = t;
601                         }
602                 ;
603
604 tagitem         : OPENPAREN TAGSVAL COMMA number CLOSEPAREN
605                         {
606                                 Tag_4 *t = (Tag_4 *)malloc(sizeof(Tag_4));
607                                 t->next = (Tag_4 *)NULL;
608                                 t->tag = externTag.tag;
609                                 t->showtime = $4;
610                                 $$ = t;
611                         }
612                 ;
613
614
615 exceptions      : /* empty */
616                         {
617                                 $$ = NULL;
618                         }
619                 | EXCEPTION COLON OPENPAREN exceptionlist CLOSEPAREN
620                         {
621                                 $$ = $4;
622                         }
623                 ;
624
625 exceptionlist : exceptitem
626                         {
627                                 $$ = $1;
628                         }
629                 | exceptitem exceptionlist
630                         {
631                                 Exception_4 p = $1;
632                                 p->next = $2;
633                                 $$ = p;
634                         }
635                 ;
636 exceptitem : number
637                 {
638                                 Exception_4 newexcept =
639                                         (Exception_4)malloc(sizeof(Except_4));
640                                 newexcept->next = (Exception_4)NULL;
641                                 newexcept->ordinal = $1;
642                                 $$ = newexcept;
643                 }
644                 ;
645
646
647 %% /* Begining of subroutine section */
648
649 void
650 yyerror(char *s)
651 {
652         (void)fprintf (stderr, "%s: %s\n", pgname, s);
653         (void)fprintf (stderr, "at line %d\n", yylineno);
654 }
655  
656 void
657 report_err(char *s)
658 {
659          (void)fprintf (stderr, "%s", s);
660 }
661
662 char *
663 str_to_cr(char *s)
664 {
665         int i, j, k;
666         char *newstr;
667
668         if (s==NULL) return(NULL);
669         i = strlen(s);
670
671         newstr= (char *)calloc(1, (unsigned)i + 1);
672         k = 0;
673         for (j=0; j<i; j++) {
674                 if (s[j]=='\\') {
675                         if (s[j+1]=='n') {
676                                 newstr[k] = '\n';
677                                 j++;
678                         }
679                         else if (s[j+1]=='\\') {
680                                 newstr[k] = '\\';
681                                 j++;
682                         }
683                         else if (s[j+1]=='\"') {
684                                 newstr[k] = '\"';
685                                 j++;
686                         }
687                         else {
688                                 newstr[k] = s[j];
689                         }
690                 }
691                 else {
692                         newstr[k] = s[j];
693                 }
694                 k++;
695         }
696         newstr[k] = NULL;
697         return(newstr);
698 }
699
700 int
701 get_wday(char *wday)
702 {
703         if (wday == NULL)
704                 return (-1);
705
706         if (strncmp(wday, "Sun", 3) == 0)
707                 return (0);
708         else if (strncmp(wday, "Mon", 3) == 0)
709                 return (1);
710         else if (strncmp(wday, "Tue", 3) == 0)
711                 return (2);
712         else if (strncmp(wday, "Wed", 3) == 0)
713                 return (3);
714         else if (strncmp(wday, "Thu", 3) == 0)
715                 return (4);
716         else if (strncmp(wday, "Fri", 3) == 0)
717                 return (5);
718         else if (strncmp(wday, "Sat", 3) == 0)
719                 return (6);
720         else
721                 return (-1);
722 }
723
724 int
725 get_month(char *month)
726 {
727         if (month == NULL)
728                 return (-1);
729
730         if (strncmp(month, "Jan", 3) == 0)
731                 return (0);
732         if (strncmp(month, "Feb", 3) == 0)
733                 return (1);
734         if (strncmp(month, "Mar", 3) == 0)
735                 return (2);
736         if (strncmp(month, "Apr", 3) == 0)
737                 return (3);
738         if (strncmp(month, "May", 3) == 0)
739                 return (4);
740         if (strncmp(month, "Jun", 3) == 0)
741                 return (5);
742         if (strncmp(month, "Jul", 3) == 0)
743                 return (6);
744         if (strncmp(month, "Aug", 3) == 0)
745                 return (7);
746         if (strncmp(month, "Sep", 3) == 0)
747                 return (8);
748         if (strncmp(month, "Oct", 3) == 0)
749                 return (9);
750         if (strncmp(month, "Nov", 3) == 0)
751                 return (10);
752         if (strncmp(month, "Dec", 3) == 0)
753                 return (11);
754 }
755
756 time_t
757 convert_2_tick(char *datestr)
758 {
759         struct tm tmstr;
760         char    datebuf[BUFSIZ];
761         char    *ptr, *tptr;
762
763         if (datestr == NULL)
764                 return (-1);
765
766         memset((void *)&tmstr, NULL, sizeof(struct tm));
767
768         strcpy(datebuf, datestr);
769
770         /* get week day */
771         ptr = strtok(datebuf, " ");
772         if ((tmstr.tm_wday = get_wday(ptr)) == -1)
773                 return (-1);
774
775         /* get month */
776         ptr = strtok(NULL, " ");
777         if ((tmstr.tm_mon = get_month(ptr)) == -1)
778                 return (-1);
779
780         /* get day of month */
781         ptr = strtok(NULL, " ");
782         if (ptr != NULL)
783                 tmstr.tm_mday = atoi(ptr);
784         else
785                 return (-1);
786
787         /* get time */
788         ptr = strtok(NULL, " ");
789         if (ptr != NULL) {
790                 /* get hour */
791                 if ((tptr = strchr(ptr, ':')) == NULL)
792                         return (-1);
793                 else {
794                         *tptr = NULL;
795                         tmstr.tm_hour = atoi(ptr);
796                 }
797
798                 ptr = tptr + 1;
799                 if ((tptr = strchr(ptr, ':')) == NULL)
800                         return (-1);
801                 else {
802                         *tptr = NULL;
803                         tmstr.tm_min = atoi(ptr);
804                 }
805
806                 tmstr.tm_sec = atoi(tptr + 1);
807         } else
808                 return (-1);
809
810         ptr = strtok(NULL, " ");
811         if (ptr != NULL)
812                 tmstr.tm_year = atoi(ptr) - 1900;
813         else
814                 return (-1);
815
816         tmstr.tm_isdst = -1;
817
818         return(mktime(&tmstr));
819 }
820
821 static void
822 add_hashed_attr_to_array(_attr_array *attrs, int num, char *value)
823 {
824         int             type;
825
826         if (num > currentCalendar->entry_tbl->size)
827                 return;
828
829         if (attrs->current == attrs->total) {
830                 grow_attr_array(attrs);
831         }
832
833         attrs->attrs[attrs->current].name.num = num;
834         attrs->attrs[attrs->current].name.name =
835                 strdup(currentCalendar->entry_tbl->names[num]);
836
837         if (get_attr_value(currentCalendar->types[num], value,
838             &attrs->attrs[attrs->current].value) == CSA_SUCCESS)
839                 attrs->current++;
840
841         return;
842 }
843
844 static void
845 add_to_attr_array(_attr_array *attrs, char *name, char *tag, char *value)
846 {
847         int             type;
848
849         if (attrs->current == attrs->total) {
850                 grow_attr_array(attrs);
851         }
852
853         attrs->attrs[attrs->current].name.name = name;
854         if ((type = get_tag_from_string(tag)) == -1)
855                 return;
856
857         if (get_attr_value(type, value, &attrs->attrs[attrs->current].value)
858             == CSA_SUCCESS)
859                 attrs->current++;
860
861         return;
862 }
863
864 static CSA_enum
865 get_tag_from_string(char *tagstr)
866 {
867         int     i;
868
869         if (*tagstr < '0' || *tagstr > '9')
870                 return (-1);
871
872         i = atoi(tagstr);
873
874         if (i < CSA_VALUE_BOOLEAN || i > CSA_VALUE_OPAQUE_DATA ||
875             i == CSA_VALUE_ATTENDEE_LIST)
876                 return (-1);
877         else
878                 return (i);
879 }
880
881 static CSA_return_code
882 get_attr_value(int type, char *valstr, cms_attribute_value **attrval)
883 {
884         char            buf1[BUFSIZ], buf2[BUFSIZ];
885         char            *ptr1, *ptr2, *ptr3, *ptr4;
886         uint            unum;
887         CSA_reminder    remval;
888         CSA_opaque_data opqval;
889         CSA_return_code stat;
890
891         switch (type) {
892         case CSA_VALUE_ENUMERATED:
893         case CSA_VALUE_SINT32:
894                 stat = _DtCm_set_sint32_attrval(atoi(valstr), attrval);
895                 break;
896         case CSA_VALUE_BOOLEAN:
897         case CSA_VALUE_FLAGS:
898         case CSA_VALUE_UINT32:
899                 sscanf(valstr, "%u", &unum);
900                 stat = _DtCm_set_uint32_attrval(unum, attrval);
901                 break;
902         case CSA_VALUE_STRING:
903         case CSA_VALUE_DATE_TIME:
904         case CSA_VALUE_DATE_TIME_RANGE:
905         case CSA_VALUE_TIME_DURATION:
906         case CSA_VALUE_CALENDAR_USER:
907                 stat = _DtCm_set_string_attrval(valstr, attrval, type);
908                 break;
909         case CSA_VALUE_REMINDER:
910                 memset((void *)&remval, NULL, sizeof (CSA_reminder));
911                 if (ptr1 = strchr(valstr, ':')) {
912                         *ptr1++ = NULL;
913                         if (ptr2 = strchr(ptr1, ':')) {
914                                 *ptr2++ = NULL;
915                                 ptr3 = strchr(ptr2, ':');
916                         }
917                 }
918
919                 if (ptr1 == NULL || ptr2 == NULL) {
920                         stat = CSA_E_INVALID_PARAMETER;
921                         break;
922                 }
923
924                 if (ptr3 == NULL) {
925                         /* format = "string:number:string" */
926                         remval.lead_time = valstr;
927                         remval.reminder_data.size = atoi(ptr1);
928                         remval.reminder_data.data = (unsigned char *)ptr2;
929                         stat = _DtCm_set_reminder_attrval(&remval, attrval);
930                 } else {
931                         /* format = "string:string:number:number:string" */
932                         *ptr3++ = NULL;
933                         if (ptr4 = strchr(ptr3, ':')) {
934                                 *ptr4++ = NULL;
935                                 remval.lead_time = valstr;
936                                 remval.snooze_time = ptr1;
937                                 remval.repeat_count = atoi(ptr2);
938                                 remval.reminder_data.size = atoi(ptr3);
939                                 remval.reminder_data.data =
940                                         (unsigned char *)ptr4;
941                                 stat = _DtCm_set_reminder_attrval(&remval,
942                                         attrval);
943                         } else
944                                 stat = CSA_E_INVALID_PARAMETER;
945                 }
946
947                 break;
948         case CSA_VALUE_ACCESS_LIST:
949                 stat = get_access_list_value(valstr, attrval);
950                 break;
951         case CSA_VALUE_DATE_TIME_LIST:
952                 stat = get_date_time_list_value(valstr, attrval);
953                 break;
954         case CSA_VALUE_OPAQUE_DATA:
955                 if (ptr1 = strchr(valstr, ':')) {
956                         *ptr1++ = NULL;
957                         opqval.size = atoi(valstr);
958                         opqval.data = (unsigned char *)ptr1;
959                         stat = _DtCm_set_opaque_attrval(&opqval, attrval);
960                 } else
961                         stat = CSA_E_INVALID_PARAMETER;
962                 break;
963         }
964
965         /* need to set type here since type may not be set correctly up there */
966         (*attrval)->type = type;
967
968         free(valstr);
969         return (stat);
970 }
971
972 static CSA_return_code
973 get_access_list_value(char *valstr, cms_attribute_value **attrval)
974 {
975         char *ptr;
976         cms_access_entry *a, *head, *prev;
977         CSA_return_code stat = CSA_SUCCESS;
978         cms_attribute_value *val;
979
980         if ((val = (cms_attribute_value *)calloc(1,
981             sizeof(cms_attribute_value))) == NULL)
982                 return (CSA_E_INSUFFICIENT_MEMORY);
983
984         val->type = CSA_VALUE_ACCESS_LIST;
985
986         if (*valstr == '\0') {
987                 *attrval = val;
988                 return (CSA_SUCCESS);
989         }
990
991         head = NULL;
992         while (ptr = strchr(valstr, ' ')) {
993
994                 *ptr = 0;
995                 stat = get_user_access_entry(valstr, &a);
996                 *ptr = ' ';
997
998                 if (stat != CSA_SUCCESS)
999                         break;
1000
1001                 if (head == NULL)
1002                         head = a;
1003                 else
1004                         prev->next = a;
1005                 prev = a;
1006
1007                 valstr = ptr + 1;
1008         }
1009
1010         if (stat == CSA_SUCCESS) {
1011                 if ((stat = get_user_access_entry(valstr, &a))
1012                     == CSA_SUCCESS) {
1013                         if (head == NULL)
1014                                 head = a;
1015                         else
1016                                 prev->next = a;
1017                 }
1018         }
1019
1020         if (stat == CSA_SUCCESS) {
1021                 val->item.access_list_value = head;
1022                 *attrval = val;
1023         } else {
1024                 _DtCm_free_cms_access_entry(head);
1025                 free(val);
1026         }
1027
1028         return (stat);
1029 }
1030
1031 static CSA_return_code
1032 get_user_access_entry(char *string, cms_access_entry **a)
1033 {
1034         char *ptr;
1035         cms_access_entry *item;
1036
1037         if ((ptr = strchr(string, ':')) == NULL)
1038                 return (CSA_E_INVALID_PARAMETER);
1039
1040         if ((item = (cms_access_entry *)malloc(sizeof(cms_access_entry)))
1041             == NULL) {
1042                 return (CSA_E_INSUFFICIENT_MEMORY);
1043         }
1044
1045         *ptr = NULL;
1046         if ((item->user = strdup(string)) == NULL) {
1047                 free(item);
1048                 return (CSA_E_INSUFFICIENT_MEMORY);
1049         }
1050         item->rights = atoi(ptr+1);
1051         item->next = NULL;
1052
1053         *a = item;
1054
1055         return (CSA_SUCCESS);
1056 }
1057
1058 #define _DEFAULT_ARRAY_SIZE     30
1059
1060 static void
1061 grow_attr_array(_attr_array *attrs)
1062 {
1063         cms_attribute *newptr;
1064
1065         if ((newptr = (cms_attribute *)realloc(attrs->attrs,
1066             sizeof(cms_attribute) * (attrs->total + _DEFAULT_ARRAY_SIZE)))
1067             == NULL)
1068                 return;
1069
1070         attrs->total += _DEFAULT_ARRAY_SIZE;
1071         attrs->attrs = newptr;
1072
1073         memset((void *)&attrs->attrs[attrs->current], NULL,
1074                 sizeof(cms_attribute)*_DEFAULT_ARRAY_SIZE);
1075 }
1076
1077 static CSA_return_code
1078 get_date_time_list_value(char *valstr, cms_attribute_value **attrval)
1079 {
1080         char *ptr;
1081         CSA_date_time_entry *a, *head, *prev;
1082         CSA_return_code stat = CSA_SUCCESS;
1083         cms_attribute_value *val;
1084
1085         if (*valstr == '\0') {
1086                 *attrval = NULL;
1087                 return (CSA_SUCCESS);
1088         }
1089
1090         if ((val = (cms_attribute_value *)calloc(1,
1091             sizeof(cms_attribute_value))) == NULL)
1092                 return (CSA_E_INSUFFICIENT_MEMORY);
1093
1094         val->type = CSA_VALUE_DATE_TIME_LIST;
1095
1096         head = NULL;
1097         while (ptr = strchr(valstr, ' ')) {
1098
1099                 *ptr = 0;
1100                 if (!(a = calloc(1, sizeof(CSA_date_time_entry))) ||
1101                     !(a->date_time = strdup(valstr))) {
1102                         *ptr = ' ';
1103                         stat = CSA_E_INSUFFICIENT_MEMORY;
1104                         break;
1105                 }
1106                 *ptr = ' ';
1107
1108                 if (head == NULL)
1109                         head = a;
1110                 else
1111                         prev->next = a;
1112                 prev = a;
1113
1114                 valstr = ptr + 1;
1115         }
1116
1117         if (stat == CSA_SUCCESS) {
1118                 if ((a = calloc(1, sizeof(CSA_date_time_entry))) &&
1119                     (a->date_time = strdup(valstr))) {
1120                         if (head == NULL)
1121                                 head = a;
1122                         else
1123                                 prev->next = a;
1124                 } else
1125                         stat = CSA_E_INSUFFICIENT_MEMORY;
1126         }
1127
1128         if (stat == CSA_SUCCESS) {
1129                 val->item.date_time_list_value = head;
1130                 *attrval = val;
1131         } else {
1132                 _DtCm_free_date_time_list(head);
1133                 free(val);
1134         }
1135
1136         return (stat);
1137 }
1138
1139 static int
1140 extend_entry_table(int hashednum, char *name, char *typestr)
1141 {
1142         int     type;
1143
1144         if (hashednum > _DtCM_DEFINED_ENTRY_ATTR_SIZE) {
1145                 if ((type = get_tag_from_string(typestr)) == -1)
1146                         return (-1);
1147
1148                 (void)_DtCmExtendNameTable(name, hashednum, type,
1149                         _DtCm_entry_name_tbl, _DtCM_DEFINED_ENTRY_ATTR_SIZE,
1150                         _CSA_entry_attribute_names, &currentCalendar->entry_tbl,
1151                         &currentCalendar->types);
1152         }
1153         return (0);
1154 }
1155