fstools: add partname volume driver
[project/fstools.git] / libfstools / common.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2
3 #include "common.h"
4 #define BUFLEN 128
5
6 int
7 read_uint_from_file(char *dirname, char *filename, unsigned int *i)
8 {
9 FILE *f;
10 char fname[BUFLEN];
11 int ret = -1;
12
13 snprintf(fname, sizeof(fname), "%s/%s", dirname, filename);
14
15 f = fopen(fname, "r");
16 if (!f)
17 return ret;
18
19 if (fscanf(f, "%u", i) == 1)
20 ret = 0;
21
22 fclose(f);
23 return ret;
24 }
25
26 char
27 *read_string_from_file(const char *dirname, const char *filename, char *buf, size_t bufsz)
28 {
29 FILE *f;
30 char fname[BUFLEN];
31 int i;
32
33 snprintf(fname, sizeof(fname), "%s/%s", dirname, filename);
34
35 f = fopen(fname, "r");
36 if (!f)
37 return NULL;
38
39 if (fgets(buf, bufsz, f) == NULL)
40 return NULL;
41
42 fclose(f);
43
44 /* make sure the string is \0 terminated */
45 buf[bufsz - 1] = '\0';
46
47 /* remove trailing whitespace */
48 i = strlen(buf) - 1;
49 while (i > 0 && buf[i] <= ' ')
50 buf[i--] = '\0';
51
52 return buf;
53 }
54
55 int block_file_identify(FILE *f, uint64_t offset)
56 {
57 uint32_t magic = 0;
58 size_t n;
59
60 fseeko(f, offset, SEEK_SET);
61 n = fread(&magic, sizeof(magic), 1, f);
62 if (magic == cpu_to_le32(0x88b1f)) {
63 return FS_TARGZ;
64 }
65
66 fseeko(f, offset + 0x400, SEEK_SET);
67 n = fread(&magic, sizeof(magic), 1, f);
68 if (n != 1)
69 return -1;
70
71 if (magic == cpu_to_le32(0xF2F52010))
72 return FS_F2FS;
73
74 magic = 0;
75 fseeko(f, offset + 0x438, SEEK_SET);
76 n = fread(&magic, sizeof(magic), 1, f);
77 if (n != 1)
78 return -1;
79
80 if ((le32_to_cpu(magic) & 0xffff) == 0xef53)
81 return FS_EXT4;
82
83 return FS_NONE;
84 }
85
86 static bool use_f2fs(struct volume *v, uint64_t offset, const char *bdev)
87 {
88 uint64_t size = 0;
89 bool ret = false;
90 int fd;
91
92 fd = open(bdev, O_RDONLY);
93 if (ioctl(fd, BLKGETSIZE64, &size) == 0)
94 ret = size - offset > F2FS_MINSIZE;
95 close(fd);
96
97 return ret;
98 }
99
100 int block_volume_format(struct volume *v, uint64_t offset, const char *bdev)
101 {
102 int ret = 0;
103 char str[128];
104
105 switch (volume_identify(v)) {
106 case FS_TARGZ:
107 snprintf(str, sizeof(str), "gzip -cd %s > /tmp/sysupgrade.tar", v->blk);
108 system(str);
109 /* fall-through */
110 case FS_NONE:
111 ULOG_INFO("overlay filesystem in %s has not been formatted yet\n", v->blk);
112 if (use_f2fs(v, offset, bdev))
113 snprintf(str, sizeof(str), "mkfs.f2fs -q -l rootfs_data %s", v->blk);
114 else
115 snprintf(str, sizeof(str), "mkfs.ext4 -q -L rootfs_data %s", v->blk);
116
117 ret = system(str);
118 break;
119 default:
120 break;
121 }
122
123 return ret;
124 }