]> glassweightruler.freedombox.rocks Git - Ventoy.git/commitdiff
Support BSD style for .md5/.sha1/.sh256/.sha512 checksum file.
authorlongpanda <admin@ventoy.net>
Sat, 31 Dec 2022 16:31:08 +0000 (00:31 +0800)
committerlongpanda <admin@ventoy.net>
Sat, 31 Dec 2022 16:31:08 +0000 (00:31 +0800)
Support VENTOY_CHECKSUM file for checksum file.
(#2112)

GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy.c
GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_cmd.c
GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_def.h
INSTALL/grub/checksum.cfg

index 5242cb0332d0c7834fdcf475b62df8a9aac06a4e..38927df89788b0ed4dbab1c162c2f9ce235e947a 100644 (file)
@@ -115,6 +115,92 @@ int ventoy_str_all_digit(const char *str)
     return 1;
 }
 
+int ventoy_str_all_alnum(const char *str)
+{
+    if (NULL == str || 0 == *str)
+    {
+        return 0;
+    }
+
+    while (*str)
+    {
+        if (!grub_isalnum(*str))
+        {
+            return 0;
+        }
+    }
+
+    return 1;
+}
+
+int ventoy_str_len_alnum(const char *str, int len)
+{
+    int i;
+    int slen;
+    
+    if (NULL == str || 0 == *str)
+    {
+        return 0;
+    }
+
+    slen = grub_strlen(str);
+    if (slen <= len)
+    {
+        return 0;
+    }
+
+    for (i = 0; i < len; i++)
+    {
+        if (!grub_isalnum(str[i]))
+        {
+            return 0;
+        }
+    }
+
+    if (str[len] == 0 || grub_isspace(str[len]))
+    {
+        return 1;
+    }
+
+    return 0;
+}
+
+char * ventoy_str_basename(char *path)
+{
+    char *pos = NULL;
+    
+    pos = grub_strrchr(path, '/');
+    if (pos)
+    {
+        pos++;
+    }
+    else
+    {
+        pos = path;
+    }
+
+    return pos;
+}
+
+int ventoy_str_chrcnt(const char *str, char c)
+{
+    int n = 0;
+    
+    if (str)
+    {
+        while (*str)
+        {
+            if (*str == c)
+            {
+                n++;                
+            }
+            str++;
+        }        
+    }
+
+    return n;
+}
+
 int ventoy_strcmp(const char *pattern, const char *str)
 {
     while (*pattern && *str)
@@ -146,6 +232,14 @@ int ventoy_strncmp (const char *pattern, const char *str, grub_size_t n)
     return (int)(grub_uint8_t)*pattern - (int)(grub_uint8_t)*str;
 }
 
+grub_err_t ventoy_env_int_set(const char *name, int value)
+{
+    char buf[16];
+    
+    grub_snprintf(buf, sizeof(buf), "%d", value);
+    return grub_env_set(name, buf);
+}
+
 void ventoy_debug_dump_guid(const char *prefix, grub_uint8_t *guid)
 {
     int i;
index 22ba948f26cedf76b284dc2272da0d767c49b437..c2c4799cdc3ff58a14b06df24909f607c9a77ffa 100644 (file)
@@ -158,6 +158,8 @@ const char *g_menu_prefix[img_type_max] =
     "iso", "wim", "efi", "img", "vhd", "vtoy"
 };
 
+static const char *g_lower_chksum_name[] = { "md5", "sha1", "sha256", "sha512" };
+
 static int g_vtoy_secondary_need_recover = 0;
 
 static int g_vtoy_load_prompt = 0;
@@ -6292,6 +6294,274 @@ static grub_err_t ventoy_cmd_load_menu_lang(grub_extcmd_context_t ctxt, int argc
     VENTOY_CMD_RETURN(0);
 }
 
+static grub_err_t ventoy_cmd_vtoychksum_exist(grub_extcmd_context_t ctxt, int argc, char **args)
+{
+    int cnt;
+    char c;
+    char *pos = NULL;
+    
+    (void)ctxt;
+    (void)argc;
+
+    cnt = ventoy_str_chrcnt(args[1], '/');
+    if (cnt > 1)
+    {
+        pos = grub_strrchr(args[1], '/');
+        c = *pos;
+        *pos = 0;
+        if (ventoy_check_file_exist("%s%s/VENTOY_CHECKSUM", args[0], args[1]))
+        {
+            VENTOY_CMD_RETURN(GRUB_ERR_NONE);
+        }
+        *pos = c;
+    }
+
+    if (ventoy_check_file_exist("%s/VENTOY_CHECKSUM", args[0]))
+    {
+        VENTOY_CMD_RETURN(GRUB_ERR_NONE);
+    }
+
+    return 1;
+}
+
+static int ventoy_chksum_pathcmp(int chktype, char *rlpath, char *rdpath)
+{
+    char *pos1 = NULL;
+    char *pos2 = NULL;
+
+    if (chktype == 2)
+    {
+        pos1 = ventoy_str_basename(rlpath);
+        pos2 = ventoy_str_basename(rdpath);
+        return grub_strcmp(pos1, pos2);
+    }
+    else if (chktype == 3 || chktype == 4)
+    {
+        if (grub_strcmp(rlpath, rdpath) == 0 || grub_strcmp(rlpath + 1, rdpath) == 0)
+        {
+            return 0;
+        }
+    }
+    
+    return 1;
+}
+
+static int ventoy_find_checksum
+(
+    grub_file_t file, 
+    const char *uname, 
+    int retlen, 
+    char *path, 
+    int chktype, 
+    char *chksum
+)
+{
+    int ulen;
+    char *pos = NULL;
+    char *pos1 = NULL;
+    char *pos2 = NULL;
+    char *buf = NULL;
+    char *currline = NULL;
+    char *nextline = NULL;
+
+    ulen = (int)grub_strlen(uname);
+
+    /* read file to buffer */
+    buf = grub_malloc(file->size + 4);
+    if (!buf)
+    {
+        return 1;
+    }
+    grub_file_read(file, buf, file->size);
+    buf[file->size] = 0;
+
+    /* parse each line */
+    for (currline = buf; currline; currline = nextline)
+    {
+        nextline = ventoy_get_line(currline);
+        VTOY_SKIP_SPACE(currline);
+
+        if (grub_strncasecmp(currline, uname, ulen) == 0)
+        {
+            pos = grub_strchr(currline, '=');
+            pos1 = grub_strchr(currline, '(');
+            pos2 = grub_strchr(currline, ')');
+            
+            if (pos && pos1 && pos2)
+            {
+                *pos2 = 0;
+                if (ventoy_chksum_pathcmp(chktype, path, pos1 + 1) == 0)
+                {
+                    VTOY_SKIP_SPACE_NEXT(pos, 1);
+                    grub_memcpy(chksum, pos, retlen);
+                    goto end;
+                }
+            }
+        }
+        else if (ventoy_str_len_alnum(currline, retlen))
+        {
+            VTOY_SKIP_SPACE_NEXT_EX(pos, currline, retlen);
+            if (ventoy_chksum_pathcmp(chktype, path, pos) == 0)
+            {
+                grub_memcpy(chksum, currline, retlen);
+                goto end;                        
+            }
+        }
+    }
+
+end:
+    grub_free(buf);
+    return 0;
+}
+
+static int ventoy_check_chkfile(const char *isopart, char *path, const char *lchkname, grub_file_t *pfile)
+{
+    int ret = 0;
+    int cnt = 0;
+    char c = 0;
+    char *pos = NULL;
+    grub_file_t file = NULL;
+
+    file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s%s.%s", isopart, path, lchkname);
+    if (file)
+    {
+        VTOY_GOTO_END(1);
+    }
+
+    cnt = ventoy_str_chrcnt(path, '/');
+    if (cnt > 1)
+    {
+        pos = grub_strrchr(path, '/');
+        c = *pos;
+        *pos = 0;
+
+        file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s%s/VENTOY_CHECKSUM", isopart, path);
+        if (file)
+        {
+            *pos = c;
+            VTOY_GOTO_END(2);
+        }
+        *pos = c;
+    }
+
+    file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s/VENTOY_CHECKSUM", isopart);
+    if (file)
+    {
+        ret = (cnt > 1) ? 3 : 4;
+    }
+
+end:
+
+    if (pfile)
+    {
+        *pfile = file;        
+    }
+    else
+    {
+        check_free(file, grub_file_close);
+    }
+    return ret;
+}
+
+static grub_err_t ventoy_cmd_cmp_checksum(grub_extcmd_context_t ctxt, int argc, char **args)
+{
+    int index = 0;
+    int chktype = 0;
+    char *pos = NULL;
+    grub_file_t file = NULL;
+    const char *calc_value = NULL;
+    const char *isopart = NULL;
+    char fchksum[64];
+    char readchk[256] = {0};
+    char filebuf[512] = {0};
+    int retlen[] = { 32, 40, 64, 128 };
+    char uchkname[16];
+
+    (void)ctxt;
+
+    index = (int)grub_strtol(args[0], NULL, 10);
+    if (argc != 2 || index < 0 || index >= (int)ARRAY_SIZE(retlen))
+    {
+        return 1;
+    }
+
+    grub_strncpy(uchkname, g_lower_chksum_name[index], sizeof(uchkname));
+    ventoy_str_toupper(uchkname);
+    
+    isopart = grub_env_get("vtoy_iso_part");
+    calc_value = grub_env_get("VT_LAST_CHECK_SUM");    
+
+    chktype = ventoy_check_chkfile(isopart, args[1], g_lower_chksum_name[index], &file);
+    if (chktype <= 0)
+    {
+        grub_printf("\n\nNo checksum file found.\n");
+        goto end;
+    }
+
+    if (chktype == 1)
+    {
+        grub_snprintf(fchksum, sizeof(fchksum), ".%s", g_lower_chksum_name[index]);
+        grub_memset(filebuf, 0, sizeof(filebuf));
+        grub_file_read(file, filebuf, 511);
+
+        pos = grub_strchr(filebuf, '=');
+        if (pos)
+        {
+            VTOY_SKIP_SPACE_NEXT(pos, 1);
+            grub_memcpy(readchk, pos, retlen[index]);
+        }
+        else
+        {
+            grub_memcpy(readchk, filebuf, retlen[index]);
+        }
+    }
+    else if (chktype == 3 || chktype == 4)
+    {
+        grub_snprintf(fchksum, sizeof(fchksum), "global VENTOY_CHECKSUM");
+        ventoy_find_checksum(file, uchkname, retlen[index], args[1], chktype, readchk);
+        if (readchk[0] == 0)
+        {
+            grub_printf("\n\n%s value not found in %s.\n", uchkname, fchksum);
+            goto end;
+        }
+    }
+    else
+    {
+        grub_snprintf(fchksum, sizeof(fchksum), "local VENTOY_CHECKSUM");
+        ventoy_find_checksum(file, uchkname, retlen[index], args[1], chktype, readchk);
+        if (readchk[0] == 0)
+        {
+            grub_file_close(file);
+            file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s/VENTOY_CHECKSUM", isopart);
+            if (file)
+            {
+                grub_snprintf(fchksum, sizeof(fchksum), "global VENTOY_CHECKSUM");
+                ventoy_find_checksum(file, uchkname, retlen[index], args[1], 3, readchk);
+                if (readchk[0] == 0)
+                {
+                    grub_printf("\n\n%s value not found in both local and global VENTOY_CHECKSUM.\n", uchkname);
+                    goto end;
+                }
+            }
+        }
+    }
+
+    if (grub_strcasecmp(calc_value, readchk) == 0)
+    {
+        grub_printf("\n\nCheck %s value with %s file.  [ SUCCESS ]\n", uchkname, fchksum);
+    }
+    else
+    {
+        grub_printf("\n\nCheck %s value with %s file.  [ ERROR ]\n", uchkname, fchksum);
+        grub_printf("The %s value in %s file is:\n%s\n", uchkname, fchksum, readchk);
+    }
+
+end:
+    grub_refresh();
+    check_free(file, grub_file_close);
+    VENTOY_CMD_RETURN(0);
+}
+
 
 static const char * ventoy_menu_lang_read_hook(struct grub_env_var *var, const char *val)
 {
@@ -6522,6 +6792,8 @@ static cmd_para ventoy_cmds[] =
     { "vt_load_menu_lang", ventoy_cmd_load_menu_lang, 0, NULL, "", "", NULL },
     { "vt_init_menu_lang", ventoy_cmd_init_menu_lang, 0, NULL, "", "", NULL },
     { "vt_cur_menu_lang", ventoy_cmd_cur_menu_lang, 0, NULL, "", "", NULL },
+    { "vt_vtoychksum_exist", ventoy_cmd_vtoychksum_exist, 0, NULL, "", "", NULL },
+    { "vt_cmp_checksum", ventoy_cmd_cmp_checksum, 0, NULL, "", "", NULL },
 
 };
 
index 7d12d60bb49c2752ccb9b2a6774f1067cec3c8b6..115e2ce5f36b61903b274e65496d8eef0c1eded0 100644 (file)
         s++;\
     }
 
+#define VTOY_SKIP_SPACE_NEXT_EX(s, base, initial) \
+    s = base + initial;\
+    while (ventoy_isspace(*s)) \
+    {\
+        s++;\
+    }
+
+#define VTOY_GOTO_END(v)  ret = v; goto end
+
 typedef enum VTOY_FILE_FLT
 {
     VTOY_FILE_FLT_ISO = 0, /* .iso */
@@ -628,6 +637,11 @@ typedef struct chk_case_fs_dir
 }chk_case_fs_dir;
 
 int ventoy_str_all_digit(const char *str);
+int ventoy_str_all_alnum(const char *str);
+int ventoy_str_len_alnum(const char *str, int len);
+char * ventoy_str_basename(char *path);
+grub_err_t ventoy_env_int_set(const char *name, int value);
+int ventoy_str_chrcnt(const char *str, char c);
 int ventoy_strcmp(const char *pattern, const char *str);
 int ventoy_strncmp (const char *pattern, const char *str, grub_size_t n);
 void ventoy_fill_os_param(grub_file_t file, ventoy_os_param *param);
index c373195441eb00e0e49913d4ad4e96bfb75e9c11..a3dc890ddde360fe106bee02f37b8a0edfd36880 100644 (file)
@@ -1,19 +1,17 @@
 
-if [ -e "${vtoy_iso_part}${VTOY_CHKSUM_FILE_PATH}.md5" ]; then
-    set default=0
+unset vtchkdef
+vt_vtoychksum_exist "${vtoy_iso_part}" "${VTOY_CHKSUM_FILE_PATH}" 
+set vtchksumfile=$?
+
+if [ -f "${vtoy_iso_part}${VTOY_CHKSUM_FILE_PATH}.md5" -o $vtchksumfile -eq 0 ]; then
+    if [ -z "$vtchkdef" ]; then
+        set default=0
+        set vtchkdef=1
+    fi
     menuentry "$VTLANG_CHKSUM_MD5_CALC_CHK" --class=checksum_md5 {
-        md5sum "${vtoy_iso_part}${VTOY_CHKSUM_FILE_PATH}"
-        
-        vt_1st_line "${vtoy_iso_part}${VTOY_CHKSUM_FILE_PATH}.md5" vtReadChecksum
-                
-        if vt_str_casebegin "$vtReadChecksum" "$VT_LAST_CHECK_SUM"; then
-            echo -e "\n\nCheck MD5 value with .md5 file.  [ OK ]"
-        else
-            echo -e "\n\nCheck MD5 value with .md5 file.  [ FAIL ]"
-            echo "The MD5 value in .md5 file is:"
-            echo "$vtReadChecksum"
-        fi
-        
+        md5sum "${vtoy_iso_part}${VTOY_CHKSUM_FILE_PATH}"       
+        vt_cmp_checksum 0 "${VTOY_CHKSUM_FILE_PATH}"
+
         echo -en "\n\n$VTLANG_ENTER_EXIT ..."
         read vtInputKey
     }
@@ -26,20 +24,14 @@ else
     }
 fi
 
-if [ -e "${vtoy_iso_part}${VTOY_CHKSUM_FILE_PATH}.sha1" ]; then
-    set default=1
+if [ -f "${vtoy_iso_part}${VTOY_CHKSUM_FILE_PATH}.sha1" -o $vtchksumfile -eq 0 ]; then
+    if [ -z "$vtchkdef" ]; then
+        set default=1
+        set vtchkdef=1
+    fi
     menuentry "$VTLANG_CHKSUM_SHA1_CALC_CHK" --class=checksum_sha1 {
         sha1sum "${vtoy_iso_part}${VTOY_CHKSUM_FILE_PATH}"
-        
-        vt_1st_line "${vtoy_iso_part}${VTOY_CHKSUM_FILE_PATH}.sha1" vtReadChecksum
-        
-        if vt_str_casebegin "$vtReadChecksum" "$VT_LAST_CHECK_SUM"; then
-            echo -e "\n\nCheck SHA1 value with .sha1 file.  [ OK ]"
-        else
-            echo -e "\n\nCheck SHA1 value with .sha1 file.  [ FAIL ]"
-            echo "The SHA1 value in .sha1 file is:"
-            echo "$vtReadChecksum"
-        fi
+        vt_cmp_checksum 1 "${VTOY_CHKSUM_FILE_PATH}" 
         
         echo -en "\n\n$VTLANG_ENTER_EXIT ..."
         read vtInputKey
@@ -55,20 +47,14 @@ fi
 
 
 
-if [ -e "${vtoy_iso_part}${VTOY_CHKSUM_FILE_PATH}.sha256" ]; then
-    set default=2
+if [ -f "${vtoy_iso_part}${VTOY_CHKSUM_FILE_PATH}.sha256" -o $vtchksumfile -eq 0 ]; then
+    if [ -z "$vtchkdef" ]; then
+        set default=2
+        set vtchkdef=1
+    fi
     menuentry "$VTLANG_CHKSUM_SHA256_CALC_CHK" --class=checksum_sha256 {
         sha256sum "${vtoy_iso_part}${VTOY_CHKSUM_FILE_PATH}"
-        
-        vt_1st_line "${vtoy_iso_part}${VTOY_CHKSUM_FILE_PATH}.sha256" vtReadChecksum
-        
-        if vt_str_casebegin "$vtReadChecksum" "$VT_LAST_CHECK_SUM"; then
-            echo -e "\n\nCheck SHA256 value with .sha256 file.  [ OK ]"
-        else
-            echo -e "\n\nCheck SHA256 value with .sha256 file.  [ FAIL ]"
-            echo "The SHA256 value in .sha256 file is:"
-            echo "$vtReadChecksum"
-        fi
+        vt_cmp_checksum 2 "${VTOY_CHKSUM_FILE_PATH}"         
         
         echo -en "\n\n$VTLANG_ENTER_EXIT ..."
         read vtInputKey
@@ -84,20 +70,14 @@ fi
 
 
 
-if [ -e "${vtoy_iso_part}${VTOY_CHKSUM_FILE_PATH}.sha512" ]; then
-    set default=3
+if [ -f "${vtoy_iso_part}${VTOY_CHKSUM_FILE_PATH}.sha512" -o $vtchksumfile -eq 0 ]; then
+    if [ -z "$vtchkdef" ]; then
+        set default=3
+        set vtchkdef=1
+    fi
     menuentry "$VTLANG_CHKSUM_SHA512_CALC_CHK" --class=checksum_sha512{
         sha512sum "${vtoy_iso_part}${VTOY_CHKSUM_FILE_PATH}"
-        
-        vt_1st_line "${vtoy_iso_part}${VTOY_CHKSUM_FILE_PATH}.sha512" vtReadChecksum
-        
-        if vt_str_casebegin "$vtReadChecksum" "$VT_LAST_CHECK_SUM"; then
-            echo -e "\n\nCheck SHA512 value with .sha512 file.  [ OK ]"
-        else
-            echo -e "\n\nCheck SHA512 value with .sha512 file.  [ FAIL ]"
-            echo "The SHA512 value in .sha512 file is:"
-            echo "$vtReadChecksum"
-        fi
+        vt_cmp_checksum 3 "${VTOY_CHKSUM_FILE_PATH}"        
         
         echo -en "\n\n$VTLANG_ENTER_EXIT ..."
         read vtInputKey