2
* Copyright (C) 2001 by Holger Rapp
4
* This program is free software; you can redistribute it and/or
5
* modify it under the terms of the GNU General Public License
6
* as published by the Free Software Foundation; either version 2
7
* of the License, or (at your option) any later version.
9
* This program is distributed in the hope that it will be useful,
10
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
* GNU General Public License for more details.
14
* You should have received a copy of the GNU General Public License
15
* along with this program; if not, write to the Free Software
16
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21
#include <sys/types.h>
25
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
27
/** class File_Locator
29
* searches for files in various searchdirs and subdirs.
30
* Reports filenames when files are found.
32
* Is also able to list files in a convenient way
35
/** File_Locator::File_Locator(void)
37
* Some inits. Nothing special
42
File_Locator::File_Locator(void) {
45
for(unsigned int i=0; i<MAX_DIRS; i++) dirs[i][0]='\0';
46
for(unsigned int i=0; i<MAX_SUBDIRS; i++) subdirs[i][0]='\0';
56
/** File_Locator::~File_Locator(void)
63
File_Locator::~File_Locator(void) {
66
/** void File_Locator::add_searchdir(const char* dir, const unsigned int prio)
68
* This adds a dir to the directorys to search. the priority
69
* is where to add the dir (so MAX_DIRS-1 is lowest, 0 is highest)
71
* Args: dir Directory to add
72
* prio Priority of the dir
75
void File_Locator::add_searchdir(const char* dir, const unsigned int prio) {
82
if(stat(dir, &st) == -1) {
87
if(!S_ISDIR(st.st_mode)) {
91
strcpy(dirs[prio], dir);
92
if(dirs[prio][strlen(dirs[prio])-1]!=CSEP) {
93
int len=strlen(dirs[prio]);
95
dirs[prio][len+1]='\0';
100
/* File_Locator::Last_action File_Locator::get_state(void) const
102
* This functions returns the error code of the last action
105
* Returns: Success information on last action
107
File_Locator::Last_action File_Locator::get_state(void) const {
111
/** void File_Locator::register_subdir(const int id, const char* subd)
113
* This function registers a subdir with a certain type of
114
* file type (for ex: #define TYPE_TEXT 0 ; register_subdir(TYPE_TEXT, "txts"))
116
* Args: id id to identify with
117
* subd subdir to identify with
121
void File_Locator::register_subdir(const unsigned int id, const char* subd) {
122
if(id>= MAX_SUBDIRS) {
127
strcpy(subdirs[id], subd);
128
if(subdirs[id][strlen(subdirs[id])-1]!=CSEP) {
129
int len=strlen(subdirs[id]);
130
subdirs[id][len]=CSEP;
131
subdirs[id][len+1]='\0';
136
/** void File_Locator::locate_file(const char* file, const int type=-1)
138
* This file locates a file in the registered dirs
140
* Args: file filename to find
141
* type subdir id to use/ if -1 == don't use subdirs
143
* Returns: a pathname to the first valid file found
145
const char* File_Locator::locate_file(const char* file, const int type = -1) {
146
if(type >= (int) MAX_SUBDIRS) {
155
for(unsigned int n=0; n<MAX_DIRS; n++) {
156
if(dirs[n][0]=='\0') continue;
158
strcpy(retval, dirs[n]);
159
if(type != -1) strcat(retval, subdirs[type]);
160
strcat(retval, file);
163
if(stat(retval, &st) == -1) {
164
// Not Found. Next one
181
/* const char* File_Locator::get_new_filename(const char* file, const int type=-1)
183
* This functions returns a valid filename in the default write dir
185
* Args: file Filename to create
186
* type file type to create
187
* Returns: Path to complete filename
189
const char* File_Locator::get_new_filename(const char* file, const int type=-1) {
190
if(type >= (int) MAX_SUBDIRS) {
197
for(unsigned int n=def_writedir; n<MAX_DIRS; n++) {
198
if(dirs[n][0]=='\0') continue;
200
strcpy(retval, dirs[n]);
201
if(type != -1) strcat(retval, subdirs[type]);
202
strcat(retval, file);
216
/* void File_Locator::set_def_writedir(const int id)
218
* This functions sets the default write dir by the priority of
219
* the registered searchdirs.
221
* Args: id Directory of this priority should be used as default write dir
224
void File_Locator::set_def_writedir(const unsigned int id) {
225
if(id >= (int) MAX_DIRS) {
230
if(dirs[id][0] == '\0') {
239
/* void File_Locator::init_filelisting( const int type, const unsigned char postfix[5] );
241
* This functions inits the filelisting. it registeres the prefix and opens the first dir
243
* Args: type Which kinds of file to list
244
* postfix With what should the files end
247
void File_Locator::init_filelisting( const int type, const char postfix[5] ) {
248
if(type >= (int) MAX_SUBDIRS) {
258
if(ncurdir<(int) MAX_DIRS)
263
if(postfix[0]!='\0') {
264
strncpy(suf, postfix, 5);
274
/** void File_Locator::open_next_dir(void)
278
* this functions trys to open the next valid dir
283
void File_Locator::open_next_dir(void) {
284
if(ncurdir<0) return;
286
if(curdir) closedir(curdir);
291
for(; ncurdir<(int)MAX_DIRS; ncurdir++) {
292
if(dirs[ncurdir][0]=='\0') continue;
294
strcpy(retval, dirs[ncurdir]);
295
if(nlisttype != -1) strcat(retval, subdirs[nlisttype]);
302
// Try to open the dir
303
curdir=opendir(retval);
305
if(!curdir && ncurdir<(int)MAX_DIRS) {
306
// dir is invalid, but there are others. try them
311
ndirstrlen=strlen(retval);
315
/** void File_Locator::end_filelisting(void)
317
* This ends the file listing process, does cleanup
322
void File_Locator::end_filelisting(void) {
323
if(curdir) closedir(curdir);
331
/** const char* File_Locator::get_next_file(void);
333
* This functions returns the next file in the file listing
337
* Returns: The next file
339
const char* File_Locator::get_next_file(void) {
340
if(la==LA_NOMOREFILES) return NULL;
350
// reset the retval to just contain the dir
351
retval[ndirstrlen]='\0';
353
file=readdir(curdir);
358
// last file to list is done
359
// return NULL, set la accordingly
363
return get_next_file();
366
// strcat the file and return it
367
strcat(retval, file->d_name);
369
// Make sure the prefix is valid
370
if(suf[0]!='\0' && strlen(retval)>strlen(suf)) {
372
for(n=strlen(suf)-1; n>0; --n) {
373
if(suf[strlen(suf)-n]!=retval[strlen(retval)-n]) break;
375
if(n) return get_next_file();