aboutsummaryrefslogtreecommitdiff
path: root/src/tools
diff options
context:
space:
mode:
Diffstat (limited to 'src/tools')
-rw-r--r--src/tools/myriad.cpp333
-rw-r--r--src/tools/myriadfs.cpp269
2 files changed, 602 insertions, 0 deletions
diff --git a/src/tools/myriad.cpp b/src/tools/myriad.cpp
new file mode 100644
index 0000000..0dd9840
--- /dev/null
+++ b/src/tools/myriad.cpp
@@ -0,0 +1,333 @@
1/*
2 * Copyright (C) 2007-2023 Xagasoft, All rights reserved.
3 *
4 * This file is part of the libbu++ library and is released under the
5 * terms of the license contained in the file LICENSE.
6 */
7
8#include "bu/sio.h"
9#include "bu/file.h"
10#include "bu/myriad.h"
11#include "bu/myriadstream.h"
12#include "bu/optparser.h"
13
14#include <stdlib.h>
15
16using namespace Bu;
17
18enum Mode
19{
20 modeCreate,
21 modeInfo,
22 modeStreamNew,
23 modeStreamErase,
24 modeStreamDump,
25 modeStreamPut,
26 modeStreamGet,
27 modeBlockMap,
28
29 modeNone
30};
31
32class Options : public OptParser
33{
34public:
35 Options( int argc, char *argv[] ) :
36 eMode( modeNone ),
37 iBlockSize( 64 ),
38 iPreallocate( 0 ),
39 iStream( 0 )
40 {
41 addHelpBanner("Mode of operation:");
42 addOption( eMode, 'c', "create",
43 "Create a new Myriad file." );
44 addOption( eMode, 'i', "info",
45 "Display some info about a Myriad file." );
46 addOption( eMode, 'n', "new",
47 "Create a new sub-stream in a Myriad file.");
48 addOption( eMode, 'e', "erase",
49 "Erase sub-stream in a Myriad file.");
50 addOption( eMode, 'd', "dump",
51 "Display a hexdump of a stream from a Myriad file.");
52 addOption( eMode, "get",
53 "Get a file out of a Myriad stream (use --dst).");
54 addOption( eMode, "put",
55 "Put a file into a Myriad stream (usr --src).");
56 addOption( eMode, 'm', "block-map",
57 "Visualize block usage.");
58 addHelpOption();
59
60 addHelpBanner("\nGeneral options:");
61 addOption( iBlockSize, 'b', "block-size", "Set the block size." );
62 addOption( iPreallocate, 'p', "preallocate",
63 "Number of blocks to preallocate." );
64 addOption( sFile, 'f', "file", "Set the Myriad filename." );
65 addOption( iStream, 's', "stream", "Substream to work with.");
66 addOption( sSrc, "src", "Source file for copying into a Myriad file.");
67 addOption( sDst, "dst",
68 "Destination file for copying out of a Myriad file.");
69
70 setOverride( "create", modeCreate );
71 setOverride( "info", modeInfo );
72 setOverride( "new", modeStreamNew );
73 setOverride( "erase", modeStreamErase );
74 setOverride( "dump", modeStreamDump );
75 setOverride( "put", modeStreamPut );
76 setOverride( "get", modeStreamGet );
77 setOverride( "block-map", modeBlockMap );
78
79 parse( argc, argv );
80 }
81
82 Mode eMode;
83 int iBlockSize;
84 int iPreallocate;
85 int iStream;
86 Bu::String sFile;
87 Bu::String sSrc;
88 Bu::String sDst;
89};
90
91Bu::Formatter &operator>>( Bu::Formatter &f, Mode & /*e*/ )
92{
93 sio << "Uh oh, the formatter was called..." << sio.nl;
94 return f;
95}
96
97void printMap( const Bu::BitString &bs )
98{
99 for( int j = 0; j < bs.getSize(); j++ )
100 {
101 if( j>0 && (j%50) == 0 )
102 Bu::println("");
103 if( bs.getBit( j ) )
104 Bu::print("#");
105 else
106 Bu::print("-");
107 }
108 Bu::println("\n");
109}
110
111void printMap( const Bu::Array<int32_t> &bm )
112{
113 int iBigest = 0;
114 for( int j = 0; j < bm.getSize(); j++ )
115 {
116 if( iBigest < bm[j] )
117 iBigest = bm[j];
118 }
119 int iWidth = Bu::String("%1").arg( iBigest ).end().getSize();
120 Bu::String sEmpty;
121 for( int j = 0; j < iWidth; j++ )
122 {
123 sEmpty += '-';
124 }
125 int iBreakAt = 60/(iWidth+1);
126 for( int j = 0; j < bm.getSize(); j++ )
127 {
128 if( j>0 && (j%iBreakAt) == 0 )
129 Bu::println("");
130
131 if( bm[j] < 0 )
132 Bu::print("%1 ").arg( sEmpty, Bu::Fmt(2).right().fill(' '));
133 else
134 Bu::print("%1 ").arg( bm[j], Bu::Fmt(2).right().fill(' '));
135
136 }
137 Bu::println("\n");
138}
139
140int main( int argc, char *argv[] )
141{
142 Options opts( argc, argv );
143
144 switch( opts.eMode )
145 {
146 case modeCreate:
147 if( !opts.sFile.isSet() )
148 {
149 sio << "Please specify a file to create." << sio.nl;
150 return 0;
151 }
152 else
153 {
154 File fOut( opts.sFile, File::WriteNew|File::Read );
155 Myriad m( fOut, opts.iBlockSize, opts.iPreallocate );
156 }
157 break;
158
159 case modeInfo:
160 if( !opts.sFile.isSet() )
161 {
162 sio << "Please specify a file to display info about." << sio.nl;
163 return 0;
164 }
165 else
166 {
167 File fIn( opts.sFile, File::Read );
168 Myriad m( fIn );
169 sio << "Myriad info:" << sio.nl
170 << " Block size: " << m.getBlockSize() << sio.nl
171 << " Block count: " << m.getTotalBlocks() << sio.nl
172 << " Blocks used: " << m.getUsedBlocks() << " ("
173 << m.getUsedBlocks()*100/m.getTotalBlocks() << "%)"
174 << sio.nl
175 << " Stream count: " << m.getTotalStreams() << sio.nl
176 << " Used space: " << m.getTotalUsedBytes() << sio.nl
177 << " Unused space: " << m.getTotalUnusedBytes() << sio.nl
178 << " % of files: " << (double)(m.getTotalBlocks()*m.getBlockSize())/(double)(m.getTotalUsedBytes() + m.getTotalUnusedBytes( 4096 ))*100.0 << sio.nl;
179/* Bu::Array<int> aStreams = m.getStreamIds();
180 sio << " Stream info:" << sio.nl;
181 for( Bu::Array<int>::iterator i = aStreams.begin(); i; i++ )
182 {
183 sio << " " << Fmt(4) << *i << ") "
184 << m.getStreamSize( *i ) << "b" << sio.nl;
185 } */
186 }
187 break;
188
189 case modeStreamNew:
190 if( !opts.sFile.isSet() )
191 {
192 sio << "Please specify a file manipulate." << sio.nl;
193 return 0;
194 }
195 else
196 {
197 File fOut( opts.sFile, File::Write|File::Read );
198 Myriad m( fOut );
199 m.create( Bu::Myriad::WriteNew, opts.iPreallocate );
200 }
201 break;
202
203 case modeStreamErase:
204 if( !opts.sFile.isSet() )
205 {
206 sio << "Please specify a file manipulate." << sio.nl;
207 return 0;
208 }
209 else
210 {
211 File fOut( opts.sFile, File::Write|File::Read );
212 Myriad m( fOut );
213 m.erase( opts.iStream );
214 printMap( m.buildBlockUseMap() );
215 printMap( m.buildBlockMap() );
216 }
217 break;
218
219 case modeStreamDump:
220 if( !opts.sFile.isSet() )
221 {
222 sio << "Please specify a file to manipulate." << sio.nl;
223 return 0;
224 }
225 else
226 {
227 File fOut( opts.sFile, File::Read );
228 Myriad m( fOut );
229 MyriadStream s = m.open( opts.iStream, Bu::Myriad::Read );
230 sio << "Stream " << opts.iStream << ":" << sio.nl;
231 char buf[8];
232 int iPos = 0;
233 while( !s.isEos() )
234 {
235 size_t sAmnt = s.read( buf, 8 );
236 sio << Fmt(5) << iPos << ": ";
237 iPos += sAmnt;
238 for( size_t j = 0; j < sAmnt; j++ )
239 {
240 sio << Fmt::hex(2) << (int)((unsigned char)buf[j])
241 << " ";
242 }
243 for( size_t j = sAmnt; j < 8; j++ )
244 {
245 sio << "-- ";
246 }
247 sio << "| ";
248 for( size_t j = 0; j < sAmnt; j++ )
249 {
250 if( buf[j] >= 32 && buf[j] <= 126 )
251 sio << buf[j] << " ";
252 else
253 sio << " ";
254 }
255 sio << sio.nl;
256 }
257 sio << "Position: " << s.tell() << ", isEos()=" << s.isEos()
258 << sio.nl;
259 }
260 break;
261
262 case modeStreamPut:
263 if( !opts.sFile.isSet() )
264 {
265 sio << "Please specify a file manipulate." << sio.nl;
266 return 0;
267 }
268 else if( !opts.sSrc.isSet() )
269 {
270 sio << "Please specify a source file to read." << sio.nl;
271 }
272 else
273 {
274 File fOut( opts.sFile, File::Write|File::Read );
275 Myriad m( fOut );
276 MyriadStream sOut = m.create(
277 Bu::Myriad::WriteNew, opts.iPreallocate
278 );
279 File fIn( opts.sSrc, File::Read );
280 char buf[1024];
281 while( !fIn.isEos() )
282 {
283 sOut.write( buf, fIn.read( buf, 1024 ) );
284 }
285 }
286 break;
287
288 case modeStreamGet:
289 if( !opts.sFile.isSet() )
290 {
291 sio << "Please specify a file manipulate." << sio.nl;
292 return 0;
293 }
294 else if( !opts.sDst.isSet() )
295 {
296 sio << "Please specify a destination file to write." << sio.nl;
297 }
298 else
299 {
300 File fIn( opts.sFile, File::Write|File::Read );
301 Myriad m( fIn );
302 MyriadStream sIn = m.open( opts.iStream, Bu::Myriad::Read );
303 File fOut( opts.sDst, File::Write|File::Create|File::Truncate );
304 char buf[1024];
305 while( !sIn.isEos() )
306 {
307 fOut.write( buf, sIn.read( buf, 1024 ) );
308 }
309 }
310 break;
311
312 case modeBlockMap:
313 if( !opts.sFile.isSet() )
314 {
315 sio << "Please specify a file manipulate." << sio.nl;
316 return 0;
317 }
318 {
319 File fIn( opts.sFile, File::Write|File::Read );
320 Myriad m( fIn );
321 printMap( m.buildBlockUseMap() );
322 printMap( m.buildBlockMap() );
323 }
324 break;
325
326 case modeNone:
327 sio << "Please select a mode, for more info, try --help."
328 << sio.nl << sio.nl;
329 break;
330 }
331
332 return 0;
333}
diff --git a/src/tools/myriadfs.cpp b/src/tools/myriadfs.cpp
new file mode 100644
index 0000000..587bc89
--- /dev/null
+++ b/src/tools/myriadfs.cpp
@@ -0,0 +1,269 @@
1/*
2 * Copyright (C) 2007-2023 Xagasoft, All rights reserved.
3 *
4 * This file is part of the libbu++ library and is released under the
5 * terms of the license contained in the file LICENSE.
6 */
7
8#include "bu/sio.h"
9#include "bu/streamstack.h"
10#include "bu/file.h"
11#include "bu/myriadfs.h"
12#include "bu/myriadstream.h"
13#include "bu/optparser.h"
14
15enum Mode
16{
17 modeList,
18 modeCat,
19 modeCopyIn,
20 modeCopyOut,
21 modeMkdir,
22 modeInitialize,
23 modeRm,
24
25 modeNone
26};
27
28Bu::Formatter &operator>>( Bu::Formatter &f, Mode & /*e*/ )
29{
30 Bu::sio << "Uh oh, the formatter was called..." << Bu::sio.nl;
31 return f;
32}
33
34class Options : public Bu::OptParser
35{
36public:
37 Options( int argc, char *argv[] ) :
38 eMode( modeNone ),
39 iBlockSize( 64 )
40 {
41 addHelpBanner("Options:");
42 addOption( sFile, 'f', "file", "Myriadfs file");
43 addOption( iBlockSize, 'b', "block-size",
44 "Specify the block size when initializing a new MyriadFs");
45
46 setNonOption( Bu::slot( this, &Options::nonOption ) );
47
48 addHelpOption();
49
50 parse( argc, argv );
51 }
52
53 int nonOption( Bu::Array<Bu::String> aParams )
54 {
55 if( eMode == modeNone )
56 {
57 //Bu::println("Checking mode");
58 // First param, must be the mode
59 if( aParams[0] == "ls" )
60 eMode = modeList;
61 else if( aParams[0] == "cat" )
62 eMode = modeCat;
63 else if( aParams[0] == "cp-in" )
64 eMode = modeCopyIn;
65 else if( aParams[0] == "cp-out" )
66 eMode = modeCopyOut;
67 else if( aParams[0] == "mkdir" )
68 eMode = modeMkdir;
69 else if( aParams[0] == "initialize" )
70 eMode = modeInitialize;
71 else if( aParams[0] == "rm" )
72 eMode = modeRm;
73 else
74 Bu::println("Unknown command, try --help");
75 return 0;
76 } else {
77 lParams.append( aParams[0] );
78 }
79 //Bu::println("Got option: \"%1\"").arg( aParams[0] );
80 return 0;
81 }
82
83 Mode eMode;
84 Bu::String sFile;
85 Bu::StringList lParams;
86 int iBlockSize;
87};
88
89int main( int argc, char *argv[] )
90{
91 Options opt( argc, argv );
92
93 if( opt.sFile.isEmpty() )
94 {
95 Bu::println("You must specify a MyriadFs stream (see -f).\n");
96 return 1;
97 }
98
99 if( opt.eMode == modeNone )
100 {
101 Bu::println("Specify an operation to perfrom.\n");
102 return 1;
103 }
104
105 int iFlags = Bu::File::ReadWrite;
106
107 if( opt.eMode == modeInitialize )
108 {
109 iFlags |= Bu::File::Create|Bu::File::Truncate;
110 }
111
112 Bu::File fFs( opt.sFile, iFlags );
113 Bu::MyriadFs mFs( fFs, opt.iBlockSize );
114
115 switch( opt.eMode )
116 {
117 case modeList:
118 {
119 Bu::String sPath = "/";
120 if( opt.lParams.getSize() > 0 )
121 {
122 sPath = opt.lParams.first();
123 }
124 Bu::MyriadFs::Dir lEnt = mFs.readDir( sPath );
125 for( Bu::MyriadFs::Dir::iterator i = lEnt.begin(); i; i++ )
126 {
127 Bu::String sPerm;
128 switch( (*i).uPerms&Bu::MyriadFs::typeMask )
129 {
130 case Bu::MyriadFs::typeDir: sPerm += "d"; break;
131 case Bu::MyriadFs::typeChrDev: sPerm += "c"; break;
132 case Bu::MyriadFs::typeBlkDev: sPerm += "b"; break;
133 case Bu::MyriadFs::typeSymLink: sPerm += "l"; break;
134 case Bu::MyriadFs::typeSocket: sPerm += "s"; break;
135 default: sPerm += "-"; break;
136 }
137 sPerm += ((*i).uPerms&Bu::MyriadFs::permUsrR)?"r":"-";
138 sPerm += ((*i).uPerms&Bu::MyriadFs::permUsrW)?"w":"-";
139 sPerm += ((*i).uPerms&Bu::MyriadFs::permUsrX)?"x":"-";
140 sPerm += ((*i).uPerms&Bu::MyriadFs::permGrpR)?"r":"-";
141 sPerm += ((*i).uPerms&Bu::MyriadFs::permGrpW)?"w":"-";
142 sPerm += ((*i).uPerms&Bu::MyriadFs::permGrpX)?"x":"-";
143 sPerm += ((*i).uPerms&Bu::MyriadFs::permOthR)?"r":"-";
144 sPerm += ((*i).uPerms&Bu::MyriadFs::permOthW)?"w":"-";
145 sPerm += ((*i).uPerms&Bu::MyriadFs::permOthX)?"x":"-";
146 Bu::println("%1 %2 %3:%4 %5 %6")
147 .arg( sPerm )
148 .arg( (*i).iNode )
149 .arg( (*i).iUser )
150 .arg( (*i).iGroup )
151 .arg( (*i).iSize )
152 .arg( (*i).sName );
153 }
154 }
155 break;
156
157 case modeCat:
158 {
159 if( opt.lParams.isEmpty() )
160 {
161 Bu::println("Specify at least one file.");
162 return 1;
163 }
164 int iBlockSize = 1024*1024;
165 char *pBuf = new char[iBlockSize];
166 for( Bu::StringList::iterator i = opt.lParams.begin(); i; i++ )
167 {
168 Bu::MyriadStream ms = mFs.open( *i, Bu::MyriadFs::Read );
169 int iRead = 0;
170 do
171 {
172 iRead = ms.read( pBuf, iBlockSize );
173 if( iRead > 0 )
174 {
175 Bu::sioRaw.write( pBuf, iRead );
176 }
177 } while( iRead == iBlockSize );
178 }
179 delete[] pBuf;
180 }
181 break;
182
183 case modeCopyIn:
184 {
185 if( opt.lParams.getSize() != 2 )
186 {
187 Bu::println("Specify a source file and destination file.");
188 return 1;
189 }
190 int iBlockSize = 1024*1024;
191 char *pBuf = new char[iBlockSize];
192 Bu::File fs = Bu::File(
193 opt.lParams.first(), Bu::File::Read );
194 Bu::MyriadStream ms = mFs.open(
195 opt.lParams.last(), Bu::MyriadFs::WriteNew );
196 int iRead = 0;
197 do
198 {
199 iRead = fs.read( pBuf, iBlockSize );
200 if( iRead > 0 )
201 {
202 ms.write( pBuf, iRead );
203 }
204 } while( iRead == iBlockSize );
205 delete[] pBuf;
206 }
207 break;
208
209 case modeCopyOut:
210 {
211 if( opt.lParams.getSize() != 2 )
212 {
213 Bu::println("Specify a source file and destination file.");
214 return 1;
215 }
216 int iBlockSize = 1024*1024;
217 char *pBuf = new char[iBlockSize];
218 Bu::MyriadStream ms = mFs.open(
219 opt.lParams.first(), Bu::MyriadFs::Read );
220 Bu::File fs = Bu::File(
221 opt.lParams.last(), Bu::File::WriteNew );
222 int iRead = 0;
223 do
224 {
225 iRead = ms.read( pBuf, iBlockSize );
226 if( iRead > 0 )
227 {
228 fs.write( pBuf, iRead );
229 }
230 } while( iRead == iBlockSize );
231 delete[] pBuf;
232 }
233 break;
234
235 case modeMkdir:
236 {
237 if( opt.lParams.isEmpty() )
238 {
239 Bu::println("Specify at least one directory.");
240 return 1;
241 }
242 for( Bu::StringList::iterator i = opt.lParams.begin(); i; i++ )
243 {
244 mFs.mkDir( *i, 0777 );
245 }
246 }
247 break;
248
249 case modeInitialize:
250 Bu::println("MyriadFs initialized.\n");
251 break;
252
253 case modeRm:
254 {
255 if( opt.lParams.getSize() != 1 )
256 {
257 Bu::println("Specify a file path.");
258 return 1;
259 }
260 mFs.unlink( opt.lParams.first() );
261 }
262 break;
263
264 case modeNone:
265 break;
266 }
267
268 return 0;
269}