func (fs *FileSession) pullHandler(incomingPacket packet.PacketStd) { if incomingPacket.Name == "REQ_FILELIST" { //db initializing db, error := sql.Open("sqlite3", "../gypo.db") //tells client pull request recieved newPacket := packet.PacketStd{packet.Packet{"pull", "REQ_FILELIST_RECV"}, ""} go newPacket.SendPacket(fs.Connection) //creates list of server files and sends back to client if error != nil { fmt.Println(error.Error()) } else { //PacketList instance for server files(db) var server_fileList packet.PacketList //get number of files from db to use for file server_fileList.Data size var dbFileCount int error = db.QueryRow("SELECT count(*) AS number FROM files WHERE user_id = ?", fs.User.Id).Scan(&dbFileCount) if error != nil { fmt.Println(error.Error()) } else { //sets PacketList instance variables server_fileList.Data = make([]packet.PacketStd, dbFileCount) server_fileList.ContentType = "pull" server_fileList.Name = "RESP_FILELIST" //get fileList from db rows, error := db.Query("SELECT filename, path, hash, is_dir FROM files WHERE user_id = ?", fs.User.Id) if error != nil { fmt.Println(error.Error()) } else { var rowPacket packet.PacketStd var filename, path, hash string var is_dir int i := 0 for rows.Next() { error = rows.Scan(&filename, &path, &hash, &is_dir) if error != nil { fmt.Println(error.Error()) } else { if is_dir == 1 { rowPacket.ContentType = "folder" rowPacket.Name = path rowPacket.Data = "" } else { rowPacket.ContentType = "hash" rowPacket.Name = path + filename rowPacket.Data = hash } } server_fileList.Data[i] = rowPacket i++ } go server_fileList.SendPacket(fs.Connection) fmt.Println("server_fileList size: ", len(server_fileList.Data)) } } } } else if incomingPacket.Name == "REQ_FILE" { //wraps file in packet and sends it newPacket := packet.PacketStd{packet.Packet{"pull", "RESP_FILE"}, incomingPacket.Data} go newPacket.SendFilePacket(fs.Connection) } }
func (fs *FileSession) pushHandler(incomingPacket packet.PacketStd) { fmt.Println("processing push") //getting pushList from socket incomingBytes, _ := strconv.Atoi(incomingPacket.Data) pushListB := make([]byte, incomingBytes) i := 0 for i < incomingBytes { chunkSize, _ := fs.Connection.Read(pushListB[i:]) i = i + chunkSize fmt.Println("read so far: ", i) } //unmarshal data from socket to PacketList instance var client_pushList packet.PacketList client_pushList.ContentType = "push" client_pushList.Name = "client" flsize, _ := strconv.Atoi(incomingPacket.Name) flObj := make([]packet.PacketStd, flsize) client_pushList.Data = flObj error := json.Unmarshal(pushListB, &client_pushList) if error == nil { fmt.Println("push recieved, " + incomingPacket.Name + " entries\n") } else { fmt.Println(error.Error()) } //tells client push was recieved newPacket := packet.PacketStd{packet.Packet{"push", ""}, "PUSH_RECIEVED"} go newPacket.SendPacket(fs.Connection) //PacketList instance for server files(db) var server_fileList packet.PacketList db, error := sql.Open("sqlite3", "../gypo.db") if error != nil { fmt.Println(error.Error()) } else { //get number of files from db to use for file array size var dbFileCount int error = db.QueryRow("SELECT count(*) AS number FROM files WHERE user_id = ?", fs.User.Id).Scan(&dbFileCount) if error != nil { fmt.Println(error.Error()) } else { server_fileList.Data = make([]packet.PacketStd, dbFileCount) //fetches files from db and adds them to server_fileList rows, error := db.Query("SELECT filename, path, hash, is_dir FROM files WHERE user_id = ?", fs.User.Id) if error != nil { fmt.Println(error.Error()) } else { var is_dir int var rowContentType, rowName, rowData string var rowPacket packet.PacketStd //populates server_fileList.Data i = 0 for rows.Next() { error = rows.Scan(&rowContentType, &rowName, &rowData, &is_dir) //fmt.Println(i, " | ", is_dir) if error != nil { fmt.Println(error.Error()) } if is_dir == 1 { rowPacket.ContentType = "folder" rowPacket.Name = rowName rowPacket.Data = "" } else { rowPacket.ContentType = "hash" rowPacket.Name = rowName + rowContentType rowPacket.Data = rowData } server_fileList.Data[i] = rowPacket i++ } fmt.Println("server_fileList size: ", len(server_fileList.Data)) fmt.Println("client_pushList size: ", len(client_pushList.Data)) /* i = 0 for i < len(server_fileList.Data) { fmt.Println("ContentType: " + server_fileList.Data[i].ContentType + " | Name: " + server_fileList.Data[i].Name + " | Data: " + server_fileList.Data[i].Data) i++ } fmt.Println("\n\n\n\n") i = 0 for i < len(client_pushList.Data) { fmt.Println("ContentType: " + client_pushList.Data[i].ContentType + " | Name: " + client_pushList.Data[i].Name + " | Data: " + server_fileList.Data[i].Data) i++ }*/ //compares client_pushList to server_fileList nilPacket := packet.PacketStd{packet.Packet{"", ""}, ""} //to flag list entries as solved i = 0 j := 0 for i < len(client_pushList.Data) { //check if i is allready solved if len(client_pushList.Data[i].ContentType) > 0 { for j < len(server_fileList.Data) { //file if client_pushList.Data[i].ContentType == "hash" { //match if client_pushList.Data[i].Name == server_fileList.Data[j].Name { //update file if needed if client_pushList.Data[i].Data != server_fileList.Data[j].Data { client_pushList.Data[i].Data = "1" + client_pushList.Data[i].Data //adds '1' to indicate UPDATE(existing file) fs.tempHash[client_pushList.Data[i].Name] = client_pushList.Data[i] fmt.Println("hash for: " + client_pushList.Data[i].Name + " added to tempHash") //fmt.Println("path and filename the same, different hash | client: " + client_pushList.Data[i].Data + " server: " + server_fileList.Data[j].Data) newPacket := packet.PacketStd{packet.Packet{"hash", client_pushList.Data[i].Name}, "SEND_FILE_TRUE"} go newPacket.SendPacket(fs.Connection) fmt.Println(client_pushList.Data[i].Name + " exist, different hash, send\n") //flag list entries as solved client_pushList.Data[i] = nilPacket server_fileList.Data[j] = nilPacket } else { //files are identical, flag list entries as solved client_pushList.Data[i] = nilPacket server_fileList.Data[j] = nilPacket } } //path } else if client_pushList.Data[i].ContentType == "folder" { //match if client_pushList.Data[i].Name == server_fileList.Data[j].Name { //if both paths exist on server and client, flag list entries as solved client_pushList.Data[i] = nilPacket server_fileList.Data[j] = nilPacket } } j++ //increase server_fileList index } } j = 0 //resets server_fileList index i++ //increase client_pushList index } //client_pushList entries not flagged as handled are treated as new files and folders and will be downloaded an/or created i = 0 for i < len(client_pushList.Data) { if client_pushList.Data[i].ContentType == "hash" { //file //adds hash to tempHash, if file recieve is successful; tempHash is dumped to db client_pushList.Data[i].Data = "0" + client_pushList.Data[i].Data //adds '0' to indicate INSERT(new file) fs.tempHash[client_pushList.Data[i].Name] = client_pushList.Data[i] fmt.Println("hash for: " + client_pushList.Data[i].Name + " added to tempHash") newPacket := packet.PacketStd{packet.Packet{"hash", client_pushList.Data[i].Name}, "SEND_FILE_TRUE"} go newPacket.SendPacket(fs.Connection) fmt.Println(client_pushList.Data[i].Name + " not exist, send\n") //flag list entry as solved client_pushList.Data[i] = nilPacket } else if client_pushList.Data[i].ContentType == "folder" { //folder error = os.MkdirAll(client_pushList.Data[i].Name[1:], 07777) //liberal chmod if error != nil { fmt.Println(error.Error()) //adds folder to db } else { _, error := db.Exec("INSERT INTO files (path, is_dir, user_id) VALUES (?, ?, ?)", client_pushList.Data[i].Name, 1, fs.User.Id) if error != nil { fmt.Println(error.Error()) } else { fmt.Println("folder: " + client_pushList.Data[i].Name + " created and added to db") } } } i++ } fmt.Println("tempHash size: ", len(fs.tempHash)) //server_fileList entries not flagged as handled are threated as deleted files and gets deleted i = 0 for i < len(server_fileList.Data) { if server_fileList.Data[i].ContentType == "hash" { //file //delete db entry _, error := db.Exec("DELETE FROM files WHERE path = ? AND hash = ? AND user_id = ?", server_fileList.Data[i].Name[:strings.LastIndex(server_fileList.Data[i].Name, "/")+1], server_fileList.Data[i].Data, fs.User.Id) if error != nil { fmt.Println(error.Error()) } else { //delete file _ = os.RemoveAll(fs.RootDir + server_fileList.Data[i].Name) /*if error != nil { fmt.Println(error.Error()) }*/ } //flag list entry as solved server_fileList.Data[i] = nilPacket } else if server_fileList.Data[i].ContentType == "folder" { //delete db entry _, error := db.Exec("DELETE FROM files WHERE path = ? AND is_dir = ? AND user_id = ?", server_fileList.Data[i].Name, 1, fs.User.Id) if error != nil { fmt.Println(error.Error()) } else { //delete folder _ = os.RemoveAll(fs.RootDir + server_fileList.Data[i].Name) /*if error != nil { fmt.Println(error.Error()) }*/ } //flag list entry as solved server_fileList.Data[i] = nilPacket } i++ } } } } }