1 /* 2 * Author: Bob Withers 3 * Copyright (c) 1993, All Rights Reserved 4 * 5 * NOTICE 6 * 7 * Permission to use, copy, modify, and distribute this software and 8 * its documentation for any purpose and without fee is hereby granted 9 * provided that the above copyright notice appears in all copies and 10 * that both the copyright notice and this permission notice appear in 11 * supporting documentation. 12 * 13 * The author makes no representations about the suitability of this 14 * software for any purpose. This software is provided ``as is'' 15 * without express or implied warranty. 16 */ 17 18 #include <stdlib.h> 19 #include <string.h> 20 21 #define INCL_DOSFILEMGR 22 #define INCL_DOSERRORS 23 #include <os2.h> 24 25 #include "dirent.h" 26 27 28 #define DIRENT_INCR 25 29 30 31 DIR *opendir(char *filename) 32 { 33 auto size_t len; 34 auto DIR *dirp; 35 auto char *p; 36 auto HDIR hdir; 37 38 #ifdef OS2_16 39 auto USHORT rc; /* for 16 bit OS/2 */ 40 auto FILEFINDBUF ff; 41 auto USHORT cnt; 42 #else 43 auto APIRET rc; /* for 32 bit OS/2 */ 44 auto FILEFINDBUF3 ff; 45 auto ULONG cnt; 46 #endif /* OS2_16 */ 47 48 if (NULL == filename || '\0' == filename[0]) 49 filename = "."; 50 51 dirp = malloc(sizeof(*dirp)); 52 if (NULL == dirp) 53 return(NULL); 54 55 len = strlen(filename); 56 dirp->dirname = malloc(len + 5); 57 if (NULL == dirp->dirname) 58 { 59 free(dirp); 60 return(NULL); 61 } 62 63 dirp->max_ent = 0; 64 dirp->tot_ent = 0; 65 dirp->cur_ent = 0; 66 dirp->entp = NULL; 67 strcpy(dirp->dirname, filename); 68 for (p = dirp->dirname; *p; ++p) 69 { 70 if ('/' == *p) 71 *p = '\\'; 72 } 73 74 if ('\\' != dirp->dirname[len - 1]) 75 strcat(dirp->dirname, "\\"); 76 77 strcat(dirp->dirname, "*.*"); 78 79 hdir = HDIR_SYSTEM; 80 cnt = 1; 81 rc = DosFindFirst(dirp->dirname, &hdir, 82 FILE_NORMAL | FILE_READONLY | FILE_HIDDEN | 83 FILE_SYSTEM | FILE_DIRECTORY | FILE_ARCHIVED, 84 &ff, sizeof(ff), &cnt, FIL_STANDARD); 85 86 while (NO_ERROR == rc) 87 { 88 auto struct dirent *entp; 89 90 if (dirp->tot_ent >= dirp->max_ent) 91 { 92 auto struct dirent **p; 93 94 dirp->max_ent += DIRENT_INCR; 95 p = realloc(dirp->entp, dirp->max_ent * sizeof(entp)); 96 if (NULL == p) 97 { 98 rc = ERROR_NOT_ENOUGH_MEMORY; 99 break; 100 } 101 102 dirp->entp = p; 103 } 104 105 entp = malloc(sizeof(*entp) + (size_t) ff.cchName); 106 if (NULL == entp) 107 { 108 rc = ERROR_NOT_ENOUGH_MEMORY; 109 break; 110 } 111 112 entp->d_ino = 0; 113 entp->d_off = dirp->tot_ent; 114 entp->d_namlen = (unsigned short) ff.cchName; 115 memcpy(entp->d_name, ff.achName, entp->d_namlen); 116 entp->d_name[entp->d_namlen] = '\0'; 117 dirp->entp[dirp->tot_ent++] = entp; 118 119 cnt = 1; 120 rc = DosFindNext(hdir, &ff, sizeof(ff), &cnt); 121 } 122 123 DosFindClose(hdir); 124 if (ERROR_NO_MORE_FILES == rc) 125 return(dirp); 126 127 closedir(dirp); 128 return(NULL); 129 } 130 131 132 struct dirent *readdir(DIR *dirp) 133 { 134 if (dirp->cur_ent < 0 || dirp->cur_ent >= dirp->tot_ent) 135 return(NULL); 136 137 return(dirp->entp[dirp->cur_ent++]); 138 } 139 140 141 long telldir(DIR *dirp) 142 { 143 return((long) dirp->cur_ent); 144 } 145 146 147 void seekdir(DIR *dirp, long loc) 148 { 149 dirp->cur_ent = (int) loc; 150 return; 151 } 152 153 154 void rewinddir(DIR *dirp) 155 { 156 dirp->cur_ent = 0; 157 return; 158 } 159 160 161 void closedir(DIR *dirp) 162 { 163 if (dirp) 164 { 165 if (dirp->dirname) 166 free(dirp->dirname); 167 168 if (dirp->entp) 169 { 170 register int i; 171 172 for (i = 0; i < dirp->tot_ent; ++i) 173 free(dirp->entp[i]); 174 175 free(dirp->entp); 176 } 177 } 178 179 return; 180 } 181