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