+
+/* Module xheader.c. */
+
+void xheader_decode (struct tar_stat_info *);
+void xheader_decode_global (void);
+void xheader_store (char const *, struct tar_stat_info const *, void *);
+void xheader_read (union block *, size_t);
+void xheader_write (char type, char *name, struct xheader *xhdr);
+void xheader_write_global (void);
+void xheader_finish (struct xheader *);
+void xheader_destroy (struct xheader *);
+char *xheader_xhdr_name (struct tar_stat_info *st);
+char *xheader_ghdr_name (void);
+void xheader_write (char, char *, struct xheader *);
+void xheader_write_global (void);
+void xheader_set_option (char *string);
+
+/* Module system.c */
+
+void sys_detect_dev_null_output (void);
+void sys_save_archive_dev_ino (void);
+void sys_drain_input_pipe (void);
+void sys_wait_for_child (pid_t);
+void sys_spawn_shell (void);
+bool sys_compare_uid (struct stat *a, struct stat *b);
+bool sys_compare_gid (struct stat *a, struct stat *b);
+bool sys_file_is_archive (struct tar_stat_info *p);
+bool sys_compare_links (struct stat *link_data, struct stat *stat_data);
+int sys_truncate (int fd);
+pid_t sys_child_open_for_compress (void);
+pid_t sys_child_open_for_uncompress (void);
+size_t sys_write_archive_buffer (void);
+bool sys_get_archive_stat (void);
+int sys_exec_command (char *file_name, int typechar, struct tar_stat_info *st);
+void sys_wait_command (void);
+
+/* Module compare.c */
+void report_difference (struct tar_stat_info *st, const char *message, ...);
+
+/* Module sparse.c */
+bool sparse_file_p (struct tar_stat_info *);
+bool sparse_member_p (struct tar_stat_info *);
+bool sparse_fixup_header (struct tar_stat_info *);
+enum dump_status sparse_dump_file (int, struct tar_stat_info *);
+enum dump_status sparse_extract_file (int, struct tar_stat_info *, off_t *);
+enum dump_status sparse_skip_file (struct tar_stat_info *);
+bool sparse_diff_file (int, struct tar_stat_info *);
+
+/* Module utf8.c */
+bool string_ascii_p (const char *str);
+bool utf8_convert (bool to_utf, char const *input, char **output);
+
+
+/* FIXME: The following should get moved into gnulib. */
+
+static inline struct timespec
+get_stat_atime (struct stat const *st)
+{
+#if defined HAVE_STRUCT_STAT_ST_ATIM_TV_NSEC
+ return st->st_atim;
+#elif defined HAVE_STRUCT_STAT_ST_ATIMESPEC_TV_NSEC
+ return st->st_atimespec;
+#else
+ struct timespec t;
+ t.tv_sec = st->st_atime;
+# if defined HAVE_STRUCT_STAT_ST_ATIMENSEC
+ t.tv_nsec = st->stat.st_atimensec;
+# elif defined HAVE_STRUCT_STAT_ST_SPARE1
+ t.tv_nsec = st->stat.st_spare1 * 1000;
+# else
+ t.tv_nsec = 0;
+# endif
+ return t;
+#endif
+}
+
+static inline struct timespec
+get_stat_ctime (struct stat const *st)
+{
+#if defined HAVE_STRUCT_STAT_ST_ATIM_TV_NSEC
+ return st->st_ctim;
+#elif defined HAVE_STRUCT_STAT_ST_ATIMESPEC_TV_NSEC
+ return st->st_ctimespec;
+#else
+ struct timespec t;
+ t.tv_sec = st->st_ctime;
+# if defined HAVE_STRUCT_STAT_ST_ATIMENSEC
+ t.tv_nsec = st->stat.st_ctimensec;
+# elif defined HAVE_STRUCT_STAT_ST_SPARE1
+ t.tv_nsec = st->stat.st_spare1 * 1000;
+# else
+ t.tv_nsec = 0;
+# endif
+ return t;
+#endif
+}
+
+static inline struct timespec
+get_stat_mtime (struct stat const *st)
+{
+#if defined HAVE_STRUCT_STAT_ST_ATIM_TV_NSEC
+ return st->st_mtim;
+#elif defined HAVE_STRUCT_STAT_ST_ATIMESPEC_TV_NSEC
+ return st->st_mtimespec;
+#else
+ struct timespec t;
+ t.tv_sec = st->st_mtime;
+# if defined HAVE_STRUCT_STAT_ST_ATIMENSEC
+ t.tv_nsec = st->stat.st_mtimensec;
+# elif defined HAVE_STRUCT_STAT_ST_SPARE1
+ t.tv_nsec = st->stat.st_spare1 * 1000;
+# else
+ t.tv_nsec = 0;
+# endif
+ return t;
+#endif
+}
+
+static inline void
+set_stat_atime (struct stat *st, struct timespec t)
+{
+#if defined HAVE_STRUCT_STAT_ST_ATIM_TV_NSEC
+ st->st_atim = t;
+#elif defined HAVE_STRUCT_STAT_ST_ATIMESPEC_TV_NSEC
+ st->st_atimespec = t;
+#else
+ st->st_atime = t.tv_sec;
+# if defined HAVE_STRUCT_STAT_ST_ATIMENSEC
+ st->stat.st_atimensec = t.tv_nsec;
+# elif defined HAVE_STRUCT_STAT_ST_SPARE1
+ st->stat.st_spare1 = t.tv_nsec / 1000;
+# endif
+#endif
+}
+
+static inline void
+set_stat_ctime (struct stat *st, struct timespec t)
+{
+#if defined HAVE_STRUCT_STAT_ST_ATIM_TV_NSEC
+ st->st_ctim = t;
+#elif defined HAVE_STRUCT_STAT_ST_ATIMESPEC_TV_NSEC
+ st->st_ctimespec = t;
+#else
+ st->st_ctime = t.tv_sec;
+# if defined HAVE_STRUCT_STAT_ST_ATIMENSEC
+ st->stat.st_ctimensec = t.tv_nsec;
+# elif defined HAVE_STRUCT_STAT_ST_SPARE1
+ st->stat.st_spare1 = t.tv_nsec / 1000;
+# endif
+#endif
+}
+
+static inline void
+set_stat_mtime (struct stat *st, struct timespec t)
+{
+#if defined HAVE_STRUCT_STAT_ST_ATIM_TV_NSEC
+ st->st_mtim = t;
+#elif defined HAVE_STRUCT_STAT_ST_ATIMESPEC_TV_NSEC
+ st->st_mtimespec = t;
+#else
+ st->st_mtime = t.tv_sec;
+# if defined HAVE_STRUCT_STAT_ST_ATIMENSEC
+ st->stat.st_mtimensec = t.tv_nsec;
+# elif defined HAVE_STRUCT_STAT_ST_SPARE1
+ st->stat.st_spare1 = t.tv_nsec / 1000;
+# endif
+#endif
+}