mirror of
https://github.com/HACKERALERT/Picocrypt.git
synced 2024-12-30 19:32:33 +00:00
Finalize v1.29
This commit is contained in:
parent
b908bd7bd1
commit
dcb6bf3839
1 changed files with 99 additions and 74 deletions
173
src/Picocrypt.go
173
src/Picocrypt.go
|
@ -437,10 +437,17 @@ func draw() {
|
||||||
}
|
}
|
||||||
|
|
||||||
fout, _ := os.Create(file)
|
fout, _ := os.Create(file)
|
||||||
data := make([]byte, MiB)
|
data := make([]byte, KiB)
|
||||||
rand.Read(data)
|
rand.Read(data)
|
||||||
fout.Write(data)
|
_, err = fout.Write(data)
|
||||||
fout.Close()
|
fout.Close()
|
||||||
|
if err != nil {
|
||||||
|
insufficientSpace(nil, nil)
|
||||||
|
os.Remove(file)
|
||||||
|
} else {
|
||||||
|
mainStatus = "Ready."
|
||||||
|
mainStatusColor = WHITE
|
||||||
|
}
|
||||||
}),
|
}),
|
||||||
giu.Tooltip("Generate a cryptographically secure keyfile."),
|
giu.Tooltip("Generate a cryptographically secure keyfile."),
|
||||||
),
|
),
|
||||||
|
@ -625,7 +632,7 @@ func onDrop(names []string) {
|
||||||
if showKeyfile {
|
if showKeyfile {
|
||||||
keyfiles = append(keyfiles, names...)
|
keyfiles = append(keyfiles, names...)
|
||||||
|
|
||||||
// Remove duplicate keyfiles and make sure they're accessible
|
// Make sure keyfiles are accessible, remove duplicates
|
||||||
var tmp []string
|
var tmp []string
|
||||||
for _, i := range keyfiles {
|
for _, i := range keyfiles {
|
||||||
duplicate := false
|
duplicate := false
|
||||||
|
@ -638,6 +645,12 @@ func onDrop(names []string) {
|
||||||
fin, err := os.Open(i)
|
fin, err := os.Open(i)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
fin.Close()
|
fin.Close()
|
||||||
|
} else {
|
||||||
|
showKeyfile = false
|
||||||
|
resetUI()
|
||||||
|
accessDenied("Keyfile read")
|
||||||
|
giu.Update()
|
||||||
|
return
|
||||||
}
|
}
|
||||||
if !duplicate && !stat.IsDir() && err == nil {
|
if !duplicate && !stat.IsDir() && err == nil {
|
||||||
tmp = append(tmp, i)
|
tmp = append(tmp, i)
|
||||||
|
@ -705,8 +718,8 @@ func onDrop(names []string) {
|
||||||
outputFile = names[0][:ind]
|
outputFile = names[0][:ind]
|
||||||
recombine = true
|
recombine = true
|
||||||
|
|
||||||
totalFiles := 0
|
|
||||||
// Find out the number of splitted chunks
|
// Find out the number of splitted chunks
|
||||||
|
totalFiles := 0
|
||||||
for {
|
for {
|
||||||
stat, err := os.Stat(fmt.Sprintf("%s.%d", inputFile, totalFiles))
|
stat, err := os.Stat(fmt.Sprintf("%s.%d", inputFile, totalFiles))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -918,11 +931,9 @@ func work() {
|
||||||
}
|
}
|
||||||
compressDone = 0
|
compressDone = 0
|
||||||
|
|
||||||
|
// Add each file to the .zip
|
||||||
writer := zip.NewWriter(file)
|
writer := zip.NewWriter(file)
|
||||||
compressStart = time.Now()
|
compressStart = time.Now()
|
||||||
|
|
||||||
// Add each file to the .zip
|
|
||||||
|
|
||||||
for i, path := range files {
|
for i, path := range files {
|
||||||
progressInfo = fmt.Sprintf("%d/%d", i+1, len(files))
|
progressInfo = fmt.Sprintf("%d/%d", i+1, len(files))
|
||||||
giu.Update()
|
giu.Update()
|
||||||
|
@ -959,17 +970,15 @@ func work() {
|
||||||
fin.Close()
|
fin.Close()
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
insufficientSpace()
|
insufficientSpace(nil, file)
|
||||||
writer.Close()
|
writer.Close()
|
||||||
file.Close()
|
|
||||||
os.Remove(inputFile)
|
os.Remove(inputFile)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if !working {
|
if !working {
|
||||||
cancel()
|
cancel(nil, file)
|
||||||
writer.Close()
|
writer.Close()
|
||||||
file.Close()
|
|
||||||
os.Remove(inputFile)
|
os.Remove(inputFile)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -1004,12 +1013,18 @@ func work() {
|
||||||
// Merge all chunks into one file
|
// Merge all chunks into one file
|
||||||
startTime := time.Now()
|
startTime := time.Now()
|
||||||
for i := 0; i < totalFiles; i++ {
|
for i := 0; i < totalFiles; i++ {
|
||||||
fin, _ := os.Open(fmt.Sprintf("%s.%d", inputFile, i))
|
fin, err := os.Open(fmt.Sprintf("%s.%d", inputFile, i))
|
||||||
|
if err != nil {
|
||||||
|
fout.Close()
|
||||||
|
os.Remove(outputFile + ".pcv")
|
||||||
|
resetUI()
|
||||||
|
accessDenied("Read")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
for {
|
for {
|
||||||
if !working {
|
if !working {
|
||||||
cancel()
|
cancel(fin, fout)
|
||||||
fin.Close()
|
|
||||||
fout.Close()
|
|
||||||
os.Remove(outputFile + ".pcv")
|
os.Remove(outputFile + ".pcv")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -1025,9 +1040,7 @@ func work() {
|
||||||
done += read
|
done += read
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
insufficientSpace()
|
insufficientSpace(fin, fout)
|
||||||
fin.Close()
|
|
||||||
fout.Close()
|
|
||||||
os.Remove(outputFile + ".pcv")
|
os.Remove(outputFile + ".pcv")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -1065,7 +1078,7 @@ func work() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set up output file
|
// Setup output file
|
||||||
var fout *os.File
|
var fout *os.File
|
||||||
|
|
||||||
// If encrypting, generate values and write to file
|
// If encrypting, generate values and write to file
|
||||||
|
@ -1073,6 +1086,9 @@ func work() {
|
||||||
popupStatus = "Generating values..."
|
popupStatus = "Generating values..."
|
||||||
giu.Update()
|
giu.Update()
|
||||||
|
|
||||||
|
// Stores any errors when writing to file
|
||||||
|
errs := make([]error, 11)
|
||||||
|
|
||||||
// Create the output file
|
// Create the output file
|
||||||
var err error
|
var err error
|
||||||
fout, err = os.Create(outputFile)
|
fout, err = os.Create(outputFile)
|
||||||
|
@ -1089,15 +1105,18 @@ func work() {
|
||||||
nonce = make([]byte, 24)
|
nonce = make([]byte, 24)
|
||||||
|
|
||||||
// Write the program version to file
|
// Write the program version to file
|
||||||
fout.Write(rsEncode(rs5, []byte(version)))
|
_, errs[0] = fout.Write(rsEncode(rs5, []byte(version)))
|
||||||
|
|
||||||
// Encode and write the comment length to file
|
// Encode and write the comment length to file
|
||||||
commentsLength := []byte(fmt.Sprintf("%05d", len(comments)))
|
commentsLength := []byte(fmt.Sprintf("%05d", len(comments)))
|
||||||
fout.Write(rsEncode(rs5, commentsLength))
|
_, errs[1] = fout.Write(rsEncode(rs5, commentsLength))
|
||||||
|
|
||||||
// Encode the comment and write to file
|
// Encode the comment and write to file
|
||||||
for _, i := range []byte(comments) {
|
for _, i := range []byte(comments) {
|
||||||
fout.Write(rsEncode(rs1, []byte{i}))
|
_, err := fout.Write(rsEncode(rs1, []byte{i}))
|
||||||
|
if err != nil {
|
||||||
|
errs[2] = err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Configure flags and write to file
|
// Configure flags and write to file
|
||||||
|
@ -1117,7 +1136,7 @@ func work() {
|
||||||
if total%int64(MiB) >= int64(MiB)-128 { // Reed-Solomon internals
|
if total%int64(MiB) >= int64(MiB)-128 { // Reed-Solomon internals
|
||||||
flags[4] = 1
|
flags[4] = 1
|
||||||
}
|
}
|
||||||
fout.Write(rsEncode(rs5, flags))
|
_, errs[3] = fout.Write(rsEncode(rs5, flags))
|
||||||
|
|
||||||
// Fill values with Go's CSPRNG
|
// Fill values with Go's CSPRNG
|
||||||
rand.Read(salt)
|
rand.Read(salt)
|
||||||
|
@ -1126,15 +1145,27 @@ func work() {
|
||||||
rand.Read(nonce)
|
rand.Read(nonce)
|
||||||
|
|
||||||
// Encode values with Reed-Solomon and write to file
|
// Encode values with Reed-Solomon and write to file
|
||||||
fout.Write(rsEncode(rs16, salt))
|
_, errs[4] = fout.Write(rsEncode(rs16, salt))
|
||||||
fout.Write(rsEncode(rs32, hkdfSalt))
|
_, errs[5] = fout.Write(rsEncode(rs32, hkdfSalt))
|
||||||
fout.Write(rsEncode(rs16, serpentSalt))
|
_, errs[6] = fout.Write(rsEncode(rs16, serpentSalt))
|
||||||
fout.Write(rsEncode(rs24, nonce))
|
_, errs[7] = fout.Write(rsEncode(rs24, nonce))
|
||||||
|
|
||||||
// Write placeholders for future use
|
// Write placeholders for future use
|
||||||
fout.Write(make([]byte, 192)) // Hash of encryption key
|
_, errs[8] = fout.Write(make([]byte, 192)) // Hash of encryption key
|
||||||
fout.Write(make([]byte, 96)) // Hash of keyfile key
|
_, errs[9] = fout.Write(make([]byte, 96)) // Hash of keyfile key
|
||||||
fout.Write(make([]byte, 192)) // BLAKE2b/HMAC-SHA3 tag
|
_, errs[10] = fout.Write(make([]byte, 192)) // BLAKE2b/HMAC-SHA3 tag
|
||||||
|
|
||||||
|
for _, err := range errs {
|
||||||
|
if err != nil {
|
||||||
|
insufficientSpace(fin, fout)
|
||||||
|
os.Remove(outputFile + ".pcv")
|
||||||
|
if len(allFiles) > 1 || len(onlyFolders) > 0 || compress {
|
||||||
|
os.Remove(inputFile)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} else { // Decrypting, read values from file and decode
|
} else { // Decrypting, read values from file and decode
|
||||||
popupStatus = "Reading values..."
|
popupStatus = "Reading values..."
|
||||||
giu.Update()
|
giu.Update()
|
||||||
|
@ -1194,12 +1225,7 @@ func work() {
|
||||||
if keep { // If the user chooses to force decrypt
|
if keep { // If the user chooses to force decrypt
|
||||||
kept = true
|
kept = true
|
||||||
} else {
|
} else {
|
||||||
mainStatus = "The volume header is damaged."
|
broken(fin, nil, "The volume header is damaged.")
|
||||||
mainStatusColor = RED
|
|
||||||
fin.Close()
|
|
||||||
if recombine {
|
|
||||||
os.Remove(inputFile)
|
|
||||||
}
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1238,16 +1264,19 @@ func work() {
|
||||||
|
|
||||||
if keyfileOrdered { // If order matters, hash progressively
|
if keyfileOrdered { // If order matters, hash progressively
|
||||||
var tmp = sha3.New256()
|
var tmp = sha3.New256()
|
||||||
|
|
||||||
|
// For each keyfile...
|
||||||
for _, path := range keyfiles {
|
for _, path := range keyfiles {
|
||||||
fin, _ := os.Open(path)
|
fin, _ := os.Open(path)
|
||||||
stat, _ := os.Stat(path)
|
stat, _ := os.Stat(path)
|
||||||
data := make([]byte, stat.Size())
|
data := make([]byte, stat.Size())
|
||||||
fin.Read(data)
|
fin.Read(data) // Read the keyfile
|
||||||
fin.Close()
|
fin.Close()
|
||||||
tmp.Write(data)
|
tmp.Write(data) // Hash the data
|
||||||
}
|
}
|
||||||
keyfileKey = tmp.Sum(nil)
|
keyfileKey = tmp.Sum(nil) // Get the SHA3-256
|
||||||
|
|
||||||
|
// Store a hash of 'keyfileKey' for comparison
|
||||||
tmp = sha3.New256()
|
tmp = sha3.New256()
|
||||||
tmp.Write(keyfileKey)
|
tmp.Write(keyfileKey)
|
||||||
keyfileHash = tmp.Sum(nil)
|
keyfileHash = tmp.Sum(nil)
|
||||||
|
@ -1256,11 +1285,15 @@ func work() {
|
||||||
fin, _ := os.Open(path)
|
fin, _ := os.Open(path)
|
||||||
stat, _ := os.Stat(path)
|
stat, _ := os.Stat(path)
|
||||||
data := make([]byte, stat.Size())
|
data := make([]byte, stat.Size())
|
||||||
fin.Read(data)
|
fin.Read(data) // Read the keyfile
|
||||||
fin.Close()
|
fin.Close()
|
||||||
|
|
||||||
|
// Get the SHA3-256
|
||||||
tmp := sha3.New256()
|
tmp := sha3.New256()
|
||||||
tmp.Write(data)
|
tmp.Write(data)
|
||||||
sum := tmp.Sum(nil)
|
sum := tmp.Sum(nil)
|
||||||
|
|
||||||
|
// XOR keyfile hash with 'keyfileKey'
|
||||||
if keyfileKey == nil {
|
if keyfileKey == nil {
|
||||||
keyfileKey = sum
|
keyfileKey = sum
|
||||||
} else {
|
} else {
|
||||||
|
@ -1270,7 +1303,7 @@ func work() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Store a hash of the keyfile key for comparison
|
// Store a hash of 'keyfileKey' for comparison
|
||||||
tmp := sha3.New256()
|
tmp := sha3.New256()
|
||||||
tmp.Write(keyfileKey)
|
tmp.Write(keyfileKey)
|
||||||
keyfileHash = tmp.Sum(nil)
|
keyfileHash = tmp.Sum(nil)
|
||||||
|
@ -1308,11 +1341,7 @@ func work() {
|
||||||
mainStatus = "Incorrect keyfiles."
|
mainStatus = "Incorrect keyfiles."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mainStatusColor = RED
|
broken(fin, nil, mainStatus)
|
||||||
fin.Close()
|
|
||||||
if recombine {
|
|
||||||
os.Remove(inputFile)
|
|
||||||
}
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1338,7 +1367,7 @@ func work() {
|
||||||
done, counter := 0, 0
|
done, counter := 0, 0
|
||||||
chacha, _ := chacha20.NewUnauthenticatedCipher(key, nonce)
|
chacha, _ := chacha20.NewUnauthenticatedCipher(key, nonce)
|
||||||
|
|
||||||
// Use HKDF-SHA3 to generate a subkey
|
// Use HKDF-SHA3 to generate a subkey for the MAC
|
||||||
var mac hash.Hash
|
var mac hash.Hash
|
||||||
subkey := make([]byte, 32)
|
subkey := make([]byte, 32)
|
||||||
hkdf := hkdf.New(sha3.New256, key, hkdfSalt, nil)
|
hkdf := hkdf.New(sha3.New256, key, hkdfSalt, nil)
|
||||||
|
@ -1355,14 +1384,12 @@ func work() {
|
||||||
s, _ := serpent.NewCipher(serpentKey)
|
s, _ := serpent.NewCipher(serpentKey)
|
||||||
serpent := cipher.NewCTR(s, serpentSalt)
|
serpent := cipher.NewCTR(s, serpentSalt)
|
||||||
|
|
||||||
|
// Start the main encryption process
|
||||||
canCancel = true
|
canCancel = true
|
||||||
startTime := time.Now()
|
startTime := time.Now()
|
||||||
for {
|
for {
|
||||||
// If the user cancels the process, stop and clean up
|
|
||||||
if !working {
|
if !working {
|
||||||
cancel()
|
cancel(fin, fout)
|
||||||
fin.Close()
|
|
||||||
fout.Close()
|
|
||||||
if recombine || len(allFiles) > 1 || len(onlyFolders) > 0 || compress {
|
if recombine || len(allFiles) > 1 || len(onlyFolders) > 0 || compress {
|
||||||
os.Remove(inputFile)
|
os.Remove(inputFile)
|
||||||
}
|
}
|
||||||
|
@ -1490,11 +1517,10 @@ func work() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Write the data to output file
|
||||||
_, err = fout.Write(dst)
|
_, err = fout.Write(dst)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
insufficientSpace()
|
insufficientSpace(fin, fout)
|
||||||
fin.Close()
|
|
||||||
fout.Close()
|
|
||||||
if recombine || len(allFiles) > 1 || len(onlyFolders) > 0 || compress {
|
if recombine || len(allFiles) > 1 || len(onlyFolders) > 0 || compress {
|
||||||
os.Remove(inputFile)
|
os.Remove(inputFile)
|
||||||
}
|
}
|
||||||
|
@ -1520,7 +1546,7 @@ func work() {
|
||||||
}
|
}
|
||||||
giu.Update()
|
giu.Update()
|
||||||
|
|
||||||
// Change counters after 60 GiB to prevent overflow
|
// Change values after 60 GiB to prevent overflow
|
||||||
if counter >= 60*GiB {
|
if counter >= 60*GiB {
|
||||||
// ChaCha20
|
// ChaCha20
|
||||||
nonce = make([]byte, 24)
|
nonce = make([]byte, 24)
|
||||||
|
@ -1556,6 +1582,7 @@ func work() {
|
||||||
|
|
||||||
// Validate the authenticity of decrypted data
|
// Validate the authenticity of decrypted data
|
||||||
if subtle.ConstantTimeCompare(mac.Sum(nil), authTag) == 0 {
|
if subtle.ConstantTimeCompare(mac.Sum(nil), authTag) == 0 {
|
||||||
|
// Decrypt again but this time rebuilding the input data
|
||||||
if reedsolo && fastDecode {
|
if reedsolo && fastDecode {
|
||||||
fastDecode = false
|
fastDecode = false
|
||||||
fin.Close()
|
fin.Close()
|
||||||
|
@ -1563,6 +1590,7 @@ func work() {
|
||||||
work()
|
work()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if keep {
|
if keep {
|
||||||
kept = true
|
kept = true
|
||||||
} else {
|
} else {
|
||||||
|
@ -1603,6 +1631,7 @@ func work() {
|
||||||
giu.Update()
|
giu.Update()
|
||||||
fin, _ := os.Open(outputFile)
|
fin, _ := os.Open(outputFile)
|
||||||
|
|
||||||
|
// Start the splitting process
|
||||||
startTime := time.Now()
|
startTime := time.Now()
|
||||||
for i := 0; i < chunks; i++ {
|
for i := 0; i < chunks; i++ {
|
||||||
// Make the chunk
|
// Make the chunk
|
||||||
|
@ -1621,40 +1650,30 @@ func work() {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
if !working {
|
if !working {
|
||||||
cancel()
|
cancel(fin, fout)
|
||||||
fin.Close()
|
|
||||||
fout.Close()
|
|
||||||
if len(allFiles) > 1 || len(onlyFolders) > 0 || compress {
|
if len(allFiles) > 1 || len(onlyFolders) > 0 || compress {
|
||||||
os.Remove(inputFile)
|
os.Remove(inputFile)
|
||||||
}
|
}
|
||||||
os.Remove(outputFile)
|
os.Remove(outputFile)
|
||||||
|
for _, j := range splitted { // Remove unfinished chunks
|
||||||
// If user cancels, remove the unfinished files
|
|
||||||
for _, j := range splitted {
|
|
||||||
os.Remove(j)
|
os.Remove(j)
|
||||||
}
|
}
|
||||||
os.Remove(fmt.Sprintf("%s.%d", outputFile, i))
|
os.Remove(fmt.Sprintf("%s.%d", outputFile, i))
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
data = data[:read]
|
data = data[:read]
|
||||||
_, err = fout.Write(data)
|
_, err = fout.Write(data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
insufficientSpace()
|
insufficientSpace(fin, fout)
|
||||||
fin.Close()
|
|
||||||
fout.Close()
|
|
||||||
if len(allFiles) > 1 || len(onlyFolders) > 0 || compress {
|
if len(allFiles) > 1 || len(onlyFolders) > 0 || compress {
|
||||||
os.Remove(inputFile)
|
os.Remove(inputFile)
|
||||||
}
|
}
|
||||||
os.Remove(outputFile)
|
os.Remove(outputFile)
|
||||||
|
for _, j := range splitted { // Remove unfinished chunks
|
||||||
// If user cancels, remove the unfinished files
|
|
||||||
for _, j := range splitted {
|
|
||||||
os.Remove(j)
|
os.Remove(j)
|
||||||
}
|
}
|
||||||
os.Remove(fmt.Sprintf("%s.%d", outputFile, i))
|
os.Remove(fmt.Sprintf("%s.%d", outputFile, i))
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
done += read
|
done += read
|
||||||
|
@ -1694,7 +1713,7 @@ func work() {
|
||||||
os.Remove(inputFile)
|
os.Remove(inputFile)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete the temporary .zip used to encrypt files
|
// Delete the temporary .zip used to encrypt multiple files
|
||||||
if len(allFiles) > 1 || len(onlyFolders) > 0 || compress {
|
if len(allFiles) > 1 || len(onlyFolders) > 0 || compress {
|
||||||
os.Remove(inputFile)
|
os.Remove(inputFile)
|
||||||
}
|
}
|
||||||
|
@ -1705,7 +1724,7 @@ func work() {
|
||||||
giu.Update()
|
giu.Update()
|
||||||
|
|
||||||
if mode == "decrypt" {
|
if mode == "decrypt" {
|
||||||
if recombine { // Remove each chunk
|
if recombine { // Remove each chunk of volume
|
||||||
i := 0
|
i := 0
|
||||||
for {
|
for {
|
||||||
_, err := os.Stat(fmt.Sprintf("%s.%d", inputFileOld, i))
|
_, err := os.Stat(fmt.Sprintf("%s.%d", inputFileOld, i))
|
||||||
|
@ -1750,7 +1769,9 @@ func accessDenied(s string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// If there isn't enough disk space
|
// If there isn't enough disk space
|
||||||
func insufficientSpace() {
|
func insufficientSpace(fin *os.File, fout *os.File) {
|
||||||
|
fin.Close()
|
||||||
|
fout.Close()
|
||||||
mainStatus = "Insufficient disk space."
|
mainStatus = "Insufficient disk space."
|
||||||
mainStatusColor = RED
|
mainStatusColor = RED
|
||||||
}
|
}
|
||||||
|
@ -1769,8 +1790,10 @@ func broken(fin *os.File, fout *os.File, message string) {
|
||||||
os.Remove(outputFile)
|
os.Remove(outputFile)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stop working
|
// Stop working if user hits "Cancel"
|
||||||
func cancel() {
|
func cancel(fin *os.File, fout *os.File) {
|
||||||
|
fin.Close()
|
||||||
|
fout.Close()
|
||||||
mainStatus = "Operation cancelled by user."
|
mainStatus = "Operation cancelled by user."
|
||||||
mainStatusColor = WHITE
|
mainStatusColor = WHITE
|
||||||
}
|
}
|
||||||
|
@ -1860,6 +1883,8 @@ func rsDecode(rs *infectious.FEC, data []byte) ([]byte, error) {
|
||||||
}
|
}
|
||||||
return data[:rs.Total()/3], err
|
return data[:rs.Total()/3], err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// No issues, return the decoded data
|
||||||
return res, nil
|
return res, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue