brew/Library/Homebrew/cask/utils/copy-xattrs.swift

81 lines
3.0 KiB
Swift
Raw Normal View History

#!/usr/bin/swift
import Foundation
struct SwiftErr: TextOutputStream {
public static var stream = SwiftErr()
mutating func write(_ string: String) {
fputs(string, stderr)
}
}
guard CommandLine.arguments.count >= 3 else {
print("Usage: swift copy-xattrs.swift <source> <dest>")
exit(2)
}
2023-05-03 11:29:01 -05:00
CommandLine.arguments[2].withCString { destinationPath in
let destinationNamesLength = listxattr(destinationPath, nil, 0, 0)
if destinationNamesLength == -1 {
print("listxattr for destination failed: \(errno)", to: &SwiftErr.stream)
exit(1)
}
2023-05-03 11:29:01 -05:00
let destinationNamesBuffer = UnsafeMutablePointer<Int8>.allocate(capacity: destinationNamesLength)
if listxattr(destinationPath, destinationNamesBuffer, destinationNamesLength, 0) != destinationNamesLength {
print("Attributes changed during system call", to: &SwiftErr.stream)
exit(1)
}
2023-05-03 11:29:01 -05:00
var destinationNamesIndex = 0
while destinationNamesIndex < destinationNamesLength {
let attribute = destinationNamesBuffer + destinationNamesIndex
2023-05-03 11:29:01 -05:00
if removexattr(destinationPath, attribute, 0) != 0 {
print("removexattr for \(String(cString: attribute)) failed: \(errno)", to: &SwiftErr.stream)
exit(1)
}
2023-05-03 11:29:01 -05:00
destinationNamesIndex += strlen(attribute) + 1
}
2023-05-03 11:29:01 -05:00
destinationNamesBuffer.deallocate()
CommandLine.arguments[1].withCString { sourcePath in
2023-05-03 11:29:01 -05:00
let sourceNamesLength = listxattr(sourcePath, nil, 0, 0)
if sourceNamesLength == -1 {
print("listxattr for source failed: \(errno)", to: &SwiftErr.stream)
exit(1)
}
2023-05-03 11:29:01 -05:00
let sourceNamesBuffer = UnsafeMutablePointer<Int8>.allocate(capacity: sourceNamesLength)
if listxattr(sourcePath, sourceNamesBuffer, sourceNamesLength, 0) != sourceNamesLength {
print("Attributes changed during system call", to: &SwiftErr.stream)
exit(1)
}
2023-05-03 11:29:01 -05:00
var sourceNamesIndex = 0
while sourceNamesIndex < sourceNamesLength {
let attribute = sourceNamesBuffer + sourceNamesIndex
2023-05-03 11:29:01 -05:00
let valueLength = getxattr(sourcePath, attribute, nil, 0, 0, 0)
if valueLength == -1 {
print("getxattr for \(String(cString: attribute)) failed: \(errno)", to: &SwiftErr.stream)
exit(1)
}
2023-05-03 11:29:01 -05:00
let valueBuffer = UnsafeMutablePointer<Int8>.allocate(capacity: valueLength)
if getxattr(sourcePath, attribute, valueBuffer, valueLength, 0, 0) != valueLength {
print("Attributes changed during system call", to: &SwiftErr.stream)
exit(1)
}
2023-05-03 11:29:01 -05:00
if setxattr(destinationPath, attribute, valueBuffer, valueLength, 0, 0) != 0 {
print("setxattr for \(String(cString: attribute)) failed: \(errno)", to: &SwiftErr.stream)
exit(1)
}
2023-05-03 11:29:01 -05:00
valueBuffer.deallocate()
sourceNamesIndex += strlen(attribute) + 1
}
2023-05-03 11:29:01 -05:00
sourceNamesBuffer.deallocate()
}
}