int process(int fd, const char *name) { char xmlconfig[XMLCONFIG_MAX]; int x, y, z; struct stat b; if (stat(name, &b)) return 1; if (path_to_xyz(name, xmlconfig, &x, &y, &z)) return 1; printf("Requesting xml(%s) x(%d) y(%d) z(%d) as last modified at %s\n", xmlconfig, x, y, z, ctime(&b.st_mtime)); return process_loop(fd, xmlconfig, x, y, z); }
int expand_meta(const char *name, struct storage_backend * store) { int fd; int x, y, z; size_t pos = 0; void *buf; char path[PATH_MAX]; struct stat_info tile_stat; if (path_to_xyz(name, &x, &y, &z)) return -1; int limit = (1 << z); limit = MIN(limit, METATILE); float fromlat = tiley2lat(y+8, z); float tolat = tiley2lat(y, z); float fromlon = tilex2long(x, z); float tolon = tilex2long(x+8, z); if (tolon < bbox[0] || fromlon > bbox[2] || tolat < bbox[1] || fromlat > bbox[3]) { if (verbose) printf("z=%d x=%d y=%d is out of bbox\n", z, x, y); return -8; } fd = open(name, O_RDONLY); if (fd < 0) { fprintf(stderr, "Could not open metatile %s. Reason: %s\n", name, strerror(errno)); return -1; } struct stat st; fstat(fd, &st); buf = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0); if (buf == MAP_FAILED) { fprintf(stderr, "Cannot mmap file %s for %ld bytes: %s\n", name, st.st_size, strerror(errno)); close(fd); return -3; } struct meta_layout *m = (struct meta_layout *)buf; if (memcmp(m->magic, META_MAGIC, strlen(META_MAGIC))) { fprintf(stderr, "Meta file %s header magic mismatch\n", name); close(fd); return -4; } if (m->count != (METATILE * METATILE)) { fprintf(stderr, "Meta file %s header bad count %d != %d\n", name, m->count, METATILE * METATILE); close(fd); return -5; } if (store == NULL) { sprintf(path, "%s/%d", target, z); if (mkdir(path, 0755) && (errno != EEXIST)) { fprintf(stderr, "cannot create directory %s: %s\n", path, strerror(errno)); close(fd); return -1; } } if (store != NULL) { if (!force) tile_stat = store->tile_stat(store, target, "options", x, y, z); if (force || (tile_stat.size < 0) || (tile_stat.expired)) { if (store->metatile_write(store, target, "options", x, y, z, buf, st.st_size) == -1) { close(fd); fprintf(stderr, "Failed to write data to Memcached %s/%d/%d/%d.png\n", target, x, y, z); return -1; } if (verbose) printf("Produced metatile: %s/%d/%d/%d.meta\n", target, x, y, z); } } else { for (int meta = 0; meta < METATILE*METATILE; meta++) { int tx = x + (meta / METATILE); int ty = y + (meta % METATILE); int output; if (ty==y) { sprintf(path, "%s/%d/%d", target, z, tx); if (mkdir(path, 0755) && (errno != EEXIST)) { fprintf(stderr, "cannot create directory %s: %s\n", path, strerror(errno)); close(fd); return -1; } } sprintf(path, "%s/%d/%d/%d.png", target, z, tx, ty); output = open(path, O_WRONLY | O_TRUNC | O_CREAT, 0666); if (output == -1) { fprintf(stderr, "cannot open %s for writing: %s\n", path, strerror(errno)); close(fd); return -1; } pos = 0; while (pos < m->index[meta].size) { size_t len = m->index[meta].size - pos; int written = write(output, buf + pos + m->index[meta].offset, len); if (written < 0) { fprintf(stderr, "Failed to write data to file %s. Reason: %s\n", path, strerror(errno)); close(fd); return -7; } else if (written > 0) { pos += written; } else { break; } } close(output); if (verbose) printf("Produced tile: %s\n", path); } } munmap(buf, st.st_size); close(fd); return pos; }