diff options
| author | Shulhan <ms@kilabit.info> | 2026-02-15 13:44:39 +0700 |
|---|---|---|
| committer | Shulhan <ms@kilabit.info> | 2026-02-15 13:45:38 +0700 |
| commit | 83a162bfa6e6eba78ae439e193682c19b9cd4744 (patch) | |
| tree | 8588115d422a34aeaefa22e759ef1f19d992784f | |
| parent | 19d58e9a4c900aec1d63de45a655657c760b1235 (diff) | |
| download | awwan-83a162bfa6e6eba78ae439e193682c19b9cd4744.tar.xz | |
all: fix chmod/chown if destination is directory
Given the following command
#put!+0644 src/file dst/
If the dst is a directory, it would cause the directory permission
changes to 0644.
This changes fix it by checking if the destination is a directory first.
If we cannot stat the dst, skip the chmod/chown command.
| -rw-r--r-- | CHANGELOG.adoc | 11 | ||||
| -rw-r--r-- | awwan_local_test.go | 5 | ||||
| -rw-r--r-- | awwan_sudo_test.go | 29 | ||||
| -rw-r--r-- | session.go | 11 | ||||
| -rw-r--r-- | testdata/local/put.aww | 2 |
5 files changed, 57 insertions, 1 deletions
diff --git a/CHANGELOG.adoc b/CHANGELOG.adoc index 7cb4910..bf40fea 100644 --- a/CHANGELOG.adoc +++ b/CHANGELOG.adoc @@ -34,6 +34,17 @@ Using parameters is acceptable only for 2 to 3 arguments. The `-shutdown-idle` option set the duration when the "serve" command will stop accepting new connections and shutting down the HTTP server. +**🌼 all: fix chmod/chown if destination is directory** + +Given the following command + + #put!+0644 src/file dst/ + +If the dst is a directory, it would cause the directory permission +changes to 0644. +This changes fix it by checking if the destination is a directory first. +If we cannot stat the dst, skip the chmod/chown command. + [#v0_13_1] == awwan v0.13.1 (2026-02-09) diff --git a/awwan_local_test.go b/awwan_local_test.go index c12f3ec..b663d67 100644 --- a/awwan_local_test.go +++ b/awwan_local_test.go @@ -306,6 +306,11 @@ func TestAwwanLocal_Put(t *testing.T) { t.Fatal(err) } + err = os.Chmod(filepath.Join(baseDir, `tmp`), 0755) + if err != nil { + t.Fatal(err) + } + var cases = []testCase{{ desc: `With text file`, lineRange: `1`, diff --git a/awwan_sudo_test.go b/awwan_sudo_test.go index eb26202..8becc0b 100644 --- a/awwan_sudo_test.go +++ b/awwan_sudo_test.go @@ -42,6 +42,11 @@ func TestAwwan_Local_SudoGet(t *testing.T) { t.Fatal(err) } + err = os.Chmod(filepath.Join(baseDir, `tmp`), 0755) + if err != nil { + t.Fatal(err) + } + var ( mockTerm = mock.ReadWriter{} @@ -141,6 +146,7 @@ func TestAwwan_Local_SudoPut(t *testing.T) { expError string expContent string expMode fs.FileMode + expDirMode fs.FileMode } // Load the test data output. @@ -157,6 +163,11 @@ func TestAwwan_Local_SudoPut(t *testing.T) { t.Fatal(err) } + err = os.Chmod(filepath.Join(baseDir, `tmp`), 0755) + if err != nil { + t.Fatal(err) + } + var cases = []testCase{{ desc: `WithTextFile`, lineRange: `7-8`, @@ -164,6 +175,7 @@ func TestAwwan_Local_SudoPut(t *testing.T) { fileDest: `/etc/plain.txt`, expContent: string(tdata.Output[`tmp/plain.txt`]), expMode: 420, + expDirMode: 0755, }, { desc: `WithMode`, lineRange: `14`, @@ -171,6 +183,7 @@ func TestAwwan_Local_SudoPut(t *testing.T) { fileDest: `/etc/sudoput_with_mode.txt`, expContent: string(tdata.Output[`tmp/plain.txt`]), expMode: 0516, + expDirMode: 0755, }, { desc: `WithOwner`, lineRange: `16`, @@ -178,6 +191,15 @@ func TestAwwan_Local_SudoPut(t *testing.T) { fileDest: `/etc/sudoput_with_owner.txt`, expContent: string(tdata.Output[`tmp/plain.txt`]), expMode: 420, + expDirMode: 0755, + }, { + desc: `WithDestinationIsDirectory`, + lineRange: `20`, + sudoPass: "awwan\nawwan\n", + fileDest: filepath.Join(baseDir, `tmp`, `plain.txt`), + expContent: string(tdata.Output[`tmp/plain.txt`]), + expMode: 0644, + expDirMode: 0755, }} var ( @@ -238,7 +260,12 @@ func TestAwwan_Local_SudoPut(t *testing.T) { if err != nil { t.Fatal(err) } - test.Assert(t, `permission`, c.expMode, fi.Mode().Perm()) + + fi, err = os.Stat(filepath.Dir(c.fileDest)) + if err != nil { + t.Fatal(err) + } + test.Assert(t, `dirMode`, c.expDirMode, fi.Mode().Perm()) } } @@ -265,6 +265,17 @@ func (ses *Session) SudoCopy(ctx context.Context, req *ExecRequest, stmt *Statem return fmt.Errorf("%s: %w", logp, err) } + dstFileInfo, err := os.Stat(dst) + if err != nil { + log.Printf(`%s: stat fails, skip setting file mode and/or owner: %s`, + logp, err) + return nil + } + if dstFileInfo.IsDir() { + srcBase := filepath.Base(src) + dst = filepath.Join(dst, srcBase) + } + if stmt.mode != 0 { var ( fsmode = strconv.FormatUint(uint64(stmt.mode), 8) diff --git a/testdata/local/put.aww b/testdata/local/put.aww index 82297e5..78bc950 100644 --- a/testdata/local/put.aww +++ b/testdata/local/put.aww @@ -16,3 +16,5 @@ sudo chmod 0644 /etc/plain.txt #put!awwan:bin+0644 {{.ScriptDir}}/plain.txt /etc/sudoput_with_owner.txt #put:$noparse {{.ScriptDir}}/plain.txt {{.ScriptDir}}/tmp/plain_noparse.txt + +#put!+0644 {{.ScriptDir}}/plain.txt {{.ScriptDir}}/tmp/ |
