// Copyright (c) 2023 Proton AG // // This file is part of Proton Mail Bridge. // // Proton Mail Bridge is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Proton Mail Bridge is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with Proton Mail Bridge. If not, see . package bridge import ( "fmt" "io" "os" "path/filepath" ) func moveDir(from, to string) error { entries, err := os.ReadDir(from) if err != nil { return err } for _, entry := range entries { if entry.IsDir() { if err := os.Mkdir(filepath.Join(to, entry.Name()), 0o700); err != nil { return err } if err := moveDir(filepath.Join(from, entry.Name()), filepath.Join(to, entry.Name())); err != nil { return err } if err := os.RemoveAll(filepath.Join(from, entry.Name())); err != nil { return err } } else { if err := moveFile(filepath.Join(from, entry.Name()), filepath.Join(to, entry.Name())); err != nil { return err } } } return os.Remove(from) } func moveFile(from, to string) error { if err := os.MkdirAll(filepath.Dir(to), 0o700); err != nil { return err } if err := os.Rename(from, to); err != nil { return err } return nil } func copyDir(from, to string) error { entries, err := os.ReadDir(from) if err != nil { return err } if err := createIfNotExists(to, 0o700); err != nil { return err } for _, entry := range entries { sourcePath := filepath.Join(from, entry.Name()) destPath := filepath.Join(to, entry.Name()) if entry.IsDir() { if err := copyDir(sourcePath, destPath); err != nil { return err } } else { if err := copyFile(sourcePath, destPath); err != nil { return err } } } return nil } func copyFile(srcFile, dstFile string) error { out, err := os.Create(filepath.Clean(dstFile)) defer func(out *os.File) { _ = out.Close() }(out) if err != nil { return err } in, err := os.Open(filepath.Clean(srcFile)) defer func(in *os.File) { _ = in.Close() }(in) if err != nil { return err } _, err = io.Copy(out, in) if err != nil { return err } return nil } func exists(filePath string) bool { if _, err := os.Stat(filePath); os.IsNotExist(err) { return false } return true } func createIfNotExists(dir string, perm os.FileMode) error { if exists(dir) { return nil } if err := os.MkdirAll(dir, perm); err != nil { return fmt.Errorf("failed to create directory: '%s', error: '%s'", dir, err.Error()) } return nil }