home *** CD-ROM | disk | FTP | other *** search
- /* readdir.c: */
-
- #include <dos/dos.h>
- #include <dos/dostags.h>
- #include <clib/dos_protos.h>
- #include <errno.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include "unixlib.h"
-
- #define MAX_DIRS 16
-
- #ifdef LATTICE
- #include <proto/dos.h>
- #endif
-
- static short g_module_initialized = 0;
- static DIR *g_dir_array[MAX_DIRS];
-
- static void Cleanup (void)
- {
- int i;
-
- for (i=0; i<MAX_DIRS; i++)
- if (g_dir_array[i]) {
- if (g_dir_array[i]->lock)
- UnLock ((BPTR) g_dir_array[i]->lock);
- if (g_dir_array[i]->fib)
- FreeDosObject (DOS_FIB, (struct FileInfoBlock *) g_dir_array[i]->fib);
- }
- }
-
- static int Register_Dir (DIR *p_dir)
- {
- int i;
-
- for (i=0; i<MAX_DIRS; i++)
- if (!g_dir_array[i]) {
- g_dir_array[i] = p_dir;
- return i+1;
- }
-
- return 0;
- }
-
- static void Initialize_Module (void)
- {
- int i;
-
- g_module_initialized = 1;
-
- for (i=0; i<MAX_DIRS; i++)
- g_dir_array[i] = NULL;
-
- atexit (Cleanup);
- }
-
- DIR *opendir (const char *p_pathname)
- {
- DIR *new = malloc (sizeof (*new));
-
- if (!malloc) {
- errno = ENOMEM;
- return NULL;
- }
-
- new->lock = new->fib = NULL;
-
- if (!(new->dir_index = Register_Dir (new))) {
- free (new);
- errno = EMFILE;
- return NULL;
- }
-
- if (!g_module_initialized)
- Initialize_Module ();
-
- new->lock = (char *) Lock ((UBYTE *) p_pathname, ACCESS_READ);
- if (!new->lock) {
- free (new);
- errno = ENOENT;
- return NULL;
- }
-
- new->fib = (char *) AllocDosObject (DOS_FIB, TAG_DONE);
- if (!new->fib) {
- UnLock ((BPTR) new->lock);
- g_dir_array[new->dir_index] = NULL;
- free (new);
- errno = ENOMEM;
- return NULL;
- }
-
- if (!Examine ((BPTR) new->lock, (struct FileInfoBlock *) new->fib) ||
- ((struct FileInfoBlock *) new->fib)->fib_DirEntryType <= 0) {
- FreeDosObject (DOS_FIB, (struct FileInfoBlock *) new->fib);
- UnLock ((BPTR) new->lock);
- g_dir_array[new->dir_index] = NULL;
- free (new);
- errno = ENOTDIR;
- return NULL;
- }
-
- new->phase = 0;
- return new;
- }
-
- struct dirent *readdir (DIR *p_dir_ptr)
- {
- struct FileInfoBlock *fib = (struct FileInfoBlock *) p_dir_ptr->fib;
-
- switch (p_dir_ptr->phase) {
- case 0:
- strcpy (p_dir_ptr->dirent.d_name, ".");
- p_dir_ptr->dirent.d_reclen = 1;
- p_dir_ptr->phase++;
- return &(p_dir_ptr->dirent);
- case 1:
- strcpy (p_dir_ptr->dirent.d_name, "..");
- p_dir_ptr->dirent.d_reclen = 2;
- p_dir_ptr->phase++;
- return &(p_dir_ptr->dirent);
- default:
- if (!ExNext ((BPTR) p_dir_ptr->lock, fib)) {
- errno = ENOENT;
- return NULL;
- }
-
- strcpy (p_dir_ptr->dirent.d_name, fib->fib_FileName);
- p_dir_ptr->dirent.d_reclen = strlen (fib->fib_FileName);
-
- return &(p_dir_ptr->dirent);
- }
- }
-
- int closedir (DIR *p_dir_ptr)
- {
- g_dir_array[p_dir_ptr->dir_index - 1] = NULL;
- UnLock ((BPTR) p_dir_ptr->lock);
- FreeDosObject (DOS_FIB, (struct FileInfoBlock *) p_dir_ptr->fib);
- free (p_dir_ptr);
- return 0;
- }
-