home *** CD-ROM | disk | FTP | other *** search
- #include <exec/memory.h>
- #include <libraries/asl.h>
- #include <intuition/intuition.h>
- #include <utility/tagitem.h>
-
- #include <proto/exec.h>
- #include <proto/dos.h>
- #include <proto/asl.h>
- #include <proto/intuition.h>
- #include <proto/graphics.h>
- #include <proto/locale.h>
- #include <string.h>
- #include <math.h>
-
- /* for debug purposes */
- #include <stdio.h>
-
- #include "split.h"
-
- STRPTR msg_notenoughspace, msg_notasplfile, msg_missingparm,
- msg_cancelled, msg_filealreadyread, msg_warnmangleddest,
- msg_warnmangledsource, msg_cantfindfile, msg_selectpath,
- msg_selectsourcefile, msg_invalidchunk, msg_fileexists,
- msg_existsgads, msg_ok, msg_filerebuilt;
-
- #define VERSION "1.0"
- char *ver = "$VER: Build "VERSION" "__AMIGADATE__;
-
- char drawer[96], name[32];
- struct TagItem tags[] = {
- { ASLFR_TitleText, NULL },
- { ASLFR_InitialDrawer, (ULONG)drawer },
- { ASLFR_InitialFile, (ULONG)name },
- { ASLFR_InitialHeight, 210L },
- { ASLFR_RejectIcons, TRUE },
- { TAG_END, NULL } };
-
- struct EasyStruct easyr = {
- sizeof(struct EasyStruct), 0, NULL, NULL, NULL };
-
- struct IntuitionBase *IntuitionBase;
- struct GfxBase *GfxBase;
- struct Library *AslBase, *LocaleBase;
-
- struct Window *window;
- struct VisualInfo *vi;
-
- struct RDArgs *args;
- STRPTR res[3] = { 0, 0, 0 };
- char **chunknames;
-
- #define CATCOMP_NUMBERS
- #define CATCOMP_BLOCK
- #define CATCOMP_CODE
- #include "Build_strings.h"
-
- #define XLocaleBase LocaleBase
-
- extern STRPTR __asm GetString(register __a0 struct LocaleInfo *li,
- register __d0 LONG stringNum);
-
- struct LocaleInfo li;
-
- ULONG filesize;
-
- void initLocale( void )
- {
- li.li_Catalog = NULL;
- if ( LocaleBase = OpenLibrary( "locale.library", 38L ) )
- {
- li.li_LocaleBase = LocaleBase;
- li.li_Catalog = OpenCatalogA( NULL, "Build.catalog", NULL );
- }
-
- easyr.es_Title = GetString( &li, MSG_BUILDREQUEST );
- msg_notenoughspace = GetString( &li, MSG_NOTENOUGHSPACE );
- msg_notasplfile = GetString( &li, MSG_NOTASPLFILE );
- msg_missingparm = GetString( &li, MSG_MISSINGPARM );
- msg_cancelled = GetString( &li, MSG_CANCELLED );
- msg_filealreadyread = GetString( &li, MSG_FILEALREADYREAD );
- msg_warnmangleddest = GetString( &li, MSG_WARNMANGLEDDEST );
- msg_warnmangledsource = GetString( &li, MSG_WARNMANGLEDSOURCE );
- msg_cantfindfile = GetString( &li, MSG_CANTFINDFILE );
- msg_selectpath = GetString( &li, MSG_SELECTPATH );
- msg_selectsourcefile = GetString( &li, MSG_SELECTSOURCEFILE );
- msg_invalidchunk = GetString( &li, MSG_INVALIDCHUNK );
- msg_ok = GetString( &li, MSG_OK );
- msg_fileexists = GetString( &li, MSG_FILEEXISTS );
- msg_existsgads = GetString( &li, MSG_EXISTSGADS );
- msg_filerebuilt = GetString( &li, MSG_FILEREBUILT );
- }
-
-
- void flushLocale( void )
- {
- if ( LocaleBase )
- {
- if ( li.li_Catalog )
- CloseCatalog( li.li_Catalog );
- CloseLibrary( LocaleBase );
- }
- }
-
-
- struct IntuiText itext = { 1, 0, JAM2, 0, 0, NULL, NULL, NULL };
- UWORD boxleft, boxtop;
- WORD whitelines[8] = { 0, 0, 0, 10, 1, 9, 1, 1 };
- WORD blacklines[8] = { 199, 10, 199, 0, 198, 1, 198, 10 };
-
- BOOL openGUI( char *name )
- {
- register struct RastPort *rp;
- struct Screen *wbs = LockPubScreen( NULL );
- BOOL result = FALSE;
- UWORD wwidth, wheight;
- register UWORD ilength, n;
-
- itext.ITextFont = wbs->Font;
- itext.IText = name;
-
- ilength = IntuiTextLength( &itext );
- wwidth = max( ilength, 200 );
- wheight = 2 * wbs->Font->ta_YSize + wbs->WBorBottom + 30;
-
- if ( window = OpenWindowTags( NULL,
- WA_Left, ( wbs->Width - wwidth ) >> 1,
- WA_Top, ( wbs->Height - wheight ) >> 1,
- WA_Width, wwidth + wbs->WBorLeft + wbs->WBorRight + 8,
- WA_Height, wheight,
- WA_Title, "Build v"VERSION,
- WA_ScreenTitle, "Build v"VERSION" Copyright © 1995 by Stefano Reksten of 3AM",
- WA_Flags, WFLG_DEPTHGADGET|WFLG_DRAGBAR|WFLG_ACTIVATE|WFLG_RMBTRAP,
- TAG_END ) )
- {
- rp = window->RPort;
- boxleft = wbs->WBorLeft + 4;
- boxtop = wbs->BarHeight + wbs->Font->ta_YSize + 6;
- for ( n = 0; n < 4; n++ )
- {
- whitelines[n<<1] += boxleft;
- whitelines[(n<<1)+1] += boxtop;
- blacklines[n<<1] += boxleft;
- blacklines[(n<<1)+1] += boxtop;
- }
- PrintIText( rp, &itext, boxleft, wbs->BarHeight + 4 );
- SetAPen( rp, 1 );
- Move( rp, boxleft + 199, boxtop );
- PolyDraw( rp, 4, whitelines );
- SetAPen( rp, 2 );
- Move( rp, 1 + boxleft, 10 + boxtop );
- PolyDraw( rp, 4, blacklines );
- SetAPen( rp, 3 );
- result = TRUE;
- }
-
- UnlockPubScreen( NULL, wbs );
- return result;
- }
-
-
- void closeGUI( void )
- {
- CloseWindow( window );
- }
-
-
- void updateGUI( ULONG offset, ULONG size )
- {
- register UWORD xmin, ymin;
-
- xmin = boxleft + 2 + 196 * offset / filesize;
- ymin = boxtop + 1;
- RectFill( window->RPort, xmin, ymin, xmin + size * 196 / filesize, ymin + 8 );
- }
-
-
-
- BOOL askFile( STRPTR dest )
- {
- struct FileRequester *request;
- BOOL result = FALSE;
-
- if ( AslBase = OpenLibrary( "asl.library", 0L ) )
- {
- if ( request = (struct FileRequester *)AllocAslRequest( ASL_FileRequest, tags ) )
- {
- if ( AslRequest( request, tags ) )
- {
- strcpy( drawer, request->fr_Drawer );
- strcpy( name, request->fr_File );
-
- strcpy( dest, request->fr_Drawer );
- if ( dest[0] )
- {
- strcpy( drawer, dest );
- if ( dest[ strlen(dest)-1 ] != ':' && dest[ strlen(dest)-1 ] != '/' )
- strcat( dest, "/" );
- }
- strcat( dest, FilePart(request->fr_File) );
- result = TRUE;
- }
- FreeAslRequest( request );
- }
- CloseLibrary( AslBase );
- }
- return result;
- }
-
-
- void error( STRPTR cause )
- {
- easyr.es_TextFormat = cause;
- easyr.es_GadgetFormat = msg_ok;
- EasyRequestArgs( NULL, &easyr, NULL, NULL );
- }
-
-
- UBYTE *mptr;
-
- BOOL transferbytes( BPTR source, BPTR dest, ULONG offset, ULONG chunksize )
- {
- ULONG bytes_copied = 0, bytes_transferred, bytes_to_transfer, current_offset = offset;
-
- Seek( dest, offset, OFFSET_BEGINNING );
- while ( bytes_copied != chunksize )
- {
- bytes_to_transfer = ( chunksize - bytes_copied > TRANSFER_SIZE ? TRANSFER_SIZE : chunksize - bytes_copied );
- bytes_transferred = Read( source, (APTR)mptr, bytes_to_transfer );
- if ( bytes_transferred != bytes_to_transfer )
- {
- easyr.es_TextFormat = msg_warnmangledsource;
- easyr.es_GadgetFormat = msg_ok;
- EasyRequestArgs( NULL, &easyr, NULL, NULL );
- goto end;
- }
- bytes_transferred = Write( dest, (APTR)mptr, bytes_to_transfer );
- if ( bytes_transferred != bytes_to_transfer )
- {
- easyr.es_TextFormat = msg_warnmangleddest;
- easyr.es_GadgetFormat = msg_ok;
- EasyRequestArgs( NULL, &easyr, NULL, NULL );
- goto end;
- }
- bytes_copied += bytes_transferred;
-
- updateGUI( current_offset, bytes_transferred );
- current_offset += bytes_to_transfer;
- }
- return TRUE;
- end:
- return FALSE;
- }
-
-
- struct List chunkSeenList;
- struct chunkseennode {
- struct Node cs_Node;
- ULONG cs_Offset; };
-
- BOOL checkchunk( ULONG offset )
- {
- struct chunkseennode *node;
- for ( node = (struct chunkseennode *)chunkSeenList.lh_Head; node->cs_Node.ln_Succ; node = (struct chunkseennode *)node->cs_Node.ln_Succ )
- if ( node->cs_Offset == offset )
- return FALSE;
- if ( node = AllocVec( sizeof(struct chunkseennode), MEMF_ANY ) )
- {
- node->cs_Offset = offset;
- AddTail( &chunkSeenList, (struct Node *)node );
- return TRUE;
- }
- return FALSE;
- }
-
-
- void freeList( void )
- {
- struct Node *node;
- while( node = RemHead( &chunkSeenList ) )
- FreeVec( node );
- }
-
-
- void rebuild( char *bname, char *bpath )
- {
- struct Header header;
- BPTR source, dest;
- char destname[128], otherchunkname[128];
- char originalname[32];
- ULONG originalsize, restored = 0;
- BOOL valid_dest = FALSE;
-
- if ( source = Open( bname, MODE_OLDFILE ) )
- {
- Read( source, &header, sizeof(struct Header) );
- if ( header.h_Identifier != (ULONG)(('S'<<24)+('P'<<16)+('L'<<8)+'0') )
- {
- error( msg_notasplfile );
- Close( source );
- return;
- }
- strcpy( originalname, header.h_FileName );
- originalsize = header.h_FileSize;
- Close( source );
- strcpy( otherchunkname, drawer );
- if ( *drawer && otherchunkname[ strlen(otherchunkname)-1 ] != ':' && otherchunkname[ strlen(otherchunkname)-1 ] != '/' )
- strcat( otherchunkname, "/" );
- strcat( otherchunkname, name );
- strcpy( name, header.h_FileName );
-
- if ( bpath )
- strcpy( destname, bpath );
- else
- destname[0] = 0;
-
- if ( openGUI( originalname ) )
- {
- tags[0].ti_Data = (ULONG)msg_selectpath;
- while ( !valid_dest )
- {
- while ( !*destname )
- if ( !askFile( destname ) )
- {
- error( msg_cancelled );
- closeGUI();
- return;
- }
- if ( !*FilePart(destname) )
- strcat( destname, originalname );
-
- if ( dest = Lock( destname, ACCESS_READ ) )
- {
- UnLock( dest );
- easyr.es_TextFormat = msg_fileexists;
- easyr.es_GadgetFormat = msg_existsgads;
- if ( EasyRequestArgs( NULL, &easyr, NULL, NULL ) )
- valid_dest = TRUE;
- else
- {
- closeGUI();
- return;
- }
- }
- else valid_dest = TRUE;
- }
-
- tags[0].ti_Data = (ULONG)msg_selectsourcefile;
- if ( dest = Open( destname, MODE_NEWFILE ) )
- {
- if ( mptr = AllocVec( TRANSFER_SIZE, MEMF_ANY ) )
- {
- NewList( &chunkSeenList );
- filesize = header.h_FileSize;
- if ( SetFileSize( dest, filesize, OFFSET_BEGINNING ) )
- {
- do {
- if ( source = Open( otherchunkname, MODE_OLDFILE ) )
- {
- Read( source, &header, sizeof(struct Header) );
- if ( header.h_Identifier != (ULONG)(('S'<<24)+('P'<<16)+('L'<<8)+'0') )
- error( msg_notasplfile );
- else
- if ( strcmp( header.h_FileName, originalname ) )
- error( msg_invalidchunk );
- else
- if ( checkchunk( header.h_ChunkStart ) )
- {
- if ( transferbytes( source, dest, header.h_ChunkStart, header.h_ChunkEnd - header.h_ChunkStart ) )
- restored += header.h_ChunkEnd - header.h_ChunkStart;
- else break;
- }
- else error( msg_filealreadyread );
- Close( source );
- }
- if ( originalsize > restored )
- {
- if ( chunknames && *chunknames )
- strcpy( otherchunkname, *chunknames++ );
- else if ( !askFile( otherchunkname ) )
- {
- error( msg_cancelled );
- break;
- }
- }
- } while( originalsize > restored );
- }
- else
- error( msg_notenoughspace );
- FreeVec( (APTR)mptr );
- }
- Close( dest );
- if ( originalsize > restored )
- DeleteFile( destname );
- else
- {
- easyr.es_TextFormat = msg_filerebuilt;
- easyr.es_GadgetFormat = msg_ok;
- EasyRequestArgs( NULL, &easyr, NULL, NULL );
- }
- }
- closeGUI();
- }
- }
- else
- error( msg_cantfindfile );
- }
-
-
- void main( int argc, char *argv[] )
- {
- char filename[128];
-
- if ( IntuitionBase = (struct IntuitionBase *)OpenLibrary( "intuition.library", 37L ) )
- {
- if ( GfxBase = (struct GfxBase *)OpenLibrary( "graphics.library", 37L ) )
- {
- initLocale();
- if ( !argc )
- {
- tags[0].ti_Data = (ULONG)msg_selectsourcefile;
- if ( askFile( filename ) )
- rebuild( filename, NULL );
- else
- error( msg_missingparm );
- }
- else
- {
- if ( args = ReadArgs( "CHUNK,PATH,OTHER_CHUNKS/M", (LONG *)res, NULL ) )
- {
- chunknames = (char **)res[2];
- if ( !res[0] )
- {
- tags[0].ti_Data = (ULONG)msg_selectsourcefile;
- if ( askFile( filename ) )
- rebuild( filename, NULL );
- else error( msg_missingparm );
- }
- else
- rebuild( res[0], res[1] );
- FreeArgs( args );
- }
- else PrintFault( IoErr(), NULL );
- }
- flushLocale();
- CloseLibrary( (struct Library *)GfxBase );
- }
- CloseLibrary( (struct Library *)IntuitionBase );
- }
- }
-