/* An alternative to DIR. Windows file manager is much better,
(and so are the more recent versions of DIR), but this still may
have use, and if nothing else, you can crib the asm routines for your
own use */
#include <stdio.h>
#include <string.h>
#include <malloc.h>
#include <stdlib.h>
#include <direct.h>
#include <dos.h>
#define Dir_Mask 16
#define Any_Mask 22
#define Showit 1
#define DontShow 0
#define WIDTH 78
struct dta {
char dos_reserved[21];
char flag;
short time;
short date;
long size;
char name[13];
} ;
struct dta *pd;
void s_print(struct dta *this);
int compare(char *this,char *that);
int makename(char *t,char *u);
int savewild(),getwild();
char *basename(char *string);
char *qualify(char *p);
int F_sort=1;
int F_quick=0;
int F_names=0;
int F_long=0;
int F_files=1;
int F_dirs=1;
int F_asterix=1;
int F_data=0;
int F_count=0;
int Wild_control=0;
int Num_Name_holders=0;
int T_drive=0;
long Total_bytes=0;
long Total_files=0;
long Total_subs=0;
long FT_bytes=0;
long SD_bytes=0;
long T_files=0,T_subs=0;
char S_wild[10][128];
char Name_holders[512][WIDTH];
char Fname_buf[128];
char Safe[128];
char *Wild=Fname_buf;
char *Flag_args,*File_args;
char *File_date="00/00/00";
char *File_time="00:00:00";
main(argc,argv)
int argc;
char **argv;
{
int x;
argc=get_args(argc,argv);
strcpy(Wild,File_args);
Wild=qualify(Wild); /* get args & flags */
do_dir(Any_Mask,Showit); /* gather data */
sr_print(); /* print it out */
if (F_data)
data();
}
do_dir(int val,int show)
{
pd=(struct dta *) malloc(sizeof(struct dta));
_asm {
pusha
call setdta
mov ah,0x4e
mov dx,Wild
mov cx,val
int 0x21
jb no_more
d_loop: mov si,pd
mov ax,[si+30]
cmp al,'.'
jz jfnext
cmp show,1
jz doshow
mov si,pd
mov ax,[si+21]
and ax,Dir_Mask
jz noshow
add si,30
push si
mov ax,Wild
push ax
call savewild
call makename
pop ax
pop ax
push 0
push Any_Mask
push pd
call do_dir
pop pd
pop ax
pop ax
call setdta
call getwild
jmp noshow
no_more:jmp outahere
jfnext: jmp fnext
doshow: push pd
call showit
pop pd
call setdta
jmp fnext
noshow: mov si,pd
mov ax,[si+21]
and ax,Dir_Mask
jnz isadir
add word ptr Total_files,1
adc word ptr Total_files+2,0
mov ax,[si+26]
mov cx,[si+28]
add word ptr Total_bytes,ax;
adc word ptr Total_bytes+2,cx;
jmp fnext
isadir: add word ptr Total_subs,1
adc word ptr Total_subs+2,0
fnext: mov ah,0x4f
int 0x21
jb no_more
jmp d_loop
setdta: mov dx,pd
mov ah,0x1a
int 0x21
ret
showit: push pd
call s_print
pop pd
ret
outahere:
popa
}
}
make_date(struct dta *dtp)
{
int year=0,month=0,day=0,is_today=0;
int fyear=0,fmonth=0,fday=0;
int fhour=0,fminutes=0,fseconds=0;
_asm {
push di
push si
push bp
push sp
push cx
mov ah,0x2A
int 0x21
mov year,cx
mov month,dh
mov day,dl
mov si,dtp
mov bx,[si+22]
mov dx,[si+24]
mov ax,bx
and ax,31
shl ax,1
mov fseconds,ax
mov ax,bx
and ax,32+64+128+256+512+1024
shr ax,5
mov fminutes,ax
mov ax,bx
and ax,2048+4096+8192+16384+32768
shr ax,11
mov fhour,ax
mov ax,dx
and ax,31
mov fday,ax
mov ax,dx
and ax,32+64+128+256
shr ax,5
mov fmonth,ax
mov ax,dx
and ax,512+1024+2048+4096+8192+16384+32768
shr ax,9
mov fyear,ax
pop cx
pop sp
pop bp
pop si
pop di
}
if (fyear == (year-1980) && fmonth == month && fday == day)
is_today=1;
sprintf(File_time,"%2.2d:%2.2d:%2.2d",fhour,fminutes,fseconds);
sprintf(File_date,"%2.2d/%2.2d/%2.2d",fmonth,fday,fyear+80);
return(is_today);
}
void s_print(struct dta *dtp)
{
int is_today;
char fn_temp[13];
char counts[30]="";
int is_directory=(dtp->flag & Dir_Mask);
int not_directory=!is_directory;
int want_files=!F_dirs;
int want_dirs=!F_files;
if ((is_directory && want_files) ||
(not_directory && want_dirs))
return;
is_today=make_date(dtp);
FT_bytes += dtp->size;
if (is_directory)
{
Total_bytes=0;
Total_files=0;
Total_subs=0;
T_subs++;
if (!F_quick && !F_names)
{
strcpy(Safe,Wild);
makename(Wild,dtp->name);
do_dir(Any_Mask,DontShow);
strcpy(Wild,Safe);
SD_bytes += Total_bytes;
}
if (!F_long)
{
if (F_asterix)
{ sprintf(Name_holders[Num_Name_holders++],"* %-10s %8s %8ld",dtp->name,(is_today==1 ? File_time : File_date),Total_bytes); }
else
{
sprintf(fn_temp,"%s\\",dtp->name);
sprintf(Name_holders[Num_Name_holders++],"%-12s %8s %8ld",fn_temp,(is_today==1 ? File_time : File_date),Total_bytes);
}
}
else
{
if (F_count)
{ sprintf(counts,"%4ld F %4ld S",Total_files,Total_subs);}
if (F_names && !F_files)
{ sprintf(fn_temp,"%s",dtp->name);}
else
{ sprintf(fn_temp,"%s\\",dtp->name);}
if (!F_names)
{
sprintf(Name_holders[Num_Name_holders++],"%-12s %8s %8s %8ld %-30s",fn_temp,File_date,File_time,Total_bytes,counts);
}
if (F_names)
{
sprintf(Name_holders[Num_Name_holders++],"%-12s",fn_temp);
}
}
}
else /* Not a directory */
{
T_files++;
if (!F_names )
{
if (!F_long)
{sprintf(Name_holders[Num_Name_holders++],"%-12s %8s %8ld",dtp->name,(is_today==1 ? File_time : File_date),dtp->size);}
if (F_long)
{sprintf(Name_holders[Num_Name_holders++],"%-12s %8s %8s %8ld",dtp->name,File_date,File_time,dtp->size);}
}
else
{
sprintf(Name_holders[Num_Name_holders++],"%-12s",dtp->name);
}
}
if (Num_Name_holders==512) { Num_Name_holders=1;strcpy(Name_holders[0],"Error > 511 !!");}
}
sr_print()
{
static int column=0;
static int doing_dirs=1;
int x;
int this_isdir=0,next_isdir=0;
int regular_list=(!F_long && !F_names && F_dirs && F_files);
int long_list=(F_long || F_names);
int files_only=!F_dirs;
if (F_sort)
qsort(Name_holders,Num_Name_holders,WIDTH,compare);
else
doing_dirs=0;
for (x=0; x < Num_Name_holders; x++)
{
if (!files_only && !long_list)
{
this_isdir=( *Name_holders[x]=='*' || strchr(Name_holders[x],'\\') !=NULL);
next_isdir=(x < Num_Name_holders && (*Name_holders[x+1] == '*'|| strchr(Name_holders[x+1],'\\') !=NULL));
}
if (files_only)
doing_dirs=0;
if (!this_isdir && doing_dirs && regular_list)
{
doing_dirs=0;
if (x > 0)
{
printf("\n\n");
}
column=0;
}
printf("%s",Name_holders[x]);
if (long_list)
{
printf("\n");
continue;
}
if (column ==1)
{
column=0;
if (!doing_dirs || (doing_dirs && next_isdir))
{
printf("\n");
}
}
else
{
column++;
printf("\t\t");
if ((x+1) == Num_Name_holders)
printf("\n");
}
}
}
savewild()
{
if (Wild_control > 9) Wild_control=9;
strcpy(S_wild[Wild_control++],Wild);
}
getwild()
{
strcpy(Wild,S_wild[--Wild_control]);
}
makename(char *string,char *name)
{
char *tt;
tt=strstr(string,"*.*");
if (tt)
sprintf(tt,"%s\\*.*",name);
}
compare(char *this, char *that)
{
int first=0,second=0;
if (*this == '*' || strchr(this,'\\'))
first=1;
if (*that == '*' || strchr(that,'\\'))
second=1;
if (first && !second)
return(-1);
if (second && !first)
return(1);
return(strcmp(this,that));
}
get_args(int argc,char **argv)
{
int x=0,y=argc;
char c;
char *cp;
char *flags="XX-FLAGS";
cp=basename(argv[0]);
flags[0]=cp[0];
flags[1]=cp[1];
if (flags[1]=='.')
strcpy(flags+1,"-FLAGS");
cp=malloc(127);File_args=cp;*File_args=0;
cp=malloc(127);Flag_args=cp;*Flag_args=0;
strcpy(Flag_args,getenv(flags));
for (x=1; x < argc; x++)
{
if (strstr(argv[x],"/") || strstr(argv[x],"-"))
{
strcat(Flag_args,strupr(argv[x]));
y--;
}
else
{
strcpy(File_args,argv[x]);
}
}
x=0;
while (c=Flag_args[x++])
{
switch(toupper(c)) {
case 'Q' : F_quick=1;F_count=0;break;
case 'R' : F_files=1;F_dirs=1;F_quick=0;
F_long=0; F_names=0; F_sort=1;
F_asterix=1;F_data=0;F_count=0;break;
case 'L' : F_long=1;break;
case 'S' : F_sort=1;break;
case 'O' : F_sort=0;break;
case 'N' : F_names=1;F_long=1;break;
case 'D' : F_files=0;break;
case 'F' : F_dirs=0;break;
case 'P' : F_asterix=0;break;
case 'M' : F_data=1; break;
case 'C' : F_count=1;F_long=1;F_quick=0; break;
case 'Z' : F_quick=0;break;
case '/': break;
case '-' : break;
case '\"' : break;
default : help(basename(argv[0]),Flag_args,File_args);break;
}
}
return(y);
}
help(char *name,char *flags,char *files)
{
fprintf(stderr,"Usage: %s path /QFLSN\n",name);
sprintf(name+2,"-FLAGS");
fprintf(stderr,"use SET %s=/QFLSN for standard behavior\n",name);
fprintf(stderr,"(Your current flags are: %s )\n",flags);
fprintf(stderr,"R-resets to defaults ");
fprintf(stderr," (sets Z,S, unsets all others)\n");
fprintf(stderr,"Q-Do not add up bytes for sub-directories (Resets C)\n");
fprintf(stderr,"Z-Do add up bytes (default)\n");
fprintf(stderr,"C-Count files & Subdirectories (implies /L and /Z)\n");
fprintf(stderr,"S-Sort (default)\n");
fprintf(stderr,"O-No Sort\n");
fprintf(stderr,"L-Long Listing\n");
fprintf(stderr,"F-Files only\n");
fprintf(stderr,"D-Directories only\n");
fprintf(stderr,"N-Names only ");
fprintf(stderr,"(D and N together : No \\ at end of directory name)\n");
fprintf(stderr,"P-Plain, do not separate directories\n");
fprintf(stderr,"M-Add directory byte & file counts at end\n");
fprintf(stderr,"\nLater flags override earlier\n");
fprintf(stderr,"\n(C)opyright November 1990, Anthony Lawrence, Lawrence & Clark,Inc\n");
fprintf(stderr," (617) 762-0707\n");
fprintf(stderr," (206) 323-2864\n");
exit(0);
}
char *basename(char *string)
{
_asm {
push si
push di
cld
mov si,string
mov di,si
f1: lodsb
cmp al, '\\'
jnz f2
mov di,si
f2: or al,al
jnz f1
cld
mov string,di
pop di
pop si
}
return(string);
}
char *qualify(char *p)
{
unsigned drive=0,drivenow=0,junk=0;
char *dirnow,*drivedir;
int ok=0;
_dos_getdrive(&drivenow);
dirnow=getcwd(NULL,64);
if (*(p+1) == ':')
drive=(toupper(*p)-64);
else
drive=drivenow;
T_drive=drive;
if (*p == 0)
return(strlwr("*.*"));
if (strcmp(p+1,":")==0)
{
strcat(p,"*.*");
return(p);
}
_dos_setdrive(drive,&junk);
drivedir=getcwd(NULL,64);
ok=chdir(p);
chdir(drivedir);
_dos_setdrive(drivenow,&junk);
chdir(dirnow);
if (!ok)
{
if (strcmp(strrchr(p,'\\'),"\\") !=0)
{
strcat(p,"\\*.*");
}
else
{
strcat(p,"*.*");
}
}
else
{
if (!strstr(p,".*") && strstr(p,"*") && !strstr(p,"*."))
strcat(p,".*");
}
return(p);
}
data()
{
struct diskfree_t drvinfo;
printf("\n%4ld SubDirs Bytes : %10ld\n",T_subs,SD_bytes);
printf("%4ld Files Bytes : %10ld\n",T_files,FT_bytes);
printf(" Total Bytes : %10ld\n\n",SD_bytes+FT_bytes);
_dos_getdiskfree( T_drive, &drvinfo );
printf("Total Disk space : %10ld bytes,%8ld clusters\n",
(long)drvinfo.total_clusters *
drvinfo.sectors_per_cluster *
drvinfo.bytes_per_sector,(long)drvinfo.total_clusters);
printf("Disk space free : %10ld bytes,%8ld clusters\n",
(long)drvinfo.avail_clusters *
drvinfo.sectors_per_cluster *
drvinfo.bytes_per_sector,(long)drvinfo.avail_clusters );
}
Enter your email address for automatic notification of new posts here
(be sure to whitelist 'feedburner.com' if you use spam filtering)
| Views for this page | ||||
|---|---|---|---|---|
| Today | This Week | This Month | This Year | Overall |
| 1 | 6 | 5 | 305 | 1,514 |
Have you tried Searching this site?
Unix/Linux/Mac OS X support by phone, email or on-site: Support Rates
This is a Unix/Linux resource website. It contains technical articles about Unix, Linux and general computing related subjects, opinion, news, help files, how-to's, tutorials and more. We appreciate comments and article submissions.

Add your comments
comment on this page here