home *** CD-ROM | disk | FTP | other *** search
- /*
- * Copyright 1993 by Ove Kalkan, Cremlingen, Germany
- *
- * Permission to use, copy, modify, distribute and sell this software and it's
- * documentation for any purpose is hereby granted without fee, rpovided that
- * the above copyright notice and this permission appear in supporting
- * documentation, and that the name of Ove Kalkan not to be used in
- * advertising or publicity pertaining to distributiopn of the software without
- * specific, written prior permission. Ove Kalkan makes no representations
- * about the suitability of this software for any purpose. It is provided
- * as is without express or implied warranty.
- *
- * OVE KALKAN DISPLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABLILITY AND FITNESS, IN NO
- * EVENT SHALL OVE KALKAN BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- *
- * $Header: filename,v 1.0 yyyy/mm/dd hh:mm:ss loginname Exp $
- */
-
- #include "global.h"
-
- /*
- * Global variables
- */
-
- /*
- ** Function name : fillDir
- **
- ** Description : Fuellen einer Dir-Struktur
- ** Input : zeiger auf den Dirglyph, dessem Unterdirectories untersucht werden sollen
- ** Ouput :
- */
- void fillDir (Dir_Glyph *dir)
- {
- String dir_path; /* Hier wird der vollstaendige Pfad des Directories
- stehen */
- DIR *dir_ptr; /* Zeiger auf die Dir-Structur */
- struct dirent *d_ent; /* Direntry */
- char s_buf[1024];
-
- /*
- * Wenn dem Dir-Glyph noch eine Dir-Liste zugeordnet ist, dann
- * diese loesche
- */
- if (dir->dir_count > 0) {
- int i;
-
- /* for (i = 0; i < dir->dir_count; i++)
- if (dir->dir[i]) {
- if (dir->dir[i]->name)
- free(dir->dir[i]->name);
- free(dir->dir[i]);
- }
- */ dir->dir_count = 0;
- }
-
- /*
- * Den vollstaendigen Pfadnamen holen
- */
- dir_path = getPath (dir);
-
- /*
- * Das Dir oeffnen und die Eintraege auslesen
- */
- if (!(dir->flags & DIR_READABLE) || !(dir_ptr = opendir (dir_path))) {
- dir->flags &= (~DIR_READABLE);
- return; /* Abbruch da nicht geoeffnet */
- }
-
- /*
- * Dir-Open flag setzen
- */
- dir->open = TRUE;
-
- /*
- * Directory auslesen
- */
- while ((d_ent = readdir(dir_ptr))) {
- struct stat buf;
-
- /*
- * Den vollen Pfadnamen des Direntries erzeugen
- */
- sprintf (s_buf,"%s%s%s\0", dir_path,
- (dir_path[1] == '\0' ? "" : "/"),
- d_ent->d_name);
-
- /*
- * Den Status des Files holen
- */
- (void) stat (s_buf, &buf);
-
- /*
- * Ueberpruefen ob der Eintrag ein Directory und nicht . oder .. ist
- */
- if (S_ISDIR(buf.st_mode) && strcmp(d_ent->d_name,".")
- && strcmp(d_ent->d_name,"..")) {
- /*
- * Da dir, Dir_Glyph um einen Eintrag erweitern
- */
- Dir_Glyph *new_dir;
-
- /*
- * Liste im Glyph um einen Eintrag erweitern
- */
- (dir->dir_count)++;
- if (!dir->dir) {
- if (!(dir->dir = (Dir_Glyph **) malloc (sizeof(Dir_Glyph *))))
- FATAL_ERROR ("fillDir: Reallocating Dirlist failed\n");
- }
- else {
- if (!(dir->dir = (Dir_Glyph **) realloc ((void *) dir->dir,
- sizeof(Dir_Glyph *)*dir->dir_count)))
- FATAL_ERROR ("fillDir: Reallocating Dirlist failed\n");
- }
- if (!(new_dir = (Dir_Glyph *) malloc(sizeof(Dir_Glyph))))
- FATAL_ERROR ("fillDir: Allocating new Glyph failed\n");
-
- /*
- * Den neuen Glyph als leer initialisieren
- */
- new_dir->dir_count = 0;
- new_dir->dir = NULL;
- new_dir->x = 0;
- new_dir->y = 0;
- new_dir->parent = dir;
- new_dir->open = FALSE;
- new_dir->link = NULL;
-
- /*
- * Den Namen des Glyphs initialisieren
- */
- if (!(new_dir->name = (String) malloc(strlen(d_ent->d_name)+1)))
- FATAL_ERROR ("fillDir: Allocating Name for new Glyph failed\n");
-
- strncpy(new_dir->name,d_ent->d_name,strlen(d_ent->d_name));
- new_dir->name[strlen(d_ent->d_name)] = '\0';
-
- /*
- * Den Status neuen Dirs bestimmen
- */
- new_dir->flags = getFlags(&buf);
-
- /*
- * Ueberpruefen ob Link
- */
- #ifndef COHERENT
- (void) lstat (s_buf, &buf);
- new_dir->flags |= (S_ISLNK(buf.st_mode) ? DIR_LINK : 0);
- if (new_dir->flags & DIR_LINK) {
- char buf[255];
- int j;
-
- if ((j = readlink(s_buf,buf,254)) > 0) {
- buf[j++] = '\0';
- new_dir->link = (char *) malloc(j);
- if (!(new_dir->link))
- FATAL_ERROR("dir.c: malloc failed.");
- sprintf(new_dir->link,"%s\0",buf);
- }
- }
- dir->dir[dir->dir_count-1] = new_dir;
- #endif
- }
- }
- closedir (dir_ptr);
- free (dir_path);
-
- /*
- * Die Directoryeintraege aplhabetisch sortieren falls moeglich
- */
- if (dir->dir_count > 1) {
- int i, j;
-
- for (i = 0; i < dir->dir_count - 1; i++) {
- for (j = 1; j < dir->dir_count - i; j++) {
- if (compareGlyph(dir->dir[j-1],dir->dir[j]) == 1) {
- Dir_Glyph *dummy = dir->dir[j];
-
- dir->dir[j] = dir->dir[j-1];
- dir->dir[j-1] = dummy;
- }
- }
- }
- }
- }
-
-
-
- /*
- ** Function name : compareGlyph
- **
- ** Description : Vergleichsfunktion fuer QSort
- ** Input : die zwei obligatorischen Zeiger auf die Elemente
- ** Ouput : -1 falls a < b, 0 fall a == b oder 1 fall a > b
- */
- int compareGlyph (Dir_Glyph *da, Dir_Glyph *db)
- {
- int i;
- char *a = da->name,
- *b = db->name;
-
- i = (strlen(a) > strlen(b) ? strlen(b) : strlen(a));
- while (i--) {
- if (*a > *b) {
- return(1);
- }
- else if (*a < *b) {
- return(-1);
- }
- a++;
- b++;
- }
- if (strlen(da->name) > strlen(db->name)) {
- return(1);
- }
- if (strlen(da->name) < strlen(db->name)) {
- return(-1);
- }
- return(0);
- }
-
-
-
- /*
- ** Function name : showDir
- **
- ** Description : Anzeigen eines Directorybaumes im Fenster
- ** Input : Zeiger auf das Fensterwidget und den Dir_glyph
- ** Ouput : Liefert den Y-Wert des letzen Dir-Glyphs im Baum zurueck
- */
- void showDir (Widget window, Dir_Glyph *dir,
- Dimension x, Dimension y,
- Dimension *lx, Dimension *ly,
- Dimension hs, Dimension he)
- {
- Dimension py;
- int i;
- Boolean b;
-
- /*
- * Position des Icons fuer das Dir_Glyph festlegen
- */
- dir->x = x;
- dir->y = y;
-
- /*
- * Icon ausgeben und Dirlabel zeichnen
- */
- if (y >= hs && y <= he) {
- b = (selc_g == dir ? TRUE : FALSE);
- drawDir (dir_area, dir, b, b);
- }
-
- if (dir->x + 24 + 8*strlen(dir->name) > *lx)
- *lx = dir->x + 24 + 8*(strlen(dir->name)+strlen(dir->link));
-
- /*
- * Alle Unterdirectories zeichnen fall Directory offen
- */
- *ly = py = y;
- if (dir->open && dir->dir_count > 0) {
- for (i = 0; i < dir->dir_count; i++) {
- /*
- * Die Pfadlinie ziehen
- */
- XDrawLine (XtDisplay(dir_area), XtWindow(dir_area),
- line_gc, x + 8, *ly + DIR_Y_STEP + 8,
- x + DIR_X_STEP - 10,
- *ly + DIR_Y_STEP + 8);
- showDir(window,dir->dir[i],x + DIR_X_STEP,
- *ly + DIR_Y_STEP, lx, ly, hs, he);
- }
- XDrawLine (XtDisplay(dir_area), XtWindow(dir_area),
- line_gc, x + 8, py + 19,
- x + 8, dir->dir[i-1]->y + 8);
- }
- }
-
-
-
-
- /*
- ** Function name : getPath
- **
- ** Description : Generieren des Vollstaendigen Pfadnamens aus einem Glyph - rekurziv
- ** Input : Zeiger auf den entsprechenden Dir_Glyph
- ** Ouput : Zeiger auf den String mit dem Pfadnamen
- */
- String getPath (Dir_Glyph *dir)
- {
- String back, /* Wird zurueck geliefert */
- got; /* kommt vom Parent */
-
- /*
- * Wenn Parentdir, dann Pfad davon holen
- */
- if (dir->parent)
- got = getPath(dir->parent);
- else
- got = "\0";
-
- /*
- * Stringlaenge fuer back besorgen
- */
- if (!(back = (String) malloc(strlen(got) + strlen(dir->name) + 2)))
- FATAL_ERROR("getPath: Cannot allocate Memory\n");
-
- /*
- * Die Teilstrings verknuepfen
- */
- if (!strcmp("/",got))
- sprintf(back,"/%s",dir->name);
-
- else if (*got != '\0')
- sprintf(back,"%s/%s\0",got,dir->name);
- else
- sprintf(back,"%s",dir->name);
-
- /*
- * Got wieder Freigeben falls nicht "\0"
- */
- if (*got != '\0')
- free(got);
-
- /*
- * Den vollstaendigen Pfad zurueckliefern
- */
- return(back);
- }
-
-
-
- /*
- * die File-Flags bestimmen
- */
- int getFlags (struct stat *buf)
- {
- uid_t uid = getuid();
- gid_t gid = getgid();
-
- int b = 0;
-
- if (uid == 0) /* Root darf alles */
- return (DIR_READABLE + DIR_WRITEABLE);
-
- /* Das scheint noch nicht ganz zu funktionieren, muss verbessert werden */
- b |= ((uid == buf->st_uid && S_IRUSR&buf->st_mode) |
- (gid == buf->st_gid && S_IRGRP&buf->st_mode) |
- S_IRGRP&buf->st_mode) ? DIR_READABLE : 0;
-
- b |= ((uid == buf->st_uid && S_IWUSR&buf->st_mode) |
- (gid == buf->st_gid && S_IWGRP&buf->st_mode) |
- S_IWGRP&buf->st_mode) ? DIR_WRITEABLE : 0;
- return (b);
- }