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:
- References:
- Re: It Works!
- From: Marcus Brinkmann <Marcus.Brinkmann@ruhr-uni-bochum.de>