ical.c - libical - A simple ical library.
(HTM) git clone git://r-36.net/libical
(DIR) Log
(DIR) Files
(DIR) Refs
(DIR) README
(DIR) LICENSE
---
ical.c (5278B)
---
1 /*
2 * Copy me if you can.
3 * by 20h
4 */
5
6 #include <unistd.h>
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <strings.h>
10 #include <string.h>
11
12 #include "ind.h"
13 #include "ical.h"
14
15 vitemprop_t *
16 vitemprop_new(void)
17 {
18 vitemprop_t *ret;
19
20 ret = mallocz(sizeof(vitemprop_t), 2);
21
22 return ret;
23 }
24
25 void
26 vitemprop_free(vitemprop_t *prop)
27 {
28 if (prop->name != NULL)
29 free(prop->name);
30 if (prop->params != NULL)
31 free(prop->params);
32 if (prop->value != NULL)
33 free(prop->value);
34
35 free(prop);
36 }
37
38 void
39 vitemprop_print(vitemprop_t *prop)
40 {
41 char *line, *lp, *cp;
42 int llen;
43
44 line = smprintf("%s%s%s:%s", prop->name,
45 (prop->params)? ";" : "",
46 (prop->params)? prop->params : "",
47 prop->value);
48 llen = strlen(line);
49 if (llen <= 73) {
50 printf("%s\r\n", line);
51 free(line);
52 return;
53 }
54
55 cp = memdupz(line, 73);
56 printf("%s\r\n", cp);
57 free(cp);
58 lp = line + 73;
59 llen -= 73;
60
61 for (; llen > 0;) {
62 cp = memdupz(lp, 72);
63 printf(" %s\r\n", cp);
64 free(cp);
65 lp += 72;
66 llen -= 72;
67 }
68 free(line);
69 }
70
71 vitem_t *
72 vitem_new(void)
73 {
74 vitem_t *ret;
75
76 ret = mallocz(sizeof(vitem_t), 2);
77
78 return ret;
79 }
80
81 void
82 vitem_free(vitem_t *item)
83 {
84 vitemprop_t *cur, *next;
85
86 for (cur = item->props; cur; cur = next) {
87 next = cur->next;
88
89 vitemprop_free(cur);
90 }
91
92 if (item->type != NULL)
93 free(item->type);
94
95 free(item);
96 }
97
98 void
99 vitem_addprop(vitem_t *item, vitemprop_t *prop)
100 {
101 if (item->props == NULL) {
102 item->props = prop;
103 item->lastp = prop;
104 } else {
105 item->lastp->next = prop;
106 prop->prev = item->lastp;
107 item->lastp = prop;
108 }
109 item->nprops++;
110 }
111
112 void
113 vitem_print(vitem_t *item)
114 {
115 vitemprop_t *elem;
116
117 printf("BEGIN:%s\n", item->type);
118 forlist(item->props, elem)
119 vitemprop_print(elem);
120 printf("END:%s\n", item->type);
121 }
122
123 vitems_t *
124 vitems_new(void)
125 {
126 vitems_t *ret;
127
128 ret = mallocz(sizeof(vitems_t), 2);
129
130 return ret;
131 }
132
133 void
134 vitems_free(vitems_t *items)
135 {
136 vitem_t *cur, *next;
137 vitemprop_t *pcur, *pnext;
138
139 for (cur = items->first; cur; cur = next) {
140 next = cur->next;
141 vitem_free(cur);
142 }
143
144 for (pcur = items->headers; pcur; pcur = pnext) {
145 pnext = pcur->next;
146 vitemprop_free(pcur);
147 }
148
149 free(items);
150 }
151
152 void
153 vitems_addhdr(vitems_t *items, vitemprop_t *hdr)
154 {
155 if (items->headers == NULL) {
156 items->headers = hdr;
157 items->lasth = hdr;
158 } else {
159 items->lasth->next = hdr;
160 hdr->prev = items->lasth;
161 items->lasth = hdr;
162 }
163 items->nheaders++;
164 }
165
166 void
167 vitems_additem(vitems_t *items, vitem_t *item)
168 {
169 if (items->first == NULL) {
170 items->first = item;
171 items->last = item;
172 } else {
173 items->last->next = item;
174 item->prev = items->last;
175 items->last = item;
176 }
177 items->nitems++;
178 }
179
180 void
181 vitems_print(vitems_t *items)
182 {
183 vitemprop_t *pelem;
184 vitem_t *ielem;
185
186 printf("BEGIN:VCALENDAR\r\n");
187 forlist(items->headers, pelem)
188 vitemprop_print(pelem);
189
190 forlist(items->first, ielem)
191 vitem_print(ielem);
192 printf("END:VCALENDAR\r\n");
193 }
194
195 enum {
196 STATE_INIT = 0x00,
197 STATE_VCALBEGIN,
198 STATE_VITEMBEGIN,
199 STATE_VCALEND
200 };
201
202 vitems_t *
203 vitems_read(int fd)
204 {
205 vitems_t *items;
206 vitem_t *item;
207 vitemprop_t *itemprop;
208 char *filebuf, *rp, *p, *sepp, *paramsp, buf[1024], *pbuf, *line,
209 *oline;
210 int len, state, blen, lnum;
211
212 filebuf = readtoeoffd(fd, &len);
213 if (filebuf == NULL)
214 return NULL;
215
216 state = STATE_INIT;
217 items = vitems_new();
218 item = NULL;
219
220 rp = filebuf;
221 p = filebuf;
222 line = NULL;
223 lnum = 0;
224 for (;;) {
225 if (line != NULL)
226 free(line);
227 line = NULL;
228 if (oline != NULL)
229 line = oline;
230
231 if (rp == NULL || state == STATE_VCALEND)
232 break;
233
234 for (; (rp = sgets(buf, sizeof(buf)-1, &p));) {
235 lnum++;
236
237 blen = strlen(buf);
238 if (buf[blen-1] == '\r') {
239 buf[blen-1] = '\0';
240 blen--;
241 }
242
243 pbuf = NULL;
244 switch (buf[0]) {
245 case '\t':
246 case ' ':
247 line = memdupcat(line, strlen(line),
248 &buf[1], blen-1);
249 pbuf = line;
250 break;
251 default:
252 break;
253 }
254
255 if (pbuf == NULL) {
256 if (line != NULL) {
257 oline = memdupz(buf, blen);
258 break;
259 } else {
260 line = memdupz(buf, blen);
261 }
262 }
263
264 }
265 if (line == NULL)
266 break;
267
268 if (strlen(line) == 0)
269 continue;
270
271 sepp = strchr(line, ':');
272 if (sepp == NULL)
273 die("No ':' separator. (line: %d)\n", lnum);
274
275 sepp[0] = '\0';
276 sepp++;
277
278 if (!strcasecmp(line, "BEGIN")) {
279 if (!strcasecmp(sepp, "VCALENDAR")) {
280 state = STATE_VCALBEGIN;
281 continue;
282 } else {
283 state = STATE_VITEMBEGIN;
284
285 item = vitem_new();
286 item->type = memdupz(sepp,
287 strlen(sepp));
288 continue;
289 }
290 } else if (!strcasecmp(line, "END")) {
291 if (!strcasecmp(sepp, "VCALENDAR")) {
292 state = STATE_VCALEND;
293 } else {
294 if (item == NULL)
295 die("item == NULL (line: %d)\n", lnum);
296 vitems_additem(items, item);
297 item = NULL;
298 }
299 continue;
300 }
301
302 paramsp = strchr(line, ';');
303 if (paramsp != NULL) {
304 paramsp[0] = '\0';
305 paramsp++;
306 }
307
308 itemprop = vitemprop_new();
309 itemprop->name = memdupz(line, strlen(line));
310 if (paramsp != NULL) {
311 itemprop->params = memdupz(paramsp,
312 strlen(paramsp));
313 }
314 itemprop->value = memdupz(sepp,
315 strlen(sepp));
316
317 if (state == STATE_VCALBEGIN) {
318 vitems_addhdr(items, itemprop);
319 } else if (state == STATE_VITEMBEGIN) {
320 vitem_addprop(item, itemprop);
321 }
322 }
323
324 free(filebuf);
325
326 if (items->nitems < 1) {
327 vitems_free(items);
328 return NULL;
329 }
330
331 return items;
332 }
333