home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Geek Gadgets 1
/
ADE-1.bin
/
ade-dist
/
emacs-19.28-src.tgz
/
tar.out
/
fsf
/
emacs
/
unixlib
/
src
/
dir.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-09-28
|
4KB
|
178 lines
#include "amiga.h"
#include "dir_data.h"
#include <string.h>
/* opendir/readdir/etc ... emulation w/ stat support hack */
static void free_entries(iDIR *info)
{
struct idirent *scan = info->files;
while (scan)
{
struct idirent *next = scan->next;
free(scan);
scan = next;
}
}
static int gobble_dir(DIR *dir)
{
iDIR *info = (iDIR *)dir->dd_buf;
long ioerr;
struct idirent **last = &info->files;
struct FileLock *dirlock;
free_entries(info);
last_dir = 0;
info->files = 0;
dir->dd_loc = 0;
/* Find a value for st_dev of stat() calls */
dirlock = BADDR(dir->dd_fd);
info->task = dirlock->fl_Task;
while (ExNext(dir->dd_fd, &info->fib))
{
u_short namlen = strlen(info->fib.fib_FileName);
u_short reclen = namlen + 1 + offsetof(struct idirent, entry.d_name);
struct idirent *newentry = (struct idirent *)malloc(reclen);
struct dirent *entry;
if (!newentry)
{
errno = ENOMEM;
return 0;
}
newentry->next = 0;
*last = newentry;
last = &newentry->next;
newentry->numblocks = info->fib.fib_NumBlocks;
newentry->size = info->fib.fib_Size;
newentry->date = info->fib.fib_Date;
newentry->type = info->fib.fib_DirEntryType;
newentry->protection = info->fib.fib_Protection;
entry = &newentry->entry;
entry->d_reclen = reclen;
entry->d_namlen = namlen;
entry->d_off = dir->dd_loc++;
strcpy(entry->d_name, info->fib.fib_FileName);
entry->d_ino = info->fib.fib_DiskKey;
}
info->pos = info->files;
dir->dd_loc = 0;
ioerr = IoErr();
if (ioerr == ERROR_NO_MORE_ENTRIES) return 1;
errno = convert_oserr(ioerr);
return 0;
}
DIR *opendir(char *dirname)
{
DIR *new = (DIR *)malloc(sizeof *new);
iDIR *info = (iDIR *)malloc(sizeof *info);
char *dircopy = malloc(strlen(dirname) + 1);
chkabort();
if (new && dircopy && info)
{
new->dd_buf = (char *)info;
new->dd_size = sizeof *info;
info->files = info->pos = 0;
info->seeked = 0;
info->dirname = dircopy;
strcpy(dircopy, dirname);
info->cdir = _get_cd();
if ((new->dd_fd = Lock(dirname, ACCESS_READ)) &&
Examine(new->dd_fd, &info->fib))
{
if (gobble_dir(new)) return new;
}
else errno = convert_oserr(IoErr());
closedir(new);
return 0;
}
errno = ENOMEM;
if (new) free(new);
if (dircopy) free(dircopy);
if (info) free(info);
return 0;
}
void closedir(DIR *dir)
{
iDIR *info = (iDIR *)dir->dd_buf;
chkabort();
last_dir = 0;
free_entries(info);
free(info->dirname);
if (dir->dd_fd) UnLock(dir->dd_fd);
free(dir->dd_buf);
free(dir);
}
struct dirent *readdir(DIR *dir)
{
iDIR *info = (iDIR *)dir->dd_buf;
struct dirent *entry = 0;
chkabort();
if (info->seeked)
{
long cloc = 0;
struct idirent *pos;
pos = info->files;
while (cloc < dir->dd_loc && pos)
{
cloc++; pos = pos->next;
}
/*if (cloc != dir->dd_loc) error ...
This doesn't seem to be defined very precisely */
info->pos = pos;
info->seeked = 0;
}
if (info->pos)
{
entry = &info->pos->entry;
last_dir = dir;
last_entry = info->pos;
info->pos = info->pos->next;
dir->dd_loc++;
}
return entry;
}
long telldir(DIR *dir)
{
chkabort();
return dir->dd_loc;
}
void seekdir(DIR *dir, long loc)
{
iDIR *info = (iDIR *)dir->dd_buf;
chkabort();
info->seeked = 1;
dir->dd_loc = loc;
}
#if 0
void rewwinddir(DIR *dir)
{
chkabort();
gobble_dir(dir);
}
#endif