home *** CD-ROM | disk | FTP | other *** search
/ PC-Online 1996 May / PCOnline_05_1996.bin / linux / source / xap / xfm / xfm-1.000 / xfm-1 / xfm-1.3.2 / src / FmDirs.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-03-24  |  6.7 KB  |  267 lines

  1. /*---------------------------------------------------------------------------
  2.   Module FmDirs.c                                                           
  3.  
  4.   (c) Simon Marlow 1990-1993
  5.   (c) Albert Graef 1994
  6.  
  7.   functions for manipulating directory lists, and some other utilities
  8.   related to the file system.
  9.  
  10.   modified 1-29-95 by rodgers@lvs-emh.lvs.loral.com (Kevin M. Rodgers)
  11.   to add filtering of icon/text directory displays by a filename filter.
  12.  
  13. -----------------------------------------------------------------------------*/
  14.  
  15. #include <memory.h>
  16. #include <string.h>
  17. #include <stdlib.h>
  18.  
  19. #include <X11/Intrinsic.h>
  20.  
  21. #include "Fm.h"
  22.  
  23. /*-----------------------------------------------------------------------------
  24.   STATIC DATA                                       
  25. -----------------------------------------------------------------------------*/
  26.  
  27. static SortType sort_type;
  28. static Boolean dirs_first;
  29.  
  30. /*-----------------------------------------------------------------------------
  31.   PRIVATE FUNCTIONS
  32. -----------------------------------------------------------------------------*/
  33.  
  34. static int comp(FileRec **fr1, FileRec **fr2)
  35. {
  36.   FileRec *fl1 = *fr1, *fl2 = *fr2;
  37.  
  38.   if (dirs_first) {
  39.     if (S_ISDIR(fl1->stats.st_mode)) {
  40.       if (!S_ISDIR(fl2->stats.st_mode))
  41.     return -1;
  42.     }
  43.     else if (S_ISDIR(fl2->stats.st_mode))
  44.       return 1;
  45.   }
  46.     
  47.   switch (sort_type) {
  48.   case SortByName:
  49.     return strcmp(fl1->name, fl2->name);
  50.   case SortBySize:
  51.     return (int)(fl2->stats.st_size - fl1->stats.st_size);
  52.   case SortByMTime:
  53.     return (int)(fl2->stats.st_mtime - fl1->stats.st_mtime);
  54.   }
  55.  
  56.   return 0;
  57. }
  58.  
  59. /*-----------------------------------------------------------------------------
  60.   PUBLIC FUNCTIONS
  61. -----------------------------------------------------------------------------*/
  62.  
  63. /* Read in the directory for the file window specified. Note that since we have
  64.    the stats available for the directory, we could simply check the modification
  65.    time, and only read in the directory if necessay. This isn't worth it though-
  66.    the time taken to stat all the files (which still needs to be done) far
  67.    outweighs the time to read in the dir */
  68.  
  69. Boolean readDirectory(FileWindowRec *fw)
  70. {
  71.   FileList fl = NULL;
  72.   DIR *dir;
  73.   struct dirent *entry;
  74.   int d, i, m;
  75.  
  76.   if ((d = findDev(fw->directory)) != -1) mountDev(d);
  77.   fw->dev = d;
  78.  
  79.   if (stat(fw->directory, &fw->stats))
  80.     goto error2;
  81.  
  82.   if (chdir(fw->directory))
  83.     goto error2;
  84.  
  85.   if (!(dir = opendir(".")))
  86.     goto error2;
  87.  
  88.   fw->n_bytes = 0;
  89.  
  90.   for(i = 0; (entry = readdir(dir)); i++) {
  91.     fl = (FileRec **) XTREALLOC(fl, (i+1)*sizeof(FileRec *));
  92.     fl[i] = (FileRec *) XtMalloc(sizeof(FileRec));
  93.     strcpy(fl[i]->name, entry->d_name);
  94. #ifdef MAGIC_HEADERS
  95.     magic_get_type(entry->d_name, fl[i]->magic_type);
  96. #endif
  97.     if (lstat(entry->d_name, &(fl[i]->stats)))
  98.       goto error1;
  99.     if (S_ISLNK(fl[i]->stats.st_mode)) {
  100.       fl[i]->sym_link = True;
  101.       stat(entry->d_name, &(fl[i]->stats));
  102.     }
  103.     else
  104.       fl[i]->sym_link = False;
  105.     fl[i]->selected = False;
  106.     fw->n_bytes += fl[i]->stats.st_size;
  107.   }
  108.  
  109.   if (closedir(dir))
  110.     goto error1;
  111.  
  112.   fw->files = fl;
  113.   fw->n_files = i;
  114.   return True;
  115.  
  116.  error1:
  117.   for(m = 0; m <= i; m++)
  118.     XTFREE(fl[m]);
  119.   XTFREE(fl);
  120.  
  121.  error2:
  122.   return False;
  123.  
  124. /*-----------------------------------------------------------------------------
  125.   Remove either files or directories from a FileList
  126. -----------------------------------------------------------------------------*/
  127.  
  128. void filterDirectory(FileWindowRec *fw, FilterType type)
  129. {
  130.   FileList fl = NULL, oldfl = fw->files;
  131.   int n = 0, m = 0;
  132.  
  133. #ifdef DEBUG_MALLOC
  134.   fprintf(stderr,"entering filterDirectory: %lu\n",malloc_inuse(NULL));
  135. #endif
  136.  
  137.   fw->n_bytes = 0;
  138.  
  139.   for (; m < fw->n_files; m++) {
  140.     if (
  141.     ( !strcmp(oldfl[m]->name,".") && (type == Directories) ) ||
  142.     ( strcmp(oldfl[m]->name,".") && 
  143.      (
  144.       !strcmp(oldfl[m]->name,"..") ||
  145.       (
  146.        (fw->show_hidden || (oldfl[m]->name[0] != '.')) &&
  147.        (
  148.         (S_ISDIR(oldfl[m]->stats.st_mode) && (type != Files)) ||
  149.         (!S_ISDIR(oldfl[m]->stats.st_mode) && type != Directories)
  150.         )
  151.        )
  152.       )
  153.      )
  154.     ) {
  155.       /* KMR now filter on dirFilter (I wouldn't dare mess with the above!) */
  156.       /* AG modified to exclude folders from filtering */
  157.       if ((type == Directories) || !fw->do_filter || 
  158.       S_ISDIR(oldfl[m]->stats.st_mode) ||
  159.       fnmatch(fw->dirFilter, oldfl[m]->name)) {
  160.     fl = (FileList) XTREALLOC(fl, (n+1)*sizeof(FileRec *));
  161.     fl[n] = oldfl[m];
  162.     n++;
  163.     fw->n_bytes += oldfl[m]->stats.st_size;
  164.       }
  165.       else
  166.     XTFREE(oldfl[m]);
  167.     }
  168.     else
  169.       XTFREE(oldfl[m]);
  170.   }
  171.   XTFREE(oldfl);
  172.   
  173. #ifdef DEBUG_MALLOC
  174.   fprintf(stderr,"exiting filterDirectory: %lu\n",malloc_inuse(NULL));
  175. #endif
  176.  
  177.   fw->n_files = n;
  178.   fw->files = fl;
  179. }  
  180.  
  181.  
  182. /*-----------------------------------------------------------------------------
  183.   Sort a directory according to the sort type and dfirst flag
  184. -----------------------------------------------------------------------------*/
  185.  
  186. void sortDirectory(FileList fl, int n, SortType type, Boolean dfirst)
  187. {
  188.   sort_type = type;
  189.   dirs_first = dfirst;
  190.   qsort(fl, n, sizeof(FileRec *), (int (*)(const void *, const void *))comp);
  191. }
  192.  
  193.  
  194. /*-----------------------------------------------------------------------------
  195.   Check permission for an operation, equivalent to UNIX access()
  196. -----------------------------------------------------------------------------*/
  197.  
  198. int permission(struct stat *stats, int perms)
  199. {
  200.   int mode = stats->st_mode;
  201.   int result = 0;
  202.  
  203.   if (user.uid == 0 || user.uid == stats->st_uid) {
  204.     if (mode & S_IRUSR)
  205.       result |= P_READ;
  206.     if (mode & S_IWUSR)
  207.       result |= P_WRITE;
  208.     if (mode & S_IXUSR)
  209.       result |= P_EXECUTE;
  210.   } 
  211.  
  212.   else if (user.uid == 0 || user.gid == stats->st_gid) {
  213.     if (mode & S_IRGRP)
  214.       result |= P_READ;
  215.     if (mode & S_IWGRP)
  216.       result |= P_WRITE;
  217.     if (mode & S_IXGRP)
  218.       result |= P_EXECUTE;
  219.   } 
  220.  
  221.   else {
  222.     if (mode & S_IROTH)
  223.       result |= P_READ;
  224.     if (mode & S_IWOTH)
  225.       result |= P_WRITE;
  226.     if (mode & S_IXOTH)
  227.       result |= P_EXECUTE;
  228.   } 
  229.  
  230.   return (result & perms) == perms;
  231. }
  232.  
  233. void makePermissionsString(char *s, int perms)
  234. {
  235.   s[0] = perms & S_IRUSR ? 'r' : '-'; 
  236.   s[1] = perms & S_IWUSR ? 'w' : '-'; 
  237.   s[2] = perms & S_IXUSR ? 'x' : '-'; 
  238.  
  239.   s[3] = perms & S_IRGRP ? 'r' : '-'; 
  240.   s[4] = perms & S_IWGRP ? 'w' : '-'; 
  241.   s[5] = perms & S_IXGRP ? 'x' : '-'; 
  242.  
  243.   s[6] = perms & S_IROTH ? 'r' : '-'; 
  244.   s[7] = perms & S_IWOTH ? 'w' : '-'; 
  245.   s[8] = perms & S_IXOTH ? 'x' : '-'; 
  246.   
  247.   s[9] = '\0';
  248. }
  249.  
  250. /*---------------------------------------------------------------------------*/
  251.  
  252. void freeFileList(FileWindowRec *fw)
  253. {
  254.   int i;
  255.  
  256.   if (fw->files) {
  257.     for (i = 0; i < fw->n_files; i++)
  258.       XTFREE(fw->files[i]);
  259.     XTFREE(fw->files);
  260.     fw->files = NULL;
  261.   }
  262.   fw->n_files = 0;
  263.   fw->n_bytes = 0;
  264. }  
  265.  
  266.