#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;
(((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;
time_t stamp;
struct tm ttm;
FILE *fp;
+
+ (void)level;
time(&stamp);
localtime_r(&stamp, &ttm);
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",
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)
return 5;
}
- if (qt4 > 0)
+ if (qt6 > 0)
{
- return 4;
+ return 6;
}
- if (qt6 > 0)
+ if (qt4 > 0)
{
- return 6;
+ return 4;
}
return 0;
if (envs)
{
vlog("recover success, argc=%d evecve <%s>\n", j, guiexe);
+ dump_args("EXECVE", newargv);
execve(guiexe, newargv, envs);
}
else
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);
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;
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;
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;
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;
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");
}
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);
}
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
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));
return 1;
}
- if (detect_gui_exe_path(curpath, path, sizeof(path)))
+ if (detect_gui_exe_path(argc, argv, curpath, path, sizeof(path)))
{
return 1;
}
{
vlog("We have root privileges, just exec %s\n", path);
argv[0] = path;
- argv[1] = NULL;
execv(argv[0], argv);
}
else
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)
+ {
+ snprintf(g_log_file, sizeof(g_log_file), "%s", argv[i + 1]);
+ break;
+ }
+ 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.log", env);
+ }
+
+ env = getenv("XDG_CONFIG_HOME");
+ if (env)
+ {
+ g_xdg_ini = 1;
+ snprintf(g_ini_file, sizeof(g_ini_file), "%s/Ventoy2Disk.ini", env);
+ }
+ }
+ }
g_log_buf = malloc(MAX_LOG_BUF);
if (!g_log_buf)