home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / SOURCE / XAP / XFILEMAN / XFILEMAN.TAR / xfilemanager / file.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-09-22  |  9.8 KB  |  393 lines

  1. /*
  2.  * Copyright 1993 by Ove Kalkan, Cremlingen, Germany
  3.  *
  4.  * Permission to use, copy, modify, distribute and sell this software and it's
  5.  * documentation for any purpose is hereby granted without fee, rpovided that
  6.  * the above copyright notice and this permission appear in supporting
  7.  * documentation, and that the name of Ove Kalkan not to be used in
  8.  * advertising or publicity pertaining to distributiopn of the software without
  9.  * specific, written prior permission. Ove Kalkan makes no representations
  10.  * about the suitability of this software for any purpose. It is provided
  11.  * as is without express or implied warranty.
  12.  *
  13.  * OVE KALKAN DISPLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
  14.  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABLILITY AND FITNESS, IN NO
  15.  * EVENT SHALL OVE KALKAN BE LIABLE FOR ANY SPECIAL, INDIRECT OR
  16.  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
  17.  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
  18.  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  19.  * PERFORMANCE OF THIS SOFTWARE.
  20.  *
  21.  * $Header: filename,v 1.0 yyyy/mm/dd hh:mm:ss loginname Exp $
  22.  */
  23.  
  24. #include "global.h"
  25.  
  26.  
  27. /*
  28. **    Function name : fillFolder
  29. **
  30. **    Description : Einlesen des gerade angewaehlten Directories
  31. **    Input : Zeiger auf den Folder
  32. **    Ouput : -
  33. */
  34. void fillFolder (Folder_Glyph *folder)
  35. {
  36.     Dir_Glyph    *dir = folder->dir;
  37.     char        s_buf[1024];
  38.     String        dir_path;
  39.     uid_t        uid = getuid();
  40.     gid_t        gid = getgid();
  41.     struct    dirent    *d_ent;
  42.     DIR        *dir_ptr;
  43.  
  44.     /*
  45.      * Wenn der Folder bereits Eintraege enthaaelt, diese loeschen
  46.      */
  47.     if (folder->file_count > 0) {
  48.         int    i;
  49.  
  50.         for (i = 0; i < folder->file_count; i++)
  51.             if (folder->file[i]) {
  52.                 if (folder->file[i]->name)
  53.                     free(folder->file[i]->name);
  54.                 free(folder->file[i]);
  55.             }
  56.         folder->file_count = 0;
  57.     }
  58.     folder->size = 0;
  59.     /*
  60.      * Den vollstaendigen Pfadnamen holen
  61.      */
  62.     dir_path = (String) getPath (dir);
  63.  
  64.     /*
  65.      * Das Dir oeffnen und die Eintraege auslesen
  66.      */
  67.     if (!(dir->flags & DIR_READABLE) || !(dir_ptr = opendir (dir_path))) {
  68.         dir->flags &= (~DIR_READABLE);
  69.         return;        /* Abbruch da nicht geoeffnet */
  70.     }
  71.  
  72.     /*
  73.      * Directory auslesen
  74.      */
  75.     folder->total_count = 0;
  76.  
  77.     while ((d_ent = readdir(dir_ptr))) {
  78.         struct stat    buf;
  79.  
  80.         /*
  81.          * Den vollen Pfadnamen des Direntries erzeugen
  82.          */
  83.         folder->total_count++;
  84.         sprintf (s_buf,"%s%s%s\0", dir_path,
  85.                        (dir_path[1] == '\0' ? "" : "/"),
  86.                        d_ent->d_name);
  87.         /*
  88.          * Den Status des Files holen
  89.          */
  90.         (void) lstat (s_buf, &buf);
  91.         folder->size += buf.st_size;
  92.  
  93.         /*
  94.          * Ueberpruefen ob der Eintrag ein Directory und nicht . oder .. ist
  95.          */
  96.         if (strcmp(d_ent->d_name,".") &&
  97.             (strcmp(d_ent->d_name,"..") || (dir != &root && !defaults.multi_window)) &&
  98.              (!folder->filter || ifFilter(folder,d_ent->d_name))) {
  99.             /*
  100.              * Da dir, Dir_Glyph um einen Eintrag erweitern
  101.              */
  102.             File_Glyph    *new_file;
  103.  
  104.             /*
  105.              * Liste im Glyph um einen Eintrag erweitern
  106.              */
  107.             (folder->file_count)++;
  108.             if (!folder->file) {
  109.                 if (!(folder->file = (File_Glyph **) malloc (sizeof(File_Glyph *))))
  110.                     FATAL_ERROR ("fillFolder: allocating Filelist failed\n");
  111.             }
  112.             else {
  113.                 if (!(folder->file = (File_Glyph **) realloc ((void *) folder->file,
  114.                                     sizeof(File_Glyph *)*folder->file_count)))
  115.                     FATAL_ERROR ("fillFolder: Reallocating Filelist failed\n");
  116.             }
  117.             if (!(new_file = (File_Glyph *) malloc(sizeof(File_Glyph))))
  118.                 FATAL_ERROR ("fillFolder: Allocating new Glyph failed\n");
  119.  
  120.             /*
  121.              * Den neuen Glyph als leer initialisieren
  122.              */
  123.             new_file->uid = buf.st_uid;
  124.             new_file->gid = buf.st_gid;
  125.             new_file->mode = buf.st_mode;
  126.             new_file->size = buf.st_size;
  127.  
  128.             /*
  129.              * Den Namen des Glyphs initialisieren
  130.              */
  131.             if (!(new_file->name = (String) malloc(strlen(d_ent->d_name)+1)))
  132.                 FATAL_ERROR ("fillFolder: Allocating Name for new Glyph failed\n");
  133.             strncpy(new_file->name,d_ent->d_name,strlen(d_ent->d_name));
  134.             new_file->name[strlen(d_ent->d_name)] = '\0';
  135.  
  136.             /*
  137.              * Den Filetype feststellen
  138.              */
  139.             if (uid != 0 &&
  140.                 !((uid == buf.st_uid && S_IRUSR&buf.st_mode) |
  141.                   (gid == buf.st_gid && S_IRGRP&buf.st_mode) | 
  142.                    S_IROTH&buf.st_mode))
  143.                 new_file->prog_type = FILE_LOCK;
  144.             else if (!(strcmp(d_ent->d_name,"..")))
  145.                 new_file->prog_type = FILE_ROOT;
  146.             else if (S_ISLNK(buf.st_mode)) {
  147.                 struct stat    lbuf;
  148.  
  149.                 stat (s_buf,&lbuf);
  150.                 if (S_ISDIR(lbuf.st_mode))
  151.                     new_file->prog_type = FILE_LDIR;
  152.                 else
  153.                     new_file->prog_type = FILE_LINK;
  154.             }
  155.             else if (S_ISDIR(buf.st_mode))
  156.                 new_file->prog_type = FILE_DIR;
  157.              else if ((uid == buf.st_uid  && S_IXUSR&buf.st_mode) |
  158.                  (gid == buf.st_gid  && S_IXGRP&buf.st_mode) | 
  159.                   S_IXOTH&buf.st_mode)
  160.                 new_file->prog_type = FILE_EXEC;
  161.             else if (buf.st_size == 0)
  162.                 new_file->prog_type = FILE_GHOST;
  163.              else if (!tryCommands(new_file))
  164.                 new_file->prog_type = FILE_PLAIN;
  165.  
  166.             folder->file[folder->file_count-1] = new_file;
  167.         }
  168.     }
  169.     closedir (dir_ptr);
  170.  
  171.     /*
  172.      * Die Directoryeintraege aplhabetisch sortieren falls moeglich
  173.      */
  174.     if (folder->file_count > 1) {
  175.         int    i, j;
  176.  
  177.         for (i = 0; i < folder->file_count - 1; i++) {
  178.             for (j = 1; j < folder->file_count - i; j++) {
  179.                 if (compareFGlyph(folder->file[j-1],folder->file[j]) == 1) {
  180.                     File_Glyph *dummy = folder->file[j];
  181.  
  182.                     folder->file[j] = folder->file[j-1];
  183.                     folder->file[j-1] = dummy;
  184.                 }
  185.             }
  186.         }
  187.     }
  188.     free (dir_path);
  189.  
  190.     /*
  191.      * Infofeld setzen
  192.      */
  193.     {    Arg    args[1];
  194.         char    s[100];
  195.  
  196.         sprintf(s,"%d Files shown (%d Files hidden)     Size: %d KBytes",folder->file_count,
  197.                     folder->total_count - folder->file_count,
  198.                     folder->size/1024);
  199.         XtSetArg(args[0],XtNlabel,s);
  200.         XtSetValues(folder->info,args,1);
  201.     }
  202. }
  203.  
  204. /*
  205. **    Function name : compareFGlyph
  206. **
  207. **    Description : Vergleichsfunktion fuer QSort 
  208. **    Input : die zwei obligatorischen Zeiger auf die Elemente
  209. **    Ouput : -1 falls a < b, 0 fall a == b oder 1 fall a > b
  210. */
  211. int compareFGlyph (File_Glyph *da, File_Glyph *db)
  212. {
  213.     int    i;
  214.     char    *a = da->name,
  215.         *b = db->name;
  216.  
  217.     if (da->prog_type > 150 || db->prog_type > 150) {
  218.         if (da->prog_type < db->prog_type)
  219.             return(1);
  220.         else if (da->prog_type > db->prog_type)
  221.             return(-1);
  222.     }
  223.  
  224.     i = (strlen(a) > strlen(b) ? strlen(b) : strlen(a));
  225.     while (i--) {
  226.         if (*a > *b) {
  227.             return(1);
  228.         }
  229.         else if (*a < *b) {
  230.             return(-1);
  231.         }
  232.         a++;
  233.         b++;
  234.     }
  235.     if (strlen(da->name) > strlen(db->name)) {
  236.         return(1);
  237.     }
  238.     if (strlen(da->name) < strlen(db->name)) {
  239.         return(-1);
  240.     }
  241.     return(0);
  242. }
  243.  
  244. /*
  245. **    Function name : showFolder
  246. **
  247. **    Description : Anzeigen der Files des derzeitigen Dirs
  248. **    Input : Zeiger auf das Fensterwidget und den Dir_glyph
  249. **    Ouput : Liefert den Y-Wert des letzen Dir-Glyphs im Baum zurueck
  250. */
  251. void showFolder (Widget window, Folder_Glyph *folder,
  252.            Dimension x, Dimension y,
  253.            Dimension *lx, Dimension *ly,
  254.            Dimension hs, Dimension he)
  255. {
  256.     int    i;
  257.     Boolean    b;
  258.  
  259.     /*
  260.      * Wenn in dem Folder Files sind, dann auflisten
  261.      */
  262.     if (folder->file_count > 0) {
  263.         *lx = 10;
  264.         for (i = 0; i < folder->file_count; i++) {
  265.             if (XTextWidth(defaults.icon_font,folder->file[i]->name,
  266.                 strlen(folder->file[i]->name)) > *lx)
  267.                 *lx = XTextWidth(defaults.icon_font,folder->file[i]->name,
  268.                     strlen(folder->file[i]->name));
  269.         }
  270.  
  271.         /*
  272.          * Fileicon und Label ausgeben
  273.          */
  274.         *lx += 3*DIR_X_STEP + 50;
  275.         folder->max_length = *lx;
  276.  
  277.         for (i = hs; i <= he; i++) {
  278.             b = (i == selc_f && folder == selc_fo ? TRUE : FALSE);
  279.             drawFile (folder, i, b,b);
  280.         }
  281.     }
  282.     *ly = y + folder->file_count*DIR_Y_STEP + 14;
  283. }
  284.  
  285.  
  286. /*********************************************************
  287.  * name:    tryCommand
  288.  * description:    versuchen anhand der suffixliste den Filetyp
  289.  *        heraus zu finden
  290.  * input:    Zeiger auf den File_Gyph
  291.  * output:    1 wenn gefunden, sonst 0
  292.  * date:    
  293.  *********************************************************/
  294. int    tryCommands (File_Glyph *file)
  295. {    int    suf;
  296.  
  297.     suf = 0;
  298.     if (strrstr(file->name,".tar.z\0") || strrstr(file->name,".tar.gz\0")
  299.          || strrstr(file->name,".tar.Z\0") || strrstr(file->name,",taz\0")
  300.          || strrstr(file->name,".tpz\0") || strrstr(file->name,".tgz\0")) {
  301.         file->prog_type = FILE_CTAR;
  302.         return(1);
  303.     }
  304.     if (strrstr(file->name,".tar\0")) {
  305.         file->prog_type = FILE_TAR;
  306.         return(1);
  307.     }
  308.  
  309.     while (filetypes[suf].cmd) {
  310.         char    *a = filetypes[suf].suffix, *b;
  311.         char    buf[30];
  312.         int    i;
  313.  
  314.         if (!a) {
  315.             file->prog_type = filetypes[suf].type;
  316.             return(1);
  317.         }
  318.         do {
  319.             b = strchr(a,',');
  320.             if (b)
  321.                 i = strlen(a) - strlen(b);
  322.             else
  323.                 i = strlen(a);
  324.             strncpy(buf,a,i);
  325.             buf[i] = '\0';
  326.             a = b+1;
  327.  
  328.             i = strlen(file->name) - strlen(buf);
  329.             if (i >= 0) {
  330.                 if (!(strncmp(&file->name[i],buf,
  331.                         strlen(buf)))) {
  332.                     file->prog_type = suf;
  333.                     return(1);
  334.                 }
  335.             }
  336.         } while (b);
  337.         suf++;
  338.     }
  339.     return(0);
  340. }
  341.  
  342.  
  343.  
  344. /*********************************************************
  345.  * name:    ifFilter
  346.  * description:    Filenamefilteringfunction. Dient zum Bewerten
  347.  *        von Filenamenunter Beruecksichtigung des
  348.  *        Filterstrings im Folder_Glyph
  349.  * input:    Folger_Glyph    *folder    - der Folder
  350.  *        char        *file    - filename
  351.  * output:    Boolean    True, wenn file zum Filter passt,
  352.  *        sonst FALSE
  353.  * author:    Ove Kalkan
  354.  * date:    1.7.1993
  355.  *********************************************************/
  356. Boolean    ifFilter (Folder_Glyph *folder, char *file)
  357. {
  358.     int    i = strlen(folder->filter);
  359.  
  360.     if (!strcmp(folder->filter,"*") || !strlen(folder->filter) ||
  361.         !folder->filter) {
  362.         folder->filter = NULL;
  363.         return(TRUE);
  364.     }
  365.     if (!strcmp(file,".."))
  366.         return(TRUE);
  367.     if (folder->filter[0] == '*') {    /* Joker am Anfang */
  368.         if (folder->filter[i-1] == '*') {    /* Joker am Ende */
  369.             if (strlen(file) < i - 2)
  370.                 return(FALSE);
  371.         }
  372.         else {
  373.             if (strlen(file) < i - 1)
  374.                 return(FALSE);
  375.             if (strncmp(&file[strlen(file) - i + 1],&folder->filter[1],i-1))
  376.                 return(FALSE);
  377.         }
  378.     }
  379.     else {
  380.         if (folder->filter[i-1] == '*') {    /* Joker am Ende */
  381.             if (strlen(file) < i - 1)
  382.                 return(FALSE);
  383.             if (strncmp(file,folder->filter,i-1))
  384.                 return(FALSE);
  385.         }
  386.         else {    /* keine Joker */
  387.             if (strcmp(folder->filter,file))
  388.                 return(FALSE);
  389.         }
  390.     }
  391.     return(TRUE);
  392. }
  393.