home *** CD-ROM | disk | FTP | other *** search
- /* Copyright (c) 1992 Torsten Poulin
- * 23-Feb-92 Version 1
- *
- * The bit-map code in this program was picked up from Dr. Dobb's
- * I think, but I don't remember which volume ;-(
- */
-
- /* Define LOCKALL to ensure that directories being examined
- * don't disappear before we're done with them.
- * The disadvantage is that we use more memory.
- */
- #define LOCKALL
-
-
- /****** English:DIRTREE ***************************************************
- *
- * FORMAT
- * DirTree [DIR] {<directory>} [NOHEAD]
- *
- * TEMPLATE
- * DIR/A/M,NOHEAD/S
- *
- * PURPOSE
- * To print sub-directory trees.
- *
- * SPECIFICATION
- * DirTree displays the sub-directory trees for the directories
- * or volumes specified in the DIR argument. The NOHEAD switch
- * suppresses the printing of the header information.
- *
- * EXAMPLE
- * 1> DIRTREE ram:
- * Directory tree for "ram:" on Saturday 22-Feb-92
- *
- * Ram Disk
- * +---Clipboards
- * +---env
- * | `---sys
- * |
- * `---T
- *
- * SEE ALSO
- * DIR, LIST
- *
- ***************************************************************************
- *
- */
- /****** dansk:DIRTREE *****************************************************
- *
- * FORMAT
- * DirTree [DIR] {<katalog>} [NOHEAD]
- *
- * SKABELON
- * DIR/A/M,NOHEAD/S
- *
- * FORMÅL
- * At udskrive underkatalogtræer.
- *
- * SPECIFIKATION
- * DirTree viser underkatalogtræer for de kataloger eller diske
- * som er givet ved argumentet DIR. Kontakten NOHEAD
- * undertrykker udskrivningen af overskriftinformationen.
- *
- * EKSEMPEL
- * 1> DIRTREE ram:
- * Directory tree for "ram:" on Saturday 22-Feb-92
- *
- * Ram Disk
- * +---Clipboards
- * +---env
- * | `---sys
- * |
- * `---T
- *
- * SE OGSÅ
- * DIR, LIST
- *
- ***************************************************************************
- *
- */
-
-
- #include <exec/types.h>
- #include <exec/memory.h>
- #include <dos/dos.h>
- #include <dos/dostags.h>
- #include <dos/datetime.h>
- #include <string.h>
-
- #include <proto/exec.h>
- #include <proto/dos.h>
-
- /* my include files are for early V36, so ... */
- #pragma libcall UtilityBase Stricmp A2 9802
- LONG Stricmp(char *, char *);
-
- #define BAR "| "
- #define ELL "`---"
- #define TEE "+---"
-
- struct nameList {
- struct nameList *next;
- char *name;
- #ifdef LOCKALL
- BPTR lock;
- #endif
- };
-
- typedef struct global {
- struct Library *SysBase;
- struct DosLibrary *DOSBase;
- struct Library *UtilityBase;
-
- char Map[64 / 8];
- } Global;
-
- char const *version = "\0$VER: DirTree 37.1 (23.2.92) ©1992 Torsten Poulin";
-
- static VOID setbit(Global *global, LONG c, LONG val);
- static VOID print_bars(Global *global, LONG depth, LONG terminate);
- static LONG printdtree(Global *global, UBYTE *dname, LONG others);
- LONG dirtree(Global *global, char *dirname, BOOL nohead);
-
-
- LONG entrypoint(VOID)
- {
- struct Library *SysBase;
- struct DosLibrary *DOSBase;
- struct Library *UtilityBase;
- Global *global;
-
- struct RDArgs *args;
- LONG arg[2];
- LONG rc = RETURN_OK;
- UBYTE **dir;
-
- arg[0] = arg[1] = 0L;
-
- SysBase = *(struct Library **) 4L;
-
- if(!(global = AllocMem(sizeof(Global), MEMF_PUBLIC | MEMF_CLEAR)))
- return RETURN_FAIL;
-
- global->SysBase = SysBase;
- if(!(global->DOSBase = DOSBase = (struct DosLibrary *)
- OpenLibrary("dos.library", 37L)))
- {
- rc = RETURN_FAIL;
- goto noDOS;
- }
- if(!(global->UtilityBase = UtilityBase =
- OpenLibrary("utility.library", 37L)))
- {
- rc = RETURN_FAIL;
- goto noUtility;
- }
-
- if(args = ReadArgs("DIR/A/M,NOHEAD/S", arg, NULL))
- {
- for(dir = (UBYTE **) *arg; *dir && rc == RETURN_OK; dir++)
- rc = dirtree(global, *dir, (BOOL) arg[1]);
- FreeArgs(args);
- }
- else
- {
- LONG err = IoErr();
- PrintFault(err, "DirTree");
- rc = RETURN_ERROR;
- }
-
- CloseLibrary(UtilityBase);
- noUtility:
- CloseLibrary((struct DosBase *) DOSBase);
- noDOS:
- FreeMem(global, sizeof(Global));
- return rc;
- }
-
-
- #define testbit(x) ( global->Map[x >> 3] & (1 << (x & 0x07)) )
-
- static VOID setbit(Global *global, LONG c, LONG val)
- {
- if(val)
- global->Map[c >> 3] |= 1 << (c & 0x07);
- else
- global->Map[c >> 3] &= ~(1 << (c & 0x07));
- }
-
-
- static VOID print_bars(Global *global, LONG depth, LONG terminate)
- {
- struct DosLibrary *DOSBase = global->DOSBase;
- LONG i;
-
- for(i = 0; i < depth - 1; i++)
- PutStr(testbit(i) ? BAR : " ");
-
- if(terminate)
- PutStr("\n");
- }
-
-
- static LONG printdtree(Global *global, UBYTE *dname, LONG others)
- {
- struct Library *SysBase = global->SysBase;
- struct DosLibrary *DOSBase = global->DOSBase;
- struct Library *UtilityBase = global->UtilityBase;
-
- struct FileInfoBlock *m;
- BPTR lock, oldlock;
- static LONG depth = -1;
- LONG count = 0;
- LONG rc = RETURN_OK;
- ULONG ADOtag = TAG_DONE;
- struct nameList *list, *p;
- BOOL OutOfMemory = FALSE;
-
- list = NULL;
-
- m = AllocDosObject(DOS_FIB, (struct TagItem *) &ADOtag);
-
- if(lock = Lock(dname, SHARED_LOCK))
- {
- oldlock = CurrentDir(lock);
- if(Examine(lock, m))
- {
- if(m->fib_DirEntryType < 0)
- {
- PrintFault(ERROR_OBJECT_WRONG_TYPE, dname);
- CurrentDir(oldlock);
- UnLock(lock);
- FreeDosObject(DOS_FIB, m);
- return RETURN_WARN;
- }
-
- if(++depth)
- {
- print_bars(global, depth, 0);
- PutStr(others ? TEE : ELL);
- }
- PutStr(m->fib_FileName /*dname*/);
- PutStr("\n");
-
- while(ExNext(lock, m))
- if(m->fib_DirEntryType > 0)
- {
- struct nameList *newnode;
-
- /* Store the directory name */
- if(!(newnode = AllocMem(sizeof(struct nameList),
- MEMF_PUBLIC)))
- {
- PrintFault(ERROR_NO_FREE_STORE, "DirTree");
- rc = RETURN_FAIL;
- OutOfMemory = TRUE;
- break;
- }
- if(!(newnode->name = AllocMem(strlen(m->fib_FileName) + 1,
- MEMF_PUBLIC)))
- {
- PrintFault(ERROR_NO_FREE_STORE, "DirTree");
- rc = RETURN_FAIL;
- OutOfMemory = TRUE;
- break;
- }
- strcpy(newnode->name, m->fib_FileName);
- #ifdef LOCKALL
- newnode->lock = Lock(m->fib_FileName, SHARED_LOCK);
- #endif
- /* Insert */
- newnode->next = NULL;
-
- if(list == NULL) /* insert into empty list */
- list = newnode;
- else
- {
- /* inserting into nonempty list */
- p = list;
-
- if(Stricmp(m->fib_FileName, p->name) < 0)
- {
- /* insert before first node */
- newnode->next = list;
- list = newnode;
- }
- else
- {
- /* general case */
- for(; p->next; p = p->next)
- if(Stricmp(m->fib_FileName,p->next->name) < 0)
- break;
- newnode->next = p->next;
- p->next = newnode;
- }
- }
- ++count;
- }
- }
-
- /* Traverse the list and free up memory */
- for(p = list; p; )
- {
- struct nameList *remember;
-
- remember = p;
- if(!OutOfMemory)
- {
- --count;
- setbit(global, depth, count);
- rc = printdtree(global, p->name, count);
- }
- p = p->next;
- #ifdef LOCKALL
- UnLock(remember->lock);
- #endif
- FreeMem(remember->name, strlen(remember->name) + 1);
- FreeMem(remember, sizeof(struct nameList));
- }
- CurrentDir(oldlock);
- UnLock(lock);
- }
- else
- {
- LONG err = IoErr();
- PrintFault(err, dname);
- rc = RETURN_ERROR;
- }
- if(!others)
- print_bars(global, depth, 1);
- --depth;
-
- FreeDosObject(DOS_FIB, m);
- return rc;
- }
-
-
- LONG dirtree(Global *global, char *dirname, BOOL nohead)
- {
- struct DosLibrary *DOSBase = global->DOSBase;
- struct DateTime dt;
- char day[LEN_DATSTRING], date[LEN_DATSTRING];
-
- if(!nohead)
- {
- DateStamp(&dt.dat_Stamp);
- dt.dat_Format = FORMAT_DOS;
- dt.dat_Flags = NULL;
- dt.dat_StrDay = day;
- dt.dat_StrDate = date;
- dt.dat_StrTime = NULL;
- DateToStr(&dt);
-
- PutStr("Directory tree for \"");
- PutStr(dirname);
- PutStr("\" on ");
- PutStr(day);
- PutStr(" ");
- PutStr(date);
- PutStr("\n\n");
- }
- return printdtree(global, dirname, 0);
- }
-