uci 命令、shell接口、API接口

uci 命令:

uci help:

Usage: uci [<options>]<command> [<arguments>]

 

Commands:

       batch

       export     [<config>]                           導出配置文件

       import     [<config>]                           以uci語法導入配置文件

       changes    [<config>]                       列出配置文件分階段修改的內容(沒有commit),若未指定配置文件,則導出所有配置文件的修改

       commit     [<config>]                        對給定的配置文件寫入修改,如果沒有指定參數則將所有的配置文件寫入文件系統

       add        <config><section-type>                                      增加指定配置文件的類型爲section-type的匿名區段

       add_list  <config>.<section>.<option>=<string>           對已存在的list選項增加字符串

       del_list  <config>.<section>.<option>=<string>             刪除已存在的list選項的字符串

       show      [<config>[.<section>[.<option>]]]                      顯示指定的選項、配置節或配置文件

       get       <config>.<section>[.<option>]                            獲取指定區段選項的值

       set        <config>.<section>[.<option>]=<value>           設置指定配置節選項的值,或者是增加一個配置節,類型設置爲指定的值

       delete    <config>[.<section>[[.<option>][=<id>]]]          刪除指定配置節或選項

       rename    <config>.<section>[.<option>]=<name>      對指定的選項或配置節重命名

       revert    <config>[.<section>[.<option>]]                        恢復指定的選項,配置節或配置文件

       reorder   <config>.<section>=<position>

 

Options:

       -c <path>             設置配置文件的搜索路徑 (default: /etc/config)

       -d <str>                在uci顯示中設置列表值的分隔符 in uci show

       -f <file>                使用<file>作爲輸入,而不是stdin

       -m                        導入時,將數據合併到現有包中

       -n                         名稱未命名部分導出(默認)

       -N                        不要命名unname dsections

       -p <path>            添加配置更改文件的搜索路徑

       -P <path>          添加配置更改文件的搜索路徑,並使用默認值

       -q                       安靜模式(不打印錯誤信息)

       -s                       強制嚴格模式(停止解析器錯誤,默認)

       -S                       停止嚴格模式

       -X                       不要在'show'上使用擴展語法


uci shell 接口:

注:以"uci_"開頭的函數和以“config_”開頭的函數大多數功能完全相同,唯一不同的是uci_get等函數直接從文件中獲取,“config_get”函數從環境變量中讀取

/lib/config/uci.sh

#參考對應的命令實現

uci_load              #從uci文件中加載配置並設置到環境變量中

uci_set_default

uci_revert_state

uci_set_state()

uci_toggle_state

uci_set

uci_get_state      #指定從/var/state中獲取狀態值

uci_get                #從uci文件中獲取值

uci_add

uci_rename

uci_remove

uci_commit


/lib/functions.sh

注意:在使用“config_”開頭的函數時要先使用config_load,將配置文件載入環境變量


#在字符串前加‘:’並返回“:123”
w=debug  123
echo $w
輸出:":123"


config 
#將配置節設置到環境變量中,供uci.sh調用
option 
#將配置節中的選項設置到環境變量中,供uci.sh調用
list
#將配置節中的鏈表設置到環境變量中,供uci.sh調用


#config_unset

#調用config_set 清空<section>.<option>的value值
#config_unset <section> <option>


#config_load:  調用uci_load函數從配置文件中讀取配置然後設置到環境變量中
config_load <config>


#config_get:從當前環境變量中獲取配置值
# variable:用來存儲config值的變量
#section/option:要獲取節點/選項的名字
config_get <variable>  <section>  <option> [<default>]

#config_get_bool:從當前環境變量中獲取配置值 ,並把值轉換成整數
config_get_bool <variable> <section> <option> [<default>]

#config_set:將變量設置到環境變量中以便後續讀取(注:並未設置到配置文件中)
#section/option
#value:要爲該節點設置的值
config_set  <section> <option> <value>


#config_foreach:遍歷每個section去調用callback_func函數(callback_func 的入參爲section name)
#[<section type>]:只遍歷這個類型的section......
config_foreach  <callback_func> [<section type>]


#config_list_foreach:遍歷section下list的option值,並調用callback_func函數(入參爲list option的值,有多少值調用多少次)
config_list_foreach <section> <list> <callback_func>


#加載/etc/modus.d/*下面的所有模塊
insert_modules

#應用shell腳本
include <shell script> [<shell script>......]

append

list_contains

reset_cb

package

default_prerm

default_postinst

find_mtd_index

find_mtd_part

group_add

group_exists

group_add_next

group_add_user

user_add

user_exists



uci重要的結構體:

struct uci_context
{
/* list of config packages */
struct uci_list root;


/* parser context, use for error handling only */
struct uci_parse_context *pctx;


/* backend for import and export */
struct uci_backend *backend;
struct uci_list backends;


/* uci runtime flags */
enum uci_flags flags;


char *confdir;
char *savedir;


/* search path for delta files */
struct uci_list delta_path;


/* private: */
int err;
const char *func;
jmp_buf trap;
bool internal, nested;
char *buf;
int bufsz;
};

uci_context:uci上下文結構,貫徹查詢、更改配置文件全過程


struct uci_package
{
struct uci_element e;
struct uci_list sections;
struct uci_context *ctx;
bool has_delta;
char *path;


/* private: */
struct uci_backend *backend;
void *priv;
int n_section;
struct uci_list delta;
struct uci_list saved_delta;
};
uci_package:對應一個配置文件

struct uci_section
{
struct uci_element e;
struct uci_list options;
struct uci_package *package;
bool anonymous;
char *type;
};
uci_section:對應配置文件中的節

struct uci_option
{
struct uci_element e;
struct uci_section *section;
enum uci_option_type type;
union {
struct uci_list list;
char *string;
} v;
};

uci_option:對應配置文件節中的option和list

struct uci_ptr
{
enum uci_type target;
enum {
UCI_LOOKUP_DONE =     (1 << 0),
UCI_LOOKUP_COMPLETE = (1 << 1),
UCI_LOOKUP_EXTENDED = (1 << 2),
} flags;


struct uci_package *p;
struct uci_section *s;
struct uci_option *o;
struct uci_element *last;


const char *package;
const char *section;
const char *option;
const char *value;
};

uci_ptr:元素位置指針結構,用以查詢並保存對應的位置元素

uci API:

/usr/local/include/uci.h

/**

 *uci_alloc_context: Allocate a new uci context

*動態申請一塊內存用於struct uci_context結構。

 */

extern struct uci_context * uci_alloc_context(void);

/**

 *uci_alloc_alternate_context: Allocate new uci context with specific default

 */

extern struct uci_context*uci_alloc_alternate_context(const char *confdir, const char *savedir);

 

/**

 *uci_free_context: Free the uci context including all of its data

*釋放struct uci_context結構內存,以及爲其成員申請的所有內存

 */

extern void uci_free_context(structuci_context *ctx);

 

/**

 *uci_perror: Print the last uci error that occured

 *@ctx: uci context

 *@str: string to print before the error message

*打印最後一條出錯信息,如果在打印出錯信息前想打印其他信息,則傳入str即可

 */

extern void uci_perror(struct uci_context*ctx, const char *str);

/**

 *uci_geterror: Get an error string for the last uci error

*獲取最後一個uci錯誤的錯誤字符串

 *@ctx: uci context

 *@dest: target pointer for the string

 *@str: prefix for the error message

 *

 *Note: string must be freed by the caller

 */

extern void uci_get_errorstr(structuci_context *ctx, char **dest, const char *str);


/**

 *uci_import: Import uci config data from a stream

*從文件流中導入uci的配置數據

 *@ctx: uci context

 *@stream: file stream to import from

 *@name: (optional) assume the config has the given name

 *@package: (optional) store the last parsed config package in this variable

 *@single: ignore the 'package' keyword and parse everything into a singlepackage

 *

 *the name parameter is for config files that don't explicitly use the 'package<...>' keyword

 * if'package' points to a non-null struct pointer, enable delta tracking and merge

 */

extern int uci_import(struct uci_context * ctx, FILE * stream, const char  *name, struct uci_package  **package, boolsingle);

/**

 *uci_export: Export one or all uci config packages

*導出uci的配置文件數據到文件流stream

 *@ctx: uci context

 *@stream: output stream

 *@package: (optional) uci config package to export

 *@header: include the package header

 */

extern int uci_export(struct uci_context*ctx, FILE *stream, struct uci_package *package, bool header);


/**

 *uci_load: Parse an uci config file and store it in the uci context

 *解析一個uci配置文件並把它存到ctx中

 *@ctx: uci context

 *@name: name of the config file (relative to the config directory)

 *@package: store the loaded config package in this variable

 */

extern int uci_load(struct uci_context*ctx, const char *name, struct uci_package **package);


/**

 *uci_unload: Unload a config file from the uci context

 *從ctx中卸載一個配置文件包

 *@ctx: uci context

 *@package: pointer to the uci_package struct

 */

extern int uci_unload(struct uci_context*ctx, struct uci_package *p);

/**

 *uci_lookup_ptr: Split an uci tuple string and look up an element tree

*分離一個uci類型的字符串元組,且查找對應的元素樹

 *@ctx: uci context

 *@ptr: lookup result struct

 *@str: uci tuple string to look up

 *@extended: allow extended syntax lookup

 *

 * ifextended is set to true, uci_lookup_ptr supports the following

 *extended syntax:

 *

 *Examples:

 *  network.@interface[0].ifname ('ifname' option of the first interfacesection)

 *  network.@interface[-1]       (lastinterface section)

 *Note: uci_lookup_ptr will automatically load a config package if necessary

 *@str must not be constant, as it will be modified and used for the stringsinside @ptr,

 *thus it must also be available as long as @ptr is in use.

 *

 *This function returns UCI_ERR_NOTFOUND if the package specified in the tuple

 *string cannot be found.  Otherwise itwill return UCI_OK.

 *

 *Note that failures in looking up other parts, if they are also specfied,

 *including section and option, will also have a return value UCI_OK but with

 *ptr->flags * UCI_LOOKUP_COMPLETE not set.

 */

extern int uci_lookup_ptr(structuci_context *ctx, struct uci_ptr *ptr, char *str, bool extended);


/**

 *uci_add_section: Add an unnamed section

*添加一個匿名節點

 *@ctx: uci context

 *@p: package to add the section to

 *@type: section type

 *@res: pointer to store a reference to the new section in

 */

extern int uci_add_section(structuci_context *ctx, struct uci_package *p, const char *type, struct uci_section**res);


/**

 *uci_set: Set an element's value; create the element if necessary

*設置一個元素值,必要的話新建這個元素

 *@ctx: uci context

 *@ptr: uci pointer

 *

 *The updated/created element is stored in ptr->last

 */

extern int uci_set(struct uci_context *ctx,struct uci_ptr *ptr);


/**

 *uci_add_list: Append a string to an element list

*附加一個字符串到一個元素列表

 *@ctx: uci context

 *@ptr: uci pointer (with value)

 *

 *Note: if the given option already contains a string value,

 * itwill be converted to an 1-element-list before appending the next element

 */

extern int uci_add_list(struct uci_context*ctx, struct uci_ptr *ptr);

/**

 *uci_del_list: Remove a string from an element list

*從一個元素列表中刪除一個元素

 *@ctx: uci context

 *@ptr: uci pointer (with value)

 *

 */

extern int uci_del_list(struct uci_context*ctx, struct uci_ptr *ptr);


/**

 *uci_reorder: Reposition a section

*改變一個節的(順序)位置

 *@ctx: uci context

 *@s: uci section to reposition

 *@pos: new position in the section list

 */

extern int uci_reorder_section(structuci_context *ctx, struct uci_section *s, int pos);


/**

 *uci_rename: Rename an element

*重命名一個元素

 *@ctx: uci context

 *@ptr: uci pointer (with value)

 */

extern int uci_rename(struct uci_context*ctx, struct uci_ptr *ptr);

/**

 *uci_delete: Delete a section or option

*刪除一個節或選項

 *@ctx: uci context

 *@ptr: uci pointer

 */

extern int uci_delete(struct uci_context*ctx, struct uci_ptr *ptr);


/**

 *uci_save: save change delta for a package

*爲一個package保存改變的delta

 *@ctx: uci context

 *@p: uci_package struct

 */

extern int uci_save(struct uci_context*ctx, struct uci_package *p);

/**

 *uci_commit: commit changes to a package

*提交改動到一個package

 *@ctx: uci context

 *@p: uci_package struct pointer

 *@overwrite: overwrite existing config data and flush delta

 *

 *committing may reload the whole uci_package data,

 *the supplied pointer is updated accordingly

 */

extern int uci_commit(struct uci_context*ctx, struct uci_package **p, bool overwrite);

/**

 *uci_list_configs: List available uci config files

*列出可用的uci配置文件

 *@ctx: uci context

 *

 *caller is responsible for freeing the allocated memory behind list

 */

extern int uci_list_configs(structuci_context *ctx, char ***list);


/**

 *uci_set_savedir: override the default delta save directory

*覆蓋默認的delta保存的目錄

 *@ctx: uci context

 *@dir: directory name

 *

 *This will also try adding the specified dir to the end of delta pathes.

 */

extern int uci_set_savedir(structuci_context *ctx, const char *dir);

/**

 *uci_set_confdir: override the default config storage directory

*覆蓋默認的配置文件存儲目錄

 *@ctx: uci context

 *@dir: directory name

 */

extern int uci_set_confdir(structuci_context *ctx, const char *dir);

/**

 *uci_add_delta_path: add a directory to the search path for change delta files

*爲detal文件添加一個目錄到搜索路徑

 *@ctx: uci context

 *@dir: directory name

 *

 *This function allows you to add directories, which contain 'overlays'

 *for the active config, that will never be committed.

 *

 *Adding a duplicate directory will cause UCI_ERR_DUPLICATE be returned.

 */

extern int uci_add_delta_path(structuci_context *ctx, const char *dir);

/**

 *uci_revert: revert all changes to a config item

*恢復一個配置項的所有變更

 *@ctx: uci context

 *@ptr: uci pointer

 */

extern int uci_revert(struct uci_context*ctx, struct uci_ptr *ptr);

/**

 *uci_parse_argument: parse a shell-style argument, with an arbitrary quotingstyle

*解析一個shell風格的參數

 *@ctx: uci context

 *@stream: input stream

 *@str: pointer to the current line (use NULL for parsing the next line)

 *@result: pointer for the result

 */

extern int uci_parse_argument(structuci_context *ctx, FILE *stream, char **str, char **result);

/**

 *uci_set_backend: change the default backend

 *@ctx: uci context

 *@name: name of the backend

 *

 *The default backend is "file", which uses /etc/config for configstorage

 */

extern int uci_set_backend(structuci_context *ctx, const char *name);

/**

 *uci_validate_text: validate a value string for uci options

*驗證uci options中的一個字符串值

 *@str: value

 *

 *this function checks whether a given string is acceptable as value

 *for uci options

 */

extern bool uci_validate_text(const char*str);

/**

 *uci_parse_ptr: parse a uci string into a uci_ptr

*解析一個uci字符串到uci_prt結構中

 *@ctx: uci context

 *@ptr: target data structure

 *@str: string to parse

 *

 *str is modified by this function

 */

int uci_parse_ptr(struct uci_context *ctx,struct uci_ptr *ptr, char *str);

/**

 * uci_lookup_next:lookup a child element

*查找子元素

 *@ctx: uci context

 *@e: target element pointer

 *@list: list of elements

 *@name: name of the child element

 *

 * ifparent is NULL, the function looks up the package with the given name

 */

int uci_lookup_next(struct uci_context*ctx, struct uci_element **e, struct uci_list *list, const char *name);

/**

 *uci_parse_section: look up a set of options

*查找一組選項

 *@s: uci section

 *@opts: list of options to look up

 *@n_opts: number of options to look up

 *@tb: array of pointers to found options

 */

void uci_parse_section(struct uci_section*s, const struct uci_parse_option *opts,
                                   int n_opts, struct uci_option **tb);

/**

 *uci_hash_options: build a hash over a list of options

*在選項列表上構建一個散列

 *@tb: list of option pointers

 *@n_opts: number of options

 */

uint32_t uci_hash_options(struct uci_option**tb, int n_opts);


/**

 *uci_alloc_element: allocate a generic uci_element, reserve a buffer andtypecast

*分配一個通用的uci_element,保留緩衝區和屬性

 *@ctx: uci context

 *@type: {package,section,option}

 *@name: string containing the name of the element

 *@datasize: additional buffer size to reserve at the end of the struct

 */

#define uci_alloc_element(ctx, type, name,datasize) \
              uci_to_## type (uci_alloc_generic(ctx, uci_type_ ## type, name, sizeof(struct uci_ ##type) + datasize))
 
#define uci_dataptr(ptr) \
              (((char*) ptr) + sizeof(*ptr))

/**

 *uci_lookup_package: look up a package

*查找package

 *@ctx: uci context

 *@name: name of the package

 */

static inline struct uci_package *
uci_lookup_package (struct uci_context *ctx,const char *name)
{
              structuci_element *e = NULL;
              if(uci_lookup_next(ctx, &e, &ctx->root, name) == 0)
                            return uci_to_package(e);
              else
                            return NULL;
}


/**

 *uci_lookup_section: look up a section

*查找section

 *@ctx: uci context

 *@p: package that the section belongs to

 *@name: name of the section

 */

static inline struct uci_section *
uci_lookup_section(struct uci_context *ctx,struct uci_package *p, const char *name)
{
              structuci_element *e = NULL;
              if(uci_lookup_next(ctx, &e, &p->sections, name) == 0)
                            returnuci_to_section(e);
              else
                            returnNULL;
}


/**

 *uci_lookup_option: look up an option

*查找option

 *@ctx: uci context

 *@section: section that the option belongs to

 *@name: name of the option

 */

static inline struct uci_option *
uci_lookup_option(struct uci_context *ctx,struct uci_section *s, const char *name)
{
              structuci_element *e = NULL;
              if(uci_lookup_next(ctx, &e, &s->options, name) == 0)
                            returnuci_to_option(e);
              else
                            returnNULL;
}
 
static inline const char *
uci_lookup_option_string(struct uci_context*ctx, struct uci_section *s, const char *name)
{
              structuci_option *o;
 
              o= uci_lookup_option(ctx, s, name);
              if(!o || o->type != UCI_TYPE_STRING)
                            returnNULL;
 
              returno->v.string;
}

end



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章