grub2: bring back build of aros-side grub2 tools
[AROS.git] / workbench / c / Unpack / package.c
blob585123cad66567840aa5f6f26356213a1473d711
1 /*
2 Copyright © 2003, 2009, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 #include <exec/memory.h>
7 #include <dos/dos.h>
9 #include <proto/exec.h>
10 #include <proto/dos.h>
11 #include <aros/macros.h>
13 #include "support.h"
14 #include "modes.h"
15 #include "bzip2.h"
16 #include "file.h"
17 #include "package.h"
18 #include "gui.h"
20 #define PKG_BUFFER_SIZE (32*1024) /* 32kiB */
22 /** Low-level functions *****************************************************/
24 APTR PKG_Open( CONST_STRPTR filename, LONG mode )
26 if( mode != MODE_READ && mode != MODE_WRITE ) return NULL;
28 return BZ2_Open( filename, mode );
31 void PKG_Close( APTR pkg )
33 if( pkg != NULL ) BZ2_Close( pkg );
36 LONG PKG_Read( APTR pkg, APTR buffer, LONG length )
38 return BZ2_Read( pkg, buffer, length );
41 /** High-level functions ****************************************************/
43 LONG /* version */ PKG_ReadHeader( APTR pkg )
45 UBYTE data[4] = { 0, 0, 0, 0 };
46 LONG version;
48 if ( PKG_Read( pkg, data, 4 ) != 4 )
50 Printf("E:read header\n");
51 return -1;
54 version = data[3];
55 if ( data[0] != 'P' || data[1] != 'K' || data[2] != 'G' )
57 Printf("E:invalid header\n");
58 return -1;
61 if ( version > 0 )
63 /* though unused at the moment we still have to read package size */
64 LONG packageSize;
65 PKG_Read( pkg, &packageSize, sizeof( packageSize ) );
66 //packageSize = AROS_BE2LONG(packageSize);
69 return version;
72 LONG /* error */ PKG_ExtractFile( APTR pkg )
74 LONG pathLength, dataLength, rc, result;
75 STRPTR path = NULL;
76 APTR buffer = NULL;
77 BPTR output = BNULL;
79 /* Read the path length */
80 rc = PKG_Read( pkg, &pathLength, sizeof( pathLength ) );
81 pathLength = AROS_BE2LONG(pathLength);
83 if( rc == -1 ) { result = -1; goto cleanup; }
84 if( rc == 0 ) { result = 0; goto cleanup; }
86 /* Read the path */
87 path = AllocMem( pathLength + 1, MEMF_ANY );
88 if( path == NULL ) { result = -1; goto cleanup; }
89 rc = PKG_Read( pkg, path, pathLength + 1 );
90 if( rc == -1 || rc == 0) { result = -1; goto cleanup; }
92 /* Read the data length */
93 rc = PKG_Read( pkg, &dataLength, sizeof( dataLength ) );
94 dataLength = AROS_BE2LONG(dataLength);
96 if( rc == -1 || rc == 0 ) { result = -1; goto cleanup; }
98 //Printf( "Extracting %s (%ld bytes)...\n", path, dataLength );
100 /* Make sure the destination directory exists */
101 if( !MakeDirs( path ) ) { Printf("E:makedirs\n"); result = -1; goto cleanup; }
103 /* Read and write the data in pieces */
104 buffer = AllocMem( PKG_BUFFER_SIZE, MEMF_ANY );
105 if( buffer == NULL ) { Printf("E:mem\n"); result = -1; goto cleanup; }
106 output = Open( path, MODE_NEWFILE );
107 if( output == BNULL ) { Printf("E:create\n"); result = -1; goto cleanup; }
110 LONG total = 0;
112 while( total < dataLength )
114 LONG length = 0;
116 if( dataLength - total >= PKG_BUFFER_SIZE )
118 length = PKG_BUFFER_SIZE;
120 else
122 length = dataLength - total;
125 rc = PKG_Read( pkg, buffer, length );
126 if( rc == -1 || rc == 0 ) { Printf("E:read\n"); result = -1; goto cleanup; }
128 rc = FILE_Write( output, buffer, length );
129 if( rc == -1 ) { Printf("E:write\n"); result = -1; goto cleanup; }
131 total += length;
135 result = 1;
137 cleanup:
138 if( path != NULL ) FreeMem( path, pathLength + 1 );
139 if( buffer != NULL ) FreeMem( buffer, PKG_BUFFER_SIZE );
140 if( output != BNULL ) Close( output );
142 return result;
145 LONG /* error */ PKG_ExtractEverything( APTR pkg )
147 LONG result = PKG_ReadHeader( pkg );
148 if ( result < 0 )
149 return result;
151 result = PKG_ExtractFile( pkg );
152 while( result != -1 && result != 0 )
154 result = PKG_ExtractFile( pkg );
157 return result;