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