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