home *** CD-ROM | disk | FTP | other *** search
/ Simtel MSDOS 1992 September / Simtel20_Sept92.cdr / msdos / gnuish / gnulib0.arc / ndir.c < prev    next >
C/C++ Source or Header  |  1990-09-20  |  5KB  |  217 lines

  1. /*  msd_dir.c - portable directory routines
  2.     Copyright (C) 1990 by Thorsten Ohl, td12@ddagsi3.bitnet
  3.  
  4.     This program is free software; you can redistribute it and/or modify
  5.     it under the terms of the GNU General Public License as published by
  6.     the Free Software Foundation; either version 1, or (at your option)
  7.     any later version.
  8.  
  9.     This program is distributed in the hope that it will be useful,
  10.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.     GNU General Public License for more details.
  13.  
  14.     You should have received a copy of the GNU General Public License
  15.     along with this program; if not, write to the Free Software
  16.     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17.  
  18.     $Header: e:/gnu/lib/RCS/ndir.c 1.0 90/09/10 23:16:19 tho Stable $
  19.  */
  20.  
  21. /* Everything non trivial in this code is from: @(#)msd_dir.c 1.4
  22.    87/11/06.  A public domain implementation of BSD directory routines
  23.    for MS-DOS.  Written by Michael Rendell ({uunet,utai}michael@garfield),
  24.    August 1897 */
  25.  
  26.  
  27. #include <stdio.h>
  28. #include <stdlib.h>
  29. #include <string.h>
  30. #include <sys/types.h>
  31. #include <sys/stat.h>
  32.  
  33. #include <dos.h>
  34.  
  35. #include <ndir.h>
  36.  
  37. static void free_dircontents (struct _dircontents *);
  38.  
  39. /* find ALL files! */
  40. #define ATTRIBUTES    (_A_RDONLY | _A_HIDDEN | _A_SYSTEM | _A_SUBDIR)
  41.  
  42.  
  43.  
  44. DIR *
  45. opendir (char *name)
  46. {
  47.   struct find_t find_buf;
  48.   DIR *dirp;
  49.   struct _dircontents *dp;
  50.   char name_buf[_MAX_PATH + 1];
  51.   char *slash = "";
  52.  
  53.   if (!name)
  54.     name = "";
  55.   else if (*name)
  56.     {
  57.       char *s;
  58.       int l = strlen (name);
  59.  
  60.       s = name + l - 1;
  61.       if ( !(l == 2 && *s == ':') && *s != '\\' && *s != '/')
  62.     slash = "/";    /* save to insert slash between path and "*.*" */
  63.     }
  64.  
  65.   strcat (strcat (strcpy (name_buf, name), slash), "*.*");
  66.  
  67.   dirp = (DIR *) malloc (sizeof (DIR));
  68.   if (dirp == (DIR *)0)
  69.     return (DIR *)0;
  70.  
  71.   dirp->dd_loc = 0;
  72.   dirp->dd_contents = dirp->dd_cp = (struct _dircontents *) 0;
  73.  
  74.   if (_dos_findfirst (name_buf, ATTRIBUTES, &find_buf))
  75.     {
  76.       free (dirp);
  77.       return (DIR *)0;
  78.     }
  79.  
  80.   do
  81.     {
  82.       dp = (struct _dircontents *) malloc (sizeof (struct _dircontents));
  83.       if (dp == (struct _dircontents *)0)
  84.     {
  85.       free_dircontents (dirp->dd_contents);
  86.       return (DIR *)0;
  87.     }
  88.  
  89.       dp->_d_entry = malloc (strlen (find_buf.name) + 1);
  90.       if (dp->_d_entry == (char *)0)
  91.     {
  92.       free (dp);
  93.       free_dircontents (dirp->dd_contents);
  94.       return (DIR *)0;
  95.     }
  96.  
  97.       if (dirp->dd_contents)
  98.     dirp->dd_cp = dirp->dd_cp->_d_next = dp;
  99.       else
  100.     dirp->dd_contents = dirp->dd_cp = dp;
  101.  
  102.       strcpy (dp->_d_entry, find_buf.name);
  103.  
  104.       dp->_d_next = (struct _dircontents *)0;
  105.  
  106.     } while (! _dos_findnext (&find_buf));
  107.  
  108.   dirp->dd_cp = dirp->dd_contents;
  109.  
  110.   return dirp;
  111. }
  112.  
  113.  
  114. void
  115. closedir (DIR *dirp)
  116. {
  117.   free_dircontents (dirp->dd_contents);
  118.   free ((char *) dirp);
  119. }
  120.  
  121.  
  122. struct direct *
  123. readdir (DIR *dirp)
  124. {
  125.   static struct direct dp;
  126.  
  127.   if (dirp->dd_cp == (struct _dircontents *)0)
  128.     return (struct direct *)0;
  129.   dp.d_namlen = dp.d_reclen =
  130.     strlen (strcpy (dp.d_name, dirp->dd_cp->_d_entry));
  131.   strlwr (dp.d_name);        /* JF */
  132.   dp.d_ino = 0;
  133.   dirp->dd_cp = dirp->dd_cp->_d_next;
  134.   dirp->dd_loc++;
  135.  
  136.   return &dp;
  137. }
  138.  
  139.  
  140. void
  141. seekdir (DIR *dirp, long off)
  142. {
  143.   long i = off;
  144.   struct _dircontents *dp;
  145.  
  146.   if (off < 0)
  147.     return;
  148.   for (dp = dirp->dd_contents; --i >= 0 && dp; dp = dp->_d_next)
  149.     ;
  150.   dirp->dd_loc = off - (i + 1);
  151.   dirp->dd_cp = dp;
  152. }
  153.  
  154.  
  155. long
  156. telldir (DIR *dirp)
  157. {
  158.   return dirp->dd_loc;
  159. }
  160.  
  161.  
  162. /* Garbage collection */
  163.  
  164. static void
  165. free_dircontents (struct _dircontents *dp)
  166. {
  167.   struct _dircontents *odp;
  168.  
  169.   while (dp)
  170.     {
  171.       if (dp->_d_entry)
  172.     free (dp->_d_entry);
  173.       dp = (odp = dp)->_d_next;
  174.       free (odp);
  175.     }
  176. }
  177.  
  178.  
  179. #ifdef TEST
  180.  
  181. void main (int argc, char *argv[]);
  182.  
  183. void
  184. main (int argc, char *argv[])
  185. {
  186.   static DIR *directory;
  187.   struct direct *entry = (struct direct *)0;
  188.  
  189.   char *name = "";
  190.  
  191.   if (argc > 1)
  192.     name = argv[1];
  193.  
  194.   directory = opendir (name);
  195.  
  196.   if (!directory)
  197.     {
  198.       fprintf (stderr, "can't open directory `%s'.\n", name);
  199.       exit (2);
  200.     }
  201.  
  202.   while (entry = readdir (directory))
  203.     printf ("> %s\n", entry->d_name);
  204.  
  205.   printf ("done.\n");
  206. }
  207.  
  208. #endif /* TEST */
  209.  
  210. /* 
  211.  * Local Variables:
  212.  * mode:C
  213.  * ChangeLog:ChangeLog
  214.  * compile-command:make
  215.  * End:
  216.  */
  217.