Skip to content

Commit 4740288

Browse files
authored
feat: 🆕 pkg cmd (#638)
1 parent d5dd8aa commit 4740288

File tree

7 files changed

+832
-3
lines changed

7 files changed

+832
-3
lines changed

‎.cursor/rules/golang.mdc

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
---
2+
description: Golang
3+
globs: *.go
4+
---
5+
6+
You are an expert AI programming assistant specializing in building APIs with Go, using the standard library's net/http package and the new ServeMux introduced in Go 1.22.
7+
8+
Always use the latest stable version of Go (1.23 or newer) and be familiar with RESTful API design principles, best practices, and Go idioms.
9+
10+
- Follow the user's requirements carefully & to the letter.
11+
- First think step-by-step - describe your plan for the API structure, endpoints, and data flow in pseudocode, written out in great detail.
12+
- Confirm the plan, then write code!
13+
- Write correct, up-to-date, bug-free, fully functional, secure, and efficient Go code for APIs.
14+
- Use the standard library's net/http package for API development:
15+
- Utilize the new ServeMux introduced in Go 1.22 for routing
16+
- Implement proper handling of different HTTP methods (GET, POST, PUT, DELETE, etc.)
17+
- Use method handlers with appropriate signatures (e.g., func(w http.ResponseWriter, r *http.Request))
18+
- Leverage new features like wildcard matching and regex support in routes
19+
- Implement proper error handling, including custom error types when beneficial.
20+
- Use appropriate status codes and format JSON responses correctly.
21+
- Implement input validation for API endpoints.
22+
- Utilize Go's built-in concurrency features when beneficial for API performance.
23+
- Follow RESTful API design principles and best practices.
24+
- Include necessary imports, package declarations, and any required setup code.
25+
- Implement proper logging using the standard library's log package or a simple custom logger.
26+
- Consider implementing middleware for cross-cutting concerns (e.g., logging, authentication).
27+
- Implement rate limiting and authentication/authorization when appropriate, using standard library features or simple custom implementations.
28+
- Leave NO todos, placeholders, or missing pieces in the API implementation.
29+
- Be concise in explanations, but provide brief comments for complex logic or Go-specific idioms.
30+
- If unsure about a best practice or implementation detail, say so instead of guessing.
31+
- Offer suggestions for testing the API endpoints using Go's testing package.
32+
33+
Always prioritize security, scalability, and maintainability in your API designs and implementations. Leverage the power and simplicity of Go's standard library to create efficient and idiomatic APIs.
34+

‎Makefile

+6
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,12 @@ work-macho: ## Work on go-macho package
163163
@go work init
164164
@go work use . ../go-macho
165165

166+
.PHONY: work-apfs
167+
work-apfs: ## Work on go-apfs package
168+
@echo " > Working on go-apfs package"
169+
@go work init
170+
@go work use . ../go-apfs
171+
166172
.PHONY: docker
167173
docker: ## Build docker image
168174
@echo " > Building Docker Image"

‎cmd/ipsw/cmd/pkg.go

+132
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
/*
2+
Copyright © 2024 blacktop
3+
4+
Permission is hereby granted, free of charge, to any person obtaining a copy
5+
of this software and associated documentation files (the "Software"), to deal
6+
in the Software without restriction, including without limitation the rights
7+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8+
copies of the Software, and to permit persons to whom the Software is
9+
furnished to do so, subject to the following conditions:
10+
11+
The above copyright notice and this permission notice shall be included in
12+
all copies or substantial portions of the Software.
13+
14+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20+
THE SOFTWARE.
21+
*/
22+
package cmd
23+
24+
import (
25+
"bytes"
26+
"context"
27+
"fmt"
28+
"path/filepath"
29+
"runtime"
30+
"sort"
31+
"strings"
32+
33+
"github.com/apex/log"
34+
"github.com/spf13/cobra"
35+
36+
"github.com/blacktop/go-macho/pkg/cpio"
37+
"github.com/blacktop/go-macho/pkg/xar"
38+
"github.com/blacktop/ipsw/internal/magic"
39+
"github.com/blacktop/ipsw/pkg/ota/pbzx"
40+
)
41+
42+
func init() {
43+
rootCmd.AddCommand(pkgCmd)
44+
}
45+
46+
// pkgCmd represents the pkg command
47+
var pkgCmd = &cobra.Command{
48+
Use: "pkg",
49+
Short: "List contents of a DMG/PKG file",
50+
Args: cobra.ExactArgs(1),
51+
SilenceUsage: true,
52+
SilenceErrors: true,
53+
RunE: func(cmd *cobra.Command, args []string) error {
54+
55+
if Verbose {
56+
log.SetLevel(log.DebugLevel)
57+
}
58+
59+
infile := filepath.Clean(args[0])
60+
61+
isDMG, err := magic.IsDMG(infile)
62+
if err != nil {
63+
return err
64+
}
65+
if !isDMG {
66+
if isXar, err := magic.IsXar(infile); err != nil {
67+
return err
68+
} else if !isXar {
69+
return fmt.Errorf("file is not a dmg OR pkg file")
70+
}
71+
}
72+
73+
if isDMG {
74+
log.Fatal("DMG files are not supported yet")
75+
// d, err := dmg.Open(infile, nil)
76+
// if err != nil {
77+
// return err
78+
// }
79+
// defer d.Close()
80+
// if err := d.Load(); err != nil {
81+
// return err
82+
// }
83+
} else { // PKG/XAR
84+
pkg, err := xar.OpenReader(infile)
85+
if err != nil {
86+
return err
87+
}
88+
// FIXME defer xar.Close()
89+
if !pkg.ValidSignature() {
90+
log.Warn("PKG/XAR file signature is invalid, this may be a corrupted file")
91+
}
92+
var names []string
93+
var payload *xar.File
94+
for _, file := range pkg.File {
95+
names = append(names, file.Name)
96+
if strings.Contains(file.Name, "Payload") {
97+
payload = file
98+
}
99+
}
100+
sort.StringSlice(names).Sort()
101+
for _, name := range names {
102+
fmt.Println(name)
103+
}
104+
if payload != nil {
105+
f, err := payload.Open()
106+
if err != nil {
107+
return err
108+
}
109+
defer f.Close()
110+
log.Infof("Parsing %s...", payload.Name)
111+
var pbuf bytes.Buffer
112+
if err := pbzx.Extract(context.Background(), f, &pbuf, runtime.NumCPU()); err != nil {
113+
return err
114+
}
115+
cr, err := cpio.NewReader(bytes.NewReader(pbuf.Bytes()), int64(pbuf.Len()))
116+
if err != nil {
117+
return err
118+
}
119+
var cnames []string
120+
for _, file := range cr.Files {
121+
cnames = append(cnames, file.Name)
122+
}
123+
sort.StringSlice(cnames).Sort()
124+
for _, name := range cnames {
125+
fmt.Println(name)
126+
}
127+
}
128+
}
129+
130+
return nil
131+
},
132+
}

‎go.mod

+3-1
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,9 @@ require (
1111
github.com/apex/log v1.9.0
1212
github.com/aymanbagabas/go-udiff v0.2.0
1313
github.com/blacktop/arm64-cgo v1.0.58
14+
github.com/blacktop/go-apfs v1.0.18
1415
github.com/blacktop/go-dwarf v1.0.10
15-
github.com/blacktop/go-macho v1.1.234
16+
github.com/blacktop/go-macho v1.1.235
1617
github.com/blacktop/go-plist v1.0.2
1718
github.com/blacktop/lzfse-cgo v1.1.20
1819
github.com/blacktop/lzss v0.1.1
@@ -174,6 +175,7 @@ require (
174175
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
175176
github.com/ugorji/go/codec v1.2.12 // indirect
176177
github.com/ulikunitz/lz v0.4.0 // indirect
178+
github.com/vbauerster/mpb/v7 v7.5.3 // indirect
177179
github.com/wk8/go-ordered-map/v2 v2.1.8 // indirect
178180
github.com/xanzy/ssh-agent v0.3.3 // indirect
179181
go.opentelemetry.io/auto/sdk v1.1.0 // indirect

‎go.sum

+8-2
Original file line numberDiff line numberDiff line change
@@ -65,10 +65,12 @@ github.com/blacktop/arm64-cgo v1.0.58 h1:ANTB5JUcLzFfsKxNsp0obn/lyvLMIBa1tKiNCAc
6565
github.com/blacktop/arm64-cgo v1.0.58/go.mod h1:3QC9E3mn9o8Xxf8fILONjGOC9Ss/OgutkYnmNnsu+X4=
6666
github.com/blacktop/cast v1.5.2 h1:xyly5tHI2Eyr6bYx5tnANMwr274RYeDBRglysZ2ECe8=
6767
github.com/blacktop/cast v1.5.2/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo=
68+
github.com/blacktop/go-apfs v1.0.18 h1:icqUskKTGfxAx8b4D3gyCHzZ5joWUpT5fjIBdmP1sno=
69+
github.com/blacktop/go-apfs v1.0.18/go.mod h1:E7ErdLcun7HCReIbOr4/ykGE1m4HYsczsxX1Q+ClkzA=
6870
github.com/blacktop/go-dwarf v1.0.10 h1:i9zYgcIROETsNZ6V+zZn3uDH21FCG5BLLZ837GitxS0=
6971
github.com/blacktop/go-dwarf v1.0.10/go.mod h1:4W2FKgSFYcZLDwnR7k+apv5i3nrau4NGl9N6VQ9DSTo=
70-
github.com/blacktop/go-macho v1.1.234 h1:zLC4Qq4K1BNm2UffcFAcQFmjloPZddleISu42VdAZnk=
71-
github.com/blacktop/go-macho v1.1.234/go.mod h1:dtlW2AJKQpFzImBVPWiUKZ6OxrQ2MLfWi/BPPe0EONE=
72+
github.com/blacktop/go-macho v1.1.235 h1:5LrK/OIhmT2A1ZOVC/Is+Y/Ch+wjYQAFmT63K5sOmF4=
73+
github.com/blacktop/go-macho v1.1.235/go.mod h1:dtlW2AJKQpFzImBVPWiUKZ6OxrQ2MLfWi/BPPe0EONE=
7274
github.com/blacktop/go-plist v1.0.2 h1:DMX8uBiE308HWZkO9o37j7Z2b0neI3GSzN2caNa2zXk=
7375
github.com/blacktop/go-plist v1.0.2/go.mod h1:fqVhCVVXVJWsIGY9QPgdK0mDWZD82HrRMfU5PanvdTA=
7476
github.com/blacktop/lzfse-cgo v1.1.20 h1:xlfMq7g1aaMCyWr8/hHqsWzvfaF8QaliU1YxDCfMx68=
@@ -319,6 +321,7 @@ github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D
319321
github.com/mattn/go-mastodon v0.0.9 h1:zAlQF0LMumKPQLNR7dZL/YVCrvr4iP6ayyzxTR3vsSw=
320322
github.com/mattn/go-mastodon v0.0.9/go.mod h1:8YkqetHoAVEktRkK15qeiv/aaIMfJ/Gc89etisPZtHU=
321323
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
324+
github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
322325
github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc=
323326
github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
324327
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE=
@@ -453,6 +456,8 @@ github.com/ulikunitz/xz v0.6.0-alpha.3 h1:7IGVhjpaTpgeNBUPQcbtooPhFXDgeGxzhFki5B
453456
github.com/ulikunitz/xz v0.6.0-alpha.3/go.mod h1:ndJU5gy7q0Ffe1saQwmPKbMhIhJbwdu4+3t8eTxRF5U=
454457
github.com/unicorn-engine/unicorn v0.0.0-20240926111503-d568885d64c8 h1:fEkcOPX+BLPy00VWa3XCR5KFfTkb8bWn58xHsEp217c=
455458
github.com/unicorn-engine/unicorn v0.0.0-20240926111503-d568885d64c8/go.mod h1:mcHBrigWSHlMZYol9QOFnK7sbltIt/OaKP5CQBZsC+4=
459+
github.com/vbauerster/mpb/v7 v7.5.3 h1:BkGfmb6nMrrBQDFECR/Q7RkKCw7ylMetCb4079CGs4w=
460+
github.com/vbauerster/mpb/v7 v7.5.3/go.mod h1:i+h4QY6lmLvBNK2ah1fSreiw3ajskRlBp9AhY/PnuOE=
456461
github.com/vbauerster/mpb/v8 v8.9.2 h1:kb91+D643Qg040bbICYtzpjgZ9ypVO/+sjv4Jcm6si4=
457462
github.com/vbauerster/mpb/v8 v8.9.2/go.mod h1:hxS8Hz4C6ijnppDSIX6LjG8FYJSoPo9iIOcE53Zik0c=
458463
github.com/wk8/go-ordered-map/v2 v2.1.8 h1:5h/BUHu93oj4gIdvHHHGsScSTMijfx5PeYkE/fJgbpc=
@@ -570,6 +575,7 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc
570575
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
571576
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
572577
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
578+
golang.org/x/sys v0.0.0-20220909162455-aba9fc2a8ff2/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
573579
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
574580
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
575581
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=

0 commit comments

Comments
 (0)