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