dtcm: Resolve CID 87822
[oweals/cde.git] / cde / programs / dtcm / server / rerule.c
1 /*
2  * CDE - Common Desktop Environment
3  *
4  * Copyright (c) 1993-2012, The Open Group. All rights reserved.
5  *
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)
10  * any later version.
11  *
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
16  * details.
17  *
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
22  */
23 /* $XConsortium: rerule.c /main/4 1995/11/09 12:50:23 rswiston $ */
24 /*
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.
29  */
30
31 #include <stdio.h>
32 #include <ctype.h>
33 #include <time.h>
34 #include <stdlib.h>
35 #include <string.h>
36 #include "rerule.h"
37
38 typedef enum {
39         NUM_NUM         = 0,    /* Used in NumsToBuf to tell the proc what  */
40         NUM_DAY,                /* type of list we are handing it.          */
41         NUM_WEEK
42 } NumType;
43
44 static void NumsToBuf(unsigned int *, unsigned int, NumType, char *,
45                         unsigned int);
46 static void WeekNumberToString(WeekNumber, char *);
47 static void WeekDayToString(WeekDay, char *);
48 static void ConvertDaily(RepeatEvent *, char *, unsigned int);
49 static void ConvertWeekly(RepeatEvent *, char *, unsigned int);
50 static void ConvertMonthly(RepeatEvent *, char *, unsigned int);
51 static void ConvertYearly(RepeatEvent *, char *, unsigned int);
52
53 #define RE_DAILY(re) (re->re_data.re_daily)
54 #define RE_WEEKLY(re) (re->re_data.re_weekly)
55 #define RE_MONTHLY(re) (re->re_data.re_monthly)
56 #define RE_YEARLY(re) (re->re_data.re_yearly)
57
58 char *
59 ReToString(
60         RepeatEvent *re)
61 {
62         char    *cmd_buf = NULL;
63         char    *cmd_buf_tmp = NULL;
64         int      cmd_buf_size = 0;
65         int      subcommand_size = 0;
66         char     subcommand[1024];  /* XXX: fixed size */
67
68         if (!re) return (char *)NULL;
69
70         while (re) {
71                 switch (re->re_type) {
72
73                 case RT_MINUTE:
74                         sprintf(subcommand, "M%d #%d",
75                                         re->re_interval, re->re_duration);
76                         break;
77                 case RT_DAILY:
78                         ConvertDaily(re, subcommand, 1024);
79                         break;
80                 case RT_WEEKLY:
81                         ConvertWeekly(re, subcommand, 1024);
82                         break;
83                 case RT_MONTHLY_POSITION:
84                 case RT_MONTHLY_DAY:
85                         ConvertMonthly(re, subcommand, 1024);
86                         break;
87                 case RT_YEARLY_MONTH:
88                 case RT_YEARLY_DAY:
89                         ConvertYearly(re, subcommand, 1024);
90                         break;
91                 }
92
93                 cmd_buf_tmp = cmd_buf;
94
95                 if (cmd_buf) cmd_buf_size = strlen(cmd_buf);
96                 if (subcommand) subcommand_size = strlen(subcommand);
97
98                 cmd_buf = (char *)calloc(1, cmd_buf_size + subcommand_size + 2);
99
100                 if (cmd_buf_tmp)
101                         strcat (cmd_buf, cmd_buf_tmp);
102                         
103                 if (subcommand) {
104                         if (cmd_buf_tmp)
105                                 strcat (cmd_buf, " ");
106                         strcat (cmd_buf, subcommand);
107                 }
108
109                 memset (subcommand, 0, 1024);
110
111                 re = re->re_next;
112         }
113
114         return cmd_buf;
115 }
116
117 /*
118  * Takes an array of numbers, converts them back into their string
119  * type (e.g. SU 1W etc) and puts them into a string buffer with end
120  * marks as necessary, seperated by spaces.
121  */
122 static void
123 NumsToBuf(
124         unsigned int    *array,
125         unsigned int     array_size,
126         NumType          type,
127         char            *buffer,
128         unsigned int     buf_size)
129 {
130         int      i,
131                  size = 0; 
132         char     tmp_buf[32],
133                  tmp_buf2[32];
134
135         for (i = 0; i < array_size; i++) {
136                 if (type == NUM_NUM)
137                         sprintf(tmp_buf2, " %d", RE_MASK_STOP(array[i]));
138                 else if (type == NUM_DAY)
139                         WeekDayToString(RE_MASK_STOP(array[i]), tmp_buf2);
140                 else if (type == NUM_WEEK)
141                         WeekNumberToString(RE_MASK_STOP(array[i]), tmp_buf2);
142                         
143                         /* Add end mark if needed */
144                 if (RE_STOP_IS_SET(array[i])) {
145                         sprintf(tmp_buf, "%s$", tmp_buf2);
146                         strcat (buffer, tmp_buf);
147                         size += strlen(tmp_buf);
148                 } else {
149                         strcat (buffer, tmp_buf2);
150                         size += strlen(tmp_buf2);
151                 }
152
153                         /* Make sure the size of our buffer does not overflow */
154                 if (size > buf_size) {
155                         printf ("Error: Internal buffer size exceeded\n");
156                         return;
157                 }
158         }
159 }
160
161 static void
162 WeekDayToString(
163         WeekDay          day,
164         char            *buffer)
165 {
166         switch (RE_MASK_STOP(day)) {
167         case WD_SUN:
168                 sprintf (buffer, " SU");
169                 break;
170         case WD_MON:
171                 sprintf (buffer, " MO");
172                 break;
173         case WD_TUE:
174                 sprintf (buffer, " TU");
175                 break;
176         case WD_WED:
177                 sprintf (buffer, " WE");
178                 break;
179         case WD_THU:
180                 sprintf (buffer, " TH");
181                 break;
182         case WD_FRI:
183                 sprintf (buffer, " FR");
184                 break;
185         case WD_SAT:
186                 sprintf (buffer, " SA");
187                 break;
188         }
189
190         if (RE_STOP_IS_SET(day))
191                 strcat (buffer, "$");
192 }
193
194 static void
195 WeekNumberToString(
196         WeekNumber       week,
197         char            *buffer)
198 {
199         switch (RE_MASK_STOP(week)) {
200         case WK_F1:
201                 sprintf (buffer, " 1+");
202                 break;
203         case WK_F2:
204                 sprintf (buffer, " 2+");
205                 break;
206         case WK_F3:
207                 sprintf (buffer, " 3+");
208                 break;
209         case WK_F4:
210                 sprintf (buffer, " 4+");
211                 break;
212         case WK_F5:
213                 sprintf (buffer, " 5+");
214                 break;
215         case WK_L1:
216                 sprintf (buffer, " 1-");
217                 break;
218         case WK_L2:
219                 sprintf (buffer, " 2-");
220                 break;
221         case WK_L3:
222                 sprintf (buffer, " 3-");
223                 break;
224         case WK_L4:
225                 sprintf (buffer, " 4-");
226                 break;
227         case WK_L5:
228                 sprintf (buffer, " 5-");
229                 break;
230         }
231
232         if (RE_STOP_IS_SET(week))
233                 strcat (buffer, "$");
234 }
235
236 static void
237 ConvertDaily(
238         RepeatEvent     *re,
239         char            *subcommand,
240         unsigned int     buf_size)
241 {
242         char            tmp_buf[32];
243         unsigned int    size = 0,
244                         num_time,
245                         i;
246
247         num_time = RE_DAILY(re)->dd_ntime;
248
249         sprintf(subcommand, "D%d", re->re_interval);
250         size += strlen(subcommand);
251
252         NumsToBuf((unsigned int *)RE_DAILY(re)->dd_time, num_time, NUM_NUM,
253                   subcommand, buf_size - size);
254
255                 /* Tack on the duration information */
256         sprintf(tmp_buf, " #%d", re->re_duration);
257
258         size += strlen(tmp_buf);
259         if (size > buf_size) {
260                 printf ("Error: Internal buffer size exceeded\n");
261                 return;
262         }
263         strcat (subcommand, tmp_buf);
264 }
265
266 static void
267 ConvertWeekly(
268         RepeatEvent     *re,
269         char            *subcommand,
270         unsigned int     subcommand_size)
271 {
272         char     tmp_buf[32];
273         int      size = 0,
274                  num_items,
275                  i;
276
277         num_items = RE_WEEKLY(re)->wd_ndaytime;
278
279         sprintf(subcommand, "W%d", re->re_interval);
280         size += strlen(subcommand);
281
282                 /* walk through Day/time data (e.g. TU 1200 Th 2000)    */
283         for (i = 0; i < num_items; i++) {
284
285                         /* The day: MO TU TH etc. */
286                 WeekDayToString(RE_WEEKLY(re)->wd_daytime[i].dt_day, tmp_buf);
287                 size += strlen(tmp_buf);
288
289                         /* Make sure the size of our buffer does not overflow */
290                 if (size > subcommand_size) {
291                         printf ("Error: Internal buffer size exceeded\n");
292                         return;
293                 }
294
295                 strcat (subcommand, tmp_buf);
296
297                         /* The hours: 1000 1400 etc. */
298                 NumsToBuf((unsigned int *)RE_WEEKLY(re)->wd_daytime[i].dt_time,
299                           RE_WEEKLY(re)->wd_daytime[i].dt_ntime, NUM_NUM,
300                           subcommand, subcommand_size - size);
301
302                 size = strlen(subcommand);
303         }
304                 /* Tack on the duration information */
305         sprintf(tmp_buf, " #%d", re->re_duration);
306
307         size += strlen(tmp_buf);
308         if (size > subcommand_size) {
309                 printf ("Error: Internal buffer size exceeded\n");
310                 return;
311         }
312         strcat (subcommand, tmp_buf);
313 }
314
315 static void
316 ConvertMonthly(
317         RepeatEvent     *re,
318         char            *subcommand,
319         unsigned int     subcommand_size)
320 {
321         char     tmp_buf[32];
322         int      size = 0,
323                  num_items,
324                  i;
325
326         num_items = RE_MONTHLY(re)->md_nitems;
327
328         if (re->re_type == RT_MONTHLY_POSITION)
329                 sprintf(subcommand, "MP%d", re->re_interval);
330         else
331                 sprintf(subcommand, "MD%d", re->re_interval);
332
333         size += strlen(subcommand);
334
335         if (re->re_type == RT_MONTHLY_POSITION) {
336
337                 /* walk through Day/time data (e.g. TU 1200 Th 2000)    */
338             for (i = 0; i < num_items; i++) {
339
340                         /* The week: 1+ 3- etc. */
341                 NumsToBuf(
342                          (unsigned int*)RE_MONTHLY(re)->md_weektime[i].wdt_week,
343                           RE_MONTHLY(re)->md_weektime[i].wdt_nweek, NUM_WEEK,
344                           subcommand, subcommand_size - size);
345
346                 size = strlen(subcommand);
347
348                         /* Make sure the size of our buffer does not overflow */
349                 if (size > subcommand_size) {
350                         printf ("Error: Internal buffer size exceeded\n");
351                         return;
352                 }
353
354                         /* The day: SU MO TU etc. */
355                 NumsToBuf(
356                          (unsigned int *)RE_MONTHLY(re)->md_weektime[i].wdt_day,
357                           RE_MONTHLY(re)->md_weektime[i].wdt_nday, NUM_DAY,
358                           subcommand, subcommand_size - size);
359
360                 size = strlen(subcommand);
361
362                         /* Make sure the size of our buffer does not overflow */
363                 if (size > subcommand_size) {
364                         printf ("Error: Internal buffer size exceeded\n");
365                         return;
366                 }
367
368                         /* The hours: 1000 1400 etc. */
369                 NumsToBuf(
370                          (unsigned int *)
371                                 RE_MONTHLY(re)->md_weektime[i].wdt_time,
372                           RE_MONTHLY(re)->md_weektime[i].wdt_ntime, NUM_NUM,
373                           subcommand, subcommand_size - size);
374
375                 size = strlen(subcommand);
376             }
377         } else {  /* RT_MONTHLY_DAY */
378                         /* The days: 1 15 31 etc. */
379                 NumsToBuf((unsigned int *)RE_MONTHLY(re)->md_days,
380                           num_items, NUM_NUM, subcommand,
381                           subcommand_size - size);
382         }
383                 /* Tack on the duration information */
384         sprintf(tmp_buf, " #%d", re->re_duration);
385
386         size += strlen(tmp_buf);
387         if (size > subcommand_size) {
388                 printf ("Error: Internal buffer size exceeded\n");
389                 return;
390         }
391         strcat (subcommand, tmp_buf);
392 }
393
394 static void
395 ConvertYearly(
396         RepeatEvent     *re,
397         char            *subcommand,
398         unsigned int     subcommand_size)
399 {
400         char     tmp_buf[32];
401         int      size = 0,
402                  num_items,
403                  i;
404
405         num_items = RE_YEARLY(re)->yd_nitems;
406
407         if (re->re_type == RT_YEARLY_MONTH)
408                 sprintf(subcommand, "YM%d", re->re_interval);
409         else
410                 sprintf(subcommand, "YD%d", re->re_interval);
411
412         size += strlen(subcommand);
413
414                 /* An array of days or months */
415         NumsToBuf(RE_YEARLY(re)->yd_items,
416                   RE_YEARLY(re)->yd_nitems, NUM_NUM,
417                   subcommand, subcommand_size - size);
418
419                 /* Tack on the duration information */
420         sprintf(tmp_buf, " #%d", re->re_duration);
421
422         size += strlen(tmp_buf);
423         if (size > subcommand_size) {
424                 printf ("Error: Internal buffer size exceeded\n");
425                 return;
426         }
427         strcat (subcommand, tmp_buf);
428 }