Changes by: flatcap
Update of /cvsroot/linux-ntfs/ntfsprogs/ntfsprogs
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv9664/ntfsprogs
Modified Files:
ntfscat.c ntfscat.8.in
Log Message:
ntfscat now works with attribute names
ntfscat now removes fixup from:
$MFT/$DATA
$MFTMirr/$DATA
anydir/$INDEX_ALLOCATION
Index: ntfscat.c
===================================================================
RCS file: /cvsroot/linux-ntfs/ntfsprogs/ntfsprogs/ntfscat.c,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -p -r1.15 -r1.16
--- ntfscat.c 19 Jun 2005 21:09:41 -0000 1.15
+++ ntfscat.c 20 Jun 2005 14:24:53 -0000 1.16
@@ -1,8 +1,8 @@
/**
* ntfscat - Part of the Linux-NTFS project.
*
- * Copyright (c) 2003 Richard Russon
- * Copyright (c) 2003 Anton Altaparmakov
+ * Copyright (c) 2003-2005 Richard Russon
+ * Copyright (c) 2003 Anton Altaparmakov
*
* This utility will concatenate files and print on the standard output.
*
@@ -70,7 +70,7 @@ static void version (void)
static void usage (void)
{
Printf ("\nUsage: %s [options] device [file]\n\n"
- " -a, --attribute num Display this attribute\n"
+ " -a, --attribute desc Display this attribute (name or number)\n"
" -i, --inode num Display this inode\n\n"
" -f --force Use less caution\n"
" -h --help Print this help\n"
@@ -85,6 +85,60 @@ static void usage (void)
}
/**
+ * parse_attribute - Read an attribute name, or number
+ * @value: String to be parsed
+ * @attr: Resulting attribute id (on success)
+ *
+ * Read a string representing an attribute. It may be a decimal, octal or
+ * hexadecimal number, or the attribute name in full. The leading $ sign is
+ * optional.
+ *
+ * Return: 1 Success, a valid attribute name or number
+ * 0 Error, not an attribute name or number
+ */
+static int parse_attribute (const char *value, ATTR_TYPES *attr)
+{
+ static const char *attr_name[] = {
+ "$STANDARD_INFORMATION",
+ "$ATTRIBUTE_LIST",
+ "$FILE_NAME",
+ "$OBJECT_ID",
+ "$SECURITY_DESCRIPTOR",
+ "$VOLUME_NAME",
+ "$VOLUME_INFORMATION",
+ "$DATA",
+ "$INDEX_ROOT",
+ "$INDEX_ALLOCATION",
+ "$BITMAP",
+ "$REPARSE_POINT",
+ "$EA_INFORMATION",
+ "$EA",
+ "$PROPERTY_SET",
+ "$LOGGED_UTILITY_STREAM",
+ NULL
+ };
+
+ int i;
+ long num;
+
+ for (i = 0; attr_name[i]; i++) {
+ if ((strcmp (value, attr_name[i]) == 0) ||
+ (strcmp (value, attr_name[i]+1) == 0)) {
+ *attr = (ATTR_TYPES) ((i+1)*16);
+ return 1;
+ }
+ }
+
+ num = strtol (value, NULL, 0);
+ if ((num > 0) && (num < 257)) {
+ *attr = (ATTR_TYPES) num;
+ return 1;
+ }
+
+ return 0;
+}
+
+/**
* parse_options - Read and validate the programs command line
*
* Read the command line, verify the syntax and parse the options.
@@ -113,7 +167,7 @@ static int parse_options (int argc, char
int err = 0;
int ver = 0;
int help = 0;
- s64 attr;
+ ATTR_TYPES attr = AT_UNUSED;
opterr = 0; /* We'll handle the errors, thank you. */
@@ -133,16 +187,16 @@ static int parse_options (int argc, char
}
break;
case 'a':
- if (opts.attr != (ATTR_TYPES)-1)
+ if (opts.attr != (ATTR_TYPES)-1) {
Eprintf("You must specify exactly one attribute.\n");
- else if (utils_parse_size(optarg, &attr, FALSE)) {
- opts.attr = (ATTR_TYPES)attr;
+ } else if (parse_attribute (optarg, &attr) > 0) {
+ opts.attr = attr;
break;
- } else
- Eprintf("Couldn't parse attribute number.\n");
+ } else {
+ Eprintf("Couldn't parse attribute.\n");
+ }
err++;
break;
-
case 'f':
opts.force++;
break;
@@ -208,18 +262,41 @@ static int parse_options (int argc, char
}
/**
+ * index_get_size - Find the INDX block size from the index root
+ * @inode: Inode of the directory to be checked
+ *
+ * Find the size of a directory's INDX block from the INDEX_ROOT attribute.
+ *
+ * Return: n Success, the INDX blocks are n bytes in size
+ * 0 Error, not a directory
+ */
+static int index_get_size (ntfs_inode *inode)
+{
+ ATTR_RECORD *attr90;
+ INDEX_ROOT *iroot;
+
+ attr90 = find_first_attribute (AT_INDEX_ROOT, inode->mrec);
+ if (!attr90)
+ return 0; // not a directory
+
+ iroot = (INDEX_ROOT*)((u8*)attr90 + le16_to_cpu(attr90->value_offset));
+
+ return iroot->index_block_size;
+}
+
+/**
* cat
*/
-static int cat (ntfs_volume *vol __attribute__((unused)), ntfs_inode *inode,
- ATTR_TYPES type, ntfschar *name __attribute__((unused)),
+static int cat (ntfs_volume *vol, ntfs_inode *inode, ATTR_TYPES type,
+ ntfschar *name __attribute__((unused)),
int namelen __attribute__((unused)))
{
- /* increase 1024 only if you fix partial writes below */
- const int bufsize = 1024;
+ const int bufsize = 4096;
char *buffer;
ntfs_attr *attr;
s64 bytes_read, written;
s64 offset;
+ u32 block_size;
buffer = malloc (bufsize);
if (!buffer)
@@ -227,14 +304,28 @@ static int cat (ntfs_volume *vol __attri
attr = ntfs_attr_open (inode, type, NULL, 0);
if (!attr) {
- Eprintf ("Cannot cat a directory.\n");
+ Eprintf ("Cannot find attribute type 0x%lx.\n", (long) type);
free (buffer);
return 1;
}
+ if ((inode->mft_no < 2) && (attr->type == AT_DATA))
+ block_size = vol->mft_record_size;
+ else if (attr->type == AT_INDEX_ALLOCATION)
+ block_size = index_get_size (inode);
+ else
+ block_size = 0;
+
offset = 0;
for (;;) {
- bytes_read = ntfs_attr_pread (attr, offset, bufsize, buffer);
+ if (block_size > 0) {
+ // These types have fixup
+ bytes_read = ntfs_attr_mst_pread(attr, offset, 1, block_size, buffer);
+ bytes_read *= block_size;
+ } else {
+ bytes_read = ntfs_attr_pread (attr, offset, bufsize, buffer);
+ }
+ //fprintf (stderr, "read %lld bytes\n", bytes_read);
if (bytes_read == -1) {
perror ("ERROR: Couldn't read file");
break;
@@ -275,8 +366,6 @@ int main (int argc, char *argv[])
utils_set_locale();
- //XXX quieten errors, temporarily
-
vol = utils_mount_volume (opts.device, MS_RDONLY, opts.force);
if (!vol) {
perror("ERROR: couldn't mount volume");
@@ -301,12 +390,8 @@ int main (int argc, char *argv[])
ntfs_inode_close (inode);
ntfs_umount (vol, FALSE);
-#if 0
- if (result)
- Printf ("failed\n");
- else
- Printf ("success\n");
-#endif
+
return result;
}
+
Index: ntfscat.8.in
===================================================================
RCS file: /cvsroot/linux-ntfs/ntfsprogs/ntfsprogs/ntfscat.8.in,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -p -r1.7 -r1.8
--- ntfscat.8.in 1 Jun 2004 20:07:35 -0000 1.7
+++ ntfscat.8.in 20 Jun 2005 14:24:53 -0000 1.8
@@ -32,13 +32,48 @@ is equivalent to
.BR "\-f \-v" .
Long named options can be abbreviated to any unique prefix of their name.
.TP
-.B \-f
+.B "\-a " desc
.br
.ns
.TP
-.B \-\-force
-This will override some sensible defaults, such as not working with a mounted
-volume. Use this option with caution.
+.B "\-\-attribute " desc
+Display the contents of a particular attribute. By default, the unname $DATA
+attribute will be shown. The attribute can be specified by number (in decimal
+or hexadecimal), or by name.
+.TS
+lB lB lB
+l l l.
+Hex Decimal Name
+0x10 16 "$STANDARD_INFORMATION",
+0x20 32 "$ATTRIBUTE_LIST",
+0x30 48 "$FILE_NAME",
+0x40 64 "$OBJECT_ID",
+0x50 80 "$SECURITY_DESCRIPTOR",
+0x60 96 "$VOLUME_NAME",
+0x70 112 "$VOLUME_INFORMATION",
+0x80 128 "$DATA",
+0x90 144 "$INDEX_ROOT",
+0xA0 160 "$INDEX_ALLOCATION",
+0xB0 176 "$BITMAP",
+0xC0 192 "$REPARSE_POINT",
+0xD0 208 "$EA_INFORMATION",
+0xE0 224 "$EA",
+0xF0 240 "$PROPERTY_SET",
+0x100 256 "$LOGGED_UTILITY_STREAM",
+.TE
+.br
+.B Notes
+.br
+The attribute names may be given without the leading $ symbol.
+.br
+If you use the $ symbol, you must escape it from the shell.
+.TP
+.B "\-i " num
+.br
+.ns
+.TP
+.B "\-\-inode " num
+Specify a file by its inode number instead of its name.
.TP
.B \-h
.br
@@ -66,7 +101,7 @@ Show the version number, copyright and l
.br
.ns
.TP
-.B \-\-vebose
+.B \-\-verbose
Display more debug/warning/error messages.
.SH EXAMPLES
Display the contents of a file in the root of an NTFS volume.
@@ -79,6 +114,14 @@ Display the contents of a file in a subd
.RS
.sp
.B ntfscat /dev/hda1 /winnt/system32/drivers/etc/hosts
+.RE
+.sp
+Display the contents of the $INDEX_ROOT attribute of the root directory (inode
+5).
+.RS
+.sp
+.B ntfscat /dev/hda1 \-a INDEX_ROOT \-i 5 | hexdump \-C
+.RE
.SH BUGS
.B ntfscat
was written in a short time, to get something "out there". It needs a lot more work.
|