summaryrefslogtreecommitdiffstats
path: root/tests/progs
diff options
context:
space:
mode:
Diffstat (limited to 'tests/progs')
-rw-r--r--tests/progs/Makefile.in83
-rw-r--r--tests/progs/crcsum.c67
-rw-r--r--tests/progs/hold_inode.c48
-rw-r--r--tests/progs/random_exercise.c171
-rw-r--r--tests/progs/test_data/bma.setup1
-rw-r--r--tests/progs/test_data/expect.brel41
-rw-r--r--tests/progs/test_data/expect.icount193
-rw-r--r--tests/progs/test_data/expect.irel62
-rw-r--r--tests/progs/test_data/ima.setup1
-rw-r--r--tests/progs/test_data/normal.setup1
-rw-r--r--tests/progs/test_data/opt.setup1
-rw-r--r--tests/progs/test_data/test.brel47
-rw-r--r--tests/progs/test_data/test.icount136
-rw-r--r--tests/progs/test_data/test.irel69
-rw-r--r--tests/progs/test_icount.c384
-rw-r--r--tests/progs/test_icount.h10
-rw-r--r--tests/progs/test_icount_cmds.ct37
-rw-r--r--tests/progs/test_rel.c764
-rw-r--r--tests/progs/test_rel.h35
-rw-r--r--tests/progs/test_rel_cmds.ct82
20 files changed, 2233 insertions, 0 deletions
diff --git a/tests/progs/Makefile.in b/tests/progs/Makefile.in
new file mode 100644
index 0000000..e1325c6
--- /dev/null
+++ b/tests/progs/Makefile.in
@@ -0,0 +1,83 @@
+#
+# Standard e2fsprogs prologue....
+#
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+top_builddir = ../..
+my_dir = tests/progs
+INSTALL = @INSTALL@
+MKDIR_P = @MKDIR_P@
+
+@MCONFIG@
+
+MK_CMDS= _SS_DIR_OVERRIDE=$(srcdir)/../../lib/ss ../../lib/ss/mk_cmds
+
+PROGS= test_icount crcsum
+
+TEST_REL_OBJS= test_rel.o test_rel_cmds.o
+
+TEST_ICOUNT_OBJS= test_icount.o test_icount_cmds.o
+
+SRCS= $(srcdir)/test_rel.c
+
+LIBS= $(LIBEXT2FS) $(LIBSS) $(LIBCOM_ERR) $(SYSLIBS)
+DEPLIBS= $(LIBEXT2FS) $(DEPLIBSS) $(DEPLIBCOM_ERR)
+
+.c.o:
+ $(E) " CC $<"
+ $(Q) $(CC) -c $(ALL_CFLAGS) $< -o $@
+ $(Q) $(CHECK_CMD) $(ALL_CFLAGS) $<
+ $(Q) $(CPPCHECK_CMD) $(CPPFLAGS) $<
+
+all:: $(PROGS)
+
+test_rel: $(TEST_REL_OBJS) $(DEPLIBS)
+ $(E) " LD $@"
+ $(Q) $(LD) $(ALL_LDFLAGS) -o test_rel $(TEST_REL_OBJS) $(LIBS)
+
+crcsum: crcsum.o $(DEPLIBS)
+ $(E) " LD $@"
+ $(Q) $(LD) $(ALL_LDFLAGS) -o crcsum crcsum.o $(LIBS)
+
+test_rel_cmds.c: test_rel_cmds.ct
+ $(E) " MK_CMDS $@"
+ $(Q) $(MK_CMDS) $(srcdir)/test_rel_cmds.ct
+
+test_icount: $(TEST_ICOUNT_OBJS) $(DEPLIBS)
+ $(E) " LD $@"
+ $(Q) $(LD) $(ALL_LDFLAGS) -o test_icount $(TEST_ICOUNT_OBJS) $(LIBS)
+
+test_icount_cmds.c: test_icount_cmds.ct
+ $(E) " MK_CMDS $@"
+ $(Q) $(MK_CMDS) $(srcdir)/test_icount_cmds.ct
+
+clean::
+ $(RM) -f $(PROGS) test_rel_cmds.c test_icount_cmds.c \
+ \#* *.s *.o *.a *~ core
+
+install:
+
+install-strip:
+
+uninstall:
+
+mostlyclean: clean
+distclean: clean
+ $(RM) -f .depend Makefile $(srcdir)/TAGS $(srcdir)/Makefile.in.old
+
+# +++ Dependency line eater +++
+#
+# Makefile dependencies follow. This must be the last section in
+# the Makefile.in file
+#
+test_rel.o: $(srcdir)/test_rel.c $(top_builddir)/lib/config.h \
+ $(top_builddir)/lib/dirpaths.h $(top_srcdir)/lib/et/com_err.h \
+ $(top_srcdir)/lib/ss/ss.h $(top_builddir)/lib/ss/ss_err.h \
+ $(top_srcdir)/lib/ext2fs/ext2_fs.h $(top_builddir)/lib/ext2fs/ext2_types.h \
+ $(top_srcdir)/lib/ext2fs/ext2fs.h $(top_srcdir)/lib/ext2fs/ext3_extents.h \
+ $(top_srcdir)/lib/ext2fs/ext2_io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
+ $(top_srcdir)/lib/ext2fs/ext2_ext_attr.h $(top_srcdir)/lib/ext2fs/hashmap.h \
+ $(top_srcdir)/lib/ext2fs/bitops.h $(top_srcdir)/lib/ext2fs/irel.h \
+ $(top_srcdir)/lib/ext2fs/brel.h $(srcdir)/test_rel.h
diff --git a/tests/progs/crcsum.c b/tests/progs/crcsum.c
new file mode 100644
index 0000000..193bf0a
--- /dev/null
+++ b/tests/progs/crcsum.c
@@ -0,0 +1,67 @@
+/*
+ * crcsum.c
+ *
+ * Copyright (C) 2013 Theodore Ts'o.
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Public
+ * License.
+ * %End-Header%
+ */
+
+#include "config.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+#include <unistd.h>
+#ifdef HAVE_GETOPT_H
+#include <getopt.h>
+#endif
+#include <fcntl.h>
+
+#include "et/com_err.h"
+#include "ss/ss.h"
+#include "ext2fs/ext2fs.h"
+
+
+int main(int argc, char **argv)
+{
+ int c;
+ uint32_t crc = ~0;
+ uint32_t (*csum_func)(uint32_t crc, unsigned char const *p,
+ size_t len);
+ FILE *f;
+
+ csum_func = ext2fs_crc32c_le;
+
+ while ((c = getopt (argc, argv, "h")) != EOF) {
+ switch (c) {
+ case 'h':
+ default:
+ com_err(argv[0], 0, "Usage: crcsum [file]\n");
+ return 1;
+ }
+ }
+
+ if (optind == argc)
+ f = stdin;
+ else {
+ f = fopen(argv[optind], "r");
+ if (!f) {
+ com_err(argv[0], errno, "while trying to open %s\n",
+ argv[optind]);
+ exit(1);
+ }
+ }
+
+ while (!feof(f)) {
+ unsigned char buf[4096];
+ int cnt = fread(buf, 1, sizeof(buf), f);
+
+ if (cnt)
+ crc = csum_func(crc, buf, cnt);
+ }
+ printf("%u\n", crc);
+ return 0;
+}
diff --git a/tests/progs/hold_inode.c b/tests/progs/hold_inode.c
new file mode 100644
index 0000000..792aa71
--- /dev/null
+++ b/tests/progs/hold_inode.c
@@ -0,0 +1,48 @@
+/*
+ * hold_inode.c --- test program which holds an inode or directory
+ * open.
+ *
+ * Copyright (C) 2000 Theodore Ts'o.
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Public
+ * License.
+ * %End-Header%
+ */
+
+#include "config.h"
+#include <unistd.h>
+#include <stdio.h>
+#include <dirent.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+
+main(int argc, char **argv)
+{
+ struct stat statbuf;
+ char *filename;
+
+ if (argc != 2) {
+ fprintf(stderr, "Usage: %s dir\n", argv[0]);
+ exit(1);
+ }
+ filename = argv[1];
+ if (stat(filename, &statbuf) < 0) {
+ perror(filename);
+ exit(1);
+ }
+ if (S_ISDIR(statbuf.st_mode)) {
+ if (!opendir(filename)) {
+ perror(filename);
+ exit(1);
+ }
+ } else {
+ if (open(filename, O_RDONLY) < 0) {
+ perror(filename);
+ exit(1);
+ }
+ }
+ sleep(30);
+}
diff --git a/tests/progs/random_exercise.c b/tests/progs/random_exercise.c
new file mode 100644
index 0000000..38217ab
--- /dev/null
+++ b/tests/progs/random_exercise.c
@@ -0,0 +1,171 @@
+/*
+ * random_exercise.c --- Test program which exercises an ext2
+ * filesystem. It creates a lot of random files in the current
+ * directory, while holding some files open while they are being
+ * deleted. This exercises the orphan list code, as well as
+ * creating lots of fodder for the ext3 journal.
+ *
+ * Copyright (C) 2000 Theodore Ts'o.
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Public
+ * License.
+ * %End-Header%
+ */
+
+#include "config.h"
+#include <unistd.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#define MAXFDS 128
+
+struct state {
+ char name[16];
+ int state;
+ int isdir;
+};
+
+#define STATE_CLEAR 0
+#define STATE_CREATED 1
+#define STATE_DELETED 2
+
+struct state state_array[MAXFDS];
+
+#define DATA_SIZE 65536
+
+char data_buffer[DATA_SIZE];
+
+void clear_state_array()
+{
+ int i;
+
+ for (i = 0; i < MAXFDS; i++)
+ state_array[i].state = STATE_CLEAR;
+}
+
+int get_random_fd()
+{
+ int fd;
+
+ while (1) {
+ fd = ((int) random()) % MAXFDS;
+ if (fd > 2)
+ return fd;
+ }
+}
+
+unsigned int get_inode_num(int fd)
+{
+ struct stat st;
+
+ if (fstat(fd, &st) < 0) {
+ perror("fstat");
+ return 0;
+ }
+ return st.st_ino;
+}
+
+
+void create_random_file()
+{
+ char template[16] = "EX.XXXXXX";
+ int fd;
+ int isdir = 0;
+ int size;
+
+ mktemp(template);
+ isdir = random() & 1;
+ if (isdir) {
+ if (mkdir(template, 0700) < 0)
+ return;
+ fd = open(template, O_RDONLY, 0600);
+ printf("Created temp directory %s, fd = %d\n",
+ template, fd);
+ } else {
+ size = random() & (DATA_SIZE-1);
+ fd = open(template, O_CREAT|O_RDWR, 0600);
+ write(fd, data_buffer, size);
+ printf("Created temp file %s, fd = %d, size=%d\n",
+ template, fd, size);
+ }
+ state_array[fd].isdir = isdir;
+ if (fd < 0)
+ return;
+ state_array[fd].isdir = isdir;
+ state_array[fd].state = STATE_CREATED;
+ strcpy(state_array[fd].name, template);
+}
+
+void truncate_file(int fd)
+{
+ int size;
+
+ size = random() & (DATA_SIZE-1);
+
+ if (state_array[fd].isdir)
+ return;
+
+ ftruncate(fd, size);
+ printf("Truncating temp file %s, fd = %d, ino=%u, size=%d\n",
+ state_array[fd].name, fd, get_inode_num(fd), size);
+}
+
+
+void unlink_file(int fd)
+{
+ char *filename = state_array[fd].name;
+
+ printf("Deleting %s, fd = %d, ino = %u\n", filename, fd,
+ get_inode_num(fd));
+
+ if (state_array[fd].isdir)
+ rmdir(filename);
+ else
+ unlink(filename);
+ state_array[fd].state = STATE_DELETED;
+}
+
+void close_file(int fd)
+{
+ char *filename = state_array[fd].name;
+
+ printf("Closing %s, fd = %d, ino = %u\n", filename, fd,
+ get_inode_num(fd));
+
+ close(fd);
+ state_array[fd].state = STATE_CLEAR;
+}
+
+
+main(int argc, char **argv)
+{
+ int i, fd;
+
+ memset(data_buffer, 0, sizeof(data_buffer));
+ sprintf(data_buffer, "This is a test file created by the "
+ "random_exerciser program\n");
+
+ for (i=0; i < 100000; i++) {
+ fd = get_random_fd();
+ switch (state_array[fd].state) {
+ case STATE_CLEAR:
+ create_random_file();
+ break;
+ case STATE_CREATED:
+ if ((state_array[fd].isdir == 0) &&
+ (random() & 2))
+ truncate_file(fd);
+ else
+ unlink_file(fd);
+ break;
+ case STATE_DELETED:
+ close_file(fd);
+ break;
+ }
+ }
+}
+
+
diff --git a/tests/progs/test_data/bma.setup b/tests/progs/test_data/bma.setup
new file mode 100644
index 0000000..f47e511
--- /dev/null
+++ b/tests/progs/test_data/bma.setup
@@ -0,0 +1 @@
+-bma_create test 23
diff --git a/tests/progs/test_data/expect.brel b/tests/progs/test_data/expect.brel
new file mode 100644
index 0000000..0858659
--- /dev/null
+++ b/tests/progs/test_data/expect.brel
@@ -0,0 +1,41 @@
+test_rel: brel_dump
+test_rel: brel_put 2 11
+test_rel: brel_put 1 10
+test_rel: brel_put 3 9
+test_rel: brel_put 1 10 4 128
+test_rel: brel_put 23 12
+test_rel: brel_put 24 13
+brel_put: Invalid argument while calling ext2fs_brel_put
+test_rel: brel_get 24
+brel_get: Invalid argument while calling ext2fs_brel_get
+test_rel: brel_delete 24
+brel_delete: Invalid argument while calling ext2fs_brel_delete
+test_rel: brel_get 5
+brel_get: No such file or directory while calling ext2fs_brel_get
+test_rel: brel_get 3
+Old= 3, New= 9, Owner= 0:0
+test_rel: brel_get 1
+Old= 1, New= 10, Owner= 4:128
+test_rel: brel_start_iter
+test_rel: brel_next
+Old= 1, New= 10, Owner= 4:128
+test_rel: brel_next
+Old= 2, New= 11, Owner= 0:0
+test_rel: brel_next
+Old= 3, New= 9, Owner= 0:0
+test_rel: brel_next
+No more entries!
+test_rel: brel_delete 2
+test_rel: brel_delete 2
+brel_delete: No such file or directory while calling ext2fs_brel_delete
+test_rel: brel_delete 5
+brel_delete: No such file or directory while calling ext2fs_brel_delete
+test_rel: brel_move 1 2
+test_rel: brel_delete 1
+brel_delete: No such file or directory while calling ext2fs_brel_delete
+test_rel: brel_move 1 4
+brel_move: No such file or directory while calling ext2fs_brel_move
+test_rel: brel_move 2 5
+test_rel: brel_dump
+Old= 3, New= 9, Owner= 0:0
+Old= 5, New= 10, Owner= 4:128
diff --git a/tests/progs/test_data/expect.icount b/tests/progs/test_data/expect.icount
new file mode 100644
index 0000000..b58a373
--- /dev/null
+++ b/tests/progs/test_data/expect.icount
@@ -0,0 +1,193 @@
+test_icount: validate
+Icount structure successfully validated
+test_icount: store 0 0
+store: Invalid argument passed to ext2 library while calling ext2fs_icount_store
+test_icount: fetch 0
+fetch: Invalid argument passed to ext2 library while calling ext2fs_icount_fetch
+test_icount: increment 0
+increment: Invalid argument passed to ext2 library while calling ext2fs_icount_increment
+test_icount: decrement 0
+decrement: Invalid argument passed to ext2 library while calling ext2fs_icount_decrement
+test_icount: store 20001 0
+store: Invalid argument passed to ext2 library while calling ext2fs_icount_store
+test_icount: fetch 20001
+fetch: Invalid argument passed to ext2 library while calling ext2fs_icount_fetch
+test_icount: increment 20001
+increment: Invalid argument passed to ext2 library while calling ext2fs_icount_increment
+test_icount: decrement 20001
+decrement: Invalid argument passed to ext2 library while calling ext2fs_icount_decrement
+test_icount: validate
+Icount structure successfully validated
+test_icount: fetch 1
+Count is 0
+test_icount: store 1 1
+test_icount: fetch 1
+Count is 1
+test_icount: store 1 2
+test_icount: fetch 1
+Count is 2
+test_icount: store 1 3
+test_icount: fetch 1
+Count is 3
+test_icount: store 1 1
+test_icount: fetch 1
+Count is 1
+test_icount: store 1 0
+test_icount: fetch 1
+Count is 0
+test_icount: fetch 20000
+Count is 0
+test_icount: store 20000 0
+test_icount: fetch 20000
+Count is 0
+test_icount: store 20000 3
+test_icount: fetch 20000
+Count is 3
+test_icount: store 20000 0
+test_icount: fetch 20000
+Count is 0
+test_icount: store 20000 42
+test_icount: fetch 20000
+Count is 42
+test_icount: store 20000 1
+test_icount: fetch 20000
+Count is 1
+test_icount: store 20000 0
+test_icount: fetch 20000
+Count is 0
+test_icount: get_size
+Size of icount is: 5
+test_icount: decrement 2
+decrement: Invalid argument passed to ext2 library while calling ext2fs_icount_decrement
+test_icount: increment 2
+Count is now 1
+test_icount: fetch 2
+Count is 1
+test_icount: increment 2
+Count is now 2
+test_icount: fetch 2
+Count is 2
+test_icount: increment 2
+Count is now 3
+test_icount: fetch 2
+Count is 3
+test_icount: increment 2
+Count is now 4
+test_icount: fetch 2
+Count is 4
+test_icount: decrement 2
+Count is now 3
+test_icount: fetch 2
+Count is 3
+test_icount: decrement 2
+Count is now 2
+test_icount: fetch 2
+Count is 2
+test_icount: decrement 2
+Count is now 1
+test_icount: fetch 2
+Count is 1
+test_icount: decrement 2
+Count is now 0
+test_icount: decrement 2
+decrement: Invalid argument passed to ext2 library while calling ext2fs_icount_decrement
+test_icount: store 3 1
+test_icount: increment 3
+Count is now 2
+test_icount: fetch 3
+Count is 2
+test_icount: decrement 3
+Count is now 1
+test_icount: fetch 3
+Count is 1
+test_icount: decrement 3
+Count is now 0
+test_icount: store 4 0
+test_icount: fetch 4
+Count is 0
+test_icount: increment 4
+Count is now 1
+test_icount: increment 4
+Count is now 2
+test_icount: fetch 4
+Count is 2
+test_icount: decrement 4
+Count is now 1
+test_icount: decrement 4
+Count is now 0
+test_icount: store 4 42
+test_icount: store 4 0
+test_icount: increment 4
+Count is now 1
+test_icount: increment 4
+Count is now 2
+test_icount: increment 4
+Count is now 3
+test_icount: decrement 4
+Count is now 2
+test_icount: decrement 4
+Count is now 1
+test_icount: decrement 4
+Count is now 0
+test_icount: decrement 4
+decrement: Invalid argument passed to ext2 library while calling ext2fs_icount_decrement
+test_icount: decrement 4
+decrement: Invalid argument passed to ext2 library while calling ext2fs_icount_decrement
+test_icount: store 5 4
+test_icount: decrement 5
+Count is now 3
+test_icount: decrement 5
+Count is now 2
+test_icount: decrement 5
+Count is now 1
+test_icount: decrement 5
+Count is now 0
+test_icount: decrement 5
+decrement: Invalid argument passed to ext2 library while calling ext2fs_icount_decrement
+test_icount: get_size
+Size of icount is: 105
+test_icount: validate
+Icount structure successfully validated
+test_icount: store 10 10
+test_icount: store 20 20
+test_icount: store 30 30
+test_icount: store 40 40
+test_icount: store 50 50
+test_icount: store 60 60
+test_icount: store 70 70
+test_icount: store 80 80
+test_icount: store 90 90
+test_icount: store 100 100
+test_icount: store 15 15
+test_icount: store 25 25
+test_icount: store 35 35
+test_icount: store 45 45
+test_icount: store 55 55
+test_icount: store 65 65
+test_icount: store 75 75
+test_icount: store 85 85
+test_icount: store 95 95
+test_icount: dump
+10: 10
+15: 15
+20: 20
+25: 25
+30: 30
+35: 35
+40: 40
+45: 45
+50: 50
+55: 55
+60: 60
+65: 65
+70: 70
+75: 75
+80: 80
+85: 85
+90: 90
+95: 95
+100: 100
+test_icount: get_size
+Size of icount is: 105
+test_icount: validate
+Icount structure successfully validated
diff --git a/tests/progs/test_data/expect.irel b/tests/progs/test_data/expect.irel
new file mode 100644
index 0000000..8e47938
--- /dev/null
+++ b/tests/progs/test_data/expect.irel
@@ -0,0 +1,62 @@
+test_rel: irel_dump
+test_rel: irel_put 2 11 3
+test_rel: irel_put 1 10 2
+test_rel: irel_put 3 9 1
+test_rel: irel_add_ref 1 4 128
+test_rel: irel_add_ref 1 5 64
+test_rel: irel_add_ref 1 6 512
+irel_add_ref: No space left on device while calling ext2fs_irel_add_ref
+test_rel: irel_put 1 8 3
+test_rel: irel_add_ref 1 6 512
+test_rel: irel_add_ref 2 4 64
+test_rel: irel_put 23 12 1
+test_rel: irel_put 24 13 1
+irel_put: Invalid argument while calling ext2fs_irel_put
+test_rel: irel_get 24
+irel_get: Invalid argument while calling ext2fs_irel_get
+test_rel: irel_delete 24
+irel_delete: Invalid argument while calling ext2fs_irel_delete
+test_rel: irel_get 3
+Old= 3, New= 9, Original=3, Max_refs=1
+test_rel: irel_get 1
+Old= 1, New= 8, Original=1, Max_refs=3
+ 4:128, 5:64, 6:512
+test_rel: irel_start_iter
+test_rel: irel_next
+Old= 1, New= 8, Original=1, Max_refs=3
+ 4:128, 5:64, 6:512
+test_rel: irel_next
+Old= 2, New= 11, Original=2, Max_refs=3
+ 4:64
+test_rel: irel_next
+Old= 3, New= 9, Original=3, Max_refs=1
+test_rel: irel_next
+No more entries!
+test_rel: irel_delete 2
+test_rel: irel_delete 2
+irel_delete: No such file or directory while calling ext2fs_irel_delete
+test_rel: irel_delete 4
+irel_delete: No such file or directory while calling ext2fs_irel_delete
+test_rel: irel_move 1 2
+test_rel: irel_dump
+Old= 2, New= 8, Original=1, Max_refs=3
+ 4:128, 5:64, 6:512
+Old= 3, New= 9, Original=3, Max_refs=1
+test_rel: irel_delete 4
+irel_delete: No such file or directory while calling ext2fs_irel_delete
+test_rel: irel_move 1 4
+irel_move: No such file or directory while calling ext2fs_irel_move
+test_rel: irel_move 2 4
+test_rel: irel_dump
+Old= 3, New= 9, Original=3, Max_refs=1
+Old= 4, New= 8, Original=1, Max_refs=3
+ 4:128, 5:64, 6:512
+test_rel: irel_get_by_orig 3
+Old= 3, New= 9, Original=3, Max_refs=1
+test_rel: irel_get_by_orig 1
+Old= 4, New= 8, Original=1, Max_refs=3
+ 4:128, 5:64, 6:512
+test_rel: irel_get_by_orig 5
+irel_get_by_orig: No such file or directory while calling ext2fs_irel_get_by_orig
+test_rel: irel_get_by_orig 2
+irel_get_by_orig: No such file or directory while calling ext2fs_irel_get_by_orig
diff --git a/tests/progs/test_data/ima.setup b/tests/progs/test_data/ima.setup
new file mode 100644
index 0000000..f411606
--- /dev/null
+++ b/tests/progs/test_data/ima.setup
@@ -0,0 +1 @@
+-ima_create test 23
diff --git a/tests/progs/test_data/normal.setup b/tests/progs/test_data/normal.setup
new file mode 100644
index 0000000..dfc6c41
--- /dev/null
+++ b/tests/progs/test_data/normal.setup
@@ -0,0 +1 @@
+-create
diff --git a/tests/progs/test_data/opt.setup b/tests/progs/test_data/opt.setup
new file mode 100644
index 0000000..79458b0
--- /dev/null
+++ b/tests/progs/test_data/opt.setup
@@ -0,0 +1 @@
+-create -i
diff --git a/tests/progs/test_data/test.brel b/tests/progs/test_data/test.brel
new file mode 100644
index 0000000..6605452
--- /dev/null
+++ b/tests/progs/test_data/test.brel
@@ -0,0 +1,47 @@
+#
+# This is the test script for the block relocation table.
+#
+# Copyright 1997 by Theodore Ts'o. This file may be redistributed
+# under the terms of the GNU Public License.
+#
+#
+brel_dump
+brel_put 2 11
+brel_put 1 10
+brel_put 3 9
+brel_put 1 10 4 128
+#
+# Test boundary cases for brel_put
+#
+brel_put 23 12
+brel_put 24 13
+#
+# Test other boundary cases
+#
+brel_get 24
+brel_delete 24
+#
+# Test getting existing and non-existent entries
+#
+brel_get 5
+brel_get 3
+brel_get 1
+#
+# Test the iterator functions
+#
+brel_start_iter
+brel_next
+brel_next
+brel_next
+brel_next
+#
+# Test delete and move
+#
+brel_delete 2
+brel_delete 2
+brel_delete 5
+brel_move 1 2
+brel_delete 1
+brel_move 1 4
+brel_move 2 5
+brel_dump
diff --git a/tests/progs/test_data/test.icount b/tests/progs/test_data/test.icount
new file mode 100644
index 0000000..8cb1955
--- /dev/null
+++ b/tests/progs/test_data/test.icount
@@ -0,0 +1,136 @@
+#
+# This is the test script for the icount abstraction
+#
+# Copyright 1997 by Theodore Ts'o. This file may be redistributed
+# under the terms of the GNU Public License.
+#
+#
+# First let's test the boundary cases for illegal arguments
+#
+validate
+store 0 0
+fetch 0
+increment 0
+decrement 0
+store 20001 0
+fetch 20001
+increment 20001
+decrement 20001
+validate
+#
+# OK, now let's test fetch and store. We also test the boundary cases
+# for legal inodes here.
+#
+fetch 1
+store 1 1
+fetch 1
+store 1 2
+fetch 1
+store 1 3
+fetch 1
+store 1 1
+fetch 1
+store 1 0
+fetch 1
+fetch 20000
+store 20000 0
+fetch 20000
+store 20000 3
+fetch 20000
+store 20000 0
+fetch 20000
+store 20000 42
+fetch 20000
+store 20000 1
+fetch 20000
+store 20000 0
+fetch 20000
+get_size
+#
+# Time to test increment. First increment from 0 (previously unreferenced)
+#
+decrement 2
+increment 2
+fetch 2
+increment 2
+fetch 2
+increment 2
+fetch 2
+increment 2
+fetch 2
+decrement 2
+fetch 2
+decrement 2
+fetch 2
+decrement 2
+fetch 2
+decrement 2
+decrement 2
+#
+# Store 1 then test...
+#
+store 3 1
+increment 3
+fetch 3
+decrement 3
+fetch 3
+decrement 3
+#
+# Store 0 then test
+#
+store 4 0
+fetch 4
+increment 4
+increment 4
+fetch 4
+decrement 4
+decrement 4
+#
+# Store something, then store 0, then test...
+#
+store 4 42
+store 4 0
+increment 4
+increment 4
+increment 4
+decrement 4
+decrement 4
+decrement 4
+decrement 4
+decrement 4
+#
+# store something, then decrement to zero
+#
+store 5 4
+decrement 5
+decrement 5
+decrement 5
+decrement 5
+decrement 5
+#
+# Test insert
+#
+get_size
+validate
+store 10 10
+store 20 20
+store 30 30
+store 40 40
+store 50 50
+store 60 60
+store 70 70
+store 80 80
+store 90 90
+store 100 100
+store 15 15
+store 25 25
+store 35 35
+store 45 45
+store 55 55
+store 65 65
+store 75 75
+store 85 85
+store 95 95
+dump
+get_size
+validate
diff --git a/tests/progs/test_data/test.irel b/tests/progs/test_data/test.irel
new file mode 100644
index 0000000..6c338bc
--- /dev/null
+++ b/tests/progs/test_data/test.irel
@@ -0,0 +1,69 @@
+#
+# This is the test script for the inode relocation table.
+#
+# Copyright 1997 by Theodore Ts'o. This file may be redistributed
+# under the terms of the GNU Public License.
+#
+#
+irel_dump
+irel_put 2 11 3
+irel_put 1 10 2
+irel_put 3 9 1
+irel_add_ref 1 4 128
+irel_add_ref 1 5 64
+#
+# Check to see what happens if we add too many references
+#
+irel_add_ref 1 6 512
+#
+# Try resizing the number of references and retry the add
+#
+irel_put 1 8 3
+irel_add_ref 1 6 512
+#
+irel_add_ref 2 4 64
+#
+# Test boundary cases of irel_put
+#
+irel_put 23 12 1
+irel_put 24 13 1
+#
+# Test other boundary cases....
+#
+irel_get 24
+irel_delete 24
+#
+# Test retrivals
+#
+irel_get 3
+irel_get 1
+#
+# Test the iterator functions
+#
+irel_start_iter
+irel_next
+irel_next
+irel_next
+irel_next
+#
+# Now try the delete function, on existing and non-existent entries
+#
+irel_delete 2
+irel_delete 2
+irel_delete 4
+#
+# Move tests...
+#
+irel_move 1 2
+irel_dump
+irel_delete 4
+irel_move 1 4
+irel_move 2 4
+#
+# Get by orig tests
+#
+irel_dump
+irel_get_by_orig 3
+irel_get_by_orig 1
+irel_get_by_orig 5
+irel_get_by_orig 2
diff --git a/tests/progs/test_icount.c b/tests/progs/test_icount.c
new file mode 100644
index 0000000..6ebb100
--- /dev/null
+++ b/tests/progs/test_icount.c
@@ -0,0 +1,384 @@
+/*
+ * test_icount.c
+ *
+ * Copyright (C) 1997 Theodore Ts'o.
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Public
+ * License.
+ * %End-Header%
+ */
+
+#include "config.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#ifdef HAVE_GETOPT_H
+#include <getopt.h>
+#endif
+#include <fcntl.h>
+
+#include <ext2fs/ext2_fs.h>
+
+#include <et/com_err.h>
+#include <ss/ss.h>
+#include <ext2fs/ext2fs.h>
+#include <ext2fs/irel.h>
+#include <ext2fs/brel.h>
+
+extern ss_request_table test_cmds;
+
+#include "test_icount.h"
+
+ext2_filsys test_fs;
+ext2_icount_t test_icount;
+
+/*
+ * Helper function which assures that the icount structure is valid
+ */
+static int check_icount(char *request)
+{
+ if (test_icount)
+ return 0;
+ com_err(request, 0, "The icount structure must be allocated.");
+ return 1;
+}
+
+/*
+ * Helper function which parses an inode number.
+ */
+static int parse_inode(const char *request, const char *desc,
+ const char *str, ext2_ino_t *ino)
+{
+ char *tmp;
+
+ *ino = strtoul(str, &tmp, 0);
+ if (*tmp) {
+ com_err(request, 0, "Bad %s - %s", desc, str);
+ return 1;
+ }
+ return 0;
+}
+
+void do_create_icount(int argc, char **argv, int sci_idx EXT2FS_ATTR((unused)),
+ void *infop EXT2FS_ATTR((unused)))
+{
+ errcode_t retval;
+ char *progname;
+ int flags = 0;
+ ext2_ino_t size = 5;
+
+ progname = *argv;
+ argv++; argc --;
+
+ if (argc && !strcmp("-i", *argv)) {
+ flags |= EXT2_ICOUNT_OPT_INCREMENT;
+ argv++; argc--;
+ }
+ if (argc) {
+ if (parse_inode(progname, "icount size", argv[0], &size))
+ return;
+ argv++; argc--;
+ }
+#if 0
+ printf("Creating icount... flags=%d, size=%d\n", flags, (int) size);
+#endif
+ retval = ext2fs_create_icount(test_fs, flags, (int) size,
+ &test_icount);
+ if (retval) {
+ com_err(progname, retval, "while creating icount");
+ return;
+ }
+}
+
+void do_free_icount(int argc, char **argv, int sci_idx EXT2FS_ATTR((unused)),
+ void *infop EXT2FS_ATTR((unused)))
+{
+ if (argc != 1) {
+ printf("Usage: free_icount\n");
+ return;
+ }
+ if (check_icount(argv[0]))
+ return;
+
+ ext2fs_free_icount(test_icount);
+ test_icount = 0;
+}
+
+void do_fetch(int argc, char **argv, int sci_idx EXT2FS_ATTR((unused)),
+ void *infop EXT2FS_ATTR((unused)))
+{
+ errcode_t retval;
+ ext2_ino_t ino;
+ __u16 count;
+
+ if (argc < 2) {
+ printf("usage: %s inode\n", argv[0]);
+ return;
+ }
+ if (check_icount(argv[0]))
+ return;
+ if (parse_inode(argv[0], "inode", argv[1], &ino))
+ return;
+ retval = ext2fs_icount_fetch(test_icount, ino, &count);
+ if (retval) {
+ com_err(argv[0], retval, "while calling ext2fs_icount_fetch");
+ return;
+ }
+ printf("Count is %u\n", count);
+}
+
+void do_increment(int argc, char **argv, int sci_idx EXT2FS_ATTR((unused)),
+ void *infop EXT2FS_ATTR((unused)))
+{
+ errcode_t retval;
+ ext2_ino_t ino;
+ __u16 count;
+
+ if (argc < 2) {
+ printf("usage: %s inode\n", argv[0]);
+ return;
+ }
+ if (check_icount(argv[0]))
+ return;
+ if (parse_inode(argv[0], "inode", argv[1], &ino))
+ return;
+ retval = ext2fs_icount_increment(test_icount, ino, &count);
+ if (retval) {
+ com_err(argv[0], retval,
+ "while calling ext2fs_icount_increment");
+ return;
+ }
+ printf("Count is now %u\n", count);
+}
+
+void do_decrement(int argc, char **argv, int sci_idx EXT2FS_ATTR((unused)),
+ void *infop EXT2FS_ATTR((unused)))
+{
+ errcode_t retval;
+ ext2_ino_t ino;
+ __u16 count;
+
+ if (argc < 2) {
+ printf("usage: %s inode\n", argv[0]);
+ return;
+ }
+ if (check_icount(argv[0]))
+ return;
+ if (parse_inode(argv[0], "inode", argv[1], &ino))
+ return;
+ retval = ext2fs_icount_decrement(test_icount, ino, &count);
+ if (retval) {
+ com_err(argv[0], retval,
+ "while calling ext2fs_icount_decrement");
+ return;
+ }
+ printf("Count is now %u\n", count);
+}
+
+void do_store(int argc, char **argv, int sci_idx EXT2FS_ATTR((unused)),
+ void *infop EXT2FS_ATTR((unused)))
+{
+ errcode_t retval;
+ ext2_ino_t ino;
+ ext2_ino_t count;
+
+ if (argc < 3) {
+ printf("usage: %s inode count\n", argv[0]);
+ return;
+ }
+ if (check_icount(argv[0]))
+ return;
+ if (parse_inode(argv[0], "inode", argv[1], &ino))
+ return;
+ if (parse_inode(argv[0], "count", argv[2], &count))
+ return;
+ if (count > 65535) {
+ printf("Count too large.\n");
+ return;
+ }
+ retval = ext2fs_icount_store(test_icount, ino, (__u16) count);
+ if (retval) {
+ com_err(argv[0], retval,
+ "while calling ext2fs_icount_store");
+ return;
+ }
+}
+
+void do_dump(int argc, char **argv, int sci_idx EXT2FS_ATTR((unused)),
+ void *infop EXT2FS_ATTR((unused)))
+{
+ errcode_t retval;
+ ext2_ino_t i;
+ __u16 count;
+
+ if (argc != 1) {
+ printf("Usage: dump\n");
+ return;
+ }
+ if (check_icount(argv[0]))
+ return;
+ for (i=1; i <= test_fs->super->s_inodes_count; i++) {
+ retval = ext2fs_icount_fetch(test_icount, i, &count);
+ if (retval) {
+ com_err(argv[0], retval,
+ "while fetching icount for %lu", (unsigned long)i);
+ return;
+ }
+ if (count)
+ printf("%lu: %u\n", (unsigned long)i, count);
+ }
+}
+
+void do_validate(int argc, char **argv, int sci_idx EXT2FS_ATTR((unused)),
+ void *infop EXT2FS_ATTR((unused)))
+{
+ errcode_t retval;
+
+ if (argc != 1) {
+ printf("Usage: validate\n");
+ return;
+ }
+ if (check_icount(argv[0]))
+ return;
+ retval = ext2fs_icount_validate(test_icount, stdout);
+ if (retval) {
+ com_err(argv[0], retval, "while validating icount structure");
+ return;
+ }
+ printf("Icount structure successfully validated\n");
+}
+
+void do_get_size(int argc, char **argv, int sci_idx EXT2FS_ATTR((unused)),
+ void *infop EXT2FS_ATTR((unused)))
+{
+ ext2_ino_t size;
+
+ if (argc != 1) {
+ printf("Usage: get_size\n");
+ return;
+ }
+ if (check_icount(argv[0]))
+ return;
+ size = ext2fs_get_icount_size(test_icount);
+ printf("Size of icount is: %lu\n", (unsigned long)size);
+}
+
+static int source_file(const char *cmd_file, int sci_idx)
+{
+ FILE *f;
+ char buf[256];
+ char *cp;
+ int exit_status = 0;
+ int retval;
+ int noecho;
+
+ if (strcmp(cmd_file, "-") == 0)
+ f = stdin;
+ else {
+ f = fopen(cmd_file, "r");
+ if (!f) {
+ perror(cmd_file);
+ exit(1);
+ }
+ }
+ fflush(stdout);
+ fflush(stderr);
+ setbuf(stdout, NULL);
+ setbuf(stderr, NULL);
+ while (!feof(f)) {
+ if (fgets(buf, sizeof(buf), f) == NULL)
+ break;
+ if (buf[0] == '#')
+ continue;
+ noecho = 0;
+ if (buf[0] == '-') {
+ noecho = 1;
+ buf[0] = ' ';
+ }
+ cp = strchr(buf, '\n');
+ if (cp)
+ *cp = 0;
+ cp = strchr(buf, '\r');
+ if (cp)
+ *cp = 0;
+ if (!noecho)
+ printf("test_icount: %s\n", buf);
+ retval = ss_execute_line(sci_idx, buf);
+ if (retval) {
+ ss_perror(sci_idx, retval, buf);
+ exit_status++;
+ }
+ }
+ if (f != stdin)
+ fclose(f);
+ return exit_status;
+}
+
+int main(int argc, char **argv)
+{
+ int retval;
+ int sci_idx;
+ int c;
+ char *request = 0;
+ int exit_status = 0;
+ char *cmd_file = 0;
+ struct ext2_super_block param;
+
+ initialize_ext2_error_table();
+
+ /*
+ * Create a sample filesystem structure
+ */
+ memset(&param, 0, sizeof(struct ext2_super_block));
+ ext2fs_blocks_count_set(&param, 80000);
+ param.s_inodes_count = 20000;
+ retval = ext2fs_initialize("/dev/null", 0, &param,
+ unix_io_manager, &test_fs);
+ if (retval) {
+ com_err("/dev/null", retval, "while setting up test fs");
+ exit(1);
+ }
+
+ while ((c = getopt (argc, argv, "wR:f:")) != EOF) {
+ switch (c) {
+ case 'R':
+ request = optarg;
+ break;
+ case 'f':
+ cmd_file = optarg;
+ break;
+ default:
+ com_err(argv[0], 0, "Usage: test_icount "
+ "[-R request] [-f cmd_file]");
+ exit(1);
+ }
+ }
+ sci_idx = ss_create_invocation("test_icount", "0.0", (char *) NULL,
+ &test_cmds, &retval);
+ if (retval) {
+ ss_perror(sci_idx, retval, "creating invocation");
+ exit(1);
+ }
+
+ (void) ss_add_request_table (sci_idx, &ss_std_requests, 1, &retval);
+ if (retval) {
+ ss_perror(sci_idx, retval, "adding standard requests");
+ exit (1);
+ }
+ if (request) {
+ retval = 0;
+ retval = ss_execute_line(sci_idx, request);
+ if (retval) {
+ ss_perror(sci_idx, retval, request);
+ exit_status++;
+ }
+ } else if (cmd_file) {
+ exit_status = source_file(cmd_file, sci_idx);
+ } else {
+ ss_listen(sci_idx);
+ }
+
+ return(exit_status);
+}
diff --git a/tests/progs/test_icount.h b/tests/progs/test_icount.h
new file mode 100644
index 0000000..29d56ab
--- /dev/null
+++ b/tests/progs/test_icount.h
@@ -0,0 +1,10 @@
+void do_create_icount(int argc, char **argv, int sci_idx, void *infop);
+void do_free_icount(int argc, char **argv, int sci_idx, void *infop);
+void do_fetch(int argc, char **argv, int sci_idx, void *infop);
+void do_increment(int argc, char **argv, int sci_idx, void *infop);
+void do_decrement(int argc, char **argv, int sci_idx, void *infop);
+void do_store(int argc, char **argv, int sci_idx, void *infop);
+void do_get_size(int argc, char **argv, int sci_idx, void *infop);
+void do_dump(int argc, char **argv, int sci_idx, void *infop);
+void do_validate(int argc, char **argv, int sci_idx, void *infop);
+
diff --git a/tests/progs/test_icount_cmds.ct b/tests/progs/test_icount_cmds.ct
new file mode 100644
index 0000000..c3cc6f4
--- /dev/null
+++ b/tests/progs/test_icount_cmds.ct
@@ -0,0 +1,37 @@
+#
+# Copyright (C) 1997 Theodore Ts'o. This file may be redistributed
+# under the terms of the GNU Public License.
+#
+command_table test_cmds;
+
+#
+# Icount table commands
+#
+request do_create_icount, "Create an icount structure",
+ create_icount, create;
+
+request do_free_icount, "Free an icount structure",
+ free_icount, free;
+
+request do_fetch, "Fetch an icount entry",
+ fetch;
+
+request do_increment, "Increment an icount entry",
+ increment, inc;
+
+request do_decrement, "Decrement an icount entry",
+ decrement, dec;
+
+request do_store, "Store an icount entry",
+ store;
+
+request do_get_size, "Get the size of the icount structure",
+ get_size;
+
+request do_dump, "Dump the icount structure",
+ dump;
+
+request do_validate, "Validate the icount structure",
+ validate, check;
+
+end;
diff --git a/tests/progs/test_rel.c b/tests/progs/test_rel.c
new file mode 100644
index 0000000..8f7280c
--- /dev/null
+++ b/tests/progs/test_rel.c
@@ -0,0 +1,764 @@
+/*
+ * test_rel.c
+ *
+ * Copyright (C) 1997 Theodore Ts'o.
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Public
+ * License.
+ * %End-Header%
+ */
+
+#include "config.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#ifdef HAVE_GETOPT_H
+#include <getopt.h>
+#endif
+#include <fcntl.h>
+
+#include <et/com_err.h>
+#include <ss/ss.h>
+#include <ext2fs/ext2_fs.h>
+#include <ext2fs/ext2fs.h>
+#include <ext2fs/irel.h>
+#include <ext2fs/brel.h>
+
+#include "test_rel.h"
+
+extern ss_request_table test_cmds;
+
+ext2_irel irel = NULL;
+ext2_brel brel = NULL;
+
+/*
+ * Helper function which parses an inode number.
+ */
+static int parse_inode(const char *request, const char *desc,
+ const char *str, ext2_ino_t *ino)
+{
+ char *tmp;
+
+ *ino = strtoul(str, &tmp, 0);
+ if (*tmp) {
+ com_err(request, 0, "Bad %s - %s", desc, str);
+ return 1;
+ }
+ return 0;
+}
+
+/*
+ * Helper function which parses a block number.
+ */
+static int parse_block(const char *request, const char *desc,
+ const char *str, blk_t *blk)
+{
+ char *tmp;
+
+ *blk = strtoul(str, &tmp, 0);
+ if (*tmp) {
+ com_err(request, 0, "Bad %s - %s", desc, str);
+ return 1;
+ }
+ return 0;
+}
+
+/*
+ * Helper function which assures that a brel table is open
+ */
+static int check_brel(char *request)
+{
+ if (brel)
+ return 0;
+ com_err(request, 0, "A block relocation table must be open.");
+ return 1;
+}
+
+/*
+ * Helper function which assures that an irel table is open
+ */
+static int check_irel(char *request)
+{
+ if (irel)
+ return 0;
+ com_err(request, 0, "An inode relocation table must be open.");
+ return 1;
+}
+
+/*
+ * Helper function which displays a brel entry
+ */
+static void display_brel_entry(blk_t old,
+ struct ext2_block_relocate_entry *ent)
+{
+ printf("Old= %u, New= %u, Owner= %u:%u\n", old, ent->new,
+ ent->owner.block_ref, ent->offset);
+}
+
+/*
+ * Helper function which displays an irel entry
+ */
+static void display_irel_entry(ext2_ino_t old,
+ struct ext2_inode_relocate_entry *ent,
+ int do_refs)
+{
+ struct ext2_inode_reference ref;
+ errcode_t retval;
+ int first = 1;
+
+ printf("Old= %lu, New= %lu, Original=%lu, Max_refs=%u\n", old,
+ ent->new, ent->orig, ent->max_refs);
+ if (!do_refs)
+ return;
+
+ retval = ext2fs_irel_start_iter_ref(irel, old);
+ if (retval) {
+ printf("\tCouldn't get references: %s\n",
+ error_message(retval));
+ return;
+ }
+ while (1) {
+ retval = ext2fs_irel_next_ref(irel, &ref);
+ if (retval) {
+ printf("(%s) ", error_message(retval));
+ break;
+ }
+ if (ref.block == 0)
+ break;
+ if (first) {
+ fputc('\t', stdout);
+ first = 0;
+ } else
+ printf(", ");
+ printf("%u:%u", ref.block, ref.offset);
+ }
+ if (!first)
+ fputc('\n', stdout);
+}
+
+/*
+ * These are the actual command table procedures
+ */
+void do_brel_ma_create(int argc, char **argv)
+{
+ const char *usage = "Usage: %s name max_blocks\n";
+ errcode_t retval;
+ blk_t max_blk;
+
+ if (argc < 3) {
+ printf(usage, argv[0]);
+ return;
+ }
+ if (parse_block(argv[0], "max_blocks", argv[2], &max_blk))
+ return;
+ retval = ext2fs_brel_memarray_create(argv[1], max_blk, &brel);
+ if (retval) {
+ com_err(argv[0], retval, "while opening memarray brel");
+ return;
+ }
+ return;
+}
+
+void do_brel_free(int argc, char **argv)
+{
+ if (check_brel(argv[0]))
+ return;
+ ext2fs_brel_free(brel);
+ brel = NULL;
+ return;
+}
+
+void do_brel_put(int argc, char **argv)
+{
+ const char *usage = "usage: %s old_block new_block [owner] [offset]";
+ errcode_t retval;
+ struct ext2_block_relocate_entry ent;
+ blk_t old, new, offset=0, owner=0;
+
+ if (check_brel(argv[0]))
+ return;
+
+ if (argc < 3) {
+ printf(usage, argv[0]);
+ return;
+ }
+ if (parse_block(argv[0], "old block", argv[1], &old))
+ return;
+ if (parse_block(argv[0], "new block", argv[2], &new))
+ return;
+ if (argc > 3 &&
+ parse_block(argv[0], "owner block", argv[3], &owner))
+ return;
+ if (argc > 4 &&
+ parse_block(argv[0], "offset", argv[4], &offset))
+ return;
+ if (offset > 65535) {
+ printf("Offset too large.\n");
+ return;
+ }
+ ent.new = new;
+ ent.offset = (__u16) offset;
+ ent.flags = 0;
+ ent.owner.block_ref = owner;
+
+ retval = ext2fs_brel_put(brel, old, &ent);
+ if (retval) {
+ com_err(argv[0], retval, "while calling ext2fs_brel_put");
+ return;
+ }
+ return;
+}
+
+void do_brel_get(int argc, char **argv)
+{
+ const char *usage = "%s block";
+ errcode_t retval;
+ struct ext2_block_relocate_entry ent;
+ blk_t blk;
+
+ if (check_brel(argv[0]))
+ return;
+ if (argc < 2) {
+ printf(usage, argv[0]);
+ return;
+ }
+ if (parse_block(argv[0], "block", argv[1], &blk))
+ return;
+ retval = ext2fs_brel_get(brel, blk, &ent);
+ if (retval) {
+ com_err(argv[0], retval, "while calling ext2fs_brel_get");
+ return;
+ }
+ display_brel_entry(blk, &ent);
+ return;
+}
+
+void do_brel_start_iter(int argc, char **argv)
+{
+ errcode_t retval;
+
+ if (check_brel(argv[0]))
+ return;
+
+ retval = ext2fs_brel_start_iter(brel);
+ if (retval) {
+ com_err(argv[0], retval, "while calling ext2fs_brel_start_iter");
+ return;
+ }
+ return;
+}
+
+void do_brel_next(int argc, char **argv)
+{
+ errcode_t retval;
+ struct ext2_block_relocate_entry ent;
+ blk_t blk;
+
+ if (check_brel(argv[0]))
+ return;
+
+ retval = ext2fs_brel_next(brel, &blk, &ent);
+ if (retval) {
+ com_err(argv[0], retval, "while calling ext2fs_brel_next");
+ return;
+ }
+ if (blk == 0) {
+ printf("No more entries!\n");
+ return;
+ }
+ display_brel_entry(blk, &ent);
+ return;
+}
+
+void do_brel_dump(int argc, char **argv)
+{
+ errcode_t retval;
+ struct ext2_block_relocate_entry ent;
+ blk_t blk;
+
+ if (check_brel(argv[0]))
+ return;
+
+ retval = ext2fs_brel_start_iter(brel);
+ if (retval) {
+ com_err(argv[0], retval, "while calling ext2fs_brel_start_iter");
+ return;
+ }
+
+ while (1) {
+ retval = ext2fs_brel_next(brel, &blk, &ent);
+ if (retval) {
+ com_err(argv[0], retval, "while calling ext2fs_brel_next");
+ return;
+ }
+ if (blk == 0)
+ break;
+
+ display_brel_entry(blk, &ent);
+ }
+ return;
+}
+
+void do_brel_move(int argc, char **argv)
+{
+ const char *usage = "%s old_block new_block";
+ errcode_t retval;
+ blk_t old, new;
+
+ if (check_brel(argv[0]))
+ return;
+ if (argc < 2) {
+ printf(usage, argv[0]);
+ return;
+ }
+ if (parse_block(argv[0], "old block", argv[1], &old))
+ return;
+ if (parse_block(argv[0], "new block", argv[2], &new))
+ return;
+
+ retval = ext2fs_brel_move(brel, old, new);
+ if (retval) {
+ com_err(argv[0], retval, "while calling ext2fs_brel_move");
+ return;
+ }
+ return;
+}
+
+void do_brel_delete(int argc, char **argv)
+{
+ const char *usage = "%s block";
+ errcode_t retval;
+ blk_t blk;
+
+ if (check_brel(argv[0]))
+ return;
+ if (argc < 2) {
+ printf(usage, argv[0]);
+ return;
+ }
+ if (parse_block(argv[0], "block", argv[1], &blk))
+ return;
+
+ retval = ext2fs_brel_delete(brel, blk);
+ if (retval) {
+ com_err(argv[0], retval, "while calling ext2fs_brel_delete");
+ return;
+ }
+}
+
+void do_irel_ma_create(int argc, char **argv)
+{
+ const char *usage = "Usage: %s name max_inode\n";
+ errcode_t retval;
+ ext2_ino_t max_ino;
+
+ if (argc < 3) {
+ printf(usage, argv[0]);
+ return;
+ }
+ if (parse_inode(argv[0], "max_inodes", argv[2], &max_ino))
+ return;
+ retval = ext2fs_irel_memarray_create(argv[1], max_ino, &irel);
+ if (retval) {
+ com_err(argv[0], retval, "while opening memarray irel");
+ return;
+ }
+ return;
+}
+
+void do_irel_free(int argc, char **argv)
+{
+ if (check_irel(argv[0]))
+ return;
+
+ ext2fs_irel_free(irel);
+ irel = NULL;
+ return;
+}
+
+void do_irel_put(int argc, char **argv)
+{
+ const char *usage = "%s old new max_refs";
+ errcode_t retval;
+ ext2_ino_t old, new, max_refs;
+ struct ext2_inode_relocate_entry ent;
+
+ if (check_irel(argv[0]))
+ return;
+
+ if (argc < 4) {
+ printf(usage, argv[0]);
+ return;
+ }
+ if (parse_inode(argv[0], "old inode", argv[1], &old))
+ return;
+ if (parse_inode(argv[0], "new inode", argv[2], &new))
+ return;
+ if (parse_inode(argv[0], "max_refs", argv[3], &max_refs))
+ return;
+ if (max_refs > 65535) {
+ printf("max_refs too big\n");
+ return;
+ }
+ ent.new = new;
+ ent.max_refs = (__u16) max_refs;
+ ent.flags = 0;
+
+ retval = ext2fs_irel_put(irel, old, &ent);
+ if (retval) {
+ com_err(argv[0], retval, "while calling ext2fs_irel_put");
+ return;
+ }
+ return;
+}
+
+void do_irel_get(int argc, char **argv)
+{
+ const char *usage = "%s inode";
+ errcode_t retval;
+ ext2_ino_t old;
+ struct ext2_inode_relocate_entry ent;
+
+ if (check_irel(argv[0]))
+ return;
+
+ if (argc < 2) {
+ printf(usage, argv[0]);
+ return;
+ }
+ if (parse_inode(argv[0], "inode", argv[1], &old))
+ return;
+
+ retval = ext2fs_irel_get(irel, old, &ent);
+ if (retval) {
+ com_err(argv[0], retval, "while calling ext2fs_irel_get");
+ return;
+ }
+ display_irel_entry(old, &ent, 1);
+ return;
+}
+
+void do_irel_get_by_orig(int argc, char **argv)
+{
+ const char *usage = "%s orig_inode";
+ errcode_t retval;
+ ext2_ino_t orig, old;
+ struct ext2_inode_relocate_entry ent;
+
+ if (check_irel(argv[0]))
+ return;
+
+ if (argc < 2) {
+ printf(usage, argv[0]);
+ return;
+ }
+ if (parse_inode(argv[0], "original inode", argv[1], &orig))
+ return;
+
+ retval = ext2fs_irel_get_by_orig(irel, orig, &old, &ent);
+ if (retval) {
+ com_err(argv[0], retval, "while calling ext2fs_irel_get_by_orig");
+ return;
+ }
+ display_irel_entry(old, &ent, 1);
+ return;
+}
+
+void do_irel_start_iter(int argc, char **argv)
+{
+ errcode_t retval;
+
+ if (check_irel(argv[0]))
+ return;
+
+ retval = ext2fs_irel_start_iter(irel);
+ if (retval) {
+ com_err(argv[0], retval, "while calling ext2fs_irel_start_iter");
+ return;
+ }
+ return;
+}
+
+void do_irel_next(int argc, char **argv)
+{
+ errcode_t retval;
+ ext2_ino_t old;
+ struct ext2_inode_relocate_entry ent;
+
+ if (check_irel(argv[0]))
+ return;
+
+ retval = ext2fs_irel_next(irel, &old, &ent);
+ if (retval) {
+ com_err(argv[0], retval, "while calling ext2fs_irel_next");
+ return;
+ }
+ if (old == 0) {
+ printf("No more entries!\n");
+ return;
+ }
+ display_irel_entry(old, &ent, 1);
+ return;
+}
+
+void do_irel_dump(int argc, char **argv)
+{
+ errcode_t retval;
+ ext2_ino_t ino;
+ struct ext2_inode_relocate_entry ent;
+
+ if (check_irel(argv[0]))
+ return;
+
+ retval = ext2fs_irel_start_iter(irel);
+ if (retval) {
+ com_err(argv[0], retval, "while calling ext2fs_irel_start_iter");
+ return;
+ }
+
+ while (1) {
+ retval = ext2fs_irel_next(irel, &ino, &ent);
+ if (retval) {
+ com_err(argv[0], retval, "while calling ext2fs_irel_next");
+ return;
+ }
+ if (ino == 0)
+ break;
+
+ display_irel_entry(ino, &ent, 1);
+ }
+ return;
+}
+
+void do_irel_add_ref(int argc, char **argv)
+{
+ const char *usage = "%s inode block offset";
+ errcode_t retval;
+ blk_t block, offset;
+ ext2_ino_t ino;
+ struct ext2_inode_reference ref;
+
+
+ if (check_irel(argv[0]))
+ return;
+
+ if (argc < 4) {
+ printf(usage, argv[0]);
+ return;
+ }
+ if (parse_inode(argv[0], "inode", argv[1], &ino))
+ return;
+ if (parse_block(argv[0], "block", argv[2], &block))
+ return;
+ if (parse_block(argv[0], "offset", argv[3], &offset))
+ return;
+ if (offset > 65535) {
+ printf("Offset too big.\n");
+ return;
+ }
+ ref.block = block;
+ ref.offset = offset;
+
+ retval = ext2fs_irel_add_ref(irel, ino, &ref);
+ if (retval) {
+ com_err(argv[0], retval, "while calling ext2fs_irel_add_ref");
+ return;
+ }
+ return;
+}
+
+void do_irel_start_iter_ref(int argc, char **argv)
+{
+ const char *usage = "%s inode";
+ errcode_t retval;
+ ext2_ino_t ino;
+
+ if (check_irel(argv[0]))
+ return;
+
+ if (argc < 2) {
+ printf(usage, argv[0]);
+ return;
+ }
+
+ if (parse_inode(argv[0], "inode", argv[1], &ino))
+ return;
+ retval = ext2fs_irel_start_iter_ref(irel, ino);
+ if (retval) {
+ com_err(argv[0], retval, "while calling ext2fs_irel_start_iter_ref");
+ return;
+ }
+ return;
+}
+
+void do_irel_next_ref(int argc, char **argv)
+{
+ struct ext2_inode_reference ref;
+ errcode_t retval;
+
+ if (check_irel(argv[0]))
+ return;
+
+ retval = ext2fs_irel_next_ref(irel, &ref);
+ if (retval) {
+ com_err(argv[0], retval, "while calling ext2fs_irel_next_ref");
+ return;
+ }
+ printf("Inode reference: %u:%u\n", ref.block, ref.offset);
+ return;
+}
+
+void do_irel_move(int argc, char **argv)
+{
+ const char *usage = "%s old new";
+ errcode_t retval;
+ ext2_ino_t old, new;
+
+ if (check_irel(argv[0]))
+ return;
+
+ if (argc < 3) {
+ printf(usage, argv[0]);
+ return;
+ }
+ if (parse_inode(argv[0], "old inode", argv[1], &old))
+ return;
+ if (parse_inode(argv[0], "new inode", argv[2], &new))
+ return;
+
+ retval = ext2fs_irel_move(irel, old, new);
+ if (retval) {
+ com_err(argv[0], retval, "while calling ext2fs_irel_move");
+ return;
+ }
+ return;
+}
+
+void do_irel_delete(int argc, char **argv)
+{
+ const char *usage = "%s inode";
+ errcode_t retval;
+ ext2_ino_t ino;
+
+ if (check_irel(argv[0]))
+ return;
+
+ if (argc < 2) {
+ printf(usage, argv[0]);
+ return;
+ }
+ if (parse_inode(argv[0], "inode", argv[1], &ino))
+ return;
+
+ retval = ext2fs_irel_delete(irel, ino);
+ if (retval) {
+ com_err(argv[0], retval, "while calling ext2fs_irel_delete");
+ return;
+ }
+ return;
+}
+
+static int source_file(const char *cmd_file, int sci_idx)
+{
+ FILE *f;
+ char buf[256];
+ char *cp;
+ int exit_status = 0;
+ int retval;
+ int noecho;
+
+ if (strcmp(cmd_file, "-") == 0)
+ f = stdin;
+ else {
+ f = fopen(cmd_file, "r");
+ if (!f) {
+ perror(cmd_file);
+ exit(1);
+ }
+ }
+ fflush(stdout);
+ fflush(stderr);
+ setbuf(stdout, NULL);
+ setbuf(stderr, NULL);
+ while (!feof(f)) {
+ if (fgets(buf, sizeof(buf), f) == NULL)
+ break;
+ if (buf[0] == '#')
+ continue;
+ noecho = 0;
+ if (buf[0] == '-') {
+ noecho = 1;
+ buf[0] = ' ';
+ }
+ cp = strchr(buf, '\n');
+ if (cp)
+ *cp = 0;
+ cp = strchr(buf, '\r');
+ if (cp)
+ *cp = 0;
+ if (!noecho)
+ printf("test_rel: %s\n", buf);
+ retval = ss_execute_line(sci_idx, buf);
+ if (retval) {
+ ss_perror(sci_idx, retval, buf);
+ exit_status++;
+ }
+ }
+ return exit_status;
+}
+
+void main(int argc, char **argv)
+{
+ int retval;
+ int sci_idx;
+ const char *usage = "Usage: test_rel [-R request] [-f cmd_file]";
+ int c;
+ char *request = 0;
+ int exit_status = 0;
+ char *cmd_file = 0;
+
+ initialize_ext2_error_table();
+
+ while ((c = getopt (argc, argv, "wR:f:")) != EOF) {
+ switch (c) {
+ case 'R':
+ request = optarg;
+ break;
+ case 'f':
+ cmd_file = optarg;
+ break;
+ default:
+ com_err(argv[0], 0, usage);
+ return;
+ }
+ }
+ sci_idx = ss_create_invocation("test_rel", "0.0", (char *) NULL,
+ &test_cmds, &retval);
+ if (retval) {
+ ss_perror(sci_idx, retval, "creating invocation");
+ exit(1);
+ }
+
+ (void) ss_add_request_table (sci_idx, &ss_std_requests, 1, &retval);
+ if (retval) {
+ ss_perror(sci_idx, retval, "adding standard requests");
+ exit (1);
+ }
+ if (request) {
+ retval = 0;
+ retval = ss_execute_line(sci_idx, request);
+ if (retval) {
+ ss_perror(sci_idx, retval, request);
+ exit_status++;
+ }
+ } else if (cmd_file) {
+ exit_status = source_file(cmd_file, sci_idx);
+ } else {
+ ss_listen(sci_idx);
+ }
+
+ exit(exit_status);
+}
+
diff --git a/tests/progs/test_rel.h b/tests/progs/test_rel.h
new file mode 100644
index 0000000..47c4d09
--- /dev/null
+++ b/tests/progs/test_rel.h
@@ -0,0 +1,35 @@
+/*
+ * test_rel.h
+ *
+ * Copyright (C) 1997 Theodore Ts'o.
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Public
+ * License.
+ * %End-Header%
+ */
+
+
+
+void do_brel_ma_create(int argc, char **argv);
+void do_brel_free(int argc, char **argv);
+void do_brel_put(int argc, char **argv);
+void do_brel_get(int argc, char **argv);
+void do_brel_start_iter(int argc, char **argv);
+void do_brel_next(int argc, char **argv);
+void do_brel_dump(int argc, char **argv);
+void do_brel_move(int argc, char **argv);
+void do_brel_delete(int argc, char **argv);
+void do_irel_ma_create(int argc, char **argv);
+void do_irel_free(int argc, char **argv);
+void do_irel_put(int argc, char **argv);
+void do_irel_get(int argc, char **argv);
+void do_irel_get_by_orig(int argc, char **argv);
+void do_irel_start_iter(int argc, char **argv);
+void do_irel_next(int argc, char **argv);
+void do_irel_dump(int argc, char **argv);
+void do_irel_add_ref(int argc, char **argv);
+void do_irel_start_iter_ref(int argc, char **argv);
+void do_irel_next_ref(int argc, char **argv);
+void do_irel_move(int argc, char **argv);
+void do_irel_delete(int argc, char **argv);
diff --git a/tests/progs/test_rel_cmds.ct b/tests/progs/test_rel_cmds.ct
new file mode 100644
index 0000000..5ed6ae2
--- /dev/null
+++ b/tests/progs/test_rel_cmds.ct
@@ -0,0 +1,82 @@
+#
+# Copyright (C) 1997 Theodore Ts'o. This file may be redistributed
+# under the terms of the GNU Public License.
+#
+command_table test_cmds;
+
+#
+# Block relocation table commands
+#
+
+request do_brel_ma_create, "Open a memory array block relocation table",
+ brel_ma_create, bma_create;
+
+request do_brel_free, "Free a block relocation table",
+ brel_free, bfree;
+
+request do_brel_put, "Add or modify a block relocation entry",
+ brel_put, bput;
+
+request do_brel_get, "Get a block relocation entry",
+ brel_get, bget;
+
+request do_brel_start_iter, "Start iterating over the block table",
+ brel_start_iter, bstart;
+
+request do_brel_next, "Get the next block relocation entry",
+ brel_next, bnext;
+
+request do_brel_dump, "Dump the block relocation table",
+ brel_dump, bdump;
+
+request do_brel_move, "Move an entry in the block relocation table",
+ brel_move, bmove;
+
+request do_brel_delete, "Delete an entry in the block relocation table",
+ brel_delete, bdelete, bdel;
+
+#
+# Inode relocation table commands
+#
+
+request do_irel_ma_create, "Open a memory array inode relocation table",
+ irel_ma_create, ima_create;
+
+request do_irel_free, "Free an inode relocation table",
+ irel_free, ifree;
+
+request do_irel_put, "Add or modify an inode relocation entry",
+ irel_put, iput;
+
+request do_irel_get, "Get an inode relocation entry",
+ irel_get, iget;
+
+request do_irel_get_by_orig,
+ "Get an inode relocation entry by its original number",
+ irel_get_by_orig, igetorig, igeto;
+
+request do_irel_start_iter, "Start iterating over the inode table",
+ irel_start_iter, istart;
+
+request do_irel_next, "Get the next block relocation entry",
+ irel_next, inext;
+
+request do_irel_dump, "Dump the inode relocation table",
+ irel_dump, idump;
+
+request do_irel_add_ref, "Add a reference to an inode entry",
+ irel_add_ref, iaddref, iaddr;
+
+request do_irel_start_iter_ref, "Start iterating over references to an inode",
+ irel_start_iter_ref, istartref, istartr;
+
+request do_irel_next_ref, "Get the next reference for an inode entry",
+ irel_next_ref, inextref, inextr;
+
+request do_irel_move, "Move an entry in the inode relocation table",
+ irel_move, imove;
+
+request do_irel_delete, "Delete an entry in the inode relocation table",
+ irel_delete, idelete, idel;
+
+end;