00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 FILE_LICENCE ( GPL2_OR_LATER );
00020
00021 #include <stdint.h>
00022 #include <stdlib.h>
00023 #include <stdio.h>
00024 #include <string.h>
00025 #include <strings.h>
00026 #include <byteswap.h>
00027 #include <errno.h>
00028 #include <assert.h>
00029 #include <gpxe/in.h>
00030 #include <gpxe/vsprintf.h>
00031 #include <gpxe/dhcp.h>
00032 #include <gpxe/uuid.h>
00033 #include <gpxe/uri.h>
00034 #include <gpxe/settings.h>
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053 struct generic_setting {
00054
00055 struct list_head list;
00056
00057 struct setting setting;
00058
00059 size_t name_len;
00060
00061 size_t data_len;
00062 };
00063
00064
00065
00066
00067
00068
00069
00070 static inline void * generic_setting_name ( struct generic_setting *generic ) {
00071 return ( ( ( void * ) generic ) + sizeof ( *generic ) );
00072 }
00073
00074
00075
00076
00077
00078
00079
00080 static inline void * generic_setting_data ( struct generic_setting *generic ) {
00081 return ( ( ( void * ) generic ) + sizeof ( *generic ) +
00082 generic->name_len );
00083 }
00084
00085
00086
00087
00088
00089
00090
00091
00092 static struct generic_setting *
00093 find_generic_setting ( struct generic_settings *generics,
00094 struct setting *setting ) {
00095 struct generic_setting *generic;
00096
00097 list_for_each_entry ( generic, &generics->list, list ) {
00098 if ( setting_cmp ( &generic->setting, setting ) == 0 )
00099 return generic;
00100 }
00101 return NULL;
00102 }
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113 int generic_settings_store ( struct settings *settings,
00114 struct setting *setting,
00115 const void *data, size_t len ) {
00116 struct generic_settings *generics =
00117 container_of ( settings, struct generic_settings, settings );
00118 struct generic_setting *old;
00119 struct generic_setting *new = NULL;
00120 size_t name_len;
00121
00122
00123 old = find_generic_setting ( generics, setting );
00124
00125
00126 if ( len ) {
00127
00128 name_len = ( strlen ( setting->name ) + 1 );
00129 new = zalloc ( sizeof ( *new ) + name_len + len );
00130 if ( ! new )
00131 return -ENOMEM;
00132
00133
00134 new->name_len = name_len;
00135 new->data_len = len;
00136 memcpy ( &new->setting, setting, sizeof ( new->setting ) );
00137 new->setting.name = generic_setting_name ( new );
00138 memcpy ( generic_setting_name ( new ),
00139 setting->name, name_len );
00140 memcpy ( generic_setting_data ( new ), data, len );
00141 }
00142
00143
00144 if ( old ) {
00145 list_del ( &old->list );
00146 free ( old );
00147 }
00148
00149
00150 if ( new )
00151 list_add ( &new->list, &generics->list );
00152
00153 return 0;
00154 }
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165 int generic_settings_fetch ( struct settings *settings,
00166 struct setting *setting,
00167 void *data, size_t len ) {
00168 struct generic_settings *generics =
00169 container_of ( settings, struct generic_settings, settings );
00170 struct generic_setting *generic;
00171
00172
00173 generic = find_generic_setting ( generics, setting );
00174 if ( ! generic )
00175 return -ENOENT;
00176
00177
00178 if ( len > generic->data_len )
00179 len = generic->data_len;
00180 memcpy ( data, generic_setting_data ( generic ), len );
00181 return generic->data_len;
00182 }
00183
00184
00185
00186
00187
00188
00189 void generic_settings_clear ( struct settings *settings ) {
00190 struct generic_settings *generics =
00191 container_of ( settings, struct generic_settings, settings );
00192 struct generic_setting *generic;
00193 struct generic_setting *tmp;
00194
00195 list_for_each_entry_safe ( generic, tmp, &generics->list, list ) {
00196 list_del ( &generic->list );
00197 free ( generic );
00198 }
00199 assert ( list_empty ( &generics->list ) );
00200 }
00201
00202
00203 struct settings_operations generic_settings_operations = {
00204 .store = generic_settings_store,
00205 .fetch = generic_settings_fetch,
00206 .clear = generic_settings_clear,
00207 };
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217 struct generic_settings generic_settings_root = {
00218 .settings = {
00219 .refcnt = NULL,
00220 .name = "",
00221 .siblings =
00222 LIST_HEAD_INIT ( generic_settings_root.settings.siblings ),
00223 .children =
00224 LIST_HEAD_INIT ( generic_settings_root.settings.children ),
00225 .op = &generic_settings_operations,
00226 },
00227 .list = LIST_HEAD_INIT ( generic_settings_root.list ),
00228 };
00229
00230
00231 #define settings_root generic_settings_root.settings
00232
00233
00234
00235
00236
00237
00238
00239
00240 static struct settings * find_child_settings ( struct settings *parent,
00241 const char *name ) {
00242 struct settings *settings;
00243
00244
00245 if ( ! *name )
00246 return parent;
00247
00248
00249 list_for_each_entry ( settings, &parent->children, siblings ) {
00250 if ( strcmp ( settings->name, name ) == 0 )
00251 return settings;
00252 }
00253
00254 return NULL;
00255 }
00256
00257
00258
00259
00260
00261
00262
00263
00264 static struct settings * autovivify_child_settings ( struct settings *parent,
00265 const char *name ) {
00266 struct {
00267 struct generic_settings generic;
00268 char name[ strlen ( name ) + 1 ];
00269 } *new_child;
00270 struct settings *settings;
00271
00272
00273 if ( ( settings = find_child_settings ( parent, name ) ) != NULL )
00274 return settings;
00275
00276
00277 new_child = zalloc ( sizeof ( *new_child ) );
00278 if ( ! new_child ) {
00279 DBGC ( parent, "Settings %p could not create child %s\n",
00280 parent, name );
00281 return NULL;
00282 }
00283 memcpy ( new_child->name, name, sizeof ( new_child->name ) );
00284 generic_settings_init ( &new_child->generic, NULL, new_child->name );
00285 settings = &new_child->generic.settings;
00286 register_settings ( settings, parent );
00287 return settings;
00288 }
00289
00290
00291
00292
00293
00294
00295
00296 static const char * settings_name ( struct settings *settings ) {
00297 static char buf[64];
00298 char tmp[ sizeof ( buf ) ];
00299 int count;
00300
00301 for ( count = 0 ; settings ; settings = settings->parent ) {
00302 memcpy ( tmp, buf, sizeof ( tmp ) );
00303 snprintf ( buf, sizeof ( buf ), "%s%c%s", settings->name,
00304 ( count++ ? '.' : '\0' ), tmp );
00305 }
00306 return ( buf + 1 );
00307 }
00308
00309
00310
00311
00312
00313
00314
00315
00316 static struct settings *
00317 parse_settings_name ( const char *name,
00318 struct settings * ( * get_child ) ( struct settings *,
00319 const char * ) ) {
00320 struct settings *settings = &settings_root;
00321 char name_copy[ strlen ( name ) + 1 ];
00322 char *subname;
00323 char *remainder;
00324
00325
00326 memcpy ( name_copy, name, sizeof ( name_copy ) );
00327 remainder = name_copy;
00328
00329
00330 while ( remainder ) {
00331 struct net_device *netdev;
00332
00333 subname = remainder;
00334 remainder = strchr ( subname, '.' );
00335 if ( remainder )
00336 *(remainder++) = '\0';
00337
00338
00339 if ( ( subname == name_copy ) && ! strcmp ( subname, "netX" ) &&
00340 ( ( netdev = last_opened_netdev() ) != NULL ) )
00341 settings = get_child ( settings, netdev->name );
00342 else
00343 settings = get_child ( settings, subname );
00344
00345 if ( ! settings )
00346 break;
00347 }
00348
00349 return settings;
00350 }
00351
00352
00353
00354
00355
00356
00357
00358 struct settings * find_settings ( const char *name ) {
00359
00360 return parse_settings_name ( name, find_child_settings );
00361 }
00362
00363
00364
00365
00366
00367
00368 static int apply_settings ( void ) {
00369 struct settings_applicator *applicator;
00370 int rc;
00371
00372
00373 for_each_table_entry ( applicator, SETTINGS_APPLICATORS ) {
00374 if ( ( rc = applicator->apply() ) != 0 ) {
00375 DBG ( "Could not apply settings using applicator "
00376 "%p: %s\n", applicator, strerror ( rc ) );
00377 return rc;
00378 }
00379 }
00380
00381 return 0;
00382 }
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392 static void reprioritise_settings ( struct settings *settings ) {
00393 struct settings *parent = settings->parent;
00394 long priority;
00395 struct settings *tmp;
00396 long tmp_priority;
00397
00398
00399 if ( ! parent )
00400 return;
00401
00402
00403 priority = fetch_intz_setting ( settings, &priority_setting );
00404
00405
00406 list_del ( &settings->siblings );
00407
00408
00409 list_for_each_entry ( tmp, &parent->children, siblings ) {
00410 tmp_priority = fetch_intz_setting ( tmp, &priority_setting );
00411 if ( priority > tmp_priority )
00412 break;
00413 }
00414 list_add_tail ( &settings->siblings, &tmp->siblings );
00415
00416
00417 reprioritise_settings ( parent );
00418 }
00419
00420
00421
00422
00423
00424
00425
00426
00427 int register_settings ( struct settings *settings, struct settings *parent ) {
00428 struct settings *old_settings;
00429
00430
00431 assert ( settings != NULL );
00432 if ( parent == NULL )
00433 parent = &settings_root;
00434
00435
00436 if ( ( old_settings = find_child_settings ( parent, settings->name ) ))
00437 unregister_settings ( old_settings );
00438
00439
00440 ref_get ( settings->refcnt );
00441 ref_get ( parent->refcnt );
00442 settings->parent = parent;
00443 list_add_tail ( &settings->siblings, &parent->children );
00444 DBGC ( settings, "Settings %p (\"%s\") registered\n",
00445 settings, settings_name ( settings ) );
00446
00447
00448 reprioritise_settings ( settings );
00449
00450
00451 apply_settings();
00452
00453 return 0;
00454 }
00455
00456
00457
00458
00459
00460
00461 void unregister_settings ( struct settings *settings ) {
00462
00463 DBGC ( settings, "Settings %p (\"%s\") unregistered\n",
00464 settings, settings_name ( settings ) );
00465
00466
00467 ref_put ( settings->refcnt );
00468 ref_put ( settings->parent->refcnt );
00469 settings->parent = NULL;
00470 list_del ( &settings->siblings );
00471
00472
00473 apply_settings();
00474 }
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492 int store_setting ( struct settings *settings, struct setting *setting,
00493 const void *data, size_t len ) {
00494 int rc;
00495
00496
00497 if ( ! settings )
00498 settings = &settings_root;
00499
00500
00501 if ( ! settings->op->store )
00502 return -ENOTSUP;
00503
00504
00505 if ( ( rc = settings->op->store ( settings, setting,
00506 data, len ) ) != 0 )
00507 return rc;
00508
00509
00510 if ( setting_cmp ( setting, &priority_setting ) == 0 )
00511 reprioritise_settings ( settings );
00512
00513
00514
00515
00516 for ( ; settings ; settings = settings->parent ) {
00517 if ( settings == &settings_root ) {
00518 if ( ( rc = apply_settings() ) != 0 )
00519 return rc;
00520 break;
00521 }
00522 }
00523
00524 return 0;
00525 }
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539 int fetch_setting ( struct settings *settings, struct setting *setting,
00540 void *data, size_t len ) {
00541 struct settings *child;
00542 int ret;
00543
00544
00545 memset ( data, 0, len );
00546
00547
00548 if ( ! settings )
00549 settings = &settings_root;
00550
00551
00552 if ( ! settings->op->fetch )
00553 return -ENOTSUP;
00554
00555
00556 if ( ( ret = settings->op->fetch ( settings, setting,
00557 data, len ) ) >= 0 )
00558 return ret;
00559
00560
00561 list_for_each_entry ( child, &settings->children, siblings ) {
00562 if ( ( ret = fetch_setting ( child, setting,
00563 data, len ) ) >= 0 )
00564 return ret;
00565 }
00566
00567 return -ENOENT;
00568 }
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580 int fetch_setting_len ( struct settings *settings, struct setting *setting ) {
00581 return fetch_setting ( settings, setting, NULL, 0 );
00582 }
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597 int fetch_string_setting ( struct settings *settings, struct setting *setting,
00598 char *data, size_t len ) {
00599 memset ( data, 0, len );
00600 return fetch_setting ( settings, setting, data,
00601 ( ( len > 0 ) ? ( len - 1 ) : 0 ) );
00602 }
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617 int fetch_string_setting_copy ( struct settings *settings,
00618 struct setting *setting,
00619 char **data ) {
00620 int len;
00621 int check_len = 0;
00622
00623 len = fetch_setting_len ( settings, setting );
00624 if ( len < 0 )
00625 return len;
00626
00627 *data = malloc ( len + 1 );
00628 if ( ! *data )
00629 return -ENOMEM;
00630
00631 check_len = fetch_string_setting ( settings, setting, *data,
00632 ( len + 1 ) );
00633 assert ( check_len == len );
00634 return len;
00635 }
00636
00637
00638
00639
00640
00641
00642
00643
00644
00645 int fetch_ipv4_setting ( struct settings *settings, struct setting *setting,
00646 struct in_addr *inp ) {
00647 int len;
00648
00649 len = fetch_setting ( settings, setting, inp, sizeof ( *inp ) );
00650 if ( len < 0 )
00651 return len;
00652 if ( len < ( int ) sizeof ( *inp ) )
00653 return -ERANGE;
00654 return len;
00655 }
00656
00657
00658
00659
00660
00661
00662
00663
00664
00665 int fetch_int_setting ( struct settings *settings, struct setting *setting,
00666 long *value ) {
00667 union {
00668 uint8_t u8[ sizeof ( long ) ];
00669 int8_t s8[ sizeof ( long ) ];
00670 } buf;
00671 int len;
00672 int i;
00673
00674
00675 *value = 0;
00676
00677
00678 len = fetch_setting ( settings, setting, &buf, sizeof ( buf ) );
00679 if ( len < 0 )
00680 return len;
00681 if ( len > ( int ) sizeof ( buf ) )
00682 return -ERANGE;
00683
00684
00685 *value = ( ( buf.s8[0] >= 0 ) ? 0 : -1L );
00686 for ( i = 0 ; i < len ; i++ ) {
00687 *value = ( ( *value << 8 ) | buf.u8[i] );
00688 }
00689
00690 return len;
00691 }
00692
00693
00694
00695
00696
00697
00698
00699
00700
00701 int fetch_uint_setting ( struct settings *settings, struct setting *setting,
00702 unsigned long *value ) {
00703 long svalue;
00704 int len;
00705
00706
00707 *value = 0;
00708
00709
00710 len = fetch_int_setting ( settings, setting, &svalue );
00711 if ( len < 0 )
00712 return len;
00713
00714
00715 assert ( len <= ( int ) sizeof ( long ) );
00716 *value = ( svalue & ( -1UL >> ( 8 * ( sizeof ( long ) - len ) ) ) );
00717
00718 return len;
00719 }
00720
00721
00722
00723
00724
00725
00726
00727
00728 long fetch_intz_setting ( struct settings *settings, struct setting *setting ){
00729 long value;
00730
00731 fetch_int_setting ( settings, setting, &value );
00732 return value;
00733 }
00734
00735
00736
00737
00738
00739
00740
00741
00742 unsigned long fetch_uintz_setting ( struct settings *settings,
00743 struct setting *setting ) {
00744 unsigned long value;
00745
00746 fetch_uint_setting ( settings, setting, &value );
00747 return value;
00748 }
00749
00750
00751
00752
00753
00754
00755
00756
00757
00758 int fetch_uuid_setting ( struct settings *settings, struct setting *setting,
00759 union uuid *uuid ) {
00760 int len;
00761
00762 len = fetch_setting ( settings, setting, uuid, sizeof ( *uuid ) );
00763 if ( len < 0 )
00764 return len;
00765 if ( len != sizeof ( *uuid ) )
00766 return -ERANGE;
00767 return len;
00768 }
00769
00770
00771
00772
00773
00774
00775 void clear_settings ( struct settings *settings ) {
00776 if ( settings->op->clear )
00777 settings->op->clear ( settings );
00778 }
00779
00780
00781
00782
00783
00784
00785
00786
00787
00788 int setting_cmp ( struct setting *a, struct setting *b ) {
00789
00790
00791 if ( a->tag && ( a->tag == b->tag ) )
00792 return 0;
00793
00794
00795 if ( a->name && b->name && a->name[0] )
00796 return strcmp ( a->name, b->name );
00797
00798
00799 return ( ! 0 );
00800 }
00801
00802
00803
00804
00805
00806
00807
00808
00809
00810
00811
00812
00813
00814
00815
00816
00817
00818 int storef_setting ( struct settings *settings, struct setting *setting,
00819 const char *value ) {
00820
00821
00822
00823
00824
00825 if ( ! value )
00826 return delete_setting ( settings, setting );
00827
00828 return setting->type->storef ( settings, setting, value );
00829 }
00830
00831
00832
00833
00834
00835
00836
00837 static struct setting * find_setting ( const char *name ) {
00838 struct setting *setting;
00839
00840 for_each_table_entry ( setting, SETTINGS ) {
00841 if ( strcmp ( name, setting->name ) == 0 )
00842 return setting;
00843 }
00844 return NULL;
00845 }
00846
00847
00848
00849
00850
00851
00852
00853 static unsigned int parse_setting_tag ( const char *name ) {
00854 char *tmp = ( ( char * ) name );
00855 unsigned int tag = 0;
00856
00857 while ( 1 ) {
00858 tag = ( ( tag << 8 ) | strtoul ( tmp, &tmp, 0 ) );
00859 if ( *tmp == 0 )
00860 return tag;
00861 if ( *tmp != '.' )
00862 return 0;
00863 tmp++;
00864 }
00865 }
00866
00867
00868
00869
00870
00871
00872
00873 static struct setting_type * find_setting_type ( const char *name ) {
00874 struct setting_type *type;
00875
00876 for_each_table_entry ( type, SETTING_TYPES ) {
00877 if ( strcmp ( name, type->name ) == 0 )
00878 return type;
00879 }
00880 return NULL;
00881 }
00882
00883
00884
00885
00886
00887
00888
00889
00890
00891
00892
00893
00894
00895
00896
00897
00898
00899
00900 static int
00901 parse_setting_name ( const char *name,
00902 struct settings * ( * get_child ) ( struct settings *,
00903 const char * ),
00904 struct settings **settings, struct setting *setting,
00905 char *tmp_name ) {
00906 char *settings_name;
00907 char *setting_name;
00908 char *type_name;
00909 struct setting *named_setting;
00910
00911
00912 *settings = &settings_root;
00913 memset ( setting, 0, sizeof ( *setting ) );
00914 setting->name = "";
00915 setting->type = &setting_type_string;
00916
00917
00918 strcpy ( tmp_name, name );
00919 if ( ( setting_name = strchr ( tmp_name, '/' ) ) != NULL ) {
00920 *(setting_name++) = 0;
00921 settings_name = tmp_name;
00922 } else {
00923 setting_name = tmp_name;
00924 settings_name = NULL;
00925 }
00926 if ( ( type_name = strchr ( setting_name, ':' ) ) != NULL )
00927 *(type_name++) = 0;
00928
00929
00930 if ( settings_name ) {
00931 *settings = parse_settings_name ( settings_name, get_child );
00932 if ( *settings == NULL ) {
00933 DBG ( "Unrecognised settings block \"%s\" in \"%s\"\n",
00934 settings_name, name );
00935 return -ENODEV;
00936 }
00937 }
00938
00939
00940 if ( ( named_setting = find_setting ( setting_name ) ) != NULL ) {
00941
00942 memcpy ( setting, named_setting, sizeof ( *setting ) );
00943 } else if ( ( setting->tag = parse_setting_tag ( setting_name ) ) !=0){
00944
00945 setting->tag |= (*settings)->tag_magic;
00946 } else {
00947
00948 setting->name = setting_name;
00949 }
00950
00951
00952 if ( type_name ) {
00953 setting->type = find_setting_type ( type_name );
00954 if ( setting->type == NULL ) {
00955 DBG ( "Invalid setting type \"%s\" in \"%s\"\n",
00956 type_name, name );
00957 return -ENOTSUP;
00958 }
00959 }
00960
00961 return 0;
00962 }
00963
00964
00965
00966
00967
00968
00969
00970
00971 int storef_named_setting ( const char *name, const char *value ) {
00972 struct settings *settings;
00973 struct setting setting;
00974 char tmp_name[ strlen ( name ) + 1 ];
00975 int rc;
00976
00977 if ( ( rc = parse_setting_name ( name, autovivify_child_settings,
00978 &settings, &setting, tmp_name )) != 0)
00979 return rc;
00980 return storef_setting ( settings, &setting, value );
00981 }
00982
00983
00984
00985
00986
00987
00988
00989
00990
00991 int fetchf_named_setting ( const char *name, char *buf, size_t len ) {
00992 struct settings *settings;
00993 struct setting setting;
00994 char tmp_name[ strlen ( name ) + 1 ];
00995 int rc;
00996
00997 if ( ( rc = parse_setting_name ( name, find_child_settings,
00998 &settings, &setting, tmp_name )) != 0)
00999 return rc;
01000 return fetchf_setting ( settings, &setting, buf, len );
01001 }
01002
01003
01004
01005
01006
01007
01008
01009
01010
01011
01012
01013
01014
01015
01016
01017
01018 static int storef_string ( struct settings *settings, struct setting *setting,
01019 const char *value ) {
01020 return store_setting ( settings, setting, value, strlen ( value ) );
01021 }
01022
01023
01024
01025
01026
01027
01028
01029
01030
01031
01032 static int fetchf_string ( struct settings *settings, struct setting *setting,
01033 char *buf, size_t len ) {
01034 return fetch_string_setting ( settings, setting, buf, len );
01035 }
01036
01037
01038 struct setting_type setting_type_string __setting_type = {
01039 .name = "string",
01040 .storef = storef_string,
01041 .fetchf = fetchf_string,
01042 };
01043
01044
01045
01046
01047
01048
01049
01050
01051
01052 static int storef_uristring ( struct settings *settings,
01053 struct setting *setting,
01054 const char *value ) {
01055 char buf[ strlen ( value ) + 1 ];
01056 size_t len;
01057
01058 len = uri_decode ( value, buf, sizeof ( buf ) );
01059 return store_setting ( settings, setting, buf, len );
01060 }
01061
01062
01063
01064
01065
01066
01067
01068
01069
01070
01071 static int fetchf_uristring ( struct settings *settings,
01072 struct setting *setting,
01073 char *buf, size_t len ) {
01074 ssize_t raw_len;
01075
01076
01077
01078
01079 raw_len = fetch_setting ( settings, setting, NULL, 0 );
01080 if ( raw_len < 0 )
01081 return raw_len;
01082
01083 {
01084 char raw_buf[ raw_len + 1 ];
01085
01086 fetch_string_setting ( settings, setting, raw_buf,
01087 sizeof ( raw_buf ) );
01088 return uri_encode ( raw_buf, buf, len, URI_FRAGMENT );
01089 }
01090 }
01091
01092
01093 struct setting_type setting_type_uristring __setting_type = {
01094 .name = "uristring",
01095 .storef = storef_uristring,
01096 .fetchf = fetchf_uristring,
01097 };
01098
01099
01100
01101
01102
01103
01104
01105
01106
01107 static int storef_ipv4 ( struct settings *settings, struct setting *setting,
01108 const char *value ) {
01109 struct in_addr ipv4;
01110
01111 if ( inet_aton ( value, &ipv4 ) == 0 )
01112 return -EINVAL;
01113 return store_setting ( settings, setting, &ipv4, sizeof ( ipv4 ) );
01114 }
01115
01116
01117
01118
01119
01120
01121
01122
01123
01124
01125 static int fetchf_ipv4 ( struct settings *settings, struct setting *setting,
01126 char *buf, size_t len ) {
01127 struct in_addr ipv4;
01128 int raw_len;
01129
01130 if ( ( raw_len = fetch_ipv4_setting ( settings, setting, &ipv4 ) ) < 0)
01131 return raw_len;
01132 return snprintf ( buf, len, "%s", inet_ntoa ( ipv4 ) );
01133 }
01134
01135
01136 struct setting_type setting_type_ipv4 __setting_type = {
01137 .name = "ipv4",
01138 .storef = storef_ipv4,
01139 .fetchf = fetchf_ipv4,
01140 };
01141
01142
01143
01144
01145
01146
01147
01148
01149
01150
01151 static int storef_int ( struct settings *settings, struct setting *setting,
01152 const char *value, unsigned int size ) {
01153 union {
01154 uint32_t num;
01155 uint8_t bytes[4];
01156 } u;
01157 char *endp;
01158
01159 u.num = htonl ( strtoul ( value, &endp, 0 ) );
01160 if ( *endp )
01161 return -EINVAL;
01162 return store_setting ( settings, setting,
01163 &u.bytes[ sizeof ( u ) - size ], size );
01164 }
01165
01166
01167
01168
01169
01170
01171
01172
01173
01174
01175 static int storef_int8 ( struct settings *settings, struct setting *setting,
01176 const char *value ) {
01177 return storef_int ( settings, setting, value, 1 );
01178 }
01179
01180
01181
01182
01183
01184
01185
01186
01187
01188
01189 static int storef_int16 ( struct settings *settings, struct setting *setting,
01190 const char *value ) {
01191 return storef_int ( settings, setting, value, 2 );
01192 }
01193
01194
01195
01196
01197
01198
01199
01200
01201
01202
01203 static int storef_int32 ( struct settings *settings, struct setting *setting,
01204 const char *value ) {
01205 return storef_int ( settings, setting, value, 4 );
01206 }
01207
01208
01209
01210
01211
01212
01213
01214
01215
01216
01217 static int fetchf_int ( struct settings *settings, struct setting *setting,
01218 char *buf, size_t len ) {
01219 long value;
01220 int rc;
01221
01222 if ( ( rc = fetch_int_setting ( settings, setting, &value ) ) < 0 )
01223 return rc;
01224 return snprintf ( buf, len, "%ld", value );
01225 }
01226
01227
01228
01229
01230
01231
01232
01233
01234
01235
01236 static int fetchf_uint ( struct settings *settings, struct setting *setting,
01237 char *buf, size_t len ) {
01238 unsigned long value;
01239 int rc;
01240
01241 if ( ( rc = fetch_uint_setting ( settings, setting, &value ) ) < 0 )
01242 return rc;
01243 return snprintf ( buf, len, "%#lx", value );
01244 }
01245
01246
01247 struct setting_type setting_type_int8 __setting_type = {
01248 .name = "int8",
01249 .storef = storef_int8,
01250 .fetchf = fetchf_int,
01251 };
01252
01253
01254 struct setting_type setting_type_int16 __setting_type = {
01255 .name = "int16",
01256 .storef = storef_int16,
01257 .fetchf = fetchf_int,
01258 };
01259
01260
01261 struct setting_type setting_type_int32 __setting_type = {
01262 .name = "int32",
01263 .storef = storef_int32,
01264 .fetchf = fetchf_int,
01265 };
01266
01267
01268 struct setting_type setting_type_uint8 __setting_type = {
01269 .name = "uint8",
01270 .storef = storef_int8,
01271 .fetchf = fetchf_uint,
01272 };
01273
01274
01275 struct setting_type setting_type_uint16 __setting_type = {
01276 .name = "uint16",
01277 .storef = storef_int16,
01278 .fetchf = fetchf_uint,
01279 };
01280
01281
01282 struct setting_type setting_type_uint32 __setting_type = {
01283 .name = "uint32",
01284 .storef = storef_int32,
01285 .fetchf = fetchf_uint,
01286 };
01287
01288
01289
01290
01291
01292
01293
01294
01295
01296 static int storef_hex ( struct settings *settings, struct setting *setting,
01297 const char *value ) {
01298 char *ptr = ( char * ) value;
01299 uint8_t bytes[ strlen ( value ) ];
01300 unsigned int len = 0;
01301
01302 while ( 1 ) {
01303 bytes[len++] = strtoul ( ptr, &ptr, 16 );
01304 switch ( *ptr ) {
01305 case '\0' :
01306 return store_setting ( settings, setting, bytes, len );
01307 case ':' :
01308 ptr++;
01309 break;
01310 default :
01311 return -EINVAL;
01312 }
01313 }
01314 }
01315
01316
01317
01318
01319
01320
01321
01322
01323
01324
01325 static int fetchf_hex ( struct settings *settings, struct setting *setting,
01326 char *buf, size_t len ) {
01327 int raw_len;
01328 int check_len;
01329 int used = 0;
01330 int i;
01331
01332 raw_len = fetch_setting_len ( settings, setting );
01333 if ( raw_len < 0 )
01334 return raw_len;
01335
01336 {
01337 uint8_t raw[raw_len];
01338
01339 check_len = fetch_setting ( settings, setting, raw,
01340 sizeof ( raw ) );
01341 if ( check_len < 0 )
01342 return check_len;
01343 assert ( check_len == raw_len );
01344
01345 if ( len )
01346 buf[0] = 0;
01347 for ( i = 0 ; i < raw_len ; i++ ) {
01348 used += ssnprintf ( ( buf + used ), ( len - used ),
01349 "%s%02x", ( used ? ":" : "" ),
01350 raw[i] );
01351 }
01352 return used;
01353 }
01354 }
01355
01356
01357 struct setting_type setting_type_hex __setting_type = {
01358 .name = "hex",
01359 .storef = storef_hex,
01360 .fetchf = fetchf_hex,
01361 };
01362
01363
01364
01365
01366
01367
01368
01369
01370
01371 static int storef_uuid ( struct settings *settings __unused,
01372 struct setting *setting __unused,
01373 const char *value __unused ) {
01374 return -ENOTSUP;
01375 }
01376
01377
01378
01379
01380
01381
01382
01383
01384
01385
01386 static int fetchf_uuid ( struct settings *settings, struct setting *setting,
01387 char *buf, size_t len ) {
01388 union uuid uuid;
01389 int raw_len;
01390
01391 if ( ( raw_len = fetch_uuid_setting ( settings, setting, &uuid ) ) < 0)
01392 return raw_len;
01393 return snprintf ( buf, len, "%s", uuid_ntoa ( &uuid ) );
01394 }
01395
01396
01397 struct setting_type setting_type_uuid __setting_type = {
01398 .name = "uuid",
01399 .storef = storef_uuid,
01400 .fetchf = fetchf_uuid,
01401 };
01402
01403
01404
01405
01406
01407
01408
01409
01410
01411 struct setting hostname_setting __setting = {
01412 .name = "hostname",
01413 .description = "Host name",
01414 .tag = DHCP_HOST_NAME,
01415 .type = &setting_type_string,
01416 };
01417
01418
01419 struct setting filename_setting __setting = {
01420 .name = "filename",
01421 .description = "Boot filename",
01422 .tag = DHCP_BOOTFILE_NAME,
01423 .type = &setting_type_string,
01424 };
01425
01426
01427 struct setting root_path_setting __setting = {
01428 .name = "root-path",
01429 .description = "iSCSI root path",
01430 .tag = DHCP_ROOT_PATH,
01431 .type = &setting_type_string,
01432 };
01433
01434
01435 struct setting username_setting __setting = {
01436 .name = "username",
01437 .description = "User name",
01438 .tag = DHCP_EB_USERNAME,
01439 .type = &setting_type_string,
01440 };
01441
01442
01443 struct setting password_setting __setting = {
01444 .name = "password",
01445 .description = "Password",
01446 .tag = DHCP_EB_PASSWORD,
01447 .type = &setting_type_string,
01448 };
01449
01450
01451 struct setting priority_setting __setting = {
01452 .name = "priority",
01453 .description = "Priority of these settings",
01454 .tag = DHCP_EB_PRIORITY,
01455 .type = &setting_type_int8,
01456 };