func processLocalEvent_Upper(globals *AsinkGlobals, event *asink.Event, latestLocal *asink.Event, absolutePath string) error { if latestLocal != nil { event.Predecessor = latestLocal.Hash if event.Timestamp < latestLocal.Timestamp { fmt.Printf("trying to send event older than latestLocal:\n") fmt.Printf("OLD %+v\n", latestLocal) fmt.Printf("NEW %+v\n", event) } } if event.IsUpdate() { //copy to tmp //TODO upload in chunks and check modification times to make sure it hasn't been changed instead of copying the whole thing off tmpfilename, err := util.CopyToTmp(absolutePath, globals.tmpDir) if err != nil { //bail out if the file we are trying to upload already got deleted if util.ErrorFileNotFound(err) { event.LocalStatus |= asink.DISCARDED return nil } return err } //try to collect the file's permissions fileinfo, err := os.Stat(absolutePath) if err != nil { //bail out if the file we are trying to upload already got deleted if util.ErrorFileNotFound(err) { event.LocalStatus |= asink.DISCARDED return nil } return ProcessingError{PERMANENT, err} } else { event.Permissions = fileinfo.Mode() } //get the file's hash hash, err := HashFile(tmpfilename) if err != nil { return ProcessingError{TEMPORARY, err} } event.Hash = hash //If the hash is the same, don't try to upload the event again if latestLocal != nil && event.Hash == latestLocal.Hash { os.Remove(tmpfilename) //If neither the file contents nor permissions changed, squash this event completely if event.Permissions == latestLocal.Permissions { event.LocalStatus |= asink.DISCARDED return nil } } else { //rename to local cache w/ filename=hash cachedFilename := path.Join(globals.cacheDir, event.Hash) err = os.Rename(tmpfilename, cachedFilename) if err != nil { err = os.Remove(tmpfilename) if err != nil { return ProcessingError{PERMANENT, err} } return ProcessingError{PERMANENT, err} } } } else { //if we're trying to delete a file that we thought was already deleted, there's no need to delete it again if latestLocal != nil && latestLocal.IsDelete() { event.LocalStatus |= asink.DISCARDED return nil } } return nil }