Home | History | Annotate | Download | only in progs
      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(&param, 0, sizeof(struct ext2_super_block));
    314 	ext2fs_blocks_count_set(&param, 80000);
    315 	param.s_inodes_count = 20000;
    316 	retval = ext2fs_initialize("/dev/null", 0, &param,
    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