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