Update README.md
[mfat.git] / examples / fatdir.c
blob206a813fa506e7e8186dc3f65df4e6954f91a5f0
1 //--------------------------------------------------------------------------------------------------
2 // Copyright (C) 2022 Marcus Geelnard
3 //
4 // Redistribution and use in source and binary forms, with or without modification, are permitted
5 // provided that the following conditions are met:
6 //
7 // 1. Redistributions of source code must retain the above copyright notice, this list of
8 // conditions and the following disclaimer.
9 //
10 // 2. Redistributions in binary form must reproduce the above copyright notice, this list of
11 // conditions and the following disclaimer in the documentation and/or other materials provided
12 // with the distribution.
14 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
15 // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
16 // FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
17 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
19 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
20 // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
21 // WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
22 //--------------------------------------------------------------------------------------------------
24 #include <mfat.h>
26 #include <fcntl.h>
27 #include <stdio.h>
28 #include <string.h>
29 #include <sys/types.h>
30 #include <unistd.h>
32 static int blkread(char* ptr, unsigned block_no, void* custom) {
33 int fd = *(int*)custom;
34 if (lseek(fd, MFAT_BLOCK_SIZE * (size_t)block_no, SEEK_SET) == -1) {
35 return -1;
37 size_t num_bytes = read(fd, ptr, MFAT_BLOCK_SIZE);
38 return (num_bytes != MFAT_BLOCK_SIZE) && (num_bytes != 0) ? -1 : 0;
41 static int blkwrite(const char* ptr, unsigned block_no, void* custom) {
42 int fd = *(int*)custom;
43 if (lseek(fd, MFAT_BLOCK_SIZE * (size_t)block_no, SEEK_SET) == -1) {
44 return -1;
46 size_t num_bytes = write(fd, ptr, MFAT_BLOCK_SIZE);
47 return (num_bytes != MFAT_BLOCK_SIZE) && (num_bytes != 0) ? -1 : 0;
50 int main(int argc, char** argv) {
51 // Get arguments.
52 if (argc != 3) {
53 printf("Usage: %s FATIMAGE DIR\n", argv[0]);
54 return 1;
56 const char* img_path = argv[1];
57 const char* dir_name = argv[2];
59 // Open the FAT image file or device.
60 int img_fd = open(img_path, O_RDONLY);
61 if (img_fd == -1) {
62 fprintf(stderr, "*** Failed to open the FAT image\n");
63 return 1;
66 // Mount the image in MFAT.
67 if (mfat_mount(blkread, blkwrite, &img_fd) == -1) {
68 close(img_fd);
69 fprintf(stderr, "*** Failed to init MFAT\n");
70 return 1;
73 // Show the files in the directory.
74 mfat_dir_t* dirp = mfat_opendir(dir_name);
75 if (dirp != NULL) {
76 mfat_dirent_t* dirent;
77 while ((dirent = mfat_readdir(dirp)) != NULL) {
78 // Construct full path.
79 char path[256];
80 snprintf(&path[0], 255, "%s/%s", dir_name, dirent->d_name);
81 path[255] = 0;
83 // Stat and print file info + name.
84 mfat_stat_t stat;
85 if (mfat_stat(path, &stat) != -1) {
86 printf("%u-%02u-%02u %02u:%02u:%02u\t%s\t%u\t%s\n",
87 stat.st_mtim.year,
88 stat.st_mtim.month,
89 stat.st_mtim.day,
90 stat.st_mtim.hour,
91 stat.st_mtim.minute,
92 stat.st_mtim.second,
93 MFAT_S_ISDIR(stat.st_mode) ? "<DIR>" : "",
94 stat.st_size,
95 dirent->d_name);
96 } else {
97 fprintf(stderr, "*** Failed to stat %s\n", path);
100 mfat_closedir(dirp);
101 } else {
102 fprintf(stderr, "*** Failed to open dir %s\n", dir_name);
105 // Unmount and close down.
106 mfat_unmount();
107 close(img_fd);
109 return 0;