/**
* ntfsls - Part of the Linux-NTFS project.
*
* Copyright (c) 2003 Lode Leroy
* Copyright (c) 2003-2005 Anton Altaparmakov
* Copyright (c) 2003 Richard Russon
* Copyright (c) 2004 Carmelo Kintana
* Copyright (c) 2004 Giang Nguyen
*
* This utility will list a directory's files.
*
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program (in the main directory of the Linux-NTFS
* distribution in the file COPYING); if not, write to the Free Software
* Foundation,Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "config.h"
#ifdef HAVE_STDIO_H
#include <stdio.h>
#endif
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#ifdef HAVE_TIME_H
#include <time.h>
#endif
#ifdef HAVE_GETOPT_H
#include <getopt.h>
#endif
#ifdef HAVE_STRING_H
#include <string.h>
#endif
#include "compat.h"
#include "types.h"
#include "mft.h"
#include "attrib.h"
#include "layout.h"
#include "inode.h"
#include "utils.h"
#include "dir.h"
#include "list.h"
#include "ntfstime.h"
#include "version.h"
#include "logging.h"
/**
* To hold sub-directory information for recursive listing.
* @depth: the level of this dir relative to opts.path
*/
struct dir {
int depth;
};
/**
* path_component - to store path component strings
*
* @name: string pointer
*
* NOTE: @name is not directly allocated memory. It simply points to the
* character array name in struct dir.
*/
struct path_component {
const char *name;
};
/* The list of sub-dirs is like a "horizontal" tree. The root of
* the tree is opts.path, but it is not part of the list because
* that's not necessary. The rules of the list are (in order of
* precedence):
* 1. directories immediately follow their parent.
* 2. siblings are next to one another.
*
* For example, if:
* 1. opts.path is /
* 2. / has 2 sub-dirs: dir1 and dir2
* 3. dir1 has 2 sub-dirs: dir11 and dir12
* 4. dir2 has 0 sub-dirs
* then the list will be:
* dummy head -> dir1 -> dir11 -> dir12 -> dir2
*
* dir_list_insert_pos keeps track of where to insert a sub-dir
* into the list.
*/
/* The global depth relative to opts.path.
* ie: opts.path has depth 0, a sub-dir of opts.path has depth 1
*/
static int depth = 0;
static struct options {
int all;
int system;
int dos;
int lng;
int inode;
int classify;
int recursive;
const char *path;
} opts;
typedef struct {
const unsigned dt_type);
/**
* version - Print version information about the program
*
* Print a copyright statement and a brief description of the program.
*
* Return: none
*/
static void version(void)
{
printf("\n%s v%s (libntfs %s) - Display information about an NTFS "
printf("Copyright (c) 2003 Lode Leroy\n");
printf("Copyright (c) 2003-2005 Anton Altaparmakov\n");
printf("Copyright (c) 2003 Richard Russon\n");
printf("Copyright (c) 2004 Carmelo Kintana\n");
printf("Copyright (c) 2004 Giang Nguyen\n");
}
/**
* usage - Print a list of the parameters to the program
*
* Print a list of the parameters and options for the program.
*
* Return: none
*/
static void usage(void)
{
printf("\nUsage: %s [options] device\n"
"\n"
" -a, --all Display all files\n"
" -F, --classify Display classification\n"
" -f, --force Use less caution\n"
" -h, --help Display this help\n"
" -i, --inode Display inode numbers\n"
" -l, --long Display long info\n"
" -p, --path PATH Directory whose contents to list\n"
" -q, --quiet Less output\n"
" -R, --recursive Recursively list subdirectories\n"
" -s, --system Display system files\n"
" -V, --version Display version information\n"
" -v, --verbose More output\n"
" -x, --dos Use short (DOS 8.3) names\n"
"\n",
printf("NOTE: If neither -a nor -s is specified, the program defaults to -a.\n\n");
}
/**
* parse_options - Read and validate the programs command line
*
* Read the command line, verify the syntax and parse the options.
* This function is very long, but quite simple.
*
* Return: 1 Success
* 0 Error, one or more problems
*/
{
};
int c = -1;
int err = 0;
int ver = 0;
int help = 0;
int levels = 0;
opterr = 0; /* We'll handle the errors, thank you. */
switch (c) {
case 1:
else
err++;
break;
case 'p':
break;
case 'f':
break;
case 'h':
case '?':
err++;
break;
}
help++;
break;
case 'q':
break;
case 'v':
break;
case 'V':
ver++;
break;
case 'x':
break;
case 'l':
break;
case 'i':
break;
case 'F':
break;
case 'a':
break;
case 's':
break;
case 'R':
break;
default:
err++;
break;
}
}
/* Make sure we're in sync with the log levels */
if (levels & NTFS_LOG_LEVEL_VERBOSE)
if (!(levels & NTFS_LOG_LEVEL_QUIET))
/* defaults to -a if -s is not specified */
else {
if (argc > 1)
ntfs_log_error("You must specify exactly one "
"device.\n");
err++;
}
ntfs_log_error("You may not use --quiet and --verbose at the "
"same time.\n");
err++;
}
}
if (ver)
version();
usage();
}
/**
* free_dir - free one dir
* @tofree: the dir to free
*
* Close the inode and then free the dir
*/
{
if (tofree) {
}
}
}
/**
* free_dirs - walk the list of dir's and free each of them
* @dir_list: the list_head of any entry in the list
*
* Iterate over @dir_list, calling free_dir on each entry
*/
{
if (dir_list) {
}
}
}
/**
* readdir_recursive - list a directory and sub-directories encountered
* @ni: ntfs inode of the directory to list
* @pos: current position in directory
* @dirent: context for filldir callback supplied by the caller
*
* For each directory, print its path relative to opts.path. List a directory,
* then list each of its sub-directories.
*
* Returns 0 on success or -1 on error.
*
* NOTE: Assumes recursive option. Currently no limit on the depths of
* recursion.
*/
{
/* list of dirs to "ls" recursively */
.name = {0},
.depth = 0
};
};
int result = 0;
}
depth++;
if (result == 0) {
/* for each of ni's sub-dirs: list in this iteration, then
free at the top of the next iteration or outside of loop */
if (tofree) {
}
/* subdir is not a subdir of ni */
break;
pos2 = 0;
("ntfsls::readdir_recursive(): cannot get inode from pathname.\n");
result = -1;
break;
}
}
puts("");
/* print relative path header */
tempcomp =
struct path_component, list);
}
puts(":");
if (result)
break;
}
}
if (tofree)
/* if at the outer-most readdir_recursive, then clean up */
if (ni_depth == 0) {
}
depth--;
return result;
}
/**
* list_dir_entry
*
* FIXME: Should we print errors as we go along? (AIA)
*/
{
int result = 0;
if (!filename)
return -1;
ntfs_log_error("Cannot represent filename in current locale.\n");
goto free;
}
result = 0; // These are successful
goto free;
goto free;
goto free;
goto free;
{
if (!dir) {
ntfs_log_error("Failed to allocate for subdir.\n");
result = -1;
goto free;
}
}
else
filename);
result = 0;
} else {
if (!ni)
goto release;
if (!ctx)
goto release;
0, ctx))
goto release;
if (!file_name_attr)
goto release;
if (dt_type != NTFS_DT_DIR) {
}
printf("%7llu %8lld %s %s\n",
filename);
else
filename);
if (dir) {
}
result = 0;
/* Release attribute search context and close the inode. */
if (ctx)
if (ni)
}
if (dir) {
if (result == 0) {
} else {
}
}
free:
return result;
}
/**
* main - Begin here
*
* Start from here.
*
* Return: 0 Success, the program worked
* 1 Error, parsing mount options failed
* 2 Error, mount attempt failed
* 3 Error, failed to open root directory
* 4 Error, failed to open directory in search path
*/
{
// FIXME: Print error... (AIA)
return 1;
}
if (!vol) {
// FIXME: Print error... (AIA)
return 2;
}
if (!ni) {
// FIXME: Print error... (AIA)
return 3;
}
/*
* We now are at the final path component. If it is a file just
* list it. If it is a directory, list its contents.
*/
pos = 0;
else
// FIXME: error checking... (AIA)
} else {
int name_len = 0;;
if (!ctx)
return -1;
/* We know this will always be resident. */
}
}
// FIXME: error checking... (AIA)
}
/* Finished with the inode; release it. */
return 0;
}