@@ -56,23 +56,22 @@ func init() {
5656
5757// dmgCmd represents the dmg command
5858var dmgCmd = & cobra.Command {
59- Use : "dmg DMG [OUTPUT] " ,
59+ Use : "dmg < DMG> " ,
6060 Short : "🚧 List/Extract DMG partiton/blocks" ,
61- Args : cobra .MinimumNArgs (1 ),
61+ Args : cobra .ExactArgs (1 ),
6262 SilenceErrors : true ,
6363 RunE : func (cmd * cobra.Command , args []string ) (err error ) {
6464 // flags
6565 pattern := viper .GetString ("dmg.re" )
6666 partition := viper .GetInt ("dmg.partition" )
67+ outfile := viper .GetString ("dmg.output" )
68+
6769 // validate args
6870 if cmd .Flags ().Changed ("partition" ) && viper .GetString ("dmg.re" ) != "" {
6971 return fmt .Errorf ("cannot specify both --partition and --re" )
7072 }
71- if len (args ) > 1 && ! cmd .Flags ().Changed ("partition" ) && viper .GetString ("dmg.re" ) == "" {
72- return fmt .Errorf ("no partition specified. (use --partition or --re)" )
73- }
74- if len (args ) == 1 && (cmd .Flags ().Changed ("partition" ) || viper .GetString ("dmg.re" ) != "" ) {
75- return fmt .Errorf ("no output file specified" )
73+ if (cmd .Flags ().Changed ("partition" ) || viper .GetString ("dmg.re" ) != "" ) && outfile == "" {
74+ return fmt .Errorf ("no output file specified (use --output flag)" )
7675 }
7776 if viper .GetString ("dmg.password" ) != "" && viper .GetString ("dmg.key" ) != "" {
7877 return fmt .Errorf ("cannot specify both --password and --key" )
@@ -95,7 +94,11 @@ var dmgCmd = &cobra.Command{
9594 }
9695 defer d .Close ()
9796
98- if viper .GetBool ("dmg.decrypt" ) || viper .GetString ("dmg.output" ) != "" {
97+ // Determine if this is a decryption operation (not partition extraction)
98+ isDecryptOperation := viper .GetBool ("dmg.decrypt" ) ||
99+ (viper .GetString ("dmg.output" ) != "" && ! cmd .Flags ().Changed ("partition" ) && viper .GetString ("dmg.re" ) == "" )
100+
101+ if isDecryptOperation {
99102 // If only c.Decrypt is set, overwrite the input file
100103 if viper .GetBool ("dmg.decrypt" ) && viper .GetString ("dmg.output" ) == "" {
101104 log .Info ("Decrypting DMG in-place.." )
@@ -135,38 +138,40 @@ var dmgCmd = &cobra.Command{
135138
136139 var p * dmg.Partition
137140
138- if len (args ) == 1 {
141+ // If no partition selection and no output, just list partitions
142+ if ! cmd .Flags ().Changed ("partition" ) && viper .GetString ("dmg.re" ) == "" && outfile == "" {
139143 for idx , p := range d .Partitions {
140144 log .Infof ("%d) %s" , idx , p .Name )
141145 }
142146 return nil
143- } else {
144- if cmd .Flags ().Changed ("partition" ) {
145- if partition > len (d .Partitions )- 1 || partition < 0 {
146- return fmt .Errorf ("partition number out of range (there are %d partitions)" , len (d .Partitions ))
147- }
148- p = & d .Partitions [partition ]
149- } else if viper .GetString ("dmg.re" ) != "" {
150- re , err := regexp .Compile (pattern )
151- if err != nil {
152- return fmt .Errorf ("failed to compile regex '%s': %w" , pattern , err )
153- }
154- for _ , part := range d .Partitions {
155- if re .MatchString (part .Name ) {
156- p = & part
157- break
158- }
147+ }
148+
149+ // Extract partition
150+ if cmd .Flags ().Changed ("partition" ) {
151+ if partition > len (d .Partitions )- 1 || partition < 0 {
152+ return fmt .Errorf ("partition number out of range (there are %d partitions)" , len (d .Partitions ))
153+ }
154+ p = & d .Partitions [partition ]
155+ } else if viper .GetString ("dmg.re" ) != "" {
156+ re , err := regexp .Compile (pattern )
157+ if err != nil {
158+ return fmt .Errorf ("failed to compile regex '%s': %w" , pattern , err )
159+ }
160+ for _ , part := range d .Partitions {
161+ if re .MatchString (part .Name ) {
162+ p = & part
163+ break
159164 }
160- } else {
161- return fmt .Errorf ("no partition specified. (use --partition or --re)" )
162165 }
166+ } else {
167+ return fmt .Errorf ("no partition specified. (use --partition or --re)" )
163168 }
164169
165170 if p == nil {
166171 return fmt .Errorf ("no partition found matching criteria" )
167172 }
168173
169- o , err := os .Create (args [ 1 ] )
174+ o , err := os .Create (outfile )
170175 if err != nil {
171176 return err
172177 }
@@ -180,7 +185,7 @@ var dmgCmd = &cobra.Command{
180185 return fmt .Errorf ("failed to flush buffer: %w" , err )
181186 }
182187
183- log .Infof ("Extracted '%s' as %s" , p .Name , args [ 1 ] )
188+ log .Infof ("Extracted '%s' as %s" , p .Name , outfile )
184189
185190 return nil
186191 },
0 commit comments