2 * CDE - Common Desktop Environment
4 * Copyright (c) 1993-2012, The Open Group. All rights reserved.
6 * These libraries and programs are free software; you can
7 * redistribute them and/or modify them under the terms of the GNU
8 * Lesser General Public License as published by the Free Software
9 * Foundation; either version 2 of the License, or (at your option)
12 * These libraries and programs are distributed in the hope that
13 * they will be useful, but WITHOUT ANY WARRANTY; without even the
14 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU Lesser General Public License for more
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with these librararies and programs; if not, write
20 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21 * Floor, Boston, MA 02110-1301 USA
23 /* $XConsortium: log.c /main/8 1996/11/21 19:45:13 drk $ */
25 * (c) Copyright 1993, 1994 Hewlett-Packard Company
26 * (c) Copyright 1993, 1994 International Business Machines Corp.
27 * (c) Copyright 1993, 1994 Novell, Inc.
28 * (c) Copyright 1993, 1994 Sun Microsystems, Inc.
31 #include <EUSCompat.h>
40 #define XOS_USE_NO_LOCKING
41 #define X_INCLUDE_TIME_H
45 #include <X11/Xos_r.h>
51 extern uid_t daemon_uid;
52 extern gid_t daemon_gid;
55 static char *spool_dir = _DtCMS_DEFAULT_DIR;
57 char *tag_string[] = {
77 * forward declaration of functions used within this file
79 static char * cr_to_str(char *s, int size);
80 static void periodtostr(Interval_4 i, char *q);
81 static void privacytostr(Privacy_Level_4 p, char *q);
82 static void apptstatustostr(Appt_Status_4 p, char *q);
83 static void apptstatustostr(Appt_Status_4 p, char *q);
84 static void tagstostr(Event_Type_4 p, char *q);
85 static char * get_fname (char *dir, char *fname, char *who);
86 static CSA_return_code append_log(int f, char *buf);
87 static CSA_return_code create_log(char *owner, char *file, int version);
88 static char *attrs_to_attrliststr(int len, cms_attribute *attrs,
89 boolean_t write_hash, boolean_t entryattrs);
90 static char *grow_n_concat(char *base, char *newstr, int newcount);
91 static char *get_access_list_string(cms_access_entry *list);
92 static char *get_date_time_list_string(CSA_date_time_list list);
100 _DtCmsGetLogFN(char *who)
102 return (get_fname (spool_dir, _DtCMS_DEFAULT_LOG, who));
106 _DtCmsGetBakFN(char *who)
108 return (get_fname (spool_dir, _DtCMS_DEFAULT_BAK, who));
112 _DtCmsGetTmpFN(char *who)
114 return (get_fname (spool_dir, _DtCMS_DEFAULT_TMP, who));
118 _DtCmsGetDelFN(char *who)
120 return (get_fname (spool_dir, _DtCMS_DEFAULT_DEL, who));
123 extern CSA_return_code
124 _DtCmsCreateLogV1(char *owner, char *file)
126 return (create_log(owner, file, _DtCMS_VERSION1));
130 extern CSA_return_code
131 _DtCmsAppendHTableByFN(char *file, uint size, char **names, int *types)
134 CSA_return_code stat;
136 if ((f = open(file, O_WRONLY | O_APPEND | O_SYNC)) < 0) {
138 return (CSA_X_DT_E_BACKING_STORE_PROBLEM);
141 stat = _DtCmsAppendHTableByFD(f, size, names, types);
148 * the first element of the arrays is not used
150 extern CSA_return_code
151 _DtCmsAppendHTableByFD(int fd, uint size, char **names, int *types)
153 CSA_return_code stat;
154 char *tptr, *buf, tmpbuf[BUFSIZ/4];
155 int i, tcount, count = 15; /* strlen("(entrytable )\n") + 1 */
157 if ((buf = malloc(BUFSIZ)) == NULL) return (CSA_E_INSUFFICIENT_MEMORY);
159 strcpy(buf, "(entrytable ");
161 for (i = 1; i <= size; i++) {
162 sprintf(tmpbuf, "(%d \"%s\" \"%s\")\n", i, names[i],
163 tag_string[types[i]]);
165 count += strlen(tmpbuf);
166 if (tcount < count) {
167 if ((tptr = grow_n_concat(buf, tmpbuf, tcount + BUFSIZ))
170 return (CSA_E_INSUFFICIENT_MEMORY);
180 stat = append_log(fd, buf);
186 extern CSA_return_code
187 _DtCmsAppendEntryByFN(char *file, cms_entry *entry, _DtCmsLogOps op)
190 CSA_return_code stat;
192 if ((f = open(file, O_WRONLY | O_APPEND | O_SYNC)) < 0) {
194 return (CSA_X_DT_E_BACKING_STORE_PROBLEM);
197 stat = _DtCmsAppendEntryByFD(f, entry, op);
203 extern CSA_return_code
204 _DtCmsAppendEntryByFD(int f, cms_entry *entry, _DtCmsLogOps op)
206 CSA_return_code stat;
208 char *cptr, *tptr, *buf;
211 if ((buf = malloc(100)) == NULL) return (CSA_E_INSUFFICIENT_MEMORY);
213 _csa_tick_to_iso8601(entry->key.time, isotime);
214 sprintf(buf, "(%s \"%s\" key: %ld%s",
215 (op == _DtCmsLogAdd ? "add" : "remove"),
216 isotime, entry->key.id,
217 (op == _DtCmsLogAdd ? "\nhashedattributes: (" : ""));
218 count = strlen(buf) + 4;
220 if (op == _DtCmsLogAdd && entry->num_attrs > 0) {
221 if ((cptr = attrs_to_attrliststr(entry->num_attrs,
222 entry->attrs, B_TRUE, B_TRUE)) == NULL) {
224 return (CSA_E_INSUFFICIENT_MEMORY);
226 count += strlen(cptr);
227 if ((tptr = grow_n_concat(buf, cptr, count)) == NULL) {
230 return (CSA_E_INSUFFICIENT_MEMORY);
236 /* closing for attr list and closing for entry */
237 if (op == _DtCmsLogAdd)
242 stat = append_log(f, buf);
248 extern CSA_return_code
249 _DtCmsAppendCalAttrsByFN(char *file, int size, cms_attribute * attrs)
252 CSA_return_code stat;
254 if (file == NULL || size <= 0)
255 return (CSA_E_INVALID_PARAMETER);
257 if ((f = open(file, O_WRONLY | O_APPEND | O_SYNC)) < 0) {
259 return (CSA_X_DT_E_BACKING_STORE_PROBLEM);
262 stat = _DtCmsAppendCalAttrsByFD(f, size, attrs);
268 extern CSA_return_code
269 _DtCmsAppendCalAttrsByFD(int f, int size, cms_attribute * attrs)
271 CSA_return_code stat;
273 char *prefix = "(calendarattributes ";
274 char *subfix = ")\n";
277 if ((attrstr = attrs_to_attrliststr(size, attrs, B_FALSE, B_FALSE))
279 return (CSA_E_INSUFFICIENT_MEMORY);
281 count = strlen(prefix) + strlen(attrstr) + strlen(subfix) + 1;
282 if ((buf = malloc(count)) == NULL) {
284 return (CSA_E_INSUFFICIENT_MEMORY);
286 sprintf(buf, "%s%s%s", prefix, attrstr, subfix);
288 stat = append_log(f, buf);
295 extern CSA_return_code
296 _DtCmsAppendAppt4ByFN(char *file, Appt_4 *appt, _DtCmsLogOps op)
299 CSA_return_code stat;
301 if ((f = open(file, O_WRONLY | O_APPEND | O_SYNC)) < 0) {
303 return (CSA_X_DT_E_BACKING_STORE_PROBLEM);
306 stat = _DtCmsAppendAppt4ByFD(f, appt, op);
312 extern CSA_return_code
313 _DtCmsAppendAppt4ByFD(int f, Appt_4 *appt, _DtCmsLogOps op)
317 char buf[BUFSIZ*3], buf2[BUFSIZ*2]; /* 1 BUFSIZ for what fields,
318 1 BUFSIZ for mailto field,
319 and 1 BUFSIZ for the rest */
321 cptr = ctime (&appt->appt_id.tick);
322 cptr[24] = '\0'; /* strip off CR */
327 sprintf(buf, "(add \"%s\" key: %ld ", cptr, appt->appt_id.key);
329 cptr = cr_to_str(appt->what, strlen(appt->what));
331 sprintf(buf2, "what: \"%s\" ", cptr);
335 return (CSA_E_INSUFFICIENT_MEMORY);
338 if (appt->client_data) {
339 sprintf(buf2, "details: \"%s\" ", appt->client_data);
342 if (appt->duration) {
343 sprintf(buf2, "duration: %d ", appt->duration);
347 periodtostr (appt->period.period, tmpbuf);
348 sprintf(buf2, "period: %s ", tmpbuf);
351 if (appt->period.nth != 0) {
352 sprintf (buf2, "nth: %d ", appt->period.nth);
355 if (appt->period.enddate != 0) {
356 cptr = ctime (&(appt->period.enddate));
357 cptr[24] = '\0'; /* strip off CR */
358 sprintf(buf2, "enddate: \"%s\" ", cptr);
362 sprintf(buf2, "ntimes: %d ", appt->ntimes);
365 if (appt->exception != NULL) {
366 struct Except_4 *e = appt->exception;
367 strcat(buf, "exceptions: (");
369 sprintf(buf2, "%d ", e->ordinal);
376 if (appt->author != NULL) {
377 sprintf(buf2, "author: \"%s\" ", appt->author);
380 if (appt->attr != NULL) {
381 struct Attribute_4 *item = appt->attr;
382 strcat(buf, "attributes: (");
383 while(item != NULL) {
384 sprintf(buf2, "(\"%s\",\"%s\",\"%s\")",
385 item->attr, item->value,
392 if (appt->tag != NULL) {
393 struct Tag_4 *item = appt->tag;
394 strcat(buf, "tags: (");
395 while(item != NULL) {
396 tagstostr(item->tag, tmpbuf);
397 sprintf(buf2, "(%s , %d)", tmpbuf,
405 apptstatustostr(appt->appt_status, tmpbuf);
406 sprintf(buf2, "apptstat: %s ", tmpbuf);
409 privacytostr(appt->privacy, tmpbuf);
410 sprintf(buf2, "privacy: %s )\n", tmpbuf);
415 case _DtCmsLogRemove:
416 sprintf(buf, "(remove \"%s\" key: %ld)\n", cptr,
421 return (append_log(f, buf));
424 extern CSA_return_code
425 _DtCmsAppendAccessByFN(char *file, int type, Access_Entry_4 *p)
428 CSA_return_code stat;
430 if ((f = open(file, O_WRONLY | O_APPEND | O_SYNC)) < 0) {
432 return (CSA_X_DT_E_BACKING_STORE_PROBLEM);
435 stat = _DtCmsAppendAccessByFD(f, type, p);
441 extern CSA_return_code
442 _DtCmsAppendAccessByFD(int f, int type, Access_Entry_4 *p)
444 CSA_return_code stat;
445 int count = 12; /* (access )\n */
449 if (type == access_read_4)
451 else if (type == access_write_4)
453 else if (type == access_delete_4)
455 else if (type == access_exec_4)
458 return (CSA_E_INVALID_PARAMETER);
460 count = count + strlen(p_type);
461 if ((buf = malloc(count)) == NULL)
462 return (CSA_E_INSUFFICIENT_MEMORY);
464 sprintf(buf, "(access %s ", p_type);
467 if (p->who != NULL) {
468 count = count + strlen(p->who) + 3;
469 if ((buf = realloc(buf, count)) == NULL)
470 return (CSA_E_INSUFFICIENT_MEMORY);
481 stat = append_log(f, buf);
488 _DtCmsPrintAppt4(caddr_t data)
490 Appt_4 *appt = (Appt_4 *)data;
494 fprintf(stderr, "*** V4 appointement: ***\n\n");
496 tmstr = ctime (&appt->appt_id.tick);
497 tmstr[24] = '\0'; /* strip off CR */
499 if (fprintf(stderr, "(add \"%s\" ", tmstr)==EOF) {
502 if (fprintf(stderr, "key: %ld ", appt->appt_id.key)==EOF) {
506 tmstr = cr_to_str(appt->what, strlen(appt->what));
507 if (fprintf(stderr, "what: \"%s\" ", tmstr) == EOF) {
513 if (appt->client_data) {
514 if (fprintf(stderr, "details: \"%s\" ", appt->client_data)
518 if (appt->duration) {
519 if (fprintf(stderr, "duration: %d ", appt->duration) == EOF)
524 periodtostr (appt->period.period, buf);
525 if (fprintf(stderr, "period: %s ", buf) == EOF)
528 if (appt->period.nth != 0) {
529 if (fprintf (stderr, "nth: %d ", appt->period.nth) == EOF)
532 if (appt->period.enddate != 0) {
533 tmstr = ctime (&(appt->period.enddate));
534 tmstr[24] = '\0'; /* strip off CR */
535 if (fprintf(stderr, "enddate: \"%s\" ", tmstr) == EOF)
539 if (fprintf(stderr, "ntimes: %d ", appt->ntimes) == EOF)
542 if (appt->exception != NULL) {
543 struct Except_4 *e = appt->exception;
544 if (fprintf(stderr, "exceptions: (") == EOF)
547 if (fprintf(stderr, "%d ", e->ordinal) == EOF)
551 if (fprintf(stderr, ") ") == EOF)
554 if (appt->author != NULL) {
555 if (fprintf(stderr, "author: \"%s\" ", appt->author) == EOF)
558 if (appt->attr != NULL) {
559 struct Attribute_4 *item = appt->attr;
560 if (fprintf(stderr, "attributes: (") == EOF)
562 while(item != NULL) {
563 if (fprintf(stderr, "(\"%s\",\"%s\",\"%s\")",
564 item->attr, item->value, item->clientdata) == EOF)
568 if (fprintf(stderr, ") ") == EOF)
571 if (appt->tag != NULL) {
572 struct Tag_4 *item = appt->tag;
573 if (fprintf(stderr, "tags: (") == EOF)
575 while(item != NULL) {
577 tagstostr(item->tag, buf);
578 if (fprintf(stderr, "(%s , %d)", buf, item->showtime)
583 if (fprintf(stderr, ") ") == EOF)
589 apptstatustostr(appt->appt_status, buf);
590 if (fprintf(stderr, "apptstat: %s ", buf) == EOF)
594 privacytostr(appt->privacy, buf);
595 if (fprintf(stderr, "privacy: %s )\n", buf) == EOF)
602 _DtCmsPrintExceptions(int len, int *exceptions)
606 fprintf(stderr, "\nexception part:\n");
607 fprintf(stderr, "number of exception = %d\n", len);
608 fprintf(stderr, "exceptions:");
609 for (i = 0; i < len; i++) {
610 fprintf(stderr, " %d", exceptions[i]);
612 fprintf(stderr, "\n");
615 extern CSA_return_code
616 _DtCmsCreateLogV2(char *owner, char *file)
618 return (create_log(owner, file, _DtCMS_VERSION4));
621 extern CSA_return_code
622 _DtCmsGetFileSize(char *calendar, int *size)
627 if ((log = _DtCmsGetLogFN(calendar)) == NULL)
628 return (CSA_E_INSUFFICIENT_MEMORY);
630 if (stat(log, &info) != 0) {
632 return (CSA_X_DT_E_BACKING_STORE_PROBLEM);
634 *size = info.st_size;
636 return (CSA_SUCCESS);
641 _DtCmsTruncateFile(char *calendar, int size)
646 if ((log = _DtCmsGetLogFN(calendar)) == NULL)
649 /* truncate log file to specified size */
650 if ((f = open(log, O_RDWR | O_APPEND | O_SYNC)) >= 0) {
651 if(-1 == ftruncate(f, size)) {
652 perror(strerror(errno));
659 extern CSA_return_code
660 _DtCmsRemoveLog(char *calendar, char *user)
662 CSA_return_code stat = CSA_SUCCESS;
665 if ((log = _DtCmsGetLogFN(calendar)) == NULL)
666 return (CSA_E_INSUFFICIENT_MEMORY);
668 if ((dlog = _DtCmsGetDelFN(calendar)) == NULL) {
670 return (CSA_E_INSUFFICIENT_MEMORY);
673 if (rename(log, dlog) < 0)
674 stat = CSA_X_DT_E_BACKING_STORE_PROBLEM;
682 extern CSA_return_code
683 _DtCmsWriteVersionString(char *file, int version)
690 CSA_return_code stat = CSA_SUCCESS;
691 _Xltimeparams localtime_buf;
692 _Xatimeparams asctime_buf;
694 tmval = time((time_t *) 0);
695 tm = _XLocaltime(&tmval, localtime_buf);
696 tmstr = _XAsctime(tm, asctime_buf);
697 tmstr[24] = '\0'; /* strip off CR */
699 if ((fd = open(file, O_WRONLY|O_TRUNC|O_SYNC)) < 0) {
701 fprintf(stderr, "%s: failed to open %s\n",
703 return (CSA_X_DT_E_BACKING_STORE_PROBLEM);
706 sprintf(buf, "Version: %d\n**** start of log on %s ****\n\n",
710 if (write(fd, buf, len) != len) {
712 stat = CSA_X_DT_E_BACKING_STORE_PROBLEM;
720 * if everything works fine, return 0; otherwise, return -1
728 boolean_t changeeuid,
734 if (changeeuid == B_TRUE) {
739 if(-1 == seteuid (0)) {
740 perror(strerror(errno));
746 if (chmod (file, mode) < 0) {
747 if (printerr == B_TRUE) {
749 sprintf (buff, "%s: chmod %s to %lo failed.\n%s: System error",
750 pgname, file, (long)mode, pgname);
757 if (chown (file, uid, gid) < 0) {
758 if (printerr == B_TRUE) {
760 sprintf (buff, "%s: chown %s to (uid=%ld,gid=%ld) failed.\n%s%s",
761 pgname, file, (long)uid, (long)gid, pgname, ": System error");
770 if (changeeuid == B_TRUE && setuid (daemon_uid) < 0)
772 if (changeeuid == B_TRUE && seteuid (daemon_uid) < 0)
775 if (printerr == B_TRUE) {
777 sprintf (buff, "%s: Can't switch process uid back to daemon.\n%s%s",
778 pgname, pgname, ": System error");
789 periodtostr(Interval_4 i, char *q)
795 strcpy (q, "single");
801 strcpy (q, "weekly");
804 strcpy (q, "biweekly");
807 strcpy (q, "monthly");
810 strcpy (q, "yearly");
813 strcpy (q, "nthWeekday");
816 strcpy (q, "everyNthDay");
819 strcpy (q, "everyNthWeek");
821 case everyNthMonth_4:
822 strcpy (q, "everyNthMonth");
825 strcpy (q, "monThruFri");
828 strcpy (q, "monWedFri");
831 strcpy (q, "tueThur");
834 strcpy (q, "daysOfWeek");
837 strcpy (q, "single");
843 privacytostr(Privacy_Level_4 p, char *q)
852 strcpy(q, "private");
855 strcpy(q, "semiprivate");
864 apptstatustostr(Appt_Status_4 p, char *q)
873 strcpy(q, "pendingAdd");
875 case pendingDelete_4:
876 strcpy(q, "pendingDelete");
879 strcpy(q, "committed");
882 strcpy(q, "cancelled");
885 strcpy(q, "completed");
894 tagstostr(Event_Type_4 p, char *q)
900 strcpy(q, "appointment");
903 strcpy(q, "reminder");
906 strcpy(q, "otherTag");
909 strcpy(q, "holiday");
915 strcpy(q, "appointment");
921 get_fname (char *dir, char *fname, char *who)
925 buf = (char *)malloc(strlen(dir) + strlen(fname) + strlen(who) + 3);
927 sprintf (buf, "%s/%s.%s", dir, fname, who);
931 static CSA_return_code
932 create_log(char *owner, char *file, int version)
938 CSA_return_code stat;
940 ptr = strchr(owner, '@');
941 if (ptr) *ptr = '\0';
942 pw = getpwnam (owner);
945 return(CSA_E_FAILURE);
949 /* Read by owner and Read/Write by group (gid must be daemon) */
950 fd = open(file, O_WRONLY|O_CREAT|O_EXCL, _DtCMS_DEFAULT_MODE);
953 fprintf(stderr, "%s: can't create %s\n", pgname, file);
956 return(CSA_E_CALENDAR_EXISTS);
958 return(CSA_X_DT_E_BACKING_STORE_PROBLEM);
961 if (_DtCmsSetFileMode(file, uid, daemon_gid, _DtCMS_DEFAULT_MODE,
962 B_TRUE, B_TRUE) < 0) {
965 return(CSA_X_DT_E_BACKING_STORE_PROBLEM);
969 if ((stat = _DtCmsWriteVersionString(file, version)) != CSA_SUCCESS) {
976 static CSA_return_code
977 append_log(int f, char *buf)
979 CSA_return_code status;
981 int file_size = 0, nbytes_written = 0, nbytes_towrite = 0;
984 return (CSA_E_INVALID_PARAMETER);
986 if (fstat(f, &finfo) < 0) {
988 return (CSA_X_DT_E_BACKING_STORE_PROBLEM);
990 file_size = finfo.st_size;
992 nbytes_towrite = strlen(buf);
993 nbytes_written = write(f, buf, nbytes_towrite);
994 if (nbytes_written != nbytes_towrite) {
996 status = CSA_E_DISK_FULL;
998 status = CSA_X_DT_E_BACKING_STORE_PROBLEM;
1001 if(-1 == ftruncate(f, file_size)) {
1002 perror(strerror(errno));
1003 status = CSA_X_DT_E_BACKING_STORE_PROBLEM;
1008 return(CSA_SUCCESS);
1012 grow_n_concat(char *base, char *newstr, int newcount)
1016 if ((ptr = realloc(base, newcount)) == NULL)
1020 strcat(ptr, newstr);
1022 strcpy(ptr, newstr);
1028 * format of attributes:
1029 * CSA_VALUE_BOOLEAN: ("name","type","number")
1030 * CSA_VALUE_ENUMERATED: ("name","type","number")
1031 * CSA_VALUE_FLAGS: ("name","type","number")
1032 * CSA_VALUE_SINT32: ("name","type","number")
1033 * CSA_VALUE_UINT32: ("name","type","number")
1034 * CSA_VALUE_STRING: ("name","type","string")
1035 * CSA_VALUE_ACCESS_LIST: ("name","type","user:rights [user:rights]")
1036 * CSA_VALUE_CALENDAR_USER: ("name","type","string")
1037 * CSA_VALUE_DATE_TIME: ("name","type","datetime")
1038 * CSA_VALUE_DATE_TIME_RANGE: ("name","type","datetimerange")
1039 * CSA_VALUE_TIME_DURATION: ("name","type","timeduration")
1040 * CSA_VALUE_DATE_TIME_LIST: ("name","type","datetime [datetime]")
1041 * CSA_VALUE_REMINDER: ("name","type","string:number:string") or
1042 * ("name","type","string:string:number:number:string")
1043 * CSA_VALUE_OPAQUE_DATA: ("name","type","number:string")
1045 * format of attributes (when only hashed number is written):
1046 * CSA_VALUE_BOOLEAN: (hash_number "number")
1047 * CSA_VALUE_ENUMERATED: (hash_number "number")
1048 * CSA_VALUE_FLAGS: (hash_number "number")
1049 * CSA_VALUE_SINT32: (hash_number "number")
1050 * CSA_VALUE_UINT32: (hash_number "number")
1051 * CSA_VALUE_STRING: (hash_number "string")
1052 * CSA_VALUE_ACCESS_LIST: (hash_number "user:rights [user:rights]")
1053 * CSA_VALUE_CALENDAR_USER: (hash_number "string")
1054 * CSA_VALUE_DATE_TIME: (hash_number "datetime")
1055 * CSA_VALUE_DATE_TIME_RANGE: (hash_number "datetimerange")
1056 * CSA_VALUE_TIME_DURATION: (hash_number "timeduration")
1057 * CSA_VALUE_DATE_TIME_LIST: (hash_number "datetime [datetime]")
1058 * CSA_VALUE_REMINDER: (hash_number "string:number:string") or
1059 * (hash_number "string:string:number:number:string")
1060 * CSA_VALUE_OPAQUE_DATA: (hash_number "number:string")
1062 * Note: element 0 of the array is not used
1065 attrs_to_attrliststr(
1067 cms_attribute *attrs,
1068 boolean_t write_hash,
1069 boolean_t entryattrs)
1071 int i, count, tcount;
1072 char *ptr, *buf = NULL;
1073 char tmpbuf[BUFSIZ/2], tmpbuf2[BUFSIZ/2], *body;
1074 CSA_opaque_data *opq;
1076 if ((buf = malloc(BUFSIZ+1)) == NULL) return (NULL);
1079 for (i = 1, count = 0, *buf = '\0'; i <= num_attr; i++) {
1081 if (attrs[i].value == NULL || (entryattrs &&
1082 (i == CSA_ENTRY_ATTR_NUMBER_RECURRENCES_I ||
1083 i == CSA_X_DT_ENTRY_ATTR_REPEAT_TYPE_I ||
1084 i == CSA_X_DT_ENTRY_ATTR_REPEAT_TIMES_I ||
1085 i == CSA_X_DT_ENTRY_ATTR_REPEAT_INTERVAL_I ||
1086 i == CSA_X_DT_ENTRY_ATTR_REPEAT_OCCURRENCE_NUM_I ||
1087 i == CSA_X_DT_ENTRY_ATTR_SEQUENCE_END_DATE_I)))
1091 /* open_bracket hash_number open quote for value */
1092 sprintf(tmpbuf, "(%d \"", attrs[i].name.num);
1094 /* open bracket name, type, open quote for value */
1095 sprintf(tmpbuf, "(\"%s\",\"%s\",\"", attrs[i].name.name,
1096 tag_string[attrs[i].value->type]);
1101 switch (attrs[i].value->type) {
1102 case CSA_VALUE_ENUMERATED:
1103 case CSA_VALUE_SINT32:
1104 sprintf(tmpbuf2, "%ld",
1105 attrs[i].value->item.sint32_value);
1108 case CSA_VALUE_BOOLEAN:
1109 case CSA_VALUE_FLAGS:
1110 case CSA_VALUE_UINT32:
1111 sprintf(tmpbuf2, "%lu",
1112 attrs[i].value->item.uint32_value);
1115 case CSA_VALUE_STRING:
1116 case CSA_VALUE_DATE_TIME:
1117 case CSA_VALUE_DATE_TIME_RANGE:
1118 case CSA_VALUE_TIME_DURATION:
1119 case CSA_VALUE_CALENDAR_USER:
1120 if (attrs[i].value->item.string_value) {
1121 if ((ptr = cr_to_str(attrs[i].value->\
1123 strlen(attrs[i].value->item.string_value)))
1134 case CSA_VALUE_REMINDER:
1135 opq = &attrs[i].value->item.reminder_value->\
1137 if (attrs[i].value->item.reminder_value->repeat_count
1140 sprintf(tmpbuf2, "%s:%s:%lu:%lu:",
1141 attrs[i].value->item.reminder_value->lead_time,
1142 (attrs[i].value->item.reminder_value->snooze_time ?
1143 attrs[i].value->item.reminder_value->snooze_time:""),
1144 attrs[i].value->item.reminder_value->repeat_count,
1147 sprintf(tmpbuf2, "%s:%lu:",
1148 attrs[i].value->item.reminder_value->lead_time,
1152 if (opq->size > 0) {
1153 if ((ptr = cr_to_str((char *)opq->data,
1154 opq->size)) == NULL) {
1164 case CSA_VALUE_OPAQUE_DATA:
1165 opq = attrs[i].value->item.opaque_data_value;
1166 sprintf(tmpbuf2, "%lu:", opq->size);
1168 if (opq->size > 0) {
1169 if ((ptr = cr_to_str((char *)opq->data,
1170 opq->size)) == NULL) {
1179 case CSA_VALUE_ACCESS_LIST:
1180 if (attrs[i].value->item.access_list_value) {
1181 if ((ptr = get_access_list_string(
1182 attrs[i].value->item.access_list_value))
1192 case CSA_VALUE_DATE_TIME_LIST:
1193 if (attrs[i].value->item.date_time_list_value) {
1194 if ((ptr = get_date_time_list_string(
1195 attrs[i].value->item.date_time_list_value))
1206 count += strlen(tmpbuf) + strlen(tmpbuf2) +
1207 (body ? strlen(body) : 0) + 3; /* closing */
1208 if (tcount < count) {
1209 if ((ptr = realloc(buf, tcount+BUFSIZ)) == NULL) {
1210 if (body) free(body);
1217 strcat(buf, tmpbuf);
1218 if (*tmpbuf2 != '\0') strcat(buf, tmpbuf2);
1219 if (body) strcat(buf, body);
1220 strcat(buf, "\")\n");
1221 if (body) free(body);
1228 get_access_list_string(cms_access_entry *list)
1230 char *ptr = NULL, *tptr, buf[BUFSIZ/4];
1233 /* do the first one */
1234 if ((ptr = malloc(BUFSIZ+1)) == NULL) return (NULL);
1236 sprintf(ptr, "%s:%u", list->user, list->rights);
1237 count = strlen(ptr);
1239 while (list->next) {
1241 sprintf(buf, " %s:%u", list->user, list->rights);
1243 count += strlen(buf);
1244 if (tcount < count) {
1245 if ((tptr = grow_n_concat(ptr, buf, tcount+BUFSIZ))
1259 cr_to_str(char *s, int size)
1267 if ((newstr = (char *) calloc(1, (unsigned)((2 * size) + 2))) == NULL)
1270 for (j=0; j<size; j++) {
1276 else if (s[j]=='\\') {
1281 else if (s[j]=='\"') {
1296 get_date_time_list_string(CSA_date_time_list list)
1298 char *ptr = NULL, *tptr, buf[80];
1299 int count, datestrlen, tcount;
1301 /* do the first one */
1302 sprintf(buf, "%s", list->date_time);
1303 if ((ptr = strdup(buf)) == NULL)
1306 if ((ptr = malloc(BUFSIZ+1)) == NULL) return (NULL);
1308 strcpy(ptr, list->date_time);
1309 count = strlen(ptr);
1311 datestrlen = count + 1;
1312 while (list->next) {
1314 sprintf(buf, " %s", list->date_time);
1316 count += datestrlen;
1317 if (tcount < count) {
1318 if ((tptr = grow_n_concat(ptr, buf, tcount+BUFSIZ))