1 #define _GNU_SOURCE
2 #include <ctype.h>
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <string.h>
6 #include <xenhypfs.h>
7
8 static struct xenhypfs_handle *hdl;
9
usage(void)10 static int usage(void)
11 {
12 fprintf(stderr, "usage: xenhypfs ls <path>\n");
13 fprintf(stderr, " xenhypfs cat [-b] <path>\n");
14 fprintf(stderr, " xenhypfs write <path> <val>\n");
15 fprintf(stderr, " xenhypfs tree\n");
16
17 return 1;
18 }
19
xenhypfs_print_escaped(char * string)20 static void xenhypfs_print_escaped(char *string)
21 {
22 char *c;
23
24 for (c = string; *c; c++) {
25 if (isgraph(*c) || isspace(*c))
26 printf("%c", *c);
27 else
28 printf("\\x%02x", *c);
29 }
30 printf("\n");
31 }
32
xenhypfs_cat(int argc,char * argv[])33 static int xenhypfs_cat(int argc, char *argv[])
34 {
35 int ret = 0;
36 char *result;
37 char *path;
38 bool bin = false;
39
40 switch (argc) {
41 case 1:
42 path = argv[0];
43 break;
44
45 case 2:
46 if (strcmp(argv[0], "-b"))
47 return usage();
48 bin = true;
49 path = argv[1];
50 break;
51
52 default:
53 return usage();
54 }
55
56 result = xenhypfs_read(hdl, path);
57 if (!result) {
58 perror("could not read");
59 ret = 3;
60 } else {
61 if (!bin)
62 printf("%s\n", result);
63 else
64 xenhypfs_print_escaped(result);
65 free(result);
66 }
67
68 return ret;
69 }
70
xenhypfs_wr(char * path,char * val)71 static int xenhypfs_wr(char *path, char *val)
72 {
73 int ret;
74
75 ret = xenhypfs_write(hdl, path, val);
76 if (ret) {
77 perror("could not write");
78 ret = 3;
79 }
80
81 return ret;
82 }
83
xenhypfs_type(struct xenhypfs_dirent * ent)84 static char *xenhypfs_type(struct xenhypfs_dirent *ent)
85 {
86 char *res;
87
88 switch (ent->type) {
89 case xenhypfs_type_dir:
90 res = "<dir> ";
91 break;
92 case xenhypfs_type_blob:
93 res = "<blob> ";
94 break;
95 case xenhypfs_type_string:
96 res = "<string>";
97 break;
98 case xenhypfs_type_uint:
99 res = "<uint> ";
100 break;
101 case xenhypfs_type_int:
102 res = "<int> ";
103 break;
104 case xenhypfs_type_bool:
105 res = "<bool> ";
106 break;
107 default:
108 res = "<\?\?\?> ";
109 break;
110 }
111
112 return res;
113 }
114
xenhypfs_ls(char * path)115 static int xenhypfs_ls(char *path)
116 {
117 struct xenhypfs_dirent *ent;
118 unsigned int n, i;
119 int ret = 0;
120
121 ent = xenhypfs_readdir(hdl, path, &n);
122 if (!ent) {
123 perror("could not read dir");
124 ret = 3;
125 } else {
126 for (i = 0; i < n; i++)
127 printf("%s r%c %s\n", xenhypfs_type(ent + i),
128 (ent[i].flags & XENHYPFS_FLAG_WRITABLE) ? 'w' : '-',
129 ent[i].name);
130
131 free(ent);
132 }
133
134 return ret;
135 }
136
xenhypfs_tree_sub(char * path,unsigned int depth)137 static int xenhypfs_tree_sub(char *path, unsigned int depth)
138 {
139 struct xenhypfs_dirent *ent;
140 unsigned int n, i;
141 int ret = 0;
142 char *p;
143
144 ent = xenhypfs_readdir(hdl, path, &n);
145 if (!ent)
146 return 2;
147
148 for (i = 0; i < n; i++) {
149 printf("%*s%s%s\n", depth * 2, "", ent[i].name,
150 ent[i].type == xenhypfs_type_dir ? "/" : "");
151 if (ent[i].type == xenhypfs_type_dir) {
152 if (asprintf(&p, "%s%s%s", path, (depth == 1) ? "" : "/",
153 ent[i].name) < 0) {
154 ret = 2;
155 break;
156 }
157 if (xenhypfs_tree_sub(p, depth + 1))
158 ret = 2;
159 free(p);
160 }
161 }
162
163 free(ent);
164
165 return ret;
166 }
167
xenhypfs_tree(void)168 static int xenhypfs_tree(void)
169 {
170 printf("/\n");
171
172 return xenhypfs_tree_sub("/", 1);
173 }
174
main(int argc,char * argv[])175 int main(int argc, char *argv[])
176 {
177 int ret;
178
179 hdl = xenhypfs_open(NULL, 0);
180
181 if (!hdl) {
182 fprintf(stderr, "Could not open libxenhypfs\n");
183 ret = 2;
184 } else if (argc >= 3 && !strcmp(argv[1], "cat"))
185 ret = xenhypfs_cat(argc - 2, argv + 2);
186 else if (argc == 3 && !strcmp(argv[1], "ls"))
187 ret = xenhypfs_ls(argv[2]);
188 else if (argc == 4 && !strcmp(argv[1], "write"))
189 ret = xenhypfs_wr(argv[2], argv[3]);
190 else if (argc == 2 && !strcmp(argv[1], "tree"))
191 ret = xenhypfs_tree();
192 else
193 ret = usage();
194
195 xenhypfs_close(hdl);
196
197 return ret;
198 }
199