X-Git-Url: https://glassweightruler.freedombox.rocks/gitweb/Ventoy.git/blobdiff_plain/dd2411d7d47fd72be78802cb28d6f0ef73785e9e..b4bb6efd3c36b1eaaa243cf63d1030001c7079d2:/LinuxGUI/Ventoy2Disk/ventoy_gui.c diff --git a/LinuxGUI/Ventoy2Disk/ventoy_gui.c b/LinuxGUI/Ventoy2Disk/ventoy_gui.c index d0c9203..a051218 100644 --- a/LinuxGUI/Ventoy2Disk/ventoy_gui.c +++ b/LinuxGUI/Ventoy2Disk/ventoy_gui.c @@ -9,9 +9,11 @@ #include #include #include +#include #include #include #include +#include "ventoy_json.h" #define LIB_FLAG_GTK2 (1 << 0) #define LIB_FLAG_GTK3 (1 << 1) @@ -31,6 +33,10 @@ #define LD_CACHE_FILE "/etc/ld.so.cache" #define INT2STR_YN(a) ((a) == 0 ? "NO" : "YES") +static int g_xdg_log = 0; +static int g_xdg_ini = 0; +static char g_log_file[PATH_MAX]; +static char g_ini_file[PATH_MAX]; static char *g_log_buf = NULL; extern char ** environ; @@ -78,7 +84,9 @@ struct cache_file_new (((addr) + __alignof__ (struct cache_file_new) -1) \ & (~(__alignof__ (struct cache_file_new) - 1))) -static void vlog(const char *Fmt, ...) +#define vlog(fmt, args...) ventoy_syslog(0, fmt, ##args) + +void ventoy_syslog(int level, const char *Fmt, ...) { int buflen; char *buf = NULL; @@ -87,6 +95,8 @@ static void vlog(const char *Fmt, ...) time_t stamp; struct tm ttm; FILE *fp; + + (void)level; time(&stamp); localtime_r(&stamp, &ttm); @@ -106,7 +116,7 @@ static void vlog(const char *Fmt, ...) vsnprintf(buf, buflen, Fmt, arg); va_end(arg); - fp = fopen("log.txt", "a+"); + fp = fopen(g_log_file, "a+"); if (fp) { fprintf(fp, "[%04u/%02u/%02u %02u:%02u:%02u] %s", @@ -116,10 +126,12 @@ static void vlog(const char *Fmt, ...) fclose(fp); } + #if 0 printf("[%04u/%02u/%02u %02u:%02u:%02u] %s", ttm.tm_year + 1900, ttm.tm_mon, ttm.tm_mday, ttm.tm_hour, ttm.tm_min, ttm.tm_sec, buf); + #endif } static int is_gtk_env(void) @@ -223,14 +235,14 @@ static int detect_qt_version(int libflag) return 5; } - if (qt4 > 0) + if (qt6 > 0) { - return 4; + return 6; } - if (qt6 > 0) + if (qt4 > 0) { - return 6; + return 4; } return 0; @@ -291,6 +303,58 @@ static int read_pid_cmdline(long pid, char *Buffer, int BufLen) return read_file_1st_line(path, Buffer, BufLen); } +static int is_dir_exist(const char *fmt, ...) +{ + va_list arg; + struct stat st; + char path[4096]; + + va_start(arg, fmt); + vsnprintf(path, sizeof(path), fmt, arg); + va_end(arg); + + memset(&st, 0, sizeof(st)); + if (stat(path, &st) < 0) + { + return 0; + } + + if (st.st_mode & S_IFDIR) + { + return 1; + } + + return 0; +} + +static void touch_new_file(char *filename) +{ + char *pos = NULL; + FILE *fp = NULL; + + if (access(filename, F_OK) == -1) + { + for (pos = filename; *pos; pos++) + { + if (*pos == '/') + { + *pos = 0; + if (!is_dir_exist("%s", filename)) + { + mkdir(filename, 0755); + } + *pos = '/'; + } + } + + fp = fopen(filename, "w+"); + if (fp) + { + fclose(fp); + } + } +} + static int find_exe_path(const char *exe, char *pathbuf, int buflen) { int i; @@ -490,6 +554,7 @@ static int restart_main(int argc, char **argv, char *guiexe) if (envs) { vlog("recover success, argc=%d evecve <%s>\n", j, guiexe); + dump_args("EXECVE", newargv); execve(guiexe, newargv, envs); } else @@ -575,12 +640,36 @@ static int restart_by_pkexec(int argc, char **argv, const char *curpath, const c newargv[j++] = pkexec; newargv[j++] = path; - for (i = 1; i < argc && j < MAX_PARAS - 2; i++) + for (i = 1; i < argc && j < MAX_PARAS; i++) { + if (strcmp(argv[i], "--xdg") == 0) + { + continue; + } newargv[j++] = argv[i]; } - newargv[j++] = create_environ_param(VTOY_ENV_STR, environ); - newargv[j++] = exepara; + + if (j < MAX_PARAS) + { + newargv[j++] = create_environ_param(VTOY_ENV_STR, environ); + } + + if (j < MAX_PARAS) + { + newargv[j++] = exepara; + } + + if (g_xdg_log && j + 1 < MAX_PARAS) + { + newargv[j++] = "-l"; + newargv[j++] = g_log_file; + } + + if (g_xdg_ini && j + 1 < MAX_PARAS) + { + newargv[j++] = "-i"; + newargv[j++] = g_ini_file; + } dump_args("PKEXEC", newargv); execv(pkexec, newargv); @@ -622,7 +711,7 @@ static int ld_cache_lib_check(const char *lib, int *flag) if (((*flag) & LIB_FLAG_QT4) == 0) { - if (strncmp(lib, "libqt4", 6) == 0) + if (strncmp(lib, "libQt4", 6) == 0) { vlog("LIB:<%s>\n", lib); *flag |= LIB_FLAG_QT4; @@ -632,7 +721,7 @@ static int ld_cache_lib_check(const char *lib, int *flag) if (((*flag) & LIB_FLAG_QT5) == 0) { - if (strncmp(lib, "libqt5", 6) == 0) + if (strncmp(lib, "libQt5", 6) == 0) { vlog("LIB:<%s>\n", lib); *flag |= LIB_FLAG_QT5; @@ -642,7 +731,7 @@ static int ld_cache_lib_check(const char *lib, int *flag) if (((*flag) & LIB_FLAG_QT6) == 0) { - if (strncmp(lib, "libqt6", 6) == 0) + if (strncmp(lib, "libQt6", 6) == 0) { vlog("LIB:<%s>\n", lib); *flag |= LIB_FLAG_QT6; @@ -783,8 +872,179 @@ static int parse_ld_cache(int *flag) return 0; } -static int detect_gui_exe_path(const char *curpath, char *pathbuf, int buflen) +static int gui_type_check(VTOY_JSON *pstNode) +{ + FILE *fp = NULL; + const char *env = NULL; + const char *arch = NULL; + const char *srctype = NULL; + const char *srcname = NULL; + const char *condition = NULL; + const char *expression = NULL; + char line[1024]; + + arch = vtoy_json_get_string_ex(pstNode, "arch"); + srctype = vtoy_json_get_string_ex(pstNode, "type"); + srcname = vtoy_json_get_string_ex(pstNode, "name"); + condition = vtoy_json_get_string_ex(pstNode, "condition"); + expression = vtoy_json_get_string_ex(pstNode, "expression"); + + if (srctype == NULL || srcname == NULL || condition == NULL) + { + return 0; + } + + if (arch && NULL == strstr(arch, VTOY_GUI_ARCH)) + { + return 0; + } + + vlog("check <%s> <%s> <%s>\n", srctype, srcname, condition); + + if (strcmp(srctype, "file") == 0) + { + if (access(srcname, F_OK) == -1) + { + return 0; + } + + if (strcmp(condition, "exist") == 0) + { + vlog("File %s exist\n", srcname); + return 1; + } + else if (strcmp(condition, "contains") == 0) + { + fp = fopen(srcname, "r"); + if (fp == NULL) + { + return 0; + } + + while (fgets(line, sizeof(line), fp)) + { + if (strstr(line, expression)) + { + vlog("File %s contains %s\n", srcname, expression); + fclose(fp); + return 1; + } + } + + fclose(fp); + return 0; + } + } + else if (strcmp(srctype, "env") == 0) + { + env = getenv(srcname); + if (env == NULL) + { + return 0; + } + + if (strcmp(condition, "exist") == 0) + { + vlog("env %s exist\n", srcname); + return 1; + } + else if (strcmp(condition, "equal") == 0) + { + if (strcmp(expression, env) == 0) + { + vlog("env %s is %s\n", srcname, env); + return 1; + } + return 0; + } + else if (strcmp(condition, "contains") == 0) + { + if (strstr(env, expression)) + { + vlog("env %s is %s contains %s\n", srcname, env, expression); + return 1; + } + return 0; + } + } + + return 0; +} + +static int read_file_to_buf(const char *FileName, int ExtLen, void **Bufer, int *BufLen) +{ + int FileSize; + FILE *fp = NULL; + void *Data = NULL; + + fp = fopen(FileName, "rb"); + if (fp == NULL) + { + vlog("Failed to open file %s", FileName); + return 1; + } + + fseek(fp, 0, SEEK_END); + FileSize = (int)ftell(fp); + + Data = malloc(FileSize + ExtLen); + if (!Data) + { + fclose(fp); + return 1; + } + + fseek(fp, 0, SEEK_SET); + fread(Data, 1, FileSize, fp); + + fclose(fp); + + *Bufer = Data; + *BufLen = FileSize; + + return 0; +} + +static int distro_check_gui_env(char *type, int len, int *pver) +{ + int size; + int length; + char *pBuf = NULL; + VTOY_JSON *pstNode = NULL; + VTOY_JSON *pstJson = NULL; + + vlog("distro_check_gui_env ...\n"); + + if (access("./tool/distro_gui_type.json", F_OK) == -1) + { + vlog("distro_gui_type.json file not exist\n"); + return 0; + } + + read_file_to_buf("./tool/distro_gui_type.json", 1, (void **)&pBuf, &size); + pBuf[size] = 0; + + pstJson = vtoy_json_create(); + vtoy_json_parse(pstJson, pBuf); + + for (pstNode = pstJson->pstChild; pstNode; pstNode = pstNode->pstNext) + { + if (gui_type_check(pstNode->pstChild)) + { + length = (int)snprintf(type, len, "%s", vtoy_json_get_string_ex(pstNode->pstChild, "gui")); + *pver = type[length - 1] - '0'; + type[length - 1] = 0; + break; + } + } + + vtoy_json_destroy(pstJson); + return pstNode ? 1 : 0; +} + +static int detect_gui_exe_path(int argc, char **argv, const char *curpath, char *pathbuf, int buflen) { + int i; int ret; int ver; int libflag = 0; @@ -792,8 +1052,46 @@ static int detect_gui_exe_path(const char *curpath, char *pathbuf, int buflen) char line[256]; mode_t mode; struct stat filestat; - - if (access("./ventoy_gui_type", F_OK) != -1) + + for (i = 1; i < argc; i++) + { + if (argv[i] && strcmp(argv[i], "--gtk2") == 0) + { + guitype = "gtk"; + ver = 2; + } + else if (argv[i] && strcmp(argv[i], "--gtk3") == 0) + { + guitype = "gtk"; + ver = 3; + } + else if (argv[i] && strcmp(argv[i], "--gtk4") == 0) + { + guitype = "gtk"; + ver = 4; + } + else if (argv[i] && strcmp(argv[i], "--qt4") == 0) + { + guitype = "qt"; + ver = 4; + } + else if (argv[i] && strcmp(argv[i], "--qt5") == 0) + { + guitype = "qt"; + ver = 5; + } + else if (argv[i] && strcmp(argv[i], "--qt6") == 0) + { + guitype = "qt"; + ver = 6; + } + } + + if (guitype) + { + vlog("Get GUI type from param <%s%d>.\n", guitype, ver); + } + else if (access("./ventoy_gui_type", F_OK) != -1) { vlog("Get GUI type from ventoy_gui_type file.\n"); @@ -860,7 +1158,12 @@ static int detect_gui_exe_path(const char *curpath, char *pathbuf, int buflen) } else if ((LIB_FLAG_GTK & libflag) > 0 && (LIB_FLAG_QT & libflag) > 0) { - if (is_gtk_env()) + if (distro_check_gui_env(line, sizeof(line), &ver)) + { + guitype = line; + vlog("distro_check_gui <%s%d> ...\n", line, ver); + } + else if (is_gtk_env()) { guitype = "gtk"; ver = detect_gtk_version(libflag); @@ -872,8 +1175,9 @@ static int detect_gui_exe_path(const char *curpath, char *pathbuf, int buflen) } else { - vlog("Current X environment is NOT supported.\n"); - return 1; + vlog("Can not distinguish GTK and QT, default use GTK.\n"); + guitype = "gtk"; + ver = detect_gtk_version(libflag); } } else @@ -928,6 +1232,7 @@ int real_main(int argc, char **argv) vlog("=============== VentoyGui %s ===============\n", VTOY_GUI_ARCH); vlog("=========================================================\n"); vlog("=========================================================\n"); + vlog("log file is <%s>\n", g_log_file); euid = geteuid(); getcwd(curpath, sizeof(curpath)); @@ -960,7 +1265,7 @@ int real_main(int argc, char **argv) return 1; } - if (detect_gui_exe_path(curpath, path, sizeof(path))) + if (detect_gui_exe_path(argc, argv, curpath, path, sizeof(path))) { return 1; } @@ -969,7 +1274,6 @@ int real_main(int argc, char **argv) { vlog("We have root privileges, just exec %s\n", path); argv[0] = path; - argv[1] = NULL; execv(argv[0], argv); } else @@ -989,7 +1293,61 @@ int real_main(int argc, char **argv) int main(int argc, char **argv) { + int i; int ret; + const char *env = NULL; + + snprintf(g_log_file, sizeof(g_log_file), "log.txt"); + for (i = 0; i < argc; i++) + { + if (argv[i] && argv[i + 1] && strcmp(argv[i], "-l") == 0) + { + touch_new_file(argv[i + 1]); + snprintf(g_log_file, sizeof(g_log_file), "%s", argv[i + 1]); + } + else if (argv[i] && argv[i + 1] && strcmp(argv[i], "-i") == 0) + { + touch_new_file(argv[i + 1]); + } + else if (argv[i] && strcmp(argv[i], "--xdg") == 0) + { + env = getenv("XDG_CACHE_HOME"); + if (env) + { + g_xdg_log = 1; + snprintf(g_log_file, sizeof(g_log_file), "%s/ventoy/ventoy.log", env); + touch_new_file(g_log_file); + } + else + { + env = getenv("HOME"); + if (env && is_dir_exist("%s/.cache", env)) + { + g_xdg_log = 1; + snprintf(g_log_file, sizeof(g_log_file), "%s/.cache/ventoy/ventoy.log", env); + touch_new_file(g_log_file); + } + } + + env = getenv("XDG_CONFIG_HOME"); + if (env) + { + g_xdg_ini = 1; + snprintf(g_ini_file, sizeof(g_ini_file), "%s/ventoy/Ventoy2Disk.ini", env); + touch_new_file(g_ini_file); + } + else + { + env = getenv("HOME"); + if (env && is_dir_exist("%s/.config", env)) + { + g_xdg_ini = 1; + snprintf(g_ini_file, sizeof(g_ini_file), "%s/.config/ventoy/Ventoy2Disk.ini", env); + touch_new_file(g_ini_file); + } + } + } + } g_log_buf = malloc(MAX_LOG_BUF); if (!g_log_buf)