Skip to content

Commit 7910eab

Browse files
authored
Merge pull request #10 from simbadMarino/go122
Bump BTFS to v3.2.0
2 parents aebacd3 + 38dcb08 commit 7910eab

File tree

22 files changed

+954
-55
lines changed

22 files changed

+954
-55
lines changed

cmd/btfs_lib/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
ANDROID_OUT=./bin/jniLibs
33
IOS_OUT=./bin/ios
44
ANDROID_SDK=$(HOME)/Library/Android/sdk
5-
NDK_BIN=$(ANDROID_SDK)/ndk/23.1.7779620/toolchains/llvm/prebuilt/darwin-x86_64/bin
5+
NDK_BIN=$(ANDROID_SDK)/ndk/25.1.8937393/toolchains/llvm/prebuilt/darwin-x86_64/bin
66

77
# README
88
# CGO_CFLAGS=-v //This flag can be used to obtain more building information on C and C++ related building processes.

core/commands/add.go

Lines changed: 65 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@ import (
88
"math/big"
99
"os"
1010
"path"
11+
"strconv"
1112
"strings"
13+
"time"
1214

1315
"github.com/bittorrent/go-btfs/chain/abi"
1416
chainconfig "github.com/bittorrent/go-btfs/chain/config"
@@ -32,11 +34,30 @@ import (
3234
// ErrDepthLimitExceeded indicates that the max depth has been exceeded.
3335
var ErrDepthLimitExceeded = fmt.Errorf("depth limit exceeded")
3436

37+
type TimeParts struct {
38+
t *time.Time
39+
}
40+
41+
func (t TimeParts) MarshalJSON() ([]byte, error) {
42+
return t.t.MarshalJSON()
43+
}
44+
45+
// UnmarshalJSON implements the json.Unmarshaler interface.
46+
// The time is expected to be a quoted string in RFC 3339 format.
47+
func (t *TimeParts) UnmarshalJSON(data []byte) (err error) {
48+
// Fractional seconds are handled implicitly by Parse.
49+
tt, err := time.Parse("\"2006-01-02T15:04:05Z\"", string(data))
50+
*t = TimeParts{&tt}
51+
return
52+
}
53+
3554
type AddEvent struct {
3655
Name string
3756
Hash string `json:",omitempty"`
3857
Bytes int64 `json:",omitempty"`
3958
Size string `json:",omitempty"`
59+
Mode string `json:",omitempty"`
60+
Mtime int64 `json:",omitempty"`
4061
}
4162

4263
const (
@@ -61,6 +82,10 @@ const (
6182
peerIdName = "peer-id"
6283
pinDurationCountOptionName = "pin-duration-count"
6384
uploadToBlockchainOptionName = "to-blockchain"
85+
preserveModeOptionName = "preserve-mode"
86+
preserveMtimeOptionName = "preserve-mtime"
87+
modeOptionName = "mode"
88+
mtimeOptionName = "mtime"
6489
)
6590

6691
const adderOutChanSize = 8
@@ -168,6 +193,10 @@ only-hash, and progress/status related flags) will change the final hash.
168193
cmds.StringOption(peerIdName, "The peer id to encrypt the file."),
169194
cmds.IntOption(pinDurationCountOptionName, "d", "Duration for which the object is pinned in days.").WithDefault(0),
170195
cmds.BoolOption(uploadToBlockchainOptionName, "add file meta to blockchain").WithDefault(false),
196+
cmds.BoolOption(preserveModeOptionName, "Apply existing POSIX permissions to created UnixFS entries. Disables raw-leaves. (experimental)"),
197+
cmds.BoolOption(preserveMtimeOptionName, "Apply existing POSIX modification time to created UnixFS entries. Disables raw-leaves. (experimental)"),
198+
cmds.UintOption(modeOptionName, "Custom POSIX file mode to store in created UnixFS entries. Disables raw-leaves. (experimental)"),
199+
cmds.Int64Option(mtimeOptionName, "Custom POSIX modification time to store in created UnixFS entries (seconds before or after the Unix Epoch). Disables raw-leaves. (experimental)"),
171200
},
172201
PreRun: func(req *cmds.Request, env cmds.Environment) error {
173202
quiet, _ := req.Options[quietOptionName].(bool)
@@ -214,6 +243,10 @@ only-hash, and progress/status related flags) will change the final hash.
214243
peerId, _ := req.Options[peerIdName].(string)
215244
pinDuration, _ := req.Options[pinDurationCountOptionName].(int)
216245
uploadToBlockchain, _ := req.Options[uploadToBlockchainOptionName].(bool)
246+
preserveMode, _ := req.Options[preserveModeOptionName].(bool)
247+
preserveMtime, _ := req.Options[preserveMtimeOptionName].(bool)
248+
mode, _ := req.Options[modeOptionName].(uint)
249+
mtime, _ := req.Options[mtimeOptionName].(int64)
217250

218251
hashFunCode, ok := mh.Names[strings.ToLower(hashFunStr)]
219252
if !ok {
@@ -250,6 +283,9 @@ only-hash, and progress/status related flags) will change the final hash.
250283

251284
options.Unixfs.TokenMetadata(tokenMetadata),
252285
options.Unixfs.PinDuration(int64(pinDuration)),
286+
287+
options.Unixfs.PreserveMode(preserveMode),
288+
options.Unixfs.PreserveMtime(preserveMtime),
253289
}
254290

255291
if cidVerSet {
@@ -260,6 +296,19 @@ only-hash, and progress/status related flags) will change the final hash.
260296
opts = append(opts, options.Unixfs.RawLeaves(rawblks))
261297
}
262298

299+
// Storing optional mode or mtime (UnixFS 1.5) requires root block
300+
// to always be 'dag-pb' and not 'raw'. Below adjusts raw-leaves setting, if possible.
301+
if preserveMode || preserveMtime || mode != 0 || mtime != 0 {
302+
// Error if --raw-leaves flag was explicitly passed by the user.
303+
// (let user make a decision to manually disable it and retry)
304+
if rbset && rawblks {
305+
return fmt.Errorf("%s can't be used with UnixFS metadata like mode or modification time", rawLeavesOptionName)
306+
}
307+
// No explicit preference from user, disable raw-leaves and continue
308+
rbset = true
309+
rawblks = false
310+
}
311+
263312
if trickle {
264313
opts = append(opts, options.Unixfs.Layout(options.TrickleLayout))
265314
}
@@ -270,6 +319,13 @@ only-hash, and progress/status related flags) will change the final hash.
270319
opts = append(opts, options.Unixfs.PeerId(peerId))
271320
}
272321

322+
if mode != 0 {
323+
opts = append(opts, options.Unixfs.Mode(os.FileMode(mode)))
324+
}
325+
if mtime != 0 {
326+
opts = append(opts, options.Unixfs.Mtime(mtime))
327+
}
328+
273329
opts = append(opts, nil) // events option placeholder
274330

275331
var added int
@@ -304,12 +360,19 @@ only-hash, and progress/status related flags) will change the final hash.
304360
output.Name = path.Join(addit.Name(), output.Name)
305361
}
306362

307-
if err := res.Emit(&AddEvent{
363+
addEvent := AddEvent{
308364
Name: output.Name,
309365
Hash: h,
310366
Bytes: output.Bytes,
311367
Size: output.Size,
312-
}); err != nil {
368+
Mtime: output.Mtime,
369+
}
370+
371+
if output.Mode != 0 {
372+
addEvent.Mode = "0" + strconv.FormatUint(uint64(output.Mode), 8)
373+
}
374+
375+
if err := res.Emit(&addEvent); err != nil {
313376
return err
314377
}
315378
}

core/commands/cidstore.go

Lines changed: 235 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,235 @@
1+
package commands
2+
3+
import (
4+
"fmt"
5+
"io"
6+
"strings"
7+
8+
cmds "github.com/bittorrent/go-btfs-cmds"
9+
"github.com/bittorrent/go-btfs/core/commands/cmdenv"
10+
"github.com/ipfs/go-cid"
11+
"github.com/ipfs/go-datastore"
12+
"github.com/ipfs/go-datastore/query"
13+
)
14+
15+
const (
16+
SizeOptionName = "size"
17+
batchOptionName = "batch"
18+
)
19+
20+
const (
21+
FilterKeyPrefix = "/gateway/filter/cid"
22+
)
23+
24+
const (
25+
cidSeparator = ","
26+
)
27+
28+
var CidStoreCmd = &cmds.Command{
29+
Helptext: cmds.HelpText{
30+
Tagline: "Manage cid stored in this node but don't want to be get by gateway api.",
31+
ShortDescription: "Commands for generate, update, get and list access-keys stored in this node.",
32+
},
33+
Subcommands: map[string]*cmds.Command{
34+
"add": addCidCmd,
35+
"del": delCidCmd,
36+
"get": getCidCmd,
37+
"has": hasCidCmd,
38+
"list": listCidCmd,
39+
},
40+
NoLocal: true,
41+
}
42+
43+
var addCidCmd = &cmds.Command{
44+
Helptext: cmds.HelpText{
45+
Tagline: "Add cid to store.",
46+
},
47+
Options: []cmds.Option{
48+
cmds.BoolOption(batchOptionName, "b", "batch add cids, cids split by , and all exits will be deleted").WithDefault(false),
49+
},
50+
Arguments: []cmds.Argument{
51+
cmds.StringArg("cid", true, false, "cid to add to store"),
52+
},
53+
Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
54+
nd, err := cmdenv.GetNode(env)
55+
if err != nil {
56+
return err
57+
}
58+
59+
batch, _ := req.Options[batchOptionName].(bool)
60+
if batch {
61+
cids := strings.Split(req.Arguments[0], cidSeparator)
62+
batch, err := nd.Repo.Datastore().Batch(req.Context)
63+
if err != nil {
64+
return cmds.EmitOnce(res, err.Error())
65+
}
66+
67+
// check if all cid is valid if not return
68+
err = validateCIDs(cids)
69+
if err != nil {
70+
return cmds.EmitOnce(res, err.Error())
71+
}
72+
73+
// delete all exits
74+
results, err := nd.Repo.Datastore().Query(req.Context, query.Query{
75+
Prefix: FilterKeyPrefix,
76+
})
77+
if err != nil {
78+
return cmds.EmitOnce(res, err.Error())
79+
}
80+
for v := range results.Next() {
81+
err = batch.Delete(req.Context, datastore.NewKey(NewGatewayFilterKey(string(v.Value))))
82+
if err != nil {
83+
return cmds.EmitOnce(res, err.Error())
84+
}
85+
}
86+
87+
for _, v := range cids {
88+
if v == "" {
89+
continue
90+
}
91+
err = batch.Put(req.Context, datastore.NewKey(NewGatewayFilterKey(v)), []byte(v))
92+
if err != nil {
93+
return cmds.EmitOnce(res, err.Error())
94+
}
95+
}
96+
err = batch.Commit(req.Context)
97+
if err != nil {
98+
return cmds.EmitOnce(res, err.Error())
99+
}
100+
return cmds.EmitOnce(res, "Add batch ok.")
101+
}
102+
103+
cid := req.Arguments[0]
104+
err = validateCIDs([]string{cid})
105+
if err != nil {
106+
return cmds.EmitOnce(res, err.Error())
107+
}
108+
err = nd.Repo.Datastore().Put(req.Context, datastore.NewKey(NewGatewayFilterKey(cid)),
109+
[]byte(req.Arguments[0]))
110+
if err != nil {
111+
return cmds.EmitOnce(res, err.Error())
112+
}
113+
return cmds.EmitOnce(res, "Add ok.")
114+
},
115+
}
116+
117+
var getCidCmd = &cmds.Command{
118+
Helptext: cmds.HelpText{
119+
Tagline: "Get cid from store.",
120+
},
121+
Arguments: []cmds.Argument{
122+
cmds.StringArg("cid", true, false, "cid to add to store"),
123+
},
124+
Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
125+
nd, err := cmdenv.GetNode(env)
126+
if err != nil {
127+
return err
128+
}
129+
v, err := nd.Repo.Datastore().Get(req.Context, datastore.NewKey(NewGatewayFilterKey(req.Arguments[0])))
130+
if err != nil {
131+
return cmds.EmitOnce(res, err.Error())
132+
}
133+
return cmds.EmitOnce(res, string(v))
134+
},
135+
}
136+
137+
var delCidCmd = &cmds.Command{
138+
Helptext: cmds.HelpText{
139+
Tagline: "Delete cid from store.",
140+
},
141+
Arguments: []cmds.Argument{
142+
cmds.StringArg("cid", true, false, "cid to add to store"),
143+
},
144+
Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
145+
nd, err := cmdenv.GetNode(env)
146+
if err != nil {
147+
return err
148+
}
149+
err = nd.Repo.Datastore().Delete(req.Context, datastore.NewKey(NewGatewayFilterKey(req.Arguments[0])))
150+
if err != nil {
151+
return cmds.EmitOnce(res, err.Error())
152+
}
153+
return cmds.EmitOnce(res, "Del ok.")
154+
},
155+
}
156+
157+
var hasCidCmd = &cmds.Command{
158+
Helptext: cmds.HelpText{
159+
Tagline: "Check cid exits in store",
160+
},
161+
Arguments: []cmds.Argument{
162+
cmds.StringArg("cid", true, false, "cid to add to store"),
163+
},
164+
Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
165+
nd, err := cmdenv.GetNode(env)
166+
if err != nil {
167+
return err
168+
}
169+
exits, err := nd.Repo.Datastore().Has(req.Context, datastore.NewKey(NewGatewayFilterKey(req.Arguments[0])))
170+
if err != nil {
171+
return err
172+
}
173+
if !exits {
174+
return cmds.EmitOnce(res, "Cid not exits")
175+
}
176+
return cmds.EmitOnce(res, "Cid exits")
177+
},
178+
}
179+
180+
var listCidCmd = &cmds.Command{
181+
Helptext: cmds.HelpText{
182+
Tagline: "List all cids in store",
183+
},
184+
Options: []cmds.Option{
185+
cmds.IntOption(SizeOptionName, "s", "Number of cids to return."),
186+
},
187+
Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
188+
nd, err := cmdenv.GetNode(env)
189+
if err != nil {
190+
return err
191+
}
192+
size, _ := req.Options[SizeOptionName].(int)
193+
results, err := nd.Repo.Datastore().Query(req.Context, query.Query{
194+
Prefix: FilterKeyPrefix,
195+
Limit: size,
196+
})
197+
if err != nil {
198+
return err
199+
}
200+
var resStr []string
201+
for v := range results.Next() {
202+
resStr = append(resStr, string(v.Value))
203+
}
204+
return cmds.EmitOnce(res, resStr)
205+
},
206+
Encoders: cmds.EncoderMap{
207+
cmds.Text: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, cids []string) error {
208+
for _, v := range cids {
209+
_, err := w.Write([]byte(v + "\n"))
210+
if err != nil {
211+
return err
212+
}
213+
}
214+
return nil
215+
}),
216+
},
217+
Type: []string{},
218+
}
219+
220+
func NewGatewayFilterKey(key string) string {
221+
return fmt.Sprintf("%s/%s", FilterKeyPrefix, key)
222+
}
223+
224+
func validateCIDs(cids []string) error {
225+
for _, c := range cids {
226+
if c == "" {
227+
continue
228+
}
229+
_, err := cid.Decode(c)
230+
if err != nil {
231+
return fmt.Errorf("Invalid CID: %s", c)
232+
}
233+
}
234+
return nil
235+
}

0 commit comments

Comments
 (0)