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 <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 	if (f != stdin)
    293 		fclose(f);
    294 	return exit_status;
    295 }
    296 
    297 int main(int argc, char **argv)
    298 {
    299 	int		retval;
    300 	int		sci_idx;
    301 	int		c;
    302 	char		*request = 0;
    303 	int		exit_status = 0;
    304 	char		*cmd_file = 0;
    305 	struct ext2_super_block param;
    306 
    307 	initialize_ext2_error_table();
    308 
    309 	/*
    310 	 * Create a sample filesystem structure
    311 	 */
    312 	memset(&param, 0, sizeof(struct ext2_super_block));
    313 	ext2fs_blocks_count_set(&param, 80000);
    314 	param.s_inodes_count = 20000;
    315 	retval = ext2fs_initialize("/dev/null", 0, &param,
    316 				   unix_io_manager, &test_fs);
    317 	if (retval) {
    318 		com_err("/dev/null", retval, "while setting up test fs");
    319 		exit(1);
    320 	}
    321 
    322 	while ((c = getopt (argc, argv, "wR:f:")) != EOF) {
    323 		switch (c) {
    324 		case 'R':
    325 			request = optarg;
    326 			break;
    327 		case 'f':
    328 			cmd_file = optarg;
    329 			break;
    330 		default:
    331 			com_err(argv[0], 0, "Usage: test_icount "
    332 				"[-R request] [-f cmd_file]");
    333 			exit(1);
    334 		}
    335 	}
    336 	sci_idx = ss_create_invocation("test_icount", "0.0", (char *) NULL,
    337 				       &test_cmds, &retval);
    338 	if (retval) {
    339 		ss_perror(sci_idx, retval, "creating invocation");
    340 		exit(1);
    341 	}
    342 
    343 	(void) ss_add_request_table (sci_idx, &ss_std_requests, 1, &retval);
    344 	if (retval) {
    345 		ss_perror(sci_idx, retval, "adding standard requests");
    346 		exit (1);
    347 	}
    348 	if (request) {
    349 		retval = 0;
    350 		retval = ss_execute_line(sci_idx, request);
    351 		if (retval) {
    352 			ss_perror(sci_idx, retval, request);
    353 			exit_status++;
    354 		}
    355 	} else if (cmd_file) {
    356 		exit_status = source_file(cmd_file, sci_idx);
    357 	} else {
    358 		ss_listen(sci_idx);
    359 	}
    360 
    361 	return(exit_status);
    362 }
    363