home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PC-Online 1998 February
/
PCOnline_02_1998.iso
/
filesbbs
/
win95
/
ext2tool.exe
/
SRC
/
E2LS.C
< prev
next >
Wrap
C/C++ Source or Header
|
1996-01-09
|
8KB
|
309 lines
/***************************************************************************
* e2ls - DOS ls program for ext2 file systems
*
* Copyright (C) 1995 Claus Tondering, ct@login.dknet.dk
* This file may be redistributed under the terms of the GNU Public License.
***************************************************************************/
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <time.h>
#include <errno.h>
#include <sys/types.h>
#include "ext2_fs.h"
#include "ext2fs/ext2fs.h"
#include "ldisk.h"
#include "e2glob.h"
#include "istat.h"
#include "e2err.h"
#include "globlib/glob.h"
extern io_manager msdos_io_manager;
int aflag, dflag, iflag, lflag, tflag, rflag;
int hasprinted;
#define NAMELEN 80
struct fileinfo {
ino_t inode;
u_char name[NAMELEN];
struct ext2_inode e2ino;
} *list;
int listix;
int maxlist;
void outino(struct fileinfo *);
/**********************************************************************
* myproc is a callback routine which is called once for each entry
* in the directory
**********************************************************************/
static int myproc(struct ext2_dir_entry *dirent,
int offset,
int blocksize,
char *buf,
void *private)
{
if (!list) {
list = malloc(100*sizeof(struct fileinfo));
if (!list)
return E2E_BADMEM;
maxlist = 100;
}
if (dirent->name[0]=='.' && !aflag)
return 0;
list[listix].inode=dirent->inode;
strncpy(list[listix].name,dirent->name,dirent->name_len);
list[listix].name[dirent->name_len] = 0;
listix++;
if (listix==maxlist) {
list = realloc(list, (maxlist+100) * sizeof(struct fileinfo));
if (!list) {
fprintf(stderr,"Cannot allocate memory\n");
return DIRENT_ABORT;
}
maxlist += 100;
}
return 0;
}
/**********************************************************************
* compare is used by qsort() to compare to list entries
**********************************************************************/
int
compare(const void *ee1, const void *ee2)
{
int res;
const struct fileinfo *e1 = ee1, *e2 = ee2;
if (tflag)
res = e1->e2ino.i_mtime < e2->e2ino.i_mtime ? 1 : -1;
else
res = strcmp(e1->name, e2->name);
return rflag ? -res : res;
}
/**********************************************************************
* usage prints usage information and exits
**********************************************************************/
void
usage()
{
fprintf(stderr, "usage: e2ls [-adiltr] [file]\n");
exit(1);
}
/**********************************************************************
* main routine
**********************************************************************/
main(int argc, char **argv)
{
int err, i, j, k, c;
ext2_filsys fs;
ino_t ino;
struct ext2_inode e2ino;
glob_t globs;
opterr = 0;
while ((c=getopt(argc, argv, "adiltr")) != -1) {
switch (c) {
case 'a': aflag++; break;
case 'd': dflag++; break;
case 'i': iflag++; break;
case 'l': lflag++; break;
case 't': tflag++; break;
case 'r': rflag++; break;
case '?': usage();
}
}
if (argc==optind) {
optind--;
argv[optind]=".";
}
/* Open file system */
err = ext2fs_open(0, 0, 0, 0, msdos_io_manager, &fs);
if (err)
e2_err("Cannot open ext2 file system",err);
e2glob_init(fs);
for (k=optind; k<argc; k++) {
char *dirlist; /* dirlist[i] will be 1 if globs.gl_pathv[i] is a directory */
glob(argv[k], GLOB_NOCHECK, 0, &globs);
dirlist = malloc(globs.gl_pathc);
if (!dirlist) {
fprintf(stderr,"Cannot allocate memory\n");
exit(1);
}
/* We make two passes - one for plain files and one for directories */
/* First print plain files */
for (j=0; j<globs.gl_pathc; j++) {
/* Lookup specified name */
err = ext2fs_namei(fs, 2, cwdino, globs.gl_pathv[j], &ino);
if (err)
e2_err2("Cannot find file", globs.gl_pathv[j], err);
/* Read specified inode */
err = ext2fs_read_inode(fs, ino, &e2ino);
if (err)
e2_err("Cannot read inode information", err);
/* Is it a directory? */
if (!S_ISDIR(e2ino.i_mode) || dflag) {
struct fileinfo fi;
fi.inode = ino;
strcpy(fi.name, globs.gl_pathv[j]);
fi.e2ino = e2ino;
outino(&fi);
dirlist[j] = 0;
}
else
dirlist[j] = 1;
}
/* Then print directories */
if (!dflag)
for (j=0; j<globs.gl_pathc; j++) {
if (!dirlist[j]) continue;
/* Lookup specified name */
err = ext2fs_namei(fs, 2, cwdino, globs.gl_pathv[j], &ino);
if (err)
e2_err2("Cannot find file", globs.gl_pathv[j], err);
/* Read specified inode */
err = ext2fs_read_inode(fs, ino, &e2ino);
if (err)
e2_err("Cannot read inode information", err);
/* Is it a directory? */
if (S_ISDIR(e2ino.i_mode)) {
if (argc>optind+1 || globs.gl_pathc>1) {
/* Print directory name */
if (hasprinted)
printf("\n");
else
hasprinted = 1;
printf("%s:\n",globs.gl_pathv[j]);
}
/* Loop through all directory entries */
err = ext2fs_dir_iterate(fs, ino, 0, 0, myproc, 0);
if (err)
e2_err("Cannot read directory",err);
if (lflag || tflag)
for (i=0; i<listix; i++) {
err = ext2fs_read_inode(fs, list[i].inode, &list[i].e2ino);
if (err)
e2_err("Cannot read file information",err);
}
qsort(list, listix, sizeof(list[0]), compare);
for (i=0; i<listix; i++)
outino(&list[i]);
free(list);
list = NULL;
maxlist = 0;
listix = 0;
}
}
free(dirlist);
}
}
/**********************************************************************
* outino writes one line of directory information
**********************************************************************/
void
outino(struct fileinfo *fi)
{
char *mtimestring;
time_t now;
time(&now);
if (iflag)
printf("%5d ",fi->inode);
if (lflag) {
if (S_ISDIR(fi->e2ino.i_mode))
printf("d");
else if (S_ISREG(fi->e2ino.i_mode))
printf("-");
else if (S_ISLNK(fi->e2ino.i_mode))
printf("l");
else if (S_ISCHR(fi->e2ino.i_mode))
printf("c");
else if (S_ISBLK(fi->e2ino.i_mode))
printf("b");
else if (S_ISFIFO(fi->e2ino.i_mode))
printf("p");
else if (S_ISSOCK(fi->e2ino.i_mode))
printf("s");
else
printf("?");
printf("%c%c%c%c%c%c%c%c%c ",
fi->e2ino.i_mode&S_IRUSR ? 'r' : '-',
fi->e2ino.i_mode&S_IWUSR ? 'w' : '-',
fi->e2ino.i_mode&S_IXUSR ? 'x' : '-',
fi->e2ino.i_mode&S_IRGRP ? 'r' : '-',
fi->e2ino.i_mode&S_IWGRP ? 'w' : '-',
fi->e2ino.i_mode&S_IXGRP ? 'x' : '-',
fi->e2ino.i_mode&S_IROTH ? 'r' : '-',
fi->e2ino.i_mode&S_IWOTH ? 'w' : '-',
fi->e2ino.i_mode&S_IXOTH ? 'x' : '-');
printf("%2d %4d %4d ",
fi->e2ino.i_links_count, fi->e2ino.i_uid, fi->e2ino.i_gid);
if (S_ISCHR(fi->e2ino.i_mode) || S_ISBLK(fi->e2ino.i_mode))
printf("%3d, %3d ", fi->e2ino.i_block[0]>>8, fi->e2ino.i_block[0]&0xff);
else
printf("%8d ", fi->e2ino.i_size);
mtimestring = ctime(&fi->e2ino.i_mtime);
if (fi->e2ino.i_mtime < now-6*30*24*60*60) /* File more than 6 months old */
printf("%.6s %.4s ",mtimestring+4, mtimestring+20);
else
printf("%.12s ",mtimestring+4);
}
printf("%s",fi->name);
if (lflag) {
if (S_ISLNK(fi->e2ino.i_mode))
printf(" -> %s",(char*)fi->e2ino.i_block);
}
printf("\n");
hasprinted = 1;
}