naughton@sun.soe.clarkson.edu (Patrick Naughton) (02/11/88)
I saw some comment about getting directories under turbo-c on comp.sys.ibm.pc.digest. I wrote this years ago for Turbo-Pascal and converted it to Turbo-C recently. There are limited docs in the form of a comment in the header file, dir.h. The test program dirtest.c should be enough to show how to use the routines in dir.c. Have fun... -Patrick (naughton@sun.soe.clarkson.edu) #!/bin/sh # This is a shell archive, meaning: # 1. Remove everything above the #!/bin/sh line. # 2. Save the resulting text in a file. # 3. Execute the file with /bin/sh (not csh) to create the files: # dir.c # dir.h # dirtest.c # This archive created: Thu Feb 11 02:18:10 1988 export PATH; PATH=/bin:$PATH if test -f 'dir.c' then echo shar: over-writing existing file "'dir.c'" fi cat << \SHAR_EOF > 'dir.c' /* * * DIR.C - Directory manipulation routines. * * Copyright (c) 1988 - Patrick Naughton - (naughton@sun.soe.clarkson.edu) * 23 Pleasant Street, #3 - Potsdam, NY 13676 - (315) 265-2853 * * This code may be freely copied and distributed without charge. * If you change and redistribute it please make a note below. * * Revision history: * 8-Feb-88: (PJN) Created. * */ #include <stdio.h> #include <string.h> #include <alloc.h> #include <dos.h> #include <dir.h> #include "dir.h" typedef int boolean; #define TRUE 1 #define FALSE 0 char getDrive(void) { return((char) getdisk() + 'A'); } void setDrive(char drive) { setdisk((int) (drive - 'A')); } long diskSpace(char drive) { struct dfree d; getdfree((int) (drive - 'A') + 1, &d); return((long) d.df_avail * d.df_bsec * d.df_sclus); } void volumeLabel(char drive, char *vl) { struct ffblk dtArea; boolean done; char *path = "x:\\*.*"; path[0] = drive; done = findfirst(path, &dtArea, FA_LABEL); while (!done) { if ((dtArea.ff_attrib & FA_LABEL)) { strcpy(vl, dtArea.ff_name); if (strlen(vl) > 8) strcpy(&vl[8], &vl[9]); return; } done = findnext(&dtArea); } vl = "missing"; } void getEntry(struct fStruct **this1, struct dStruct *d, struct ffblk *dtArea) { struct fStruct *f; f = (struct fStruct *) malloc(sizeof(struct fStruct)); strcpy(f->filename, dtArea->ff_name); if (dtArea->ff_attrib & FA_DIREC) { f->subDir = TRUE; f->size = 0; d->dirCount++; } else { f->subDir = FALSE; f->size = dtArea->ff_fsize; d->fileCount++; d->totalSize = d->totalSize + f->size; } f->hours = dtArea->ff_ftime >> 11; if (f->hours > 11) f->pm = TRUE; else f->pm = FALSE; if (f->hours > 12) f->hours -= 12; f->minutes = (dtArea->ff_ftime >> 5) & 0x3f; f->seconds = (dtArea->ff_ftime << 1) & 0x3f; f->mm = (dtArea->ff_fdate >> 5) & 0xf; f->dd = dtArea->ff_fdate & 0x1f; f->yy = 80 + (dtArea->ff_fdate >> 9); f->next = NULL; *this1 = f; } boolean getDir(char *pattern, struct dStruct *d) { struct ffblk dtArea; struct fStruct *entryPtr; int i; boolean done; char *drive = "x:"; char dir[MAXPATH]; char *name = "????????"; char *ext = ".???"; strcpy(d->path, pattern); strupr(d->path); i = fnsplit(d->path, drive, dir, name, ext); if (!(i & DRIVE)) drive[0] = getDrive(); if (!(i & DIRECTORY)) { getcurdir(1 + (int) (drive[0] - 'A'), &dir[1]); dir[0] = '\\'; dir[strlen(dir) + 1] = '\0'; dir[strlen(dir)] = '\\'; } if (!(i & FILENAME)) name = "*"; if (!(i & EXTENSION)) ext = ".*"; fnmerge(d->path, drive, dir, name, ext); volumeLabel(drive[0], d->volume); d->freespace = diskSpace(drive[0]); d->totalSize = 0; d->fileCount = 0; d->dirCount = 0; done = findfirst(d->path, &dtArea, FA_DIREC); if (done) return(FALSE); getEntry(&(d->entries), d, &dtArea); entryPtr = d->entries; while (!done) { done = findnext(&dtArea); if (!done) { getEntry(&(entryPtr->next), d, &dtArea); entryPtr = entryPtr->next; } }; return(TRUE); } void dumpEntry(struct fStruct *f) { if (f->next != NULL) dumpEntry(f->next); free(f); } void dumpDir(struct dStruct *d) { if (d->entries != NULL) dumpEntry(d->entries); d->entries = NULL; d->volume[0] = '\0'; d->freespace = 0; d->totalSize = 0; d->dirCount = 0; d->fileCount = 0; d->path[0] = '\0'; } boolean getNiceDir(char *pattern, struct dStruct *d) { boolean i; struct fStruct *temp; i = getDir(pattern, d); if (i) { if (!strcmp(d->entries->filename, ".")) { temp = d->entries->next; free(d->entries); d->entries = temp; d->dirCount--; } if (!strcmp(d->entries->filename, "..")) strcpy(d->entries->filename, "<parent>"); } return(i); } SHAR_EOF if test -f 'dir.h' then echo shar: over-writing existing file "'dir.h'" fi cat << \SHAR_EOF > 'dir.h' /* * * DIR.H - Directory manipulation declarations. * * Copyright (c) 1988 - Patrick Naughton - (naughton@sun.soe.clarkson.edu) * 23 Pleasant Street, #3 - Potsdam, NY 13676 - (315) 265-2853 * * This code may be freely copied and distributed without charge. * If you change and redistribute it please make a note below. * * Revision history: * 8-Feb-88: (PJN) Created. * * getDrive() returns a char for the current drive (i.e. A, B, C...) * setDrive('A') would set the current drive to A:. * diskSpace('C') would return the number of bytes remaining on C: * volumeLabel('C', vl) puts the volume lable from C: in the string vl. * getDir("C:\*.c", &d) puts the directory of all .c files in the root of C:. * dumpDir(&d) cleans up the dynamic memory used by getDir(). * getNiceDir() deletes "." and replaces ".." with "<parent>". * */ struct fStruct { char filename[13]; int subDir, pm; int hours, minutes, seconds, dd, mm, yy; long size; struct fStruct *next; }; struct dStruct { char volume[13]; char path[80]; long freespace, totalSize; int dirCount, fileCount; struct fStruct *entries; }; char getDrive(void); void setDrive(char drive); long diskSpace(char drive); void volumeLabel(char drive, char *vl); int getDir(char *pattern, struct dStruct *d); void dumpDir(struct dStruct *d); int getNiceDir(char *pattern, struct dStruct *d); SHAR_EOF if test -f 'dirtest.c' then echo shar: over-writing existing file "'dirtest.c'" fi cat << \SHAR_EOF > 'dirtest.c' /* * * DIRTEST.C - Test the directory manipulation routines. * * Copyright (c) 1988 - Patrick Naughton - (naughton@sun.soe.clarkson.edu) * 23 Pleasant Street, #3 - Potsdam, NY 13676 - (315) 265-2853 * * This code may be freely copied and distributed without charge. * If you change and redistribute it please make a note below. * * Revision history: * 8-Feb-88: (PJN) Created. * */ #include <stdio.h> #include <string.h> #include <alloc.h> #include <dos.h> #include <dir.h> #include "dir.h" typedef int boolean; #define TRUE 1 #define FALSE 0 void showDir(struct dStruct *d) { struct fStruct *nextPtr; printf("Volume %s\n", d->volume); printf("Directory of %s\n", d->path); nextPtr = d->entries; while(nextPtr) { printf("%14s ", nextPtr->filename); if (nextPtr->subDir) puts(" <dir>"); else { printf("%7ld ", nextPtr->size); if (nextPtr->mm < 10) printf(" "); printf("%d/", nextPtr->mm); if (nextPtr->dd < 10) printf("0"); printf("%d/", nextPtr->dd); if (nextPtr->yy < 10) printf("0"); printf("%d ", nextPtr->yy); if (nextPtr->hours < 10) printf(" "); printf("%d:", nextPtr->hours); if (nextPtr->minutes < 10) printf("0"); printf("%d:", nextPtr->minutes); if (nextPtr->seconds < 10) printf("0"); printf("%d", nextPtr->seconds); if (nextPtr->pm) puts("p"); else puts("a"); } nextPtr = nextPtr->next; } printf("%d files and %d directories using %ld bytes out of %ld remaining.\n", d->fileCount, d->dirCount, d->totalSize, d->freespace); } main(int argc, char *argv[]) { struct dStruct dir; char *path = " "; if (argc == 1) path = "*.*"; else path = argv[1]; if (!getNiceDir(path, &dir)) { puts(path); puts("Path not found!"); } else { showDir(&dir); dumpDir(&dir); } } SHAR_EOF # End of shell archive exit 0