@@ -36,6 +36,7 @@ static struct option longopts[] = {
3636 { " verbose" , no_argument, NULL , ' v' },
3737 { " writeable" , no_argument, NULL , ' w' },
3838
39+ { " extract-resource" , no_argument, NULL , 0 },
3940 { " inode" , required_argument, NULL , 0 },
4041 { " mount" , required_argument, NULL , 0 },
4142 { " offset" , required_argument, NULL , 0 },
@@ -58,6 +59,7 @@ void cmd_help(){
5859 " -r, --recursive\t\t perform operation recursively\n "
5960 " -v, --verbose\t\t\t increase logging output\n "
6061 " -w, --writeable\t\t open image in write mode\n "
62+ " --extract-resource\t extract file resource instead of file contents\n "
6163 " --inode <num>\t\t specify file by Inode instead of path\n "
6264 " --mount <path>\t\t path to mount\n "
6365 " --offset <cnt>\t\t offset inside image\n "
@@ -127,6 +129,7 @@ int main_r(int argc, const char * argv[]) {
127129
128130 bool doList = false ;
129131 bool doExtract = false ;
132+ bool doExtractResource = false ;
130133
131134 bool dumpInode = false ;
132135
@@ -136,7 +139,9 @@ int main_r(int argc, const char * argv[]) {
136139 {
137140 std::string curopt = longopts[optindex].name ;
138141
139- if (curopt == " inode" ) {
142+ if (curopt == " extract-resource" ) {
143+ doExtractResource = true ;
144+ }else if (curopt == " inode" ){
140145 iNode = atoi (optarg);
141146 }else if (curopt == " mount" ){
142147 mountPath = optarg;
@@ -229,18 +234,35 @@ int main_r(int argc, const char * argv[]) {
229234 size_t bufSize = img->getBlocksize ();
230235
231236 auto f = img->openFilAtPath (imagePath);
232- uint64_t size = f->size ();
233- if (bufSize > size) bufSize = size;
234- assure (buf = (uint8_t *)calloc (1 , bufSize));
237+
235238 retassure ((fd = open (outfile, O_CREAT | O_WRONLY, 0644 )) != -1 , " Failed to create output file '%s' errno=%d (%s)" ,outfile,errno,strerror (errno));
236-
237- while (size) {
238- size_t didread = 0 ;
239- retassure (didread = f->read (buf, bufSize), " Failed to read file" );
240- retassure (write (fd, buf, bufSize) == bufSize, " Failed to write data to file '%s'" ,outfile);
241- size -= didread;
239+
240+ uint64_t size = doExtractResource ? f->resource_size () : f->size ();
241+ if (size) {
242+ if (bufSize > size) bufSize = size;
243+ assure (buf = (uint8_t *)calloc (1 , bufSize));
244+
245+
246+ if (doExtractResource){
247+ uint64_t offset = 0 ;
248+ while (size) {
249+ size_t didread = 0 ;
250+ retassure (didread = f->resource_pread (buf, bufSize, offset), " Failed to pread file resource" );
251+ retassure (write (fd, buf, bufSize) == bufSize, " Failed to write data to file '%s'" ,outfile);
252+ offset += didread;
253+ size -= didread;
254+ }
255+ info (" Extracted resource of '%s' to '%s'" ,imagePath.c_str (),outfile);
256+ }else {
257+ while (size) {
258+ size_t didread = 0 ;
259+ retassure (didread = f->read (buf, bufSize), " Failed to read file" );
260+ retassure (write (fd, buf, bufSize) == bufSize, " Failed to write data to file '%s'" ,outfile);
261+ size -= didread;
262+ }
263+ info (" Extracted '%s' to '%s'" ,imagePath.c_str (),outfile);
264+ }
242265 }
243- info (" Extracted '%s' to '%s'" ,imagePath.c_str (),outfile);
244266 } else if (doList) {
245267 if (!imagePath.size ()) imagePath = " /" ;
246268 img->iterateOverFilesInFolder (imagePath, recursive, [&](std::string path, OrbisFSInode_t node){
@@ -299,7 +321,10 @@ int main_r(int argc, const char * argv[]) {
299321 printf (" \t createDate : %10lld (%s)\n " ,node.createDate ,strForDate (node.createDate ).c_str ());
300322 printf (" \t accessOrModDate : %10lld (%s)\n " ,node.accessOrModDate ,strForDate (node.accessOrModDate ).c_str ());
301323 printf (" \t modOrAccessData : %10lld (%s)\n " ,node.modOrAccessData ,strForDate (node.modOrAccessData ).c_str ());
302- printf (" \t resourceLnkMaybe : type: 0x%02x blk: %d\n " ,node.resourceLnkMaybe .type ,node.resourceLnkMaybe .blk );
324+ for (int i=0 ; i<ARRAYOF (node.resourceLnk ); i++) {
325+ if (node.resourceLnk [i].type != ORBIS_FS_CHAINLINK_TYPE_LINK) break ;
326+ printf (" \t resourceLnk[%2d] : type: 0x%02x blk: %d\n " ,i,node.resourceLnk [i].type ,node.resourceLnk [i].blk );
327+ }
303328 for (int i=0 ; i<ARRAYOF (node.dataLnk ); i++) {
304329 if (node.dataLnk [i].type != ORBIS_FS_CHAINLINK_TYPE_LINK) break ;
305330 printf (" \t dataLnk[%2d] : type: 0x%02x blk: %d\n " ,i,node.dataLnk [i].type ,node.dataLnk [i].blk );
0 commit comments