libical

A simple ical library.
git clone git://r-36.net/libical
Log | Files | Refs | README | 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