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 0 : supported_val_type( int val_type ) {
18 0 : return (val_type==FD_POD_VAL_TYPE_CSTR ) | (val_type==FD_POD_VAL_TYPE_CHAR )
19 0 : | (val_type==FD_POD_VAL_TYPE_SCHAR ) | (val_type==FD_POD_VAL_TYPE_SHORT )
20 0 : | (val_type==FD_POD_VAL_TYPE_INT ) | (val_type==FD_POD_VAL_TYPE_LONG )
21 0 : | (val_type==FD_POD_VAL_TYPE_UCHAR ) | (val_type==FD_POD_VAL_TYPE_USHORT)
22 0 : | (val_type==FD_POD_VAL_TYPE_UINT ) | (val_type==FD_POD_VAL_TYPE_ULONG )
23 0 : | (val_type==FD_POD_VAL_TYPE_FLOAT )
24 0 : # if FD_HAS_DOUBLE
25 0 : | (val_type==FD_POD_VAL_TYPE_DOUBLE)
26 0 : # endif
27 0 : ;
28 0 : }
29 :
30 : static ulong
31 : insert_val( uchar * pod,
32 : char const * path,
33 : int val_type,
34 0 : char const * val ) {
35 0 : ulong off;
36 0 : switch( val_type ) {
37 0 : case FD_POD_VAL_TYPE_CSTR: off = fd_pod_insert_cstr ( pod, path, fd_cstr_to_cstr ( val ) ); break;
38 0 : case FD_POD_VAL_TYPE_CHAR: off = fd_pod_insert_char ( pod, path, fd_cstr_to_char ( val ) ); break;
39 0 : case FD_POD_VAL_TYPE_SCHAR: off = fd_pod_insert_schar ( pod, path, fd_cstr_to_schar ( val ) ); break;
40 0 : case FD_POD_VAL_TYPE_SHORT: off = fd_pod_insert_short ( pod, path, fd_cstr_to_short ( val ) ); break;
41 0 : case FD_POD_VAL_TYPE_INT: off = fd_pod_insert_int ( pod, path, fd_cstr_to_int ( val ) ); break;
42 0 : case FD_POD_VAL_TYPE_LONG: off = fd_pod_insert_long ( pod, path, fd_cstr_to_long ( val ) ); break;
43 0 : case FD_POD_VAL_TYPE_UCHAR: off = fd_pod_insert_uchar ( pod, path, fd_cstr_to_uchar ( val ) ); break;
44 0 : case FD_POD_VAL_TYPE_USHORT: off = fd_pod_insert_ushort( pod, path, fd_cstr_to_ushort( val ) ); break;
45 0 : case FD_POD_VAL_TYPE_UINT: off = fd_pod_insert_uint ( pod, path, fd_cstr_to_uint ( val ) ); break;
46 0 : case FD_POD_VAL_TYPE_ULONG: off = fd_pod_insert_ulong ( pod, path, fd_cstr_to_ulong ( val ) ); break;
47 0 : 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 0 : }
53 0 : return off;
54 0 : }
55 :
56 : static inline int
57 0 : issingleprint( int c ) {
58 0 : return fd_isalnum( c ) | fd_ispunct( c ) | (c==' ');
59 0 : }
60 :
61 : static void
62 0 : printf_path( fd_pod_info_t const * info ) {
63 0 : if( FD_UNLIKELY( !info ) ) return;
64 :
65 0 : fd_pod_info_t const * node = info;
66 0 : ulong sz = 0UL;
67 0 : do {
68 0 : ulong key_sz = node->key_sz;
69 0 : if( FD_UNLIKELY( !key_sz ) ) return;
70 0 : sz += key_sz;
71 0 : node = node->parent;
72 0 : } while( node );
73 :
74 0 : char * buf = malloc( sz );
75 0 : if( !buf ) return;
76 :
77 0 : char * p = buf + sz;
78 0 : int subpod = 0;
79 0 : node = info;
80 0 : do {
81 0 : ulong key_sz = node->key_sz;
82 0 : p -= key_sz;
83 0 : strcpy( p, node->key );
84 0 : if( subpod ) p[ key_sz-1UL ] = '.';
85 0 : subpod = 1;
86 0 : node = node->parent;
87 0 : } while( node );
88 :
89 0 : printf( "%s", buf );
90 0 : free( buf );
91 0 : }
92 :
93 : static void
94 0 : printf_val( fd_pod_info_t const * info ) {
95 0 : switch( info->val_type ) {
96 :
97 0 : case FD_POD_VAL_TYPE_SUBPOD: {
98 0 : uchar * subpod = (uchar *)info->val;
99 0 : printf( "max %lu bytes, used %lu bytes, kcnt %lu keys", fd_pod_max( subpod ), fd_pod_used( subpod ), fd_pod_cnt( subpod ) );
100 0 : break;
101 0 : }
102 :
103 0 : default:
104 0 : case FD_POD_VAL_TYPE_BUF: {
105 0 : uchar const * buf = (uchar const *)info->val;
106 0 : ulong sz = info->val_sz;
107 0 : printf( "sz %lu", sz );
108 0 : for( ulong off=0UL; off<sz; off++ ) {
109 0 : ulong col = off & 15UL;
110 : /* FIXME: USER SPECIFIED INDENT AND CONFIGURE OFF WIDTH BASED ON SZ */
111 0 : if( FD_UNLIKELY( col==0UL ) ) printf( "\n\t\t%04lx: ", off );
112 0 : if( FD_UNLIKELY( col==8UL ) ) putc( ' ', stdout );
113 0 : printf( "%02x ", (uint)buf[ off ] );
114 0 : if( FD_UNLIKELY( (col==15UL) | ((off+1UL)==sz) ) ) { /* End of row */
115 : /* Output whitespace to align 2nd column */
116 0 : for( ulong rem=48UL-3UL*col; rem; rem-- ) putc( ' ', stdout );
117 : /* Output single character friendly bytes from row in 2nd column */
118 0 : char const * p = (char const *)(buf + (off & ~15UL));
119 0 : for( ulong rem=col+1UL; rem; rem-- ) { int c = (int)*(p++); putc( issingleprint( c ) ? c : '.', stdout ); }
120 0 : }
121 0 : }
122 0 : break;
123 0 : }
124 :
125 0 : case FD_POD_VAL_TYPE_CSTR: {
126 0 : if( !info->val_sz ) printf( "(null)" );
127 0 : else printf( "\"%s\"", (char const *)info->val );
128 0 : break;
129 0 : }
130 :
131 0 : case FD_POD_VAL_TYPE_CHAR: {
132 0 : int c = (int)*(char *)info->val;
133 0 : if( issingleprint( c ) ) printf( "'%c'", c );
134 0 : else printf( "0x%02x", (uint)(uchar)c );
135 0 : break;
136 0 : }
137 :
138 0 : case FD_POD_VAL_TYPE_UCHAR: { uint u = (uint)*(uchar *)info->val; printf( "%u", u ); break; }
139 0 : case FD_POD_VAL_TYPE_USHORT:
140 0 : case FD_POD_VAL_TYPE_UINT:
141 0 : case FD_POD_VAL_TYPE_ULONG: { ulong u; fd_ulong_svw_dec( info->val, &u ); printf( "%lu", u ); break; }
142 :
143 0 : case FD_POD_VAL_TYPE_SCHAR: { int i = (int) *(schar *)info->val; printf( "%i", i ); break; }
144 0 : case FD_POD_VAL_TYPE_SHORT:
145 0 : case FD_POD_VAL_TYPE_INT:
146 0 : 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 0 : }
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 0 : }
164 0 : # endif
165 :
166 0 : 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 0 : # endif
170 :
171 0 : }
172 0 : }
173 :
174 : int
175 : main( int argc,
176 0 : char ** argv ) {
177 0 : fd_boot( &argc, &argv );
178 :
179 0 : # define SHIFT(n) argv+=(n),argc-=(n)
180 :
181 0 : if( FD_UNLIKELY( argc<1 ) ) FD_LOG_ERR(( "no arguments" ));
182 0 : char const * bin = argv[0];
183 0 : SHIFT(1);
184 :
185 0 : ulong tag = 1UL;
186 :
187 0 : int cnt = 0;
188 0 : while( argc ) {
189 0 : char const * cmd = argv[0];
190 0 : SHIFT(1);
191 :
192 0 : if( !strcmp( cmd, "help" ) ) {
193 :
194 0 : fputs( fd_pod_ctl_help, stdout );
195 :
196 0 : FD_LOG_NOTICE(( "%i: %s: success", cnt, cmd ));
197 :
198 0 : } else if( !strcmp( cmd, "tag" ) ) {
199 :
200 0 : if( FD_UNLIKELY( argc<1 ) ) FD_LOG_ERR(( "%i: %s: too few arguments\n\tDo %s help for help", cnt, cmd, bin ));
201 :
202 0 : tag = fd_cstr_to_ulong( argv[0] );
203 :
204 0 : FD_LOG_NOTICE(( "%i: %s %lu: success", cnt, cmd, tag ));
205 0 : SHIFT(1);
206 :
207 0 : } else if( !strcmp( cmd, "new" ) ) {
208 :
209 0 : if( FD_UNLIKELY( argc<2 ) ) FD_LOG_ERR(( "%i: %s: too few arguments\n\tDo %s help for help", cnt, cmd, bin ));
210 :
211 0 : char const * name = argv[0];
212 0 : ulong max = fd_cstr_to_ulong( argv[1] ); if( !max ) max = 4096UL;
213 :
214 0 : ulong align = fd_pod_align();
215 0 : ulong footprint = fd_pod_footprint( max );
216 :
217 0 : if( FD_UNLIKELY( !footprint ) )
218 0 : FD_LOG_ERR(( "%i: %s: bad max (%lu)\n\tDo %s help for help", cnt, cmd, max, bin ));
219 :
220 0 : fd_wksp_t * wksp = fd_wksp_attach( name );
221 0 : if( FD_UNLIKELY( !wksp ) )
222 0 : FD_LOG_ERR(( "%i: %s: fd_wksp_attach( \"%s\" ) failed\n\tDo %s help for help", cnt, cmd, name, bin ));
223 :
224 0 : ulong gaddr = fd_wksp_alloc( wksp, align, footprint, tag );
225 0 : 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 0 : void * shmem = fd_wksp_laddr( wksp, gaddr );
232 0 : 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 0 : 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 0 : char cstr[ FD_WKSP_CSTR_MAX ];
245 0 : 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 0 : printf( "%s\n", cstr );
252 :
253 0 : fd_wksp_detach( wksp );
254 :
255 0 : FD_LOG_NOTICE(( "%i: %s %s %lu: success", cnt, cmd, name, max ));
256 0 : SHIFT(2);
257 :
258 0 : } else if( !strcmp( cmd, "delete" ) ) {
259 :
260 0 : if( FD_UNLIKELY( argc<1 ) ) FD_LOG_ERR(( "%i: %s: too few arguments\n\tDo %s help for help", cnt, cmd, bin ));
261 :
262 0 : char const * cstr = argv[0];
263 :
264 0 : void * shmem = fd_wksp_map( cstr );
265 0 : if( FD_UNLIKELY( !shmem ) )
266 0 : FD_LOG_ERR(( "%i: %s: fd_wksp_map( \"%s\" ) failed\n\tDo %s help for help", cnt, cmd, cstr, bin ));
267 :
268 0 : 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 0 : fd_wksp_free_laddr( shmem );
274 0 : fd_wksp_unmap( shmem );
275 :
276 0 : FD_LOG_NOTICE(( "%i: %s %s: success", cnt, cmd, cstr ));
277 0 : SHIFT(1);
278 :
279 0 : } else if( !strcmp( cmd, "reset" ) ) {
280 :
281 0 : if( FD_UNLIKELY( argc<1 ) ) FD_LOG_ERR(( "%i: %s: too few arguments\n\tDo %s help for help", cnt, cmd, bin ));
282 :
283 0 : char const * cstr = argv[0];
284 :
285 0 : void * shmem = fd_wksp_map( cstr );
286 0 : if( FD_UNLIKELY( !shmem ) )
287 0 : FD_LOG_ERR(( "%i: %s: fd_wksp_map( \"%s\" ) failed\n\tDo %s help for help", cnt, cmd, cstr, bin ));
288 :
289 0 : uchar * pod = fd_pod_join( shmem );
290 0 : 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 0 : fd_pod_reset( pod );
296 :
297 0 : fd_wksp_unmap( fd_pod_leave( pod ) );
298 :
299 0 : FD_LOG_NOTICE(( "%i: %s %s: success", cnt, cmd, cstr ));
300 0 : SHIFT(1);
301 :
302 0 : } else if( !strcmp( cmd, "list" ) ) {
303 :
304 0 : if( FD_UNLIKELY( argc<1 ) ) FD_LOG_ERR(( "%i: %s: too few arguments\n\tDo %s help for help", cnt, cmd, bin ));
305 :
306 0 : char const * cstr = argv[0];
307 :
308 0 : void * shmem = fd_wksp_map( cstr );
309 0 : if( FD_UNLIKELY( !shmem ) )
310 0 : FD_LOG_ERR(( "%i: %s: fd_wksp_map( \"%s\" ) failed\n\tDo %s help for help", cnt, cmd, cstr, bin ));
311 :
312 0 : uchar * pod = fd_pod_join( shmem );
313 0 : 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 0 : fd_pod_info_t * info;
319 0 : ulong info_cnt = fd_pod_cnt_recursive( pod );
320 0 : if( FD_UNLIKELY( !info_cnt ) ) info = NULL;
321 0 : else {
322 0 : info = (fd_pod_info_t *)aligned_alloc( alignof(fd_pod_info_t), info_cnt*sizeof(fd_pod_info_t) );
323 0 : 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 0 : 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 0 : }
333 :
334 0 : printf( "pod %s\n", cstr );
335 0 : printf( "\tmax %20lu bytes used %20lu bytes avail %20lu bytes\n",
336 0 : fd_pod_max( pod ), fd_pod_used ( pod ), fd_pod_avail( pod ) );
337 0 : printf( "\tkcnt %20lu keys icnt %20lu paths\n", fd_pod_cnt( pod ), info_cnt );
338 0 : for( ulong info_idx=0UL; info_idx<info_cnt; info_idx++ ) {
339 0 : fd_pod_info_t * node = &info[ info_idx ];
340 0 : char type[ FD_POD_VAL_TYPE_CSTR_MAX ]; fd_pod_val_type_to_cstr( node->val_type, type );
341 0 : printf( "\t%s %s ", cstr, type );
342 0 : printf_path( node );
343 0 : printf( " " );
344 0 : printf_val( node );
345 0 : printf( "\n" );
346 0 : }
347 :
348 0 : if( FD_LIKELY( info ) ) free( info );
349 0 : fd_wksp_unmap( fd_pod_leave( pod ) );
350 :
351 0 : FD_LOG_NOTICE(( "%i: %s %s: success", cnt, cmd, cstr ));
352 0 : SHIFT(1);
353 :
354 0 : } else if( !strcmp( cmd, "insert" ) ) {
355 :
356 0 : if( FD_UNLIKELY( argc<4 ) ) FD_LOG_ERR(( "%i: %s: too few arguments\n\tDo %s help for help", cnt, cmd, bin ));
357 :
358 0 : char const * cstr = argv[0];
359 0 : char const * type = argv[1];
360 0 : char const * path = argv[2];
361 0 : char const * val = argv[3];
362 :
363 0 : int val_type = fd_cstr_to_pod_val_type( type );
364 0 : if( FD_UNLIKELY( !supported_val_type( val_type ) ) )
365 0 : FD_LOG_ERR(( "%i: %s: unsupported type %s\n\tDo %s help for help", cnt, cmd, type, bin ));
366 :
367 0 : void * shmem = fd_wksp_map( cstr );
368 0 : if( FD_UNLIKELY( !shmem ) )
369 0 : FD_LOG_ERR(( "%i: %s: fd_wksp_map( \"%s\" ) failed\n\tDo %s help for help", cnt, cmd, cstr, bin ));
370 :
371 0 : uchar * pod = fd_pod_join( shmem );
372 0 : 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 0 : ulong off = insert_val( pod, path, val_type, val );
378 :
379 0 : fd_wksp_unmap( fd_pod_leave( pod ) );
380 :
381 0 : 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 0 : cnt, cmd, type, cstr, path, val, bin ));
384 :
385 0 : FD_LOG_NOTICE(( "%i: %s %s %s %s %s: success", cnt, cmd, cstr, type, path, val ));
386 0 : SHIFT(4);
387 :
388 0 : } else if( !strcmp( cmd, "insert-file" ) ) {
389 :
390 0 : if( FD_UNLIKELY( argc<3 ) ) FD_LOG_ERR(( "%i: %s: too few arguments\n\tDo %s help for help", cnt, cmd, bin ));
391 :
392 0 : char const * cstr = argv[0];
393 0 : char const * path = argv[1];
394 0 : char const * file = argv[2];
395 :
396 0 : void * shmem = fd_wksp_map( cstr );
397 0 : if( FD_UNLIKELY( !shmem ) )
398 0 : FD_LOG_ERR(( "%i: %s: fd_wksp_map( \"%s\" ) failed\n\tDo %s help for help", cnt, cmd, cstr, bin ));
399 :
400 0 : uchar * pod = fd_pod_join( shmem );
401 0 : 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 0 : int fd = open( file, O_RDONLY );
407 0 : if( FD_UNLIKELY( fd == -1 ) )
408 0 : FD_LOG_ERR(( "%i: %s: open( \"%s\" ) failed\n\tDo %s help for help", cnt, cmd, file, bin ));
409 :
410 0 : struct stat st;
411 0 : 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 0 : ulong buf_sz = (ulong)st.st_size;
414 :
415 0 : ulong off = fd_pod_alloc( pod, path, FD_POD_VAL_TYPE_BUF, buf_sz );
416 0 : if( FD_UNLIKELY( !off ) )
417 0 : FD_LOG_ERR(( "%i: %s: fd_pod_alloc( \"%s\", \"%s\", FD_POD_VAL_TYPE_BUF, %lu ) failed\n\tDo %s help for help",
418 0 : cnt, cmd, cstr, path, buf_sz, bin ));
419 :
420 0 : 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 0 : if( FD_UNLIKELY( close( fd ) ) )
427 0 : FD_LOG_WARNING(( "%i: %s: close( \"%s\" ) failed; attempting to continue", cnt, cmd, file ));
428 :
429 0 : fd_wksp_unmap( fd_pod_leave( pod ) );
430 :
431 0 : FD_LOG_NOTICE(( "%i: %s %s %s %s: success", cnt, cmd, cstr, path, file ));
432 0 : SHIFT(3);
433 :
434 0 : } else if( !strcmp( cmd, "remove" ) ) {
435 :
436 0 : if( FD_UNLIKELY( argc<2 ) ) FD_LOG_ERR(( "%i: %s: too few arguments\n\tDo %s help for help", cnt, cmd, bin ));
437 :
438 0 : char const * cstr = argv[0];
439 0 : char const * path = argv[1];
440 :
441 0 : void * shmem = fd_wksp_map( cstr );
442 0 : 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 0 : uchar * pod = fd_pod_join( shmem );
446 0 : 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 0 : int err = fd_pod_remove( pod, path );
452 :
453 0 : fd_wksp_unmap( fd_pod_leave( pod ) );
454 :
455 0 : if( FD_UNLIKELY( err ) )
456 0 : FD_LOG_ERR(( "%i: %s: fd_pod_remove( \"%s\", \"%s\" ) failed (%i-%s)\n\tDo %s help for help",
457 0 : cnt, cmd, cstr, path, err, fd_pod_strerror( err ), bin ));
458 :
459 0 : FD_LOG_NOTICE(( "%i: %s %s %s: success", cnt, cmd, cstr, path ));
460 0 : SHIFT(2);
461 :
462 0 : } else if( !strcmp( cmd, "update" ) ) {
463 :
464 0 : if( FD_UNLIKELY( argc<4 ) ) FD_LOG_ERR(( "%i: %s: too few arguments\n\tDo %s help for help", cnt, cmd, bin ));
465 :
466 0 : char const * cstr = argv[0];
467 0 : char const * type = argv[1];
468 0 : char const * path = argv[2];
469 0 : char const * val = argv[3];
470 :
471 0 : int val_type = fd_cstr_to_pod_val_type( type );
472 0 : if( FD_UNLIKELY( !supported_val_type( val_type ) ) )
473 0 : FD_LOG_ERR(( "%i: %s: unsupported type %s\n\tDo %s help for help", cnt, cmd, type, bin ));
474 :
475 0 : void * shmem = fd_wksp_map( cstr );
476 0 : if( FD_UNLIKELY( !shmem ) )
477 0 : FD_LOG_ERR(( "%i: %s: fd_wksp_map( \"%s\" ) failed\n\tDo %s help for help", cnt, cmd, cstr, bin ));
478 :
479 0 : uchar * pod = fd_pod_join( shmem );
480 0 : 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 0 : fd_pod_info_t info[1];
486 0 : int err = fd_pod_query( pod, path, info );
487 0 : 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 0 : if( FD_UNLIKELY( info->val_type!=val_type ) ) {
494 0 : fd_wksp_unmap( fd_pod_leave( pod ) );
495 0 : char buf[ FD_POD_VAL_TYPE_CSTR_MAX ];
496 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",
497 0 : cnt, cmd, info->val_type, fd_pod_val_type_to_cstr( info->val_type, buf ),
498 0 : cstr, path, val_type, type, bin ));
499 0 : }
500 :
501 0 : err = fd_pod_remove( pod, path );
502 0 : 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 0 : ulong off = insert_val( pod, path, val_type, val );
509 :
510 0 : fd_wksp_unmap( fd_pod_leave( pod ) );
511 :
512 0 : 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 0 : cnt, cmd, type, cstr, path, val, bin ));
515 :
516 0 : FD_LOG_NOTICE(( "%i: %s %s %s %s %s: success", cnt, cmd, cstr, type, path, val ));
517 0 : SHIFT(4);
518 :
519 0 : } else if( !strcmp( cmd, "set" ) ) {
520 :
521 0 : if( FD_UNLIKELY( argc<4 ) ) FD_LOG_ERR(( "%i: %s: too few arguments\n\tDo %s help for help", cnt, cmd, bin ));
522 :
523 0 : char const * cstr = argv[0];
524 0 : char const * type = argv[1];
525 0 : char const * path = argv[2];
526 0 : char const * val = argv[3];
527 :
528 0 : int val_type = fd_cstr_to_pod_val_type( type );
529 0 : if( FD_UNLIKELY( !supported_val_type( val_type ) ) )
530 0 : FD_LOG_ERR(( "%i: %s: unsupported type %s\n\tDo %s help for help", cnt, cmd, type, bin ));
531 :
532 0 : void * shmem = fd_wksp_map( cstr );
533 0 : if( FD_UNLIKELY( !shmem ) )
534 0 : FD_LOG_ERR(( "%i: %s: fd_wksp_map( \"%s\" ) failed\n\tDo %s help for help", cnt, cmd, cstr, bin ));
535 :
536 0 : uchar * pod = fd_pod_join( shmem );
537 0 : 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 0 : fd_pod_info_t info[1];
543 0 : int err = fd_pod_query( pod, path, info );
544 0 : if( FD_LIKELY( !err ) ) {
545 :
546 0 : if( FD_UNLIKELY( info->val_type!=val_type ) ) {
547 0 : fd_wksp_unmap( fd_pod_leave( pod ) );
548 0 : char buf[ FD_POD_VAL_TYPE_CSTR_MAX ];
549 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",
550 0 : cnt, cmd, info->val_type, fd_pod_val_type_to_cstr( info->val_type, buf ),
551 0 : cstr, path, val_type, type, bin ));
552 0 : }
553 :
554 0 : err = fd_pod_remove( pod, path );
555 0 : 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 0 : } 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 0 : ulong off = insert_val( pod, path, val_type, val );
570 :
571 0 : fd_wksp_unmap( fd_pod_leave( pod ) );
572 :
573 0 : 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 0 : cnt, cmd, type, cstr, path, val, bin ));
576 :
577 0 : FD_LOG_NOTICE(( "%i: %s %s %s %s %s: success", cnt, cmd, cstr, type, path, val ));
578 0 : SHIFT(4);
579 :
580 0 : } 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 0 : } else if( !strcmp( cmd, "query-root" ) ) {
608 :
609 0 : if( FD_UNLIKELY( argc<2 ) ) FD_LOG_ERR(( "%i: %s: too few arguments\n\tDo %s help for help", cnt, cmd, bin ));
610 :
611 0 : char const * what = argv[0];
612 0 : char const * cstr = argv[1];
613 :
614 0 : void * shmem = NULL;
615 0 : uchar * pod = NULL;
616 0 : int err = FD_POD_ERR_INVAL;
617 :
618 0 : shmem = fd_wksp_map( cstr );
619 0 : if( FD_LIKELY( shmem ) ) {
620 0 : pod = fd_pod_join( shmem );
621 0 : if( FD_LIKELY( pod ) ) err = 0;
622 0 : }
623 :
624 0 : if( !strcmp( what, "test" ) ) printf( "%i\n", err );
625 0 : else if( !strcmp( what, "max" ) ) printf( "%lu\n", FD_LIKELY(!err) ? fd_pod_max ( pod ) : 0UL );
626 0 : else if( !strcmp( what, "used" ) ) printf( "%lu\n", FD_LIKELY(!err) ? fd_pod_used ( pod ) : 0UL );
627 0 : else if( !strcmp( what, "avail" ) ) printf( "%lu\n", FD_LIKELY(!err) ? fd_pod_avail ( pod ) : 0UL );
628 0 : else if( !strcmp( what, "cnt" ) ) printf( "%lu\n", FD_LIKELY(!err) ? fd_pod_cnt ( pod ) : 0UL );
629 0 : else if( !strcmp( what, "recursive" ) ) printf( "%lu\n", FD_LIKELY(!err) ? fd_pod_cnt_recursive( pod ) : 0UL );
630 0 : 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 0 : if( FD_LIKELY( pod ) ) fd_pod_leave( pod );
634 0 : if( FD_LIKELY( shmem ) ) fd_wksp_unmap( shmem );
635 0 : FD_LOG_NOTICE(( "%i: %s %s %s: success", cnt, cmd, what, cstr ));
636 0 : SHIFT(2);
637 :
638 0 : } else if( !strcmp( cmd, "query" ) ) {
639 :
640 0 : if( FD_UNLIKELY( argc<3 ) ) FD_LOG_ERR(( "%i: %s: too few arguments\n\tDo %s help for help", cnt, cmd, bin ));
641 :
642 0 : char const * what = argv[0];
643 0 : char const * cstr = argv[1];
644 0 : char const * path = argv[2];
645 :
646 0 : void * shmem = NULL;
647 0 : uchar * pod = NULL;
648 0 : int err = FD_POD_ERR_INVAL;
649 0 : fd_pod_info_t info[1];
650 0 : char type[ FD_POD_VAL_TYPE_CSTR_MAX ];
651 0 : int is_subpod = 0;
652 :
653 0 : shmem = fd_wksp_map( cstr );
654 0 : if( FD_LIKELY( shmem ) ) {
655 0 : pod = fd_pod_join( shmem );
656 0 : if( FD_LIKELY( pod ) ) {
657 0 : err = fd_pod_query( pod, path, info );
658 0 : if( FD_LIKELY( !err ) ) {
659 0 : is_subpod = (info->val_type==FD_POD_VAL_TYPE_SUBPOD);
660 0 : 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 0 : }
664 0 : }
665 0 : }
666 :
667 0 : if( !strcmp( what, "test" ) ) printf( "%i\n", err );
668 0 : else if( !strcmp( what, "type" ) ) printf( "%s\n", FD_LIKELY( !err ) ? type : "void" );
669 0 : else if( !strcmp( what, "val" ) ) {
670 0 : if( FD_UNLIKELY( err ) ) printf( "void\n" );
671 0 : else {
672 0 : printf_val( info );
673 0 : printf( "\n" );
674 0 : }
675 0 : }
676 0 : else if( !strcmp( what, "max" ) ) printf( "%lu\n", FD_LIKELY( is_subpod ) ? fd_pod_max ( info->val ) : 0UL );
677 0 : else if( !strcmp( what, "used" ) ) printf( "%lu\n", FD_LIKELY( is_subpod ) ? fd_pod_used ( info->val ) : 0UL );
678 0 : else if( !strcmp( what, "avail" ) ) printf( "%lu\n", FD_LIKELY( is_subpod ) ? fd_pod_avail ( info->val ) : 0UL );
679 0 : else if( !strcmp( what, "cnt" ) ) printf( "%lu\n", FD_LIKELY( is_subpod ) ? fd_pod_cnt ( info->val ) : 0UL );
680 0 : else if( !strcmp( what, "recursive" ) ) printf( "%lu\n", FD_LIKELY( is_subpod ) ? fd_pod_cnt_recursive( info->val ) : 0UL );
681 0 : else if( !strcmp( what, "subpod-cnt" ) ) printf( "%lu\n", FD_LIKELY( is_subpod ) ? fd_pod_cnt_subpod ( info->val ) : 0UL );
682 0 : else if( !strcmp( what, "gaddr" ) ) {
683 0 : char buf[ FD_WKSP_CSTR_MAX ];
684 0 : printf( "%s\n", (FD_LIKELY( !err ) && FD_LIKELY( fd_wksp_cstr_laddr( info->val, buf ) )) ? buf : "null" );
685 0 : }
686 0 : else if( !strcmp( what, "full" ) ) {
687 0 : if( FD_UNLIKELY( err ) ) printf( "%s void %s void\n", cstr, path );
688 0 : else {
689 0 : printf( "%s %s %s ", cstr, type, path );
690 0 : printf_val( info );
691 0 : printf( "\n" );
692 0 : }
693 0 : }
694 0 : else FD_LOG_ERR(( "unknown query %s", what ));
695 :
696 0 : if( FD_LIKELY( pod ) ) fd_pod_leave( pod );
697 0 : if( FD_LIKELY( shmem ) ) fd_wksp_unmap( shmem );
698 0 : FD_LOG_NOTICE(( "%i: %s %s %s %s: success", cnt, cmd, what, cstr, path ));
699 0 : SHIFT(3);
700 :
701 0 : } 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 0 : cnt++;
708 0 : }
709 :
710 0 : if( FD_UNLIKELY( cnt<1 ) ) FD_LOG_NOTICE(( "processed %i commands\n\tDo %s help for help", cnt, bin ));
711 0 : else FD_LOG_NOTICE(( "processed %i commands", cnt ));
712 :
713 0 : # undef SHIFT
714 0 : fd_halt();
715 0 : return 0;
716 0 : }
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
|