home *** CD-ROM | disk | FTP | other *** search
- // 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);
- }
-
-