// 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 }