/* Program to seek to a certain position on a disk partition  */
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/uio.h>
#include <string.h>

#define REISERFS_DISK_OFFSET_IN_BYTES (64 * 1024)
#define REISERFS_OLD_DISK_OFFSET_IN_BYTES (8 * 1024)
#define REISERFS_SUPER_MAGIC_STRING "ReIsErFs"
#define REISER2FS_SUPER_MAGIC_STRING "ReIsEr2Fs"

struct reiserfs_super_block
{
  u_char  s_block_count[4];
  u_char  s_free_blocks[4];
  u_char  s_root_block[4];
  u_char  s_journal_block[4];
  u_char  s_journal_dev[4];
  u_char  s_orig_journal_size[4];
  u_char  s_journal_trans_max[4];
  u_char  s_journal_block_count[4];
  u_char  s_journal_max_batch[4];
  u_char  s_journal_max_commit_age[4];
  u_char  s_journal_max_trans_age[4];
  u_char  s_blocksize[2];
  u_char  s_oid_maxsize[2];
  u_char  s_oid_cursize[2];
  u_char  s_state[2];
  u_char  s_magic[12];
  u_char  s_pad[448];  /* The size accepted by FreeBSD read for char. devices */
};

static int is_reiserfs_magic_string (struct reiserfs_super_block *);


int
main(int argc, char **argv)
{
  off_t seekpos;
  ssize_t rbytes;
  char *device;
  int fd;
  char *progname = argv[0];
  struct reiserfs_super_block rfs_sblock;

  if (argc != 2) {
    fprintf(stderr, "Usage: %s partition\n", progname);
    exit(EXIT_FAILURE);
  }
  device = argv[1];
  fd = open(device, O_RDONLY);
  if (fd < 0) {
    perror(progname);
    exit(EXIT_FAILURE);
  }
  /* seek to reiserfs offset */
  seekpos = lseek(fd, REISERFS_DISK_OFFSET_IN_BYTES, SEEK_SET);
  rbytes = read(fd, (char *)&rfs_sblock, sizeof(rfs_sblock));
  if (rbytes < 0) 
    perror(argv[0]);
  if (is_reiserfs_magic_string(&rfs_sblock))
    printf("reiserfs\n");
  else
    return(1);
  return(0);
}

static int is_reiserfs_magic_string (struct reiserfs_super_block * rs)
{
    return (!strncmp (rs->s_magic, REISERFS_SUPER_MAGIC_STRING, 
		      strlen ( REISERFS_SUPER_MAGIC_STRING)) ||
	    !strncmp (rs->s_magic, REISER2FS_SUPER_MAGIC_STRING, 
		      strlen ( REISER2FS_SUPER_MAGIC_STRING)));
}
