#define _GNU_SOURCE #include #include #include #include #include static struct xenhypfs_handle *hdl; static int usage(void) { fprintf(stderr, "usage: xenhypfs ls \n"); fprintf(stderr, " xenhypfs cat [-b] \n"); fprintf(stderr, " xenhypfs write \n"); fprintf(stderr, " xenhypfs tree\n"); return 1; } static void xenhypfs_print_escaped(char *string) { char *c; for (c = string; *c; c++) { if (isgraph(*c) || isspace(*c)) printf("%c", *c); else printf("\\x%02x", *c); } printf("\n"); } static int xenhypfs_cat(int argc, char *argv[]) { int ret = 0; char *result; char *path; bool bin = false; switch (argc) { case 1: path = argv[0]; break; case 2: if (strcmp(argv[0], "-b")) return usage(); bin = true; path = argv[1]; break; default: return usage(); } result = xenhypfs_read(hdl, path); if (!result) { perror("could not read"); ret = 3; } else { if (!bin) printf("%s\n", result); else xenhypfs_print_escaped(result); free(result); } return ret; } static int xenhypfs_wr(char *path, char *val) { int ret; ret = xenhypfs_write(hdl, path, val); if (ret) { perror("could not write"); ret = 3; } return ret; } static const char *xenhypfs_type(struct xenhypfs_dirent *ent) { const char *res; switch (ent->type) { case xenhypfs_type_dir: res = " "; break; case xenhypfs_type_blob: res = " "; break; case xenhypfs_type_string: res = ""; break; case xenhypfs_type_uint: res = " "; break; case xenhypfs_type_int: res = " "; break; case xenhypfs_type_bool: res = " "; break; default: res = "<\?\?\?> "; break; } return res; } static int xenhypfs_ls(char *path) { struct xenhypfs_dirent *ent; unsigned int n, i; int ret = 0; ent = xenhypfs_readdir(hdl, path, &n); if (!ent) { perror("could not read dir"); ret = 3; } else { for (i = 0; i < n; i++) printf("%s r%c %s\n", xenhypfs_type(ent + i), (ent[i].flags & XENHYPFS_FLAG_WRITABLE) ? 'w' : '-', ent[i].name); free(ent); } return ret; } static int xenhypfs_tree_sub(const char *path, unsigned int depth) { struct xenhypfs_dirent *ent; unsigned int n, i; int ret = 0; char *p; ent = xenhypfs_readdir(hdl, path, &n); if (!ent) return 2; for (i = 0; i < n; i++) { printf("%*s%s%s\n", depth * 2, "", ent[i].name, ent[i].type == xenhypfs_type_dir ? "/" : ""); if (ent[i].type == xenhypfs_type_dir) { if (asprintf(&p, "%s%s%s", path, (depth == 1) ? "" : "/", ent[i].name) < 0) { ret = 2; break; } if (xenhypfs_tree_sub(p, depth + 1)) ret = 2; free(p); } } free(ent); return ret; } static int xenhypfs_tree(void) { printf("/\n"); return xenhypfs_tree_sub("/", 1); } int main(int argc, char *argv[]) { int ret; hdl = xenhypfs_open(NULL, 0); if (!hdl) { fprintf(stderr, "Could not open libxenhypfs\n"); ret = 2; } else if (argc >= 3 && !strcmp(argv[1], "cat")) ret = xenhypfs_cat(argc - 2, argv + 2); else if (argc == 3 && !strcmp(argv[1], "ls")) ret = xenhypfs_ls(argv[2]); else if (argc == 4 && !strcmp(argv[1], "write")) ret = xenhypfs_wr(argv[2], argv[3]); else if (argc == 2 && !strcmp(argv[1], "tree")) ret = xenhypfs_tree(); else ret = usage(); xenhypfs_close(hdl); return ret; }