agent/fileutil/fileutil_unix.go (77 lines of code) (raw):
// Copyright 2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License"). You may not
// use this file except in compliance with the License. A copy of the
// License is located at
//
// http://aws.amazon.com/apache2.0/
//
// or in the "license" file accompanying this file. This file is distributed
// on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// either express or implied. See the License for the specific language governing
// permissions and limitations under the License.
//go:build darwin || freebsd || linux || netbsd || openbsd
// +build darwin freebsd linux netbsd openbsd
// Package fileutil contains utilities for working with the file system.
package fileutil
import (
"archive/tar"
"compress/gzip"
"fmt"
"io"
"os"
"syscall"
"github.com/aws/amazon-ssm-agent/agent/appconfig"
"github.com/aws/amazon-ssm-agent/agent/log"
)
const (
fileNotFoundErrorMessage = "open : no such file or directory"
)
// Uncompress untar the installation package
func Uncompress(log log.T, src, dest string) error {
file, err := os.Open(src)
if err != nil {
return err
}
defer file.Close()
gr, err := gzip.NewReader(file)
if err != nil {
return err
}
defer gr.Close()
os.MkdirAll(dest, appconfig.ReadWriteExecuteAccess)
tr := tar.NewReader(gr)
for {
hdr, err := tr.Next()
if err == io.EOF {
break
} else if err != nil {
return err
}
itemPath := dest + string(os.PathSeparator) + hdr.Name
if !isUnderDir(itemPath, dest) {
return fmt.Errorf("%v attepts to place files outside %v subtree", file.Name(), dest)
}
if hdr.FileInfo().IsDir() {
os.MkdirAll(itemPath, hdr.FileInfo().Mode())
} else {
mode := hdr.FileInfo().Mode()
log.Debugf("Uncompressing file %v with %v mode", itemPath, mode.Perm().String())
fw, err := os.OpenFile(itemPath, appconfig.FileFlagsCreateOrTruncate, mode)
if err != nil {
return err
}
defer fw.Close()
_, err = io.Copy(fw, tr)
if err != nil {
return err
}
if err = os.Chmod(itemPath, mode); err != nil {
return err
}
log.Debugf("Uncompressed file mode is %v", GetFileMode(itemPath).Perm().String())
}
}
return nil
}
// GetDiskSpaceInfo returns DiskSpaceInfo with available, free, and total bytes from system disk space
func GetDiskSpaceInfo() (diskSpaceInfo DiskSpaceInfo, err error) {
var stat syscall.Statfs_t
var wd string
// get a rooted path name
if wd, err = os.Getwd(); err != nil {
return
}
// get filesystem statistics
syscall.Statfs(wd, &stat)
// get block size
bSize := uint64(stat.Bsize)
// return DiskSpaceInfo with calculated bytes
return DiskSpaceInfo{
// On Linux the struct statfs.f_bavail field is unsigned, but on FreeBSD the field is an int64
AvailBytes: (int64)((uint64)(stat.Bavail) * bSize), // available space = # of available blocks * block size
FreeBytes: (int64)(stat.Bfree * bSize), // free space = # of free blocks * block size
TotalBytes: (int64)(stat.Blocks * bSize), // total space = # of total blocks * block size
}, nil
}
// HardenDataFolder sets permission of %PROGRAM_DATA% folder for Windows. In
// Linux, each components handles the permission of its data.
func HardenDataFolder(log log.T) error {
return nil // do nothing
}