static struct icaltimetype
get_last_modified (icalcomponent *component)
{
	icalcomponent *inner = icalcomponent_get_inner (component);
	icalproperty  *prop;

	prop = icalcomponent_get_first_property (inner, ICAL_LASTMODIFIED_PROPERTY);

	if (prop == 0) {
		return icaltime_null_time ();
	}

	return icalproperty_get_lastmodified (prop);
}
예제 #2
0
/* Add all ZONEs and LINKs in the given directory to the hash table */
void do_zonedir(const char *dir, struct hash_table *tzentries,
		struct zoneinfo *info)
{
    DIR *dirp;
    struct dirent *dirent;

    signals_poll();

    if (verbose) printf("Rebuilding %s\n", dir);

    dirp = opendir(dir);
    if (!dirp) {
	fprintf(stderr, "can't open zoneinfo directory %s\n", dir);
    }

    while ((dirent = readdir(dirp))) {
	char path[2048], *tzid;
	int plen;
	struct stat sbuf;
	struct zoneinfo *zi;

	if (*dirent->d_name == '.') continue;	    

	plen = snprintf(path, sizeof(path), "%s/%s", dir, dirent->d_name);
	lstat(path, &sbuf);

	if (S_ISDIR(sbuf.st_mode)) {
	    /* Path is a directory (region) */
	  do_zonedir(path, tzentries, info);
	}
	else if (S_ISLNK(sbuf.st_mode)) {
	    /* Path is a symlink (alias) */
	    char link[1024], *alias;
	    ssize_t llen;

	    /* Isolate tzid in path */
	    if ((llen = readlink(path, link, sizeof(link))) < 0) continue;
	    link[llen-4] = '\0';  /* Trim ".ics" */
	    for (tzid = link; !strncmp(tzid, "../", 3); tzid += 3);

	    /* Isolate alias in path */
	    path[plen-4] = '\0';  /* Trim ".ics" */
	    alias = path + strlen(config_dir) + strlen("zoneinfo") + 2;

	    if (verbose) printf("\tLINK: %s -> %s\n", alias, tzid);

	    /* Create hash entry for alias */
	    if (!(zi = hash_lookup(alias, tzentries))) {
		zi = xzmalloc(sizeof(struct zoneinfo));
		hash_insert(alias, zi, tzentries);
	    }
	    zi->type = ZI_LINK;
	    appendstrlist(&zi->data, tzid);

	    /* Create/update hash entry for tzid */
	    if (!(zi = hash_lookup(tzid, tzentries))) {
		zi = xzmalloc(sizeof(struct zoneinfo));
		hash_insert(tzid, zi, tzentries);
	    }
	    zi->type = ZI_ZONE;
	    appendstrlist(&zi->data, alias);
	}
	else if (S_ISREG(sbuf.st_mode)) {
	    /* Path is a regular file (zone) */
	    int fd;
	    const char *base = NULL;
	    size_t len = 0;
	    icalcomponent *ical, *comp;
	    icalproperty *prop;

	    /* Parse the iCalendar file for important properties */
	    if ((fd = open(path, O_RDONLY)) == -1) continue;
	    map_refresh(fd, 1, &base, &len, MAP_UNKNOWN_LEN, path, NULL);
	    close(fd);

	    ical = icalparser_parse_string(base);
	    map_free(&base, &len);

	    if (!ical) continue;  /* skip non-iCalendar files */

	    comp = icalcomponent_get_first_component(ical,
						     ICAL_VTIMEZONE_COMPONENT);
	    prop = icalcomponent_get_first_property(comp, ICAL_TZID_PROPERTY);
	    tzid = (char *) icalproperty_get_value_as_string(prop);

	    if (verbose) printf("\tZONE: %s\n", tzid);

	    /* Create/update hash entry for tzid */
	    if (!(zi = hash_lookup(tzid, tzentries))) {
		zi = xzmalloc(sizeof(struct zoneinfo));
		hash_insert(tzid, zi, tzentries);
	    }
	    zi->type = ZI_ZONE;
	    prop = icalcomponent_get_first_property(comp,
						    ICAL_LASTMODIFIED_PROPERTY);
	    zi->dtstamp = icaltime_as_timet(icalproperty_get_lastmodified(prop));

	    icalcomponent_free(ical);

	    /* Check overall lastmod */
	    if (zi->dtstamp > info->dtstamp) info->dtstamp = zi->dtstamp;
	}
	else {
	    fprintf(stderr, "unknown path type %s\n", path);
	}
    }

    closedir(dirp);
}