1 /* 2 * test_icount.c 3 * 4 * Copyright (C) 1997 Theodore Ts'o. 5 * 6 * %Begin-Header% 7 * This file may be redistributed under the terms of the GNU Public 8 * License. 9 * %End-Header% 10 */ 11 12 #include <stdio.h> 13 #include <stdlib.h> 14 #include <string.h> 15 #include <unistd.h> 16 #ifdef HAVE_GETOPT_H 17 #include <getopt.h> 18 #endif 19 #include <fcntl.h> 20 21 #include <ext2fs/ext2_fs.h> 22 23 #include <et/com_err.h> 24 #include <ss/ss.h> 25 #include <ext2fs/ext2fs.h> 26 #include <ext2fs/irel.h> 27 #include <ext2fs/brel.h> 28 29 extern ss_request_table test_cmds; 30 31 #include "test_icount.h" 32 33 ext2_filsys test_fs; 34 ext2_icount_t test_icount; 35 36 /* 37 * Helper function which assures that the icount structure is valid 38 */ 39 static int check_icount(char *request) 40 { 41 if (test_icount) 42 return 0; 43 com_err(request, 0, "The icount structure must be allocated."); 44 return 1; 45 } 46 47 /* 48 * Helper function which parses an inode number. 49 */ 50 static int parse_inode(const char *request, const char *desc, 51 const char *str, ext2_ino_t *ino) 52 { 53 char *tmp; 54 55 *ino = strtoul(str, &tmp, 0); 56 if (*tmp) { 57 com_err(request, 0, "Bad %s - %s", desc, str); 58 return 1; 59 } 60 return 0; 61 } 62 63 void do_create_icount(int argc, char **argv) 64 { 65 errcode_t retval; 66 char *progname; 67 int flags = 0; 68 ext2_ino_t size = 5; 69 70 progname = *argv; 71 argv++; argc --; 72 73 if (argc && !strcmp("-i", *argv)) { 74 flags |= EXT2_ICOUNT_OPT_INCREMENT; 75 argv++; argc--; 76 } 77 if (argc) { 78 if (parse_inode(progname, "icount size", argv[0], &size)) 79 return; 80 argv++; argc--; 81 } 82 #if 0 83 printf("Creating icount... flags=%d, size=%d\n", flags, (int) size); 84 #endif 85 retval = ext2fs_create_icount(test_fs, flags, (int) size, 86 &test_icount); 87 if (retval) { 88 com_err(progname, retval, "while creating icount"); 89 return; 90 } 91 } 92 93 void do_free_icount(int argc, char **argv) 94 { 95 if (check_icount(argv[0])) 96 return; 97 98 ext2fs_free_icount(test_icount); 99 test_icount = 0; 100 } 101 102 void do_fetch(int argc, char **argv) 103 { 104 const char *usage = "usage: %s inode\n"; 105 errcode_t retval; 106 ext2_ino_t ino; 107 __u16 count; 108 109 if (argc < 2) { 110 printf(usage, argv[0]); 111 return; 112 } 113 if (check_icount(argv[0])) 114 return; 115 if (parse_inode(argv[0], "inode", argv[1], &ino)) 116 return; 117 retval = ext2fs_icount_fetch(test_icount, ino, &count); 118 if (retval) { 119 com_err(argv[0], retval, "while calling ext2fs_icount_fetch"); 120 return; 121 } 122 printf("Count is %u\n", count); 123 } 124 125 void do_increment(int argc, char **argv) 126 { 127 const char *usage = "usage: %s inode\n"; 128 errcode_t retval; 129 ext2_ino_t ino; 130 __u16 count; 131 132 if (argc < 2) { 133 printf(usage, argv[0]); 134 return; 135 } 136 if (check_icount(argv[0])) 137 return; 138 if (parse_inode(argv[0], "inode", argv[1], &ino)) 139 return; 140 retval = ext2fs_icount_increment(test_icount, ino, &count); 141 if (retval) { 142 com_err(argv[0], retval, 143 "while calling ext2fs_icount_increment"); 144 return; 145 } 146 printf("Count is now %u\n", count); 147 } 148 149 void do_decrement(int argc, char **argv) 150 { 151 const char *usage = "usage: %s inode\n"; 152 errcode_t retval; 153 ext2_ino_t ino; 154 __u16 count; 155 156 if (argc < 2) { 157 printf(usage, argv[0]); 158 return; 159 } 160 if (check_icount(argv[0])) 161 return; 162 if (parse_inode(argv[0], "inode", argv[1], &ino)) 163 return; 164 retval = ext2fs_icount_decrement(test_icount, ino, &count); 165 if (retval) { 166 com_err(argv[0], retval, 167 "while calling ext2fs_icount_decrement"); 168 return; 169 } 170 printf("Count is now %u\n", count); 171 } 172 173 void do_store(int argc, char **argv) 174 { 175 const char *usage = "usage: %s inode count\n"; 176 errcode_t retval; 177 ext2_ino_t ino; 178 ext2_ino_t count; 179 180 if (argc < 3) { 181 printf(usage, argv[0]); 182 return; 183 } 184 if (check_icount(argv[0])) 185 return; 186 if (parse_inode(argv[0], "inode", argv[1], &ino)) 187 return; 188 if (parse_inode(argv[0], "count", argv[2], &count)) 189 return; 190 if (count > 65535) { 191 printf("Count too large.\n"); 192 return; 193 } 194 retval = ext2fs_icount_store(test_icount, ino, (__u16) count); 195 if (retval) { 196 com_err(argv[0], retval, 197 "while calling ext2fs_icount_store"); 198 return; 199 } 200 } 201 202 void do_dump(int argc, char **argv) 203 { 204 errcode_t retval; 205 ext2_ino_t i; 206 __u16 count; 207 208 if (check_icount(argv[0])) 209 return; 210 for (i=1; i <= test_fs->super->s_inodes_count; i++) { 211 retval = ext2fs_icount_fetch(test_icount, i, &count); 212 if (retval) { 213 com_err(argv[0], retval, 214 "while fetching icount for %lu", (unsigned long)i); 215 return; 216 } 217 if (count) 218 printf("%lu: %u\n", (unsigned long)i, count); 219 } 220 } 221 222 void do_validate(int argc, char **argv) 223 { 224 errcode_t retval; 225 226 if (check_icount(argv[0])) 227 return; 228 retval = ext2fs_icount_validate(test_icount, stdout); 229 if (retval) { 230 com_err(argv[0], retval, "while validating icount structure"); 231 return; 232 } 233 printf("Icount structure successfully validated\n"); 234 } 235 236 void do_get_size(int argc, char **argv) 237 { 238 ext2_ino_t size; 239 240 if (check_icount(argv[0])) 241 return; 242 size = ext2fs_get_icount_size(test_icount); 243 printf("Size of icount is: %lu\n", (unsigned long)size); 244 } 245 246 static int source_file(const char *cmd_file, int sci_idx) 247 { 248 FILE *f; 249 char buf[256]; 250 char *cp; 251 int exit_status = 0; 252 int retval; 253 int noecho; 254 255 if (strcmp(cmd_file, "-") == 0) 256 f = stdin; 257 else { 258 f = fopen(cmd_file, "r"); 259 if (!f) { 260 perror(cmd_file); 261 exit(1); 262 } 263 } 264 fflush(stdout); 265 fflush(stderr); 266 setbuf(stdout, NULL); 267 setbuf(stderr, NULL); 268 while (!feof(f)) { 269 if (fgets(buf, sizeof(buf), f) == NULL) 270 break; 271 if (buf[0] == '#') 272 continue; 273 noecho = 0; 274 if (buf[0] == '-') { 275 noecho = 1; 276 buf[0] = ' '; 277 } 278 cp = strchr(buf, '\n'); 279 if (cp) 280 *cp = 0; 281 cp = strchr(buf, '\r'); 282 if (cp) 283 *cp = 0; 284 if (!noecho) 285 printf("test_icount: %s\n", buf); 286 retval = ss_execute_line(sci_idx, buf); 287 if (retval) { 288 ss_perror(sci_idx, retval, buf); 289 exit_status++; 290 } 291 } 292 return exit_status; 293 } 294 295 int main(int argc, char **argv) 296 { 297 int retval; 298 int sci_idx; 299 int c; 300 char *request = 0; 301 int exit_status = 0; 302 char *cmd_file = 0; 303 struct ext2_super_block param; 304 305 initialize_ext2_error_table(); 306 307 /* 308 * Create a sample filesystem structure 309 */ 310 memset(¶m, 0, sizeof(struct ext2_super_block)); 311 param.s_blocks_count = 80000; 312 param.s_inodes_count = 20000; 313 retval = ext2fs_initialize("/dev/null", 0, ¶m, 314 unix_io_manager, &test_fs); 315 if (retval) { 316 com_err("/dev/null", retval, "while setting up test fs"); 317 exit(1); 318 } 319 320 while ((c = getopt (argc, argv, "wR:f:")) != EOF) { 321 switch (c) { 322 case 'R': 323 request = optarg; 324 break; 325 case 'f': 326 cmd_file = optarg; 327 break; 328 default: 329 com_err(argv[0], 0, "Usage: test_icount " 330 "[-R request] [-f cmd_file]"); 331 exit(1); 332 } 333 } 334 sci_idx = ss_create_invocation("test_icount", "0.0", (char *) NULL, 335 &test_cmds, &retval); 336 if (retval) { 337 ss_perror(sci_idx, retval, "creating invocation"); 338 exit(1); 339 } 340 341 (void) ss_add_request_table (sci_idx, &ss_std_requests, 1, &retval); 342 if (retval) { 343 ss_perror(sci_idx, retval, "adding standard requests"); 344 exit (1); 345 } 346 if (request) { 347 retval = 0; 348 retval = ss_execute_line(sci_idx, request); 349 if (retval) { 350 ss_perror(sci_idx, retval, request); 351 exit_status++; 352 } 353 } else if (cmd_file) { 354 exit_status = source_file(cmd_file, sci_idx); 355 } else { 356 ss_listen(sci_idx); 357 } 358 359 return(exit_status); 360 } 361