simplFT/server/server/commands.go

177 lines
4 KiB
Go
Raw Normal View History

2017-10-20 15:08:25 +00:00
package server
import (
2017-10-28 20:40:24 +00:00
"bytes"
"io"
2017-10-28 20:40:24 +00:00
"io/ioutil"
"log"
2017-11-26 21:03:15 +00:00
"math/rand"
2017-10-20 15:08:25 +00:00
"os"
"strconv"
2017-10-28 20:40:24 +00:00
"strings"
2017-11-24 20:16:06 +00:00
2017-11-24 20:50:23 +00:00
"github.com/spf13/viper"
"github.com/zyxar/image2ascii/ascii"
2017-10-20 15:08:25 +00:00
)
2017-11-26 21:03:15 +00:00
func randSeq(n int) string {
var letters = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
b := make([]rune, n)
for i := range b {
b[i] = letters[rand.Intn(len(letters))]
}
return string(b)
}
// UploadFile uploads a file to the server
func UploadFile(c Client, filename string) error {
2017-11-26 21:03:15 +00:00
f, err := os.Create(MakePathFromStringStack(c.Stack()) + filename)
if err != nil {
return err
2017-11-26 21:03:15 +00:00
}
defer f.Close()
io.Copy(f, c.Connection())
2017-11-26 21:03:15 +00:00
return nil
2017-11-26 21:03:15 +00:00
}
2017-12-16 20:46:55 +00:00
// SendASCIIPic sends an image as ascii text to the client.
func SendASCIIPic(c Client, path string) error {
2017-11-24 20:16:06 +00:00
f, err := os.Open(MakePathFromStringStack(c.Stack()) + path)
if err != nil {
log.Println(err)
return err
}
defer f.Close()
opt := ascii.Options{
2017-11-24 20:50:23 +00:00
Width: viper.GetInt("pic.x"),
Height: viper.GetInt("pic.y"),
Color: viper.GetBool("pic.color"),
Invert: false,
Flipx: false,
Flipy: false}
a, err := ascii.Decode(f, opt)
2017-11-24 20:16:06 +00:00
if err != nil {
log.Println(err)
return err
}
_, err = a.WriteTo(c.Connection())
2017-11-24 20:16:06 +00:00
return err
}
2017-10-20 15:34:16 +00:00
// GetFile sends the file to the client and returns true if it succeeds and false otherwise.
// it also returns the total number of send bytes.
2017-11-08 20:18:23 +00:00
func GetFile(c Client, path string) (int, error) {
2017-11-09 20:39:58 +00:00
fileName, sanitized := sanitizeFilePath(path)
if sanitized {
return 0, ErrSlashNotAllowed
}
2017-10-20 15:08:25 +00:00
file, err := os.Open(MakePathFromStringStack(c.Stack()) + fileName)
2017-10-20 15:08:25 +00:00
if err != nil {
log.Println(err.Error())
2017-10-20 15:08:25 +00:00
return 0, err
}
2017-10-28 20:36:57 +00:00
defer file.Close()
var data = make([]byte, DataBufferSize, DataBufferSize)
totalSend := 0
for {
n, err := file.Read(data)
if err == io.EOF {
break
} else if err != nil {
return totalSend, err
}
totalSend += n
_, err = c.Connection().Write(data)
if err != nil {
2017-11-24 20:16:06 +00:00
break
}
2017-10-20 15:08:25 +00:00
}
return totalSend, nil
2017-10-28 20:36:57 +00:00
}
2017-11-09 20:39:58 +00:00
func sanitizeFilePath(path string) (string, bool) {
2017-10-28 20:36:57 +00:00
var fileName string
2017-11-09 20:39:58 +00:00
var sanitized bool
2017-10-28 20:36:57 +00:00
// Make sure the user can't request any files on the system.
lastForwardSlash := strings.LastIndex(path, "/")
if lastForwardSlash != -1 {
// Eliminate the last forward slash i.e ../../asdas will become asdas
fileName = path[lastForwardSlash+1:]
2017-11-09 20:39:58 +00:00
sanitized = true
2017-10-28 20:36:57 +00:00
} else {
fileName = path
2017-11-09 20:39:58 +00:00
sanitized = false
2017-10-28 20:36:57 +00:00
}
2017-11-09 20:39:58 +00:00
return fileName, sanitized
2017-10-28 20:36:57 +00:00
}
2017-10-20 15:08:25 +00:00
// ListFiles list the files from path and sends them to the connection
2017-11-08 20:18:23 +00:00
func ListFiles(c Client) error {
files, err := ioutil.ReadDir(MakePathFromStringStack(c.Stack()))
2017-10-20 15:08:25 +00:00
if err != nil {
2017-10-28 20:36:57 +00:00
return err
2017-10-20 15:08:25 +00:00
}
buffer := bytes.NewBufferString("Directory Mode Size LastModified Name\n")
for _, f := range files {
buffer.WriteString(strconv.FormatBool(f.IsDir()) + " " + string(f.Mode().String()) + " " +
strconv.FormatInt(f.Size(), 10) + " " + f.ModTime().String() + " " + string(f.Name()) + " " + "\n")
}
2017-11-08 20:18:23 +00:00
_, err = c.Connection().Write(buffer.Bytes())
2017-11-24 20:16:06 +00:00
return err
2017-10-20 15:08:25 +00:00
}
2017-10-20 15:20:11 +00:00
2017-11-09 20:39:58 +00:00
// ClearScreen cleans the client's screen by sending clear to the terminal.
func ClearScreen(c Client) error {
// Ansi clear: 1b 5b 48 1b 5b 4a
// clear | hexdump -C
var b = []byte{0x1b, 0x5b, 0x48, 0x1b, 0x5b, 0x4a}
_, err := c.Connection().Write(b)
return err
}
// ChangeDirectoryCommand changes the directory to the given directory
func ChangeDirectoryCommand(c Client, directory string) error {
var err error
path, sanitized := sanitizeFilePath(directory)
if sanitized {
return ErrSlashNotAllowed
}
2017-11-09 21:03:31 +00:00
if path == "." {
err = nil
} else if path == ".." {
err = ChangeDirectoryToPrevious(c.Stack())
2017-11-09 20:39:58 +00:00
} else {
err = ChangeDirectory(c.Stack(), path)
2017-11-09 20:39:58 +00:00
}
return err
}
2017-12-16 20:46:55 +00:00
// ShowHelp writes the help text to the client.
2017-11-08 20:18:23 +00:00
func ShowHelp(c Client) error {
2017-10-29 13:01:45 +00:00
var helpText = `
2017-10-20 15:20:11 +00:00
The available commands are:
get <filename> - Download the requested filename.
2017-11-09 20:39:58 +00:00
ls - List the files in the current directory.
cd - Changes the directory.
clear - Clear the screen.
exit - Close the connection with the server.c
2017-11-24 20:16:06 +00:00
pic - Returns the ascii art of an image. :-)
2017-10-20 15:20:11 +00:00
`
2017-11-08 20:18:23 +00:00
_, err := c.Connection().Write([]byte(helpText))
2017-10-20 15:20:11 +00:00
return err
}