commit fff4be4daece60c4ca5581bfea39f6af27db9f43 Author: Akshay Pushparaj Date: Fri Aug 15 06:02:54 2025 +0530 DoubleSync first commit diff --git a/README.md b/README.md new file mode 100644 index 0000000..af2cd86 --- /dev/null +++ b/README.md @@ -0,0 +1,6 @@ +# DoubleSync +Your files are always in sync, just like the Party’s truth + +# Usage +go mod tidy +go run ./doublesync.go diff --git a/doublesync.go b/doublesync.go new file mode 100644 index 0000000..bd4f04d --- /dev/null +++ b/doublesync.go @@ -0,0 +1,126 @@ +package main + +import ( + "log" + "os" + "path/filepath" + "github.com/fsnotify/fsnotify" + "regexp" + "slices" + "io/ioutil" + "strings" +) + +func main() { + // Create new watcher. + watcher, err := fsnotify.NewWatcher() + if err != nil { + log.Fatal(err) + } + defer watcher.Close() + + // Start listening for events. + go func() { + for { + select { + case event, ok := <-watcher.Events: + if !ok { + return + } + + archive_basedir := "/tmp/newmails/" + var mailbox string + var dovecot_uidlist_src string + var dovecot_indexlog_src string + var dovecot_indexcache_src string + var dovecot_dest string + + if event.Has(fsnotify.Create) { + + re := regexp.MustCompile(`^.*\.archival\.Incoming\/new\/.*$`) + new_mail := re.FindString(event.Name) + last_mail := regexp.MustCompile(`/`).Split(new_mail, -1) + username_index := slices.Index(last_mail, "home") + username := last_mail[username_index+1] + archive_mailbox := archive_basedir + username + ".Incoming/new/" + archive_err := ensureDir(archive_mailbox) + new_loc := archive_mailbox + last_mail[len(last_mail)-1] + + // Get archive mailbox path + mailbox_index := username_index+4 + if len(last_mail) > 1 { + mailbox = strings.Join(last_mail[0:mailbox_index], "/") + dovecot_uidlist_src = mailbox + "/dovecot-uidlist" + dovecot_indexlog_src = mailbox + "/dovecot.index.log" + dovecot_indexcache_src = mailbox + "/dovecot.index.cache" + dovecot_dest = archive_basedir + last_mail[mailbox_index] + log.Println(mailbox) + } + //log.Println(len(last_mail)) + log.Println("dovecot") + log.Println(dovecot_dest) + log.Println(dovecot_uidlist_src) + log.Println(dovecot_indexlog_src) + log.Println(dovecot_indexcache_src) + if archive_err != nil { + log.Fatal(archive_err) + } + if len(new_mail) > 0 { + log.Println("moving user ",username,"files to ", new_loc) + err := os.Rename(new_mail, new_loc) + if err != nil { + panic(err) + } + //uidlist_err := copyFiles(dovecot_uidlist_src, dovecot_dest) + //log_err := copyFiles(dovecot_indexlog_src, dovecot_dest) + //cache_err := copyFiles(dovecot_indexcache_src, dovecot_dest) + //if uidlist_err != nil || log_err != nil || cache_err != nil { + // panic(err) + //} + } + } + + + case err, ok := <-watcher.Errors: + if !ok { + return + } + log.Println("error:", err) + } + } + }() + + // Add a path. + filepath.Walk("/home/", func(path string, info os.FileInfo, err error) error{ + if info.IsDir() { + watcher.Add(path) + } + return nil + }) + // Block main goroutine forever. + <-make(chan struct{}) +} + +// Create archive directory +func ensureDir(dirName string) error { + err := os.MkdirAll(dirName, 0755) + if err == nil || os.IsExist(err) { + return nil + } else { + return err + } +} + +// Copy dovecot index and cache +func copyFiles(src string, dest string) error { + bytesRead, err := ioutil.ReadFile(src) + if err != nil { + log.Fatal(err) + } + err = ioutil.WriteFile(dest, bytesRead, 0644) + if err == nil { + return nil + } else { + return err + } +} diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..608ec6a --- /dev/null +++ b/go.mod @@ -0,0 +1,8 @@ +module deepOfix/letter_sync + +go 1.22.5 + +require ( + github.com/fsnotify/fsnotify v1.7.0 // indirect + golang.org/x/sys v0.4.0 // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..ccd7ce9 --- /dev/null +++ b/go.sum @@ -0,0 +1,4 @@ +github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= +github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= +golang.org/x/sys v0.4.0 h1:Zr2JFtRQNX3BCZ8YtxRE9hNJYC8J6I1MVbMg6owUp18= +golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=