home *** CD-ROM | disk | FTP | other *** search
/ PC-Online 1998 February / PCOnline_02_1998.iso / filesbbs / win95 / ext2tool.exe / SRC / E2LS.C < prev    next >
C/C++ Source or Header  |  1996-01-09  |  8KB  |  309 lines

  1. /***************************************************************************
  2.  * e2ls - DOS ls program for ext2 file systems
  3.  *
  4.  * Copyright (C) 1995 Claus Tondering, ct@login.dknet.dk
  5.  * This file may be redistributed under the terms of the GNU Public License.
  6.  ***************************************************************************/
  7.  
  8. #include <stdio.h>
  9. #include <unistd.h>
  10. #include <stdlib.h>
  11. #include <time.h>
  12. #include <errno.h>
  13. #include <sys/types.h>
  14.  
  15. #include "ext2_fs.h"
  16. #include "ext2fs/ext2fs.h"
  17. #include "ldisk.h"
  18. #include "e2glob.h"
  19. #include "istat.h"
  20. #include "e2err.h"
  21. #include "globlib/glob.h"
  22.  
  23. extern io_manager msdos_io_manager;
  24.  
  25. int aflag, dflag, iflag, lflag, tflag, rflag;
  26. int hasprinted;
  27.  
  28. #define NAMELEN 80
  29. struct fileinfo {
  30.     ino_t    inode;
  31.     u_char    name[NAMELEN];
  32.     struct ext2_inode e2ino;
  33. } *list;
  34. int listix;
  35. int maxlist;
  36.  
  37. void outino(struct fileinfo *);
  38.  
  39.  
  40. /**********************************************************************
  41.  * myproc is a callback routine which is called once for each entry
  42.  * in the directory
  43.  **********************************************************************/
  44.  
  45. static int myproc(struct ext2_dir_entry *dirent,
  46.                   int    offset,
  47.                   int    blocksize,
  48.                   char    *buf,
  49.                   void    *private)
  50. {
  51.     if (!list) {
  52.         list = malloc(100*sizeof(struct fileinfo));
  53.         if (!list)
  54.             return E2E_BADMEM;
  55.         maxlist = 100;
  56.     }
  57.  
  58.     if (dirent->name[0]=='.' && !aflag)
  59.         return 0;
  60.  
  61.     list[listix].inode=dirent->inode;
  62.     strncpy(list[listix].name,dirent->name,dirent->name_len);
  63.     list[listix].name[dirent->name_len] = 0;
  64.  
  65.     listix++;
  66.     if (listix==maxlist) {
  67.         list = realloc(list, (maxlist+100) * sizeof(struct fileinfo));
  68.         if (!list) {
  69.             fprintf(stderr,"Cannot allocate memory\n");
  70.             return DIRENT_ABORT;
  71.         }
  72.         maxlist += 100;
  73.     }
  74.     return 0;
  75. }
  76.  
  77.  
  78. /**********************************************************************
  79.  * compare is used by qsort() to compare to list entries
  80.  **********************************************************************/
  81.  
  82. int
  83. compare(const void *ee1, const void *ee2)
  84. {
  85.     int res;
  86.     const struct fileinfo *e1 = ee1, *e2 = ee2;
  87.  
  88.     if (tflag)
  89.         res = e1->e2ino.i_mtime < e2->e2ino.i_mtime ? 1 : -1;
  90.     else
  91.         res = strcmp(e1->name, e2->name);
  92.  
  93.     return rflag ? -res : res;
  94. }
  95.  
  96.  
  97. /**********************************************************************
  98.  * usage prints usage information and exits
  99.  **********************************************************************/
  100.  
  101. void
  102. usage()
  103. {
  104.     fprintf(stderr, "usage: e2ls [-adiltr] [file]\n");
  105.     exit(1);
  106. }
  107.  
  108.  
  109. /**********************************************************************
  110.  * main routine
  111.  **********************************************************************/
  112.  
  113. main(int argc, char **argv)
  114. {
  115.     int err, i, j, k, c;
  116.     ext2_filsys fs;
  117.     ino_t ino;
  118.     struct ext2_inode e2ino;
  119.     glob_t globs;
  120.  
  121.     opterr = 0;
  122.     while ((c=getopt(argc, argv, "adiltr")) != -1) {
  123.         switch (c) {
  124.          case 'a': aflag++; break;
  125.          case 'd': dflag++; break;
  126.          case 'i': iflag++; break;
  127.          case 'l': lflag++; break;
  128.          case 't': tflag++; break;
  129.          case 'r': rflag++; break;
  130.          case '?': usage();
  131.         }
  132.     }
  133.  
  134.     if (argc==optind) {
  135.         optind--;
  136.         argv[optind]=".";
  137.     }
  138.  
  139.     /* Open file system */
  140.     err = ext2fs_open(0, 0, 0, 0, msdos_io_manager, &fs);
  141.     if (err)
  142.         e2_err("Cannot open ext2 file system",err);
  143.  
  144.     e2glob_init(fs);
  145.     
  146.     for (k=optind; k<argc; k++) {
  147.         char *dirlist;    /* dirlist[i] will be 1 if globs.gl_pathv[i] is a directory */
  148.  
  149.         glob(argv[k], GLOB_NOCHECK, 0, &globs);
  150.  
  151.         dirlist = malloc(globs.gl_pathc);
  152.         if (!dirlist) {
  153.             fprintf(stderr,"Cannot allocate memory\n");
  154.             exit(1);
  155.         }
  156.  
  157.         /* We make two passes - one for plain files and one for directories */
  158.  
  159.         /* First print plain files */
  160.         for (j=0; j<globs.gl_pathc; j++) {
  161.             /* Lookup specified name */
  162.             err = ext2fs_namei(fs, 2, cwdino, globs.gl_pathv[j], &ino);
  163.             if (err)
  164.                 e2_err2("Cannot find file", globs.gl_pathv[j], err);
  165.  
  166.             /* Read specified inode */
  167.             err = ext2fs_read_inode(fs, ino, &e2ino);
  168.             if (err)
  169.                 e2_err("Cannot read inode information", err);
  170.  
  171.             /* Is it a directory? */
  172.             if (!S_ISDIR(e2ino.i_mode) || dflag) {
  173.                 struct fileinfo fi;
  174.                 fi.inode = ino;
  175.                 strcpy(fi.name, globs.gl_pathv[j]);
  176.                 fi.e2ino = e2ino;
  177.                 outino(&fi);
  178.                 dirlist[j] = 0;
  179.             }
  180.             else
  181.                 dirlist[j] = 1;
  182.         }
  183.  
  184.         /* Then print directories */
  185.         if (!dflag)
  186.             for (j=0; j<globs.gl_pathc; j++) {
  187.                 if (!dirlist[j]) continue;
  188.  
  189.                 /* Lookup specified name */
  190.                 err = ext2fs_namei(fs, 2, cwdino, globs.gl_pathv[j], &ino);
  191.                 if (err)
  192.                     e2_err2("Cannot find file", globs.gl_pathv[j], err);
  193.  
  194.                 /* Read specified inode */
  195.                 err = ext2fs_read_inode(fs, ino, &e2ino);
  196.                 if (err)
  197.                     e2_err("Cannot read inode information", err);
  198.  
  199.                 /* Is it a directory? */
  200.                 if (S_ISDIR(e2ino.i_mode)) {
  201.                     if (argc>optind+1 || globs.gl_pathc>1) {
  202.                         /* Print directory name */
  203.                         if (hasprinted)
  204.                             printf("\n");
  205.                         else
  206.                             hasprinted = 1;
  207.                         printf("%s:\n",globs.gl_pathv[j]);
  208.                     }
  209.                     /* Loop through all directory entries */
  210.                     err = ext2fs_dir_iterate(fs, ino, 0, 0, myproc, 0);
  211.                     if (err)
  212.                         e2_err("Cannot read directory",err);
  213.  
  214.                     if (lflag || tflag)
  215.                         for (i=0; i<listix; i++) {
  216.                             err = ext2fs_read_inode(fs, list[i].inode, &list[i].e2ino);
  217.                             if (err)
  218.                                 e2_err("Cannot read file information",err);
  219.                         }
  220.  
  221.  
  222.                     qsort(list, listix, sizeof(list[0]), compare);
  223.  
  224.                     for (i=0; i<listix; i++)
  225.                         outino(&list[i]);
  226.  
  227.                     free(list);
  228.                     list = NULL;
  229.                     maxlist = 0;
  230.                     listix = 0;
  231.                 }
  232.             }
  233.  
  234.         free(dirlist);
  235.     }
  236. }
  237.  
  238.  
  239. /**********************************************************************
  240.  * outino writes one line of directory information
  241.  **********************************************************************/
  242.  
  243. void
  244. outino(struct fileinfo *fi)
  245. {
  246.     char *mtimestring;
  247.     time_t now;
  248.  
  249.     time(&now);
  250.  
  251.     if (iflag)
  252.         printf("%5d ",fi->inode);
  253.  
  254.     if (lflag) {
  255.         if (S_ISDIR(fi->e2ino.i_mode))
  256.             printf("d");
  257.         else if (S_ISREG(fi->e2ino.i_mode))
  258.             printf("-");
  259.         else if (S_ISLNK(fi->e2ino.i_mode))
  260.             printf("l");
  261.         else if (S_ISCHR(fi->e2ino.i_mode))
  262.             printf("c");
  263.         else if (S_ISBLK(fi->e2ino.i_mode))
  264.             printf("b");
  265.         else if (S_ISFIFO(fi->e2ino.i_mode))
  266.             printf("p");
  267.         else if (S_ISSOCK(fi->e2ino.i_mode))
  268.             printf("s");
  269.         else
  270.             printf("?");
  271.  
  272.         printf("%c%c%c%c%c%c%c%c%c ",
  273.                        fi->e2ino.i_mode&S_IRUSR ? 'r' : '-',
  274.                        fi->e2ino.i_mode&S_IWUSR ? 'w' : '-',
  275.                        fi->e2ino.i_mode&S_IXUSR ? 'x' : '-',
  276.                        fi->e2ino.i_mode&S_IRGRP ? 'r' : '-',
  277.                        fi->e2ino.i_mode&S_IWGRP ? 'w' : '-',
  278.                        fi->e2ino.i_mode&S_IXGRP ? 'x' : '-',
  279.                        fi->e2ino.i_mode&S_IROTH ? 'r' : '-',
  280.                        fi->e2ino.i_mode&S_IWOTH ? 'w' : '-',
  281.                        fi->e2ino.i_mode&S_IXOTH ? 'x' : '-');
  282.  
  283.         printf("%2d  %4d %4d ",
  284.                fi->e2ino.i_links_count, fi->e2ino.i_uid, fi->e2ino.i_gid);
  285.  
  286.         if (S_ISCHR(fi->e2ino.i_mode) || S_ISBLK(fi->e2ino.i_mode))
  287.             printf("%3d, %3d ", fi->e2ino.i_block[0]>>8, fi->e2ino.i_block[0]&0xff);
  288.         else
  289.             printf("%8d ", fi->e2ino.i_size);
  290.  
  291.         mtimestring = ctime(&fi->e2ino.i_mtime);
  292.  
  293.         if (fi->e2ino.i_mtime < now-6*30*24*60*60) /* File more than 6 months old */
  294.             printf("%.6s  %.4s ",mtimestring+4, mtimestring+20);
  295.         else
  296.             printf("%.12s ",mtimestring+4);
  297.     }
  298.  
  299.     printf("%s",fi->name);
  300.     
  301.     if (lflag) {
  302.         if (S_ISLNK(fi->e2ino.i_mode))
  303.             printf(" -> %s",(char*)fi->e2ino.i_block);
  304.     }
  305.     printf("\n");
  306.     hasprinted = 1;
  307. }
  308.  
  309.