static unsigned int child(struct service_backend *backend, struct service_state *state, struct cpio_header *header, unsigned int id, char *path, unsigned int length) { struct cpio_header *eheader; unsigned int current = 0; do { char *name; eheader = mapheader(backend, state, current); if (!eheader) break; if (eheader->namesize != header->namesize + length + 1) continue; name = mapname(backend, state, eheader, current); if (!name) break; if (memory_match(name + header->namesize, path, length)) return current; } while ((current = cpio_next(eheader, current))); return id; }
static unsigned int root(struct service_backend *backend, struct service_state *state) { struct cpio_header *eheader; unsigned int id = 0; unsigned int current = 0; do { eheader = mapheader(backend, state, current); if (!eheader) break; if ((eheader->mode & 0xF000) != 0x4000) continue; id = current; } while ((current = cpio_next(eheader, current))); return id; }
static unsigned int parent(struct service_backend *backend, struct service_state *state, struct cpio_header *header, unsigned int id) { unsigned int length = memory_findlastbyte(mapname(backend, state, header, id), header->namesize - 1, '/'); struct cpio_header *eheader; unsigned int current = id; do { eheader = mapheader(backend, state, current); if (!eheader) break; if ((eheader->mode & 0xF000) != 0x4000) continue; if (eheader->namesize == length + 1) return current; } while ((current = cpio_next(eheader, current))); return id; }
static unsigned int parent(struct service_backend *backend, struct cpio_header *header, unsigned int id) { struct cpio_header eheader; unsigned char name[1024]; unsigned int length; if (!readname(backend, header, id, name, 1024)) return 0; for (length = header->namesize - 1; length && name[length] != '/'; length--); do { if (!readheader(backend, &eheader, id)) break; if ((eheader.mode & 0xF000) != 0x4000) continue; if (eheader.namesize == length + 1) return id; } while ((id = cpio_next(&eheader, id))); return 0; }
static unsigned int stepdirectory(struct service_backend *backend, struct service_state *state, unsigned int id, unsigned int current) { struct cpio_header *eheader = mapheader(backend, state, current); if (!eheader) return 0; while ((current = cpio_next(eheader, current))) { if (current == id) break; eheader = mapheader(backend, state, current); if (!eheader) break; if (parent(backend, state, eheader, current) == id) return current; } return 0; }
static unsigned int stepdirectory(struct service_backend *backend, unsigned int id, unsigned int current) { struct cpio_header eheader; if (!readheader(backend, &eheader, current)) return 0; while ((current = cpio_next(&eheader, current))) { if (current == id) break; if (!readheader(backend, &eheader, current)) break; if (parent(backend, &eheader, current) == id) return current; } return 0; }
static unsigned int protocol_child(struct service_backend *backend, struct service_state *state, char *path, unsigned int length) { struct cpio_header header; struct cpio_header eheader; unsigned char name[1024]; unsigned int id = 0; if (!length) return 1; if (!readheader(backend, &header, state->id)) return 0; if (!readname(backend, &header, state->id, name, 1024)) return 0; if (path[length - 1] == '/') length--; do { unsigned char cname[1024]; if (id == state->id) break; if (!readheader(backend, &eheader, id)) break; if (eheader.namesize - header.namesize != length + 1) continue; if (!readname(backend, &eheader, id, cname, 1024)) break; if (memory_match(cname + header.namesize, path, length)) { state->id = id; return 1; } } while ((id = cpio_next(&eheader, id))); return 0; }
int bv_find(struct bv *bv, char *name, struct bv_file *file) { struct cpio_file cpio_file; int ret = cpio_first((u8 *) bv->start, (u8 *) bv->end, &cpio_file); while (!ret) { if (!strncmp(cpio_file.name, name, cpio_file.name_size)) { file->start = cpio_file.data; file->end = (u8 *) cpio_file.data + cpio_file.size; return 0; } ret = cpio_next((u8 *) bv->end, &cpio_file); } return ret; }
static unsigned int protocol_parent(struct service_backend *backend, struct service_state *state) { struct cpio_header header; struct cpio_header eheader; unsigned char name[1024]; unsigned int id = state->id; if (!readheader(backend, &header, state->id)) return 0; if (!readname(backend, &header, state->id, name, 1024)) return 0; while (name[header.namesize] != '/') header.namesize--; do { if (!readheader(backend, &eheader, id)) break; if ((eheader.mode & 0xF000) != 0x4000) continue; if (eheader.namesize == header.namesize + 1) { state->id = id; return 1; } } while ((id = cpio_next(&eheader, id))); return 0; }
static unsigned int protocol_root(struct service_backend *backend) { struct cpio_header header; unsigned int id = 0; unsigned int last = id; do { if (!readheader(backend, &header, id)) break; if ((header.mode & 0xF000) != 0x4000) continue; last = id; } while ((id = cpio_next(&header, id))); return last; }