[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: It Works!



> Should we add it to the task list? I think it is extremely useful.
> A standalone utility would also be nice iff debugfs can't be used easily in
> batch mode for scripts.

Here is a program I whipped up that you can drop into the
e2fsprogs-1.17/misc directory and build.  This is very rough, but does most
of the job and should be enough for someone else to take and clean up to be
a usable program, or to submit for inclusion in e2fsprogs.  It should be
enough to show you how to add the features to debugfs too.


#include <fcntl.h>
#include <grp.h>
#ifdef HAVE_GETOPT_H
#include <getopt.h>
#endif
#include <pwd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <sys/types.h>

#include <linux/ext2_fs.h>

#include "ext2fs/ext2fs.h"
#include "et/com_err.h"
#include "uuid/uuid.h"
#include "e2p/e2p.h"

#include "../version.h"


int
main (int argc, char **argv)
{
  errcode_t rc;
  ext2_filsys fs;
  struct ext2fs_sb *sb;
  const char *program_name = argv[0];
  const char *device = argv[1];
  const char *filename = argv[2];
  ino_t inum;
  struct ext2_inode di;
  unsigned int blkno;

  initialize_ext2_error_table ();

  rc = ext2fs_open (device, EXT2_FLAG_RW, 0, 0, unix_io_manager, &fs);
  if (rc)
    {
      com_err (program_name, rc, "while trying to open %s", device);
      exit (1);
    }

  sb = (struct ext2fs_sb *) fs->super;

  if (sb->s_creator_os != EXT2_OS_HURD)
    {
      fprintf (stderr, "%s: creator OS is %u, not Hurd",
	       device, sb->s_creator_os);
      exit (1);
    }

  rc = ext2fs_namei (fs, EXT2_ROOT_INO, EXT2_ROOT_INO, filename, &inum);
  if (rc)
    {
      com_err (program_name, rc, "while trying to resolve file name");
      exit (1);
    }

  rc = ext2fs_read_inode (fs, inum, &di);
  if (rc)
    {
      com_err (program_name, rc, "while reading file's inode");
      exit (1);
    }

  blkno = di.osd1.hurd1.h_i_translator;
  if (blkno == 0)
    printf ("%s has no translator\n", filename);
  else
    {
      unsigned char buf[EXT2_BLOCK_SIZE (sb) + 1];
      size_t namelen, i;
      rc = io_channel_read_blk (fs->io, blkno, 1, buf);
      if (rc)
	{
	  com_err (program_name, rc, "while reading translator block");
	  error (0, 1, "cannot read translator block");
	}
      namelen = (buf[1] << 8) | buf[0];
      if (namelen > EXT2_BLOCK_SIZE (sb) || namelen < 1)
	{
	  fprintf (stderr, "bogus translator length %u in block %u",
		   namelen, blkno);
	  exit (1);
	}

      for (i = 0; i < namelen; ++i)
	if (buf[2 + i] == 0)
	  buf[2 + i] = ' ';
      buf[2 + namelen - 1] = 0;

      printf ("%s: %.*s\n", filename, namelen, &buf[2]);
    }

  if (argc > 3)
    {
      unsigned char buf[EXT2_BLOCK_SIZE (sb)];
      size_t translen = 0;
      unsigned int i, j;
      for (i = 3; i < argc; ++i)
	translen += strlen (argv[i]) + 1;
      if (translen + 2 > sizeof buf)
	{
	  fprintf (stderr, "cannot write %u bytes of translator, only %u\n",
		   translen, sizeof buf - 2);
	  exit (1);
	}
      if (blkno == 0)
	{
	  rc = ext2fs_alloc_block (fs, 0, /* ? */
				   buf, &blkno);
	  if (rc)
	    {
	      com_err (program_name, rc, "while allocating translator block");
	      exit (1);
	    }
	  ++di.i_blocks;
	}
      buf[0] = translen & 0xff;
      buf[1] = (translen >> 8) & 0xff;
      j = 2;
      for (i = 3; i < argc; ++i)
	{
	  strcpy (&buf[j], argv[i]);
	  j += strlen (argv[i]);
	  buf[j++] = 0;
	}
      rc = io_channel_write_blk (fs->io, blkno, 1, buf);
      if (rc)
	{
	  com_err (program_name, rc, "while writing translator block");
	  exit (1);
	}
      di.osd1.hurd1.h_i_translator = blkno;
      rc = ext2fs_write_inode (fs, inum, &di);
      if (rc)
	{
	  com_err (program_name, rc, "while writing inode");
	  exit (1);
	}
    }

  exit (0);
}


Reply to: