150 lines
3.6 KiB
C
150 lines
3.6 KiB
C
/* Copyright (C) 2005 David Decotigny
|
|
|
|
This program is free software; you can redistribute it and/or
|
|
modify 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; if not, write to the Free Software
|
|
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
|
USA.
|
|
*/
|
|
|
|
#include <libc.h>
|
|
#include <stdarg.h>
|
|
#include <debug.h>
|
|
|
|
#include "fstest_utils.h"
|
|
|
|
|
|
/** Helper functions that dumps the contents of the current working
|
|
directory of the process */
|
|
static void cwd_ls(int detailed, int recursive, int reclevel)
|
|
{
|
|
char tab[256], *c;
|
|
int i;
|
|
struct dirent * dirent;
|
|
DIR * here;
|
|
|
|
here = opendir(".");
|
|
if (! here)
|
|
return;
|
|
|
|
/* Build initial tabulation */
|
|
if (recursive)
|
|
{
|
|
for (c = tab, i = 0 ; (i < reclevel) && (i < sizeof(tab)/2) ; i++)
|
|
{
|
|
*c++ = ' ';
|
|
*c++ = ' ';
|
|
}
|
|
*c++ = '\0';
|
|
}
|
|
else
|
|
*tab = '\0';
|
|
|
|
while ((dirent = readdir(here)) != NULL)
|
|
{
|
|
char entrychar;
|
|
char * entrysuffix;
|
|
|
|
switch(dirent->type)
|
|
{
|
|
case S_IFREG: entrychar='-'; entrysuffix=""; break;
|
|
case S_IFDIR: entrychar='d'; entrysuffix="/"; break;
|
|
case S_IFLNK: entrychar='l'; entrysuffix="@"; break;
|
|
case S_IFCHR: entrychar='c'; entrysuffix=NULL; break;
|
|
case S_IFBLK: entrychar='b'; entrysuffix=NULL; break;
|
|
default: entrychar='?'; entrysuffix="?!?"; break;
|
|
}
|
|
|
|
if (detailed)
|
|
{
|
|
struct stat stat;
|
|
char target_name[SOS_FS_DIRENT_NAME_MAXLEN];
|
|
char majorminor[24];
|
|
|
|
if (lstat(dirent->name, & stat))
|
|
continue;
|
|
|
|
*target_name = '\0';
|
|
if (stat.st_type == S_IFLNK)
|
|
{
|
|
int fd = open(dirent->name, O_RDONLY | O_NOFOLLOW);
|
|
if (fd >= 0)
|
|
{
|
|
int len = read(fd, target_name, sizeof(target_name) - 1);
|
|
if (len < 0)
|
|
*target_name='\0';
|
|
else
|
|
target_name[len] = '\0';
|
|
close(fd);
|
|
}
|
|
}
|
|
else if ( (stat.st_type == S_IFCHR) || (stat.st_type == S_IFBLK) )
|
|
{
|
|
snprintf(majorminor, sizeof(majorminor), " %d,%d",
|
|
stat.st_rdev_major, stat.st_rdev_minor);
|
|
entrysuffix = majorminor;
|
|
}
|
|
|
|
bochs_printf("%s%c%c%c%c %lld %s%s%s%s (location=0x%llx)\n",
|
|
tab, entrychar,
|
|
(stat.st_access_rights&S_IRUSR)?'r':'-',
|
|
(stat.st_access_rights&S_IWUSR)?'w':'-',
|
|
(stat.st_access_rights&S_IXUSR)?'x':'-',
|
|
stat.st_size,
|
|
dirent->name,
|
|
entrysuffix,
|
|
(stat.st_type==S_IFLNK)?" -> ":"",
|
|
target_name,
|
|
stat.st_storage_location);
|
|
}
|
|
else
|
|
bochs_printf("%s%s%s\n",
|
|
tab, dirent->name, entrysuffix);
|
|
|
|
/* Next iteration */
|
|
if (recursive && (dirent->type == S_IFDIR))
|
|
{
|
|
int fd_here = dirfd(here);
|
|
if (chdir(dirent->name))
|
|
continue;
|
|
cwd_ls(detailed, recursive, reclevel+1);
|
|
if(fchdir(fd_here))
|
|
{
|
|
closedir(here);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
closedir(here);
|
|
}
|
|
|
|
|
|
void ls(const char * path, int detailed, int recursive)
|
|
{
|
|
int fd_here = open(".", O_RDONLY | O_DIRECTORY);
|
|
if (fd_here < 0)
|
|
return;
|
|
|
|
if (chdir(path))
|
|
{
|
|
close(fd_here);
|
|
return;
|
|
}
|
|
|
|
bochs_printf("----------- Contents of %s:\n", path);
|
|
cwd_ls(detailed, recursive, 1);
|
|
bochs_printf("---------------------------\n");
|
|
|
|
fchdir(fd_here);
|
|
close(fd_here);
|
|
}
|