8dc109537a195c0476a5c02cc2eb4391157ff477
[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 fseeko(f, offset, SEEK_SET);
63 n = fread(&magic, sizeof(magic), 1, f);
64 if (magic == cpu_to_le32(0x88b1f)) {
65 return FS_TARGZ;
66 }
67
68 fseeko(f, offset + 0x400, SEEK_SET);
69 n = fread(&magic, sizeof(magic), 1, f);
70 if (n != 1)
71 return -1;
72
73 if (magic == cpu_to_le32(0xF2F52010))
74 return FS_F2FS;
75
76 magic = 0;
77 fseeko(f, offset + 0x438, SEEK_SET);
78 n = fread(&magic, sizeof(magic), 1, f);
79 if (n != 1)
80 return -1;
81
82 if ((le32_to_cpu(magic) & 0xffff) == 0xef53)
83 return FS_EXT4;
84
85 return FS_NONE;
86 }
87
88 static bool use_f2fs(struct volume *v, uint64_t offset, const char *bdev)
89 {
90 uint64_t size = 0;
91 bool ret = false;
92 int fd;
93
94 fd = open(bdev, O_RDONLY);
95 if (fd < 0)
96 return false;
97
98 if (ioctl(fd, BLKGETSIZE64, &size) == 0)
99 ret = size - offset > F2FS_MINSIZE;
100
101 close(fd);
102
103 return ret;
104 }
105
106 int block_volume_format(struct volume *v, uint64_t offset, const char *bdev)
107 {
108 int ret = 0;
109 char str[128];
110
111 switch (volume_identify(v)) {
112 case FS_TARGZ:
113 snprintf(str, sizeof(str), "gzip -cd %s > /tmp/sysupgrade.tar", v->blk);
114 system(str);
115 /* fall-through */
116 case FS_NONE:
117 ULOG_INFO("overlay filesystem in %s has not been formatted yet\n", v->blk);
118 if (use_f2fs(v, offset, bdev))
119 snprintf(str, sizeof(str), "mkfs.f2fs -q -l rootfs_data %s", v->blk);
120 else
121 snprintf(str, sizeof(str), "mkfs.ext4 -q -L rootfs_data %s", v->blk);
122
123 ret = system(str);
124 break;
125 default:
126 break;
127 }
128
129 return ret;
130 }