Line data Source code
1 : #include "../fd_util.h"
2 : #include "../../util/pod/fd_pod.h"
3 :
4 : #if FD_HAS_HOSTED
5 :
6 : #include <stdio.h>
7 : #include <stdlib.h>
8 : #include <ctype.h>
9 : #include <sys/types.h>
10 : #include <sys/stat.h>
11 : #include <fcntl.h>
12 : #include <unistd.h>
13 :
14 : FD_IMPORT_CSTR( fd_pod_ctl_help, "src/util/pod/fd_pod_ctl_help" );
15 :
16 : static int
17 132 : supported_val_type( int val_type ) {
18 132 : return (val_type==FD_POD_VAL_TYPE_CSTR ) | (val_type==FD_POD_VAL_TYPE_CHAR )
19 132 : | (val_type==FD_POD_VAL_TYPE_SCHAR ) | (val_type==FD_POD_VAL_TYPE_SHORT )
20 132 : | (val_type==FD_POD_VAL_TYPE_INT ) | (val_type==FD_POD_VAL_TYPE_LONG )
21 132 : | (val_type==FD_POD_VAL_TYPE_UCHAR ) | (val_type==FD_POD_VAL_TYPE_USHORT)
22 132 : | (val_type==FD_POD_VAL_TYPE_UINT ) | (val_type==FD_POD_VAL_TYPE_ULONG )
23 132 : | (val_type==FD_POD_VAL_TYPE_FLOAT )
24 132 : # if FD_HAS_DOUBLE
25 132 : | (val_type==FD_POD_VAL_TYPE_DOUBLE)
26 132 : # endif
27 132 : ;
28 132 : }
29 :
30 : static ulong
31 : insert_val( uchar * pod,
32 : char const * path,
33 : int val_type,
34 108 : char const * val ) {
35 108 : ulong off;
36 108 : switch( val_type ) {
37 15 : case FD_POD_VAL_TYPE_CSTR: off = fd_pod_insert_cstr ( pod, path, fd_cstr_to_cstr ( val ) ); break;
38 9 : case FD_POD_VAL_TYPE_CHAR: off = fd_pod_insert_char ( pod, path, fd_cstr_to_char ( val ) ); break;
39 9 : case FD_POD_VAL_TYPE_SCHAR: off = fd_pod_insert_schar ( pod, path, fd_cstr_to_schar ( val ) ); break;
40 9 : case FD_POD_VAL_TYPE_SHORT: off = fd_pod_insert_short ( pod, path, fd_cstr_to_short ( val ) ); break;
41 9 : case FD_POD_VAL_TYPE_INT: off = fd_pod_insert_int ( pod, path, fd_cstr_to_int ( val ) ); break;
42 9 : case FD_POD_VAL_TYPE_LONG: off = fd_pod_insert_long ( pod, path, fd_cstr_to_long ( val ) ); break;
43 9 : case FD_POD_VAL_TYPE_UCHAR: off = fd_pod_insert_uchar ( pod, path, fd_cstr_to_uchar ( val ) ); break;
44 9 : case FD_POD_VAL_TYPE_USHORT: off = fd_pod_insert_ushort( pod, path, fd_cstr_to_ushort( val ) ); break;
45 9 : case FD_POD_VAL_TYPE_UINT: off = fd_pod_insert_uint ( pod, path, fd_cstr_to_uint ( val ) ); break;
46 9 : case FD_POD_VAL_TYPE_ULONG: off = fd_pod_insert_ulong ( pod, path, fd_cstr_to_ulong ( val ) ); break;
47 12 : case FD_POD_VAL_TYPE_FLOAT: off = fd_pod_insert_float ( pod, path, fd_cstr_to_float ( val ) ); break;
48 0 : # if FD_HAS_DOUBLE
49 0 : case FD_POD_VAL_TYPE_DOUBLE: off = fd_pod_insert_double( pod, path, fd_cstr_to_double( val ) ); break;
50 0 : # endif
51 0 : default: FD_LOG_ERR(( "never get here" ));
52 108 : }
53 108 : return off;
54 108 : }
55 :
56 : static inline int
57 135 : issingleprint( int c ) {
58 135 : return fd_isalnum( c ) | fd_ispunct( c ) | (c==' ');
59 135 : }
60 :
61 : static void
62 81 : printf_path( fd_pod_info_t const * info ) {
63 81 : if( FD_UNLIKELY( !info ) ) return;
64 :
65 81 : fd_pod_info_t const * node = info;
66 81 : ulong sz = 0UL;
67 120 : do {
68 120 : ulong key_sz = node->key_sz;
69 120 : if( FD_UNLIKELY( !key_sz ) ) return;
70 120 : sz += key_sz;
71 120 : node = node->parent;
72 120 : } while( node );
73 :
74 81 : char * buf = malloc( sz );
75 81 : if( !buf ) return;
76 :
77 81 : char * p = buf + sz;
78 81 : int subpod = 0;
79 81 : node = info;
80 120 : do {
81 120 : ulong key_sz = node->key_sz;
82 120 : p -= key_sz;
83 120 : strcpy( p, node->key );
84 120 : if( subpod ) p[ key_sz-1UL ] = '.';
85 120 : subpod = 1;
86 120 : node = node->parent;
87 120 : } while( node );
88 :
89 81 : printf( "%s", buf );
90 81 : free( buf );
91 81 : }
92 :
93 : static void
94 96 : printf_val( fd_pod_info_t const * info ) {
95 96 : switch( info->val_type ) {
96 :
97 39 : case FD_POD_VAL_TYPE_SUBPOD: {
98 39 : uchar * subpod = (uchar *)info->val;
99 39 : printf( "max %lu bytes, used %lu bytes, kcnt %lu keys", fd_pod_max( subpod ), fd_pod_used( subpod ), fd_pod_cnt( subpod ) );
100 39 : break;
101 0 : }
102 :
103 0 : default:
104 6 : case FD_POD_VAL_TYPE_BUF: {
105 6 : uchar const * buf = (uchar const *)info->val;
106 6 : ulong sz = info->val_sz;
107 6 : printf( "sz %lu", sz );
108 138 : for( ulong off=0UL; off<sz; off++ ) {
109 132 : ulong col = off & 15UL;
110 : /* FIXME: USER SPECIFIED INDENT AND CONFIGURE OFF WIDTH BASED ON SZ */
111 132 : if( FD_UNLIKELY( col==0UL ) ) printf( "\n\t\t%04lx: ", off );
112 132 : if( FD_UNLIKELY( col==8UL ) ) putc( ' ', stdout );
113 132 : printf( "%02x ", (uint)buf[ off ] );
114 132 : if( FD_UNLIKELY( (col==15UL) | ((off+1UL)==sz) ) ) { /* End of row */
115 : /* Output whitespace to align 2nd column */
116 72 : for( ulong rem=48UL-3UL*col; rem; rem-- ) putc( ' ', stdout );
117 : /* Output single character friendly bytes from row in 2nd column */
118 9 : char const * p = (char const *)(buf + (off & ~15UL));
119 141 : for( ulong rem=col+1UL; rem; rem-- ) { int c = (int)*(p++); putc( issingleprint( c ) ? c : '.', stdout ); }
120 9 : }
121 132 : }
122 6 : break;
123 0 : }
124 :
125 15 : case FD_POD_VAL_TYPE_CSTR: {
126 15 : if( !info->val_sz ) printf( "(null)" );
127 15 : else printf( "\"%s\"", (char const *)info->val );
128 15 : break;
129 0 : }
130 :
131 3 : case FD_POD_VAL_TYPE_CHAR: {
132 3 : int c = (int)*(char *)info->val;
133 3 : if( issingleprint( c ) ) printf( "'%c'", c );
134 0 : else printf( "0x%02x", (uint)(uchar)c );
135 3 : break;
136 0 : }
137 :
138 3 : case FD_POD_VAL_TYPE_UCHAR: { uint u = (uint)*(uchar *)info->val; printf( "%u", u ); break; }
139 3 : case FD_POD_VAL_TYPE_USHORT:
140 6 : case FD_POD_VAL_TYPE_UINT:
141 9 : case FD_POD_VAL_TYPE_ULONG: { ulong u; fd_ulong_svw_dec( info->val, &u ); printf( "%lu", u ); break; }
142 :
143 6 : case FD_POD_VAL_TYPE_SCHAR: { int i = (int) *(schar *)info->val; printf( "%i", i ); break; }
144 3 : case FD_POD_VAL_TYPE_SHORT:
145 6 : case FD_POD_VAL_TYPE_INT:
146 9 : case FD_POD_VAL_TYPE_LONG: { ulong u; fd_ulong_svw_dec( info->val, &u ); printf( "%li", fd_long_zz_dec( u ) ); break; }
147 :
148 0 : # if FD_HAS_INT128
149 0 : case FD_POD_VAL_TYPE_INT128: {
150 0 : union { ulong w[2]; uint128 u; } tmp;
151 0 : fd_ulong_svw_dec( fd_ulong_svw_dec( (uchar const *)info->val, tmp.w ), tmp.w+1 );
152 0 : tmp.u = (uint128)fd_int128_zz_dec( tmp.u ); /* FIXME: INT128 decimal pretty printer */
153 0 : printf( "0x%016lx%016lx", (ulong)(tmp.u>>64), (ulong)tmp.u );
154 0 : break;
155 6 : }
156 :
157 0 : case FD_POD_VAL_TYPE_UINT128: {
158 0 : union { ulong w[2]; uint128 u; } tmp;
159 0 : fd_ulong_svw_dec( fd_ulong_svw_dec( (uchar const *)info->val, tmp.w ), tmp.w+1 );
160 : /* FIXME: UINT128 decimal pretty printer */
161 0 : printf( "0x%016lx%016lx", (ulong)(tmp.u>>64), (ulong)tmp.u );
162 0 : break;
163 6 : }
164 0 : # endif
165 :
166 6 : case FD_POD_VAL_TYPE_FLOAT: { float f = *(float *)info->val; printf( "%.21e", (double)f ); break; }
167 0 : # if FD_HAS_DOUBLE
168 0 : case FD_POD_VAL_TYPE_DOUBLE: { double f = *(double *)info->val; printf( "%.21e", f ); break; }
169 96 : # endif
170 :
171 96 : }
172 96 : }
173 :
174 : int
175 : main( int argc,
176 204 : char ** argv ) {
177 204 : fd_boot( &argc, &argv );
178 :
179 1017 : # define SHIFT(n) argv+=(n),argc-=(n)
180 :
181 204 : if( FD_UNLIKELY( argc<1 ) ) FD_LOG_ERR(( "no arguments" ));
182 204 : char const * bin = argv[0];
183 204 : SHIFT(1);
184 :
185 204 : ulong tag = 1UL;
186 :
187 204 : int cnt = 0;
188 534 : while( argc ) {
189 486 : char const * cmd = argv[0];
190 486 : SHIFT(1);
191 :
192 486 : if( !strcmp( cmd, "help" ) ) {
193 :
194 3 : fputs( fd_pod_ctl_help, stdout );
195 :
196 3 : FD_LOG_NOTICE(( "%i: %s: success", cnt, cmd ));
197 :
198 483 : } else if( !strcmp( cmd, "tag" ) ) {
199 :
200 6 : if( FD_UNLIKELY( argc<1 ) ) FD_LOG_ERR(( "%i: %s: too few arguments\n\tDo %s help for help", cnt, cmd, bin ));
201 :
202 3 : tag = fd_cstr_to_ulong( argv[0] );
203 :
204 3 : FD_LOG_NOTICE(( "%i: %s %lu: success", cnt, cmd, tag ));
205 3 : SHIFT(1);
206 :
207 477 : } else if( !strcmp( cmd, "new" ) ) {
208 :
209 15 : if( FD_UNLIKELY( argc<2 ) ) FD_LOG_ERR(( "%i: %s: too few arguments\n\tDo %s help for help", cnt, cmd, bin ));
210 :
211 9 : char const * name = argv[0];
212 9 : ulong max = fd_cstr_to_ulong( argv[1] ); if( !max ) max = 4096UL;
213 :
214 9 : ulong align = fd_pod_align();
215 9 : ulong footprint = fd_pod_footprint( max );
216 :
217 9 : if( FD_UNLIKELY( !footprint ) )
218 3 : FD_LOG_ERR(( "%i: %s: bad max (%lu)\n\tDo %s help for help", cnt, cmd, max, bin ));
219 :
220 6 : fd_wksp_t * wksp = fd_wksp_attach( name );
221 6 : if( FD_UNLIKELY( !wksp ) )
222 3 : FD_LOG_ERR(( "%i: %s: fd_wksp_attach( \"%s\" ) failed\n\tDo %s help for help", cnt, cmd, name, bin ));
223 :
224 3 : ulong gaddr = fd_wksp_alloc( wksp, align, footprint, tag );
225 3 : if( FD_UNLIKELY( !gaddr ) ) {
226 0 : fd_wksp_detach( wksp );
227 0 : FD_LOG_ERR(( "%i: %s: fd_wksp_alloc( \"%s\", %lu, %lu, %lu ) failed\n\tDo %s help for help",
228 0 : cnt, cmd, name, align, footprint, tag, bin ));
229 0 : }
230 :
231 3 : void * shmem = fd_wksp_laddr( wksp, gaddr );
232 3 : if( FD_UNLIKELY( !shmem ) ) { /* should be impossible given fd_wksp_alloc success */
233 0 : fd_wksp_free( wksp, gaddr );
234 0 : fd_wksp_detach( wksp );
235 0 : FD_LOG_ERR(( "%i: %s: fd_wksp_laddr( \"%s\", %lu ) failed\n\tDo %s help for help", cnt, cmd, name, gaddr, bin ));
236 0 : }
237 :
238 3 : if( FD_UNLIKELY( !fd_pod_new( shmem, max ) ) ) {;
239 0 : fd_wksp_free( wksp, gaddr );
240 0 : fd_wksp_detach( wksp );
241 0 : FD_LOG_ERR(( "%i: %s: fd_pod_new( \"%s:%lu\", %lu ) failed\n\tDo %s help for help", cnt, cmd, name, gaddr, max, bin ));
242 0 : }
243 :
244 3 : char cstr[ FD_WKSP_CSTR_MAX ];
245 3 : if( FD_UNLIKELY( !fd_wksp_cstr( wksp, gaddr, cstr ) ) ) {
246 0 : fd_wksp_free( wksp, gaddr );
247 0 : fd_wksp_detach( wksp );
248 0 : FD_LOG_ERR(( "%i: %s: fd_pod_cstr( \"%s:%lu\" ) failed\n\tDo %s help for help", cnt, cmd, name, gaddr, bin ));
249 0 : }
250 :
251 3 : printf( "%s\n", cstr );
252 :
253 3 : fd_wksp_detach( wksp );
254 :
255 3 : FD_LOG_NOTICE(( "%i: %s %s %lu: success", cnt, cmd, name, max ));
256 3 : SHIFT(2);
257 :
258 462 : } else if( !strcmp( cmd, "delete" ) ) {
259 :
260 12 : if( FD_UNLIKELY( argc<1 ) ) FD_LOG_ERR(( "%i: %s: too few arguments\n\tDo %s help for help", cnt, cmd, bin ));
261 :
262 9 : char const * cstr = argv[0];
263 :
264 9 : void * shmem = fd_wksp_map( cstr );
265 9 : if( FD_UNLIKELY( !shmem ) )
266 3 : FD_LOG_ERR(( "%i: %s: fd_wksp_map( \"%s\" ) failed\n\tDo %s help for help", cnt, cmd, cstr, bin ));
267 :
268 6 : if( FD_UNLIKELY( !fd_pod_delete( shmem ) ) ) {
269 0 : fd_wksp_unmap( shmem );
270 0 : FD_LOG_ERR(( "%i: %s: fd_pod_delete( \"%s\" ) failed\n\tDo %s help for help", cnt, cmd, cstr, bin ));
271 0 : }
272 :
273 6 : fd_wksp_free_laddr( shmem );
274 6 : fd_wksp_unmap( shmem );
275 :
276 6 : FD_LOG_NOTICE(( "%i: %s %s: success", cnt, cmd, cstr ));
277 6 : SHIFT(1);
278 :
279 450 : } else if( !strcmp( cmd, "reset" ) ) {
280 :
281 9 : if( FD_UNLIKELY( argc<1 ) ) FD_LOG_ERR(( "%i: %s: too few arguments\n\tDo %s help for help", cnt, cmd, bin ));
282 :
283 6 : char const * cstr = argv[0];
284 :
285 6 : void * shmem = fd_wksp_map( cstr );
286 6 : if( FD_UNLIKELY( !shmem ) )
287 3 : FD_LOG_ERR(( "%i: %s: fd_wksp_map( \"%s\" ) failed\n\tDo %s help for help", cnt, cmd, cstr, bin ));
288 :
289 3 : uchar * pod = fd_pod_join( shmem );
290 3 : if( FD_UNLIKELY( !pod ) ) {
291 0 : fd_wksp_unmap( shmem );
292 0 : FD_LOG_ERR(( "%i: %s: fd_pod_join( \"%s\" ) failed\n\tDo %s help for help", cnt, cmd, cstr, bin ));
293 0 : }
294 :
295 3 : fd_pod_reset( pod );
296 :
297 3 : fd_wksp_unmap( fd_pod_leave( pod ) );
298 :
299 3 : FD_LOG_NOTICE(( "%i: %s %s: success", cnt, cmd, cstr ));
300 3 : SHIFT(1);
301 :
302 441 : } else if( !strcmp( cmd, "list" ) ) {
303 :
304 9 : if( FD_UNLIKELY( argc<1 ) ) FD_LOG_ERR(( "%i: %s: too few arguments\n\tDo %s help for help", cnt, cmd, bin ));
305 :
306 6 : char const * cstr = argv[0];
307 :
308 6 : void * shmem = fd_wksp_map( cstr );
309 6 : if( FD_UNLIKELY( !shmem ) )
310 3 : FD_LOG_ERR(( "%i: %s: fd_wksp_map( \"%s\" ) failed\n\tDo %s help for help", cnt, cmd, cstr, bin ));
311 :
312 3 : uchar * pod = fd_pod_join( shmem );
313 3 : if( FD_UNLIKELY( !pod ) ) {
314 0 : fd_wksp_unmap( shmem );
315 0 : FD_LOG_ERR(( "%i: %s: fd_pod_join( \"%s\" ) failed\n\tDo %s help for help", cnt, cmd, cstr, bin ));
316 0 : }
317 :
318 3 : fd_pod_info_t * info;
319 3 : ulong info_cnt = fd_pod_cnt_recursive( pod );
320 3 : if( FD_UNLIKELY( !info_cnt ) ) info = NULL;
321 3 : else {
322 3 : info = (fd_pod_info_t *)aligned_alloc( alignof(fd_pod_info_t), info_cnt*sizeof(fd_pod_info_t) );
323 3 : if( FD_UNLIKELY( !info ) ) {
324 0 : fd_wksp_unmap( fd_pod_leave( pod ) );
325 0 : FD_LOG_ERR(( "%i: %s: aligned_alloc failed\n\tDo %s help for help", cnt, cmd, bin ));
326 0 : }
327 3 : if( FD_UNLIKELY( !fd_pod_list_recursive( pod, info ) ) ) {
328 0 : free( info );
329 0 : fd_wksp_unmap( fd_pod_leave( pod ) );
330 0 : FD_LOG_ERR(( "%i: %s: fd_pod_list_recursive( \"%s\" ) failed\n\tDo %s help for help", cnt, cmd, cstr, bin ));
331 0 : }
332 3 : }
333 :
334 3 : printf( "pod %s\n", cstr );
335 3 : printf( "\tmax %20lu bytes used %20lu bytes avail %20lu bytes\n",
336 3 : fd_pod_max( pod ), fd_pod_used ( pod ), fd_pod_avail( pod ) );
337 3 : printf( "\tkcnt %20lu keys icnt %20lu paths\n", fd_pod_cnt( pod ), info_cnt );
338 84 : for( ulong info_idx=0UL; info_idx<info_cnt; info_idx++ ) {
339 81 : fd_pod_info_t * node = &info[ info_idx ];
340 81 : char type[ FD_POD_VAL_TYPE_CSTR_MAX ]; fd_pod_val_type_to_cstr( node->val_type, type );
341 81 : printf( "\t%s %s ", cstr, type );
342 81 : printf_path( node );
343 81 : printf( " " );
344 81 : printf_val( node );
345 81 : printf( "\n" );
346 81 : }
347 :
348 3 : if( FD_LIKELY( info ) ) free( info );
349 3 : fd_wksp_unmap( fd_pod_leave( pod ) );
350 :
351 3 : FD_LOG_NOTICE(( "%i: %s %s: success", cnt, cmd, cstr ));
352 3 : SHIFT(1);
353 :
354 432 : } else if( !strcmp( cmd, "insert" ) ) {
355 :
356 54 : if( FD_UNLIKELY( argc<4 ) ) FD_LOG_ERR(( "%i: %s: too few arguments\n\tDo %s help for help", cnt, cmd, bin ));
357 :
358 42 : char const * cstr = argv[0];
359 42 : char const * type = argv[1];
360 42 : char const * path = argv[2];
361 42 : char const * val = argv[3];
362 :
363 42 : int val_type = fd_cstr_to_pod_val_type( type );
364 42 : if( FD_UNLIKELY( !supported_val_type( val_type ) ) )
365 3 : FD_LOG_ERR(( "%i: %s: unsupported type %s\n\tDo %s help for help", cnt, cmd, type, bin ));
366 :
367 39 : void * shmem = fd_wksp_map( cstr );
368 39 : if( FD_UNLIKELY( !shmem ) )
369 3 : FD_LOG_ERR(( "%i: %s: fd_wksp_map( \"%s\" ) failed\n\tDo %s help for help", cnt, cmd, cstr, bin ));
370 :
371 36 : uchar * pod = fd_pod_join( shmem );
372 36 : if( FD_UNLIKELY( !pod ) ) {
373 0 : fd_wksp_unmap( shmem );
374 0 : FD_LOG_ERR(( "%i: %s: fd_pod_join( \"%s\" ) failed\n\tDo %s help for help", cnt, cmd, cstr, bin ));
375 0 : }
376 :
377 36 : ulong off = insert_val( pod, path, val_type, val );
378 :
379 36 : fd_wksp_unmap( fd_pod_leave( pod ) );
380 :
381 36 : if( FD_UNLIKELY( !off ) )
382 0 : FD_LOG_ERR(( "%i: %s: fd_pod_insert_%s( \"%s\", \"%s\", \"%s\" ) failed\n\tDo %s help for help",
383 36 : cnt, cmd, type, cstr, path, val, bin ));
384 :
385 36 : FD_LOG_NOTICE(( "%i: %s %s %s %s %s: success", cnt, cmd, cstr, type, path, val ));
386 36 : SHIFT(4);
387 :
388 378 : } else if( !strcmp( cmd, "insert-file" ) ) {
389 :
390 27 : if( FD_UNLIKELY( argc<3 ) ) FD_LOG_ERR(( "%i: %s: too few arguments\n\tDo %s help for help", cnt, cmd, bin ));
391 :
392 18 : char const * cstr = argv[0];
393 18 : char const * path = argv[1];
394 18 : char const * file = argv[2];
395 :
396 18 : void * shmem = fd_wksp_map( cstr );
397 18 : if( FD_UNLIKELY( !shmem ) )
398 3 : FD_LOG_ERR(( "%i: %s: fd_wksp_map( \"%s\" ) failed\n\tDo %s help for help", cnt, cmd, cstr, bin ));
399 :
400 15 : uchar * pod = fd_pod_join( shmem );
401 15 : if( FD_UNLIKELY( !pod ) ) {
402 0 : fd_wksp_unmap( shmem );
403 0 : FD_LOG_ERR(( "%i: %s: fd_pod_join( \"%s\" ) failed\n\tDo %s help for help", cnt, cmd, cstr, bin ));
404 0 : }
405 :
406 15 : int fd = open( file, O_RDONLY );
407 15 : if( FD_UNLIKELY( fd == -1 ) )
408 3 : FD_LOG_ERR(( "%i: %s: open( \"%s\" ) failed\n\tDo %s help for help", cnt, cmd, file, bin ));
409 :
410 12 : struct stat st;
411 12 : if( FD_UNLIKELY( fstat( fd, &st ) == -1 ) )
412 0 : FD_LOG_ERR(( "%i: %s: fstat( \"%s\" ) failed\n\tDo %s help for help", cnt, cmd, file, bin ));
413 12 : ulong buf_sz = (ulong)st.st_size;
414 :
415 12 : ulong off = fd_pod_alloc( pod, path, FD_POD_VAL_TYPE_BUF, buf_sz );
416 12 : if( FD_UNLIKELY( !off ) )
417 6 : FD_LOG_ERR(( "%i: %s: fd_pod_alloc( \"%s\", \"%s\", FD_POD_VAL_TYPE_BUF, %lu ) failed\n\tDo %s help for help",
418 12 : cnt, cmd, cstr, path, buf_sz, bin ));
419 :
420 6 : if( FD_UNLIKELY( read( fd, pod + off, buf_sz )!=(long)buf_sz ) ) {
421 0 : if( FD_UNLIKELY( fd_pod_remove( pod, path ) ) )
422 0 : FD_LOG_WARNING(( "%i: %s: fd_pod_remove( \"%s\", \"%s\" ) failed; pod likely corrupt", cnt, cmd, cstr, path ));
423 0 : FD_LOG_ERR(( "%i: %s: read( \"%s\" ) failed\n\tDo %s help for help", cnt, cmd, file, bin ));
424 0 : }
425 :
426 6 : if( FD_UNLIKELY( close( fd ) ) )
427 0 : FD_LOG_WARNING(( "%i: %s: close( \"%s\" ) failed; attempting to continue", cnt, cmd, file ));
428 :
429 6 : fd_wksp_unmap( fd_pod_leave( pod ) );
430 :
431 6 : FD_LOG_NOTICE(( "%i: %s %s %s %s: success", cnt, cmd, cstr, path, file ));
432 6 : SHIFT(3);
433 :
434 351 : } else if( !strcmp( cmd, "remove" ) ) {
435 :
436 57 : if( FD_UNLIKELY( argc<2 ) ) FD_LOG_ERR(( "%i: %s: too few arguments\n\tDo %s help for help", cnt, cmd, bin ));
437 :
438 51 : char const * cstr = argv[0];
439 51 : char const * path = argv[1];
440 :
441 51 : void * shmem = fd_wksp_map( cstr );
442 51 : if( FD_UNLIKELY( !shmem ) )
443 0 : FD_LOG_ERR(( "%i: %s: fd_wksp_map( \"%s\" ) failed\n\tDo %s help for help", cnt, cmd, cstr, bin ));
444 :
445 51 : uchar * pod = fd_pod_join( shmem );
446 51 : if( FD_UNLIKELY( !pod ) ) {
447 0 : fd_wksp_unmap( shmem );
448 0 : FD_LOG_ERR(( "%i: %s: fd_pod_join( \"%s\" ) failed\n\tDo %s help for help", cnt, cmd, cstr, bin ));
449 0 : }
450 :
451 51 : int err = fd_pod_remove( pod, path );
452 :
453 51 : fd_wksp_unmap( fd_pod_leave( pod ) );
454 :
455 51 : if( FD_UNLIKELY( err ) )
456 12 : FD_LOG_ERR(( "%i: %s: fd_pod_remove( \"%s\", \"%s\" ) failed (%i-%s)\n\tDo %s help for help",
457 51 : cnt, cmd, cstr, path, err, fd_pod_strerror( err ), bin ));
458 :
459 39 : FD_LOG_NOTICE(( "%i: %s %s %s: success", cnt, cmd, cstr, path ));
460 39 : SHIFT(2);
461 :
462 294 : } else if( !strcmp( cmd, "update" ) ) {
463 :
464 54 : if( FD_UNLIKELY( argc<4 ) ) FD_LOG_ERR(( "%i: %s: too few arguments\n\tDo %s help for help", cnt, cmd, bin ));
465 :
466 42 : char const * cstr = argv[0];
467 42 : char const * type = argv[1];
468 42 : char const * path = argv[2];
469 42 : char const * val = argv[3];
470 :
471 42 : int val_type = fd_cstr_to_pod_val_type( type );
472 42 : if( FD_UNLIKELY( !supported_val_type( val_type ) ) )
473 3 : FD_LOG_ERR(( "%i: %s: unsupported type %s\n\tDo %s help for help", cnt, cmd, type, bin ));
474 :
475 39 : void * shmem = fd_wksp_map( cstr );
476 39 : if( FD_UNLIKELY( !shmem ) )
477 3 : FD_LOG_ERR(( "%i: %s: fd_wksp_map( \"%s\" ) failed\n\tDo %s help for help", cnt, cmd, cstr, bin ));
478 :
479 36 : uchar * pod = fd_pod_join( shmem );
480 36 : if( FD_UNLIKELY( !pod ) ) {
481 0 : fd_wksp_unmap( shmem );
482 0 : FD_LOG_ERR(( "%i: %s: fd_pod_join( \"%s\" ) failed\n\tDo %s help for help", cnt, cmd, cstr, bin ));
483 0 : }
484 :
485 36 : fd_pod_info_t info[1];
486 36 : int err = fd_pod_query( pod, path, info );
487 36 : if( FD_UNLIKELY( !!err ) ) {
488 0 : fd_wksp_unmap( fd_pod_leave( pod ) );
489 0 : FD_LOG_ERR(( "%i: %s: no path %s to type (%i-%s) in pod %s (%i-%s)\n\tDo %s help for help",
490 0 : cnt, cmd, path, val_type, type, cstr, err, fd_pod_strerror( err ), bin ));
491 0 : }
492 :
493 36 : if( FD_UNLIKELY( info->val_type!=val_type ) ) {
494 3 : fd_wksp_unmap( fd_pod_leave( pod ) );
495 3 : char buf[ FD_POD_VAL_TYPE_CSTR_MAX ];
496 3 : FD_LOG_ERR(( "%i: %s: type (%i-%s) at %s %s does not match requested type (%i-%s)\n\tDo %s help for help",
497 3 : cnt, cmd, info->val_type, fd_pod_val_type_to_cstr( info->val_type, buf ),
498 3 : cstr, path, val_type, type, bin ));
499 3 : }
500 :
501 33 : err = fd_pod_remove( pod, path );
502 33 : if( FD_UNLIKELY( err ) ) {
503 0 : fd_wksp_unmap( fd_pod_leave( pod ) );
504 0 : FD_LOG_ERR(( "%i: %s: fd_pod_remove( \"%s\", \"%s\" ) failed (%i-%s)\n\tDo %s help for help",
505 0 : cnt, cmd, cstr, path, err, fd_pod_strerror( err ), bin ));
506 0 : }
507 :
508 33 : ulong off = insert_val( pod, path, val_type, val );
509 :
510 33 : fd_wksp_unmap( fd_pod_leave( pod ) );
511 :
512 33 : if( FD_UNLIKELY( !off ) )
513 0 : FD_LOG_ERR(( "%i: %s: fd_pod_insert_%s( \"%s\", \"%s\", \"%s\" ) failed\n\tDo %s help for help",
514 33 : cnt, cmd, type, cstr, path, val, bin ));
515 :
516 33 : FD_LOG_NOTICE(( "%i: %s %s %s %s %s: success", cnt, cmd, cstr, type, path, val ));
517 33 : SHIFT(4);
518 :
519 240 : } else if( !strcmp( cmd, "set" ) ) {
520 :
521 60 : if( FD_UNLIKELY( argc<4 ) ) FD_LOG_ERR(( "%i: %s: too few arguments\n\tDo %s help for help", cnt, cmd, bin ));
522 :
523 48 : char const * cstr = argv[0];
524 48 : char const * type = argv[1];
525 48 : char const * path = argv[2];
526 48 : char const * val = argv[3];
527 :
528 48 : int val_type = fd_cstr_to_pod_val_type( type );
529 48 : if( FD_UNLIKELY( !supported_val_type( val_type ) ) )
530 3 : FD_LOG_ERR(( "%i: %s: unsupported type %s\n\tDo %s help for help", cnt, cmd, type, bin ));
531 :
532 45 : void * shmem = fd_wksp_map( cstr );
533 45 : if( FD_UNLIKELY( !shmem ) )
534 3 : FD_LOG_ERR(( "%i: %s: fd_wksp_map( \"%s\" ) failed\n\tDo %s help for help", cnt, cmd, cstr, bin ));
535 :
536 42 : uchar * pod = fd_pod_join( shmem );
537 42 : if( FD_UNLIKELY( !pod ) ) {
538 0 : fd_wksp_unmap( shmem );
539 0 : FD_LOG_ERR(( "%i: %s: fd_pod_join( \"%s\" ) failed\n\tDo %s help for help", cnt, cmd, cstr, bin ));
540 0 : }
541 :
542 42 : fd_pod_info_t info[1];
543 42 : int err = fd_pod_query( pod, path, info );
544 42 : if( FD_LIKELY( !err ) ) {
545 :
546 36 : if( FD_UNLIKELY( info->val_type!=val_type ) ) {
547 3 : fd_wksp_unmap( fd_pod_leave( pod ) );
548 3 : char buf[ FD_POD_VAL_TYPE_CSTR_MAX ];
549 3 : FD_LOG_ERR(( "%i: %s: type (%i-%s) at %s %s does not match requested type (%i-%s)\n\tDo %s help for help",
550 3 : cnt, cmd, info->val_type, fd_pod_val_type_to_cstr( info->val_type, buf ),
551 3 : cstr, path, val_type, type, bin ));
552 3 : }
553 :
554 33 : err = fd_pod_remove( pod, path );
555 33 : if( FD_UNLIKELY( err ) ) {
556 0 : fd_wksp_unmap( fd_pod_leave( pod ) );
557 0 : FD_LOG_ERR(( "%i: %s: fd_pod_remove( \"%s\", \"%s\" ) failed (%i-%s)\n\tDo %s help for help",
558 0 : cnt, cmd, cstr, path, err, fd_pod_strerror( err ), bin ));
559 0 : }
560 :
561 33 : } else if( FD_UNLIKELY( err!=FD_POD_ERR_RESOLVE ) ) {
562 :
563 0 : fd_wksp_unmap( fd_pod_leave( pod ) );
564 0 : FD_LOG_ERR(( "%i: %s: fd_pod_query( \"%s\", \"%s\" ) failed (%i-%s)\n\tDo %s help for help",
565 0 : cnt, cmd, cstr, path, err, fd_pod_strerror( err ), bin ));
566 :
567 0 : }
568 :
569 39 : ulong off = insert_val( pod, path, val_type, val );
570 :
571 39 : fd_wksp_unmap( fd_pod_leave( pod ) );
572 :
573 39 : if( FD_UNLIKELY( !off ) )
574 0 : FD_LOG_ERR(( "%i: %s: fd_pod_insert_%s( \"%s\", \"%s\", \"%s\" ) failed\n\tDo %s help for help",
575 39 : cnt, cmd, type, cstr, path, val, bin ));
576 :
577 39 : FD_LOG_NOTICE(( "%i: %s %s %s %s %s: success", cnt, cmd, cstr, type, path, val ));
578 39 : SHIFT(4);
579 :
580 180 : } else if( !strcmp( cmd, "compact" ) ) {
581 :
582 0 : if( FD_UNLIKELY( argc<2 ) ) FD_LOG_ERR(( "%i: %s: too few arguments\n\tDo %s help for help", cnt, cmd, bin ));
583 :
584 0 : char const * cstr = argv[0];
585 0 : int full = fd_cstr_to_int( argv[1] );
586 :
587 0 : void * shmem = fd_wksp_map( cstr );
588 0 : if( FD_UNLIKELY( !shmem ) )
589 0 : FD_LOG_ERR(( "%i: %s: fd_wksp_map( \"%s\" ) failed\n\tDo %s help for help", cnt, cmd, cstr, bin ));
590 :
591 0 : uchar * pod = fd_pod_join( shmem );
592 0 : if( FD_UNLIKELY( !pod ) ) {
593 0 : fd_wksp_unmap( shmem );
594 0 : FD_LOG_ERR(( "%i: %s: fd_pod_join( \"%s\" ) failed\n\tDo %s help for help", cnt, cmd, cstr, bin ));
595 0 : }
596 :
597 0 : ulong new_max = fd_pod_compact( pod, full );
598 :
599 0 : fd_wksp_unmap( fd_pod_leave( pod ) );
600 :
601 0 : if( FD_UNLIKELY( !new_max ) )
602 0 : FD_LOG_ERR(( "%i: %s: fd_pod_compact( \"%s\", %i ) failed\n\tDo %s help for help", cnt, cmd, cstr, full, bin ));
603 :
604 0 : FD_LOG_NOTICE(( "%i: %s %s %i: success", cnt, cmd, cstr, full ));
605 0 : SHIFT(2);
606 :
607 180 : } else if( !strcmp( cmd, "query-root" ) ) {
608 :
609 51 : if( FD_UNLIKELY( argc<2 ) ) FD_LOG_ERR(( "%i: %s: too few arguments\n\tDo %s help for help", cnt, cmd, bin ));
610 :
611 45 : char const * what = argv[0];
612 45 : char const * cstr = argv[1];
613 :
614 45 : void * shmem = NULL;
615 45 : uchar * pod = NULL;
616 45 : int err = FD_POD_ERR_INVAL;
617 :
618 45 : shmem = fd_wksp_map( cstr );
619 45 : if( FD_LIKELY( shmem ) ) {
620 24 : pod = fd_pod_join( shmem );
621 24 : if( FD_LIKELY( pod ) ) err = 0;
622 24 : }
623 :
624 45 : if( !strcmp( what, "test" ) ) printf( "%i\n", err );
625 39 : else if( !strcmp( what, "max" ) ) printf( "%lu\n", FD_LIKELY(!err) ? fd_pod_max ( pod ) : 0UL );
626 33 : else if( !strcmp( what, "used" ) ) printf( "%lu\n", FD_LIKELY(!err) ? fd_pod_used ( pod ) : 0UL );
627 27 : else if( !strcmp( what, "avail" ) ) printf( "%lu\n", FD_LIKELY(!err) ? fd_pod_avail ( pod ) : 0UL );
628 21 : else if( !strcmp( what, "cnt" ) ) printf( "%lu\n", FD_LIKELY(!err) ? fd_pod_cnt ( pod ) : 0UL );
629 15 : else if( !strcmp( what, "recursive" ) ) printf( "%lu\n", FD_LIKELY(!err) ? fd_pod_cnt_recursive( pod ) : 0UL );
630 9 : else if( !strcmp( what, "subpod-cnt" ) ) printf( "%lu\n", FD_LIKELY(!err) ? fd_pod_cnt_subpod ( pod ) : 0UL );
631 3 : else FD_LOG_ERR(( "unknown query %s", what ));
632 :
633 42 : if( FD_LIKELY( pod ) ) fd_pod_leave( pod );
634 42 : if( FD_LIKELY( shmem ) ) fd_wksp_unmap( shmem );
635 42 : FD_LOG_NOTICE(( "%i: %s %s %s: success", cnt, cmd, what, cstr ));
636 42 : SHIFT(2);
637 :
638 129 : } else if( !strcmp( cmd, "query" ) ) {
639 :
640 126 : if( FD_UNLIKELY( argc<3 ) ) FD_LOG_ERR(( "%i: %s: too few arguments\n\tDo %s help for help", cnt, cmd, bin ));
641 :
642 117 : char const * what = argv[0];
643 117 : char const * cstr = argv[1];
644 117 : char const * path = argv[2];
645 :
646 117 : void * shmem = NULL;
647 117 : uchar * pod = NULL;
648 117 : int err = FD_POD_ERR_INVAL;
649 117 : fd_pod_info_t info[1];
650 117 : char type[ FD_POD_VAL_TYPE_CSTR_MAX ];
651 117 : int is_subpod = 0;
652 :
653 117 : shmem = fd_wksp_map( cstr );
654 117 : if( FD_LIKELY( shmem ) ) {
655 114 : pod = fd_pod_join( shmem );
656 114 : if( FD_LIKELY( pod ) ) {
657 114 : err = fd_pod_query( pod, path, info );
658 114 : if( FD_LIKELY( !err ) ) {
659 75 : is_subpod = (info->val_type==FD_POD_VAL_TYPE_SUBPOD);
660 75 : if( FD_UNLIKELY( !fd_pod_val_type_to_cstr( info->val_type, type ) ) ) { /* only possible if corruption */
661 0 : err = FD_POD_ERR_INVAL;
662 0 : }
663 75 : }
664 114 : }
665 114 : }
666 :
667 117 : if( !strcmp( what, "test" ) ) printf( "%i\n", err );
668 102 : else if( !strcmp( what, "type" ) ) printf( "%s\n", FD_LIKELY( !err ) ? type : "void" );
669 90 : else if( !strcmp( what, "val" ) ) {
670 9 : if( FD_UNLIKELY( err ) ) printf( "void\n" );
671 6 : else {
672 6 : printf_val( info );
673 6 : printf( "\n" );
674 6 : }
675 9 : }
676 81 : else if( !strcmp( what, "max" ) ) printf( "%lu\n", FD_LIKELY( is_subpod ) ? fd_pod_max ( info->val ) : 0UL );
677 72 : else if( !strcmp( what, "used" ) ) printf( "%lu\n", FD_LIKELY( is_subpod ) ? fd_pod_used ( info->val ) : 0UL );
678 63 : else if( !strcmp( what, "avail" ) ) printf( "%lu\n", FD_LIKELY( is_subpod ) ? fd_pod_avail ( info->val ) : 0UL );
679 54 : else if( !strcmp( what, "cnt" ) ) printf( "%lu\n", FD_LIKELY( is_subpod ) ? fd_pod_cnt ( info->val ) : 0UL );
680 45 : else if( !strcmp( what, "recursive" ) ) printf( "%lu\n", FD_LIKELY( is_subpod ) ? fd_pod_cnt_recursive( info->val ) : 0UL );
681 36 : else if( !strcmp( what, "subpod-cnt" ) ) printf( "%lu\n", FD_LIKELY( is_subpod ) ? fd_pod_cnt_subpod ( info->val ) : 0UL );
682 27 : else if( !strcmp( what, "gaddr" ) ) {
683 12 : char buf[ FD_WKSP_CSTR_MAX ];
684 12 : printf( "%s\n", (FD_LIKELY( !err ) && FD_LIKELY( fd_wksp_cstr_laddr( info->val, buf ) )) ? buf : "null" );
685 12 : }
686 15 : else if( !strcmp( what, "full" ) ) {
687 12 : if( FD_UNLIKELY( err ) ) printf( "%s void %s void\n", cstr, path );
688 9 : else {
689 9 : printf( "%s %s %s ", cstr, type, path );
690 9 : printf_val( info );
691 9 : printf( "\n" );
692 9 : }
693 12 : }
694 3 : else FD_LOG_ERR(( "unknown query %s", what ));
695 :
696 114 : if( FD_LIKELY( pod ) ) fd_pod_leave( pod );
697 114 : if( FD_LIKELY( shmem ) ) fd_wksp_unmap( shmem );
698 114 : FD_LOG_NOTICE(( "%i: %s %s %s %s: success", cnt, cmd, what, cstr, path ));
699 114 : SHIFT(3);
700 :
701 114 : } else {
702 :
703 3 : FD_LOG_ERR(( "%i: %s: unknown command\n\t"
704 3 : "Do %s help for help", cnt, cmd, bin ));
705 :
706 3 : }
707 330 : cnt++;
708 330 : }
709 :
710 48 : if( FD_UNLIKELY( cnt<1 ) ) FD_LOG_NOTICE(( "processed %i commands\n\tDo %s help for help", cnt, bin ));
711 45 : else FD_LOG_NOTICE(( "processed %i commands", cnt ));
712 :
713 48 : # undef SHIFT
714 48 : fd_halt();
715 48 : return 0;
716 204 : }
717 :
718 : #else
719 :
720 : int
721 : main( int argc,
722 : char ** argv ) {
723 : fd_boot( &argc, &argv );
724 : if( FD_UNLIKELY( argc<1 ) ) FD_LOG_ERR(( "No arguments" ));
725 : if( FD_UNLIKELY( argc>1 ) ) FD_LOG_ERR(( "fd_pod_ctl not supported on this platform" ));
726 : FD_LOG_NOTICE(( "processed 0 commands" ));
727 : fd_halt();
728 : return 0;
729 : }
730 :
731 : #endif
|