Category : Files from Magazines
Archive   : CGAZ2-4.ZIP
Filename : DCHART.C
Output of file : DCHART.C contained in archive : CGAZ2-4.ZIP
* *
* Purpose: illustrate use of a tree of structures and how *
* to recursively walk the tree *
* Author: John Rex (c) Copyright 1988 *
* Compiler: Validated for DeSmet V2.61, MSC 5.0 *
* Memory Model: Pointers to data must be 32-bit *
* Date: October, 1987 *
***************************************************************/
#define DESMET 0
#define MSC 1
#include
#if MSC
#include
#include
#endif
#if DESMET
char *malloc();
#endif
/* the key structure - it holds the directory nodes */
struct dir {
char *name; /* the directory's name */
struct dir *sister; /* its sister (if any) */
struct dir *daughter; /* its daughter (if any) */
};
main (argc, argv)
int argc;
char **argv;
{
struct dir *root; /* will be our root struct */
struct dir *dir_setup(); /* returns an empty struct */
int add_subs();
void print_node(), new_dta(), old_dta();
if (argc != 2) { /* check command line */
fputs ("Usage is: dchart drive\n", stderr);
exit(0);
}
new_dta();
/* setup root directory */
root = dir_setup();
root -> name = malloc(4); /* name will be like "a:\" */
root -> name[0] = argv[1][0]; /* get drive character */
strcpy(root -> name + 1, ":\\");
/* now build up the directory tree */
if (add_subs(root -> name, root) == 0)
fputs("Invalid directory\n", stderr);
/* and print the tree */
else
print_node(root -> name, root);
old_dta();
}
int add_subs(ppath, droot) /* add subdirectories to a node */
char *ppath; /* the partial path at present */
struct dir *droot; /* the node to add on to */
{
char pbuffer[80]; /* work area for path names */
char nbuffer[13]; /* work area for dir name */
int first_match(), next_match(); /* directory look up */
struct dir *dptr; /* a temporary */
int error;
/* first, find all the sisters at the next level down */
strcpy(pbuffer, ppath);
strcat(pbuffer, "*.*");
error = first_match(pbuffer, nbuffer);
if ( error == 1) { /* found one! */
droot -> daughter = dir_setup(); /* place to store 1st one */
dptr = droot -> daughter;
/* save name */
dptr -> name = malloc(strlen(nbuffer) + 1);
strcpy(dptr -> name, nbuffer);
while (next_match (nbuffer)) { /* while more sisters ... */
dptr -> sister = dir_setup();
dptr = dptr -> sister;
dptr -> name = malloc(strlen(nbuffer) + 1);
strcpy(dptr -> name, nbuffer);
}
}
else if (error == 0)
return(1); /* no matches found */
else
return(0); /* bad path */
/* now look at each of the sisters and check for daughters */
for (dptr = droot -> daughter; dptr != NULL; dptr = dptr -> sister)
{
strcpy (pbuffer, ppath);
strcat (pbuffer, dptr -> name);
strcat (pbuffer, "\\");
add_subs (pbuffer, dptr);
}
return (1);
}
void print_node (ppath, droot) /* print node and its subdirectories */
char *ppath; /* the partial path at present */
struct dir *droot; /* the node to print */
{
struct dir *dptr;
char pbuffer[80];
/* print our name */
fputs (ppath, stdout);
fputs ("\n", stdout);
/* and now our kids */
for (dptr = droot -> daughter; dptr != NULL; dptr = dptr -> sister)
{
strcpy(pbuffer, ppath);
strcat(pbuffer, dptr -> name);
strcat(pbuffer, "\\");
print_node(pbuffer, dptr);
}
}
struct dir *dir_setup() /* return ptr to empty struct */
{
struct dir *ptr;
/* get a ptr to an appropriate block of memory */
ptr = (struct dir *) malloc(sizeof(struct dir));
/* initialize it */
ptr -> name = NULL;
ptr -> sister = NULL;
ptr -> daughter = NULL;
/* and return the pointer */
return(ptr);
}
/* a union that allows for two ways to access 32 bits */
typedef union {
char *ptr; /* as a pointer */
struct { /* or as two unsigned words */
unsigned offset; /* an offset ... */
unsigned segment; /* ... and its segment */
} split;
} bits_32;
unsigned dptr_off(x) /* return offset portion of a pointer */
char *x;
{
bits_32 y;
y.ptr = x;
return(y.split.offset);
}
unsigned dptr_seg(x) /* return segment part of a data pointer */
char *x;
{
bits_32 y;
y.ptr = x;
return(y.split.segment);
}
#define DOS_CALL 0x21
#define SET_DTA 0x1A
#define GET_DTA 0x2f
#define FIRST_MATCH 0x4E
#define NEXT_MATCH 0x4f
/* our local dta */
static unsigned old_dta_segment;
static unsigned old_dta_offset;
static char dta[128];
/* and some locations in our dta */
#define FILE_TYPE *(dta+21)
#define FILE_NAME dta+30
/* access to DOS */
#if DESMET
extern unsigned _rax, _rbx, _rcx, _rdx;
extern unsigned _rsi, _rdi, _res, _rds;
extern char _carryf, _zerof;
void _doint();
#define AH_IN *( ((char *) &_rax) + 1)
#define CX_IN _rcx
#define DX_IN _rdx
#define DS_IN _rds
#define AX_OUT _rax
#define BX_OUT _rbx
#define ES_OUT _res
#define CARRY_OUT _carryf
#define GO_DOS(x) _doint(x)
#endif
#if MSC
union REGS inregs; /* MSC's structures */
union REGS outregs;
struct SREGS segregs;
#define AH_IN inregs.h.ah
#define CX_IN inregs.x.cx
#define DX_IN inregs.x.dx
#define DS_IN segregs.ds
#define AX_OUT outregs.x.ax
#define BX_OUT outregs.x.bx
#define ES_OUT segregs.es
#define CARRY_OUT outregs.x.cflag
#define GO_DOS(x) int86x(x,&inregs,&outregs,&segregs)
#endif
void new_dta() /* tell DOS about our local DTA */
{
unsigned dptr_off(), dptr_seg();
AH_IN = GET_DTA;
GO_DOS(DOS_CALL);
old_dta_segment = ES_OUT;
old_dta_offset = BX_OUT;
DS_IN = dptr_seg(dta);
DX_IN = dptr_off(dta);
AH_IN = SET_DTA;
GO_DOS(DOS_CALL);
}
void old_dta() /* restore previous dta */
{
DS_IN = old_dta_segment;
DX_IN = old_dta_offset;
AH_IN = SET_DTA;
GO_DOS(DOS_CALL);
}
int first_match(file, buffer) /* look for first match */
char *file; /* pattern to search for */
char *buffer; /* where to put the answer */
{
unsigned dptr_seg(), dptr_off();
int n_match(), check_match();
AH_IN = FIRST_MATCH;
CX_IN = 0x10; /* subdirs */
DS_IN = dptr_seg(file);
DX_IN = dptr_off(file);
GO_DOS(DOS_CALL);
if (CARRY_OUT) { /* ? failure */
if (AX_OUT == 2)
return(-1); /* bad path */
else
return(0); /* no matches */
}
else {
while (check_match() == 0)
if (n_match(buffer) == 0)
return(0);
strcpy(buffer, FILE_NAME);
return(1);
}
}
int next_match(buffer)
char *buffer;
{
int n_match(), check_match();
if (n_match(buffer) == 0)
return(0);
while (check_match() == 0)
if (n_match(buffer) == 0)
return(0);
return(1);
}
int n_match(buffer) /* subsequent match */
char *buffer;
{
AH_IN = NEXT_MATCH;
GO_DOS(DOS_CALL);
if (CARRY_OUT)
return(0);
else {
strcpy(buffer, FILE_NAME);
return(1);
}
}
int check_match() /* make sure the "directory" DOS found is ok */
{
if ((FILE_TYPE & 0x10) == 0 )
return(0); /* nope - it's really a file name */
else if (strchr(FILE_NAME , '.') != NULL)
return(0); /* nope - it's "." or ".." */
else
return(1);
}
Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!
This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.
But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/