1
/****************************************************************************
5
This file contains the C code to implement the DirectoryMgr system.
7
This system is intended to manage filtered and sorted directory
10
****************************************************************************/
15
* Department of Computer Science
16
* University Of Illinois at Urbana-Champaign
17
* 1304 West Springfield Avenue
30
#define DIR_MGR_FSM_SIZE 1024
32
/*---------------------------------------------------------------------------*
34
S I M P L E I N T E R F A C E
36
*---------------------------------------------------------------------------*/
38
DirectoryMgr *DirectoryMgrSimpleOpen(path,sort_type,pattern)
47
if (pattern == NULL) pattern = "*";
48
if (!DirectoryMgrSimpleFilterFunc(pattern,&f_func,&f_data))
52
if (!DirectoryMgrSimpleSortingFunc(sort_type,&s_func))
57
dm = DirectoryMgrOpen(path,s_func,f_func,f_data,TRUE);
59
} /* End DirectoryMgrSimpleOpen */
62
int DirectoryMgrSimpleRefilter(dm,pattern)
69
if (!DirectoryMgrSimpleFilterFunc(pattern,&f_func,&f_data))
73
DirectoryMgrRefilter(dm,f_func,f_data,TRUE);
75
} /* End DirectoryMgrSimpleRefilter */
78
int DirectoryMgrSimpleResort(dm,sort_type)
84
if (!DirectoryMgrSimpleSortingFunc(sort_type,&c_func))
88
DirectoryMgrResort(dm,c_func);
90
} /* End DirectoryMgrSimpleResort */
93
/*---------------------------------------------------------------------------*
95
N O R M A L I N T E R F A C E
97
*---------------------------------------------------------------------------*/
99
int DirectoryMgrCanOpen(path)
105
status = DirectoryOpen(path,&dir);
106
if (status == TRUE) DirectoryClose(&dir);
108
} /* End DirectoryMgrCanOpen */
111
DirectoryMgr *DirectoryMgrOpen(path,c_func,f_func,f_data,free_data)
119
dm = (DirectoryMgr *)calloc(1,sizeof(DirectoryMgr));
122
fprintf(stderr,"DirectoryMgrOpen: out of memory\n");
123
if (free_data && f_data) free(f_data);
126
if (DirectoryOpen(path,DirectoryMgrDir(dm)) == FALSE)
128
fprintf(stderr,"DirectoryMgrOpen: can't open dir '%s'\n",
129
DirectoryMgrDir(dm));
131
if (free_data && f_data) free(f_data);
134
DirectoryMgrCompFunc(dm) = c_func;
135
DirectoryMgrRefilter(dm,f_func,f_data,free_data);
137
} /* End DirectoryMgrOpen */
140
void DirectoryMgrClose(dm)
143
free(DirectoryMgrData(dm));
144
free(DirectoryMgrSortedPtrs(dm));
145
if (DirectoryMgrFilterData(dm) && DirectoryMgrFreeFilterData(dm))
147
free(DirectoryMgrFilterData(dm));
149
DirectoryClose(DirectoryMgrDir(dm));
151
} /* End DirectoryMgrClose */
154
int DirectoryMgrRefilter(dm,f_func,f_data,f_free)
160
if (DirectoryMgrFilterData(dm) && DirectoryMgrFreeFilterData(dm))
162
free(DirectoryMgrFilterData(dm));
164
DirectoryMgrFilterFunc(dm) = f_func;
165
DirectoryMgrFilterData(dm) = f_data;
166
DirectoryMgrFreeFilterData(dm) = f_free;
167
DirectoryMgrRefresh(dm);
168
} /* End DirectoryMgrRefilter */
171
int DirectoryMgrRefresh(dm)
174
int err,data_size,ptrs_size,i;
175
DirEntryCons *head,*tail,*cons;
176
DirEntry *dm_data,**dm_ptrs;
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));
186
f_func = DirectoryMgrFilterFunc(dm);
187
f_data = DirectoryMgrFilterData(dm);
190
cons = (DirEntryCons *)malloc(sizeof(DirEntryCons));
194
"DirectoryMgrRefresh: Can't Alloc Cons\n");
197
err = DirectoryReadNextEntry(DirectoryMgrDir(dm),
204
++ DirectoryMgrTotalCount(dm);
205
if ((f_func == NULL) ||
206
(f_func && f_func(&(cons->dir_entry),f_data)))
214
++ DirectoryMgrFilteredCount(dm);
216
else /* Filter Failed */
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))
229
fprintf(stderr,"DirectoryMgrRefresh: Out of memory\n");
232
DirectoryMgrData(dm) = dm_data;
233
DirectoryMgrSortedPtrs(dm) = dm_ptrs;
235
for (i = 0; i < DirectoryMgrFilteredCount(dm); i++)
237
DirectoryMgrData(dm)[i] = head->dir_entry;
238
DirectoryMgrSortedPtrs(dm)[i] = &(DirectoryMgrData(dm)[i]);
244
DirectoryMgrResort(dm,DirectoryMgrCompFunc(dm));
245
DirectoryMgrRestart(dm);
247
} /* End DirectoryMgrRefresh */
250
void DirectoryMgrResort(dm,c_func)
254
DirectoryMgrCompFunc(dm) = c_func;
257
qsort(DirectoryMgrSortedPtrs(dm),DirectoryMgrFilteredCount(dm),
258
sizeof(DirEntry *),DirectoryMgrCompFunc(dm));
260
DirectoryMgrRestart(dm);
261
} /* End DirectoryMgrResort */
263
/*---------------------------------------------------------------------------*
265
I T E R A T I O N C O M M A N D S
267
*---------------------------------------------------------------------------*/
269
int DirectoryMgrGotoItem(dm,i)
273
if (i < 0 || i >= DirectoryMgrFilteredCount(dm)) return(FALSE);
274
DirectoryMgrCurrentIndex(dm) = i;
276
} /* End DirectoryMgrGotoItem */
279
int DirectoryMgrGotoNamedItem(dm,name)
286
for (i = 0; i < DirectoryMgrFilteredCount(dm); i++)
288
entry = DirectoryMgrSortedPtrs(dm)[i];
289
if (strcmp(DirEntryFileName(entry),name) == 0)
291
DirectoryMgrCurrentIndex(dm) = i;
296
} /* End DirectoryMgrGotoNamedItem */
299
void DirectoryMgrRestart(dm)
302
DirectoryMgrCurrentIndex(dm) = 0;
303
} /* End DirectoryMgrRestart */
306
DirEntry *DirectoryMgrCurrentEntry(dm)
311
index = DirectoryMgrCurrentIndex(dm);
312
if (index < 0 || index >= DirectoryMgrFilteredCount(dm)) return(NULL);
313
return(DirectoryMgrSortedPtrs(dm)[index]);
314
} /* End DirectoryMgrCurrentEntry */
317
DirEntry *DirectoryMgrNextEntry(dm)
322
index = DirectoryMgrCurrentIndex(dm);
323
if (index >= DirectoryMgrFilteredCount(dm)) return(NULL);
324
++ DirectoryMgrCurrentIndex(dm);
325
return(DirectoryMgrSortedPtrs(dm)[index]);
326
} /* End DirectoryMgrNextEntry */
329
DirEntry *DirectoryMgrPrevEntry(dm)
334
index = DirectoryMgrCurrentIndex(dm) - 1;
335
if (index < 0) return(NULL);
336
-- DirectoryMgrCurrentIndex(dm);
337
return(DirectoryMgrSortedPtrs(dm)[index]);
338
} /* End DirectoryMgrPrevEntry */
340
/*---------------------------------------------------------------------------*
342
U T I L I T Y F U N C T I O N S
344
*---------------------------------------------------------------------------*/
346
int DirectoryMgrSimpleFilterFunc(pattern,ff_ptr,fd_ptr)
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);
363
} /* End DirectoryMgrSimpleFilterFunc */
366
int DirectoryMgrSimpleSortingFunc(sort_type,sf_ptr)
373
case DIR_MGR_SORT_NONE:
375
case DIR_MGR_SORT_NAME:
376
*sf_ptr = DirectoryMgrCompareName;
378
case DIR_MGR_SORT_SIZE_ASCENDING:
379
*sf_ptr = DirectoryMgrCompareSizeAscending;
381
case DIR_MGR_SORT_SIZE_DESCENDING:
382
*sf_ptr = DirectoryMgrCompareSizeDescending;
384
case DIR_MGR_SORT_NAME_DIRS_FIRST:
385
*sf_ptr = DirectoryMgrCompareNameDirsFirst;
387
case DIR_MGR_SORT_ACCESS_ASCENDING:
388
*sf_ptr = DirectoryMgrCompareLastAccessAscending;
390
case DIR_MGR_SORT_ACCESS_DESCENDING:
391
*sf_ptr = DirectoryMgrCompareLastAccessDescending;
394
fprintf(stderr,"Bad sort type %d\n",sort_type);
398
} /* End DirectoryMgrSimpleSortingFunc */
400
/*---------------------------------------------------------------------------*
402
S O R T I N G R O U T I N E S
404
*---------------------------------------------------------------------------*/
406
int DirectoryMgrCompareName(e1p,e2p)
407
DirEntry **e1p,**e2p;
409
return(strcmp(DirEntryFileName(*e1p),DirEntryFileName(*e2p)));
410
} /* End DirectoryMgrCompareName */
413
int DirectoryMgrCompareNameDirsFirst(e1p,e2p)
414
DirEntry **e1p,**e2p;
416
if (DirEntryLeadsToDir(*e1p))
418
if (!DirEntryLeadsToDir(*e2p)) return(-1);
420
else if (DirEntryLeadsToDir(*e2p))
424
return(strcmp(DirEntryFileName(*e1p),DirEntryFileName(*e2p)));
425
} /* End DirectoryMgrCompareNameDirsFirst */
428
int DirectoryMgrCompareSizeAscending(e1p,e2p)
429
DirEntry **e1p,**e2p;
431
if (DirEntryFileSize(*e1p) < DirEntryFileSize(*e2p))
433
else if (DirEntryFileSize(*e1p) == DirEntryFileSize(*e2p))
437
} /* End DirectoryMgrCompareSizeAscending */
440
int DirectoryMgrCompareSizeDescending(e1p,e2p)
441
DirEntry **e1p,**e2p;
443
if (DirEntryFileSize(*e1p) > DirEntryFileSize(*e2p))
445
else if (DirEntryFileSize(*e1p) == DirEntryFileSize(*e2p))
449
} /* End DirectoryMgrCompareSizeDescending */
452
int DirectoryMgrCompareLastAccessAscending(e1p,e2p)
453
DirEntry **e1p,**e2p;
455
return((long)DirEntryLastAccess(*e1p) >
456
(long)DirEntryLastAccess(*e2p));
457
} /* End DirectoryMgrCompareLastAccessAscending */
460
int DirectoryMgrCompareLastAccessDescending(e1p,e2p)
461
DirEntry **e1p,**e2p;
463
return((long)DirEntryLastAccess(*e1p) <
464
(long)DirEntryLastAccess(*e2p));
465
} /* End DirectoryMgrCompareLastAccessDescending */
467
/*---------------------------------------------------------------------------*
469
F I L T E R R O U T I N E S
471
*---------------------------------------------------------------------------*/
473
int DirectoryMgrFilterName(de,fsm)
478
return(RegExpMatch(DirEntryFileName(de),fsm));
482
} /* End DirectoryMgrFilterName */