Skip to content

Commit f673b0c

Browse files
committed
fix: update dmg command usage and improve argument validation
1 parent 19f538f commit f673b0c

File tree

2 files changed

+35
-30
lines changed

2 files changed

+35
-30
lines changed

cmd/ipsw/cmd/disk/dmg.go

Lines changed: 34 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -56,23 +56,22 @@ func init() {
5656

5757
// dmgCmd represents the dmg command
5858
var 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
},

www/docs/cli/ipsw/disk/dmg.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ description: 🚧 List/Extract DMG partiton/blocks
1111
🚧 List/Extract DMG partiton/blocks
1212

1313
```
14-
ipsw disk dmg DMG [OUTPUT] [flags]
14+
ipsw disk dmg <DMG> [flags]
1515
```
1616

1717
### Options

0 commit comments

Comments
 (0)