/
fileOperation.go
141 lines (110 loc) · 2.89 KB
/
fileOperation.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
package tengu
import (
"bytes"
"fmt"
"github.com/jackpal/bencode-go"
"io"
"os"
)
type KeyPiece [SHA1Len]byte
type DataPiece []byte
type DataPackage struct {
size int
data []DataPiece
}
type KeyPackage struct {
size int
length int
infoHash [SHA1Len]byte
key []KeyPiece
}
func (this *KeyPackage) getKey(index int) string {
var ret KeyPiece
for i := 0; i < SHA1Len; i++ {
ret[i] = this.key[index][i] ^ this.infoHash[i]
}
return fmt.Sprintf("%x", ret)
}
func UploadFileProcessing(filePath string, fileName string, seedPath string) (KeyPackage, DataPackage, string, string) {
dataPackage, length := makeDataPackage(filePath)
green.Println("Data Packaged Finish. Total Piece: ", dataPackage.size)
var pieces string
for i := 0; i < dataPackage.size; i++ {
piece, _ := PiecesHash(dataPackage.data[i], i)
pieces += fmt.Sprintf("%x", piece)
}
torrent := bencodeTorrent{
Announce: "",
Info: bencodeInfo{
Length: length,
Pieces: pieces,
PieceLength: PieceSize,
Name: fileName,
},
}
err := torrent.Save(seedPath + fileName + ".torrent")
if err != nil {
red.Println("Failed to Make Torrent File ", err.Error())
}
keyPackage := torrent.makeKeyPackage()
green.Println("Torrent Resolved Finish: ")
torrent.Info.Display()
var magnet string
fileIO, err := os.Create(seedPath + fileName + "-magnet.txt")
if err != nil {
red.Println("Failed to Save Magnet URL.")
} else {
magnet = MakeMagnet(fmt.Sprintf("%x", keyPackage.infoHash))
fileIO.Write([]byte(magnet))
}
writer := bytes.NewBufferString("")
err = bencode.Marshal(writer, torrent)
return keyPackage, dataPackage, magnet, writer.String()
}
func DownloadFileProcessing(seedPath string) (KeyPackage, string) {
torrent, err := Open(seedPath)
if err != nil {
red.Println("Torrent Open Failed in path: ", seedPath, err.Error())
return KeyPackage{}, ""
}
keyPackage := torrent.makeKeyPackage()
green.Println("Torrent Resolved Finish: ")
torrent.Info.Display()
return keyPackage, torrent.Info.Name
}
func makeDataPackage(path string) (DataPackage, int) {
fileIO, err := os.Open(path)
length := 0
if err != nil {
red.Println("File Open Failed in path: ", path, err.Error())
return DataPackage{}, 0
}
var ret DataPackage
for {
buf := make([]byte, PieceSize)
bufSize, err := fileIO.Read(buf)
if err != nil && err != io.EOF {
red.Println("File Read Error.")
return DataPackage{}, 0
}
if bufSize == 0 {
break //finish read
}
ret.size++
length += bufSize
ret.data = append(ret.data, buf[:bufSize][:])
}
return ret, length
}
func (this *bencodeTorrent) makeKeyPackage() KeyPackage {
var ret KeyPackage
buf := []byte(this.Info.Pieces)
ret.size = len(buf) / SHA1StrLen
ret.infoHash, _ = this.Info.InfoHash()
ret.length = this.Info.Length
ret.key = make([]KeyPiece, ret.size)
for i := 0; i < ret.size; i++ {
copy(ret.key[i][:], buf[i*SHA1StrLen:(i+1)*SHA1StrLen])
}
return ret
}