home *** CD-ROM | disk | FTP | other *** search
/ Chip 2000 May / Chip_2000-05_cd2.bin / dosutils / ext2tool / src / e2ls.c < prev    next >
C/C++ Source or Header  |  1995-05-10  |  6KB  |  250 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 "istat.h"
  19. #include "e2err.h"
  20.  
  21. extern io_manager msdos_io_manager;
  22.  
  23. int aflag, dflag, iflag, lflag, tflag, rflag;
  24.  
  25. struct fileinfo {
  26.     ino_t    inode;
  27.     u_char    name[80];
  28.     struct ext2_inode e2ino;
  29. } *list;
  30. int listix;
  31. int maxlist;
  32.  
  33. void outino(struct fileinfo *);
  34.  
  35.  
  36. /**********************************************************************
  37.  * myproc is a callback routine which is called once for each entry
  38.  * in the directory
  39.  **********************************************************************/
  40.  
  41. static int myproc(struct ext2_dir_entry *dirent,
  42.                   int    offset,
  43.                   int    blocksize,
  44.                   char    *buf,
  45.                   void    *private)
  46. {
  47.     if (!list) {
  48.         list = malloc(100*sizeof(struct fileinfo));
  49.         if (!list)
  50.             return E2E_BADMEM;
  51.         maxlist = 100;
  52.     }
  53.  
  54.     if (dirent->name[0]=='.' && !aflag)
  55.         return 0;
  56.  
  57.     list[listix].inode=dirent->inode;
  58.     strncpy(list[listix].name,dirent->name,dirent->name_len);
  59.  
  60.     listix++;
  61.     if (listix==maxlist) {
  62.         list = realloc(list, (maxlist+100) * sizeof(struct fileinfo));
  63.         if (!list) {
  64.             fprintf(stderr,"Cannot allocate memory\n");
  65.             return DIRENT_ABORT;
  66.         }
  67.         maxlist += 100;
  68.     }
  69.     return 0;
  70. }
  71.  
  72.  
  73. /**********************************************************************
  74.  * compare is used by qsort() to compare to list entries
  75.  **********************************************************************/
  76.  
  77. int
  78. compare(const void *ee1, const void *ee2)
  79. {
  80.     int res;
  81.     const struct fileinfo *e1 = ee1, *e2 = ee2;
  82.  
  83.     if (tflag)
  84.         res = e1->e2ino.i_mtime < e2->e2ino.i_mtime ? 1 : -1;
  85.     else
  86.         res = strcmp(e1->name, e2->name);
  87.  
  88.     return rflag ? -res : res;
  89. }
  90.  
  91.  
  92. /**********************************************************************
  93.  * usage prints usage information and exits
  94.  **********************************************************************/
  95.  
  96. void
  97. usage()
  98. {
  99.     fprintf(stderr, "usage: e2ls [-adiltr] [file]\n");
  100.     exit(1);
  101. }
  102.  
  103.  
  104. /**********************************************************************
  105.  * main routine
  106.  **********************************************************************/
  107.  
  108. main(int argc, char **argv)
  109. {
  110.     int err, i, c;
  111.     ext2_filsys fs;
  112.     ino_t ino;
  113.     struct ext2_inode e2ino;
  114.     char *filename;
  115.  
  116.     opterr = 0;
  117.     while ((c=getopt(argc, argv, "adiltr")) != -1) {
  118.         switch (c) {
  119.          case 'a': aflag++; break;
  120.          case 'd': dflag++; break;
  121.          case 'i': iflag++; break;
  122.          case 'l': lflag++; break;
  123.          case 't': tflag++; break;
  124.          case 'r': rflag++; break;
  125.          case '?': usage();
  126.         }
  127.     }
  128.  
  129.     if (argc==optind)
  130.         filename = ".";
  131.     else if (argc!=optind+1)
  132.         usage();
  133.     else
  134.         filename = argv[optind];
  135.  
  136.     /* Open file system */
  137.     err = ext2fs_open(0, 0, 0, 0, msdos_io_manager, &fs);
  138.     if (err)
  139.         e2_err("Cannot open ext2 file system",err);
  140.  
  141.     /* Lookup specified name */
  142.     err = ext2fs_namei(fs, 2, cwdino, filename, &ino);
  143.     if (err)
  144.         e2_err("Cannot find file",err);
  145.  
  146.     /* Read specified inode */
  147.     err = ext2fs_read_inode(fs, ino, &e2ino);
  148.     if (err)
  149.         e2_err("Cannot read inode information", err);
  150.  
  151.     /* Is it a directory? */
  152.     if (!S_ISDIR(e2ino.i_mode) || dflag) {
  153.         struct fileinfo fi;
  154.         fi.inode = ino;
  155.         strcpy(fi.name, filename);
  156.         fi.e2ino = e2ino;
  157.         outino(&fi);
  158.     }
  159.     else {
  160.         /* Loop through all directory entries */
  161.         err = ext2fs_dir_iterate(fs, ino, 0, 0, myproc, 0);
  162.         if (err)
  163.             e2_err("Cannot read directory",err);
  164.  
  165.         if (lflag || tflag)
  166.             for (i=0; i<listix; i++) {
  167.                 err = ext2fs_read_inode(fs, list[i].inode, &list[i].e2ino);
  168.                 if (err)
  169.                     e2_err("Cannot read file information",err);
  170.             }
  171.  
  172.  
  173.         qsort(list, listix, sizeof(list[0]), compare);
  174.  
  175.         for (i=0; i<listix; i++)
  176.             outino(&list[i]);
  177.     }
  178. }        
  179.  
  180.  
  181. /**********************************************************************
  182.  * outino writes one line of directory information
  183.  **********************************************************************/
  184.  
  185. void
  186. outino(struct fileinfo *fi)
  187. {
  188.     char *mtimestring;
  189.     time_t now;
  190.  
  191.     time(&now);
  192.  
  193.     if (iflag)
  194.         printf("%5d ",fi->inode);
  195.  
  196.     if (lflag) {
  197.         if (S_ISDIR(fi->e2ino.i_mode))
  198.             printf("d");
  199.         else if (S_ISREG(fi->e2ino.i_mode))
  200.             printf("-");
  201.         else if (S_ISLNK(fi->e2ino.i_mode))
  202.             printf("l");
  203.         else if (S_ISCHR(fi->e2ino.i_mode))
  204.             printf("c");
  205.         else if (S_ISBLK(fi->e2ino.i_mode))
  206.             printf("b");
  207.         else if (S_ISFIFO(fi->e2ino.i_mode))
  208.             printf("p");
  209.         else if (S_ISSOCK(fi->e2ino.i_mode))
  210.             printf("s");
  211.         else
  212.             printf("?");
  213.  
  214.         printf("%c%c%c%c%c%c%c%c%c ",
  215.                        fi->e2ino.i_mode&S_IRUSR ? 'r' : '-',
  216.                        fi->e2ino.i_mode&S_IWUSR ? 'w' : '-',
  217.                        fi->e2ino.i_mode&S_IXUSR ? 'x' : '-',
  218.                        fi->e2ino.i_mode&S_IRGRP ? 'r' : '-',
  219.                        fi->e2ino.i_mode&S_IWGRP ? 'w' : '-',
  220.                        fi->e2ino.i_mode&S_IXGRP ? 'x' : '-',
  221.                        fi->e2ino.i_mode&S_IROTH ? 'r' : '-',
  222.                        fi->e2ino.i_mode&S_IWOTH ? 'w' : '-',
  223.                        fi->e2ino.i_mode&S_IXOTH ? 'x' : '-');
  224.  
  225.         printf("%2d  %4d %4d ",
  226.                fi->e2ino.i_links_count, fi->e2ino.i_uid, fi->e2ino.i_gid);
  227.  
  228.         if (S_ISCHR(fi->e2ino.i_mode) || S_ISBLK(fi->e2ino.i_mode))
  229.             printf("%3d, %3d ", fi->e2ino.i_block[0]>>8, fi->e2ino.i_block[0]&0xff);
  230.         else
  231.             printf("%8d ", fi->e2ino.i_size);
  232.  
  233.         mtimestring = ctime(&fi->e2ino.i_mtime);
  234.  
  235.         if (fi->e2ino.i_mtime < now-6*30*24*60*60) /* File more than 6 months old */
  236.             printf("%.6s  %.4s ",mtimestring+4, mtimestring+20);
  237.         else
  238.             printf("%.12s ",mtimestring+4);
  239.     }
  240.  
  241.     printf("%s",fi->name);
  242.     
  243.     if (lflag) {
  244.         if (S_ISLNK(fi->e2ino.i_mode))
  245.             printf(" -> %s",(char*)fi->e2ino.i_block);
  246.     }
  247.     printf("\n");
  248. }
  249.  
  250.