]>
glassweightruler.freedombox.rocks Git - Ventoy.git/blob - Vlnk/src/main_linux.c
9 #include <sys/statfs.h>
19 #define IS_DIGIT(x) ((x) >= '0' && (x) <= '9')
21 static int verbose
= 0;
22 #define debug(fmt, args...) if(verbose) printf(fmt, ##args)
24 static uint8_t g_vlnk_buf
[VLNK_FILE_LEN
];
26 static int64_t get_file_size(char *file
)
30 if (stat(file
, &stStat
) < 0)
35 return (int64_t)(stStat
.st_size
);
38 static int get_disk_sig(char *diskname
, uint32_t *sig
)
41 uint8_t buf
[512] = {0};
43 fd
= open(diskname
, O_RDONLY
);
46 printf("Failed to open %s\n", diskname
);
53 memcpy(sig
, buf
+ 0x1b8, 4);
57 static int vtoy_get_disk_guid(const char *diskname
, uint8_t *vtguid
, uint8_t *vtsig
)
61 char devdisk
[128] = {0};
63 snprintf(devdisk
, sizeof(devdisk
) - 1, "/dev/%s", diskname
);
65 fd
= open(devdisk
, O_RDONLY
);
68 lseek(fd
, 0x180, SEEK_SET
);
71 lseek(fd
, 0x1b8, SEEK_SET
);
78 debug("failed to open %s %d\n", devdisk
, errno
);
83 static int vtoy_is_possible_blkdev(const char *name
)
91 if (name
[0] == 'r' && name
[1] == 'a' && name
[2] == 'm')
97 if (name
[0] == 'l' && name
[1] == 'o' && name
[2] == 'o' && name
[3] == 'p')
103 if (name
[0] == 'd' && name
[1] == 'm' && name
[2] == '-' && IS_DIGIT(name
[3]))
109 if (name
[0] == 's' && name
[1] == 'r' && IS_DIGIT(name
[2]))
118 static int find_disk_by_sig(uint8_t *sig
, char *diskname
)
123 struct dirent
* p
= NULL
;
127 dir
= opendir("/sys/block");
133 while ((p
= readdir(dir
)) != NULL
)
135 if (!vtoy_is_possible_blkdev(p
->d_name
))
140 rc
= vtoy_get_disk_guid(p
->d_name
, vtguid
, vtsig
);
141 if (rc
== 0 && memcmp(vtsig
, sig
, 4) == 0)
143 sprintf(diskname
, "%s", p
->d_name
);
152 static uint64_t get_part_offset(char *partname
)
159 snprintf(path
, PATH_MAX
- 1, "/sys/class/block/%s/start", partname
);
161 fd
= open(path
, O_RDONLY
);
167 read(fd
, buf
, sizeof(buf
));
170 offset
= (uint64_t)strtoull(buf
, NULL
, 10);
176 static int create_vlnk(char *infile
, char *diskname
, uint64_t partoff
, char *outfile
)
182 debug("create vlnk\n");
184 if (infile
[0] == 0 || outfile
[0] == 0 || diskname
[0] == 0 || partoff
== 0)
186 debug("Invalid parameters: %d %d %d %llu\n", infile
[0], outfile
[0], diskname
[0], (unsigned long long)partoff
);
190 len
= (int)strlen(infile
);
191 if (len
>= VLNK_NAME_MAX
)
193 printf("File name length %d is too long for vlnk!\n", len
);
197 if (get_disk_sig(diskname
, &sig
))
199 printf("Failed to read disk sig\n");
203 fp
= fopen(outfile
, "wb+");
206 printf("Failed to create file %s\n", outfile
);
210 memset(g_vlnk_buf
, 0, sizeof(g_vlnk_buf
));
211 ventoy_create_vlnk(sig
, partoff
, infile
, (ventoy_vlnk
*)g_vlnk_buf
);
212 fwrite(g_vlnk_buf
, 1, VLNK_FILE_LEN
, fp
);
218 static int get_mount_point(char *partname
, char *mntpoint
)
226 fp
= fopen("/proc/mounts", "r");
232 len
= (int)strlen(partname
);
233 while (fgets(line
, sizeof(line
), fp
))
235 if (strncmp(line
, partname
, len
) == 0)
237 for (i
= len
; i
< PATH_MAX
&& line
[i
]; i
++)
243 strncpy(mntpoint
, line
+ len
, PATH_MAX
- 1);
255 static int parse_vlnk(char *infile
)
261 char diskname
[128] = {0};
262 char partname
[128] = {0};
263 char partpath
[256] = {0};
264 char mntpoint
[PATH_MAX
];
267 debug("parse vlnk\n");
271 debug("input file null\n");
275 fd
= open(infile
, O_RDONLY
);
278 printf("Failed to open file %s error %d\n", infile
, errno
);
282 memset(&vlnk
, 0, sizeof(vlnk
));
283 read(fd
, &vlnk
, sizeof(vlnk
));
286 debug("disk_signature:%08X\n", vlnk
.disk_signature
);
287 debug("file path:<%s>\n", vlnk
.filepath
);
288 debug("part offset: %llu\n", (unsigned long long)vlnk
.part_offset
);
290 cnt
= find_disk_by_sig((uint8_t *)&(vlnk
.disk_signature
), diskname
);
293 printf("Disk in vlnk not found!\n");
297 debug("Disk is <%s>\n", diskname
);
299 if (strstr(diskname
, "nvme") || strstr(diskname
, "mmc") || strstr(diskname
, "nbd"))
304 for (i
= 1; i
<= 128; i
++)
308 snprintf(partname
, sizeof(partname
) - 1, "%sp%d", diskname
, i
);
312 snprintf(partname
, sizeof(partname
) - 1, "%s%d", diskname
, i
);
315 if (get_part_offset(partname
) == vlnk
.part_offset
)
317 debug("Find correct partition </dev/%s>\n", partname
);
324 printf("Partition in vlnk not found!");
328 snprintf(partpath
, sizeof(partpath
), "/dev/%s ", partname
);
329 if (get_mount_point(partpath
, mntpoint
))
331 printf("Mountpoint of %s is not found!\n", partpath
);
334 debug("moutpoint of %s is <%s>\n", partpath
, mntpoint
);
336 strcat(mntpoint
, vlnk
.filepath
);
337 printf("Vlnk Point: %s\n", mntpoint
);
338 if (access(mntpoint
, F_OK
) >= 0)
340 printf("File Exist: YES\n");
344 printf("File Exist: NO\n");
350 static int check_vlnk(char *infile
)
356 debug("check vlnk\n");
360 debug("input file null\n");
364 size
= get_file_size(infile
);
365 if (size
!= VLNK_FILE_LEN
)
367 debug("file size %lld is not a vlnk file size\n", (long long)size
);
371 fd
= open(infile
, O_RDONLY
);
374 debug("Failed to open file %s error %d\n", infile
, errno
);
378 memset(&vlnk
, 0, sizeof(vlnk
));
379 read(fd
, &vlnk
, sizeof(vlnk
));
382 if (CheckVlnkData(&vlnk
))
390 int main(int argc
, char **argv
)
394 uint64_t partoff
= 0;
395 char infile
[PATH_MAX
] = {0};
396 char outfile
[PATH_MAX
] = {0};
397 char diskname
[256] = {0};
399 while ((ch
= getopt(argc
, argv
, "c:t:l:d:p:o:v::")) != -1)
404 strncpy(infile
, optarg
, sizeof(infile
) - 1);
408 strncpy(outfile
, optarg
, sizeof(outfile
) - 1);
413 strncpy(infile
, optarg
, sizeof(infile
) - 1);
418 strncpy(infile
, optarg
, sizeof(infile
) - 1);
422 strncpy(diskname
, optarg
, sizeof(diskname
) - 1);
426 partoff
= (uint64_t)strtoull(optarg
, NULL
, 10);
441 return create_vlnk(infile
, diskname
, partoff
, outfile
);
445 return parse_vlnk(infile
);
449 return check_vlnk(infile
);
453 printf("Invalid command %d\n", cmd
);