Category : File Managers
Archive   : LS.ZIP
Filename : LS.C

 
Output of file : LS.C contained in archive : LS.ZIP
/***********************/
/* */
/* LS v1.4 */
/* */
/* by Mike Klein */
/* */
/*---------------------*/
/* */
/* Started 6/12/89 */
/* Finished */
/* */
/* VERSIONS */
/* 1.1 06/27/89 */
/* 1.2 07/04/89 */
/* Imprvd path disp */
/* /lower parm */
/* /comma parm */
/* /wide parm */
/* /pause parm */
/* /rows parm */
/* /cols parm */
/* 1.3 08/06/89 */
/* /military /24 */
/* /dirsizes */
/* */
/* 1.4 */
/* /pre, /post */
/* Fixed volume name */
/* printing */
/* /nocolors */
/* */
/***********************/
#define VER 1.4


/*****************/
/* */
/* INCLUDE FILES */
/* */
/*****************/

#include
#include
#include
#include
#include
#include
#include


/***********/
/* */
/* DEFINES */
/* */
/***********/

#define PASSED 0
#define FAILED -1
#define TRUE 1
#define FALSE 0
#define YES 1
#define NO 0
#define ON 1
#define OFF 0
#define VOID void
#define KB 1000
#define MB 1000000



/************/
/* */
/* TYPEDEFS */
/* */
/************/

typedef signed char CHAR;
typedef signed int INT;
typedef unsigned int WORD;
typedef signed char BOOLEAN;
typedef unsigned char BYTE;
typedef unsigned char CNTR;
typedef unsigned int COUNTER;


/****************/
/* */
/* DECLARATIONS */
/* */
/****************/

static VOID exit_error();
static BOOLEAN match_mask();
static VOID get_files();
static VOID get_volume();
static VOID print_header();
static VOID make_mask();
static VOID list_delimited();
static VOID list_wide();
static VOID list_normal();
static VOID display_files();
static VOID print_file();
static VOID show_parms();
static unsigned long int get_dir_size();
static BOOLEAN printable();

static struct FILES
{
CHAR drive[MAXDRIVE];
CHAR dir[MAXDIR];
CHAR name[9];
CHAR ext[5];
unsigned long size;
WORD date;
WORD time;
CHAR attrib;
struct FILES *prior;
struct FILES *next;
};

static COUNTER current, bottom, screen_top = 0;

static union REGS regs;
static struct SREGS sregs;

static struct FILES **entry;
static COUNTER max_entries = 1000;

static CHAR *mask[30];
static CNTR mask_count = 0;
static CHAR *file_spec[30];
static CNTR file_spec_count = 0;

static CNTR max_cols = 80;
static CNTR max_rows = 25;

static CHAR drive[MAXDRIVE];
static CHAR dir[MAXDIR];
static CHAR name[MAXFILE];
static CHAR ext[MAXEXT];

static CHAR volume_name[12];
static COUNTER file_count = 0;
static COUNTER dir_count = 0;
static unsigned long int sum_file_sizes = 0;

static CHAR pre_string[MAXPATH] = "";
static CHAR post_string[MAXPATH] = "";

static BOOLEAN show_files =YES;
static BOOLEAN show_dirs = YES;
static BOOLEAN show_system = NO;
static BOOLEAN system_flag = OFF;
static BOOLEAN show_hidden = NO;
static BOOLEAN hidden_flag = OFF;
static BOOLEAN show_read_only = YES;
static BOOLEAN read_only_flag = OFF;
static BOOLEAN show_archive = YES;
static BOOLEAN archive_flag = OFF;
static BOOLEAN show_path = NO;
static BOOLEAN show_lower = NO;
static BOOLEAN show_delimited = NO;
static BOOLEAN show_wide = NO;
static BOOLEAN military_time = NO;
static BOOLEAN pause_listing = NO;
static BOOLEAN show_help = NO;
static BOOLEAN show_dir_sizes = NO;
static BOOLEAN show_info = YES;
static BOOLEAN search_subs = NO;
static BOOLEAN use_colors = YES;

/* If sizes are in bytes # = 1 if in KB # = 1000 if in MB # = 1000000 */
static unsigned long int file_size_div = 1;


/********/
/* */
/* MAIN */
/* */
/********/

VOID main(int argc, CHAR *argv[])
{
CNTR i;
CNTR cntr;
BYTE buffer[MAXPATH];
CHAR *ptr;

get_volume(volume_name);

regs.x.ax = 0x0f00; /* INT10 FUNC 0F Get video mode */
int86(0x10, ®s, ®s); /* for # of columns. */
max_cols = regs.h.ah;

regs.x.ax = 0x1130; /* INT10 FUNC 11/30 Get font */
regs.h.bh = 0x01; /* information for # of rows. */
int86(0x10, ®s, ®s);
max_rows = regs.h.dl + 1;

for(cntr = 1; cntr < argc; ++cntr)
{
strcpy(buffer, strupr(argv[cntr]));
switch(buffer[0])
{
case '/' :
if(!strcmp(buffer, "/K") || !strcmp(buffer, "/KB"))
{
file_size_div = KB;
break;
}
if(!strcmp(buffer, "/M") || !strcmp(buffer, "/MB"))
{
file_size_div = MB;
break;
}
if(!strcmp(buffer, "/S") || !strcmp(buffer, "/SUB"))
{
search_subs = YES;
break;
}
if(!strcmp(buffer, "/NC") || !strcmp(buffer, "/NOCOLORS"))
{
use_colors = NO;
break;
}
if(!strcmp(buffer, "/P") || !strcmp(buffer, "/PAUSE"))
{
pause_listing = YES;
break;
}
if(!strcmp(buffer, "/W") || !strcmp(buffer, "/WIDE"))
{
show_wide = YES;
break;
}
if(!strncmp(buffer, "/E=", 3) || !strncmp(buffer, "/ENTRIES=", 9))
{
ptr = strchr(buffer, '=');
if(atoi(ptr + 1) > 0)
max_entries = (COUNTER) atoi(ptr + 1);
break;
}
if(!strncmp(buffer, "/C=", 3) || !strncmp(buffer, "/COLS=", 6))
{
ptr = strchr(buffer, '=');
if(atoi(ptr + 1) > 0)
max_cols = (CNTR) atoi(ptr + 1);
break;
}
if(!strncmp(buffer, "/R=", 3) || !strncmp(buffer, "/ROWS=", 6))
{
ptr = strchr(buffer, '=');
if(atoi(ptr + 1) > 0)
max_rows = (CNTR) atoi(ptr + 1);
break;
}
if(!strcmp(buffer, "/ND") || !strcmp(buffer, "/NODIR"))
{
show_dirs = NO;
break;
}
if(!strcmp(buffer, "/?") || !strcmp(buffer, "/HELP"))
{
show_help = YES;
show_parms();
break;
}
if(!strcmp(buffer, "/L") || !strcmp(buffer, "/LOWER"))
{
show_lower = YES;
break;
}
if(!strcmp(buffer, "/24") || !strcmp(buffer, "/MILITARY"))
{
military_time = YES;
break;
}
if(!strcmp(buffer, "/SIZE") || !strcmp(buffer, "/SIZES"))
{
show_dir_sizes = YES;
break;
}
if(!strcmp(buffer, "/NF") || !strcmp(buffer, "/NOFILES"))
{
show_files = NO;
break;
}
if(!strcmp(buffer, "/PATH"))
{
show_path = YES;
break;
}
if(!strncmp(buffer, "/PRE=", 5))
{
strcpy(pre_string, &buffer[5]);
for(i = 0; i < MAXPATH; ++i)
{
if(pre_string[i] == NULL)
break;
if(pre_string[i] == '^')
pre_string[i] = ' ';
}
show_info = NO;
break;
}
if(!strncmp(buffer, "/POST=", 6))
{
strcpy(post_string, &buffer[6]);
for(i = 0; i < MAXPATH; ++i)
{
if(post_string[i] == NULL)
break;
if(post_string[i] == '^')
post_string[i] = ' ';
}
show_info = NO;
break;
}
if(!strcmp(buffer, "/C") || !strcmp(buffer, "/COMMA"))
{
show_dirs = NO;
show_delimited = YES;
break;
}
if((buffer[1] == '+') && (buffer[2] == 'R'))
{
read_only_flag = ON;
show_read_only = YES;
break;
}
if((buffer[1] == '-') && (buffer[2] == 'R'))
{
read_only_flag = ON;
show_read_only = NO;
break;
}
if((buffer[1] == '+') && (buffer[2] == 'S'))
{
system_flag = ON;
show_system = YES;
break;
}
if((buffer[1] == '-') && (buffer[2] == 'S'))
{
system_flag = ON;
show_system = NO;
break;
}
if((buffer[1] == '+') && (buffer[2] == 'H'))
{
hidden_flag = ON;
show_hidden = YES;
break;
}
if((buffer[1] == '-') && (buffer[2] == 'H'))
{
hidden_flag = ON;
show_hidden = NO;
break;
}
if((buffer[1] == '+') && (buffer[2] == 'A'))
{
archive_flag = ON;
show_archive = YES;
break;
}
if((buffer[1] == '-') && (buffer[2] == 'A'))
{
archive_flag = ON;
show_archive = NO;
break;
}
if(buffer[1] == '!')
{
make_mask(&buffer[2]);
break;
}
show_parms();
exit_error("Invalid parameter");
break;
default :
if((file_spec[file_spec_count] = malloc(sizeof(buffer))) == NULL)
exit_error("Allocating memory");
strcpy(file_spec[file_spec_count], buffer);
++file_spec_count;
break;
}
}

if((entry = malloc(sizeof(struct FILES *) * max_entries)) == NULL)
exit_error("Memory allocation");

for(i = 0; i < file_spec_count; ++i) /* Get all files requested */
get_files(file_spec[i]);

if(!(show_help && (argc == 2))) /* If /? or /HELP only, then don't */
{ /* automatically get *.* */
if(!bottom) /* Check for empty file array */
if(file_spec_count) /* Have they used any flspecs? */
exit_error("Path/filename not found");
else
{
if(!*(strrchr(getcwd(buffer, MAXPATH), '\\') + 1))
strcat(buffer, "*.*");
else
strcat(buffer, "\\*.*");
get_files(buffer);
}
display_files();
}
}


/**************/
/* */
/* SHOW_PARMS */
/* */
/**************/

VOID show_parms(VOID)
{
printf("\nLS ver %1.1f by Mike Klein\n", VER);
puts("Parameters:");
printf("\n");
puts("/Pause Pause listing at every screen page.");
puts("/Wide Display files in columns.");
puts("/NoDir Show no directories in listing.");
puts("/NoFiles Show no files in listing.");
puts("/DirSize Shows directory sizes. Output is slower due to disk I/O.");
puts("/Comma List files in comma delimited format.");
puts("/Lower Show all output in lower case.");
puts("/Cols= User inputted screen columns.");
puts("/Rows= User inputted screen rows.");
puts("/PATH Show path next to filename.");
puts("/MILITARY Show time in military format.");
puts("/PRE= Prepend a string to file names.");
puts("/POST= Append a string to file names.");
puts("/+-R (+) Show R/O files. (-) Show everything but R/O files.");
puts("/+-A Same as above but for archive files.");
puts("/+-H Same as above but for hidden files.");
puts("/+-S Same as above but for system files.");
puts("/?, /HELP This help screen.\n");
puts("\nATTRIBUTES");
puts("D = Directory");
puts("R = Read-Only");
puts("A = Archive");
puts("H = Hidden");
puts("S = System\n");
}


/*************/
/* */
/* LIST_WIDE */
/* */
/*************/

VOID list_wide(VOID)
{
CHAR filename[13];
CHAR *ptr = filename;

CNTR rows = 0;
CNTR cols = 0;

for(current = 0; current < bottom; ++current)
{
strcpy(filename, entry[current]->name);
if(strcmp(entry[current]->ext, "."))
ptr = strcat(filename, entry[current]->ext);
printf("%-13s", ptr);
sum_file_sizes += entry[current]->size;
cols += 13;

if(max_cols - cols < 13)
{
printf("\n");
++rows;
cols = 0;
}

if(pause_listing && (rows == max_rows - 1) && !cols)
{
while(!kbhit())
;
getch();
rows = cols = 0;
}
}
if(cols)
printf("\n");
}


/******************/
/* */
/* LIST_DELIMITED */
/* */
/******************/

VOID list_delimited(VOID)
{
for(current = 0; current < bottom; ++current)
{
if(current)
printf(",");
printf("%s", entry[current]->name);
if(strcmp(entry[current]->ext, "."))
printf("%s", entry[current]->ext);
}
}


/*****************/
/* */
/* DISPLAY_FILES */
/* */
/*****************/

VOID display_files(VOID)
{
INT sectors_per_cluster;
INT available_clusters;
INT bytes_per_sector;
INT clusters_per_drive;
INT cluster_size;
unsigned long int disk_total;
unsigned long int disk_free;

if(show_info)
print_header();

if(show_delimited)
list_delimited();
else
if(show_wide)
list_wide();
else
list_normal();

if(!show_delimited && show_info)
{
printf("\n");
if(show_files)
if(show_lower)
printf("files=%d\n", file_count);
else
printf("FILES=%d\n", file_count);
if(show_dirs)
if(show_lower)
printf("dirs=%d\n", dir_count);
else
printf("DIRS=%d\n", dir_count);
printf("\n");

regs.x.ax = 0x3600; /* Getting disk total/free space */
regs.h.dl = getdisk() + 1;
intdos(®s, ®s);

sectors_per_cluster = regs.x.ax;
available_clusters = regs.x.bx;
bytes_per_sector = regs.x.cx;
clusters_per_drive = regs.x.dx;
cluster_size = sectors_per_cluster * bytes_per_sector;
disk_total = (unsigned long) cluster_size * clusters_per_drive;
disk_free = (unsigned long) cluster_size * available_clusters;

if(show_lower)
{
printf("disk total=%9lu bytes (%3.2fmb)\n", disk_total, (float) disk_total / 1000000);
printf(" disk used=%9lu bytes (%3.2fmb)\n", sum_file_sizes, (float) sum_file_sizes / 1000000); /* Disk use shown */
printf(" disk free=%9lu bytes (%3.2fmb)\n", disk_free, (float) disk_free / 1000000);
}
else
{
printf("DISK TOTAL=%9lu bytes (%3.2fMB)\n", disk_total, (float) disk_total / 1000000);
printf(" DISK USED=%9lu bytes (%3.2fMB)\n", sum_file_sizes, (float) sum_file_sizes / 1000000); /* Disk use shown */
printf(" DISK FREE=%9lu bytes (%3.2fMB)\n", disk_free, (float) disk_free / 1000000);
}
}
}


/***************/
/* */
/* LIST_NORMAL */
/* */
/***************/

VOID list_normal(VOID)
{
CNTR rows = 0;

if(show_info)
puts(" DATE TIME SIZE ATTRIB NAME EXT");

for(current = 0; current < bottom; ++current)
{
print_file(current);
++rows;

if(pause_listing && (rows == max_rows - 2))
{
while(!kbhit())
;
getch();
rows = 0;
}
}
}


/****************/
/* */
/* GET_DIR_SIZE */
/* */
/****************/

unsigned long int get_dir_size(CHAR *fname)
{
struct ffblk ffblk;
unsigned long int dir_size = 0;
static COUNTER file_count = 0;
BOOLEAN getfirst = YES;
CHAR file0[MAXPATH];
CHAR file1[MAXPATH];

strcpy(file0, fname);
while(TRUE)
{
if(!getfirst)
{
if(findnext(&ffblk) == FAILED)
break;
}
else
{
if(findfirst(fname, &ffblk, 0xff) == FAILED)
break;
}
if(ffblk.ff_attrib & FA_DIREC && ffblk.ff_name[0] != '.' && \
ffblk.ff_name[1] != '.')
{
strcpy(file1, file0);
*(strrchr(file1, '\\') + 1) = '\0';
strcat(file1, ffblk.ff_name);
strcat(file1, "\\*.*");
dir_size += get_dir_size(file1);
}
else
if(!(ffblk.ff_attrib & FA_LABEL))
{
++file_count;
dir_size += ffblk.ff_fsize;
}
getfirst = NO;
}
return(dir_size);
}


/****************/
/* */
/* PRINT_HEADER */
/* */
/****************/

VOID print_header(VOID)
{
CHAR path[MAXPATH];

printf("\nLS ver %1.1f by Mike Klein\n", VER);

if(!show_delimited)
if(show_lower)
{
printf("\nvolume=%s\n", strlwr(volume_name));
printf("path=%s\n\n", strlwr(getcwd(path, MAXPATH)));
}
else
{
printf("\nVOLUME=%s\n", volume_name);
printf("PATH=%s\n\n", getcwd(path, MAXPATH));
}
}


/**************/
/* */
/* GET_VOLUME */
/* */
/**************/

VOID get_volume(CHAR *volume_name)
{
struct ffblk ffblk;
CNTR i;

if(findfirst("\\*.*", &ffblk, 0xff) == FAILED)
strcpy(volume_name, "ERROR");
else
if(ffblk.ff_attrib & FA_LABEL)
strcpy(volume_name, ffblk.ff_name);
else
while(TRUE)
{
if(findnext(&ffblk) == FAILED)
{
strcpy(volume_name, "NO LABEL");
break;
}
if(ffblk.ff_attrib & FA_LABEL)
{
for(i = 8; i < 12; ++i)
{
if(!ffblk.ff_name[i])
break;
else
ffblk.ff_name[i] = ffblk.ff_name[i + 1];
}
strcpy(volume_name, ffblk.ff_name);
break;
}
}
}


/**************/
/* */
/* PRINT_FILE */
/* */
/**************/

VOID print_file(COUNTER index)
{
unsigned long int div_size = file_size_div;
CHAR fname[MAXPATH];
WORD date, time;
CNTR hours;
CNTR minutes;
BYTE am_pm;
fname[0] = '\0';

if(show_lower)
{ /* Let's convert output to lower if */
strlwr(entry[index]->drive); /* the /lower command was used. */
strlwr(entry[index]->dir);
strlwr(entry[index]->name);
strlwr(entry[index]->ext);
}

if(pre_string[0])
printf("%s", pre_string);

if(show_info)
{
date = entry[current]->date;
printf("%02d-%02d-%02d ", (date >> 5) & 0x0f, date & 0x1f, \
80 + (date >> 9) & 0x7f);

time = entry[current]->time;
hours = time >> 11;
minutes = (time >> 5) &0x3f;

if(military_time)
printf("%02d:%02d ", hours, minutes);
else
{
if(hours > 12)
{
hours -= 12;
am_pm = 'P';
}
else
{
if(!hours)
hours = 12;
am_pm = 'A';
}

if(show_lower)
am_pm = (BYTE) tolower(am_pm);
printf("%02d:%02d%c ", hours, minutes, am_pm);
}

if(entry[index]->attrib & FA_DIREC && entry[index]->size == -1)
{
if(show_dir_sizes && entry[index]->name[0] != '.')
{
strcpy(fname, entry[index]->drive);
strcat(fname, entry[index]->dir);
strcat(fname, entry[index]->name);
if(strcmp(entry[index]->ext, "."))
strcat(fname, entry[index]->ext);
strcat(fname, "\\*.*");
entry[index]->size = get_dir_size(fname);
sum_file_sizes += entry[index]->size;

if(!((unsigned long int) entry[index]->size / file_size_div))
{
if(file_size_div == MB && ((unsigned long int) entry[index]->size / KB))
{
printf("%8lu", entry[index]->size / KB);
div_size = KB;
}
else
{
printf("%8lu", entry[index]->size);
div_size = 1;
}
}
else
printf("%8lu", (unsigned long int) entry[index]->size / file_size_div);

switch(div_size)
{
case KB :
printf("K ");
break;
case MB :
printf("MB ");
break;
default :
printf(" ");
break;
}
}
else
printf(" ");
}
else
{
if(!((unsigned long int) entry[index]->size / file_size_div))
{
if(file_size_div == MB && ((unsigned long int) entry[index]->size / KB))
{
printf("%8lu", entry[index]->size / KB);
div_size = KB;
}
else
{
printf("%8lu", entry[index]->size);
div_size = 1;
}
}
else
printf("%8lu", (unsigned long int) entry[index]->size / file_size_div);

sum_file_sizes += entry[index]->size;
switch(div_size)
{
case KB :
printf("K ");
break;
case MB :
printf("MB ");
break;
default :
printf(" ");
break;
}
}

}

if(show_info)
printf("DRSHA ");

if(show_path)
printf("%s%s", entry[index]->drive, entry[index]->dir);

if(show_info)
printf("%-9s%-4s", entry[index]->name, &entry[index]->ext[1]);
else
{
printf("%s", entry[index]->name);
if(entry[index]->ext[1])
printf("%s", entry[index]->ext);
}

if(post_string[0] != NULL)
printf("%s\n", post_string);
else
printf("\n");
}


/*************/
/* */
/* PRINTABLE */
/* */

/*************/

BOOLEAN printable(struct ffblk *ffblk)
{
if(ffblk->ff_attrib & FA_LABEL)
return(NO);

if(ffblk->ff_attrib & FA_DIREC)
{
if(!show_dirs && !search_subs)
return(NO);
}
else
if(!show_files)
return(NO);

if(archive_flag)
{
if((ffblk->ff_attrib & FA_ARCH) && !show_archive)
return(NO);
if(!(ffblk->ff_attrib & FA_ARCH) && show_archive)
return(NO);
}
if(read_only_flag)
{
if((ffblk->ff_attrib & FA_RDONLY) && !show_read_only)
return(NO);
if(!(ffblk->ff_attrib & FA_RDONLY) && show_read_only)
return(NO);
}
if(system_flag)
{
if(ffblk->ff_attrib & FA_SYSTEM && !show_system)
return(NO);
if(!(ffblk->ff_attrib & FA_SYSTEM) && show_system)
return(NO);
}
if(hidden_flag)
{
if(ffblk->ff_attrib & FA_HIDDEN && !show_hidden)
return(NO);
if(!(ffblk->ff_attrib & FA_HIDDEN) && show_hidden)
return(NO);
}

/* Now we have to mask out files that match our exclude "!" */
/* parameter, if one was used */

if(mask_count && !((ffblk->ff_attrib & FA_DIREC) && search_subs) && \
(match_mask(ffblk) == YES))
return(NO);

return(YES);
}


/*************/
/* */
/* MAKE_MASK */
/* */
/*************/

VOID make_mask(CHAR *file_name)
{
int status;
CNTR i;
CHAR template[13] = "????????.???";

if((mask[mask_count] = malloc(sizeof(template))) == NULL)
exit_error("Allocating memory");

status = fnsplit(file_name, drive, dir, name, ext); /* Get components of */
if(!(status & FILENAME)) /* file for exclude parameter */
strcpy(name, "????????");
if(!(status & EXTENSION))
strcpy(ext, ".???");

for(i = 0; i < strlen(name); ++i) /* Copy over name until '*' */
if(name[i] == '*')
break;
else
template[i] = name[i];
for(i = 1; i < strlen(ext); ++i) /* Copy over ext until '*' */
if(ext[i] == '*')
break;
else
template[8 + i] = ext[i];

strcpy(mask[mask_count], template);
++mask_count;
}


/**************/
/* */
/* MATCH_MASK */
/* */
/**************/

BOOLEAN match_mask(struct ffblk *ffblk)
{
BOOLEAN matches = NO;
CNTR i, j;
CHAR file[13];

if(!mask_count)
return(matches);

strcpy(file, "????????.???");

i = j = 0;

while(ffblk->ff_name[i] != NULL)
{
if(ffblk->ff_name[i] == '.')
{
++i;
j = 9;
}
else
{
file[j] = ffblk->ff_name[i];
++i;
++j;
}
}

for(i = 0; i < mask_count; ++i) /* See if file matches */
{ /* users masks. */
for(j = 0; j < strlen(file); ++j)
if((file[j] != *(mask[i] + j)) && *(mask[i] + j) != '?')
break;
if(j == strlen(file))
{
matches = YES;
break;
}
}
return(matches);
}


/*************/
/* */
/* GET_FILES */
/* */
/*************/

VOID get_files(CHAR *fname)
{
struct ffblk ffblk;
COUNTER buf_len;
INT status;
COUNTER passes = 0;
CHAR buffer[MAXPATH];
CHAR buffer2[MAXPATH];

strcpy(buffer, fname);
buf_len = strlen(buffer);

status = fnsplit(buffer, drive, dir, name, ext);

if((status & DIRECTORY) && !(status & FILENAME) && !(status & EXTENSION))
{
if(buffer[buf_len - 1] == '.') /* Take care of . and .. and */
strcpy(buffer, "\\*.*");
else
if(!*(strrchr(buffer, '\\') + 1))
strcat(buffer, "*.*");
}
else
{
if(!(status & FILENAME))
strcpy(name, "*");
if(!*(strrchr(buffer, '.') + 1))
strcpy(ext, ".");
else
if(!(status & EXTENSION) && !(status & FILENAME))
strcpy(ext, ".*");
fnmerge(buffer, drive, dir, name, ext);
}

while(TRUE)
{
if(bottom == max_entries)
{
printf("\007");
break;
}
if(passes)
{
if(findnext(&ffblk) == FAILED)
break;
}
else
{
if(findfirst(buffer, &ffblk, 0xff) == FAILED) /* Nothing matches their */
break;

/* This is for when the syntax is 'cat \dirname' or 'cat dirname' so */
/* that the computer adds a \*.* to it and has the files in the dir get */
/* pulled up instead of just the dir name by itself. */

if((ffblk.ff_attrib & FA_DIREC) && (strcspn(buffer, "?*") == strlen(buffer)))
{
strcat(buffer, "\\*.*");
if(findfirst(buffer, &ffblk, 0xff) == FAILED)
break;
}
}
++passes;

if(printable(&ffblk))
{
if((entry[bottom] = malloc(sizeof(struct FILES))) == NULL)
exit_error("Out of memory");
if(bottom) /* Takes care for first item in array */
++current;
++bottom;

status = fnsplit(buffer, drive, dir, name, ext);

if(!(status & DRIVE))
sprintf(drive, "%c%c", getdisk() + 'A', ':');

if(status & DIRECTORY) /* Did they include a path */
{
if(dir[0] != '\\') /* Is it a full path? */
{
movmem(&dir[0], &dir[1], strlen(dir));
dir[0] = '\\';
if(*(strrchr(dir, '\\') + 1))
strcat(dir, "\\");
}
}
else
{ /* If no, get current path */
dir[0] = '\\';
getcurdir((int) (drive[0] - 'A' + 1), &dir[1]);
if(*(strrchr(dir, '\\') + 1))
strcat(dir, "\\");
if(dir[0] != '\\')
{
strcpy(&dir[1], dir);
dir[0] = '\\';
}
}
strcpy(entry[current]->drive, drive);
strcpy(entry[current]->dir, dir);

if(ffblk.ff_attrib & FA_DIREC)
{
entry[current]->size = -1;

++dir_count;
}
else
{
entry[current]->size = ffblk.ff_fsize;
++file_count;
}

entry[current]->date = ffblk.ff_fdate;
entry[current]->time = ffblk.ff_ftime;
entry[current]->attrib = ffblk.ff_attrib;

status = fnsplit(ffblk.ff_name, drive, dir, name, ext);

if(status & FILENAME)
strcpy(entry[current]->name, name);
else
strcpy(entry[current]->name, "");

if(status & EXTENSION)
strcpy(entry[current]->ext, ext);
else
strcpy(entry[current]->ext, ".");

if(dir[0] == '.')
strcpy(entry[current]->name, dir);

/* The following is for when the /sub or /s option is used */

if((ffblk.ff_attrib & FA_DIREC) && search_subs && (ffblk.ff_name[0] != '.'))
{
fnsplit(buffer, drive, dir, name, ext);
strcat(ffblk.ff_name, "\\*");
strcpy(ext, ".*");
fnmerge(buffer2, drive, dir, ffblk.ff_name, ext);
get_files(buffer2);
}
}
}
}


/**************/
/* */
/* EXIT_ERROR */
/* */
/**************/

VOID exit_error(CHAR *err_str)
{
printf("\nERROR: %s...\n", err_str);
if(fcloseall() == EOF)
puts("ERROR: Closing files...\n");
exit(FAILED);
}


  3 Responses to “Category : File Managers
Archive   : LS.ZIP
Filename : LS.C

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. 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/