home *** CD-ROM | disk | FTP | other *** search
- #define MADE_VIA_MY_SHELL /*
- local f
- strrhead f . $_srcfile
- cc $f; ln -t $f -Lc
- return $_maxerr
- *
- * $Id: GDu.c 1.2 1994/10/26 22:35:31 RK Exp RK $
- * $Log: GDu.c $
- * Revision 1.2 1994/10/26 22:35:31 RK
- * FreeVec(Fib)-Bug fixed / New Options: -num -links
- * Dir-request / can be called from WB
- *
- * Revision 1.1 1994/10/16 16:43:53 RK
- * Initial revision
- *
- * GDu - graphically display disk usage
- * Copyright (C) 1994 Rainer Köhler
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 1, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
- #include <exec/types.h>
- #include <exec/memory.h>
- #include <graphics/gfx.h>
- #include <graphics/text.h>
- #include <intuition/intuition.h>
- #include <libraries/dos.h>
- #include <libraries/dosextens.h>
- #include <libraries/asl.h>
- #include <functions.h>
- #include <stdlib.h>
- #include <string.h>
- #include <stdio.h>
-
- static char Version[]= "$VER: GDu 1.1 (26.10.94)";
-
- #define WIDTH (12*8)
-
- #define Fib_Type Fib->fib_DirEntryType /** Fasse Dich kurz! **/
-
- struct Library *IntuitionBase, *GfxBase, *AslBase;
- struct Window *Win;
- struct RastPort *RPort;
-
- char *MyName= "GDu";
- long ForeGround=1, BackGround=0;
- BOOL Quiet= FALSE, SortSize= FALSE, ShowLinks= FALSE;
-
- struct Dir
- { struct Dir *Next;
- struct Dir *Prev;
- struct Dir *Parent;
- struct Dir *Subdir;
- char Name[30];
- ULONG FileSize;
- ULONG Total;
- USHORT Top;
- } RootNode, *BaseNode;
-
-
- void _wb_parse() {}
-
- char Indentation[100];
-
-
- static long AddObj( struct Dir *Parent, BPTR lock) /** recursive! **/
- {
- struct FileInfoBlock *Fib;
- struct Dir *Node, *Next, *Last;
- BPTR cwd, sublock;
- long objsz, totsz=1; /** 1 for UserDir-Block **/
- long indent;
-
- if( !(Fib= AllocVec(sizeof(struct FileInfoBlock),MEMF_PUBLIC)))
- return 0;
-
- cwd= CurrentDir(lock);
- if( Examine(lock,Fib))
- { if( !Quiet)
- Printf("%s %s...\233K\r",(long)Indentation,Fib->fib_FileName);
-
- if( Fib->fib_DirEntryType < 0) /** oops, a file **/
- { objsz = Fib->fib_NumBlocks;
- objsz += (objsz+71)/72; /** File Header bzw. List Blocks **/
- Parent->FileSize += objsz;
- }
- else
- { if( !(Node= malloc(sizeof(struct Dir))))
- { PutStr("Out of Memory!\n"); goto abort; }
-
- strcpy( Node->Name, Fib->fib_FileName);
- Node->Parent= Parent;
- Node->Subdir= NULL;
- Node->FileSize= 0;
- Node->Total = 1; /** 1 für Dir-Block **/
-
- indent= strlen(Indentation); strcpy( &Indentation[indent]," ");
-
- while( ExNext(lock,Fib) && !(SetSignal(0L,0L) & SIGBREAKF_CTRL_C))
- {
- if( ShowLinks ||
- Fib_Type==ST_ROOT || Fib_Type==ST_USERDIR || Fib_Type==ST_FILE)
- {
- if( sublock= Lock(Fib->fib_FileName,ACCESS_READ))
- { AddObj( Node,sublock);
- UnLock( sublock);
- }
- }
- }
- objsz= Node->Total; Indentation[indent]= 0;
-
- if( Next= Parent->Subdir)
- { Last= NULL;
- while( Next && (SortSize? Next->Total > objsz
- : strcmp(Next->Name,Node->Name)<0))
- { Last= Next; Next= Next->Next; }
-
- Node->Prev= Last;
- Node->Next= Next;
- if(Next) Next->Prev= Node;
- if(Last) Last->Next= Node;
- else Parent->Subdir= Node;
- }
- else
- { Node->Next= Node->Prev= NULL; Parent->Subdir= Node; }
- }
- Parent->Total += objsz;
- }
- abort: CurrentDir(cwd); FreeVec(Fib); return 1;
- }
-
-
- void DrawObj( struct Dir *Node, long left, long top, long height)
- {
- long total= Node->Total, subheight;
-
- Node->Top= top;
-
- if( height > RPort->TxHeight<<1)
- { Move(RPort,left+2,top+(height>>1));
- Text(RPort,Node->Name,strlen(Node->Name));
-
- sprintf( Indentation,"(%ld)",total);
- Move(RPort,left+2,top+(height>>1)+RPort->TxHeight);
- Text(RPort,Indentation,strlen(Indentation));
- }
-
- Move(RPort,left,top+height); left += WIDTH;
- Draw(RPort,left,top+height); Draw(RPort,left,top); Draw(RPort,left-WIDTH,top);
-
- if(left > Win->Width-Win->BorderRight) return;
-
- for( Node= Node->Subdir; Node; Node= Node->Next)
- { subheight= height * Node->Total / total;
- DrawObj(Node,left,top,subheight);
- top += subheight;
- }
- }
-
- void DrawAll(void)
- {
- struct Window *W= Win;
-
- SetAPen( RPort,BackGround);
- RectFill(RPort,W->BorderLeft,W->BorderTop,
- W->Width-W->BorderRight-1, W->Height-W->BorderBottom-1);
-
- SetAPen(RPort,ForeGround); SetBPen(RPort,BackGround);
- DrawObj( BaseNode, W->BorderLeft,W->BorderTop,
- W->Height - W->BorderTop - W->BorderBottom -1);
- }
-
-
- struct Dir *FindNode(long x, long y)
- {
- struct Dir *Node= BaseNode;
-
- x /= WIDTH;
- if(x<=0) return Node->Parent;
-
- while( Node->Subdir && x)
- for( Node= Node->Subdir, --x;
- Node->Next && Node->Next->Top<y; Node= Node->Next) ;
-
- return Node;
- }
-
-
- struct
- { Tag ti_Tag;
- void *ti_Data;
- }
- AslTags[]=
- { ASL_Hail, "Select root of directory tree",
- ASL_OKText, "Display",
- ASL_ExtFlags1, (void *)FIL1F_NOFILES,
- TAG_DONE
- };
-
- char *DirRequest(void)
- { struct FileRequester *FReq;
- char *DirName= NULL;
-
- if( !(AslBase= OpenLibrary("asl.library",37L)))
- { Printf("%s: Can't open asl.library!\n",(long)MyName); }
- else
- {
- if( !(FReq= (void *)AllocAslRequest(ASL_FileRequest,(void *)AslTags)))
- { Printf("%s: Can't create file requester!\n",(long)MyName); }
- else
- { if( AslRequest(FReq,NULL))
- { if( DirName= malloc( strlen(FReq->rf_Dir)+1))
- strcpy( DirName,FReq->rf_Dir);
- }
- FreeAslRequest(FReq);
- }
- CloseLibrary(AslBase);
- }
- return DirName;
- }
-
- ULONG WinTags[]=
- { WA_Title,NULL, WA_PubScreenName,NULL,
- TAG_IGNORE,0, TAG_IGNORE,0, TAG_IGNORE,-1, TAG_IGNORE,-1, /* l,t,w,h */
- WA_IDCMP, IDCMP_CLOSEWINDOW|IDCMP_NEWSIZE|
- IDCMP_REFRESHWINDOW|IDCMP_MOUSEBUTTONS|IDCMP_RAWKEY,
- WA_SizeGadget,TRUE, WA_DragBar,TRUE, WA_DepthGadget,TRUE,
- WA_CloseGadget,TRUE, WA_SimpleRefresh,TRUE,
- WA_MinWidth,42, WA_MinHeight,42, TAG_DONE
- };
-
- main(int argc, char **argv)
- {
- char *RootName;
- BPTR RootLock;
- BOOL ende= FALSE;
- long argi, res=20;
-
- MyName= argv[0];
-
- if( argc>=2 && argv[1][0]=='?')
- { Printf("Usage: %s [-quiet] [-links] [-num] [-window x y w h] [-fg num] [-bg num] [dir]\n",
- (long)MyName);
- return 0;
- }
- if( !(IntuitionBase= OpenLibrary("intuition.library",36))
- || !(GfxBase= OpenLibrary("graphics.library",36))) exit(36);
-
- for( argi=1; argi<argc; ++argi)
- { char *arg= argv[argi];
-
- if( !strcmp( arg,"-fg"))
- { if( 0 >= StrToLong( argv[++argi], &ForeGround))
- ForeGround=1;
- }
- else
- if( !strcmp( arg,"-bg"))
- { StrToLong( argv[++argi], &BackGround); }
- else
- if( !strncmp( arg,"-w",2)) /** "-window" **/
- { if( 0<StrToLong( argv[++argi], (LONG *)&WinTags[2*2+1])) /* left */
- WinTags[2*2]= WA_Left;
- if( 0<StrToLong( argv[++argi], (LONG *)&WinTags[3*2+1])) /* top */
- WinTags[3*2]= WA_Top;
- if( 0<StrToLong( argv[++argi], (LONG *)&WinTags[4*2+1])) /* width */
- WinTags[4*2]= WA_Width;
- if( 0<StrToLong( argv[++argi], (LONG *)&WinTags[5*2+1])) /* height */
- WinTags[5*2]= WA_Height;
- }
- else if( !strncmp( arg,"-n",2)) SortSize= TRUE;
- else if( !strncmp( arg,"-l",2)) ShowLinks= TRUE;
- else if( !strncmp( arg,"-q",2)) Quiet= TRUE;
- else break;
- }
- if( argi>=argc)
- { if( !(RootName= DirRequest())) goto clean1; }
- else RootName= argv[argi];
-
- if( !(RootLock= Lock(RootName,ACCESS_READ)))
- { Printf("%s not found\n",(long)RootName); goto clean1; }
-
- RootNode.Total= 1; RootNode.FileSize= 0;
- strncpy( RootNode.Name,RootName,30);
-
- Indentation[0]= 0; AddObj( &RootNode,RootLock); UnLock(RootLock);
-
- if( SetSignal(0L,0L) & SIGBREAKF_CTRL_C)
- { Printf("\233K%s: User Abort\n",(long)MyName); goto clean1; }
-
- if( !Quiet) PutStr("\233K\n");
-
- WinTags[1]= (ULONG) RootName;
-
- if( !(Win= OpenWindowTagList(NULL,(void *)WinTags)))
- { PutStr("GDu: Can't open Window!\n"); goto clean1; }
-
- RPort= Win->RPort; BaseNode= RootNode.Subdir;
- DrawAll();
-
- do{ struct IntuiMessage *Msg;
- struct Dir *Node;
- USHORT m_code;
- ULONG m_class;
- SHORT m_X,m_Y;
-
- while( Msg= (void *) GetMsg(Win->UserPort))
- { m_class= Msg->Class; m_code= Msg->Code;
- m_X = Msg->MouseX; m_Y = Msg->MouseY;
- ReplyMsg((void *)Msg);
-
- switch(m_class)
- { case IDCMP_MOUSEBUTTONS:
- m_code ^= 128; /** up in down **/
- case IDCMP_RAWKEY:
- if(m_code>128) break; /** don't redraw on up-event **/
- switch(m_code)
- { case SELECTDOWN:
- Node= FindNode(m_X-Win->BorderLeft,m_Y); break;
- case CURSORUP:
- Node= BaseNode->Prev; break;
- case CURSORDOWN:
- Node= BaseNode->Next; break;
- case CURSORLEFT:
- Node= BaseNode->Parent; break;
- case CURSORRIGHT:
- Node= BaseNode->Subdir; break;
- case 0x41: /** BS **/
- case 0x3A: /** '/'(usa) bzw. '-'(d) **/
- Node= RootNode.Subdir;
- break;
- case 0x45: /** ESC **/
- case KEYCODE_Q:
- ende= TRUE;
- default:
- Node= NULL; break;
- }
- if( Node==NULL || Node== &RootNode) break;
- BaseNode= Node;
- case IDCMP_NEWSIZE:
- DrawAll();
- break;
- case IDCMP_REFRESHWINDOW:
- BeginRefresh(Win); DrawAll(); EndRefresh(Win,TRUE);
- break;
- case IDCMP_CLOSEWINDOW:
- ende= TRUE;
- }
- }
- }while( !ende);
-
- res= 0;
- CloseWindow(Win);
- clean1: CloseLibrary(GfxBase); CloseLibrary(IntuitionBase);
- return res;
- }
-