LD.C Tony Lawrence:
/* 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 ); }
Got something to add? Send me email.
Increase ad revenue 50-250% with Ezoic
Inexpensive and informative Apple related e-books:
Take Control of iCloud
Take Control of Numbers
Photos for Mac: A Take Control Crash Course
Take Control of Security for Mac Users
iOS 10: A Take Control Crash Course
More Articles by Tony Lawrence
Find me on Google+
© 2009-11-07 Tony Lawrence
Printer Friendly Version
An alternative to DIR. Copyright © January 1997 Tony Lawrence
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.
Contact us
Printer Friendly Version