supports rootfs resize

This commit is contained in:
maguoqun 2024-07-13 18:42:50 +08:00
parent 1bed103474
commit 0acba7fe05
5 changed files with 731 additions and 5 deletions

View file

@ -45,6 +45,10 @@ IMG_PART_SIGNATURE:=$(shell echo $(SOURCE_DATE_EPOCH)$(LINUX_VERMAGIC) | $(MKHAS
IMG_PART_DISKGUID:=$(shell echo $(SOURCE_DATE_EPOCH)$(LINUX_VERMAGIC) | $(MKHASH) md5 | sed -E 's/(.{8})(.{4})(.{4})(.{4})(.{10})../\1-\2-\3-\4-\500/')
endif
EXT4_UUID_NAMESPACE:=e67fcece-4ba7-4341-a2ed-d366699c745b
EXT4_ROOTFS_UUID:=$(shell uuidgen -s -n $(EXT4_UUID_NAMESPACE) -N rootfs-uuid-$(SOURCE_DATE_EPOCH))
EXT4_ROOTFS_HASH_SEED:=$(shell uuidgen -s -n $(EXT4_UUID_NAMESPACE) -N rootfs-hash-seed-$(SOURCE_DATE_EPOCH))
MKFS_DEVTABLE_OPT := -D $(INCLUDE_DIR)/device_table.txt
ifneq ($(CONFIG_BIG_ENDIAN),)
@ -270,12 +274,15 @@ define Image/mkfs/ubifs
endef
define Image/mkfs/ext4
$(STAGING_DIR_HOST)/bin/make_ext4fs -L rootfs \
-l $(ROOTFS_PARTSIZE) -b $(CONFIG_TARGET_EXT4_BLOCKSIZE) \
$(if $(SOURCE_DATE_EPOCH),E2FSPROGS_FAKE_TIME=$(SOURCE_DATE_EPOCH)) \
$(STAGING_DIR_HOST)/bin/mkfs.ext4 -L rootfs \
-T default -b $(CONFIG_TARGET_EXT4_BLOCKSIZE) \
$(if $(CONFIG_TARGET_EXT4_RESERVED_PCT),-m $(CONFIG_TARGET_EXT4_RESERVED_PCT)) \
$(if $(CONFIG_TARGET_EXT4_JOURNAL),,-J) \
$(if $(SOURCE_DATE_EPOCH),-T $(SOURCE_DATE_EPOCH)) \
$@ $(call mkfs_target_dir,$(1))/
$(if $(CONFIG_TARGET_EXT4_JOURNAL),,-O ^has_journal) \
-U $(EXT4_ROOTFS_UUID) -E hash_seed=$(EXT4_ROOTFS_HASH_SEED) \
-u 0:0 \
-d $(call mkfs_target_dir,$(1))/ \
$@ $$(($(ROOTFS_PARTSIZE)/$(CONFIG_TARGET_EXT4_BLOCKSIZE)))
endef
define Image/Manifest

View file

@ -4,4 +4,8 @@ echo "custom init env"
ln -s /lib/libc.so /usr/lib/libc.so
# auto resize rootfs
ROOTFS=$(cat /proc/cmdline | grep -Eo "root=[^ ]*" | awk -F '=' '{print $2}')
resize2fs $ROOTFS
exit 0

View file

@ -0,0 +1,192 @@
From 76c6186e7ea6b5ab11348b50236635812e85d39e Mon Sep 17 00:00:00 2001
From: Torste Aikio <zokier@gmail.com>
Date: Sun, 25 Feb 2024 16:29:59 +0200
Subject: [PATCH] Add -u flag to set uid:gid when populating new fs
This flag is useful when making root fs without root privileges
Heavily inspired by patch from David Timber <dxdt@dev.snart.me>
---
misc/create_inode.c | 12 ++++++++--
misc/create_inode.h | 3 +++
misc/mke2fs.c | 54 ++++++++++++++++++++++++++++++++++++++++-----
3 files changed, 62 insertions(+), 7 deletions(-)
diff --git a/misc/create_inode.c b/misc/create_inode.c
index a3a34cd9..0005fc02 100644
--- a/misc/create_inode.c
+++ b/misc/create_inode.c
@@ -109,7 +109,7 @@ static errcode_t add_link(ext2_filsys fs, ext2_ino_t parent_ino,
/* Set the uid, gid, mode and time for the inode */
static errcode_t set_inode_extra(ext2_filsys fs, ext2_ino_t ino,
- struct stat *st)
+ struct stat *st, struct fs_ops_callbacks *fs_callbacks)
{
errcode_t retval;
struct ext2_inode inode;
@@ -129,6 +129,14 @@ static errcode_t set_inode_extra(ext2_filsys fs, ext2_ino_t ino,
inode.i_mtime = st->st_mtime;
inode.i_ctime = st->st_ctime;
+ if (fs_callbacks && fs_callbacks->before_inode_extra_write) {
+ retval = fs_callbacks->before_inode_extra_write(fs, ino, st, &inode);
+ if (retval) {
+ com_err(__func__, retval, _("callback error while writing inode %u"), ino);
+ return retval;
+ }
+ }
+
retval = ext2fs_write_inode(fs, ino, &inode);
if (retval)
com_err(__func__, retval, _("while writing inode %u"), ino);
@@ -986,7 +994,7 @@ find_lnf:
goto out;
}
- retval = set_inode_extra(fs, ino, &st);
+ retval = set_inode_extra(fs, ino, &st, fs_callbacks);
if (retval) {
com_err(__func__, retval,
_("while setting inode for \"%s\""), name);
diff --git a/misc/create_inode.h b/misc/create_inode.h
index b5eeb420..6f31fcfb 100644
--- a/misc/create_inode.h
+++ b/misc/create_inode.h
@@ -1,6 +1,7 @@
#ifndef _CREATE_INODE_H
#define _CREATE_INODE_H
+#include <ext2fs/ext2_fs.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
@@ -31,6 +32,8 @@ struct fs_ops_callbacks {
errcode_t (* end_create_new_inode)(ext2_filsys fs,
const char *target_path, const char *name,
ext2_ino_t parent_ino, ext2_ino_t root, mode_t mode);
+ errcode_t (* before_inode_extra_write)(ext2_filsys fs, ext2_ino_t ino,
+ struct stat *st, struct ext2_inode *inode);
};
extern int no_copy_xattrs; /* this should eventually be a flag
diff --git a/misc/mke2fs.c b/misc/mke2fs.c
index 4a9c1b09..bdf6a2ee 100644
--- a/misc/mke2fs.c
+++ b/misc/mke2fs.c
@@ -16,6 +16,7 @@
* enforced (but it's not much fun on a character device :-).
*/
+#include <stdint.h>
#define _XOPEN_SOURCE 600
#include "config.h"
@@ -119,6 +120,8 @@ static int sync_kludge; /* Set using the MKE2FS_SYNC env. option */
char **fs_types;
const char *src_root_dir; /* Copy files from the specified directory */
static char *undo_file;
+static uid_t populate_uid = -1;
+static gid_t populate_gid = -1;
static int android_sparse_file; /* -E android_sparse */
@@ -139,8 +142,8 @@ static void usage(void)
"\t[-g blocks-per-group] [-L volume-label] "
"[-M last-mounted-directory]\n\t[-O feature[,...]] "
"[-r fs-revision] [-E extended-option[,...]]\n"
- "\t[-t fs-type] [-T usage-type ] [-U UUID] [-e errors_behavior]"
- "[-z undo_file]\n"
+ "\t[-t fs-type] [-T usage-type ] [-u uid[:gid]] [-U UUID]\n"
+ "\t[-e errors_behavior] [-z undo_file]\n"
"\t[-jnqvDFSV] device [blocks-count]\n"),
program_name);
exit(1);
@@ -1604,6 +1607,7 @@ static void PRS(int argc, char *argv[])
int use_bsize;
char *newpath;
int pathlen = sizeof(PATH_SET) + 1;
+ long u_opt = -1;
#ifdef HAVE_BLKID_PROBE_GET_TOPOLOGY
struct device_param dev_param;
#endif
@@ -1678,7 +1682,7 @@ profile_error:
}
while ((c = getopt (argc, argv,
- "b:cd:e:g:i:jl:m:no:qr:s:t:vC:DE:FG:I:J:KL:M:N:O:R:ST:U:Vz:")) != EOF) {
+ "b:cd:e:g:i:jl:m:no:qr:s:t:u:vC:DE:FG:I:J:KL:M:N:O:R:ST:U:Vz:")) != EOF) {
switch (c) {
case 'b':
blocksize = parse_num_blocks2(optarg, -1);
@@ -1910,6 +1914,28 @@ profile_error:
}
usage_types = strdup(optarg);
break;
+ case 'u':
+ errno = 0;
+ u_opt = strtol(optarg, &tmp, 10);
+ if (errno != 0 || u_opt < -1 || u_opt > UINT32_MAX) {
+ com_err(program_name, 0, _("invalid uid %s"), optarg);
+ exit(1);
+ }
+ populate_uid = u_opt;
+ if (*tmp == ':') {
+ tmp++;
+ u_opt = strtol(tmp, &tmp, 10);
+ if (errno != 0 || u_opt < -1 || u_opt > UINT32_MAX) {
+ com_err(program_name, 0, _("invalid gid %s"), optarg);
+ exit(1);
+ }
+ populate_gid = u_opt;
+ }
+ if (*tmp != 0) {
+ com_err(program_name, 0, _("invalid uid[:gid] %s"), optarg);
+ exit(1);
+ }
+ break;
case 'U':
fs_uuid = optarg;
break;
@@ -3012,6 +3038,21 @@ try_user:
return 0;
}
+static errcode_t cb_populate_set_uidgid(ext2_filsys fs, ext2_ino_t ino,
+ struct stat *st, struct ext2_inode *inode)
+{
+ if (populate_uid < UINT32_MAX) {
+ inode->i_uid = populate_uid;
+ ext2fs_set_i_uid_high(*inode, populate_uid >> 16);
+ }
+ if (populate_gid < UINT32_MAX) {
+ inode->i_gid = populate_gid;
+ ext2fs_set_i_gid_high(*inode, populate_gid >> 16);
+ }
+
+ return 0;
+}
+
int main (int argc, char *argv[])
{
errcode_t retval = 0;
@@ -3553,11 +3594,14 @@ no_journal:
com_err(program_name, retval, "while creating huge files");
/* Copy files from the specified directory */
if (src_root_dir) {
+ struct fs_ops_callbacks fs_ops_callbacks = {0};
+ fs_ops_callbacks.before_inode_extra_write = cb_populate_set_uidgid;
+
if (!quiet)
printf("%s", _("Copying files into the device: "));
- retval = populate_fs(fs, EXT2_ROOT_INO, src_root_dir,
- EXT2_ROOT_INO);
+ retval = populate_fs2(fs, EXT2_ROOT_INO, src_root_dir,
+ EXT2_ROOT_INO, &fs_ops_callbacks);
if (retval) {
com_err(program_name, retval, "%s",
_("while populating file system"));
--
2.43.2

View file

@ -0,0 +1,425 @@
From 13a53c84801d57f1d76656f7913628a7b526c335 Mon Sep 17 00:00:00 2001
From: Torste Aikio <zokier@gmail.com>
Date: Sun, 25 Feb 2024 22:18:18 +0200
Subject: [PATCH] include uuid_generate_sha1
---
lib/uuid/Makefile.in | 4 +
lib/uuid/gen_uuid.c | 27 +++++
lib/uuid/sha1.c | 263 +++++++++++++++++++++++++++++++++++++++++++
lib/uuid/sha1.h | 31 +++++
lib/uuid/uuid.h.in | 2 +
5 files changed, 327 insertions(+)
create mode 100644 lib/uuid/sha1.c
create mode 100644 lib/uuid/sha1.h
diff --git a/lib/uuid/Makefile.in b/lib/uuid/Makefile.in
index 5f697792..dd9231b9 100644
--- a/lib/uuid/Makefile.in
+++ b/lib/uuid/Makefile.in
@@ -24,6 +24,7 @@ OBJS= clear.o \
isnull.o \
pack.o \
parse.o \
+ sha1.o \
unpack.o \
unparse.o \
uuid_time.o
@@ -35,6 +36,7 @@ SRCS= $(srcdir)/clear.c \
$(srcdir)/isnull.c \
$(srcdir)/pack.c \
$(srcdir)/parse.c \
+ $(srcdir)/sha1.c \
$(srcdir)/unpack.c \
$(srcdir)/unparse.c \
$(srcdir)/uuid_time.c
@@ -206,6 +208,8 @@ isnull.o: $(srcdir)/isnull.c $(top_builddir)/lib/config.h \
$(top_builddir)/lib/dirpaths.h $(srcdir)/uuidP.h
pack.o: $(srcdir)/pack.c $(top_builddir)/lib/config.h \
$(top_builddir)/lib/dirpaths.h $(srcdir)/uuidP.h
+sha1.o: $(srcdir)/sha1.c $(top_builddir)/lib/config.h \
+ $(top_builddir)/lib/dirpaths.h $(srcdir)/uuidP.h $(srcdir)/sha1.h
parse.o: $(srcdir)/parse.c $(top_builddir)/lib/config.h \
$(top_builddir)/lib/dirpaths.h $(srcdir)/uuidP.h
unpack.o: $(srcdir)/unpack.c $(top_builddir)/lib/config.h \
diff --git a/lib/uuid/gen_uuid.c b/lib/uuid/gen_uuid.c
index 2f028867..c208c045 100644
--- a/lib/uuid/gen_uuid.c
+++ b/lib/uuid/gen_uuid.c
@@ -41,6 +41,7 @@
#include "config.h"
+#include <assert.h>
#include <stdio.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
@@ -95,6 +96,7 @@
#include "uuidP.h"
#include "uuidd.h"
+#include "sha1.h"
#ifdef HAVE_SRANDOM
#define srand(x) srandom(x)
@@ -666,6 +668,31 @@ void uuid_generate_random(uuid_t out)
uuid__generate_random(out, &num);
}
+/*
+ * Generate a SHA1 hashed (predictable) UUID based on a well-known UUID
+ * providing the namespace and an arbitrary binary string.
+ */
+void uuid_generate_sha1(uuid_t out, const uuid_t ns, const char *name, size_t len)
+{
+ UL_SHA1_CTX ctx;
+ char hash[UL_SHA1LENGTH];
+ uuid_t buf;
+ struct uuid uu;
+
+ ul_SHA1Init(&ctx);
+ ul_SHA1Update(&ctx, ns, sizeof(uuid_t));
+ ul_SHA1Update(&ctx, (const unsigned char *)name, len);
+ ul_SHA1Final((unsigned char *)hash, &ctx);
+
+ assert(sizeof(buf) <= sizeof(hash));
+
+ memcpy(buf, hash, sizeof(buf));
+ uuid_unpack(buf, &uu);
+
+ uu.clock_seq = (uu.clock_seq & 0x3FFF) | 0x8000;
+ uu.time_hi_and_version = (uu.time_hi_and_version & 0x0FFF) | 0x5000;
+ uuid_pack(&uu, out);
+}
/*
* This is the generic front-end to uuid_generate_random and
diff --git a/lib/uuid/sha1.c b/lib/uuid/sha1.c
new file mode 100644
index 00000000..32ef5b9c
--- /dev/null
+++ b/lib/uuid/sha1.c
@@ -0,0 +1,263 @@
+/*
+ * No copyright is claimed. This code is in the public domain; do with
+ * it what you wish.
+ *
+ * SHA-1 in C by Steve Reid <steve@edmweb.com>
+ * 100% Public Domain
+ *
+ * Test Vectors (from FIPS PUB 180-1)
+ * 1) "abc": A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D
+ * 2) "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq": 84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1
+ * 3) A million repetitions of "a": 34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F
+ */
+
+#define UL_SHA1HANDSOFF
+
+#include <stdio.h>
+#include <string.h>
+#include <stdint.h>
+
+#include "sha1.h"
+
+#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
+
+/* blk0() and blk() perform the initial expand. */
+#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+# define blk0(i) block->l[i]
+#else
+# define blk0(i) (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) \
+ |(rol(block->l[i],8)&0x00FF00FF))
+#endif
+
+#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \
+ ^block->l[(i+2)&15]^block->l[i&15],1))
+
+/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
+#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30);
+#define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30);
+#define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30);
+#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30);
+#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30);
+
+/* Hash a single 512-bit block. This is the core of the algorithm. */
+
+void ul_SHA1Transform(uint32_t state[5], const unsigned char buffer[64])
+{
+ uint32_t a, b, c, d, e;
+
+ typedef union {
+ unsigned char c[64];
+ uint32_t l[16];
+ } CHAR64LONG16;
+
+#ifdef UL_SHA1HANDSOFF
+ CHAR64LONG16 block[1]; /* use array to appear as a pointer */
+
+ memcpy(block, buffer, 64);
+#else
+ /* The following had better never be used because it causes the
+ * pointer-to-const buffer to be cast into a pointer to non-const.
+ * And the result is written through. I threw a "const" in, hoping
+ * this will cause a diagnostic.
+ */
+ CHAR64LONG16 *block = (const CHAR64LONG16 *)buffer;
+#endif
+ /* Copy context->state[] to working vars */
+ a = state[0];
+ b = state[1];
+ c = state[2];
+ d = state[3];
+ e = state[4];
+ /* 4 rounds of 20 operations each. Loop unrolled. */
+ R0(a, b, c, d, e, 0);
+ R0(e, a, b, c, d, 1);
+ R0(d, e, a, b, c, 2);
+ R0(c, d, e, a, b, 3);
+ R0(b, c, d, e, a, 4);
+ R0(a, b, c, d, e, 5);
+ R0(e, a, b, c, d, 6);
+ R0(d, e, a, b, c, 7);
+ R0(c, d, e, a, b, 8);
+ R0(b, c, d, e, a, 9);
+ R0(a, b, c, d, e, 10);
+ R0(e, a, b, c, d, 11);
+ R0(d, e, a, b, c, 12);
+ R0(c, d, e, a, b, 13);
+ R0(b, c, d, e, a, 14);
+ R0(a, b, c, d, e, 15);
+ R1(e, a, b, c, d, 16);
+ R1(d, e, a, b, c, 17);
+ R1(c, d, e, a, b, 18);
+ R1(b, c, d, e, a, 19);
+ R2(a, b, c, d, e, 20);
+ R2(e, a, b, c, d, 21);
+ R2(d, e, a, b, c, 22);
+ R2(c, d, e, a, b, 23);
+ R2(b, c, d, e, a, 24);
+ R2(a, b, c, d, e, 25);
+ R2(e, a, b, c, d, 26);
+ R2(d, e, a, b, c, 27);
+ R2(c, d, e, a, b, 28);
+ R2(b, c, d, e, a, 29);
+ R2(a, b, c, d, e, 30);
+ R2(e, a, b, c, d, 31);
+ R2(d, e, a, b, c, 32);
+ R2(c, d, e, a, b, 33);
+ R2(b, c, d, e, a, 34);
+ R2(a, b, c, d, e, 35);
+ R2(e, a, b, c, d, 36);
+ R2(d, e, a, b, c, 37);
+ R2(c, d, e, a, b, 38);
+ R2(b, c, d, e, a, 39);
+ R3(a, b, c, d, e, 40);
+ R3(e, a, b, c, d, 41);
+ R3(d, e, a, b, c, 42);
+ R3(c, d, e, a, b, 43);
+ R3(b, c, d, e, a, 44);
+ R3(a, b, c, d, e, 45);
+ R3(e, a, b, c, d, 46);
+ R3(d, e, a, b, c, 47);
+ R3(c, d, e, a, b, 48);
+ R3(b, c, d, e, a, 49);
+ R3(a, b, c, d, e, 50);
+ R3(e, a, b, c, d, 51);
+ R3(d, e, a, b, c, 52);
+ R3(c, d, e, a, b, 53);
+ R3(b, c, d, e, a, 54);
+ R3(a, b, c, d, e, 55);
+ R3(e, a, b, c, d, 56);
+ R3(d, e, a, b, c, 57);
+ R3(c, d, e, a, b, 58);
+ R3(b, c, d, e, a, 59);
+ R4(a, b, c, d, e, 60);
+ R4(e, a, b, c, d, 61);
+ R4(d, e, a, b, c, 62);
+ R4(c, d, e, a, b, 63);
+ R4(b, c, d, e, a, 64);
+ R4(a, b, c, d, e, 65);
+ R4(e, a, b, c, d, 66);
+ R4(d, e, a, b, c, 67);
+ R4(c, d, e, a, b, 68);
+ R4(b, c, d, e, a, 69);
+ R4(a, b, c, d, e, 70);
+ R4(e, a, b, c, d, 71);
+ R4(d, e, a, b, c, 72);
+ R4(c, d, e, a, b, 73);
+ R4(b, c, d, e, a, 74);
+ R4(a, b, c, d, e, 75);
+ R4(e, a, b, c, d, 76);
+ R4(d, e, a, b, c, 77);
+ R4(c, d, e, a, b, 78);
+ R4(b, c, d, e, a, 79);
+ /* Add the working vars back into context.state[] */
+ state[0] += a;
+ state[1] += b;
+ state[2] += c;
+ state[3] += d;
+ state[4] += e;
+ /* Wipe variables */
+ explicit_bzero(&a, sizeof(a));
+ explicit_bzero(&b, sizeof(b));
+ explicit_bzero(&c, sizeof(c));
+ explicit_bzero(&d, sizeof(d));
+ explicit_bzero(&e, sizeof(e));
+#ifdef UL_SHA1HANDSOFF
+ memset(block, '\0', sizeof(block));
+#endif
+}
+
+/* SHA1Init - Initialize new context */
+
+void ul_SHA1Init(UL_SHA1_CTX *context)
+{
+ /* SHA1 initialization constants */
+ context->state[0] = 0x67452301;
+ context->state[1] = 0xEFCDAB89;
+ context->state[2] = 0x98BADCFE;
+ context->state[3] = 0x10325476;
+ context->state[4] = 0xC3D2E1F0;
+ context->count[0] = context->count[1] = 0;
+}
+
+/* Run your data through this. */
+
+void ul_SHA1Update(UL_SHA1_CTX *context, const unsigned char *data, uint32_t len)
+{
+ uint32_t i;
+
+ uint32_t j;
+
+ j = context->count[0];
+ if ((context->count[0] += len << 3) < j)
+ context->count[1]++;
+ context->count[1] += (len >> 29);
+ j = (j >> 3) & 63;
+ if ((j + len) > 63) {
+ memcpy(&context->buffer[j], data, (i = 64 - j));
+ ul_SHA1Transform(context->state, context->buffer);
+ for (; i + 63 < len; i += 64) {
+ ul_SHA1Transform(context->state, &data[i]);
+ }
+ j = 0;
+ } else
+ i = 0;
+ memcpy(&context->buffer[j], &data[i], len - i);
+}
+
+/* Add padding and return the message digest. */
+
+void ul_SHA1Final(unsigned char digest[20], UL_SHA1_CTX *context)
+{
+ unsigned i;
+
+ unsigned char finalcount[8];
+
+ unsigned char c;
+
+#if 0 /* untested "improvement" by DHR */
+ /* Convert context->count to a sequence of bytes
+ * in finalcount. Second element first, but
+ * big-endian order within element.
+ * But we do it all backwards.
+ */
+ unsigned char *fcp = &finalcount[8];
+
+ for (i = 0; i < 2; i++) {
+ uint32_t t = context->count[i];
+
+ int j;
+
+ for (j = 0; j < 4; t >>= 8, j++)
+ *--fcp = (unsigned char)t}
+#else
+ for (i = 0; i < 8; i++) {
+ finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)] >> ((3 - (i & 3)) * 8)) & 255); /* Endian independent */
+ }
+#endif
+ c = 0200;
+ ul_SHA1Update(context, &c, 1);
+ while ((context->count[0] & 504) != 448) {
+ c = 0000;
+ ul_SHA1Update(context, &c, 1);
+ }
+ ul_SHA1Update(context, finalcount, 8); /* Should cause a SHA1Transform() */
+ for (i = 0; i < 20; i++) {
+ digest[i] = (unsigned char)
+ ((context->state[i >> 2] >> ((3 - (i & 3)) * 8)) & 255);
+ }
+ /* Wipe variables */
+ memset(context, '\0', sizeof(*context));
+ memset(&finalcount, '\0', sizeof(finalcount));
+}
+
+void ul_SHA1(char *hash_out, const char *str, unsigned len)
+{
+ UL_SHA1_CTX ctx;
+ unsigned int ii;
+
+ ul_SHA1Init(&ctx);
+ for (ii = 0; ii < len; ii += 1)
+ ul_SHA1Update(&ctx, (const unsigned char *)str + ii, 1);
+ ul_SHA1Final((unsigned char *)hash_out, &ctx);
+ hash_out[20] = '\0';
+}
diff --git a/lib/uuid/sha1.h b/lib/uuid/sha1.h
new file mode 100644
index 00000000..8ec74c9b
--- /dev/null
+++ b/lib/uuid/sha1.h
@@ -0,0 +1,31 @@
+/*
+ * No copyright is claimed. This code is in the public domain; do with
+ * it what you wish.
+ */
+#ifndef UTIL_LINUX_SHA1_H
+#define UTIL_LINUX_SHA1_H
+
+/*
+ SHA-1 in C
+ By Steve Reid <steve@edmweb.com>
+ 100% Public Domain
+ */
+
+#include "stdint.h"
+
+#define UL_SHA1LENGTH 20
+
+typedef struct
+{
+ uint32_t state[5];
+ uint32_t count[2];
+ unsigned char buffer[64];
+} UL_SHA1_CTX;
+
+void ul_SHA1Transform(uint32_t state[5], const unsigned char buffer[64]);
+void ul_SHA1Init(UL_SHA1_CTX *context);
+void ul_SHA1Update(UL_SHA1_CTX *context, const unsigned char *data, uint32_t len);
+void ul_SHA1Final(unsigned char digest[UL_SHA1LENGTH], UL_SHA1_CTX *context);
+void ul_SHA1(char *hash_out, const char *str, unsigned len);
+
+#endif /* UTIL_LINUX_SHA1_H */
diff --git a/lib/uuid/uuid.h.in b/lib/uuid/uuid.h.in
index ca846da0..c77d325e 100644
--- a/lib/uuid/uuid.h.in
+++ b/lib/uuid/uuid.h.in
@@ -52,6 +52,7 @@ typedef unsigned char uuid_t[16];
/* UUID Type definitions */
#define UUID_TYPE_DCE_TIME 1
#define UUID_TYPE_DCE_RANDOM 4
+#define UUID_TYPE_DCE_SHA1 5
/* Allow UUID constants to be defined */
#ifdef __GNUC__
@@ -79,6 +80,7 @@ void uuid_copy(uuid_t dst, const uuid_t src);
void uuid_generate(uuid_t out);
void uuid_generate_random(uuid_t out);
void uuid_generate_time(uuid_t out);
+void uuid_generate_sha1(uuid_t out, const uuid_t ns, const char *name, size_t len);
/* isnull.c */
int uuid_is_null(const uuid_t uu);
--
2.43.2

View file

@ -0,0 +1,98 @@
From a181b1aa2ef0641da23b8267b0b9e499d740e1c4 Mon Sep 17 00:00:00 2001
From: Torste Aikio <zokier@gmail.com>
Date: Sun, 25 Feb 2024 21:12:45 +0200
Subject: [PATCH] Add flags to uuidgen for generating sha1 uuid
---
misc/uuidgen.c | 33 +++++++++++++++++++++++++++++++--
1 file changed, 31 insertions(+), 2 deletions(-)
diff --git a/misc/uuidgen.c b/misc/uuidgen.c
index 1233f3df..d48bd02e 100644
--- a/misc/uuidgen.c
+++ b/misc/uuidgen.c
@@ -11,6 +11,7 @@
#include "config.h"
#include <stdio.h>
+#include <string.h>
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
@@ -26,10 +27,11 @@ extern int optind;
#define DO_TYPE_TIME 1
#define DO_TYPE_RANDOM 2
+#define DO_TYPE_SHA1 3
static void usage(const char *progname)
{
- fprintf(stderr, _("Usage: %s [-r] [-t]\n"), progname);
+ fprintf(stderr, _("Usage: %s [-r] [-t] [-s] [-n ns] [-N name]\n"), progname);
exit(1);
}
@@ -39,6 +41,8 @@ main (int argc, char *argv[])
int c;
int do_type = 0;
char str[37];
+ uuid_t ns = {0};
+ char *sha1_name = 0;
uuid_t uu;
#ifdef ENABLE_NLS
@@ -48,18 +52,40 @@ main (int argc, char *argv[])
textdomain(NLS_CAT_NAME);
#endif
- while ((c = getopt (argc, argv, "tr")) != EOF)
+ while ((c = getopt (argc, argv, "trsn:N:")) != EOF)
switch (c) {
case 't':
+ if (do_type != 0) usage(argv[0]);
do_type = DO_TYPE_TIME;
break;
case 'r':
+ if (do_type != 0) usage(argv[0]);
do_type = DO_TYPE_RANDOM;
break;
+ case 's':
+ if (do_type != 0) usage(argv[0]);
+ do_type = DO_TYPE_SHA1;
+ break;
+ case 'n':
+ if (uuid_parse(optarg, ns) != 0) usage(argv[0]);
+ break;
+ case 'N':
+ sha1_name = strdupa(optarg);
+ break;
default:
usage(argv[0]);
}
+ if (do_type == DO_TYPE_SHA1) {
+ if (uuid_is_null(ns) || sha1_name == 0) {
+ usage(argv[0]);
+ }
+ } else {
+ if (!uuid_is_null(ns) || sha1_name != 0) {
+ usage(argv[0]);
+ }
+ }
+
switch (do_type) {
case DO_TYPE_TIME:
uuid_generate_time(uu);
@@ -67,6 +93,9 @@ main (int argc, char *argv[])
case DO_TYPE_RANDOM:
uuid_generate_random(uu);
break;
+ case DO_TYPE_SHA1:
+ uuid_generate_sha1(uu, ns, sha1_name, strlen(sha1_name));
+ break;
default:
uuid_generate(uu);
break;
--
2.43.2