]> glassweightruler.freedombox.rocks Git - Ventoy.git/blobdiff - LinuxGUI/Ventoy2Disk/ventoy_gui.c
Add checksum jif
[Ventoy.git] / LinuxGUI / Ventoy2Disk / ventoy_gui.c
index d0c92037562d4dce7e35610b9f237c225fe86c38..a0512187f2959390a559f2a72ca67c1c42a594ea 100644 (file)
@@ -9,9 +9,11 @@
 #include <dirent.h> 
 #include <sys/utsname.h>
 #include <sys/types.h>
+#include <linux/limits.h>
 #include <sys/stat.h>
 #include <sys/fcntl.h>
 #include <sys/mman.h>
+#include "ventoy_json.h"
 
 #define LIB_FLAG_GTK2   (1 << 0)
 #define LIB_FLAG_GTK3   (1 << 1)
 #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)