xref: /openbsd-src/gnu/usr.bin/cvs/windows-NT/ndir.c (revision 2286d8ed900f26153a3cd5227a124b1c0adce72f)
11e72d8d2Sderaadt /*  msd_dir.c - portable directory routines
21e72d8d2Sderaadt     Copyright (C) 1990 by Thorsten Ohl, td12@ddagsi3.bitnet
31e72d8d2Sderaadt 
41e72d8d2Sderaadt     This program is free software; you can redistribute it and/or modify
51e72d8d2Sderaadt     it under the terms of the GNU General Public License as published by
61e72d8d2Sderaadt     the Free Software Foundation; either version 1, or (at your option)
71e72d8d2Sderaadt     any later version.
81e72d8d2Sderaadt 
91e72d8d2Sderaadt     This program is distributed in the hope that it will be useful,
101e72d8d2Sderaadt     but WITHOUT ANY WARRANTY; without even the implied warranty of
111e72d8d2Sderaadt     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12*2286d8edStholo     GNU General Public License for more details.  */
131e72d8d2Sderaadt 
141e72d8d2Sderaadt /* Everything non trivial in this code is from: @(#)msd_dir.c 1.4
151e72d8d2Sderaadt    87/11/06.  A public domain implementation of BSD directory routines
161e72d8d2Sderaadt    for MS-DOS.  Written by Michael Rendell ({uunet,utai}michael@garfield),
171e72d8d2Sderaadt    August 1897 */
181e72d8d2Sderaadt 
191e72d8d2Sderaadt 
201e72d8d2Sderaadt #include <io.h>
211e72d8d2Sderaadt #include <stdio.h>
221e72d8d2Sderaadt #include <stdlib.h>
231e72d8d2Sderaadt #include <string.h>
241e72d8d2Sderaadt #include <sys/types.h>
251e72d8d2Sderaadt #include <sys/stat.h>
261e72d8d2Sderaadt 
271e72d8d2Sderaadt #include <dos.h>
281e72d8d2Sderaadt 
291e72d8d2Sderaadt #include <ndir.h>
301e72d8d2Sderaadt 
311e72d8d2Sderaadt static void free_dircontents (struct _dircontents *);
321e72d8d2Sderaadt 
331e72d8d2Sderaadt /* find ALL files! */
341e72d8d2Sderaadt #define ATTRIBUTES	(_A_RDONLY | _A_HIDDEN | _A_SYSTEM | _A_SUBDIR)
351e72d8d2Sderaadt 
361e72d8d2Sderaadt 
371e72d8d2Sderaadt 
381e72d8d2Sderaadt DIR *
opendir(const char * name)391e72d8d2Sderaadt opendir (const char *name)
401e72d8d2Sderaadt {
411e72d8d2Sderaadt   struct _finddata_t find_buf;
421e72d8d2Sderaadt   DIR *dirp;
431e72d8d2Sderaadt   struct _dircontents *dp;
441e72d8d2Sderaadt   char name_buf[_MAX_PATH + 1];
451e72d8d2Sderaadt   char *slash = "";
461e72d8d2Sderaadt   long hFile;
471e72d8d2Sderaadt 
481e72d8d2Sderaadt   if (!name)
491e72d8d2Sderaadt     name = "";
501e72d8d2Sderaadt   else if (*name)
511e72d8d2Sderaadt     {
521e72d8d2Sderaadt       const char *s;
531e72d8d2Sderaadt       int l = strlen (name);
541e72d8d2Sderaadt 
551e72d8d2Sderaadt       s = name + l - 1;
561e72d8d2Sderaadt       if ( !(l == 2 && *s == ':') && *s != '\\' && *s != '/')
571e72d8d2Sderaadt 	slash = "/";	/* save to insert slash between path and "*.*" */
581e72d8d2Sderaadt     }
591e72d8d2Sderaadt 
601e72d8d2Sderaadt   strcat (strcat (strcpy (name_buf, name), slash), "*.*");
611e72d8d2Sderaadt 
621e72d8d2Sderaadt   dirp = (DIR *) malloc (sizeof (DIR));
631e72d8d2Sderaadt   if (dirp == (DIR *)0)
641e72d8d2Sderaadt     return (DIR *)0;
651e72d8d2Sderaadt 
661e72d8d2Sderaadt   dirp->dd_loc = 0;
671e72d8d2Sderaadt   dirp->dd_contents = dirp->dd_cp = (struct _dircontents *) 0;
681e72d8d2Sderaadt 
691e72d8d2Sderaadt   if ((hFile = _findfirst (name_buf, &find_buf)) < 0)
701e72d8d2Sderaadt     {
711e72d8d2Sderaadt       free (dirp);
721e72d8d2Sderaadt       return (DIR *)0;
731e72d8d2Sderaadt     }
741e72d8d2Sderaadt 
751e72d8d2Sderaadt   do
761e72d8d2Sderaadt     {
771e72d8d2Sderaadt       dp = (struct _dircontents *) malloc (sizeof (struct _dircontents));
781e72d8d2Sderaadt       if (dp == (struct _dircontents *)0)
791e72d8d2Sderaadt 	{
801e72d8d2Sderaadt 	  free_dircontents (dirp->dd_contents);
811e72d8d2Sderaadt 	  return (DIR *)0;
821e72d8d2Sderaadt 	}
831e72d8d2Sderaadt 
841e72d8d2Sderaadt       dp->_d_entry = malloc (strlen (find_buf.name) + 1);
851e72d8d2Sderaadt       if (dp->_d_entry == (char *)0)
861e72d8d2Sderaadt 	{
871e72d8d2Sderaadt 	  free (dp);
881e72d8d2Sderaadt 	  free_dircontents (dirp->dd_contents);
891e72d8d2Sderaadt 	  return (DIR *)0;
901e72d8d2Sderaadt 	}
911e72d8d2Sderaadt 
921e72d8d2Sderaadt       if (dirp->dd_contents)
931e72d8d2Sderaadt 	dirp->dd_cp = dirp->dd_cp->_d_next = dp;
941e72d8d2Sderaadt       else
951e72d8d2Sderaadt 	dirp->dd_contents = dirp->dd_cp = dp;
961e72d8d2Sderaadt 
971e72d8d2Sderaadt       strcpy (dp->_d_entry, find_buf.name);
981e72d8d2Sderaadt 
991e72d8d2Sderaadt       dp->_d_next = (struct _dircontents *)0;
1001e72d8d2Sderaadt 
1011e72d8d2Sderaadt     } while (!_findnext (hFile, &find_buf));
1021e72d8d2Sderaadt 
1031e72d8d2Sderaadt   dirp->dd_cp = dirp->dd_contents;
1041e72d8d2Sderaadt 
1051e72d8d2Sderaadt   _findclose(hFile);
1061e72d8d2Sderaadt 
1071e72d8d2Sderaadt   return dirp;
1081e72d8d2Sderaadt }
1091e72d8d2Sderaadt 
1101e72d8d2Sderaadt 
1111e72d8d2Sderaadt void
closedir(DIR * dirp)1121e72d8d2Sderaadt closedir (DIR *dirp)
1131e72d8d2Sderaadt {
1141e72d8d2Sderaadt   free_dircontents (dirp->dd_contents);
1151e72d8d2Sderaadt   free ((char *) dirp);
1161e72d8d2Sderaadt }
1171e72d8d2Sderaadt 
1181e72d8d2Sderaadt 
1191e72d8d2Sderaadt struct direct *
readdir(DIR * dirp)1201e72d8d2Sderaadt readdir (DIR *dirp)
1211e72d8d2Sderaadt {
1221e72d8d2Sderaadt   static struct direct dp;
1231e72d8d2Sderaadt 
1241e72d8d2Sderaadt   if (dirp->dd_cp == (struct _dircontents *)0)
1251e72d8d2Sderaadt     return (struct direct *)0;
1261e72d8d2Sderaadt   dp.d_namlen = dp.d_reclen =
1271e72d8d2Sderaadt     strlen (strcpy (dp.d_name, dirp->dd_cp->_d_entry));
1281e72d8d2Sderaadt #if 0 /* JB */
1291e72d8d2Sderaadt   strlwr (dp.d_name);		/* JF */
1301e72d8d2Sderaadt #endif
1311e72d8d2Sderaadt   dp.d_ino = 0;
1321e72d8d2Sderaadt   dirp->dd_cp = dirp->dd_cp->_d_next;
1331e72d8d2Sderaadt   dirp->dd_loc++;
1341e72d8d2Sderaadt 
1351e72d8d2Sderaadt   return &dp;
1361e72d8d2Sderaadt }
1371e72d8d2Sderaadt 
1381e72d8d2Sderaadt 
1391e72d8d2Sderaadt void
seekdir(DIR * dirp,long off)1401e72d8d2Sderaadt seekdir (DIR *dirp, long off)
1411e72d8d2Sderaadt {
1421e72d8d2Sderaadt   long i = off;
1431e72d8d2Sderaadt   struct _dircontents *dp;
1441e72d8d2Sderaadt 
1451e72d8d2Sderaadt   if (off < 0)
1461e72d8d2Sderaadt     return;
1471e72d8d2Sderaadt   for (dp = dirp->dd_contents; --i >= 0 && dp; dp = dp->_d_next)
1481e72d8d2Sderaadt     ;
1491e72d8d2Sderaadt   dirp->dd_loc = off - (i + 1);
1501e72d8d2Sderaadt   dirp->dd_cp = dp;
1511e72d8d2Sderaadt }
1521e72d8d2Sderaadt 
1531e72d8d2Sderaadt 
1541e72d8d2Sderaadt long
telldir(DIR * dirp)1551e72d8d2Sderaadt telldir (DIR *dirp)
1561e72d8d2Sderaadt {
1571e72d8d2Sderaadt   return dirp->dd_loc;
1581e72d8d2Sderaadt }
1591e72d8d2Sderaadt 
1601e72d8d2Sderaadt 
1611e72d8d2Sderaadt /* Garbage collection */
1621e72d8d2Sderaadt 
1631e72d8d2Sderaadt static void
free_dircontents(struct _dircontents * dp)1641e72d8d2Sderaadt free_dircontents (struct _dircontents *dp)
1651e72d8d2Sderaadt {
1661e72d8d2Sderaadt   struct _dircontents *odp;
1671e72d8d2Sderaadt 
1681e72d8d2Sderaadt   while (dp)
1691e72d8d2Sderaadt     {
1701e72d8d2Sderaadt       if (dp->_d_entry)
1711e72d8d2Sderaadt 	free (dp->_d_entry);
1721e72d8d2Sderaadt       dp = (odp = dp)->_d_next;
1731e72d8d2Sderaadt       free (odp);
1741e72d8d2Sderaadt     }
1751e72d8d2Sderaadt }
1761e72d8d2Sderaadt 
1771e72d8d2Sderaadt 
1781e72d8d2Sderaadt #ifdef TEST
1791e72d8d2Sderaadt 
1801e72d8d2Sderaadt void main (int argc, char *argv[]);
1811e72d8d2Sderaadt 
1821e72d8d2Sderaadt void
main(int argc,char * argv[])1831e72d8d2Sderaadt main (int argc, char *argv[])
1841e72d8d2Sderaadt {
1851e72d8d2Sderaadt   static DIR *directory;
1861e72d8d2Sderaadt   struct direct *entry = (struct direct *)0;
1871e72d8d2Sderaadt 
1881e72d8d2Sderaadt   char *name = "";
1891e72d8d2Sderaadt 
1901e72d8d2Sderaadt   if (argc > 1)
1911e72d8d2Sderaadt     name = argv[1];
1921e72d8d2Sderaadt 
1931e72d8d2Sderaadt   directory = opendir (name);
1941e72d8d2Sderaadt 
1951e72d8d2Sderaadt   if (!directory)
1961e72d8d2Sderaadt     {
1971e72d8d2Sderaadt       fprintf (stderr, "can't open directory `%s'.\n", name);
1981e72d8d2Sderaadt       exit (2);
1991e72d8d2Sderaadt     }
2001e72d8d2Sderaadt 
2011e72d8d2Sderaadt   while (entry = readdir (directory))
2021e72d8d2Sderaadt     printf ("> %s\n", entry->d_name);
2031e72d8d2Sderaadt 
2041e72d8d2Sderaadt   printf ("done.\n");
2051e72d8d2Sderaadt }
2061e72d8d2Sderaadt 
2071e72d8d2Sderaadt #endif /* TEST */
2081e72d8d2Sderaadt 
2091e72d8d2Sderaadt /*
2101e72d8d2Sderaadt  * Local Variables:
2111e72d8d2Sderaadt  * mode:C
2121e72d8d2Sderaadt  * ChangeLog:ChangeLog
2131e72d8d2Sderaadt  * compile-command:make
2141e72d8d2Sderaadt  * End:
2151e72d8d2Sderaadt  */
216