1 /* 2 * Test filesystem listing concurrency limitations. 3 * 4 * Copyright (C) 2019, 2021 Paul Boddie <paul@boddie.org.uk> 5 * 6 * This program is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU General Public License as 8 * published by the Free Software Foundation; either version 2 of 9 * the License, or (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, 19 * Boston, MA 02110-1301, USA 20 */ 21 22 #include <stdio.h> 23 #include <stdlib.h> 24 #include <string.h> 25 26 #include <sys/types.h> 27 #include <sys/stat.h> 28 29 #include <ext2fs/ext2fs.h> 30 31 #include "file.h" 32 #include "format.h" 33 #include "image.h" 34 #include "path.h" 35 36 37 38 /* Show directory entries when iterating. */ 39 40 static int image_list_dir_proc(struct ext2_dir_entry *dirent, int offset, 41 int blocksize, char *buf, void *priv_data) 42 { 43 ext2_filsys fs = (ext2_filsys) priv_data; 44 struct ext2_inode inode; 45 ext2_file_t file; 46 __u64 size; 47 char *to_remove[] = {"file0061", "file0062", "file0063", "file0125", "file0126", "file0127", 0}; 48 char **f; 49 50 /* Obtain the inode details for metadata. */ 51 52 if (ext2fs_read_inode(fs, dirent->inode, &inode)) 53 return DIRENT_ABORT; 54 55 /* Output details in the style of "ls -l" showing directory, permissions, 56 owner, group and size information. */ 57 58 printf("%06d: %s%s %5d %5d %6d ", 59 offset, 60 _image_isdir(fs, dirent->inode) ? "d" : "-", 61 get_permission_string(inode.i_mode), 62 inode.i_uid, 63 inode.i_gid, 64 EXT2_I_SIZE(&inode)); 65 66 /* Output the name which is presumably not necessarily null-terminated. */ 67 68 fwrite(dirent->name, sizeof(char), ext2fs_dirent_name_len(dirent), stdout); 69 fputc((int) '\n', stdout); 70 71 /* Remove files at an awkward point in time. */ 72 73 if (!strncmp(dirent->name, "file0060", ext2fs_dirent_name_len(dirent))) 74 { 75 for (f = to_remove; *f; f++) 76 if (ext2fs_unlink(fs, EXT2_ROOT_INO, *f, 0, 0)) 77 printf("%s not removed!\n", *f); 78 } 79 80 return 0; 81 } 82 83 84 85 int main(int argc, char *argv[]) 86 { 87 int flags = EXT2_FLAG_RW; 88 char *fsname; 89 ext2_filsys fs = NULL; 90 errcode_t retval; 91 int exitcode = 0; 92 char basename[32]; 93 ext2_ino_t ino; 94 ext2_file_t file; 95 int i; 96 97 if (argc < 2) 98 { 99 printf("Usage: %s <device or image file>\n", argv[0]); 100 return 1; 101 } 102 103 fsname = argv[1]; 104 105 /* Open the filesystem image using the POSIX file access mechanism. */ 106 107 retval = ext2fs_open(fsname, flags, 0, 0, unix_io_manager, &fs); 108 if (retval) 109 { 110 printf("Could not open filesystem using %s\n", fsname); 111 return 1; 112 } 113 114 retval = ext2fs_read_bitmaps(fs); 115 if (retval) 116 { 117 printf("Could not read bitmaps from %s\n", fsname); 118 return 1; 119 } 120 121 printf("Filesystem with blocksize %d\n", fs->blocksize); 122 123 /* Create some files. */ 124 125 for (i = 1; i <= 200; i++) 126 { 127 sprintf(basename, "file%04d", i); 128 129 retval = image_create_file(fs, EXT2_ROOT_INO, basename, 0644, 130 1000, 1000, &ino); 131 132 if (retval) 133 { 134 printf("Could not create file %s\n", basename); 135 return 1; 136 } 137 138 if (ext2fs_file_open(fs, ino, EXT2_FILE_WRITE | EXT2_FILE_CREATE, &file)) 139 { 140 printf("Could not write file %s\n", basename); 141 return 1; 142 } 143 144 ext2fs_file_flush(file); 145 ext2fs_file_close(file); 146 } 147 148 image_list_dir(fs, "", image_list_dir_proc, fs); 149 image_list_dir(fs, "", image_list_dir_proc, fs); 150 151 /* Close the filesystem image. */ 152 153 retval = ext2fs_flush(fs); 154 if (retval) 155 { 156 printf("Error flushing filesystem in %s\n", fsname); 157 exitcode = 1; 158 } 159 160 retval = ext2fs_close(fs); 161 if (retval) 162 { 163 printf("Error closing filesystem in %s\n", fsname); 164 exitcode = 1; 165 } 166 167 ext2fs_free(fs); 168 return exitcode; 169 }