|
|
1.1 ! root 1: /* library:dosdir.c 1.3 */ ! 2: #include "sccsid.h" ! 3: VERSION(@(#)library:dosdir.c 1.3) ! 4: ! 5: /* ! 6: * dir.c - contains routines which behave (hopefully) like the ! 7: * similar versions on 4.2 BSD. ! 8: * ! 9: */ ! 10: #include <dos.h> ! 11: #include <errno.h> ! 12: #include <dir.h> ! 13: #include <malloc.h> ! 14: #include <errno.h> ! 15: #define NULL (char *)0 ! 16: ! 17: #define ROOTFIX ! 18: ! 19: /* ! 20: * opendir - opens given directory and reads its contents into memory. ! 21: * Other functions use this data or the DIR structure to do their work. ! 22: */ ! 23: DIR * ! 24: opendir(dirname) ! 25: char *dirname; ! 26: { ! 27: struct direct **namelist; ! 28: DIR *dirptr; ! 29: ! 30: dirptr = (DIR *)calloc(1, sizeof(DIR)); ! 31: if(dirptr == (DIR *)0) ! 32: { ! 33: errno = ENOMEM; ! 34: return((DIR *)0); ! 35: } ! 36: dirptr->d_magic = DMAGIC; ! 37: dirptr->d_pos = 0; ! 38: #ifdef ROOTFIX ! 39: again: ! 40: #endif ! 41: dirptr->d_length = scandir(dirname, &(dirptr->namelist), ! 42: (int (*)())0, (int (*)())0); ! 43: if(dirptr->d_length < 0) ! 44: { ! 45: #ifdef ROOTFIX ! 46: static char *root = "a:"; ! 47: ! 48: /* DOS quirk: there's no "." in root directory. vqh */ ! 49: if (dirname[0]=='.' && dirname[1] == '\0') { ! 50: *root = (bdos(0x19,0,0) & 0xf)+ 'a'; /* current disk */ ! 51: dirname = root; ! 52: goto again; ! 53: } ! 54: #endif ! 55: free((char *)dirptr); ! 56: return((DIR *)0); ! 57: } ! 58: return(dirptr); ! 59: } ! 60: ! 61: /* ! 62: * readdir - returns the next directory structure from the list and ! 63: * updates values in the DIR structure. ! 64: */ ! 65: struct direct * ! 66: readdir(dirptr) ! 67: DIR *dirptr; ! 68: { ! 69: if(dirptr->d_magic != DMAGIC) ! 70: { ! 71: errno = ENOTDIR; ! 72: return((struct direct *)0); ! 73: } ! 74: if(dirptr->d_pos >= dirptr->d_length) ! 75: { ! 76: errno = ENFILE; ! 77: return((struct direct *)0); ! 78: } ! 79: return(dirptr->namelist[dirptr->d_pos++]); ! 80: } ! 81: ! 82: /* ! 83: * telldir - return the current position of the directory. ! 84: */ ! 85: long ! 86: telldir(dirptr) ! 87: DIR *dirptr; ! 88: { ! 89: if(dirptr->d_magic != DMAGIC) ! 90: { ! 91: errno = ENOTDIR; ! 92: return(-1L); ! 93: } ! 94: return((long)dirptr->d_pos); ! 95: } ! 96: ! 97: /* ! 98: * seekdir - position the given DIR stream to position given. ! 99: */ ! 100: seekdir(dirptr, loc) ! 101: DIR *dirptr; ! 102: long loc; ! 103: { ! 104: if(dirptr->d_magic != DMAGIC) ! 105: { ! 106: errno = ENOTDIR; ! 107: return(-1); ! 108: } ! 109: if(loc > (long)dirptr->d_length) ! 110: { ! 111: errno = EINVAL; ! 112: return(-1); ! 113: } ! 114: dirptr->d_pos = (int)loc; ! 115: return(0); ! 116: } ! 117: ! 118: /* ! 119: * rewinddir - rewind given DIR to beginning ! 120: */ ! 121: rewinddir(dirptr) ! 122: DIR *dirptr; ! 123: { ! 124: if(dirptr->d_magic != DMAGIC) ! 125: { ! 126: errno = ENOTDIR; ! 127: return(-1); ! 128: } ! 129: dirptr->d_pos = 0; ! 130: return(0); ! 131: } ! 132: ! 133: /* ! 134: * closedir - close given directory. destroy given DIR struct so we ! 135: * know it is closed. ! 136: */ ! 137: closedir(dirptr) ! 138: DIR *dirptr; ! 139: { ! 140: if(dirptr->d_magic != DMAGIC) ! 141: { ! 142: errno = ENOTDIR; ! 143: return(-1); ! 144: } ! 145: dirptr->d_magic = ~DMAGIC; /* mess it up a little */ ! 146: freedir(dirptr->namelist); ! 147: free(dirptr); ! 148: return(0); ! 149: } ! 150: ! 151: /* XXXXXX scandir.c below here XXXXXXX */ ! 152: ! 153: static struct direct buffer; ! 154: ! 155: scandir(dirname, namelist, select, compar) ! 156: char *dirname; ! 157: struct direct *(*namelist[]); ! 158: int (*select)(); ! 159: int (*compar)(); ! 160: { ! 161: register struct direct **names; ! 162: register int dirno; ! 163: union REGS sregs, oregs; ! 164: struct SREGS segregs; ! 165: char *ptr, *paths; ! 166: ! 167: names = (struct direct **)calloc(1, sizeof(struct direct *)); ! 168: paths = calloc(128, 1); ! 169: if(names == (struct direct **)0 || paths == NULL) ! 170: { ! 171: errno = ENOMEM; ! 172: return(-1); ! 173: } ! 174: strcpy(paths, dirname); ! 175: ptr = &paths[strlen(paths) - 1]; ! 176: if(*ptr == '/' || *ptr == '\\') ! 177: *ptr = '\0'; ! 178: strcat(paths, "/*.*"); ! 179: ! 180: segread(&segregs); /* set up segment registers */ ! 181: ptr = (char *)&buffer; ! 182: sregs.h.ah = 0x1a; /* set DTA to buffer */ ! 183: sregs.x.dx = FP_OFF(ptr); /* offset */ ! 184: #ifdef M_I86LM ! 185: segregs.ds = FP_SEG(ptr); /* pointer in large model */ ! 186: #endif /* M_I86LM */ ! 187: intdosx(&sregs, &oregs, &segregs); ! 188: sregs.x.ax = 0x4e00; /* search for first */ ! 189: sregs.x.cx = 0x1f; /* include all attributes */ ! 190: sregs.x.dx = FP_OFF(paths); /* offset to path */ ! 191: #ifdef M_I86LM ! 192: segregs.ds = FP_SEG(paths); /* segment for large model */ ! 193: #endif /* M_I86LM */ ! 194: intdosx(&sregs, &oregs, &segregs); ! 195: if(oregs.x.cflag) ! 196: { ! 197: errno = ENOTDIR; ! 198: return(-1); ! 199: } ! 200: sregs.x.ax = 0x4f00; /* search for next */ ! 201: for(dirno = 0; oregs.x.cflag == 0; intdosx(&sregs, &oregs, &segregs)) ! 202: { ! 203: for(ptr = buffer.d_name; *ptr; ptr++) ! 204: *ptr = tolower(*ptr); ! 205: if(select == (int (*)())0 || (*select)(&buffer)) ! 206: { ! 207: names = (struct direct **)realloc((char *)names, ! 208: (dirno + 2)*sizeof(struct direct *)); ! 209: if(names == (struct direct **)0) ! 210: { ! 211: errno = ENOMEM; ! 212: return(-1); ! 213: } ! 214: names[dirno] = (struct direct *)calloc(1, ! 215: sizeof(struct direct)); ! 216: if(names[dirno] == (struct direct *)0) ! 217: { ! 218: errno = ENOMEM; ! 219: return(-1); ! 220: } ! 221: *names[dirno] = buffer; ! 222: names[++dirno] = (struct direct *)0; ! 223: } ! 224: } ! 225: ! 226: if(compar != (int (*)())0) ! 227: qsort((char *)names, dirno, sizeof(char *), compar); ! 228: ! 229: *namelist = names; ! 230: free(paths); /* free temp space */ ! 231: return(dirno); ! 232: } ! 233: ! 234: freedir(dirs) ! 235: register struct direct **dirs; ! 236: { ! 237: register int ii; ! 238: ! 239: if(dirs == (struct direct **)0) ! 240: return(-1); ! 241: for(ii = 0; dirs[ii] != (struct direct *)0; ii++) ! 242: free(dirs[ii]); ! 243: free(dirs); ! 244: return(0); ! 245: } ! 246: ! 247: alphasort(dirptr1, dirptr2) ! 248: struct direct **dirptr1, **dirptr2; ! 249: { ! 250: return(strcmp((*dirptr1)->d_name, (*dirptr2)->d_name)); ! 251: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.