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