home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Zodiac Super OZ
/
MEDIADEPOT.ISO
/
FILES
/
16
/
FREEDOS.ZIP
/
FD_A4PRE.ZIP
/
SOURCE
/
MICROC.ZIP
/
TREE.C
< prev
next >
Wrap
C/C++ Source or Header
|
1995-06-23
|
8KB
|
319 lines
/*
tree - A graphical directory path lister.
Copyright (C) 1995 Robert C. Schanke
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*---------------------------- Include Files ------------------------------*/
#include <stdio.h>
#include <file.h>
#include "freedos.h"
/*--------------------------------- Defines -------------------------------*/
#define MAX_RECURSE 10
/*---------------------------- Global Variables ---------------------------*/
char current_dir[64]; /* String to hold the directory we are
currently in. */
int eol[MAX_RECURSE]; /* End of List marker for sub-dirs */
struct FF_block nextfile[MAX_RECURSE]; /* One ahead file buffers */
int lastlevel; /* 'How far in where we' marker */
char drive; /* Char for drive & file path */
/*------------------------ Start of Code ----------------------------------*/
/*
** Standard usage routine ...
*/
void usage (void) {
printp ("TREE", "Graphical display of recursive sub-directories.");
printu ("TREE", "[directory]");
exit (1);
}
/*
** print_list is the routine which draws the 'lines' for the subdirectories
*/
void print_list(char name[255], int level) {
int cnt; /* Our counter */
for (cnt=0; cnt < level; cnt++) /* move over to current level*/
if (!eol[cnt]) /* Are dirs from above? */
printf("│ "); /* Yeah, draw the line */
else
printf(" "); /* No, just space over */
if (!eol[level]) /* Are ther more files here? */
printf("├───"); /* Yeah, draw line down */
else
printf("└───"); /* No, just draw accross */
printf("%s\n",name); /* Print the name of the dir */
lastlevel = level; /* Set new last level */
}
/*
** build_tree routine is the heart of the program. It reads the directories
** into a one directory buffer. This buffer is so we can tell if we are
** at the last directory or not.
*/
void build_tree(char *dir, int recurse) {
char where[64]; /* working directory name II */
struct FF_block file; /* Working directory physical */
char cur_dir[64]; /* working directory name */
int cnt; /* counter */
strcpy(where,dir); /* copy passed dir to where */
strcat(where,"*.*"); /* append a *.* */
/*
** Get the first directory from this level. And set the end of list flag
** eol to 0 if end, -1 if more.
*/
eol[recurse] = findfirst(where, nextfile[recurse], DIRECTORY);
/*
** Keep reading until we find another sub directory. This will be
** the '..' directory.
*/
if (!eol[recurse])
do {
eol[recurse] = findnext (nextfile[recurse]);
} while ((nextfile[recurse].FF_attrib != DIRECTORY) && (!eol[recurse]));
/*
** Keep reading until we find another sub directory. This will be
** the first to place in our buffer.
*/
if (!eol[recurse])
do {
eol[recurse] = findnext(nextfile[recurse]);
} while ((nextfile[recurse].FF_attrib != DIRECTORY) && (!eol[recurse]));
else
printf("There are no sub-directories.\n");
/*
** Ok, if we didn't run out of subdirectories already, ie a hard disk
** with no subdirectories, lets go ahead and list them
*/
if (!eol[recurse])
/*
** While we aren't at the end of the first one lets keep going
*/
do {
/*
** get the next file from the buffer
*/
memcpy (file, nextfile[recurse], sizeof(file));
/*
** Read next directory, or stop if we run out of them
*/
do {
eol[recurse] = findnext (nextfile[recurse]);
} while ((nextfile[recurse].FF_attrib != DIRECTORY) && (!eol[recurse]));
/*
** Send the file to the print_list for formated output
*/
print_list(file.FF_name,recurse);
/*
** Copy the the directory to the variable cur_dir
*/
strcpy(cur_dir,dir);
/*
** Append the next directory to cur_dir
*/
strcat(cur_dir,file.FF_name);
/*
** Append an '\' and a NULL to cur_dir
*/
strcat(cur_dir,"\\\0");
/*
** Call build_dir again with the new cur_dir and new level
*/
build_tree(cur_dir,recurse+1);
} while (!eol[recurse]);
}
/*
** Initialize variables
*/
void init(void) {
/*
** Initialize variables
*/
eol[0] = 0;
lastlevel = 0;
}
/*
** Function to extract the volume label, and display the header
** of output
*/
void header(void) {
struct FF_block vol; /* Drive Volume structure */
char volume[13]; /* String for drives Volume */
int cnt; /* A counter */
char buf[6];
/*
** format the drive letter into the format x:\*.* where x is the drive letter.
*/
sprintf(buf,"%c:\*.*",drive);
/*
** Get the volume if the drive has one and put it into vol
*/
eol[0] = findfirst(buf, vol, VOLUME);
/*
** If there was a volume, lets get rid of the . and make it one
** continuous 11 character string/
*/
if (!eol[0]) {
if (strlen(vol.FF_name) > 8) {
for (cnt=0; cnt < 8; cnt++)
volume[cnt] = vol.FF_name[cnt];
for (cnt=9; cnt < 12; cnt++)
volume[cnt-1] = vol.FF_name[cnt];
} else
strcpy(volume,vol.FF_name);
volume[11] = '\0';
}
/*
** Ok, if we have a volume, let's print it out, otherwise don't
** worry about printint it out.
*/
if (!eol[0])
printf("Directory PATH listing for Volume %s\n%c:.\n",volume,drive);
else
printf("Directory PATH listing\n%c:.\n",drive);
}
/*
** The main function
*/
void main(int argc, char *argv[]) {
/*
** Did the user pass a /?
*/
if ((argv[1][0] == '/') && (argv[1][1] == '?'))
usage(); /* Yeah, so tell 'em how to use */
if (argc == 1) { /* Did they pass something else? */
getdir(current_dir); /* No, get current directory */
if (strlen(current_dir)==0) /* if nothing, we are in root */
strcpy(current_dir,"\\\0"); /* format it out to '\' */
else { /* otherwise.... */
getdir(current_dir+1); /* get it a 1 byte offset */
strcat(current_dir,"\\\0"); /* add a trailing '\' */
current_dir[0]='\\'; /* add a leading '\' */
}
/*
** Get the current logical disk number, and add 65 to get a drive letter
*/
drive = get_drive()+'A';
} else { /* Something passed */
strcpy(current_dir,argv[1]); /* Move it to current_dir string */
/*
** If no trailing '\' put one on there.
*/
if (current_dir[strlen(current_dir)-1] != '\\')
strcat(current_dir,"\\");
/*
** Extract drive letter from current_dir if it's given, otherwise return
** current drive letter.
*/
if (current_dir[1] != ':')
drive = get_drive()+'A';
else
drive = current_dir[0];
/*
** If the drive letter was taken from current_dir and is lower case,
** make it upper case for looks.
*/
if (drive > 96)
drive = (drive - 32);
}
init(); /* Initialize the variables */
header(); /* Display our header */
build_tree(current_dir,0); /* Start display tree at level 0 */
exit(1);
}