• source navigation  • diff markup  • identifier search  • freetext search  • 

Sources/fstools/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         if (magic == cpu_to_be32(0xdeadc0de))
 70                 return FS_DEADCODE;
 71 
 72         if (fseeko(f, offset + 0x400, SEEK_SET) < 0)
 73                 return -1;
 74 
 75         n = fread(&magic, sizeof(magic), 1, f);
 76         if (n != 1)
 77                 return -1;
 78 
 79         if (magic == cpu_to_le32(0xF2F52010))
 80                 return FS_F2FS;
 81 
 82         magic = 0;
 83         if (fseeko(f, offset + 0x438, SEEK_SET) < 0)
 84                 return -1;
 85 
 86         n = fread(&magic, sizeof(magic), 1, f);
 87         if (n != 1)
 88                 return -1;
 89 
 90         if ((le32_to_cpu(magic) & 0xffff) == 0xef53)
 91                 return FS_EXT4;
 92 
 93         return FS_NONE;
 94 }
 95 
 96 static bool use_f2fs(struct volume *v, uint64_t offset, const char *bdev)
 97 {
 98         uint64_t size = 0;
 99         bool ret = false;
100         int fd;
101 
102         fd = open(bdev, O_RDONLY);
103         if (fd < 0)
104                 return false;
105 
106         if (ioctl(fd, BLKGETSIZE64, &size) == 0)
107                 ret = size - offset > F2FS_MINSIZE;
108 
109         close(fd);
110 
111         return ret;
112 }
113 
114 int block_volume_format(struct volume *v, uint64_t offset, const char *bdev)
115 {
116         int ret = 0;
117         char str[128];
118         unsigned int skip_blocks = 0;
119         int fd;
120         __u32 deadc0de;
121         size_t sz;
122 
123         switch (volume_identify(v)) {
124         case FS_DEADCODE:
125                 /* skip padding */
126                 fd = open(v->blk, O_RDONLY);
127                 if (fd < 0) {
128                         ret = EIO;
129                         break;
130                 }
131                 do {
132                         if (lseek(fd, (skip_blocks + 1) * 512, SEEK_SET) == (off_t) -1) {
133                                 ret = EIO;
134                                 break;
135                         }
136                         sz = read(fd, &deadc0de, sizeof(deadc0de));
137                         if (sz != sizeof(deadc0de)) {
138                                 ret = EIO;
139                                 break;
140                         }
141                 } while(++skip_blocks <= 512 &&
142                         (deadc0de == cpu_to_be32(0xdeadc0de) || deadc0de == 0xffffffff));
143 
144                 close(fd);
145                 if (ret)
146                         break;
147 
148                 /* only try extracting in case gzip header is present */
149                 if (deadc0de != cpu_to_le32(0x88b1f))
150                         goto do_format;
151 
152                 /* fall-through */
153         case FS_TARGZ:
154                 snprintf(str, sizeof(str),
155                          "dd if=%s bs=512 skip=%u 2>/dev/null | gzip -cd > /tmp/sysupgrade.tar 2>/dev/null",
156                          v->blk, skip_blocks);
157                 ret = system(str);
158                 if (ret < 0) {
159                         ULOG_ERR("failed extracting config backup from %s\n", v->blk);
160                         break;
161                 }
162                 /* fall-through */
163         case FS_NONE:
164 do_format:
165                 ULOG_INFO("overlay filesystem in %s has not been formatted yet\n", v->blk);
166                 if (use_f2fs(v, offset, bdev))
167                         snprintf(str, sizeof(str), "mkfs.f2fs -q -f -l rootfs_data %s", v->blk);
168                 else
169                         snprintf(str, sizeof(str), "mkfs.ext4 -q -F -L rootfs_data %s", v->blk);
170 
171                 ret = system(str);
172                 break;
173         default:
174                 break;
175         }
176 
177         return ret;
178 }
179 

This page was automatically generated by LXR 0.3.1.  •  OpenWrt