home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Frozen Fish 1: Amiga
/
FrozenFish-Apr94.iso
/
bbs
/
oct93
/
cli_util
/
dirs.lha
/
Dirs
/
English
/
dirs.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-08-23
|
16KB
|
658 lines
// dirs written by Harald Pehl
// Last change 28-Aug-93, 18:35:16
// Version 1.00
// compiled with MaxonC++
// Includes
#include <pragma/exec_lib.h>
#include <pragma/dos_lib.h>
#include <dos/dosextens.h>
#include <dos/datetime.h>
#include <exec/memory.h>
#include <dos/dos.h>
#include <stream.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
// Functions
void close_all (const char *, const int);
char *itoa (int);
void strrfil (char *, char *, const char, int);
void strlfil (char *, char *, const char, int);
BOOL readdir (char *);
void usage ();
// Options for ReadArgs
char *template = "ARGS/M,C=CLI/S,S=SINCE/K,U=UPTO/K,AS=ALPHASORT/S,"\
"-AS=-ALPHASORT/S,SS=SIZESORT/S,-SS=-SIZESORT/S,"\
"DS=DATESORT/S,-DS=-DATESORT/S,Q=QUICK/S,DO=DIRSONLY/S,"\
"FO=FILESONLY/S,FF=FILESFIRST/S,SH=SHOWHIDDEN/S,NH=NOHEAD/S,"\
"NI=NOINFO/S,NS=NOSIZE/S,NP=NOPROTECT/S,ND=NODATE/S,"\
"NC=NOCOMMENT/S,V=VAR/K,HEADFORM/K,?=HELP/S";
struct Def
{
char **argv;
long cli;
char *since;
char *upto;
long alphasort;
long alphasortdown;
long sizesort;
long sizesortdown;
long datesort;
long datesortdown;
long quick;
long dirsonly;
long filesonly;
long filesfirst;
long showhidden;
long nohead;
long noinfo;
long nosize;
long noprotect;
long nodate;
long nocomment;
char *var;
char *headform;
long help;
} args = {NULL, FALSE, FALSE, FALSE, NULL, NULL, FALSE, FALSE,
FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE,
FALSE, FALSE, FALSE, FALSE, FALSE, NULL, " <»--«> ", FALSE};
struct RDArgs *rda = NULL;
struct FileInfoBlock *fib = NULL;
BOOL sincedate = TRUE, uptodate = TRUE;
struct DateTime *dat = NULL, *since = NULL, *upto = NULL;
char strdate[LEN_DATSTRING], strtime[LEN_DATSTRING], *pat = NULL;
// Class, in which one file or directory is stored
class Entry
{
Entry *prev, *next;
BOOL dir;
long size, days, mins;
char name[108], outstr[116];
Entry ();
int compare (const Entry *) const;
friend class Lst;
};
Entry::Entry ()
{
char *s = outstr;
prev = next = NULL;
dir = fib->fib_DirEntryType > 0 ? TRUE : FALSE;
size = fib->fib_Size;
days = fib->fib_Date.ds_Days;
mins = fib->fib_Date.ds_Minute;
strcpy (name, fib->fib_FileName);
memset (s, 0, 116);
if (args.quick) // Now fill outstr with datas according to parameters
{
strcpy (outstr, name);
return;
}
strlfil (s, name, ' ', 25);
s += 24;
if (!args.nosize)
{
if (dir)
{
strncpy (s, " (dir) ", 11);
s += 10;
}
else
{
strrfil (s, itoa (size), ' ', 7);
strcat (s, " ");
s += 10;
}
}
if (!args.noprotect)
{
int i, j;
char p[] = "hsparwed";
for (i = 128, j = 0 ; i >= 16 ; i >>= 1, j++, s++)
if (fib->fib_Protection & i)
*s = p[j];
else
*s = '-';
for (i = 8, j = 4 ; i >= 1 ; i >>= 1, j++, s++)
if (fib->fib_Protection & i)
*s = '-';
else
*s = p[j];
strcat (s, " ");
s += 3;
}
if (!args.nodate)
{
dat->dat_Stamp = fib->fib_Date;
if (DateToStr (dat))
{
strlfil (s, dat->dat_StrDate, ' ', 11);
s += 10;
strlfil (s, dat->dat_StrTime, ' ', 12);
s += 11;
}
}
if (!args.nocomment)
{
if (*fib->fib_Comment != '\0')
{
strcat (s, "\n ");
s += 4;
strncat (s, fib->fib_Comment, 40);
}
}
}
int Entry::compare (const Entry *that) const
{
if (args.alphasort || args.alphasortdown)
return stricmp (name, that->name);
else if (args.sizesort || args.sizesortdown)
return size - that->size;
else if (args.datesort || args.datesortdown)
return (days - that->days) ? (days - that->days) : (mins - that->mins);
// If the difference of the two dates is 0, then give back the difference
// of the two times
else return -1;
}
// Class, in which the entries are stored
class Lst
{
Entry *first, *last;
public:
int count, bytes;
Lst ();
~Lst ();
void insert ();
void ausgabe () const;
BOOL empty () const;
};
Lst::Lst ()
{
count = bytes = 0;
first = last = NULL;
}
Lst::~Lst ()
{
Entry *e = first;
while (e)
{
Entry *hilf = e;
e = e->next;
delete hilf;
}
}
void Lst::insert ()
{
BOOL sort = FALSE;
Entry *pos = first, *neu = NULL;
if (pat) // Is there a pattern?
if (MatchPatternNoCase (pat, fib->fib_FileName) == NULL)
return;
if (args.since) // Is there a since-option
{
if (sincedate)
{
if (fib->fib_Date.ds_Days < since->dat_Stamp.ds_Days)
return;
}
else
{
if (fib->fib_Date.ds_Minute < since->dat_Stamp.ds_Minute)
return;
}
}
if (args.upto) // Is ther a upto-option
{
if (uptodate)
{
if (fib->fib_Date.ds_Days > upto->dat_Stamp.ds_Days)
return;
}
else
{
if (fib->fib_Date.ds_Minute > upto->dat_Stamp.ds_Minute)
return;
}
}
if (fib->fib_DirEntryType < 0) // Is the entry a file
{ // and defined the user
if (args.dirsonly) // dirsonly...
return;
if (args.noinfo && strstr (fib->fib_FileName, ".info"))
return;
}
else
{
if (args.filesonly) // ...or visa versa ?
return;
}
if (!args.showhidden) // Is the 'h'-flag set
if (fib->fib_Protection & FIBF_HIDDEN)
return;
neu = new Entry ();
if (neu == NULL)
{
cout << "\nNo memory!!\n\n";
return;
}
// if neccesary, sort the entries
if (args.alphasort || args.sizesort || args.datesort)
{
while (pos && neu->compare (pos) > 0)
pos = pos->next;
sort = TRUE;
}
else if (args.alphasortdown || args.sizesortdown || args.datesortdown)
{
while (pos && neu->compare (pos) < 0)
pos = pos->next;
sort = TRUE;
}
if (sort)
{
if (pos == NULL)
{
Entry *alt = last;
if (alt != NULL)
{
alt->next = neu;
neu->prev = alt;
last = neu;
}
else
{
first = neu;
last = neu;
}
}
else
{
if (pos->prev == NULL)
{
pos->prev = neu;
neu->next = pos;
first = neu;
}
else
{
Entry *vor = pos->prev;
vor->next = neu;
neu->prev = vor;
neu->next = pos;
pos->prev = neu;
}
}
}
else
{
Entry *alt = last;
if (alt)
{
alt->next = neu;
neu->prev = alt;
last = neu;
}
else
{
first = neu;
last = neu;
}
}
count++;
if (!neu->dir)
bytes += neu->size;
return;
}
void Lst::ausgabe () const
{
for (Entry *e = first ; e ; e = e->next)
cout << " " << e->outstr << "\n";
}
BOOL Lst::empty () const
{
return first || last ? FALSE : TRUE;
}
void close_all (const char *why, const int how)
{
if (why) cout << why << "\n\n";
if (pat) delete [] pat;
if (fib) FreeDosObject (DOS_FIB, (APTR)fib);
if (upto) FreeVec ((APTR)upto);
if (since) FreeVec ((APTR)since);
if (dat) FreeVec ((APTR)dat);
if (rda) FreeArgs (rda);
exit (how);
}
char *itoa (int zahl)
{
static char res[10];
char c, *dest = res;
int maxpot = 1000000, flag = 0;
while (maxpot >= 1)
{
c = zahl / maxpot + '0';
if ((c != '0') || (maxpot == 1) || flag)
{
flag = 1;
*dest++ = c;
}
zahl %= maxpot;
maxpot /= 10;
}
*dest = '\0';
return res;
}
// Fill a string with characters. Start from right
void strrfil (char *s, char *t, const char c, int n)
{
int len = strlen (t);
while (n-- > len)
*s++ = c;
while (*s++ = *t++)
;
}
// Fill a string with characters. Start from left
void strlfil (char *s, char *t, const char c, int n)
{
while ((n-- > 0) && (*s++ = *t++))
;
s--;
while (n-- > 0)
*s++ = c;
}
BOOL readdir (char *name)
{
BOOL file = FALSE;
BPTR lock = NULL, l = NULL;
Lst *dl = new Lst, *fl = new Lst; // Create two lists, one for
// Directoriess and one for files
if (lock = Lock (name, ACCESS_READ))
{
Examine (lock, fib);
if (fib->fib_DirEntryType < 0)
{
file = TRUE;
fl->insert ();
}
else
{
while (ExNext (lock, fib) == DOSTRUE)
{
if (fib->fib_DirEntryType < 0)
fl->insert ();
else
dl->insert ();
}
}
if ((!fl->empty ()) || (!dl->empty ())) // is there something in the lists?
{
if (!args.nohead)
{
cout << '\n';
if (!file)
{
if (*name)
cout << "Directory: \x9b""1m" << name << "\x9b""0m\n\n";
else
cout << "Current Directory:\n\n";
}
}
if (args.filesfirst)
{
fl->ausgabe ();
dl->ausgabe ();
}
else
{
dl->ausgabe ();
fl->ausgabe ();
}
if (!args.nohead)
{
cout << "\n";
if (dl->count)
cout << dl->count << " Director" << (dl->count==1 ? "y" : "ies");
if (fl->count)
{
if (dl->count)
cout << args.headform;
cout << fl->count << " File" << (fl->count==1 ? "" : "s")
<< args.headform << fl->bytes << " bytes used";
}
cout << "\n\n";
}
}
delete dl;
delete fl;
UnLock (lock);
return TRUE;
}
return FALSE;
}
void usage ()
{
cout << "\x9b""32;40m\x9b""1mDirs © by Harald Pehl in 1993\n";
cout << "\x9b""31;40mOptions:\x9b""0m " << template << "\n\n";
cout << "The value in brackets is the default-value for the argument\n";
cout << "ARGS = Directory(ies) which are displayed\n"
"CLI = Read arguments ONLY via CLI (FALSE)\n"
"SINCE = Files since a date (empty)\n"
"UPTO = Files upto a date (empty)\n"
"(-)ALPHASORT = Sort by name A-Z (unsorted)\n"
"(-)SIZESORT = Sort by size 10,20,30... (unsorted)\n"
"(-)DATESORT = Sort by date 1.1.78-today (unsorted)\n"
"QUICK = Display only the name (FALSE)\n"
"DIRSONLY = Display only directories (FALSE)\n"
"FILESONLY = Display only files (FALSE)\n"
"FILESFIRST = Display files before directories (FALSE)\n"
"SHOWHIDDEN = Display hidden files (FALSE)\n"
"NOHEAD = No statusbar (FALSE)\n"
"NOINFO = Don\'t display .info - Files (FALSE)\n"
"NOSIZE = Don\'t display the size (FALSE)\n"
"NOPROTECT = Don\'t display the protection-bits (FALSE)\n"
"NODATE = Don\'t display the date (FALSE)\n"
"NOCOMMENT = Don\'t display the comment (FALSE)\n"
"VAR = Variable which will be read in (FALSE)\n"
"HEADFORM = String in the statusbar (<»--«>)\n\n";
close_all (NULL, 0);
}
void main (int argc, char **argv)
{
BPTR lock = NULL;
char name[108], str[256], var[108];
rda = ReadArgs (template, (LONG *)&args, NULL);
if (args.help)
usage ();
if (!args.cli) // Read in an ENV-variable
{
if (args.var)
{
if (strstr (args.var, "ENV:"))
strcpy (var, args.var);
else
{
strcpy (var, "ENV:\0");
strcat (var, args.var);
}
}
else
strcpy (var, "ENV:DIRCMD\0");
if (GetVar (var, str, 256, 0) != -1)
{
struct RDArgs *env = NULL;
if (env = (struct RDArgs *)AllocDosObject (DOS_RDARGS, NULL))
{
env->RDA_Source.CS_Buffer = str;
env->RDA_Source.CS_Length = strlen (str);
env->RDA_Source.CS_CurChr = 0;
env->RDA_DAList = NULL;
env->RDA_Buffer = NULL;
env->RDA_BufSiz = 0;
env->RDA_ExtHelp = NULL;
env->RDA_Flags = 0;
rda = ReadArgs (template, (LONG *)&args, env);
FreeDosObject (DOS_RDARGS, (APTR)env);
}
}
}
if (args.quick)
args.nohead = args.nosize = args.noprotect = args.nodate = args.nocomment = TRUE;
// Allocate memory and define structs, if neccesary
if (!args.nodate)
{
if (! (dat = (struct DateTime *)AllocVec (sizeof (struct DateTime), MEMF_CLEAR)))
close_all ("Kein Speicherplatz mehr", 10);
dat->dat_Stamp.ds_Days = 0;
dat->dat_Stamp.ds_Minute = 0;
dat->dat_Stamp.ds_Tick = 0;
dat->dat_Format = FORMAT_DOS;
dat->dat_Flags = DTF_SUBST;
dat->dat_StrDay = NULL;
dat->dat_StrDate = strdate;
dat->dat_StrTime = strtime;
}
if (args.since)
{
if (! (since = (struct DateTime *)AllocVec (sizeof (struct DateTime), MEMF_CLEAR)))
close_all ("Kein Speicherplatz mehr", 10);
since->dat_Stamp.ds_Days = 0;
since->dat_Stamp.ds_Minute = 0;
since->dat_Stamp.ds_Tick = 0;
since->dat_Format = FORMAT_DOS;
since->dat_Flags = DTF_SUBST;
since->dat_StrDay = NULL;
if (strchr (args.since, ':'))
{
sincedate = FALSE;
since->dat_StrDate = NULL;
since->dat_StrTime = args.since;
}
else
{
since->dat_StrDate = args.since;
since->dat_StrTime = NULL;
}
StrToDate (since);
}
if (args.upto)
{
if (! (upto = (struct DateTime *)AllocVec (sizeof (struct DateTime), MEMF_CLEAR)))
close_all ("Kein Speicherplatz mehr", 10);
upto->dat_Stamp.ds_Days = 0;
upto->dat_Stamp.ds_Minute = 0;
upto->dat_Stamp.ds_Tick = 0;
upto->dat_Format = FORMAT_DOS;
upto->dat_Flags = DTF_SUBST;
upto->dat_StrDay = NULL;
if (strchr (args.since, ':'))
{
uptodate = FALSE;
upto->dat_StrDate = NULL;
upto->dat_StrTime = args.upto;
}
else
{
upto->dat_StrDate = args.upto;
upto->dat_StrTime = NULL;
}
StrToDate (upto);
}
if (! (fib = (struct FileInfoBlock *)AllocDosObject (DOS_FIB, NULL)))
close_all ("Kein Speicherplatz mehr", 10);
argv = args.argv; // Copy dirs and files to argv
if (*argv == NULL)
{
GetCurrentDirName (name, 108);
readdir (name);
}
else
{
do
{
if (strstr (*argv, "#?") || strchr (*argv, '?'))
{
char *s = *argv;
int len = strlen (*argv) * 3;
pat = new char [len];
*argv = FilePart (*argv);
if (s != *argv)
{
strncpy (name, s, *argv-s);
name[*argv-s] = '\0';
}
else
GetCurrentDirName (name, 108);
ParsePatternNoCase (*argv, pat, len);
lock = Lock (name, ACCESS_READ);
}
else
strcpy (name, *argv);
if (!readdir (name))
cout << "\nFile/Directory not found: \'" << name << "\' !!\n\n";
argv++;
delete [] pat;
pat = NULL;
} while (*argv);
}
close_all (NULL, 0);
}