1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255
|
/*
*****************************************************************************
** FILE: misc.c
**
** xbmbrowser is Public Domain. However it, and all the code still belong to me.
** I do, however grant permission for you to freely copy and distribute it on
** the condition that this and all other copyright notices remain unchanged in
** all distributions.
**
** This software comes with NO warranty whatsoever. I therefore take no
** responsibility for any damages, losses or problems that the program may
** cause.
** Anthony Thyssen and Ashley Roll
*****************************************************************************
*/
#include <sys/types.h> /* for missing types in stat.h */
#include <sys/stat.h>
#include "xbmbrowser.h"
/* Marco for brain dead Ultrix and SVR4 machines
** Brian Dowling <bdowling@ccs.neu.edu> -- Ultrix
** John Polstra <jdp@polstra.com> -- SVR4
*/
#ifndef S_ISLNK
# ifdef S_IFLNK
# if defined(_S_IFMT) /* Ultrix */
# define S_ISLNK(mode) (((mode) & _S_IFMT) == S_IFLNK)
# elif defined(S_IFMT) /* SVR4 */
# define S_ISLNK(mode) (((mode) & S_IFMT) == S_IFLNK)
# endif
# else /* no S_IFLNK then system probably has no symlinks */
# define S_ISLNK(mode) (0)
# endif
#endif
/*========================================================================*/
/* Cursour Control for Application */
void
set_busywait()
/* change the cursour to a busy symbol */
{
XtVaSetValues(mainpw, XtNcursor, (XtArgVal)waitCursor, NULL);
XFlush(display);
}
void
clear_busywait()
/* clear the busywait cursour back to normal */
{
XtVaSetValues(mainpw, XtNcursor, (XtArgVal)normalCursor, NULL);
XFlush(display);
}
/*========================================================================*/
/* Control over the stipple of the icon box display */
static Pixmap stipple = (Pixmap)None;
void
set_stipple()
/* set/reset the stipple pattern on the iconbox */
{
XtVaSetValues(iconbox,
XtNbackgroundPixmap,
(XtArgVal)(app_data.solid_bgnd ? XtUnspecifiedPixmap
: stipple ), NULL );
}
void
init_stipple()
/* initialize the ability to and and remove the stipple in iconbox */
{
Pixel foreground;
/* find and set the stipple background pattern */
XtVaGetValues(iconbox, XtNborderColor, &foreground, NULL);
stipple = XmuCreateStippledPixmap(
XtScreen(iconbox), foreground, app_data.stipple_bg, depth);
XtVaSetValues(iconbox,
XtNbackground, app_data.solid_bg,
XtNbackgroundPixmap,
(XtArgVal)(app_data.solid_bgnd ? XtUnspecifiedPixmap
: stipple ), NULL );
}
/*========================================================================*/
/* sort a linked list of the files just read in */
static Item *r; /* remainer of the list (find the second half to merge) */
static Item *
merge(a,b)
Item *a, *b;
{
Item aux, *temp = &aux;
while(b != NULL)
if(a == NULL) {
a = b;
break;
} else
if( strcmp( b->fname, a->fname ) > 0) {
temp = temp->next = a;
a = a->next;
} else {
temp = temp->next = b;
b = b->next;
}
temp->next = a;
return(aux.next);
}
static Item *
sort(n)
int n;
{
Item *fi,*la, *temp;
if(r == NULL) return(NULL);
else if(n > 1)
return(merge(sort(n/2),sort((n+1)/2)));
else {
fi = r;
la = r;
/* build list as long as possible */
for(r = r->next; r != NULL;)
if(strcmp(r->fname,la->fname) >= 0) {
la->next = r;
la = r;
r = r->next;
}
else if(strcmp(r->fname,fi->fname) <= 0) {
temp = r;
r = r->next;
temp->next = fi;
fi = temp;
}
else break;
la->next = NULL;
return(fi);
}
}
/*------------------------------------------------------------------------*/
/* global variables to ease building of linked list */
static Item **last_link;
static int count;
static Boolean
read_dir(dir)
/* scan the directory given appending any files found to the list given.
** Recursively decend into subdirectories as required.
** Assumes that directory names end in `/'.
*/
char *dir; /* the directory to scan */
{
DIR *dirp; /* directory file pointer */
struct dirent *dp; /* current directory item */
struct stat info; /* file stat info for current item */
Item *item; /* the file items infomation (output) */
Boolean subdir; /* are we in a sub directory? */
subdir = strcmp(dir, "./") != 0;
if( (dirp = opendir(dir)) == NULL )
return FALSE; /* this (sub)directory is unaccessable -- Bad! */
while( (dp = readdir(dirp)) != NULL ) {
if( strcmp(dp->d_name, ".") == 0 || strcmp(dp->d_name, "..") == 0 )
continue; /* skip directory links */
item = (Item *)alloc_item();
*last_link = item;
last_link = &(item->next);
count++;
if( subdir )
strncpy(item->fname, dir, MAXNAMLEN);
strncat(item->fname, dp->d_name, MAXNAMLEN);
stat(item->fname, &info); /* discover information about this file */
if( S_ISREG(info.st_mode) ) { /* IF Plain File */
item->type = File; /* normal file (to study further) */
item->mtime = info.st_mtime; /* save its last modification time */
}
else
if( S_ISDIR(info.st_mode) ) { /* IF directory -- check if sym-link */
lstat(item->fname, &info);
item->type = ( S_ISLNK(info.st_mode) ? DirLink : Dir );
strncat(item->fname, "/", MAXNAMLEN); /* append `/' to dir name */
if( app_data.recursive ) /* do recursion if needed */
if( ! read_dir( item->fname ) )
item->type = DirBad;
} else
item->type = Unknown; /* Unknown or Special file type */
}
closedir(dirp);
return TRUE; /* success -- Good sub-directory */
}
/*------------------------------------------------------------------------*/
/*------------------------ Public Functions ------------------------------*/
Item *
get_files()
/* return a linked link of all directory items found in the current
** directory (recursively?). The list is sorted and the first item
** in the list is the parent directory link.
*/
{
Item *item; /* pointer to the first item */
item = (Item *)alloc_item(); /* always alloc at least one item */
last_link = &(item->next); /* initialize the lask link pointer */
count = 0; /* and no other itams are in the list */
strcpy(item->fname, "../"); /* this item is the parent link */
/* do the actual reading of the current directory
** set the first items type in the process.
*/
item->type = (read_dir("./") ? DirUp : DirBad);
r = item->next; /* don't include first item in the sort */
item->next = sort(count);
return item;
}
time_t
check_file_time(file)
/* just return the current modification time for this file
** or 0 if deleted or not a file. This is just a quick check
** routine for the rescan_file() function in "images.c"
*/
char *file;
{
struct stat info; /* file stat info for current item */
if( stat(file, &info) == 0 && S_ISREG(info.st_mode) ) {
return info.st_mtime;
}
return 0;
}
|