 /* Tree Directory Command by David A. Dette in Wichita, Kansas */
 /* Portions of this Program borrowed from a program named Ld */
 /* Programmed by  Dave Haynie */

 /* This command is designed to get an AmigaDOS directory and
    display it and its sub-directories to the screen.  The number of
    columns per line may be specified on the command line with a
    preceeding dash i.e. -6 would be six columns instead of the default
    of four.  The output may be redirected to the printer by using the
    standard cli redirection system but the redirection must follow the
    command and preceed any directory or column options.  */

 #include <stdio.h>
 #include <ctype.h>
 #include <libraries/dosextens.h>

 struct FileLock *Lock();  /* Lock doesn't seem declared yet. */
 int perline;

 main(argc,argv)
 int argc;
 char *argv[];
 {
    char *dirname;             /* Pointer to Starting AmigaDOS directory */
    perline = 4;

    switch (argc){
       case 1 :
          dirname = "";     /* No Directory Specified start with current */
          break;
       case 2 :
          if (argv[1][0] == '?'){
             printf("Usage: Tree [dirname] {-columns perline}\n");
             printf("Programmed by: David A. Dette\n");
             printf("               Wichita, Kansas\n");
             Exit();
          }else if (argv[1][0] == '-'){
             perline = atoi(argv[1]+1);
             dirname = "";
          }else dirname = argv[1];
          break;
       case 3 :
          if (argv[2][0] == '-'){
             perline = atoi(argv[2]+1);
             dirname = argv[1];
          }else if (argv[1][0] == '-'){
             perline = atoi(argv[1]+1);
             dirname = argv[2];
          }else dirname = argv[1];
          break;
       default :
          printf("Usage: Tree [dirname] {-columns perline}\n");
          printf("Programmed by: David A. Dette\n");
          printf("               Wichita, Kansas\n");
          Exit();
    }
    printdir(dirname);
 }


 printdir(dirname)
 char *dirname;
 {
    char *adddir();
    char *subdir[50];          /* Pointer area for Sub-Directories */
    char pathname[400];        /* Pointers to AmigaDOS sub-directories */
    struct FileLock *dir;      /* Locked AmigaDOS directory */
    struct FileInfoBlock *fb;  /* File Info from locked directory */
    BOOL fail;                 /* Directory Access Failure */
    UBYTE count;               /* Line length count */
    UBYTE countdir,indexdir;   /* Pending Directories */

    countdir = indexdir = 0;   /* Zero Directory Entry Counters */

    fb = (struct FileInfoBlock *) AllocMem(sizeof(struct FileInfoBlock),0);
    dir = Lock(dirname,ACCESS_READ);

    fail = (dir == NULL) | !Examine(dir,fb);
    if (fail) {
       printf("Invalid directory '%s' requested\n",dirname);
       UnLock(dir);
       FreeMem(fb,sizeof(struct FileInfoBlock));
       Exit();
    }

    printf("\033[7m\033[3m%s\033[0m\n",fb->fib_FileName);
    ExNext(dir,fb);

    count = 0;
    while (IoErr() != ERROR_NO_MORE_ENTRIES) {
       if (fb->fib_DirEntryType > 0){
          printf("\033[37m\033[3m%-19s\033[0m",fb->fib_FileName);
          subdir[countdir++] = adddir(fb->fib_FileName);
       }else
          printf("%-19s",fb->fib_FileName);
       count++;
       if (count == perline) {
          printf("\n");
          count = 0;
       }
       ExNext(dir,fb);
    }
    if (count != 0) printf("\n");
    printf("\n");
    UnLock(dir);
    FreeMem(fb,sizeof(struct FileInfoBlock));
    
    while (indexdir < countdir){
       strcpy(pathname,dirname);
       if ((dirname[strlen(dirname)-1] != ':') &&
           (dirname[strlen(dirname)-1] != '/') && (strlen(dirname) > 0))
          strcat(pathname,"/");
       strcat(pathname,subdir[indexdir]);
       printdir(pathname);
       FreeMem(subdir[indexdir],strlen(subdir[indexdir])+1);
       indexdir++;
    }
    return;
 }


 char *adddir(dirname)
 char *dirname;
 {
    char *nameadd;    /* Address of the directory name */

    nameadd = AllocMem(strlen(dirname)+1,0);
    if (nameadd == NULL){
       printf("Not Enough Memory for Directories!!!\n");
       Exit();
    }
    return(strcpy(nameadd,dirname));
 }

