github.com/dnutiu/simplFT@v0.0.0-20181023061248-df4b14cdce57/server/commands.go (about) 1 package server 2 3 import ( 4 "bytes" 5 "io" 6 "io/ioutil" 7 "log" 8 "math/rand" 9 "os" 10 "strconv" 11 "strings" 12 13 "github.com/spf13/viper" 14 "github.com/zyxar/image2ascii/ascii" 15 ) 16 17 func randSeq(n int) string { 18 var letters = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ") 19 b := make([]rune, n) 20 for i := range b { 21 b[i] = letters[rand.Intn(len(letters))] 22 } 23 return string(b) 24 } 25 26 // UploadFile uploads a file to the server 27 func UploadFile(c Client, filename string) error { 28 f, err := os.Create(MakePathFromStringStack(c.Stack()) + filename) 29 if err != nil { 30 return err 31 } 32 defer f.Close() 33 34 io.Copy(f, c.Connection()) 35 36 return nil 37 } 38 39 // SendASCIIPic sends an image as ascii text to the client. 40 func SendASCIIPic(c Client, path string) error { 41 f, err := os.Open(MakePathFromStringStack(c.Stack()) + path) 42 if err != nil { 43 log.Println(err) 44 return err 45 } 46 defer f.Close() 47 opt := ascii.Options{ 48 Width: viper.GetInt("pic.x"), 49 Height: viper.GetInt("pic.y"), 50 Color: viper.GetBool("pic.color"), 51 Invert: false, 52 Flipx: false, 53 Flipy: false} 54 55 a, err := ascii.Decode(f, opt) 56 if err != nil { 57 log.Println(err) 58 return err 59 } 60 _, err = a.WriteTo(c.Connection()) 61 return err 62 } 63 64 // GetFile sends the file to the client and returns true if it succeeds and false otherwise. 65 // it also returns the total number of send bytes. 66 func GetFile(c Client, path string) (int64, error) { 67 fileName, sanitized := sanitizeFilePath(path) 68 if sanitized { 69 return 0, ErrSlashNotAllowed 70 } 71 72 file, err := os.Open(MakePathFromStringStack(c.Stack()) + fileName) 73 if err != nil { 74 log.Println(err.Error()) 75 return 0, err 76 } 77 defer file.Close() 78 79 totalSend, err := io.Copy(c.Connection(), file) 80 81 return totalSend, err 82 } 83 84 func sanitizeFilePath(path string) (string, bool) { 85 var fileName string 86 var sanitized bool 87 // Make sure the user can't request any files on the system. 88 lastForwardSlash := strings.LastIndex(path, "/") 89 if lastForwardSlash != -1 { 90 // Eliminate the last forward slash i.e ../../asdas will become asdas 91 fileName = path[lastForwardSlash+1:] 92 sanitized = true 93 } else { 94 fileName = path 95 sanitized = false 96 } 97 return fileName, sanitized 98 } 99 100 // ListFiles list the files from path and sends them to the connection 101 func ListFiles(c Client) error { 102 103 files, err := ioutil.ReadDir(MakePathFromStringStack(c.Stack())) 104 if err != nil { 105 return err 106 } 107 108 buffer := bytes.NewBufferString("Directory Mode Size LastModified Name\n") 109 for _, f := range files { 110 buffer.WriteString(strconv.FormatBool(f.IsDir()) + " " + string(f.Mode().String()) + " " + 111 strconv.FormatInt(f.Size(), 10) + " " + f.ModTime().String() + " " + string(f.Name()) + " " + "\n") 112 } 113 114 _, err = c.Connection().Write(buffer.Bytes()) 115 return err 116 } 117 118 // ClearScreen cleans the client's screen by sending clear to the terminal. 119 func ClearScreen(c Client) error { 120 // Ansi clear: 1b 5b 48 1b 5b 4a 121 // clear | hexdump -C 122 var b = []byte{0x1b, 0x5b, 0x48, 0x1b, 0x5b, 0x4a} 123 _, err := c.Connection().Write(b) 124 125 return err 126 } 127 128 // ChangeDirectoryCommand changes the directory to the given directory 129 func ChangeDirectoryCommand(c Client, directory string) error { 130 var err error 131 path, sanitized := sanitizeFilePath(directory) 132 if sanitized { 133 return ErrSlashNotAllowed 134 } 135 136 if path == "." { 137 err = nil 138 } else if path == ".." { 139 err = ChangeDirectoryToPrevious(c.Stack()) 140 } else { 141 err = ChangeDirectory(c.Stack(), path) 142 } 143 144 return err 145 } 146 147 // ShowHelp writes the help text to the client. 148 func ShowHelp(c Client) error { 149 var helpText = ` 150 The available commands are: 151 get <filename> - Download the requested filename. 152 ls - List the files in the current directory. 153 cd - Changes the directory. 154 clear - Clear the screen. 155 exit - Close the connection with the server.c 156 pic - Returns the ascii art of an image. :-) 157 ` 158 _, err := c.Connection().Write([]byte(helpText)) 159 160 return err 161 }