Move dirent related parsers to a separate file

* dirent.c: New file.
* Makefile.am (strace_SOURCES): Add it.
* file.c (print_old_dirent, sys_readdir, sys_getdents, sys_getdents64):
Move to dirent.c.
diff --git a/Makefile.am b/Makefile.am
index a30ac1c..7dfdf2c 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -22,6 +22,7 @@
 	block.c		\
 	count.c		\
 	desc.c		\
+	dirent.c	\
 	fanotify.c	\
 	file.c		\
 	inotify.c	\
diff --git a/dirent.c b/dirent.c
new file mode 100644
index 0000000..cbebdb7
--- /dev/null
+++ b/dirent.c
@@ -0,0 +1,210 @@
+#include "defs.h"
+#include <dirent.h>
+
+struct kernel_dirent {
+	unsigned long   d_ino;
+	unsigned long   d_off;
+	unsigned short  d_reclen;
+	char            d_name[1];
+};
+
+static void
+print_old_dirent(struct tcb *tcp, long addr)
+{
+#ifdef SH64
+	typedef struct kernel_dirent old_dirent_t;
+#else
+	typedef struct {
+		uint32_t	d_ino;
+		uint32_t	d_off;
+		unsigned short  d_reclen;
+		char            d_name[1];
+	} old_dirent_t;
+#endif
+	old_dirent_t d;
+
+	if (!verbose(tcp) || umove(tcp, addr, &d) < 0) {
+		tprintf("%#lx", addr);
+		return;
+	}
+
+	tprintf("{d_ino=%lu, d_off=%lu, d_reclen=%u, d_name=\"",
+		(unsigned long) d.d_ino, (unsigned long) d.d_off, d.d_reclen);
+	if (d.d_reclen > 256)
+		d.d_reclen = 256;
+	printpathn(tcp, addr + offsetof(old_dirent_t, d_name), d.d_reclen);
+	tprints("\"}");
+}
+
+int
+sys_readdir(struct tcb *tcp)
+{
+	if (entering(tcp)) {
+		printfd(tcp, tcp->u_arg[0]);
+		tprints(", ");
+	} else {
+		if (syserror(tcp) || tcp->u_rval == 0 || !verbose(tcp))
+			tprintf("%#lx", tcp->u_arg[1]);
+		else
+			print_old_dirent(tcp, tcp->u_arg[1]);
+		/* Not much point in printing this out, it is always 1. */
+		if (tcp->u_arg[2] != 1)
+			tprintf(", %lu", tcp->u_arg[2]);
+	}
+	return 0;
+}
+
+#include "xlat/direnttypes.h"
+
+int
+sys_getdents(struct tcb *tcp)
+{
+	unsigned int i, len, dents = 0;
+	char *buf;
+
+	if (entering(tcp)) {
+		printfd(tcp, tcp->u_arg[0]);
+		tprints(", ");
+		return 0;
+	}
+	if (syserror(tcp) || !verbose(tcp)) {
+		tprintf("%#lx, %lu", tcp->u_arg[1], tcp->u_arg[2]);
+		return 0;
+	}
+
+	/* Beware of insanely large or too small values in tcp->u_rval */
+	if (tcp->u_rval > 1024*1024)
+		len = 1024*1024;
+	else if (tcp->u_rval < (int) sizeof(struct kernel_dirent))
+		len = 0;
+	else
+		len = tcp->u_rval;
+
+	if (len) {
+		buf = malloc(len);
+		if (!buf)
+			die_out_of_memory();
+		if (umoven(tcp, tcp->u_arg[1], len, buf) < 0) {
+			tprintf("%#lx, %lu", tcp->u_arg[1], tcp->u_arg[2]);
+			free(buf);
+			return 0;
+		}
+	} else {
+		buf = NULL;
+	}
+
+	if (!abbrev(tcp))
+		tprints("{");
+	for (i = 0; len && i <= len - sizeof(struct kernel_dirent); ) {
+		struct kernel_dirent *d = (struct kernel_dirent *) &buf[i];
+
+		if (!abbrev(tcp)) {
+			int oob = d->d_reclen < sizeof(struct kernel_dirent) ||
+				  i + d->d_reclen - 1 >= len;
+			int d_name_len = oob ? len - i : d->d_reclen;
+			d_name_len -= offsetof(struct kernel_dirent, d_name) + 1;
+
+			tprintf("%s{d_ino=%lu, d_off=%lu, ",
+				i ? " " : "", d->d_ino, d->d_off);
+			tprintf("d_reclen=%u, d_name=\"%.*s\", d_type=",
+				d->d_reclen, d_name_len, d->d_name);
+			if (oob)
+				tprints("?");
+			else
+				printxval(direnttypes, buf[i + d->d_reclen - 1], "DT_???");
+			tprints("}");
+		}
+		dents++;
+		if (d->d_reclen < sizeof(struct kernel_dirent)) {
+			tprints("/* d_reclen < sizeof(struct kernel_dirent) */");
+			break;
+		}
+		i += d->d_reclen;
+	}
+	if (!abbrev(tcp))
+		tprints("}");
+	else
+		tprintf("/* %u entries */", dents);
+	tprintf(", %lu", tcp->u_arg[2]);
+	free(buf);
+	return 0;
+}
+
+int
+sys_getdents64(struct tcb *tcp)
+{
+	/* the minimum size of a valid dirent64 structure */
+	const unsigned int d_name_offset = offsetof(struct dirent64, d_name);
+
+	unsigned int i, len, dents = 0;
+	char *buf;
+
+	if (entering(tcp)) {
+		printfd(tcp, tcp->u_arg[0]);
+		tprints(", ");
+		return 0;
+	}
+	if (syserror(tcp) || !verbose(tcp)) {
+		tprintf("%#lx, %lu", tcp->u_arg[1], tcp->u_arg[2]);
+		return 0;
+	}
+
+	/* Beware of insanely large or too small tcp->u_rval */
+	if (tcp->u_rval > 1024*1024)
+		len = 1024*1024;
+	else if (tcp->u_rval < (int) d_name_offset)
+		len = 0;
+	else
+		len = tcp->u_rval;
+
+	if (len) {
+		buf = malloc(len);
+		if (!buf)
+			die_out_of_memory();
+		if (umoven(tcp, tcp->u_arg[1], len, buf) < 0) {
+			tprintf("%#lx, %lu", tcp->u_arg[1], tcp->u_arg[2]);
+			free(buf);
+			return 0;
+		}
+	} else {
+		buf = NULL;
+	}
+
+	if (!abbrev(tcp))
+		tprints("{");
+	for (i = 0; len && i <= len - d_name_offset; ) {
+		struct dirent64 *d = (struct dirent64 *) &buf[i];
+		if (!abbrev(tcp)) {
+			int d_name_len;
+			if (d->d_reclen >= d_name_offset
+			    && i + d->d_reclen <= len) {
+				d_name_len = d->d_reclen - d_name_offset;
+			} else {
+				d_name_len = len - i - d_name_offset;
+			}
+
+			tprintf("%s{d_ino=%" PRIu64 ", d_off=%" PRId64
+				", d_reclen=%u, d_type=",
+				i ? " " : "",
+				d->d_ino,
+				d->d_off,
+				d->d_reclen);
+			printxval(direnttypes, d->d_type, "DT_???");
+			tprintf(", d_name=\"%.*s\"}",
+				d_name_len, d->d_name);
+		}
+		if (d->d_reclen < d_name_offset) {
+			tprints("/* d_reclen < offsetof(struct dirent64, d_name) */");
+			break;
+		}
+		i += d->d_reclen;
+		dents++;
+	}
+	if (!abbrev(tcp))
+		tprints("}");
+	else
+		tprintf("/* %u entries */", dents);
+	tprintf(", %lu", tcp->u_arg[2]);
+	free(buf);
+	return 0;
+}
diff --git a/file.c b/file.c
index 0044429..47ca230 100644
--- a/file.c
+++ b/file.c
@@ -29,7 +29,6 @@
  */
 
 #include "defs.h"
-#include <dirent.h>
 #include <sys/swap.h>
 
 #if defined(SPARC) || defined(SPARC64)
@@ -204,13 +203,6 @@
 # include <sys/asynch.h>
 #endif
 
-struct kernel_dirent {
-	unsigned long   d_ino;
-	unsigned long   d_off;
-	unsigned short  d_reclen;
-	char            d_name[1];
-};
-
 #ifdef O_LARGEFILE
 # if O_LARGEFILE == 0          /* biarch platforms in 64-bit mode */
 #  undef O_LARGEFILE
@@ -2009,207 +2001,6 @@
 	return decode_mknod(tcp, 1);
 }
 
-static void
-print_old_dirent(struct tcb *tcp, long addr)
-{
-#ifdef SH64
-	typedef struct kernel_dirent old_dirent_t;
-#else
-	typedef struct {
-		uint32_t	d_ino;
-		uint32_t	d_off;
-		unsigned short  d_reclen;
-		char            d_name[1];
-	} old_dirent_t;
-#endif
-	old_dirent_t d;
-
-	if (!verbose(tcp) || umove(tcp, addr, &d) < 0) {
-		tprintf("%#lx", addr);
-		return;
-	}
-
-	tprintf("{d_ino=%lu, d_off=%lu, d_reclen=%u, d_name=\"",
-		(unsigned long) d.d_ino, (unsigned long) d.d_off, d.d_reclen);
-	if (d.d_reclen > 256)
-		d.d_reclen = 256;
-	printpathn(tcp, addr + offsetof(old_dirent_t, d_name), d.d_reclen);
-	tprints("\"}");
-}
-
-int
-sys_readdir(struct tcb *tcp)
-{
-	if (entering(tcp)) {
-		printfd(tcp, tcp->u_arg[0]);
-		tprints(", ");
-	} else {
-		if (syserror(tcp) || tcp->u_rval == 0 || !verbose(tcp))
-			tprintf("%#lx", tcp->u_arg[1]);
-		else
-			print_old_dirent(tcp, tcp->u_arg[1]);
-		/* Not much point in printing this out, it is always 1. */
-		if (tcp->u_arg[2] != 1)
-			tprintf(", %lu", tcp->u_arg[2]);
-	}
-	return 0;
-}
-
-#include "xlat/direnttypes.h"
-
-int
-sys_getdents(struct tcb *tcp)
-{
-	unsigned int i, len, dents = 0;
-	char *buf;
-
-	if (entering(tcp)) {
-		printfd(tcp, tcp->u_arg[0]);
-		tprints(", ");
-		return 0;
-	}
-	if (syserror(tcp) || !verbose(tcp)) {
-		tprintf("%#lx, %lu", tcp->u_arg[1], tcp->u_arg[2]);
-		return 0;
-	}
-
-	/* Beware of insanely large or too small values in tcp->u_rval */
-	if (tcp->u_rval > 1024*1024)
-		len = 1024*1024;
-	else if (tcp->u_rval < (int) sizeof(struct kernel_dirent))
-		len = 0;
-	else
-		len = tcp->u_rval;
-
-	if (len) {
-		buf = malloc(len);
-		if (!buf)
-			die_out_of_memory();
-		if (umoven(tcp, tcp->u_arg[1], len, buf) < 0) {
-			tprintf("%#lx, %lu", tcp->u_arg[1], tcp->u_arg[2]);
-			free(buf);
-			return 0;
-		}
-	} else {
-		buf = NULL;
-	}
-
-	if (!abbrev(tcp))
-		tprints("{");
-	for (i = 0; len && i <= len - sizeof(struct kernel_dirent); ) {
-		struct kernel_dirent *d = (struct kernel_dirent *) &buf[i];
-
-		if (!abbrev(tcp)) {
-			int oob = d->d_reclen < sizeof(struct kernel_dirent) ||
-				  i + d->d_reclen - 1 >= len;
-			int d_name_len = oob ? len - i : d->d_reclen;
-			d_name_len -= offsetof(struct kernel_dirent, d_name) + 1;
-
-			tprintf("%s{d_ino=%lu, d_off=%lu, ",
-				i ? " " : "", d->d_ino, d->d_off);
-			tprintf("d_reclen=%u, d_name=\"%.*s\", d_type=",
-				d->d_reclen, d_name_len, d->d_name);
-			if (oob)
-				tprints("?");
-			else
-				printxval(direnttypes, buf[i + d->d_reclen - 1], "DT_???");
-			tprints("}");
-		}
-		dents++;
-		if (d->d_reclen < sizeof(struct kernel_dirent)) {
-			tprints("/* d_reclen < sizeof(struct kernel_dirent) */");
-			break;
-		}
-		i += d->d_reclen;
-	}
-	if (!abbrev(tcp))
-		tprints("}");
-	else
-		tprintf("/* %u entries */", dents);
-	tprintf(", %lu", tcp->u_arg[2]);
-	free(buf);
-	return 0;
-}
-
-int
-sys_getdents64(struct tcb *tcp)
-{
-	/* the minimum size of a valid dirent64 structure */
-	const unsigned int d_name_offset = offsetof(struct dirent64, d_name);
-
-	unsigned int i, len, dents = 0;
-	char *buf;
-
-	if (entering(tcp)) {
-		printfd(tcp, tcp->u_arg[0]);
-		tprints(", ");
-		return 0;
-	}
-	if (syserror(tcp) || !verbose(tcp)) {
-		tprintf("%#lx, %lu", tcp->u_arg[1], tcp->u_arg[2]);
-		return 0;
-	}
-
-	/* Beware of insanely large or too small tcp->u_rval */
-	if (tcp->u_rval > 1024*1024)
-		len = 1024*1024;
-	else if (tcp->u_rval < (int) d_name_offset)
-		len = 0;
-	else
-		len = tcp->u_rval;
-
-	if (len) {
-		buf = malloc(len);
-		if (!buf)
-			die_out_of_memory();
-		if (umoven(tcp, tcp->u_arg[1], len, buf) < 0) {
-			tprintf("%#lx, %lu", tcp->u_arg[1], tcp->u_arg[2]);
-			free(buf);
-			return 0;
-		}
-	} else {
-		buf = NULL;
-	}
-
-	if (!abbrev(tcp))
-		tprints("{");
-	for (i = 0; len && i <= len - d_name_offset; ) {
-		struct dirent64 *d = (struct dirent64 *) &buf[i];
-		if (!abbrev(tcp)) {
-			int d_name_len;
-			if (d->d_reclen >= d_name_offset
-			    && i + d->d_reclen <= len) {
-				d_name_len = d->d_reclen - d_name_offset;
-			} else {
-				d_name_len = len - i - d_name_offset;
-			}
-
-			tprintf("%s{d_ino=%" PRIu64 ", d_off=%" PRId64
-				", d_reclen=%u, d_type=",
-				i ? " " : "",
-				d->d_ino,
-				d->d_off,
-				d->d_reclen);
-			printxval(direnttypes, d->d_type, "DT_???");
-			tprintf(", d_name=\"%.*s\"}",
-				d_name_len, d->d_name);
-		}
-		if (d->d_reclen < d_name_offset) {
-			tprints("/* d_reclen < offsetof(struct dirent64, d_name) */");
-			break;
-		}
-		i += d->d_reclen;
-		dents++;
-	}
-	if (!abbrev(tcp))
-		tprints("}");
-	else
-		tprintf("/* %u entries */", dents);
-	tprintf(", %lu", tcp->u_arg[2]);
-	free(buf);
-	return 0;
-}
-
 int
 sys_getcwd(struct tcb *tcp)
 {