home *** CD-ROM | disk | FTP | other *** search
- /***************************************************************************
- * 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 "istat.h"
- #include "e2err.h"
-
- extern io_manager msdos_io_manager;
-
- int aflag, dflag, iflag, lflag, tflag, rflag;
-
- struct fileinfo {
- ino_t inode;
- u_char name[80];
- 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);
-
- 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, c;
- ext2_filsys fs;
- ino_t ino;
- struct ext2_inode e2ino;
- char *filename;
-
- 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)
- filename = ".";
- else if (argc!=optind+1)
- usage();
- else
- filename = 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);
-
- /* Lookup specified name */
- err = ext2fs_namei(fs, 2, cwdino, filename, &ino);
- if (err)
- e2_err("Cannot find file",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, filename);
- fi.e2ino = e2ino;
- outino(&fi);
- }
- else {
- /* 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]);
- }
- }
-
-
- /**********************************************************************
- * 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");
- }
-
-