Пример #1
0
// checks request code and calls corresponding function
func (st StorageNode) handleCode(uuid uint64, code uint8, conn net.Conn, r *bufio.Reader, w *bufio.Writer) {

	switch code {
	case 1: // client is requesting a file
		hash := utils.ReadHashAsString(r)
		fmt.Println("Hash received: " + hash)

		// check if file exists
		var sendcode uint8
		fp := st.getPath() + "files/" + hash
		if _, err := os.Stat(fp); err == nil {
			fmt.Println("File with hash " + hash + " exists")
			sendcode = 3                 // file available code
			err := w.WriteByte(sendcode) // let client know
			if err != nil {
				panic(err)
			}
			w.Flush()

			// send the file
			fmt.Println("Sending file " + hash)
			utils.SendFile(conn, w, fp)
		} else {
			fmt.Println("File with hash " + hash + " does not exist")
			sendcode = 4
			err := w.WriteByte(sendcode) // let client know
			if err != nil {
				panic(err)
			}
			w.Flush()
		}

	case 2: // receive file from client
		fmt.Println("Receiving file")

		hash := utils.ReadHashAsString(r)
		output := st.getPath() + "files/" + hash
		utils.ReceiveFile(conn, r, output)

		fmt.Println("File received; md5 checksum of file is: " + hash)
	}
	fmt.Println()
	conn.Close()
}
Пример #2
0
func send(r *bufio.Reader, w *bufio.Writer, currentDir string, args []string, thisUser *utils.User) (err error) {

	if len(args) < 2 {
		return err
	}

	// Format the file to send (absolute or relative)
	filepath := ""
	if path.IsAbs(args[1]) { // if we are trying to send an absolute filepath

		filepath = args[1]

	} else { // we must be sending a relative filepath, so calculate the path

		wd, err := os.Getwd()
		if err != nil {
			return err
		}
		filepath = path.Join(wd, args[1])
	}

	// ensure the file is existant locally
	src, err := os.Stat(filepath)
	if err != nil {

		fmt.Println("\"" + filepath + "\" does not exist")
		return nil

	} else if src.IsDir() {

		fmt.Println("\"" + filepath + "\" is a directory, not a file")
		return nil

	} else {

		fmt.Println("Sending: \"" + filepath + "\"")

	}

	// START SENDCODE BLOCK - tell mdserv we are sending a file
	err = w.WriteByte(6)
	w.Flush()
	if err != nil {
		panic(err)
	}
	// END SENDCODE BLOCK

	// Send current dir
	w.WriteString(currentDir + "\n")
	// Send filename to mdserv
	w.WriteString(path.Base(filepath) + "\n")

	w.Flush()

	// Get fail if file exists already
	exists, _ := r.ReadByte()
	if exists == 1 {

		fmt.Println("Bad send request, check file name again")
		return nil
	} else if exists == 3 {

		fmt.Println("Permission denied")
		return nil
	} else if exists != 2 {

		fmt.Println("Bad reponse from metadata service")
		return nil
	}

	// Encryption or not?
	if len(args) >= 3 {
		if args[2] != "--protect" && args[2] != "-p" {
			fmt.Println("Invalid argument option: \"" + args[2] + "\"")
			w.WriteByte(2)
			w.Flush()
			return nil
		}

		w.WriteByte(1) // tell mdserv we are encrypting
		w.Flush()

		users := []utils.User{*thisUser}

		// send len of args
		w.WriteByte(uint8(len(args) - 3))
		w.Flush()

		for i := 3; i < len(args); i++ {

			w.WriteString(args[i] + "\n")
			w.Flush()

			uuid, _ := r.ReadString('\n')
			uuid = strings.TrimSpace(uuid)

			if uuid != "INV" {

				var newUser utils.User

				newUser.Uuid, _ = strconv.ParseUint(uuid, 10, 64)

				// receive the public key for the new user

				pubKN, _ := r.ReadString('\n')
				pubKE, _ := r.ReadString('\n')

				newUser.Pubkey = &rsa.PublicKey{N: big.NewInt(0)}
				newUser.Pubkey.N.SetString(strings.TrimSpace(pubKN), 10)
				newUser.Pubkey.E, err = strconv.Atoi(strings.TrimSpace(pubKE))

				users = append(users, newUser)
			}
		}

		encrypFile := os.TempDir() + "/" + path.Base(filepath)

		err = utils.EncryptFile(filepath, encrypFile, users...)
		if err != nil {
			return err
		}

		filepath = encrypFile
		fmt.Println("File successfully protected")

	} else {

		w.WriteByte(3) // normal continue
		w.Flush()
	}

	// get hash of the file to send to the stnode and mdserv
	hash, err := utils.ComputeMd5(filepath)
	if err != nil {
		panic(err)
	}

	//checksum := hex.EncodeToString(hash)

	// Send hash to mdserv
	err = utils.WriteHash(w, hash)
	if err != nil {
		return err
	}

	// See are there stnodes available
	avail, _ := r.ReadByte()

	var conns net.Conn

	for avail != 2 {

		// Get details of a storage node if file not exists
		protocol, _ := r.ReadString('\n')
		nAddress, _ := r.ReadString('\n')

		protocol = strings.TrimSpace(protocol)
		nAddress = strings.TrimSpace(nAddress)

		// connect to stnode
		conns, err = net.Dial(protocol, nAddress)
		if err != nil {

			w.WriteByte(1)
			w.Flush()

		} else { // successful connection

			avail = 3
			w.WriteByte(2)
			w.Flush()
			break
		}

		avail, _ = r.ReadByte()
	}

	if avail != 3 {
		fmt.Println("There were no stnodes available")
		return nil
	}

	defer conns.Close()

	// create a read and write buffer for the connection
	ws := bufio.NewWriter(conns)

	// tell the stnode we are sending a file
	err = ws.WriteByte(2)
	if err != nil {
		return err
	}

	// send hash to stnode
	err = utils.WriteHash(ws, hash)
	if err != nil {
		return err
	}

	// send file to stnode
	utils.SendFile(conns, ws, filepath)

	// Send success/fail to mdserv to log the file send or not
	w.WriteByte(1)
	w.Flush()

	fmt.Println("Successfully sent file")
	// on failure to send a file, print err
	return err
}