@@ -22,6 +22,7 @@ THE SOFTWARE.
22
22
package cmd
23
23
24
24
import (
25
+ "bufio"
25
26
"bytes"
26
27
"context"
27
28
"fmt"
@@ -37,6 +38,8 @@ import (
37
38
38
39
"github.com/alecthomas/chroma/v2/quick"
39
40
"github.com/apex/log"
41
+ "github.com/blacktop/go-apfs/pkg/disk/dmg"
42
+ "github.com/blacktop/go-apfs/pkg/disk/hfsplus"
40
43
"github.com/blacktop/go-macho/pkg/cpio"
41
44
"github.com/blacktop/go-macho/pkg/xar"
42
45
"github.com/blacktop/ipsw/internal/magic"
@@ -72,14 +75,12 @@ func init() {
72
75
// pkgCmd represents the pkg command
73
76
var pkgCmd = & cobra.Command {
74
77
Use : "pkg [DMG|PKG]" ,
75
- Short : "List contents of a DMG/PKG file" ,
78
+ Short : "🚧 List contents of a DMG/PKG file" ,
76
79
Args : cobra .ExactArgs (1 ),
77
80
SilenceUsage : true ,
78
81
SilenceErrors : true ,
79
82
RunE : func (cmd * cobra.Command , args []string ) (err error ) {
80
83
81
- var cwd string
82
-
83
84
if Verbose {
84
85
log .SetLevel (log .DebugLevel )
85
86
}
@@ -92,6 +93,7 @@ var pkgCmd = &cobra.Command{
92
93
flat := viper .GetBool ("pkg.flat" )
93
94
output := viper .GetString ("pkg.output" )
94
95
96
+ var cwd string
95
97
if len (output ) == 0 {
96
98
cwd , err = os .Getwd ()
97
99
if err != nil {
@@ -115,15 +117,57 @@ var pkgCmd = &cobra.Command{
115
117
}
116
118
117
119
if isDMG {
118
- log .Fatal ("DMG files are not supported yet" )
119
- // d, err := dmg.Open(infile, nil)
120
- // if err != nil {
121
- // return err
122
- // }
123
- // defer d.Close()
124
- // if err := d.Load(); err != nil {
125
- // return err
120
+ d , err := dmg .Open (infile , nil )
121
+ if err != nil {
122
+ return err
123
+ }
124
+ defer d .Close ()
125
+ diskImg , err := d .Partition ("disk image" )
126
+ if err != nil {
127
+ return fmt .Errorf ("failed to open partition: %w" , err )
128
+ }
129
+ o , err := os .Create (filepath .Join (output , "disk.img" ))
130
+ if err != nil {
131
+ return err
132
+ }
133
+ defer o .Close ()
134
+ // if _, err := io.Copy(o, diskImg); err != nil {
135
+ // return fmt.Errorf("failed to copy disk image: %w", err)
126
136
// }
137
+
138
+ w := bufio .NewWriter (o )
139
+ if err := diskImg .Write (w ); err != nil {
140
+ return fmt .Errorf ("failed to write disk image: %w" , err )
141
+ }
142
+ if err := w .Flush (); err != nil {
143
+ return fmt .Errorf ("failed to flush buffer: %w" , err )
144
+ }
145
+ log .Infof ("Extracted disk image to %s" , strings .TrimPrefix (filepath .Join (output , "disk.img" ), cwd + "/" ))
146
+
147
+ ///////////////////////////////////////
148
+
149
+ log .Info ("Parsing disk.img as HFS+..." )
150
+ hfs , err := hfsplus .Open (filepath .Join (output , "disk.img" ))
151
+ if err != nil {
152
+ return fmt .Errorf ("failed to open HFS+: %w" , err )
153
+ }
154
+ defer hfs .Close ()
155
+ files , err := hfs .Files ()
156
+ if err != nil {
157
+ return fmt .Errorf ("failed to get files: %w" , err )
158
+ }
159
+ for _ , hf := range files {
160
+ ff , err := os .Create (filepath .Join (output , hf .Key .NodeName .String ()))
161
+ if err != nil {
162
+ return fmt .Errorf ("failed to create file: %w" , err )
163
+ }
164
+ defer ff .Close ()
165
+ if _ , err := io .Copy (ff , hf .Reader ()); err != nil {
166
+ return fmt .Errorf ("failed to copy file: %w" , err )
167
+ }
168
+ log .Infof ("Extracted %s" , strings .TrimPrefix (filepath .Join (output , hf .Key .NodeName .String ()), cwd + "/" ))
169
+ log .Warnf ("NOW try running `ipsw pkg %s`" , strings .TrimPrefix (filepath .Join (output , hf .Key .NodeName .String ()), cwd + "/" ))
170
+ }
127
171
} else { // PKG/XAR
128
172
pkg , err := xar .Open (infile )
129
173
if err != nil {
0 commit comments