~ubuntu-branches/debian/sid/acfax/sid

« back to all changes in this revision

Viewing changes to DirMgr.c

  • Committer: Bazaar Package Importer
  • Author(s): Hamish Moffatt
  • Date: 2001-12-27 12:07:46 UTC
  • Revision ID: james.westby@ubuntu.com-20011227120746-iz2p5k757bcla8ov
Tags: upstream-981011
ImportĀ upstreamĀ versionĀ 981011

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/****************************************************************************
 
2
 
 
3
        DirMgr.c
 
4
 
 
5
        This file contains the C code to implement the DirectoryMgr system.
 
6
 
 
7
        This system is intended to manage filtered and sorted directory
 
8
        lists.
 
9
 
 
10
 ****************************************************************************/
 
11
 
 
12
/*
 
13
 * Author:
 
14
 *      Brian Totty
 
15
 *      Department of Computer Science
 
16
 *      University Of Illinois at Urbana-Champaign
 
17
 *      1304 West Springfield Avenue
 
18
 *      Urbana, IL 61801
 
19
 * 
 
20
 *      totty@cs.uiuc.edu
 
21
 *      
 
22
 */ 
 
23
 
 
24
#include "DirMgr.h"
 
25
 
 
26
#ifndef NO_REGEXP
 
27
#include "RegExp.h"
 
28
#endif
 
29
 
 
30
#define DIR_MGR_FSM_SIZE 1024
 
31
 
 
32
/*---------------------------------------------------------------------------*
 
33
 
 
34
                   S I M P L E    I N T E R F A C E
 
35
 
 
36
 *---------------------------------------------------------------------------*/
 
37
 
 
38
DirectoryMgr *DirectoryMgrSimpleOpen(path,sort_type,pattern)
 
39
char *path;
 
40
int sort_type;
 
41
char *pattern;
 
42
{
 
43
        DirectoryMgr *dm;
 
44
        PFI f_func,s_func;
 
45
        char *f_data;
 
46
 
 
47
        if (pattern == NULL) pattern = "*";
 
48
        if (!DirectoryMgrSimpleFilterFunc(pattern,&f_func,&f_data))
 
49
        {
 
50
                return(NULL);
 
51
        }
 
52
        if (!DirectoryMgrSimpleSortingFunc(sort_type,&s_func))
 
53
        {
 
54
                free(f_data);
 
55
                return(NULL);
 
56
        }
 
57
        dm = DirectoryMgrOpen(path,s_func,f_func,f_data,TRUE);
 
58
        return(dm);
 
59
} /* End DirectoryMgrSimpleOpen */
 
60
 
 
61
 
 
62
int DirectoryMgrSimpleRefilter(dm,pattern)
 
63
DirectoryMgr *dm;
 
64
char *pattern;
 
65
{
 
66
        PFI f_func;
 
67
        char *f_data;
 
68
 
 
69
        if (!DirectoryMgrSimpleFilterFunc(pattern,&f_func,&f_data))
 
70
        {
 
71
                return(FALSE);
 
72
        }
 
73
        DirectoryMgrRefilter(dm,f_func,f_data,TRUE);
 
74
        return(TRUE);
 
75
} /* End DirectoryMgrSimpleRefilter */
 
76
 
 
77
 
 
78
int DirectoryMgrSimpleResort(dm,sort_type)
 
79
DirectoryMgr *dm;
 
80
int sort_type;
 
81
{
 
82
        PFI c_func;
 
83
 
 
84
        if (!DirectoryMgrSimpleSortingFunc(sort_type,&c_func))
 
85
        {
 
86
                return(FALSE);
 
87
        }
 
88
        DirectoryMgrResort(dm,c_func);
 
89
        return(TRUE);
 
90
} /* End DirectoryMgrSimpleResort */
 
91
 
 
92
 
 
93
/*---------------------------------------------------------------------------*
 
94
 
 
95
                    N O R M A L    I N T E R F A C E
 
96
 
 
97
 *---------------------------------------------------------------------------*/
 
98
 
 
99
int DirectoryMgrCanOpen(path)
 
100
char *path;
 
101
{
 
102
        int status;
 
103
        Directory dir;
 
104
 
 
105
        status = DirectoryOpen(path,&dir);
 
106
        if (status == TRUE) DirectoryClose(&dir);
 
107
        return(status);
 
108
} /* End DirectoryMgrCanOpen */
 
109
 
 
110
 
 
111
DirectoryMgr *DirectoryMgrOpen(path,c_func,f_func,f_data,free_data)
 
112
char *path;
 
113
PFI c_func,f_func;
 
114
char *f_data;
 
115
int free_data;
 
116
{
 
117
        DirectoryMgr *dm;
 
118
 
 
119
        dm = (DirectoryMgr *)calloc(1,sizeof(DirectoryMgr));
 
120
        if (dm == NULL)
 
121
        {
 
122
                fprintf(stderr,"DirectoryMgrOpen: out of memory\n");
 
123
                if (free_data && f_data) free(f_data);
 
124
                return(NULL);
 
125
        }
 
126
        if (DirectoryOpen(path,DirectoryMgrDir(dm)) == FALSE)
 
127
        {
 
128
                fprintf(stderr,"DirectoryMgrOpen: can't open dir '%s'\n",
 
129
                        DirectoryMgrDir(dm));
 
130
                free(dm);
 
131
                if (free_data && f_data) free(f_data);
 
132
                return(NULL);
 
133
        }
 
134
        DirectoryMgrCompFunc(dm) = c_func;
 
135
        DirectoryMgrRefilter(dm,f_func,f_data,free_data);
 
136
        return(dm);
 
137
} /* End DirectoryMgrOpen */
 
138
 
 
139
 
 
140
void DirectoryMgrClose(dm)
 
141
DirectoryMgr *dm;
 
142
{
 
143
        free(DirectoryMgrData(dm));
 
144
        free(DirectoryMgrSortedPtrs(dm));
 
145
        if (DirectoryMgrFilterData(dm) && DirectoryMgrFreeFilterData(dm))
 
146
        {
 
147
                free(DirectoryMgrFilterData(dm));
 
148
        }
 
149
        DirectoryClose(DirectoryMgrDir(dm));
 
150
        free(dm);
 
151
} /* End DirectoryMgrClose */
 
152
 
 
153
 
 
154
int DirectoryMgrRefilter(dm,f_func,f_data,f_free)
 
155
DirectoryMgr *dm;
 
156
PFI f_func;
 
157
char *f_data;
 
158
int f_free;
 
159
{
 
160
        if (DirectoryMgrFilterData(dm) && DirectoryMgrFreeFilterData(dm))
 
161
        {
 
162
                free(DirectoryMgrFilterData(dm));
 
163
        }
 
164
        DirectoryMgrFilterFunc(dm) = f_func;
 
165
        DirectoryMgrFilterData(dm) = f_data;
 
166
        DirectoryMgrFreeFilterData(dm) = f_free;
 
167
        DirectoryMgrRefresh(dm);
 
168
} /* End DirectoryMgrRefilter */
 
169
 
 
170
 
 
171
int DirectoryMgrRefresh(dm)
 
172
DirectoryMgr *dm;
 
173
{
 
174
        int err,data_size,ptrs_size,i;
 
175
        DirEntryCons *head,*tail,*cons;
 
176
        DirEntry *dm_data,**dm_ptrs;
 
177
        PFI f_func;
 
178
        char *f_data;
 
179
 
 
180
        DirectoryMgrTotalCount(dm) = 0;
 
181
        DirectoryMgrFilteredCount(dm) = 0;
 
182
        DirectoryRestart(DirectoryMgrDir(dm));
 
183
        if (DirectoryMgrData(dm)) free(DirectoryMgrData(dm));
 
184
        if (DirectoryMgrSortedPtrs(dm)) free(DirectoryMgrSortedPtrs(dm));
 
185
        head = NULL;
 
186
        f_func = DirectoryMgrFilterFunc(dm);
 
187
        f_data = DirectoryMgrFilterData(dm);
 
188
        while (1)
 
189
        {
 
190
                cons = (DirEntryCons *)malloc(sizeof(DirEntryCons));
 
191
                if (cons == NULL)
 
192
                {
 
193
                        fprintf(stderr,
 
194
                                "DirectoryMgrRefresh: Can't Alloc Cons\n");
 
195
                        exit(-1);
 
196
                }
 
197
                err = DirectoryReadNextEntry(DirectoryMgrDir(dm),
 
198
                                             &(cons->dir_entry));
 
199
                if (err == FALSE)
 
200
                {
 
201
                        free(cons);
 
202
                        break;
 
203
                }
 
204
                ++ DirectoryMgrTotalCount(dm);
 
205
                if ((f_func == NULL) ||
 
206
                    (f_func && f_func(&(cons->dir_entry),f_data)))
 
207
                {
 
208
                        cons->next = NULL;
 
209
                        if (head == NULL)
 
210
                                head = cons;
 
211
                            else
 
212
                                tail->next = cons;
 
213
                        tail = cons;
 
214
                        ++ DirectoryMgrFilteredCount(dm);
 
215
                }
 
216
                    else                        /* Filter Failed */
 
217
                {
 
218
                        free(cons);
 
219
                }
 
220
        }
 
221
 
 
222
        data_size = sizeof(DirEntry) * DirectoryMgrFilteredCount(dm);
 
223
        ptrs_size = sizeof(DirEntry *) * DirectoryMgrFilteredCount(dm);
 
224
        /* changed next 2 lines due to malloc(0) returning NULL - ACZ */
 
225
        if (data_size) dm_data = (DirEntry *)malloc(data_size);
 
226
        if (ptrs_size) dm_ptrs = (DirEntry **)malloc(ptrs_size);
 
227
        if ((dm_data == NULL) || (dm_ptrs == NULL))
 
228
        {
 
229
                fprintf(stderr,"DirectoryMgrRefresh: Out of memory\n");
 
230
                exit(1);
 
231
        }
 
232
        DirectoryMgrData(dm) = dm_data;
 
233
        DirectoryMgrSortedPtrs(dm) = dm_ptrs;
 
234
 
 
235
        for (i = 0; i < DirectoryMgrFilteredCount(dm); i++)
 
236
        {
 
237
                DirectoryMgrData(dm)[i] = head->dir_entry;
 
238
                DirectoryMgrSortedPtrs(dm)[i] = &(DirectoryMgrData(dm)[i]);
 
239
                cons = head->next;
 
240
                free(head);
 
241
                head = cons;
 
242
        }
 
243
 
 
244
        DirectoryMgrResort(dm,DirectoryMgrCompFunc(dm));
 
245
        DirectoryMgrRestart(dm);
 
246
        return(TRUE);
 
247
} /* End DirectoryMgrRefresh */
 
248
 
 
249
 
 
250
void DirectoryMgrResort(dm,c_func)
 
251
DirectoryMgr *dm;
 
252
PFI c_func;
 
253
{
 
254
        DirectoryMgrCompFunc(dm) = c_func;
 
255
        if (c_func != NULL)
 
256
        {
 
257
                qsort(DirectoryMgrSortedPtrs(dm),DirectoryMgrFilteredCount(dm),
 
258
                      sizeof(DirEntry *),DirectoryMgrCompFunc(dm));
 
259
        }
 
260
        DirectoryMgrRestart(dm);
 
261
} /* End DirectoryMgrResort */
 
262
 
 
263
/*---------------------------------------------------------------------------*
 
264
 
 
265
                  I T E R A T I O N    C O M M A N D S
 
266
 
 
267
 *---------------------------------------------------------------------------*/
 
268
 
 
269
int DirectoryMgrGotoItem(dm,i)
 
270
DirectoryMgr *dm;
 
271
int i;
 
272
{
 
273
        if (i < 0 || i >= DirectoryMgrFilteredCount(dm)) return(FALSE);
 
274
        DirectoryMgrCurrentIndex(dm) = i;
 
275
        return(TRUE);
 
276
} /* End DirectoryMgrGotoItem */
 
277
 
 
278
 
 
279
int DirectoryMgrGotoNamedItem(dm,name)
 
280
DirectoryMgr *dm;
 
281
char *name;
 
282
{
 
283
        int i;
 
284
        DirEntry *entry;
 
285
 
 
286
        for (i = 0; i < DirectoryMgrFilteredCount(dm); i++)
 
287
        {
 
288
                entry = DirectoryMgrSortedPtrs(dm)[i];
 
289
                if (strcmp(DirEntryFileName(entry),name) == 0)
 
290
                {
 
291
                        DirectoryMgrCurrentIndex(dm) = i;
 
292
                        return(TRUE);
 
293
                }
 
294
        }
 
295
        return(FALSE);
 
296
} /* End DirectoryMgrGotoNamedItem */
 
297
 
 
298
 
 
299
void DirectoryMgrRestart(dm)
 
300
DirectoryMgr *dm;
 
301
{
 
302
        DirectoryMgrCurrentIndex(dm) = 0;
 
303
} /* End DirectoryMgrRestart */
 
304
 
 
305
 
 
306
DirEntry *DirectoryMgrCurrentEntry(dm)
 
307
DirectoryMgr *dm;
 
308
{
 
309
        int index;
 
310
 
 
311
        index = DirectoryMgrCurrentIndex(dm);
 
312
        if (index < 0 || index >= DirectoryMgrFilteredCount(dm)) return(NULL);
 
313
        return(DirectoryMgrSortedPtrs(dm)[index]);
 
314
} /* End DirectoryMgrCurrentEntry */
 
315
 
 
316
 
 
317
DirEntry *DirectoryMgrNextEntry(dm)
 
318
DirectoryMgr *dm;
 
319
{
 
320
        int index;
 
321
 
 
322
        index = DirectoryMgrCurrentIndex(dm);
 
323
        if (index >= DirectoryMgrFilteredCount(dm)) return(NULL);
 
324
        ++ DirectoryMgrCurrentIndex(dm);
 
325
        return(DirectoryMgrSortedPtrs(dm)[index]);
 
326
} /* End DirectoryMgrNextEntry */
 
327
 
 
328
 
 
329
DirEntry *DirectoryMgrPrevEntry(dm)
 
330
DirectoryMgr *dm;
 
331
{
 
332
        int index;
 
333
 
 
334
        index = DirectoryMgrCurrentIndex(dm) - 1;
 
335
        if (index < 0) return(NULL);
 
336
        -- DirectoryMgrCurrentIndex(dm);
 
337
        return(DirectoryMgrSortedPtrs(dm)[index]);
 
338
} /* End DirectoryMgrPrevEntry */
 
339
 
 
340
/*---------------------------------------------------------------------------*
 
341
 
 
342
                   U T I L I T Y    F U N C T I O N S
 
343
 
 
344
 *---------------------------------------------------------------------------*/
 
345
 
 
346
int DirectoryMgrSimpleFilterFunc(pattern,ff_ptr,fd_ptr)
 
347
char *pattern;
 
348
PFI *ff_ptr;
 
349
char **fd_ptr;
 
350
{
 
351
#ifndef NO_REGEXP
 
352
        char regexp[2048];
 
353
 
 
354
        *ff_ptr = DirectoryMgrFilterName;
 
355
        *fd_ptr = (char *)malloc(sizeof(regex_t));
 
356
        if (*fd_ptr == NULL) return(FALSE);
 
357
        RegExpPatternToRegExp(pattern,regexp);
 
358
        re_set_syntax(RE_SYNTAX_EGREP);
 
359
        strcat(regexp,"|^\\.+$"); /* ALWAYS! match . and .. - ACZ */
 
360
        RegExpCompile(regexp,(regex_t *)*fd_ptr);
 
361
#endif
 
362
        return(TRUE);
 
363
} /* End DirectoryMgrSimpleFilterFunc */
 
364
 
 
365
 
 
366
int DirectoryMgrSimpleSortingFunc(sort_type,sf_ptr)
 
367
int sort_type;
 
368
PFI *sf_ptr;
 
369
{
 
370
        *sf_ptr = NULL;
 
371
        switch (sort_type)
 
372
        {
 
373
            case DIR_MGR_SORT_NONE:
 
374
                break;
 
375
            case DIR_MGR_SORT_NAME:
 
376
                *sf_ptr = DirectoryMgrCompareName;
 
377
                break;
 
378
            case DIR_MGR_SORT_SIZE_ASCENDING:
 
379
                *sf_ptr = DirectoryMgrCompareSizeAscending;
 
380
                break;
 
381
            case DIR_MGR_SORT_SIZE_DESCENDING:
 
382
                *sf_ptr = DirectoryMgrCompareSizeDescending;
 
383
                break;
 
384
            case DIR_MGR_SORT_NAME_DIRS_FIRST:
 
385
                *sf_ptr = DirectoryMgrCompareNameDirsFirst;
 
386
                break;
 
387
            case DIR_MGR_SORT_ACCESS_ASCENDING:
 
388
                *sf_ptr = DirectoryMgrCompareLastAccessAscending;
 
389
                break;
 
390
            case DIR_MGR_SORT_ACCESS_DESCENDING:
 
391
                *sf_ptr = DirectoryMgrCompareLastAccessDescending;
 
392
                break;
 
393
            default:
 
394
                fprintf(stderr,"Bad sort type %d\n",sort_type);
 
395
                return(FALSE);
 
396
        }
 
397
        return(TRUE);
 
398
} /* End DirectoryMgrSimpleSortingFunc */
 
399
 
 
400
/*---------------------------------------------------------------------------*
 
401
 
 
402
                    S O R T I N G    R O U T I N E S
 
403
 
 
404
 *---------------------------------------------------------------------------*/
 
405
 
 
406
int DirectoryMgrCompareName(e1p,e2p)
 
407
DirEntry **e1p,**e2p;
 
408
{
 
409
        return(strcmp(DirEntryFileName(*e1p),DirEntryFileName(*e2p)));
 
410
} /* End DirectoryMgrCompareName */
 
411
 
 
412
 
 
413
int DirectoryMgrCompareNameDirsFirst(e1p,e2p)
 
414
DirEntry **e1p,**e2p;
 
415
{
 
416
        if (DirEntryLeadsToDir(*e1p))
 
417
        {
 
418
                if (!DirEntryLeadsToDir(*e2p)) return(-1);
 
419
        }
 
420
            else if (DirEntryLeadsToDir(*e2p))
 
421
        {
 
422
                return(1);
 
423
        }
 
424
        return(strcmp(DirEntryFileName(*e1p),DirEntryFileName(*e2p)));
 
425
} /* End DirectoryMgrCompareNameDirsFirst */
 
426
 
 
427
 
 
428
int DirectoryMgrCompareSizeAscending(e1p,e2p)
 
429
DirEntry **e1p,**e2p;
 
430
{
 
431
        if (DirEntryFileSize(*e1p) < DirEntryFileSize(*e2p))
 
432
                return (-1);
 
433
            else if (DirEntryFileSize(*e1p) == DirEntryFileSize(*e2p))
 
434
                return (0);
 
435
            else
 
436
                return (1);
 
437
} /* End DirectoryMgrCompareSizeAscending */
 
438
 
 
439
 
 
440
int DirectoryMgrCompareSizeDescending(e1p,e2p)
 
441
DirEntry **e1p,**e2p;
 
442
{
 
443
        if (DirEntryFileSize(*e1p) > DirEntryFileSize(*e2p))
 
444
                return (-1);
 
445
            else if (DirEntryFileSize(*e1p) == DirEntryFileSize(*e2p))
 
446
                return (0);
 
447
            else
 
448
                return (1);
 
449
} /* End DirectoryMgrCompareSizeDescending */
 
450
 
 
451
 
 
452
int DirectoryMgrCompareLastAccessAscending(e1p,e2p)
 
453
DirEntry **e1p,**e2p;
 
454
{
 
455
        return((long)DirEntryLastAccess(*e1p) >
 
456
               (long)DirEntryLastAccess(*e2p));
 
457
} /* End DirectoryMgrCompareLastAccessAscending */
 
458
 
 
459
 
 
460
int DirectoryMgrCompareLastAccessDescending(e1p,e2p)
 
461
DirEntry **e1p,**e2p;
 
462
{
 
463
        return((long)DirEntryLastAccess(*e1p) <
 
464
               (long)DirEntryLastAccess(*e2p));
 
465
} /* End DirectoryMgrCompareLastAccessDescending */
 
466
 
 
467
/*---------------------------------------------------------------------------*
 
468
 
 
469
                     F I L T E R    R O U T I N E S
 
470
 
 
471
 *---------------------------------------------------------------------------*/
 
472
 
 
473
int DirectoryMgrFilterName(de,fsm)
 
474
DirEntry *de;
 
475
regex_t *fsm;
 
476
{
 
477
#ifndef NO_REGEXP
 
478
        return(RegExpMatch(DirEntryFileName(de),fsm));
 
479
#else
 
480
        return(TRUE);
 
481
#endif
 
482
} /* End DirectoryMgrFilterName */