home *** CD-ROM | disk | FTP | other *** search
/ Amiga ISO Collection / AmigaUtilCD2.iso / Misc / Split_GUI.lha / Split_v1.0 / Sources.lha / Sources / build.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-03-22  |  10.9 KB  |  450 lines

  1. #include <exec/memory.h>
  2. #include <libraries/asl.h>
  3. #include <intuition/intuition.h>
  4. #include <utility/tagitem.h>
  5.  
  6. #include <proto/exec.h>
  7. #include <proto/dos.h>
  8. #include <proto/asl.h>
  9. #include <proto/intuition.h>
  10. #include <proto/graphics.h>
  11. #include <proto/locale.h>
  12. #include <string.h>
  13. #include <math.h>
  14.  
  15. /* for debug purposes */
  16. #include <stdio.h>
  17.  
  18. #include "split.h"
  19.  
  20. STRPTR msg_notenoughspace, msg_notasplfile, msg_missingparm,
  21.     msg_cancelled, msg_filealreadyread, msg_warnmangleddest,
  22.     msg_warnmangledsource, msg_cantfindfile, msg_selectpath,
  23.     msg_selectsourcefile, msg_invalidchunk, msg_fileexists,
  24.     msg_existsgads, msg_ok, msg_filerebuilt;
  25.  
  26. #define VERSION "1.0"
  27. char *ver = "$VER: Build "VERSION" "__AMIGADATE__;
  28.  
  29. char drawer[96], name[32];
  30. struct TagItem tags[] = {
  31. { ASLFR_TitleText, NULL },
  32. { ASLFR_InitialDrawer, (ULONG)drawer },
  33. { ASLFR_InitialFile, (ULONG)name },
  34. { ASLFR_InitialHeight, 210L },
  35. { ASLFR_RejectIcons, TRUE },
  36. { TAG_END, NULL } };
  37.  
  38. struct EasyStruct easyr = {
  39.     sizeof(struct EasyStruct), 0, NULL, NULL, NULL };
  40.  
  41. struct IntuitionBase *IntuitionBase;
  42. struct GfxBase *GfxBase;
  43. struct Library *AslBase, *LocaleBase;
  44.  
  45. struct Window *window;
  46. struct VisualInfo *vi;
  47.  
  48. struct RDArgs *args;
  49. STRPTR res[3] = { 0, 0, 0 };
  50. char **chunknames;
  51.  
  52. #define CATCOMP_NUMBERS
  53. #define CATCOMP_BLOCK
  54. #define CATCOMP_CODE
  55. #include "Build_strings.h"
  56.  
  57. #define XLocaleBase LocaleBase
  58.  
  59. extern STRPTR __asm GetString(register __a0 struct LocaleInfo *li,
  60.                        register __d0 LONG stringNum);
  61.  
  62. struct LocaleInfo li;
  63.  
  64. ULONG filesize;
  65.  
  66. void initLocale( void )
  67. {
  68. li.li_Catalog = NULL;
  69. if ( LocaleBase = OpenLibrary( "locale.library", 38L ) )
  70.     {
  71.     li.li_LocaleBase = LocaleBase;
  72.     li.li_Catalog = OpenCatalogA( NULL, "Build.catalog", NULL );
  73.     }
  74.  
  75. easyr.es_Title = GetString( &li, MSG_BUILDREQUEST );
  76. msg_notenoughspace = GetString( &li, MSG_NOTENOUGHSPACE );
  77. msg_notasplfile = GetString( &li, MSG_NOTASPLFILE );
  78. msg_missingparm = GetString( &li, MSG_MISSINGPARM );
  79. msg_cancelled = GetString( &li, MSG_CANCELLED );
  80. msg_filealreadyread = GetString( &li, MSG_FILEALREADYREAD );
  81. msg_warnmangleddest = GetString( &li, MSG_WARNMANGLEDDEST );
  82. msg_warnmangledsource = GetString( &li, MSG_WARNMANGLEDSOURCE );
  83. msg_cantfindfile = GetString( &li, MSG_CANTFINDFILE );
  84. msg_selectpath = GetString( &li, MSG_SELECTPATH );
  85. msg_selectsourcefile = GetString( &li, MSG_SELECTSOURCEFILE );
  86. msg_invalidchunk = GetString( &li, MSG_INVALIDCHUNK );
  87. msg_ok = GetString( &li, MSG_OK );
  88. msg_fileexists = GetString( &li, MSG_FILEEXISTS );
  89. msg_existsgads = GetString( &li, MSG_EXISTSGADS );
  90. msg_filerebuilt = GetString( &li, MSG_FILEREBUILT );
  91. }
  92.  
  93.  
  94. void flushLocale( void )
  95. {
  96. if ( LocaleBase )
  97.     {
  98.     if ( li.li_Catalog )
  99.         CloseCatalog( li.li_Catalog );
  100.     CloseLibrary( LocaleBase );
  101.     }
  102. }
  103.  
  104.  
  105. struct IntuiText itext = { 1, 0, JAM2, 0, 0, NULL, NULL, NULL };
  106. UWORD boxleft, boxtop;
  107. WORD whitelines[8] = { 0, 0, 0, 10, 1, 9, 1, 1 };
  108. WORD blacklines[8] = { 199, 10, 199, 0, 198, 1, 198, 10 };
  109.  
  110. BOOL openGUI( char *name )
  111. {
  112. register struct RastPort *rp;
  113. struct Screen *wbs = LockPubScreen( NULL );
  114. BOOL result = FALSE;
  115. UWORD wwidth, wheight;
  116. register UWORD ilength, n;
  117.  
  118. itext.ITextFont = wbs->Font;
  119. itext.IText = name;
  120.  
  121. ilength = IntuiTextLength( &itext );
  122. wwidth = max( ilength, 200 );
  123. wheight = 2 * wbs->Font->ta_YSize + wbs->WBorBottom + 30;
  124.  
  125. if ( window = OpenWindowTags( NULL,
  126.     WA_Left, ( wbs->Width - wwidth ) >> 1,
  127.     WA_Top, ( wbs->Height - wheight ) >> 1,
  128.     WA_Width, wwidth + wbs->WBorLeft + wbs->WBorRight + 8,
  129.     WA_Height, wheight,
  130.     WA_Title, "Build v"VERSION,
  131.     WA_ScreenTitle, "Build v"VERSION" Copyright © 1995 by Stefano Reksten of 3AM",
  132.     WA_Flags, WFLG_DEPTHGADGET|WFLG_DRAGBAR|WFLG_ACTIVATE|WFLG_RMBTRAP,
  133.     TAG_END ) )
  134.     {
  135.     rp = window->RPort;
  136.     boxleft = wbs->WBorLeft + 4;
  137.     boxtop = wbs->BarHeight + wbs->Font->ta_YSize + 6;
  138.     for ( n = 0; n < 4; n++ )
  139.         {
  140.         whitelines[n<<1] += boxleft;
  141.         whitelines[(n<<1)+1] += boxtop;
  142.         blacklines[n<<1] += boxleft;
  143.         blacklines[(n<<1)+1] += boxtop;
  144.         }
  145.     PrintIText( rp, &itext, boxleft, wbs->BarHeight + 4 );
  146.     SetAPen( rp, 1 );
  147.     Move( rp, boxleft + 199, boxtop );
  148.     PolyDraw( rp, 4, whitelines );
  149.     SetAPen( rp, 2 );
  150.     Move( rp, 1 + boxleft, 10 + boxtop );
  151.     PolyDraw( rp, 4, blacklines );
  152.     SetAPen( rp, 3 );
  153.     result = TRUE;
  154.     }
  155.  
  156. UnlockPubScreen( NULL, wbs );
  157. return result;
  158. }
  159.  
  160.  
  161. void closeGUI( void )
  162. {
  163. CloseWindow( window );
  164. }
  165.  
  166.  
  167. void updateGUI( ULONG offset, ULONG size )
  168. {
  169. register UWORD xmin, ymin;
  170.  
  171. xmin = boxleft + 2 + 196 * offset / filesize;
  172. ymin = boxtop + 1;
  173. RectFill( window->RPort, xmin, ymin, xmin + size * 196 / filesize, ymin + 8 );
  174. }
  175.  
  176.  
  177.  
  178. BOOL askFile( STRPTR dest )
  179. {
  180. struct FileRequester *request;
  181. BOOL result = FALSE;
  182.  
  183. if ( AslBase = OpenLibrary( "asl.library", 0L ) )
  184.     {
  185.     if ( request = (struct FileRequester *)AllocAslRequest( ASL_FileRequest, tags ) )
  186.         {
  187.         if ( AslRequest( request, tags ) )
  188.             {
  189.             strcpy( drawer, request->fr_Drawer );
  190.             strcpy( name, request->fr_File );
  191.  
  192.             strcpy( dest, request->fr_Drawer );
  193.             if ( dest[0] )
  194.                 {
  195.                 strcpy( drawer, dest );
  196.                 if ( dest[ strlen(dest)-1 ] != ':' && dest[ strlen(dest)-1 ] != '/' )
  197.                     strcat( dest, "/" );
  198.                 }
  199.             strcat( dest, FilePart(request->fr_File) );
  200.             result = TRUE;
  201.             }
  202.         FreeAslRequest( request );
  203.         }
  204.     CloseLibrary( AslBase );
  205.     }
  206. return result;
  207. }
  208.  
  209.  
  210. void error( STRPTR cause )
  211. {
  212. easyr.es_TextFormat = cause;
  213. easyr.es_GadgetFormat = msg_ok;
  214. EasyRequestArgs( NULL, &easyr, NULL, NULL );
  215. }
  216.  
  217.  
  218. UBYTE *mptr;
  219.  
  220. BOOL transferbytes( BPTR source, BPTR dest, ULONG offset, ULONG chunksize )
  221. {
  222. ULONG bytes_copied = 0, bytes_transferred, bytes_to_transfer, current_offset = offset;
  223.  
  224. Seek( dest, offset, OFFSET_BEGINNING );
  225. while ( bytes_copied != chunksize )
  226.     {
  227.     bytes_to_transfer = ( chunksize - bytes_copied > TRANSFER_SIZE ? TRANSFER_SIZE : chunksize - bytes_copied );
  228.     bytes_transferred = Read( source, (APTR)mptr, bytes_to_transfer );
  229.     if ( bytes_transferred != bytes_to_transfer )
  230.         {
  231.         easyr.es_TextFormat = msg_warnmangledsource;
  232.         easyr.es_GadgetFormat = msg_ok;
  233.         EasyRequestArgs( NULL, &easyr, NULL, NULL );
  234.         goto end;
  235.         }
  236.     bytes_transferred = Write( dest, (APTR)mptr, bytes_to_transfer );
  237.     if ( bytes_transferred != bytes_to_transfer )
  238.         {
  239.         easyr.es_TextFormat = msg_warnmangleddest;
  240.         easyr.es_GadgetFormat = msg_ok;
  241.         EasyRequestArgs( NULL, &easyr, NULL, NULL );
  242.         goto end;
  243.         }
  244.     bytes_copied += bytes_transferred;
  245.  
  246.     updateGUI( current_offset, bytes_transferred );
  247.     current_offset += bytes_to_transfer;
  248.     }
  249. return TRUE;
  250. end:
  251. return FALSE;
  252. }
  253.  
  254.  
  255. struct List chunkSeenList;
  256. struct chunkseennode {
  257.     struct Node cs_Node;
  258.     ULONG cs_Offset; };
  259.  
  260. BOOL checkchunk( ULONG offset )
  261. {
  262. struct chunkseennode *node;
  263. for ( node = (struct chunkseennode *)chunkSeenList.lh_Head; node->cs_Node.ln_Succ; node = (struct chunkseennode *)node->cs_Node.ln_Succ )
  264.     if ( node->cs_Offset == offset )
  265.         return FALSE;
  266. if ( node = AllocVec( sizeof(struct chunkseennode), MEMF_ANY ) )
  267.     {
  268.     node->cs_Offset = offset;
  269.     AddTail( &chunkSeenList, (struct Node *)node );
  270.     return TRUE;
  271.     }
  272. return FALSE;
  273. }
  274.  
  275.  
  276. void freeList( void )
  277. {
  278. struct Node *node;
  279. while( node = RemHead( &chunkSeenList ) )
  280.     FreeVec( node );
  281. }
  282.  
  283.  
  284. void rebuild( char *bname, char *bpath )
  285. {
  286. struct Header header;
  287. BPTR source, dest;
  288. char destname[128], otherchunkname[128];
  289. char originalname[32];
  290. ULONG originalsize, restored = 0;
  291. BOOL valid_dest = FALSE;
  292.  
  293. if ( source = Open( bname, MODE_OLDFILE ) )
  294.     {
  295.     Read( source, &header, sizeof(struct Header) );
  296.     if ( header.h_Identifier != (ULONG)(('S'<<24)+('P'<<16)+('L'<<8)+'0') )
  297.         {
  298.         error( msg_notasplfile );
  299.         Close( source );
  300.         return;
  301.         }
  302.     strcpy( originalname, header.h_FileName );
  303.     originalsize = header.h_FileSize;
  304.     Close( source );
  305.     strcpy( otherchunkname, drawer );
  306.     if ( *drawer && otherchunkname[ strlen(otherchunkname)-1 ] != ':' && otherchunkname[ strlen(otherchunkname)-1 ] != '/' )
  307.             strcat( otherchunkname, "/" );
  308.     strcat( otherchunkname, name );
  309.     strcpy( name, header.h_FileName );
  310.  
  311.     if ( bpath )
  312.         strcpy( destname, bpath );
  313.     else
  314.         destname[0] = 0;
  315.  
  316.     if ( openGUI( originalname ) )
  317.         {
  318.         tags[0].ti_Data = (ULONG)msg_selectpath;
  319.         while ( !valid_dest )
  320.             {
  321.             while ( !*destname )
  322.                 if ( !askFile( destname ) )
  323.                     {
  324.                     error( msg_cancelled );
  325.                     closeGUI();
  326.                     return;
  327.                     }
  328.             if ( !*FilePart(destname) )
  329.                 strcat( destname, originalname );
  330.  
  331.             if ( dest = Lock( destname, ACCESS_READ ) )
  332.                 {
  333.                 UnLock( dest );
  334.                 easyr.es_TextFormat = msg_fileexists;
  335.                 easyr.es_GadgetFormat = msg_existsgads;
  336.                 if ( EasyRequestArgs( NULL, &easyr, NULL, NULL ) )
  337.                     valid_dest = TRUE;
  338.                 else
  339.                     {
  340.                     closeGUI();
  341.                     return;
  342.                     }
  343.                 }
  344.             else valid_dest = TRUE;
  345.             }
  346.  
  347.         tags[0].ti_Data = (ULONG)msg_selectsourcefile;
  348.         if ( dest = Open( destname, MODE_NEWFILE ) )
  349.             {
  350.             if ( mptr = AllocVec( TRANSFER_SIZE, MEMF_ANY ) )
  351.                 {
  352.                 NewList( &chunkSeenList );
  353.                 filesize = header.h_FileSize;
  354.                 if ( SetFileSize( dest, filesize, OFFSET_BEGINNING ) )
  355.                     {
  356.                     do    {
  357.                         if ( source = Open( otherchunkname, MODE_OLDFILE ) ) 
  358.                             {
  359.                             Read( source, &header, sizeof(struct Header) );
  360.                             if ( header.h_Identifier != (ULONG)(('S'<<24)+('P'<<16)+('L'<<8)+'0') )
  361.                                 error( msg_notasplfile );
  362.                             else
  363.                             if ( strcmp( header.h_FileName, originalname ) )
  364.                                 error( msg_invalidchunk );
  365.                             else
  366.                             if ( checkchunk( header.h_ChunkStart ) )
  367.                                 {
  368.                                 if ( transferbytes( source, dest, header.h_ChunkStart, header.h_ChunkEnd - header.h_ChunkStart ) )
  369.                                     restored += header.h_ChunkEnd - header.h_ChunkStart;
  370.                                 else break;
  371.                                 }
  372.                             else error( msg_filealreadyread );
  373.                             Close( source );
  374.                             }
  375.                         if ( originalsize > restored )
  376.                             {
  377.                             if ( chunknames && *chunknames )
  378.                                 strcpy( otherchunkname, *chunknames++ );
  379.                             else if ( !askFile( otherchunkname ) )
  380.                                 {
  381.                                 error( msg_cancelled );
  382.                                 break;
  383.                                 }
  384.                             }
  385.                         } while( originalsize > restored );
  386.                     }
  387.                 else
  388.                      error( msg_notenoughspace );
  389.                 FreeVec( (APTR)mptr );
  390.                 }
  391.             Close( dest );
  392.             if ( originalsize > restored )
  393.                 DeleteFile( destname );
  394.             else
  395.                 {
  396.                 easyr.es_TextFormat = msg_filerebuilt;
  397.                 easyr.es_GadgetFormat = msg_ok;
  398.                 EasyRequestArgs( NULL, &easyr, NULL, NULL );
  399.                 }
  400.             }
  401.         closeGUI();
  402.         }
  403.     }
  404. else
  405.     error( msg_cantfindfile );
  406. }
  407.  
  408.  
  409. void main( int argc, char *argv[] )
  410. {
  411. char filename[128];
  412.  
  413. if ( IntuitionBase = (struct IntuitionBase *)OpenLibrary( "intuition.library", 37L ) )
  414.     {
  415.     if ( GfxBase = (struct GfxBase *)OpenLibrary( "graphics.library", 37L ) )
  416.         {
  417.         initLocale();
  418.         if ( !argc )
  419.             {
  420.             tags[0].ti_Data = (ULONG)msg_selectsourcefile;
  421.             if ( askFile( filename ) )
  422.                 rebuild( filename, NULL );
  423.             else
  424.                 error( msg_missingparm );
  425.             }
  426.         else
  427.             {
  428.             if ( args = ReadArgs( "CHUNK,PATH,OTHER_CHUNKS/M", (LONG *)res, NULL ) )
  429.                 {
  430.                 chunknames = (char **)res[2];
  431.                 if ( !res[0] )
  432.                     {
  433.                     tags[0].ti_Data = (ULONG)msg_selectsourcefile;
  434.                     if ( askFile( filename ) )
  435.                         rebuild( filename, NULL );
  436.                     else error( msg_missingparm );
  437.                     }
  438.                 else
  439.                     rebuild( res[0], res[1] );
  440.                 FreeArgs( args );
  441.                 }
  442.             else PrintFault( IoErr(), NULL );
  443.             }
  444.         flushLocale();
  445.         CloseLibrary( (struct Library *)GfxBase );
  446.         }
  447.     CloseLibrary( (struct Library *)IntuitionBase );
  448.     }
  449. }
  450.