home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Club Amiga de Montreal - CAM
/
CAM_CD_1.iso
/
files
/
191.lha
/
ARequester
/
reqdir.c
< prev
next >
Wrap
C/C++ Source or Header
|
1988-04-28
|
5KB
|
216 lines
#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';
}