diff --git a/README.md b/README.md deleted file mode 100644 index 6ffa4c0..0000000 --- a/README.md +++ /dev/null @@ -1,2 +0,0 @@ -# reptile - diff --git a/doc/45c3058a738bf0f2646d09ca34b12a2.png b/doc/45c3058a738bf0f2646d09ca34b12a2.png new file mode 100644 index 0000000..deea775 Binary files /dev/null and b/doc/45c3058a738bf0f2646d09ca34b12a2.png differ diff --git a/doc/README.md b/doc/README.md new file mode 100644 index 0000000..5b3aca3 --- /dev/null +++ b/doc/README.md @@ -0,0 +1,91 @@ +# reptile +# **scripts 目录** + +* kconfig目录(这里只列举核心文件的功能) + + * lxdialog目录 + + * .pc目录 + + * patches目录 + + * check.sh + + * 用于检查系统是否支持国际化(gettext)功能 + + * conf.c、confdata.c、config.sh、mconf.c、nconf.c等 + + * 用于配置管理,构建系统或内核配置 + + * expr.c + + * 用于处理配置表达式的C语言程序 + + * gconf.c + + * 基于GTK+的图形化配置工具(gkc),用于管理和配置Linux内核或其他类似项目的配置选项 + + * image.c + + * 定义了一系列的XPM(X PixMap)图像数据,主要用于表示图形用户界面中的图标和图像。每个图像都使用数组形式存储,图像的数据格式是以文本形式表示的像素颜色和形状。 + + * kxgettext.c + + * 实现了一个用于国际化(i18n)支持的消息处理系统,主要功能包括创建、查找、存储和打印消息,处理消息的转义和格式化,以适应多语言环境的需求。 + + * menu.c + + * 菜单配置,包括其功能、使用方式、涉及的技术细节及操作提示 + + * util.c + + * 提供了有效的内存管理和字符串处理功能 + + * merge\_config.sh(核心) + + * 合并多个配置片段,生成一个最终的 .config 文件,并在过程中提供对重定义值的警告以及检查缺失的依赖项。 + + * 存放补丁代码 + + * 总的来说,kconfig用来配置内核,它就是各种配置界面的源文件,内核的配置工具读取各个kconfig文件,生成配置界面供开发人员配置内核,最后生成配置文件.config + +* lib目录 + + * Unescape.pm文件 + + * 提供了一个名为 unescape 的函数,用于将 Perl 中的转义字符转换为相应的字符。例如,字符串 '\t\c@\x41\n' 将被转换为实际的制表符、控制字符、十六进制字符和换行符。 + +* bashrc + + * 设置交互式 shell 的环境 + + * 配置终端设置、颜色提示以及对 ls、grep 等命令的别名 + + * 包括检查以确保用户不是 root,暗示该项目设计为非特权操作以避免被检测。 + +* destringify.pl( Perl 脚本) + + * 用于处理输入以反转义字符串并将其翻译为类似 C 的语法 + + * 忽略包含 asm、include 和 \_\_attribute\_\_ 等关键字的行,避免干扰实际的代码段 + + * 将字符串字面量翻译为适合嵌入 C 程序的格式,利于二进制注入或操作 + +* installer.sh + + * 负责安装 Reptile 项目,创建目录并复制必要的文件 + +* random.sh + + * 生成两个随机的十六进制数(4 字节),并将这些值以 AUTH 和 HTUA 的形式写入指定的配置文件中 + +* rule + + * 内容:ACTION=="add", ENV{MAJOR}=="1", ENV{MINOR}=="8", RUN+="/lib/udev/reptile" + + * 这条 udev 规则的功能是:当一个主设备号为 1,次设备号为 8 的设备被添加到系统时,系统将执行 /lib/udev/reptile 这个程序或脚本。 + +* start + + * 全文被注释 + diff --git a/src/Reptile/scripts/kconfig/conf.c b/src/Reptile/scripts/kconfig/conf.c index 6780bd3..4c2cc51 100644 --- a/src/Reptile/scripts/kconfig/conf.c +++ b/src/Reptile/scripts/kconfig/conf.c @@ -3,265 +3,306 @@ * Released under the terms of the GNU GPL v2.0. */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "lkc.h" - -static void conf(struct menu *menu); -static void check_conf(struct menu *menu); -static void xfgets(char *str, int size, FILE *in); - +#include // 引入本地化相关功能的头文件 +#include // 引入字符处理函数的头文件,例如 isspace、isdigit 等 +#include // 引入标准输入输出库 +#include // 引入标准库,提供内存管理、程序退出等功能 +#include // 引入字符串处理函数库 +#include // 引入时间日期相关函数 +#include // 引入 Unix 系统 API,提供与系统交互的功能 +#include // 引入命令行参数解析函数 +#include // 引入文件状态函数 +#include // 引入时间管理函数 +#include // 引入错误码定义 +#include "lkc.h" // 引入项目自定义的头文件 + +// 函数声明 +static void conf(struct menu *menu); // 配置函数 +static void check_conf(struct menu *menu); // 检查配置函数 +static void xfgets(char *str, int size, FILE *in); // 自定义的 fgets 函数 + +// 定义输入模式枚举类型 enum input_mode { - oldaskconfig, - silentoldconfig, - oldconfig, - allnoconfig, - allyesconfig, - allmodconfig, - alldefconfig, - randconfig, - defconfig, - savedefconfig, - listnewconfig, - olddefconfig, -} input_mode = oldaskconfig; - -static int indent = 1; -static int tty_stdio; -static int valid_stdin = 1; -static int sync_kconfig; -static int conf_cnt; -static char line[128]; -static struct menu *rootEntry; - + oldaskconfig, // 用户交互模式 + silentoldconfig, // 无用户交互模式,使用默认值 + oldconfig, // 使用旧的配置 + allnoconfig, // 所有选项都为 no + allyesconfig, // 所有选项都为 yes + allmodconfig, // 所有选项都为模块 + alldefconfig, // 所有选项都为默认值 + randconfig, // 随机配置 + defconfig, // 使用默认配置 + savedefconfig, // 保存默认配置 + listnewconfig, // 列出新的配置项 + olddefconfig, // 使用旧的默认配置 +} input_mode = oldaskconfig; // 设置默认输入模式为 oldaskconfig + +// 静态变量声明 +static int indent = 1; // 配置输出时的缩进级别 +static int tty_stdio; // 标识标准输入输出是否是终端设备 +static int valid_stdin = 1; // 标识标准输入是否有效 +static int sync_kconfig; // 同步配置标志 +static int conf_cnt; // 配置项计数器 +static char line[128]; // 用于存储输入行的缓冲区 +static struct menu *rootEntry; // 配置菜单的根节点指针 + +// 打印帮助信息 static void print_help(struct menu *menu) { - struct gstr help = str_new(); + struct gstr help = str_new(); // 创建一个新的字符串对象 - menu_get_ext_help(menu, &help); + menu_get_ext_help(menu, &help); // 获取菜单项的扩展帮助信息 - printf("\n%s\n", str_get(&help)); - str_free(&help); + printf("\n%s\n", str_get(&help)); // 打印帮助信息 + str_free(&help); // 释放帮助字符串资源 } +// 去除字符串两端的空白字符 static void strip(char *str) { - char *p = str; - int l; - - while ((isspace(*p))) - p++; - l = strlen(p); - if (p != str) - memmove(str, p, l + 1); - if (!l) - return; - p = str + l - 1; - while ((isspace(*p))) - *p-- = 0; + char *p = str; + int l; + + // 跳过前导空格 + while ((isspace(*p))) + p++; + + l = strlen(p); // 获取字符串的长度 + if (p != str) // 如果有前导空格,移动字符串内容 + memmove(str, p, l + 1); + + if (!l) // 如果字符串为空,返回 + return; + + // 去除尾部空格 + p = str + l - 1; + while ((isspace(*p))) // 从字符串末尾向前查找空格并去除 + *p-- = 0; } +// 检查标准输入是否有效 static void check_stdin(void) { - if (!valid_stdin) { - printf(_("aborted!\n\n")); - printf(_("Console input/output is redirected. ")); - printf(_("Run 'make oldconfig' to update configuration.\n\n")); - exit(1); - } + if (!valid_stdin) { // 如果标准输入无效 + printf(_("aborted!\n\n")); + printf(_("Console input/output is redirected. ")); + printf(_("Run 'make oldconfig' to update configuration.\n\n")); + exit(1); // 退出程序 + } } +// 配置选项的处理函数 static int conf_askvalue(struct symbol *sym, const char *def) { - enum symbol_type type = sym_get_type(sym); - - if (!sym_has_value(sym)) - printf(_("(NEW) ")); - - line[0] = '\n'; - line[1] = 0; - - if (!sym_is_changable(sym)) { - printf("%s\n", def); - line[0] = '\n'; - line[1] = 0; - return 0; - } - - switch (input_mode) { - case oldconfig: - case silentoldconfig: - if (sym_has_value(sym)) { - printf("%s\n", def); - return 0; - } - check_stdin(); - /* fall through */ - case oldaskconfig: - fflush(stdout); - xfgets(line, 128, stdin); - if (!tty_stdio) - printf("\n"); - return 1; - default: - break; - } - - switch (type) { - case S_INT: - case S_HEX: - case S_STRING: - printf("%s\n", def); - return 1; - default: - ; - } - printf("%s", line); - return 1; + enum symbol_type type = sym_get_type(sym); // 获取符号的类型 + + if (!sym_has_value(sym)) // 如果没有值,标记为新选项 + printf(_("(NEW) ")); + + line[0] = '\n'; + line[1] = 0; + + if (!sym_is_changable(sym)) { // 如果符号不可修改,直接输出默认值 + printf("%s\n", def); + line[0] = '\n'; + line[1] = 0; + return 0; + } + + // 根据输入模式不同执行不同的操作 + switch (input_mode) { + case oldconfig: + case silentoldconfig: + if (sym_has_value(sym)) { // 如果已有值,直接输出默认值 + printf("%s\n", def); + return 0; + } + check_stdin(); // 检查标准输入有效性 + /* fall through */ + case oldaskconfig: + fflush(stdout); // 刷新标准输出缓冲区 + xfgets(line, 128, stdin); // 获取用户输入 + if (!tty_stdio) // 如果标准输入不是终端,换行 + printf("\n"); + return 1; + default: + break; + } + + // 根据符号类型进行处理 + switch (type) { + case S_INT: + case S_HEX: + case S_STRING: + printf("%s\n", def); + return 1; + default: + ; + } + printf("%s", line); // 输出用户输入的内容 + return 1; } +// 配置字符串类型的处理函数 static int conf_string(struct menu *menu) { - struct symbol *sym = menu->sym; - const char *def; - - while (1) { - printf("%*s%s ", indent - 1, "", _(menu->prompt->text)); - printf("(%s) ", sym->name); - def = sym_get_string_value(sym); - if (sym_get_string_value(sym)) - printf("[%s] ", def); - if (!conf_askvalue(sym, def)) - return 0; - switch (line[0]) { - case '\n': - break; - case '?': - /* print help */ - if (line[1] == '\n') { - print_help(menu); - def = NULL; - break; - } - /* fall through */ - default: - line[strlen(line)-1] = 0; - def = line; - } - if (def && sym_set_string_value(sym, def)) - return 0; - } + struct symbol *sym = menu->sym; + const char *def; + + while (1) { + printf("%*s%s ", indent - 1, "", _(menu->prompt->text)); // 打印菜单提示 + printf("(%s) ", sym->name); // 打印符号名称 + def = sym_get_string_value(sym); // 获取符号的默认字符串值 + if (def) // 如果有默认值,打印出来 + printf("[%s] ", def); + if (!conf_askvalue(sym, def)) // 获取用户输入并处理 + return 0; + + // 根据用户输入的内容进行处理 + switch (line[0]) { + case '\n': + break; // 如果用户没有输入内容,继续 + case '?': + // 打印帮助信息 + if (line[1] == '\n') { + print_help(menu); // 打印帮助 + def = NULL; + break; + } + /* fall through */ + default: + line[strlen(line) - 1] = 0; // 去掉换行符 + def = line; // 将用户输入的内容赋给 def + } + + // 设置符号的字符串值 + if (def && sym_set_string_value(sym, def)) + return 0; + } } + +// 配置符号的值(如:yes、no、mod)的函数 static int conf_sym(struct menu *menu) { - struct symbol *sym = menu->sym; - tristate oldval, newval; + struct symbol *sym = menu->sym; // 获取菜单项的符号 + tristate oldval, newval; // 旧值和新值变量,tristate表示三种状态(yes、no、mod) + + while (1) { + // 打印菜单提示信息,包括符号名称(如果存在) + printf("%*s%s ", indent - 1, "", _(menu->prompt->text)); // 打印缩进和提示文本 + if (sym->name) // 如果符号有名称,打印符号名称 + printf("(%s) ", sym->name); + + putchar('['); // 打印开头的方括号 + oldval = sym_get_tristate_value(sym); // 获取符号的当前值 + + // 根据当前的状态值(oldval),打印相应的字符 + switch (oldval) { + case no: + putchar('N'); // 输出 'N' 表示当前为 no + break; + case mod: + putchar('M'); // 输出 'M' 表示当前为 mod + break; + case yes: + putchar('Y'); // 输出 'Y' 表示当前为 yes + break; + } + + // 根据当前的状态值,显示可选的值(no、mod、yes),如果符号的值在范围内 + if (oldval != no && sym_tristate_within_range(sym, no)) + printf("/n"); + if (oldval != mod && sym_tristate_within_range(sym, mod)) + printf("/m"); + if (oldval != yes && sym_tristate_within_range(sym, yes)) + printf("/y"); + + // 如果菜单项有帮助信息,显示帮助提示 + if (menu_has_help(menu)) + printf("/?"); + + printf("] "); // 打印结束的方括号 + // 询问用户输入新值,如果没有输入有效值,返回 0 + if (!conf_askvalue(sym, sym_get_string_value(sym))) + return 0; + + strip(line); // 去除用户输入的字符串两端空格 + + // 根据用户输入的值进行处理 + switch (line[0]) { + case 'n': + case 'N': // 如果输入是 'n' 或 'N',设置新值为 no + newval = no; + if (!line[1] || !strcmp(&line[1], "o")) + break; + continue; // 如果有其他字符,继续下一次循环 + case 'm': + case 'M': // 如果输入是 'm' 或 'M',设置新值为 mod + newval = mod; + if (!line[1]) + break; + continue; // 如果有其他字符,继续下一次循环 + case 'y': + case 'Y': // 如果输入是 'y' 或 'Y',设置新值为 yes + newval = yes; + if (!line[1] || !strcmp(&line[1], "es")) + break; + continue; // 如果有其他字符,继续下一次循环 + case 0: // 如果没有输入内容,保留旧值 + newval = oldval; + break; + case '?': // 如果输入是 '?',显示帮助 + goto help; + default: + continue; // 继续循环,直到输入合法 + } + + // 设置符号的新值 + if (sym_set_tristate_value(sym, newval)) + return 0; // 如果设置失败,返回 0 - while (1) { - printf("%*s%s ", indent - 1, "", _(menu->prompt->text)); - if (sym->name) - printf("(%s) ", sym->name); - putchar('['); - oldval = sym_get_tristate_value(sym); - switch (oldval) { - case no: - putchar('N'); - break; - case mod: - putchar('M'); - break; - case yes: - putchar('Y'); - break; - } - if (oldval != no && sym_tristate_within_range(sym, no)) - printf("/n"); - if (oldval != mod && sym_tristate_within_range(sym, mod)) - printf("/m"); - if (oldval != yes && sym_tristate_within_range(sym, yes)) - printf("/y"); - if (menu_has_help(menu)) - printf("/?"); - printf("] "); - if (!conf_askvalue(sym, sym_get_string_value(sym))) - return 0; - strip(line); - - switch (line[0]) { - case 'n': - case 'N': - newval = no; - if (!line[1] || !strcmp(&line[1], "o")) - break; - continue; - case 'm': - case 'M': - newval = mod; - if (!line[1]) - break; - continue; - case 'y': - case 'Y': - newval = yes; - if (!line[1] || !strcmp(&line[1], "es")) - break; - continue; - case 0: - newval = oldval; - break; - case '?': - goto help; - default: - continue; - } - if (sym_set_tristate_value(sym, newval)) - return 0; help: - print_help(menu); - } + print_help(menu); // 打印帮助信息 + } } +// 配置选择菜单项的函数 static int conf_choice(struct menu *menu) { - struct symbol *sym, *def_sym; - struct menu *child; - bool is_new; - - sym = menu->sym; - is_new = !sym_has_value(sym); - if (sym_is_changable(sym)) { - conf_sym(menu); - sym_calc_value(sym); - switch (sym_get_tristate_value(sym)) { - case no: - return 1; - case mod: - return 0; - case yes: - break; - } - } else { - switch (sym_get_tristate_value(sym)) { - case no: - return 1; - case mod: - printf("%*s%s\n", indent - 1, "", _(menu_get_prompt(menu))); - return 0; - case yes: - break; - } - } + struct symbol *sym, *def_sym; + struct menu *child; + bool is_new; + + sym = menu->sym; // 获取当前菜单项的符号 + is_new = !sym_has_value(sym); // 检查符号是否有值(是否为新符号) + + // 如果符号可修改,进行符号的配置 + if (sym_is_changable(sym)) { + conf_sym(menu); // 调用 conf_sym 函数配置符号 + sym_calc_value(sym); // 计算符号的值 + + // 根据符号的值执行不同的操作 + switch (sym_get_tristate_value(sym)) { + case no: // 如果值是 no,返回 1 + return 1; + case mod: // 如果值是 mod,返回 0 + return 0; + case yes: // 如果值是 yes,继续执行 + break; + } + } else { // 如果符号不可修改 + switch (sym_get_tristate_value(sym)) { + case no: // 如果值是 no,返回 1 + return 1; + case mod: // 如果值是 mod,打印菜单提示并返回 0 + printf("%*s%s\n", indent - 1, "", _(menu_get_prompt(menu))); + return 0; + case yes: // 如果值是 yes,继续执行 + break; + } + } +} while (1) { int cnt, def;