home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C!T ROM 2
/
ctrom_ii_b.zip
/
ctrom_ii_b
/
PROGRAM
/
C
/
WORST102
/
WORST.C
< prev
next >
Wrap
C/C++ Source or Header
|
1992-08-01
|
12KB
|
692 lines
/* File: WORST.C */
#define VERSION "1.02"
/*
Written by Dan Lewis and released to the public domain.
Compiled using the C-Ware (DeSmet) DC88 compiler and the
-px switch, bound (linked) using C-Ware (DeSmet) BIND.
*/
#ifdef _lint
#include "\lint\sl-desm.c"
#else
#include <stdio.h>
#endif
#ifndef CALL
#define CALL (void)
#endif
typedef unsigned BOOL ;
typedef unsigned char BYTE ;
typedef unsigned int WORD ;
typedef long DUBL ;
#define READ_ONLY 0x01
#define HIDDEN 0x02
#define SYSTEM 0x04
#define VOL_LABEL 0x08
#define DIR_ENTRY 0x10
#define ARCHIVE 0x20
#define FIRST 0x4E
#define NEXT 0x4F
typedef struct TIME
{
unsigned
hsec:5, /* seconds/2 (0-29) */
min:6, /* minute (0-59) */
hour:5 ; /* hour (0-23) */
} TIME ;
typedef struct DATE
{
unsigned
day:5, /* day (1-31) */
month:4, /* month (1-12) */
year:7 ; /* year - 1980 */
} DATE ;
typedef struct DTA
{
char rsvd[21] ;
char attb ;
TIME time ;
DATE date ;
long size ;
char name[13] ;
} DTA ;
typedef struct STAT
{
char *name ;
char file[100] ;
TIME time ;
DATE date ;
DUBL size ;
} STAT ;
#define SAME(s1, s2) !strcmp(s1, s2)
#define ENDCHAR(s) s[strlen(s) - 1]
#define SLASH(c) (c == '\\' || c == '/')
BOOL found = FALSE ;
char *slash ;
#define NONE "[ none ]"
STAT empty_f = {"Empty", NONE} ;
STAT newest_f = {"Newest", NONE} ;
STAT oldest_f = {"Oldest", NONE} ;
STAT largest_f = {"Largest", NONE} ;
STAT smallest_f = {"Smallest", NONE} ;
STAT empty_d = {"Empty", NONE} ;
STAT newest_d = {"Newest", NONE} ;
STAT oldest_d = {"Oldest", NONE} ;
STAT largest_d = {"Largest", NONE} ;
STAT smallest_d = {"Smallest", NONE} ;
void Set_DTA(DTA *) ;
BOOL Find(WORD, char *, WORD) ;
void Replace(STAT *, char *, DTA *) ;
void Header(char *) ;
char *Time(TIME *) ;
char *Date(DATE *) ;
DUBL Search(char *, BOOL) ;
void Display(STAT *) ;
void Extract_Prefix(char *, char *) ;
void Split(char *, char *, char *) ;
void Update_Files(char *, DTA *) ;
void Update_Dirs(char *, DTA *) ;
DUBL Contents(char *) ;
void Working(char *) ;
void Set_Vector(unsigned, ...) ;
DUBL Get_Vector(unsigned) ;
void pokew(WORD, ...) ;
void poked(DUBL, ...) ;
/*lint -e715 */
void Set_DTA(dta)
DTA *dta ;
{
#ifndef _lint
#asm
mov ah,1Ah
mov dx,#dta
int 21h
#end
#endif
}
BOOL Find(mode, spec, attb)
WORD mode ;
char *spec ;
WORD attb ;
{
#ifndef _lint
#asm
mov ah,#mode
xor al,al
mov cx,#attb
mov dx,#spec
int 21h
mov ax,0
jc Fail1
inc ax
Fail1:
#end
#endif
}
/*lint +e715 */
void Replace(stat, pfx, dta)
STAT *stat ;
char *pfx ;
DTA *dta ;
{
strcpy(stat->file, pfx) ;
strcat(stat->file, dta->name) ;
stat->time = dta->time ;
stat->date = dta->date ;
stat->size = dta->size ;
found = TRUE ;
}
void Banner()
{
char bfr[80] ;
sprintf(bfr, "\nWORST v%s - Last revision date: %s ",
VERSION, __DATE__) ;
Working(bfr) ;
}
void Header(type)
char *type ;
{
printf("\n") ;
printf("Category Date Time Bytes %s\n", type) ;
printf("-------- -------- ------ --------- -----------------------") ;
printf("\n") ;
}
char *Time(t)
TIME *t ;
{
static char time[7] ;
char ampm ;
if (t->hour >= 12)
{
t->hour -= 12 ;
ampm = 'p' ;
}
else ampm = 'a' ;
sprintf(time, "%2u:%02u%c", t->hour, t->min, ampm) ;
return time ;
}
char *Date(d)
DATE *d ;
{
static char date[9] ;
sprintf(date, "%2u-%02u-%02u", d->month, d->day,
(d->year + 1980) % 100) ;
return date ;
}
void Extract_Prefix(head, pfx)
char *head ;
char *pfx ;
{
char *p ;
strcpy(pfx, head) ;
p = &pfx[strlen(head)] ;
while (p >= pfx)
{
switch (p[0])
{
case '?':
case '*':
p[0] = '\0' ;
break ;
case '\\':
case '/':
case ':':
p[1] = '\0' ;
return ;
}
p-- ;
}
}
void Split(spec, head, tail)
char *spec ;
char *head ;
char *tail ;
{
unsigned state ;
char ch, *p ;
state = 1 ;
*tail = '\0' ;
p = head ;
while ((ch = *spec++) != '\0')
{
switch (ch)
{
case '*':
case '?':
if (state == 1) state = 2 ;
break ;
case '\\':
case '/':
if (state != 2) break ;
*p = '\0' ;
p = tail ;
state = 3 ;
break ;
}
*p++ = ch ;
}
*p = '\0' ;
}
#define NEWER(a, b) (*((DUBL *) &a->time) >= *((DUBL *) &b.time))
#define OLDER(a, b) (*((DUBL *) &a->time) <= *((DUBL *) &b.time))
void Update_Files(pfx, dta)
char *pfx ;
DTA *dta ;
{
if (NEWER(dta, newest_f)) Replace(&newest_f, pfx, dta) ;
if (OLDER(dta, oldest_f)) Replace(&oldest_f, pfx, dta) ;
if (dta->size > largest_f.size) Replace(&largest_f, pfx, dta) ;
else if (dta->size == largest_f.size && OLDER(dta, largest_f))
{
Replace(&largest_f, pfx, dta) ;
}
if (dta->size == 0L)
{
if (OLDER(dta, empty_f)) Replace(&empty_f, pfx, dta) ;
}
else if (dta->size < smallest_f.size) Replace(&smallest_f, pfx, dta);
else if (dta->size == smallest_f.size && OLDER(dta, smallest_f))
{
Replace(&smallest_f, pfx, dta);
}
}
void Update_Dirs(pfx, dta)
char *pfx ;
DTA *dta ;
{
if (NEWER(dta, newest_d)) Replace(&newest_d, pfx, dta) ;
if (OLDER(dta, oldest_d)) Replace(&oldest_d, pfx, dta) ;
if (dta->size > largest_d.size) Replace(&largest_d, pfx, dta) ;
else if (dta->size == largest_d.size && OLDER(dta, largest_d))
{
Replace(&largest_d, pfx, dta) ;
}
if (dta->size == 0L)
{
if (OLDER(dta, empty_d)) Replace(&empty_d, pfx, dta) ;
}
else if (dta->size < smallest_d.size) Replace(&smallest_d, pfx, dta);
else if (dta->size == smallest_d.size && OLDER(dta, smallest_d))
{
Replace(&smallest_d, pfx, dta);
}
}
DUBL Search(spec, recurse)
char *spec ;
BOOL recurse ;
{
char *pfx, *head, *tail ;
unsigned find ;
DUBL bytes ;
DTA *dta ;
bytes = 0L ;
head = malloc(strlen(spec) + 1) ;
tail = malloc(strlen(spec) + 1) ;
Split(spec, head, tail) ;
pfx = malloc(strlen(head) + 1) ;
Extract_Prefix(head, pfx) ;
dta = malloc(sizeof(DTA)) ;
Set_DTA(dta) ;
find = FIRST ;
while (Find(find, head, DIR_ENTRY))
{
find = NEXT ;
if (SAME(dta->name, ".")) continue ;
if (SAME(dta->name, "..")) continue ;
if (!(dta->attb & DIR_ENTRY)) continue ;
strcpy(spec, pfx) ;
strcat(spec, dta->name) ;
if (SAME(tail, ""))
{
dta->size = Contents(spec) ;
if (recurse)
{
strcat(spec, slash) ;
strcat(spec, "*.*") ;
bytes += Search(spec, recurse) ;
}
Update_Dirs(pfx, dta) ;
}
else
{
strcat(spec, tail) ;
bytes += Search(spec, recurse) ;
}
Set_DTA(dta) ;
}
if (SAME(tail, ""))
{
find = FIRST ;
while (Find(find, head, HIDDEN|SYSTEM))
{
find = NEXT ;
bytes += dta->size ;
Update_Files(pfx, dta) ;
}
}
CALL free(head) ;
CALL free(tail) ;
CALL free(pfx) ;
CALL free(dta) ;
return bytes ;
}
DUBL Contents(dir)
char *dir ;
{
unsigned find ;
DTA *dta ;
DUBL bytes ;
char *spec ;
bytes = 0 ;
dta = malloc(sizeof(DTA)) ;
spec = malloc(strlen(dir) + 14) ;
strcpy(spec, dir) ;
strcat(spec, slash) ;
strcat(spec, "*.*") ;
Set_DTA(dta) ;
find = FIRST ;
while (Find(find, spec, HIDDEN|SYSTEM|DIR_ENTRY))
{
find = NEXT ;
if (SAME(dta->name, ".")) continue ;
if (SAME(dta->name, "..")) continue ;
if (dta->attb & DIR_ENTRY)
{
strcpy(spec, dir) ;
strcat(spec, slash) ;
strcat(spec, dta->name) ;
bytes += Contents(spec) ;
Set_DTA(dta) ;
}
else bytes += dta->size ;
}
CALL free(dta) ;
CALL free(spec) ;
return bytes ;
}
void Display(stat)
STAT *stat ;
{
if (SAME(stat->file, NONE)) return ;
printf("%-8s %s %s %9lu %s\n",
stat->name,
Date(&stat->date),
Time(&stat->time),
stat->size,
stat->file) ;
}
void main(argc, argv)
unsigned argc ;
char **argv ;
{
static char spec[100] ;
BOOL recurse, searched ;
unsigned arg ;
Banner() ;
smallest_f.size = 0x7FFFFFFFL ;
*((DUBL *) &oldest_f.time) = 0x7FFFFFFFL ;
*((DUBL *) &empty_f.time) = 0x7FFFFFFFL ;
smallest_d.size = 0x7FFFFFFFL ;
*((DUBL *) &oldest_d.time) = 0x7FFFFFFFL ;
*((DUBL *) &empty_d.time) = 0x7FFFFFFFL ;
slash = "\\" ;
for (arg = 1; arg < argc; arg++)
{
if (!strchr(argv[arg], '/')) continue ;
slash = "/" ;
break ;
}
recurse = searched = FALSE ;
for (arg = 1; arg < argc; arg++)
{
CALL strupr(argv[arg]) ;
if (SAME(argv[arg], "+S"))
{
recurse = TRUE ;
continue ;
}
if (SAME(argv[arg], "-S"))
{
recurse = FALSE ;
continue ;
}
strcpy(spec, argv[arg]) ;
Search(spec, recurse) ;
searched = TRUE ;
}
if (!searched)
{
strcpy(spec, "*.*") ;
Search(spec, recurse) ;
}
if (!found)
{
printf("\n\tNo matching directories/files!\7\n") ;
exit(0xFF) ;
}
Working(NULL) ;
printf("\n") ;
Header("Directory") ;
Display(&empty_d) ;
Display(&smallest_d) ;
Display(&largest_d) ;
Display(&oldest_d) ;
Display(&newest_d) ;
Header("File") ;
Display(&empty_f) ;
Display(&smallest_f) ;
Display(&largest_f) ;
Display(&oldest_f) ;
Display(&newest_f) ;
exit(0x00) ;
}
#define WIDTH 75
#define MAXLEN (WIDTH - 10)
BYTE busy ;
BYTE width ;
BYTE fwd_count ;
BYTE rev_count ;
void _Working() ;
void data_seg() ;
void chain() ;
void Dummy()
{
#ifndef _lint
#asm
data_seg_ dw 0
chain_ dd 0
;---------
_Working_:
;---------
sti
push ax
push ds
mov ds,data_seg_
mov al,1
xchg busy_,al
or al,al
jnz Skip_Tick
push bx
push cx
Forward: cmp fwd_count_,0
je Reverse
mov ah,0Eh ; write TTY
mov al,'.'
mov bx,7
int 10h
dec fwd_count_
jnz Finished
mov al,width_
mov rev_count_,al
jmp Finished
Reverse: cmp rev_count_,0
je Finished
mov ax,0E08h ; write backspace
mov bx,7
int 10h
mov ah,0Ah ; write, no advance
mov al,' '
xor bh,bh
mov cx,1
int 10h
dec rev_count_
jnz Finished
mov al,width_
mov fwd_count_,al
Finished: mov BYTE busy_,0
pop cx
pop bx
Skip_Tick: pop ds
pop ax
cli
ljmp DWORD chain_
#end
#endif
}
/*lint -e715 */
DUBL Get_Vector(vector)
unsigned vector ;
{
#ifndef _lint
#asm
mov ah,35h ; get old vector
mov al,#vector
int 21h
mov ax,bx
mov dx,es
#end
#endif
}
void Set_Vector(vector, off, seg)
unsigned vector ;
WORD off ;
WORD seg ;
{
#ifndef _lint
#asm
mov ah,25h ; Install new routine
mov al,#vector
push ds
mov dx,#off
mov ds,#seg
int 21h
pop ds
#end
#endif
}
void pokew(word, off, seg)
WORD word ;
WORD off ;
WORD seg ;
{
#ifndef _lint
#asm
les bx,#off
mov ax,#word
mov es:[bx],ax
#end
#endif
}
void poked(dubl, off, seg)
DUBL dubl ;
WORD off ;
WORD seg ;
{
#ifndef _lint
#asm
les bx,#off
mov ax,#dubl[0]
mov es:[bx],ax
mov ax,#dubl[2]
mov es:[bx+2],ax
#end
#endif
}
/*lint +e715 */
void Working(label)
char *label ;
{
DUBL Get_Vector() ;
static DUBL old_int1c ;
static unsigned len = MAXLEN + 1 ;
WORD cs ;
if (label != NULL)
{
printf(label) ;
len = strlen(label) ;
if (len > MAXLEN) return ;
fwd_count = width = (BYTE) (WIDTH - len) ;
rev_count = busy = 0 ;
pokew(_showds(), (WORD) data_seg, cs = _showcs()) ;
old_int1c = Get_Vector(0x1C) ;
poked(old_int1c, (WORD) chain, cs) ;
Set_Vector(0x1C, (WORD) _Working, cs) ;
}
else
{
if (len > MAXLEN) return ;
Set_Vector(0x1C, old_int1c) ;
if (!isatty(fileno(stdout))) return ;
if (fwd_count) rev_count = (BYTE) (width - fwd_count) ;
while (rev_count-- > 0) printf("\b \b") ;
}
}