home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / SOURCE / AP / ASH / ASH-LINU.2 / ASH-LINU / ash-linux-0.2 / dirent.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-08-24  |  4.9 KB  |  196 lines

  1. /*-
  2.  * Copyright (c) 1991 The Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * This code is derived from software contributed to Berkeley by
  6.  * Kenneth Almquist.
  7.  *
  8.  * Redistribution and use in source and binary forms, with or without
  9.  * modification, are permitted provided that the following conditions
  10.  * are met:
  11.  * 1. Redistributions of source code must retain the above copyright
  12.  *    notice, this list of conditions and the following disclaimer.
  13.  * 2. Redistributions in binary form must reproduce the above copyright
  14.  *    notice, this list of conditions and the following disclaimer in the
  15.  *    documentation and/or other materials provided with the distribution.
  16.  * 3. All advertising materials mentioning features or use of this software
  17.  *    must display the following acknowledgement:
  18.  *    This product includes software developed by the University of
  19.  *    California, Berkeley and its contributors.
  20.  * 4. Neither the name of the University nor the names of its contributors
  21.  *    may be used to endorse or promote products derived from this software
  22.  *    without specific prior written permission.
  23.  *
  24.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  25.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  26.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  27.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  28.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  29.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  30.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  31.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  32.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  33.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  34.  * SUCH DAMAGE.
  35.  */
  36.  
  37. #ifndef lint
  38. /*static char sccsid[] = "from: @(#)dirent.c    5.1 (Berkeley) 3/7/91";*/
  39. static char rcsid[] = "dirent.c,v 1.4 1993/08/01 18:58:21 mycroft Exp";
  40. #endif /* not lint */
  41.  
  42. #include "shell.h"    /* definitions for pointer, NULL, DIRENT, and BSD */
  43.  
  44. #if ! DIRENT
  45.  
  46. #include <errno.h>
  47. #include <sys/types.h>
  48. #include <sys/stat.h>
  49. #include <fcntl.h>
  50. #include <dirent.h>
  51.  
  52. #ifndef S_ISDIR                /* macro to test for directory file */
  53. #define    S_ISDIR(mode)        (((mode) & S_IFMT) == S_IFDIR)
  54. #endif
  55.  
  56. #ifdef BSD
  57.  
  58. #ifdef __STDC__
  59. int stat(char *, struct stat *);
  60. #else
  61. int stat();
  62. #endif
  63.  
  64.  
  65. /*
  66.  * The BSD opendir routine doesn't check that what is being opened is a
  67.  * directory, so we have to include the check in a wrapper routine.
  68.  */
  69.  
  70. #undef opendir
  71.  
  72. DIR *
  73. myopendir(dirname)
  74.     char *dirname;            /* name of directory */
  75.     {
  76.     struct stat statb;
  77.  
  78.     if (stat(dirname, &statb) != 0 || ! S_ISDIR(statb.st_mode)) {
  79.         errno = ENOTDIR;
  80.         return NULL;        /* not a directory */
  81.     }
  82.     return opendir(dirname);
  83. }
  84.  
  85. #else /* not BSD */
  86.  
  87. /*
  88.  * Dirent routines for old style file systems.
  89.  */
  90.  
  91. #ifdef __STDC__
  92. pointer malloc(unsigned);
  93. void free(pointer);
  94. int open(char *, int, ...);
  95. int close(int);
  96. int fstat(int, struct stat *);
  97. #else
  98. pointer malloc();
  99. void free();
  100. int open();
  101. int close();
  102. int fstat();
  103. #endif
  104.  
  105.  
  106. DIR *
  107. opendir(dirname)
  108.     char        *dirname;    /* name of directory */
  109.     {
  110.     register DIR    *dirp;        /* -> malloc'ed storage */
  111.     register int    fd;        /* file descriptor for read */
  112.     struct stat    statb;        /* result of fstat() */
  113.  
  114. #ifdef O_NDELAY
  115.     fd = open(dirname, O_RDONLY|O_NDELAY);
  116. #else
  117.     fd = open(dirname, O_RDONLY);
  118. #endif
  119.     if (fd < 0)
  120.         return NULL;        /* errno set by open() */
  121.  
  122.     if (fstat(fd, &statb) != 0 || !S_ISDIR(statb.st_mode)) {
  123.         (void)close(fd);
  124.         errno = ENOTDIR;
  125.         return NULL;        /* not a directory */
  126.     }
  127.  
  128.     if ((dirp = (DIR *)malloc(sizeof(DIR))) == NULL) {
  129.         (void)close(fd);
  130.         errno = ENOMEM;
  131.         return NULL;        /* not enough memory */
  132.     }
  133.  
  134.     dirp->dd_fd = fd;
  135.     dirp->dd_nleft = 0;        /* refill needed */
  136.  
  137.     return dirp;
  138. }
  139.  
  140.  
  141.  
  142. int
  143. closedir(dirp)
  144.     register DIR *dirp;        /* stream from opendir() */
  145.     {
  146.     register int fd;
  147.  
  148.     if (dirp == NULL) {
  149.         errno = EFAULT;
  150.         return -1;            /* invalid pointer */
  151.     }
  152.  
  153.     fd = dirp->dd_fd;
  154.     free((pointer)dirp);
  155.     return close(fd);
  156. }
  157.  
  158.  
  159.  
  160. struct dirent *
  161. readdir(dirp)
  162.     register DIR *dirp;        /* stream from opendir() */
  163.     {
  164.     register struct direct *dp;
  165.     register char *p, *q;
  166.     register int i;
  167.  
  168.     do {
  169.         if ((dirp->dd_nleft -= sizeof (struct direct)) < 0) {
  170.             if ((i = read(dirp->dd_fd,
  171.                        (char *)dirp->dd_buf,
  172.                        DIRBUFENT*sizeof(struct direct))) <= 0) {
  173.                 if (i == 0)
  174.                     errno = 0;    /* unnecessary */
  175.                 return NULL;        /* EOF or error */
  176.             }
  177.             dirp->dd_loc = dirp->dd_buf;
  178.             dirp->dd_nleft = i - sizeof (struct direct);
  179.         }
  180.         dp = dirp->dd_loc++;
  181.     } while (dp->d_ino == 0);
  182.     dirp->dd_entry.d_ino = dp->d_ino;
  183.  
  184.     /* now copy the name, nul terminating it */
  185.     p = dp->d_name;
  186.     q = dirp->dd_entry.d_name;
  187.     i = DIRSIZ;
  188.     while (--i >= 0 && *p != '\0')
  189.         *q++ = *p++;
  190.     *q = '\0';
  191.     return &dirp->dd_entry;
  192. }
  193.  
  194. #endif /* BSD */
  195. #endif /* DIRENT */
  196.