home *** CD-ROM | disk | FTP | other *** search
/ Frozen Fish 1: Amiga / FrozenFish-Apr94.iso / bbs / oct93 / cli_util / dirs.lha / Dirs / Deutsch / dirs.c < prev    next >
C/C++ Source or Header  |  1993-08-23  |  16KB  |  659 lines

  1. // dirs geschrieben von Harald Pehl
  2. // Letze Änderung am 23.August.1993, 18:30:24
  3. // Version 1.00
  4. // compiliert mit MaxonC++
  5.  
  6.  
  7. // Includes
  8. #include <pragma/exec_lib.h>
  9. #include <pragma/dos_lib.h>
  10. #include <dos/dosextens.h>
  11. #include <dos/datetime.h>
  12. #include <exec/memory.h>
  13. #include <dos/dos.h>
  14. #include <stream.h>
  15. #include <stdlib.h>
  16. #include <string.h>
  17. #include <ctype.h>
  18. #include <stdio.h>
  19.  
  20.  
  21. // Funktionen
  22. void close_all (const char *, const int);
  23. char *itoa (int);
  24. void strrfil (char *, char *, const char, int);
  25. void strlfil (char *, char *, const char, int);
  26. BOOL readdir (char *);
  27. void usage ();
  28.  
  29.  
  30.  
  31. // Optionen für ReadArgs
  32. char *template = "ARGS/M,C=CLI/S,S=SINCE/K,U=UPTO/K,AS=ALPHASORT/S,"\
  33.                  "-AS=-ALPHASORT/S,SS=SIZESORT/S,-SS=-SIZESORT/S,"\
  34.                  "DS=DATESORT/S,-DS=-DATESORT/S,Q=QUICK/S,DO=DIRSONLY/S,"\
  35.                  "FO=FILESONLY/S,FF=FILESFIRST/S,SH=SHOWHIDDEN/S,NH=NOHEAD/S,"\
  36.                  "NI=NOINFO/S,NS=NOSIZE/S,NP=NOPROTECT/S,ND=NODATE/S,"\
  37.                  "NC=NOCOMMENT/S,V=VAR/K,HEADFORM/K,?=HELP/S";
  38.  
  39. struct Def
  40. {
  41.    char **argv;
  42.    long cli;
  43.    char *since;
  44.    char *upto;
  45.    long alphasort;
  46.    long alphasortdown;
  47.    long sizesort;
  48.    long sizesortdown;
  49.    long datesort;
  50.    long datesortdown;
  51.    long quick;
  52.    long dirsonly;
  53.    long filesonly;
  54.    long filesfirst;
  55.    long showhidden;
  56.    long nohead;
  57.    long noinfo;
  58.    long nosize;
  59.    long noprotect;
  60.    long nodate;
  61.    long nocomment;
  62.    char *var;
  63.    char *headform;
  64.    long help;
  65. } args = {NULL,  FALSE, FALSE, FALSE, NULL,  NULL,  FALSE, FALSE,
  66.           FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE,
  67.           FALSE, FALSE, FALSE, FALSE, FALSE, NULL,  "  <»--«>  ", FALSE};
  68.  
  69.  
  70.  
  71. struct RDArgs *rda = NULL;
  72. struct FileInfoBlock *fib = NULL;
  73. BOOL sincedate = TRUE, uptodate = TRUE;
  74. struct DateTime *dat = NULL, *since = NULL, *upto = NULL;
  75. char strdate[LEN_DATSTRING], strtime[LEN_DATSTRING], *pat = NULL;
  76.  
  77.  
  78. // Klasse, in der ein File bzw. Directory festgehalten wird
  79. class Entry
  80. {
  81.    Entry *prev, *next;
  82.    BOOL dir;
  83.    long size, days, mins;
  84.    char name[108], outstr[116];
  85.    
  86.    Entry ();
  87.    int compare (const Entry *) const;
  88.    friend class Lst;
  89. };
  90.  
  91.  
  92. Entry::Entry ()
  93. {
  94.    char *s = outstr;
  95.    
  96.    prev = next = NULL;
  97.    dir  = fib->fib_DirEntryType > 0 ? TRUE : FALSE;
  98.    size = fib->fib_Size;
  99.    days = fib->fib_Date.ds_Days;
  100.    mins = fib->fib_Date.ds_Minute;
  101.    strcpy (name, fib->fib_FileName);
  102.    memset (s, 0, 116);
  103.    if (args.quick)      // Jetzt outstr je nach Parameter mit Daten auffüllen
  104.    {
  105.       strcpy (outstr, name);
  106.       return;
  107.    }
  108.    strlfil (s, name, ' ', 25);
  109.    s += 24;
  110.    if (!args.nosize)
  111.    {
  112.       if (dir)
  113.       {
  114.          strncpy (s, "  (dir)   ", 11);
  115.          s += 10;
  116.       }
  117.       else
  118.       {
  119.          strrfil (s, itoa (size), ' ', 7);
  120.          strcat (s, "    "); 
  121.          s += 10;
  122.       }
  123.    }
  124.    if (!args.noprotect)
  125.    {
  126.       int i, j;
  127.       char p[] = "hsparwed";
  128.       
  129.       for (i = 128, j = 0 ; i >= 16 ; i >>= 1, j++, s++)
  130.          if (fib->fib_Protection & i)
  131.             *s = p[j];
  132.          else
  133.             *s = '-';
  134.       for (i = 8, j = 4 ; i >= 1 ; i >>= 1, j++, s++)
  135.          if (fib->fib_Protection & i)
  136.             *s = '-';
  137.          else
  138.             *s = p[j];
  139.       strcat (s, "    ");
  140.       s += 3;
  141.    }
  142.    if (!args.nodate)
  143.    {
  144.       dat->dat_Stamp = fib->fib_Date;
  145.       if (DateToStr (dat))
  146.       {
  147.          strlfil (s, dat->dat_StrDate, ' ', 11);
  148.          s += 10;
  149.          strlfil (s, dat->dat_StrTime, ' ', 12);
  150.          s += 11;
  151.       }
  152.    }
  153.    if (!args.nocomment)
  154.    {
  155.       if (*fib->fib_Comment != '\0')
  156.       {
  157.          strcat (s, "\n    ");
  158.          s += 4;
  159.          strncat (s, fib->fib_Comment, 40);
  160.       }
  161.    }
  162. }
  163.  
  164.  
  165. int Entry::compare (const Entry *that) const
  166. {
  167.    if (args.alphasort || args.alphasortdown)
  168.       return stricmp (name, that->name);
  169.    else if (args.sizesort || args.sizesortdown)
  170.       return size - that->size;
  171.    else if (args.datesort || args.datesortdown)
  172.       return (days - that->days) ? (days - that->days) : (mins - that->mins);
  173.       // Wenn die Differenz der zwei Daten 0 ist, dann wird die Differenz
  174.       // der zwei Zeitangaben zurückgegeben
  175.    else return -1;
  176. }
  177.  
  178.  
  179. // Klasse, die die Einträge enthält
  180. class Lst
  181. {
  182.    Entry *first, *last;
  183.    
  184.    public:
  185.    int count, bytes;
  186.    
  187.    Lst ();
  188.    ~Lst ();
  189.    void insert ();
  190.    void ausgabe () const;
  191.    BOOL empty () const;
  192. };
  193.  
  194.  
  195. Lst::Lst ()
  196. {
  197.    count = bytes = 0;
  198.    first = last = NULL;
  199. }
  200.  
  201.  
  202. Lst::~Lst ()
  203. {
  204.    Entry *e = first;
  205.    
  206.    while (e)
  207.    {
  208.       Entry *hilf = e;
  209.       e = e->next;
  210.       delete hilf;
  211.    }
  212. }
  213.  
  214.  
  215. void Lst::insert ()
  216. {
  217.    BOOL sort = FALSE;
  218.    Entry *pos = first, *neu = NULL;
  219.    
  220.    if (pat)             // Ist ein Pattern definiert?
  221.       if (MatchPatternNoCase (pat, fib->fib_FileName) == NULL)
  222.          return;
  223.    if (args.since)      // Gibt es eine since-Vorgabe
  224.    {
  225.       if (sincedate)
  226.       {
  227.          if (fib->fib_Date.ds_Days < since->dat_Stamp.ds_Days)
  228.             return;
  229.       }
  230.       else
  231.       {
  232.          if (fib->fib_Date.ds_Minute < since->dat_Stamp.ds_Minute)
  233.             return;
  234.       }
  235.    }
  236.    if (args.upto)       // Gibt es eine upto-Vorgabe
  237.    {
  238.       if (uptodate)
  239.       {
  240.          if (fib->fib_Date.ds_Days > upto->dat_Stamp.ds_Days)
  241.             return;
  242.       }
  243.       else
  244.       {
  245.          if (fib->fib_Date.ds_Minute > upto->dat_Stamp.ds_Minute)
  246.             return;
  247.       }
  248.    }
  249.    if (fib->fib_DirEntryType < 0)   // Ist der Eintrag ein File
  250.    {                                // und sind nur Dirs
  251.       if (args.dirsonly)            // zugelassen...
  252.          return;
  253.       if (args.noinfo && strstr (fib->fib_FileName, ".info"))
  254.          return;
  255.    }
  256.    else
  257.    {
  258.       if (args.filesonly)           // ...oder umgekehrt?
  259.          return;
  260.    }
  261.    if (!args.showhidden)            // Ist das 'h'-Bit gesetzt
  262.       if (fib->fib_Protection & FIBF_HIDDEN)
  263.          return;
  264.    neu = new Entry ();
  265.    if (neu == NULL)
  266.    {
  267.       cout << "\nKein Speicherplatz mehr!!\n\n";
  268.       return;
  269.    }
  270.    
  271.    // Sortieren falls nötig
  272.    if (args.alphasort || args.sizesort || args.datesort)
  273.    {
  274.       while (pos && neu->compare (pos) > 0)
  275.          pos = pos->next;
  276.       sort = TRUE;
  277.    }
  278.    else if (args.alphasortdown || args.sizesortdown || args.datesortdown)
  279.    {
  280.       while (pos && neu->compare (pos) < 0)
  281.          pos = pos->next;
  282.       sort = TRUE;
  283.    }
  284.    if (sort)
  285.    {
  286.       // und endlich einfügen
  287.       if (pos == NULL)
  288.       {
  289.          Entry *alt = last;
  290.  
  291.          if (alt != NULL)
  292.          {
  293.             alt->next = neu;
  294.             neu->prev = alt;
  295.             last = neu;
  296.          }
  297.          else
  298.          {
  299.             first = neu;
  300.             last = neu;
  301.          }
  302.       }
  303.       else
  304.       {
  305.          if (pos->prev == NULL)
  306.          {
  307.             pos->prev = neu;
  308.             neu->next = pos;
  309.             first = neu;
  310.          }
  311.          else
  312.          {
  313.             Entry *vor = pos->prev;
  314.             
  315.             vor->next = neu;
  316.             neu->prev = vor;
  317.             neu->next = pos;
  318.             pos->prev = neu;
  319.          }
  320.       }
  321.    }
  322.    else
  323.    {
  324.       Entry *alt = last;
  325.    
  326.       if (alt)
  327.       {
  328.          alt->next = neu;
  329.          neu->prev = alt;
  330.          last = neu;
  331.       }
  332.       else
  333.       {
  334.          first = neu;
  335.          last = neu;
  336.       }
  337.    }
  338.    count++;
  339.    if (!neu->dir)
  340.       bytes += neu->size;
  341.    return;
  342. }
  343.  
  344.  
  345. void Lst::ausgabe () const
  346. {
  347.    for (Entry *e = first ; e ; e = e->next)
  348.       cout << "   " << e->outstr << "\n";
  349. }
  350.  
  351.  
  352. BOOL Lst::empty () const
  353. {
  354.    return first || last ? FALSE : TRUE;
  355. }
  356.  
  357.  
  358.  
  359. void close_all (const char *why, const int how)
  360. {
  361.    if (why)    cout << why << "\n\n";
  362.    if (pat)    delete [] pat;
  363.    if (fib)    FreeDosObject (DOS_FIB, (APTR)fib);
  364.    if (upto)   FreeVec ((APTR)upto);
  365.    if (since)  FreeVec ((APTR)since);
  366.    if (dat)    FreeVec ((APTR)dat);
  367.    if (rda)    FreeArgs (rda);
  368.    exit (how);
  369. }
  370.  
  371.  
  372. char *itoa (int zahl)
  373. {
  374.    static char res[10];
  375.    char c, *dest = res;
  376.    int maxpot = 1000000, flag = 0;
  377.    
  378.    while (maxpot >= 1)
  379.    {
  380.       c = zahl / maxpot + '0';
  381.       if ((c != '0') || (maxpot == 1) || flag)
  382.       {
  383.          flag = 1;
  384.          *dest++ = c;
  385.       }
  386.       zahl %= maxpot;
  387.       maxpot /= 10;
  388.    }
  389.    *dest = '\0';
  390.    return res;
  391. }
  392.  
  393. // Auffüllen eines Stringes mit einem Zeichen von rechts
  394. void strrfil (char *s, char *t, const char c, int n)
  395. {
  396.    int len = strlen (t);
  397.    
  398.    while (n-- > len)
  399.       *s++ = c;
  400.    while (*s++ = *t++)
  401.       ;
  402. }
  403.  
  404. // Auffüllen eines Stringes mit einem Zeichen von links
  405. void strlfil (char *s, char *t, const char c, int n)
  406. {
  407.    while ((n-- > 0) && (*s++ = *t++))
  408.       ;
  409.    s--;
  410.    while (n-- > 0)
  411.       *s++ = c;
  412. }
  413.  
  414.  
  415. BOOL readdir (char *name)
  416. {
  417.    BOOL file = FALSE;
  418.    BPTR lock = NULL, l = NULL;
  419.    Lst *dl = new Lst, *fl = new Lst;   // Zwei Listen anlegen, eine für
  420.                                        // Dirs eine für Files
  421.    if (lock = Lock (name, ACCESS_READ))
  422.    {
  423.       Examine (lock, fib);
  424.       if (fib->fib_DirEntryType < 0)
  425.       {
  426.          file = TRUE;
  427.          fl->insert ();
  428.       }
  429.       else
  430.       {
  431.          while (ExNext (lock, fib) == DOSTRUE)
  432.          {
  433.             if (fib->fib_DirEntryType < 0)
  434.                fl->insert ();
  435.             else
  436.                dl->insert ();
  437.          }
  438.       }
  439.       if ((!fl->empty ()) || (!dl->empty ()))   // steht was in den Listen?
  440.       {
  441.          if (!args.nohead)
  442.          {
  443.             cout << '\n';
  444.             if (!file)
  445.             {
  446.                if (*name)
  447.                   cout << "Verzeichnis: \x9b""1m" << name << "\x9b""0m\n\n";
  448.                else
  449.                   cout << "Aktuelles Verzeichnis:\n\n";
  450.             }
  451.          }
  452.          if (args.filesfirst)
  453.          {
  454.             fl->ausgabe ();
  455.             dl->ausgabe ();
  456.          }
  457.          else
  458.          {
  459.             dl->ausgabe ();
  460.             fl->ausgabe ();
  461.          }
  462.          if (!args.nohead)
  463.          {
  464.             cout << "\n";
  465.             if (dl->count)
  466.                cout << dl->count << " Verzeichnis" << (dl->count==1 ? "" : "se");
  467.             if (fl->count)
  468.             {
  469.                if (dl->count)
  470.                   cout << args.headform;
  471.                cout << fl->count << " Datei" << (fl->count==1 ? "" : "en")
  472.                     << args.headform << fl->bytes << " Bytes benutzt";
  473.             }
  474.             cout << "\n\n";
  475.          }
  476.       }
  477.       delete dl;
  478.       delete fl;
  479.       UnLock (lock);
  480.       return TRUE;
  481.    }
  482.    return FALSE;
  483. }
  484.  
  485.  
  486. void usage ()
  487. {
  488.    cout << "\x9b""32;40m\x9b""1mDirs © by  Harald Pehl in 1993\n";
  489.    cout << "\x9b""31;40mOptionen:\x9b""0m " << template << "\n\n";
  490.    cout << "In den Klammern ist die jeweilige Grund-Einstellung angegeben\n";
  491.    cout << "ARGS         = Verzeichnis(se) die aufgelistet werden\n"
  492.            "CLI          = Parameter NUR übers CLI einlesen  (aus)\n"
  493.            "SINCE        = Dateien seit einem Datum          (leer)\n"
  494.            "UPTO         = Dateien bis zu einem Datum        (leer)\n"
  495.            "(-)ALPHASORT = Nach Namen sortieren A-Z          (unsortiert)\n"
  496.            "(-)SIZESORT  = Nach Größe sortieren 10,20,30...  (unsortiert)\n"
  497.            "(-)DATESORT  = Nach Datum sortieren 1.1.78-heute (unsortiert)\n"
  498.            "QUICK        = Nur den Dateinamen ausgeben       (aus)\n"
  499.            "DIRSONLY     = Nur Directories ausgeben          (aus)\n"
  500.            "FILESONLY    = Nur Files ausgeben                (aus)\n"
  501.            "FILESFIRST   = Files vor Directories ausgeben    (aus)\n"
  502.            "SHOWHIDDEN   = Versteckte Dateien mitanzeigen    (aus)\n"
  503.            "NOHEAD       = Keine Kopf- und Fußzeile          (aus)\n"
  504.            "NOINFO       = Keine .info - Dateien ausgeben    (aus)\n"
  505.            "NOSIZE       = Keine Größe ausgeben              (aus)\n"
  506.            "NOPROTECT    = Keine Schutzbits ausgeben         (aus)\n"
  507.            "NODATE       = Kein Datum ausgeben               (aus)\n"
  508.            "NOCOMMENT    = Kein Kommentar  ausgeben          (aus)\n"
  509.            "VAR          = Variable, die ausgelesen wird     (aus)\n"
  510.            "HEADFORM     = Zeichenkette in der Fußzeile      (<»--«>)\n\n";
  511.    close_all (NULL, 0);
  512. }
  513.  
  514.  
  515. void main (int argc, char **argv)
  516. {
  517.    BPTR lock = NULL;
  518.    char name[108], str[256], var[108];
  519.    
  520.    rda = ReadArgs (template, (LONG *)&args, NULL);
  521.    if (args.help)
  522.       usage ();
  523.    if (!args.cli)       // Eine ENV-Variable wird eingelesen
  524.    {
  525.       if (args.var)
  526.       {                                      // var in richtige Form bringen...
  527.          if (strstr (args.var, "ENV:"))
  528.             strcpy (var, args.var);
  529.          else
  530.          {
  531.             strcpy (var, "ENV:\0");
  532.             strcat (var, args.var);
  533.          }
  534.       }
  535.       else
  536.          strcpy (var, "ENV:DIRCMD\0");
  537.       if (GetVar (var, str, 256, 0) != -1)   // ...und einlesen
  538.       {
  539.          struct RDArgs *env = NULL;
  540.    
  541.          if (env = (struct RDArgs *)AllocDosObject (DOS_RDARGS, NULL))
  542.          {
  543.             env->RDA_Source.CS_Buffer = str;
  544.             env->RDA_Source.CS_Length = strlen (str);
  545.             env->RDA_Source.CS_CurChr = 0;
  546.             env->RDA_DAList  = NULL;
  547.             env->RDA_Buffer  = NULL;
  548.             env->RDA_BufSiz  = 0;
  549.             env->RDA_ExtHelp = NULL;
  550.             env->RDA_Flags   = 0;
  551.             rda = ReadArgs (template, (LONG *)&args, env);
  552.             FreeDosObject (DOS_RDARGS, (APTR)env);
  553.          }
  554.       }
  555.    }
  556.    if (args.quick)
  557.       args.nohead = args.nosize = args.noprotect = args.nodate = args.nocomment = TRUE;
  558.    // Strukturen anlegen und Speicher allokieren, falls erforderlich
  559.    if (!args.nodate)
  560.    {
  561.       if (! (dat = (struct DateTime *)AllocVec (sizeof (struct DateTime), MEMF_CLEAR)))
  562.          close_all ("Kein Speicherplatz mehr", 10);
  563.       dat->dat_Stamp.ds_Days   = 0;
  564.       dat->dat_Stamp.ds_Minute = 0;
  565.       dat->dat_Stamp.ds_Tick   = 0;
  566.       dat->dat_Format  = FORMAT_DOS;
  567.       dat->dat_Flags   = DTF_SUBST;
  568.       dat->dat_StrDay  = NULL;
  569.       dat->dat_StrDate = strdate;
  570.       dat->dat_StrTime = strtime;
  571.    }
  572.    if (args.since)
  573.    {
  574.       if (! (since = (struct DateTime *)AllocVec (sizeof (struct DateTime), MEMF_CLEAR)))
  575.          close_all ("Kein Speicherplatz mehr", 10);
  576.       since->dat_Stamp.ds_Days   = 0;
  577.       since->dat_Stamp.ds_Minute = 0;
  578.       since->dat_Stamp.ds_Tick   = 0;
  579.       since->dat_Format = FORMAT_DOS;
  580.       since->dat_Flags  = DTF_SUBST;
  581.       since->dat_StrDay = NULL;
  582.       if (strchr (args.since, ':'))
  583.       {
  584.          sincedate = FALSE;
  585.          since->dat_StrDate = NULL;
  586.          since->dat_StrTime = args.since;
  587.       }
  588.       else
  589.       {
  590.          since->dat_StrDate = args.since;
  591.          since->dat_StrTime = NULL;
  592.       }
  593.       StrToDate (since);
  594.    }
  595.    if (args.upto)
  596.    {
  597.       if (! (upto = (struct DateTime *)AllocVec (sizeof (struct DateTime), MEMF_CLEAR)))
  598.          close_all ("Kein Speicherplatz mehr", 10);
  599.       upto->dat_Stamp.ds_Days   = 0;
  600.       upto->dat_Stamp.ds_Minute = 0;
  601.       upto->dat_Stamp.ds_Tick   = 0;
  602.       upto->dat_Format = FORMAT_DOS;
  603.       upto->dat_Flags  = DTF_SUBST;
  604.       upto->dat_StrDay = NULL;
  605.       if (strchr (args.since, ':'))
  606.       {
  607.          uptodate = FALSE;
  608.          upto->dat_StrDate = NULL;
  609.          upto->dat_StrTime = args.upto;
  610.       }
  611.       else
  612.       {
  613.          upto->dat_StrDate = args.upto;
  614.          upto->dat_StrTime = NULL;
  615.       }
  616.       StrToDate (upto);
  617.    }
  618.    if (! (fib = (struct FileInfoBlock *)AllocDosObject (DOS_FIB, NULL)))
  619.       close_all ("Kein Speicherplatz mehr", 10);
  620.    argv = args.argv;    // Dirs und Files in argv kopieren
  621.    if (*argv == NULL)
  622.    {
  623.       GetCurrentDirName (name, 108);
  624.       readdir (name);
  625.    }
  626.    else
  627.    {
  628.       do
  629.       {
  630.          if (strstr (*argv, "#?") || strchr (*argv, '?'))
  631.          {
  632.             char *s = *argv;
  633.             int len = strlen (*argv) * 3;
  634.             
  635.             pat = new char [len];
  636.             *argv = FilePart (*argv);
  637.             if (s != *argv)
  638.             {
  639.                strncpy (name, s, *argv-s);
  640.                name[*argv-s] = '\0';
  641.             }
  642.             else
  643.                GetCurrentDirName (name, 108);
  644.             ParsePatternNoCase (*argv, pat, len);
  645.             lock = Lock (name, ACCESS_READ);
  646.          }
  647.          else
  648.             strcpy (name, *argv);
  649.          if (!readdir (name))
  650.             cout << "\nUngültiger Dateiname: \'" << name << "\' !!\n\n";
  651.          argv++;
  652.          delete [] pat;
  653.          pat = NULL;
  654.       } while (*argv);
  655.    }  
  656.    close_all (NULL, 0);
  657. }
  658.  
  659.