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 /* Everything non trivial in this code is from: @(#)msd_dir.c 1.4 15 87/11/06. A public domain implementation of BSD directory routines 16 for MS-DOS. Written by Michael Rendell ({uunet,utai}michael@garfield), 17 August 1897 */ 18 19 20 #include <io.h> 21 #include <stdio.h> 22 #include <stdlib.h> 23 #include <string.h> 24 #include <sys/types.h> 25 #include <sys/stat.h> 26 27 #include <dos.h> 28 29 #include <ndir.h> 30 31 static void free_dircontents (struct _dircontents *); 32 33 /* find ALL files! */ 34 #define ATTRIBUTES (_A_RDONLY | _A_HIDDEN | _A_SYSTEM | _A_SUBDIR) 35 36 37 38 DIR * 39 opendir (const char *name) 40 { 41 struct _finddata_t find_buf; 42 DIR *dirp; 43 struct _dircontents *dp; 44 char name_buf[_MAX_PATH + 1]; 45 char *slash = ""; 46 long hFile; 47 48 if (!name) 49 name = ""; 50 else if (*name) 51 { 52 const char *s; 53 int l = strlen (name); 54 55 s = name + l - 1; 56 if ( !(l == 2 && *s == ':') && *s != '\\' && *s != '/') 57 slash = "/"; /* save to insert slash between path and "*.*" */ 58 } 59 60 strcat (strcat (strcpy (name_buf, name), slash), "*.*"); 61 62 dirp = (DIR *) malloc (sizeof (DIR)); 63 if (dirp == (DIR *)0) 64 return (DIR *)0; 65 66 dirp->dd_loc = 0; 67 dirp->dd_contents = dirp->dd_cp = (struct _dircontents *) 0; 68 69 if ((hFile = _findfirst (name_buf, &find_buf)) < 0) 70 { 71 free (dirp); 72 return (DIR *)0; 73 } 74 75 do 76 { 77 dp = (struct _dircontents *) malloc (sizeof (struct _dircontents)); 78 if (dp == (struct _dircontents *)0) 79 { 80 free_dircontents (dirp->dd_contents); 81 return (DIR *)0; 82 } 83 84 dp->_d_entry = malloc (strlen (find_buf.name) + 1); 85 if (dp->_d_entry == (char *)0) 86 { 87 free (dp); 88 free_dircontents (dirp->dd_contents); 89 return (DIR *)0; 90 } 91 92 if (dirp->dd_contents) 93 dirp->dd_cp = dirp->dd_cp->_d_next = dp; 94 else 95 dirp->dd_contents = dirp->dd_cp = dp; 96 97 strcpy (dp->_d_entry, find_buf.name); 98 99 dp->_d_next = (struct _dircontents *)0; 100 101 } while (!_findnext (hFile, &find_buf)); 102 103 dirp->dd_cp = dirp->dd_contents; 104 105 _findclose(hFile); 106 107 return dirp; 108 } 109 110 111 void 112 closedir (DIR *dirp) 113 { 114 free_dircontents (dirp->dd_contents); 115 free ((char *) dirp); 116 } 117 118 119 struct direct * 120 readdir (DIR *dirp) 121 { 122 static struct direct dp; 123 124 if (dirp->dd_cp == (struct _dircontents *)0) 125 return (struct direct *)0; 126 dp.d_namlen = dp.d_reclen = 127 strlen (strcpy (dp.d_name, dirp->dd_cp->_d_entry)); 128 #if 0 /* JB */ 129 strlwr (dp.d_name); /* JF */ 130 #endif 131 dp.d_ino = 0; 132 dirp->dd_cp = dirp->dd_cp->_d_next; 133 dirp->dd_loc++; 134 135 return &dp; 136 } 137 138 139 void 140 seekdir (DIR *dirp, long off) 141 { 142 long i = off; 143 struct _dircontents *dp; 144 145 if (off < 0) 146 return; 147 for (dp = dirp->dd_contents; --i >= 0 && dp; dp = dp->_d_next) 148 ; 149 dirp->dd_loc = off - (i + 1); 150 dirp->dd_cp = dp; 151 } 152 153 154 long 155 telldir (DIR *dirp) 156 { 157 return dirp->dd_loc; 158 } 159 160 161 /* Garbage collection */ 162 163 static void 164 free_dircontents (struct _dircontents *dp) 165 { 166 struct _dircontents *odp; 167 168 while (dp) 169 { 170 if (dp->_d_entry) 171 free (dp->_d_entry); 172 dp = (odp = dp)->_d_next; 173 free (odp); 174 } 175 } 176 177 178 #ifdef TEST 179 180 void main (int argc, char *argv[]); 181 182 void 183 main (int argc, char *argv[]) 184 { 185 static DIR *directory; 186 struct direct *entry = (struct direct *)0; 187 188 char *name = ""; 189 190 if (argc > 1) 191 name = argv[1]; 192 193 directory = opendir (name); 194 195 if (!directory) 196 { 197 fprintf (stderr, "can't open directory `%s'.\n", name); 198 exit (2); 199 } 200 201 while (entry = readdir (directory)) 202 printf ("> %s\n", entry->d_name); 203 204 printf ("done.\n"); 205 } 206 207 #endif /* TEST */ 208 209 /* 210 * Local Variables: 211 * mode:C 212 * ChangeLog:ChangeLog 213 * compile-command:make 214 * End: 215 */ 216