one include and 256 lines shed

(Logical change 1.88)
edge.strict_endians
flatcap.org!flatcap 2003-01-11 02:09:53 +00:00
parent 986c523c33
commit 4633bcf2de
1 changed files with 15 additions and 256 deletions

View File

@ -49,6 +49,7 @@
#include "layout.h"
#include "inode.h"
#include "disk_io.h"
#include "utils.h"
static const char *AUTHOR = "Richard Russon (FlatCap)";
static const char *EXEC_NAME = "ntfsundelete";
@ -58,49 +59,12 @@ static char *NONE = "<none>";
static char *UNKNOWN = "unknown";
static struct options opts;
GEN_PRINTF (Eprintf, stderr, NULL, FALSE)
GEN_PRINTF (Vprintf, stdout, &opts.verbose, TRUE)
GEN_PRINTF (Iprintf, stdout, &opts.quiet, FALSE)
#define _(S) gettext(S)
/**
* Eprintf - Print error messages
*/
void Eprintf (const char *format, ...)
{
va_list va;
va_start (va, format);
vfprintf (stderr, format, va);
va_end (va);
}
/**
* Iprintf - Print informative messages
*/
void Iprintf (const char *format, ...)
{
va_list va;
#ifndef DEBUG
if (opts.quiet)
return;
#endif
va_start (va, format);
vfprintf (stdout, format, va);
va_end (va);
}
/**
* Vprintf - Print verbose messages
*/
void Vprintf (const char *format, ...)
{
va_list va;
#ifndef DEBUG
if (!opts.verbose)
return;
#endif
va_start (va, format);
vfprintf (stdout, format, va);
va_end (va);
}
/**
* Dprintf - Print debug messages
*/
@ -310,121 +274,6 @@ int parse_time (const char *value, time_t *since)
return 1;
}
/**
* parse_size - Convert a string representing a size
* @value: String to be parsed
* @size: Parsed size
*
* Read a string and convert it to a number. Strings may be suffixed to scale
* them. Any number without a suffix is assumed to be in bytes.
*
* Suffix Description Multiple
* [tT] Terabytes 10^12
* [gG] Gigabytes 10^9
* [mM] Megabytes 10^6
* [kK] Kilobytes 10^3
*
* Notes:
* Only the first character of the suffix is read.
* The multipliers are decimal thousands, not binary: 1000, not 1024.
* If parse_size fails, @size will not be changed
*
* Return: 1 Success
* 0 Error, the string was malformed
*/
int parse_size (const char *value, long long *size)
{
long long result;
char *suffix = NULL;
if (!value || !size)
return 0;
Dprintf ("Parsing size '%s'.\n", value);
result = strtoll (value, &suffix, 10);
if (result < 0 || errno == ERANGE) {
Eprintf ("Invalid size '%s'.\n", value);
return 0;
}
if (!suffix) {
Eprintf ("Internal error, strtoll didn't return a suffix.\n");
return 0;
}
/*if (strlen (suffix) > 1) {
Eprintf ("Invalid size suffix '%s'. Use T, G, M, or K.\n", suffix);
return 0;
} Can't do this because of ranges*/
switch (suffix[0]) {
case 't': case 'T': result *= 1000;
case 'g': case 'G': result *= 1000;
case 'm': case 'M': result *= 1000;
case 'k': case 'K': result *= 1000;
case '-': case 0:
break;
default:
Eprintf ("Invalid size suffix '%s'. Use T, G, M, or K.\n", suffix);
return 0;
}
Dprintf ("Parsed size = %lld.\n", result);
*size = result;
return 1;
}
/**
* parse_range - Convert a string representing a range of numbers
* @string: The string to be parsed
* @start: The beginning of the range will be stored here
* @finish: The end of the range will be stored here
*
* Read a string of the form n-m. If the lower end is missing, zero will be
* substituted. If the upper end is missing LONG_MAX will be used. If the
* string cannot be parsed correctly, @start and @finish will not be changed.
*
* Return: 1 Success, a valid string was found
* 0 Error, the string was not a valid range
*/
int parse_range (const char *string, long long *start, long long *finish)
{
long long a, b;
char *middle;
if (!string || !start || !finish)
return 0;
middle = strchr (string, '-');
if (string == middle) {
Dprintf ("Range has no beginning, defaulting to 0.\n");
a = 0;
} else {
if (!parse_size (string, &a))
return 0;
}
if (middle) {
if (middle[1] == 0) {
b = LONG_MAX;
Dprintf ("Range has no end, defaulting to %lld.\n", b);
} else {
if (!parse_size (middle+1, &b))
return 0;
}
} else {
b = a;
}
Dprintf ("Range '%s' = %lld - %lld\n", string, a, b);
*start = a;
*finish = b;
return 1;
}
/**
* parse_options - Read and validate the programs command line
*
@ -495,7 +344,8 @@ int parse_options (int argc, char *argv[])
break;
case 'c':
if (opts.mode == MODE_NONE) {
if (!parse_range (argv[optind-1], &opts.mft_begin, &opts.mft_end))
if (!utils_parse_range (argv[optind-1],
&opts.mft_begin, &opts.mft_end, TRUE))
err++;
opts.mode = MODE_COPY;
} else {
@ -550,8 +400,8 @@ int parse_options (int argc, char *argv[])
break;
case 'S':
if ((opts.size_begin > 0) || (opts.size_end > 0) ||
!parse_range (argv[optind-1], &opts.size_begin,
&opts.size_end)) {
!utils_parse_range (argv[optind-1], &opts.size_begin,
&opts.size_end, TRUE)) {
err++;
}
break;
@ -703,85 +553,6 @@ void free_file (struct ufile *file)
free (file);
}
/**
* ntfs2utc - Convert an NTFS time to Unix time
* @time: An NTFS time in 100ns units since 1601
*
* NTFS stores times as the number of 100ns intervals since January 1st 1601 at
* 00:00 UTC. This system will not suffer from Y2K problems until ~57000AD.
*
* Return: n A Unix time (number of seconds since 1970)
*/
time_t ntfs2utc (long long time)
{
return (time - ((long long) (369 * 365 + 89) * 24 * 3600 * 10000000)) / 10000000;
}
/**
* find_attribute - Find an attribute of the given type
* @type: An attribute type, e.g. AT_FILE_NAME
* @ctx: A search context, created using ntfs_get_attr_search_ctx
*
* Using the search context to keep track, find the first/next occurrence of a
* given attribute type.
*
* N.B. This will return a pointer into @mft. As long as the search context
* has been created without an inode, it won't overflow the buffer.
*
* Return: Pointer Success, an attribute was found
* NULL Error, no matching attributes were found
*/
ATTR_RECORD * find_attribute (const ATTR_TYPES type, ntfs_attr_search_ctx *ctx)
{
if (!ctx)
return NULL;
if (ntfs_attr_lookup(type, NULL, 0, 0, 0, NULL, 0, ctx) != 0) {
Dprintf ("find_attribute didn't find an attribute of type: 0x%02x.\n", type);
return NULL; /* None / no more of that type */
}
Dprintf ("find_attribute found an attribute of type: 0x%02x.\n", type);
return ctx->attr;
}
/**
* find_first_attribute - Find the first attribute of a given type
* @type: An attribute type, e.g. AT_FILE_NAME
* @mft: A buffer containing a raw MFT record
*
* Search through a raw MFT record for an attribute of a given type.
* The return value is a pointer into the MFT record that was supplied.
*
* N.B. This will return a pointer into @mft. The pointer won't stray outside
* the buffer, since we created the search context without an inode.
*
* Return: Pointer Success, an attribute was found
* NULL Error, no matching attributes were found
*/
ATTR_RECORD * find_first_attribute (const ATTR_TYPES type, MFT_RECORD *mft)
{
ntfs_attr_search_ctx *ctx;
ATTR_RECORD *rec;
if (!mft)
return NULL;
ctx = ntfs_attr_get_search_ctx(NULL, mft);
if (!ctx) {
Eprintf ("Couldn't create a search context.\n");
return NULL;
}
rec = find_attribute (type, ctx);
ntfs_attr_put_search_ctx(ctx);
if (rec)
Dprintf ("find_first_attribute: found attr of type 0x%02x.\n", type);
else
Dprintf ("find_first_attribute: didn't find attr of type 0x%02x.\n", type);
return rec;
}
/**
* get_filenames - Read an MFT Record's $FILENAME attributes
* @file: The file object to work with
@ -1920,7 +1691,7 @@ int copy_mft (ntfs_volume *vol, long long mft_begin, long long mft_end)
for (i = mft_begin; i <= mft_end; i++) {
if (ntfs_attr_pread (mft, vol->mft_record_size * i, vol->mft_record_size, buffer) < vol->mft_record_size) {
Eprintf ("Couldn't read MFT Record %d: %s.\n", i, strerror (errno));
Eprintf ("Couldn't read MFT Record %lld: %s.\n", i, strerror (errno));
goto close;
}
@ -1930,7 +1701,7 @@ int copy_mft (ntfs_volume *vol, long long mft_begin, long long mft_end)
}
}
Vprintf ("Read %d MFT Records\n", mft_end - mft_begin + 1);
Vprintf ("Read %lld MFT Records\n", mft_end - mft_begin + 1);
result = 0;
close:
close (fd);
@ -2006,29 +1777,17 @@ int valid_device (const char *name, int force)
*/
int main (int argc, char *argv[])
{
const char *locale;
ntfs_volume *vol;
int result = 1;
locale = setlocale (LC_ALL, "");
if (!locale) {
locale = setlocale (LC_ALL, NULL);
Vprintf ("Failed to set locale, using default '%s'.\n", locale);
} else {
Vprintf ("Using locale '%s'.\n", locale);
}
utils_set_locale();
if (!parse_options (argc, argv))
goto free;
if (!valid_device (opts.device, opts.force))
goto free;
vol = ntfs_mount (opts.device, MS_RDONLY);
if (!vol) {
Eprintf ("Couldn't mount device '%s': %s\n", opts.device, strerror (errno));
goto free;
}
vol = utils_mount_volume (opts.device, MS_RDONLY, opts.force);
if (!vol)
return 1;
if (vol->flags & VOLUME_IS_DIRTY) {
Iprintf ("Volume is dirty.\n");