home *** CD-ROM | disk | FTP | other *** search
- /* C.Dir: Directory handling */
-
- #include <stddef.h>
- #include <stdlib.h>
- #include <string.h>
- #include "kernel.h"
- #include "swis.h"
-
- #include "sys/dir.h"
-
- #define ReadDir 9
-
- /* Constants. The function assumes that a directory can hold no more than
- * MAX_DIR entries, and a filename can be no longer than MAXNAMELEN (which
- * is defined in the header file to be 10 as a default) characters. It also
- * assumes that OS_GBPB 9 will only ever fail to return all possible
- * filenames on the first call if the supplied buffer becomes full. In this
- * case, dirscan() will ignore any omitted entries. This behaviour is not
- * ideal, but gains significantly in efficiency. (The given buffer size
- * should be easily enough for all normal cases).
- */
- #define MAX_DIR 255
- #define CACHE_SIZE (MAX_DIR * (MAXNAMELEN + 1))
-
- DIR *opendir (char *name)
- {
- register char *cache;
- register DIR *dirp;
- _kernel_swi_regs regs;
-
- dirp = malloc(sizeof(DIR));
- if (dirp == 0)
- return NULL;
-
- cache = malloc(CACHE_SIZE);
- if (cache == NULL)
- {
- free(dirp);
- return NULL;
- }
-
- regs.r[0] = ReadDir;
- regs.r[1] = (int) name;
- regs.r[2] = (int) cache;
- regs.r[3] = CACHE_SIZE;
- regs.r[4] = 0;
- regs.r[5] = CACHE_SIZE;
- regs.r[6] = (int) "*";
-
- if (_kernel_swi(OS_GBPB, ®s, ®s))
- {
- free (cache);
- free (dirp);
- return NULL;
- }
-
- dirp->dd_pos = 0;
- dirp->dd_num = regs.r[3];
- dirp->dd_loc = cache;
- dirp->dd_cache = cache;
-
- return dirp;
- }
-
- struct direct *readdir (DIR *dirp)
- {
- register char *from;
- register char *to;
- static struct direct dir;
-
- /* If no more entries, return NULL */
- if (dirp->dd_pos >= dirp->dd_num)
- return NULL;
-
- /* Copy the name into the struct direct */
- to = dir.d_name;
- from = dirp->dd_loc;
- while ((*to++ = *from++) != 0)
- ;
-
- /* Update the DIR structure */
- ++dirp->dd_pos;
- dirp->dd_loc = from;
-
- /* Set up the rest of the struct direct */
- dir.d_ino = 0;
- dir.d_reclen = dir.d_namlen = strlen(dir.d_name);
-
- return &dir;
- }
-
- extern void closedir (DIR *dirp)
- {
- if (dirp != NULL)
- {
- if (dirp->dd_cache != NULL)
- free(dirp->dd_cache);
-
- free(dirp);
- }
- }
-
- extern int seekdir (DIR *dirp, int pos)
- {
- register int old_pos = dirp->dd_pos;
- register int i = 0;
- register char *p = dirp->dd_cache;
-
- while (i < pos)
- {
- while (*p++ != 0)
- ;
- ++i;
- }
-
- dirp->dd_pos = pos;
- dirp->dd_loc = p;
-
- return old_pos;
- }
-
- /* ---------------------------------------------------------------------- */
-
- #ifdef test
-
- #include <ctype.h>
- #include <stdio.h>
-
- #define BUFLEN 255
-
- int main (void)
- {
- char buf[BUFLEN];
- char s[20];
- int i;
- DIR *dp;
-
- for ( ; ; )
- {
- printf(">");
- fgets(buf,BUFLEN,stdin);
-
- if ( buf[0] == '\n' || buf[0] == '\0' )
- continue;
- else if ( sscanf(buf,"dir %s",&s) == 1 )
- dp = opendir(s);
- else if ( strncmp(buf,"dir",3) == 0 )
- dp = opendir("");
- else if ( sscanf(buf,"goto %d",&i) == 1 )
- printf("From: %d\n",seekdir(dp,i));
- else if ( strncmp(buf,"close",5) == 0 )
- closedir(dp);
- else if ( *buf == 'n' )
- {
- int pos = telldir(dp);
- struct direct *d = readdir(dp);
- if (d)
- printf("Pos: %d, Name: %s\n", pos, d->d_name);
- else
- printf("Finished...\n");
- }
- else if ( strncmp(buf,"dump",4) == 0 )
- {
- int max = dp->dd_num * 11;
- char *p = dp->dd_cache;
-
- printf("Pos: %d\n", dp->dd_pos);
- printf("Num: %d\n", dp->dd_num);
- printf("Loc: %p\n", dp->dd_loc);
- printf("Cache: %p\n", dp->dd_cache);
-
- while (p < &dp->dd_cache[max])
- {
- if (isgraph(*p) || *p == ' ')
- putchar(*p);
- else
- putchar('.');
- ++p;
- }
- }
- else if ( strncmp(buf,"quit",4) == 0 )
- break;
- else if ( *buf == '*' )
- system(&buf[1]);
- else
- printf("Mistake\n");
- }
-
- return 0;
- }
-
- #endif
-