1b22d2cb19aefe1b928fad6045210b2656c1c16d
[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 fclose(f);
41 return NULL;
42 }
43
44 fclose(f);
45
46 /* make sure the string is \0 terminated */
47 buf[bufsz - 1] = '\0';
48
49 /* remove trailing whitespace */
50 i = strlen(buf) - 1;
51 while (i > 0 && buf[i] <= ' ')
52 buf[i--] = '\0';
53
54 return buf;
55 }
56
57 int block_file_identify(FILE *f, uint64_t offset)
58 {
59 uint32_t magic = 0;
60 size_t n;
61
62 if (fseeko(f, offset, SEEK_SET) < 0)
63 return -1;
64
65 n = fread(&magic, sizeof(magic), 1, f);
66 if (magic == cpu_to_le32(0x88b1f)) {
67 return FS_TARGZ;
68 }
69
70 if (fseeko(f, offset + 0x400, SEEK_SET) < 0)
71 return -1;
72
73 n = fread(&magic, sizeof(magic), 1, f);
74 if (n != 1)
75 return -1;
76
77 if (magic == cpu_to_le32(0xF2F52010))
78 return FS_F2FS;
79
80 magic = 0;
81 if (fseeko(f, offset + 0x438, SEEK_SET) < 0)
82 return -1;
83
84 n = fread(&magic, sizeof(magic), 1, f);
85 if (n != 1)
86 return -1;
87
88 if ((le32_to_cpu(magic) & 0xffff) == 0xef53)
89 return FS_EXT4;
90
91 return FS_NONE;
92 }
93
94 static bool use_f2fs(struct volume *v, uint64_t offset, const char *bdev)
95 {
96 uint64_t size = 0;
97 bool ret = false;
98 int fd;
99
100 fd = open(bdev, O_RDONLY);
101 if (fd < 0)
102 return false;
103
104 if (ioctl(fd, BLKGETSIZE64, &size) == 0)
105 ret = size - offset > F2FS_MINSIZE;
106
107 close(fd);
108
109 return ret;
110 }
111
112 int block_volume_format(struct volume *v, uint64_t offset, const char *bdev)
113 {
114 int ret = 0;
115 char str[128];
116
117 switch (volume_identify(v)) {
118 case FS_TARGZ:
119 snprintf(str, sizeof(str), "gzip -cd %s > /tmp/sysupgrade.tar", v->blk);
120 system(str);
121 /* fall-through */
122 case FS_NONE:
123 ULOG_INFO("overlay filesystem in %s has not been formatted yet\n", v->blk);
124 if (use_f2fs(v, offset, bdev))
125 snprintf(str, sizeof(str), "mkfs.f2fs -q -l rootfs_data %s", v->blk);
126 else
127 snprintf(str, sizeof(str), "mkfs.ext4 -q -L rootfs_data %s", v->blk);
128
129 ret = system(str);
130 break;
131 default:
132 break;
133 }
134
135 return ret;
136 }