home *** CD-ROM | disk | FTP | other *** search
- #include <libraries/dosextens.h>
- #include "reqdir.h"
-
- #define ALIGN(X) ((X+1)&~1)
- #define DaysInYear(year) ((year%4) ? 365 : 366)
-
- /* Array of entry pointers */
- static Entry **ent;
- static ULONG num_entries, max_entries;
- static char *buffer_max;
-
- extern struct Lock *Lock();
- extern short Examine();
- extern short ExNext();
- extern long IoErr();
- extern char *strcpy();
- extern void UnLock();
- extern void *AllocMem();
-
-
- static void put_date(e,fib)
- register Entry *e;
- struct FileInfoBlock *fib;
- {
- register UWORD year, month;
- register long d;
- static UWORD days[12] = {31,28,31,30,31,30,31,31,30,31,30,31};
-
- /* figure out what year */
- for( year = 1978, d = fib->fib_Date.ds_Days; d > DaysInYear(year);)
- { d -= DaysInYear(year); year++; }
-
- /* there are 29 days in February in a leap year */
- days[1] = (year % 4) ? 28 : 29;
-
- /* figure out what month */
- for( month = 0; d > days[month]; month++)
- d -= days[month];
-
- e->month = month+1;
- e->day = d+1;
- e->year = year - 1978;
- }
-
-
- /* adds a directory entry to the buffer */
-
- static char *add_entry(curr,fib)
- register char *curr;
- register struct FileInfoBlock *fib;
- {
- register Entry *e;
- register char *next;
- register UWORD len;
-
- len = ALIGN(strlen(fib->fib_FileName) + 1);
-
- /* check for space in the buffer */
- if( (next = curr + (sizeof(Entry) + len*sizeof(char)) ) > buffer_max )
- return(0L);
-
- e = (Entry *)curr;
- e->size = len + sizeof(Entry);
-
- strcpy(EntryName(e),fib->fib_FileName);
-
- if( !(e->dir = ((fib->fib_EntryType > 0) ? 1 : 0)) )
- {
- e->archive = (fib->fib_Protection & FIBF_ARCHIVE) ? 0 : 1;
- e->read = (fib->fib_Protection & FIBF_READ) ? 0 : 1;
- e->write = (fib->fib_Protection & FIBF_WRITE) ? 0 : 1;
- e->execute = (fib->fib_Protection & FIBF_EXECUTE) ? 0 : 1;
- e->delete = (fib->fib_Protection & FIBF_DELETE) ? 0 : 1;
- }
-
- put_date(e,fib);
-
- if( num_entries < max_entries )
- ent[num_entries] = e;
- else return(0L);
-
- return(next);
- }
-
-
- static short comp(i,j)
- register ULONG i, j;
- {
- extern short strcmpa();
-
- if( ent[i]->dir != ent[j]->dir )
- return( (short)(ent[j]->dir - ent[i]->dir) );
- return( strcmpa(EntryName(ent[i]),EntryName(ent[j])) );
- }
-
- static void swap(i,j)
- register ULONG i, j;
- {
- register Entry *e;
- e = ent[i];
- ent[i] = ent[j];
- ent[j] = e;
- }
-
- /* Returns the number of directory entries found or an error */
-
- long reqdir(name,buffer,bufsize,entries,maxent)
- char *name; /* => The directory to lock first */
- char *buffer; /* => The buffer for the directory entries */
- ULONG bufsize; /* => The size of the buffer for dir entries */
- Entry *entries[]; /* <= A sorted array of directory entry pointers */
- ULONG maxent; /* => The maximum number of directory entries */
- {
- register struct Lock *lock;
- register char *max = buffer + (bufsize - 1);
- register char *curr = buffer;
- register struct FileInfoBlock *fib;
- short error;
-
- /* Assign some global variables so the sorting functions
- * can get at them */
- ent = entries;
- max_entries = maxent;
- buffer_max = max;
-
- if( !(lock = Lock(name,(long)ACCESS_READ)) )
- return(-1L);
-
- if( !(fib = AllocMem((long)sizeof(struct FileInfoBlock),(long)MEMF_CLEAR)) )
- {
- UnLock(lock);
- return(-1L);
- }
- if( !Examine(lock, fib) )
- {
- UnLock(lock);
- return(-1L);
- }
- if( fib->fib_DirEntryType <= 0 )
- {
- FreeMem(fib,(long)sizeof(struct FileInfoBlock));
- UnLock(lock);
- return(-2L);
- }
-
- /* always add the parent directory to the list of entries */
- num_entries = 0L;
- fib->fib_EntryType = 1;
- strcpy(fib->fib_FileName,"/");
- curr = add_entry(curr,fib);
-
-
- for(num_entries = 1L;;)
- {
- if( !ExNext(lock,fib) )
- if( IoErr() == ERROR_NO_MORE_ENTRIES )
- break;
- if( !(curr = add_entry(curr,fib)) )
- break;
- num_entries++;
- }
-
- UnLock(lock);
-
- /* Sort the directory entries */
- if( num_entries )
- quicksort(num_entries,comp,swap);
-
- FreeMem(fib,(long)sizeof(struct FileInfoBlock));
-
- return((long)num_entries);
- }
-
-
- /* This is need to convert the stupid BCPL strings */
- UBYTE *bstrcpy(dest,src)
- register UBYTE *dest;
- BSTR *src;
- {
- register char *string;
- register UWORD length, i;
-
- string = (char *) BADDR(src);
- length = *string++;
-
- for( i = 0; i < length; i++)
- dest[i] = string[i];
-
- dest[length] = '\0';
-
- return(dest);
- }
-
-
- void init_dir(path,ac)
- UBYTE *path;
- short ac;
- {
- extern struct Task *FindTask();
-
- register struct Process *me;
-
- me = (struct Process *)FindTask(0L);
-
- /* find the current directrory */
- if( ac ) /* startup from the CLI */
- {
- register struct CommandLineInterface *cli =
- (struct CommandLineInterface *) BADDR(me->pr_CLI);
- bstrcpy(path,cli->cli_SetName);
- }
- else path[0] = '\0';
-
- }
-
-