#!/usr/bin/env bash
set -ex

# Below command actually runs `sudo dnf clean all` for AL2023.
# See https://docs.aws.amazon.com/linux/al2023/ug/package-management.html for more details.
sudo yum clean all

function cleanup() {
    FILES=("$@")
    for FILE in "${FILES[@]}"; do
        if sudo test -f $FILE; then
            echo "Deleting $FILE"
            sudo shred -zuf $FILE
        fi
        if sudo test -f $FILE; then
            echo "Failed to delete '$FILE'. Failing."
            exit 1
        fi
    done
}

# Clean up for cloud-init files
CLOUD_INIT_FILES=(
    "/etc/locale.conf"
    "/var/log/cloud-init.log"
    "/var/log/cloud-init-output.log"
)
echo "Cleaning up cloud init files"
cleanup "${CLOUD_INIT_FILES[@]}"
if [[ $(sudo find /var/lib/cloud -type f | sudo wc -l) -gt 0 ]]; then
    echo "Deleting files within /var/lib/cloud/*"
    sudo find /var/lib/cloud -type f -exec shred -zuf {} \;
fi

if [[ $(sudo ls /var/lib/cloud | sudo wc -l) -gt 0 ]]; then
    echo "Deleting /var/lib/cloud/*"
    sudo rm -rf /var/lib/cloud/* || true
fi

# Clean up for temporary instance files
INSTANCE_FILES=(
    "/etc/.updated"
    "/etc/aliases.db"
    "/etc/hostname"
    "/var/lib/misc/postfix.aliasesdb-stamp"
    "/var/lib/postfix/master.lock"
    "/var/spool/postfix/pid/master.pid"
    "/var/.updated"
    "/var/cache/yum/x86_64/2/.gpgkeyschecked.yum"
)
echo "Cleaning up instance files"
cleanup "${INSTANCE_FILES[@]}"

# Clean up for ssh files
SSH_FILES=(
    "/etc/ssh/ssh_host_rsa_key"
    "/etc/ssh/ssh_host_rsa_key.pub"
    "/etc/ssh/ssh_host_ecdsa_key"
    "/etc/ssh/ssh_host_ecdsa_key.pub"
    "/etc/ssh/ssh_host_ed25519_key"
    "/etc/ssh/ssh_host_ed25519_key.pub"
    "/root/.ssh/authorized_keys"
)
echo "Cleaning up ssh files"
cleanup "${SSH_FILES[@]}"
USERS=$(ls /home/)
for user in $USERS; do
    echo Deleting /home/"$user"/.ssh/authorized_keys
    sudo find /home/"$user"/.ssh/authorized_keys -type f -exec shred -zuf {} \;
done
for user in $USERS; do
    if sudo test -f /home/"$user"/.ssh/authorized_keys; then
        echo Failed to delete /home/"$user"/.ssh/authorized_keys
        exit 1
    fi
done

INSTANCE_LOG_FILES=(
    "/var/log/audit/audit.log"
    "/var/log/boot.log"
    "/var/log/dmesg"
    "/var/log/messages"
    "/var/log/cron"
)
echo "Cleaning up instance log files"
cleanup "${INSTANCE_LOG_FILES[@]}"

echo "Cleaning TOE files"
if [[ $(sudo find {{workingDirectory}}/TOE_* -type f | sudo wc -l) -gt 0 ]]; then
    echo "Deleting files within {{workingDirectory}}/TOE_*"
    sudo find {{workingDirectory}}/TOE_* -type f -exec shred -zuf {} \;
fi
if [[ $(sudo find {{workingDirectory}}/TOE_* -type f | sudo wc -l) -gt 0 ]]; then
    echo "Failed to delete {{workingDirectory}}/TOE_*"
    exit 1
fi
if [[ $(sudo find {{workingDirectory}}/TOE_* -type d | sudo wc -l) -gt 0 ]]; then
    echo "Deleting {{workingDirectory}}/TOE_*"
    sudo rm -rf {{workingDirectory}}/TOE_*
fi
if [[ $(sudo find {{workingDirectory}}/TOE_* -type d | sudo wc -l) -gt 0 ]]; then
    echo "Failed to delete {{workingDirectory}}/TOE_*"
    exit 1
fi

echo "Cleaning up ssm log files"
if [[ $(sudo find /var/log/amazon/ssm -type f | sudo wc -l) -gt 0 ]]; then
    echo "Deleting files within /var/log/amazon/ssm/*"
    sudo find /var/log/amazon/ssm -type f -exec shred -zuf {} \;
fi
if [[ $(sudo find /var/log/amazon/ssm -type f | sudo wc -l) -gt 0 ]]; then
    echo "Failed to delete /var/log/amazon/ssm"
    exit 1
fi
if sudo test -d "/var/log/amazon/ssm"; then
    echo "Deleting /var/log/amazon/ssm/*"
    sudo rm -rf /var/log/amazon/ssm
fi
if sudo test -d "/var/log/amazon/ssm"; then
    echo "Failed to delete /var/log/amazon/ssm"
    exit 1
fi

if [[ $(sudo find /var/log/sa/sa* -type f | sudo wc -l) -gt 0 ]]; then
    echo "Deleting /var/log/sa/sa*"
    sudo shred -zuf /var/log/sa/sa*
fi
if [[ $(sudo find /var/log/sa/sa* -type f | sudo wc -l) -gt 0 ]]; then
    echo "Failed to delete /var/log/sa/sa*"
    exit 1
fi

if [[ $(sudo find /var/lib/dhclient/dhclient*.lease -type f | sudo wc -l) -gt 0 ]]; then
    echo "Deleting /var/lib/dhclient/dhclient*.lease"
    sudo shred -zuf /var/lib/dhclient/dhclient*.lease
fi
if [[ $(sudo find /var/lib/dhclient/dhclient*.lease -type f | sudo wc -l) -gt 0 ]]; then
    echo "Failed to delete /var/lib/dhclient/dhclient*.lease"
    exit 1
fi

if [[ $(sudo find /var/tmp -type f | sudo wc -l) -gt 0 ]]; then
    echo "Deleting files within /var/tmp/*"
    sudo find /var/tmp -type f -exec shred -zuf {} \;
fi
if [[ $(sudo find /var/tmp -type f | sudo wc -l) -gt 0 ]]; then
    echo "Failed to delete /var/tmp"
    exit 1
fi
if [[ $(sudo ls /var/tmp | sudo wc -l) -gt 0 ]]; then
    echo "Deleting /var/tmp/*"
    sudo rm -rf /var/tmp/*
fi

# Shredding is not guaranteed to work well on rolling logs

if sudo test -f "/var/lib/rsyslog/imjournal.state"; then
    echo "Deleting /var/lib/rsyslog/imjournal.state"
    sudo shred -zuf /var/lib/rsyslog/imjournal.state
    sudo rm -f /var/lib/rsyslog/imjournal.state
fi

if [[ $(sudo ls /var/log/journal/ | sudo wc -l) -gt 0 ]]; then
    echo "Deleting /var/log/journal/*"
    sudo find /var/log/journal/ -type f -exec shred -zuf {} \;
    sudo rm -rf /var/log/journal/*
fi

# delete a few items missed in https://docs.aws.amazon.com/imagebuilder/latest/userguide/security-best-practices.html
sudo rm -rf \
    /etc/machine-id \
    /var/cache/dnf \
    /var/cache/yum \
    /tmp/* \
    /var/lib/dhcp/dhclient.* \
    /var/lib/dnf/history* \
    /var/lib/yum/history \
    /var/log/secure \
    /var/log/wtmp \
    /etc/ssh/ssh_host*

sudo touch /etc/machine-id


#!/usr/bin/env bash
set -ex

if [[ $AMI_TYPE != "al2gpu" ]]; then
    exit 0
fi

GPG_CHECK=1
# don't do the gpg check in air-gapped regions
if [ -n "$AIR_GAPPED" ]; then
    GPG_CHECK=0
fi
tmpfile=$(mktemp)
cat >$tmpfile <<EOF
[amzn2-nvidia]
name=Amazon Linux 2 Nvidia repository
mirrorlist=\$awsproto://\$amazonlinux.\$awsregion.\$awsdomain/\$releasever/amzn2-nvidia/latest/\$basearch/mirror.list
priority=20
gpgcheck=$GPG_CHECK
gpgkey=https://developer.download.nvidia.com/compute/cuda/repos/rhel7/x86_64/7fa2af80.pub
enabled=1
exclude=libglvnd-*
EOF

# this repo is temporary and only used for installing the system-release-nvidia package
sudo mv $tmpfile /etc/yum.repos.d/amzn2-nvidia-tmp.repo
# system-release-nvidia creates an nvidia repo file at /etc/yum.repos.d/amzn2-nvidia.repo
sudo yum install -y system-release-nvidia
sudo rm /etc/yum.repos.d/amzn2-nvidia-tmp.repo

sudo yum install -y kernel-devel-$(uname -r) \
    system-release-nvidia \
    nvidia-driver-latest-dkms \
    nvidia-fabric-manager \
    pciutils \
    xorg-x11-server-Xorg \
    docker-runtime-nvidia \
    oci-add-hooks \
    libnvidia-container \
    libnvidia-container-tools \
    nvidia-container-runtime-hook

sudo yum install -y cuda-drivers \
    cuda

# The Fabric Manager service needs be started and enabled on EC2 P4d instances
# in order to configure NVLinks and NVSwitches
sudo systemctl enable nvidia-fabricmanager
mkdir -p /tmp/ecs
echo 'ECS_ENABLE_GPU_SUPPORT=true' >>/tmp/ecs/ecs.config
sudo mv /tmp/ecs/ecs.config /var/lib/ecs/ecs.config


#!/usr/bin/env bash
set -ex

if [[ $AMI_TYPE != "al2inf" && $AMI_TYPE != "al2023neu" ]]; then
    exit 0
fi

# docs about installing neuron docker environment on inferentia instances:
# https://awsdocs-neuron.readthedocs-hosted.com/en/latest/neuron-deploy/tutorials/tutorial-docker-env-setup.html
# https://awsdocs-neuron.readthedocs-hosted.com/en/latest/neuron-intro/mxnet-setup/mxnet-install.html#install-neuron-mxnet

# Copy the neuron repo
cat >/tmp/neuron.repo <<EOF
[neuron]
name=neuron
baseurl=https://yum.repos.neuron.amazonaws.com/
priority=12
gpgcheck=0
gpgkey=https://yum.repos.neuron.amazonaws.com/GPG-PUB-KEY-AMAZON-AWS-NEURON.PUB
enabled=1
keepcache=0
EOF

sudo mv /tmp/neuron.repo /etc/yum.repos.d/neuron.repo

# Install OS headers
sudo yum install kernel-devel-$(uname -r) kernel-headers-$(uname -r) -y

# Install Neuron Driver
sudo yum install -y aws-neuronx-dkms-2.*
sudo yum install -y aws-neuronx-oci-hook-2.*

# Install oci-add-hooks
# TODO: oci-add-hooks package has compatibility issue with AL2023 IMDSv2. Remove condition after root caused and resolved
if [[ $AMI_TYPE == "al2inf" ]]; then
    sudo yum install -y oci-add-hooks
fi

# Install Neuron Tools
# TODO: use aws-neuronx-tools on al2inf when it is ready
if [[ $AMI_TYPE == "al2inf" ]]; then # drop this dependency for AL2023 or later AMIs
    sudo yum install -y aws-neuron-tools
fi

# disable neuron package upgrades by deleting the yum repo
sudo rm /etc/yum.repos.d/neuron.repo

NEURON_RUNTIME=/etc/docker-runtimes.d/neuron
# Add env variable to identify if inf is supported on this ami
mkdir -p /tmp/ecs
echo 'ECS_ENABLE_INF_SUPPORT=true' >>/tmp/ecs/ecs.config
sudo mv /tmp/ecs/ecs.config /var/lib/ecs/ecs.config

# Copy neuron runtime to docker runtime to be accessed as one of the runtimes supported.
if [ ! -f $NEURON_RUNTIME ]; then
    sudo cp /opt/aws/neuron/bin/oci_neuron_hook_wrapper.sh $NEURON_RUNTIME
    sudo chmod +x $NEURON_RUNTIME
fi


#!/usr/bin/env bash
set -ex

sudo systemctl enable ecs
sudo systemctl enable amazon-ecs-volume-plugin
sudo systemctl enable amazon-ssm-agent


#!/usr/bin/env bash
set -ex

ARCH=$(uname -m)

# install any rpm packages from the additional-packages/ directory
if ls /tmp/additional-packages/*."${ARCH}".rpm; then
    echo "Found additional packages with architecture ${ARCH} to be installed"
    sudo yum localinstall -y /tmp/additional-packages/*."${ARCH}".rpm
else
    echo "No matching additional packages with architecture ${ARCH} found"
fi
if ls /tmp/additional-packages/*.noarch.rpm; then
    echo "Found additional packages with no specific architecture to be installed"
    sudo yum localinstall -y /tmp/additional-packages/*.noarch.rpm
else
    echo "No matching additional packages with no architecture found"
fi


#!/usr/bin/env bash
set -ex

if [ -n "$AIR_GAPPED" ]; then
    echo "Air-gapped region, assuming docker and dependencies will be in additional-packages/ directory"
    exit 0
fi

if command -v amazon-linux-extras; then
    # enable docker "extras" repo when available
    sudo amazon-linux-extras enable docker
fi

sudo yum install -y "docker-$DOCKER_VERSION" "containerd-$CONTAINERD_VERSION"


#!/usr/bin/env bash
set -ex

if [ -n "$AIR_GAPPED" ]; then
    echo "Air-gapped region, exec feature is not supported"
    exit 0
fi

BINARY_PATH="/var/lib/ecs/deps/execute-command/bin/${EXEC_SSM_VERSION}"
CERTS_PATH="/var/lib/ecs/deps/execute-command/certs"
ARCHITECTURE="$(uname -m)"

host_suffix=""
if grep -q "^cn-" <<<"$REGION"; then
    host_suffix=".cn"
fi

# Download ssm agent static binaries in BINARY_PATH
mkdir -p /tmp/ssm-binaries && cd /tmp/ssm-binaries
case $ARCHITECTURE in
'x86_64')
    curl -fLSs "https://amazon-ssm-${REGION}.s3.${REGION}.amazonaws.com${host_suffix}/${EXEC_SSM_VERSION}/linux_amd64/amazon-ssm-agent-binaries.tar.gz" -o amazon-ssm-agent.tar.gz
    echo "0100e5f6299274150d9252eb56ace6f3ff797ee2e9c17be1d6b9b8035b75315c ./amazon-ssm-agent.tar.gz" >./amazon-ssm-agent.tar.gz.sha256
    sha256sum -c ./amazon-ssm-agent.tar.gz.sha256
    ;;
'aarch64')
    curl -fLSs "https://amazon-ssm-${REGION}.s3.${REGION}.amazonaws.com${host_suffix}/${EXEC_SSM_VERSION}/linux_arm64/amazon-ssm-agent-binaries.tar.gz" -o amazon-ssm-agent.tar.gz
    echo "2f345a98ed25a9ffeb12355533b242110a502c929dd3abd61c2936000d22f230 ./amazon-ssm-agent.tar.gz" >./amazon-ssm-agent.tar.gz.sha256
    sha256sum -c ./amazon-ssm-agent.tar.gz.sha256
    ;;
esac

sudo tar -xvf amazon-ssm-agent.tar.gz
sudo mkdir -p "${BINARY_PATH}"
sudo cp amazon-ssm-agent "${BINARY_PATH}"/amazon-ssm-agent
sudo cp ssm-agent-worker "${BINARY_PATH}"/ssm-agent-worker
sudo cp ssm-session-worker "${BINARY_PATH}"/ssm-session-worker
rm -rf /tmp/ssm-binaries

# Copy certs with 400 permission in CERTS_PATH
sudo mkdir -p ${CERTS_PATH} && cd ${CERTS_PATH}
sudo cp /etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem tls-ca-bundle.pem
sudo chmod 400 tls-ca-bundle.pem


#!/usr/bin/env bash
set -ex

sudo yum install -y ecs-service-connect-agent


#!/usr/bin/env bash
set -ex

check_ownership() {
    path=$1
    expected_user=$2
    expected_group=$3

    actual_user=$(stat -c '%U' "${path}")
    if [ "${actual_user}" != "${expected_user}" ]; then
        echo "ERROR: Ownership for ${path}: expected user is ${expected_user}, actual user found was ${actual_user}"
        exit 1
    fi

    actual_group=$(stat -c '%G' "${path}")
    if [ "${actual_group}" != "${expected_group}" ]; then
        echo "ERROR: Ownership for ${path}: expected group is ${expected_group}, actual group found was ${actual_group}"
        exit 1
    fi
}

check_ownership /var/spool/mail root mail


#!/usr/bin/env bash
set -ex

# ECS-optimized AMIs are provisioned with two disks:
# 1) Root volume at /dev/sda (GP2, 8GB, delete on terminate)
# 2) Extra EBS volume at /dev/xvdcz just for Docker (GP2, 22GB, delete on terminate)
#
# We use docker-storage-setup to configure this additional device properly.
# By default docker-storage-setup will configure 40% of the device, and will
# then grow the available space over time up to the maximum in the pool
# (volume group).  We can tweak the initial space higher if necessary, but
# cannot set DATA_SIZE=100%FREE, as some space must be reserved for the
# metadata and root of the pool.
#
# VG=docker because that's what the volume group is for.
cat >>/tmp/docker-storage-setup <<EOF
DEVS=/dev/xvdcz
VG=docker
DATA_SIZE=99%FREE
AUTO_EXTEND_POOL=yes
LV_ERROR_WHEN_FULL=yes
EXTRA_DOCKER_STORAGE_OPTIONS="--storage-opt dm.fs=ext4 --storage-opt dm.use_deferred_deletion=true"
EOF
sudo mv /tmp/docker-storage-setup /etc/sysconfig/docker-storage-setup


#!/usr/bin/env bash
set -ex

sudo sed -i 's,^#releasever=,releasever=,' /etc/yum.conf


#!/usr/bin/env bash
set -ex

yum update -y
yum install -y openssh-clients


#!/usr/bin/env bash
# TO-DO once Amazon Linux team has released AL2 kernel 5.10 minimal AMIs:
#   - Disable/remove this script
#   - Modify AL2 kernel 5.10 variables in generate-release-vars.sh to use SSM parameters of AL2 kernel 5.10 minimal AMIs
set -ex

if [[ $AMI_TYPE == "al2kernel5dot10" || $AMI_TYPE == "al2kernel5dot10arm" ]]; then
    sudo amazon-linux-extras install -y kernel-5.10
    sudo rpm -e kernel-4.*
fi


#!/usr/bin/env bash
set -ex

# AL2023 uses pam-motd, for docs see:
# http://www.linux-pam.org/Linux-PAM-html/sag-pam_motd.html

# disable the Amazon Linux motd banner (found at /usr/lib/motd.d/30-banner):
sudo ln -s /dev/null /etc/motd.d/30-banner

# add the ECS motd banner
cat <<'EOF' >>/tmp/31-banner
   ,     #_
   ~\_  ####_
  ~~  \_#####\
  ~~     \###|
  ~~       \#/ ___   Amazon Linux 2023 (ECS Optimized)
   ~~       V~' '->
    ~~~         /
      ~~._.   _/
         _/ _/
       _/m/'

For documentation, visit http://aws.amazon.com/documentation/ecs
EOF
sudo mv /tmp/31-banner /etc/motd.d/31-banner


#!/usr/bin/env bash
set -e

cd "$(dirname "$(readlink -f "${BASH_SOURCE[*]}")")/../.."

# see also ".mailmap" for how email addresses and names are deduplicated

{
	cat <<-'EOH'
	# This file lists all individuals having contributed content to the repository.
	# For how it is generated, see `scripts/docs/generate-authors.sh`.
	EOH
	echo
	git log --format='%aN <%aE>' | LC_ALL=C.UTF-8 sort -uf
} > AUTHORS


#!/usr/bin/env bash
set -e

cd "$(dirname "$(readlink -f "$BASH_SOURCE")")/.."

# see also ".mailmap" for how email addresses and names are deduplicated

{
	cat <<-'EOH'
	# This file lists all individuals having contributed content to the repository.
	# For how it is generated, see `hack/generate-authors.sh`.
	EOH
	echo
	git log --format='%aN <%aE>' | LC_ALL=C.UTF-8 sort -uf
} > AUTHORS


#!/usr/bin/env bash
# Copyright 2009 The Go Authors. All rights reserved.
# Use of this source code is governed by a BSD-style
# license that can be found in the LICENSE file.

# This script runs or (given -n) prints suggested commands to generate files for
# the Architecture/OS specified by the GOARCH and GOOS environment variables.
# See README.md for more information about how the build system works.

GOOSARCH="${GOOS}_${GOARCH}"

# defaults
mksyscall="./mksyscall.pl"
mkerrors="./mkerrors.sh"
zerrors="zerrors_$GOOSARCH.go"
mksysctl=""
zsysctl="zsysctl_$GOOSARCH.go"
mksysnum=
mktypes=
run="sh"
cmd=""

case "$1" in
-syscalls)
	for i in zsyscall*go
	do
		# Run the command line that appears in the first line
		# of the generated file to regenerate it.
		sed 1q $i | sed 's;^// ;;' | sh > _$i && gofmt < _$i > $i
		rm _$i
	done
	exit 0
	;;
-n)
	run="cat"
	cmd="echo"
	shift
esac

case "$#" in
0)
	;;
*)
	echo 'usage: mkall.sh [-n]' 1>&2
	exit 2
esac

if [[ "$GOOS" = "linux" ]] && [[ "$GOARCH" != "sparc64" ]]; then
	# Use then new build system
	# Files generated through docker (use $cmd so you can Ctl-C the build or run)
	$cmd docker build --tag generate:$GOOS $GOOS
	$cmd docker run --interactive --tty --volume $(dirname "$(readlink -f "$0")"):/build generate:$GOOS
	exit
fi

GOOSARCH_in=syscall_$GOOSARCH.go
case "$GOOSARCH" in
_* | *_ | _)
	echo 'undefined $GOOS_$GOARCH:' "$GOOSARCH" 1>&2
	exit 1
	;;
darwin_386)
	mkerrors="$mkerrors -m32"
	mksyscall="./mksyscall.pl -l32"
	mksysnum="./mksysnum_darwin.pl $(xcrun --show-sdk-path --sdk macosx)/usr/include/sys/syscall.h"
	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
	;;
darwin_amd64)
	mkerrors="$mkerrors -m64"
	mksysnum="./mksysnum_darwin.pl $(xcrun --show-sdk-path --sdk macosx)/usr/include/sys/syscall.h"
	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
	;;
darwin_arm)
	mkerrors="$mkerrors"
	mksysnum="./mksysnum_darwin.pl $(xcrun --show-sdk-path --sdk iphoneos)/usr/include/sys/syscall.h"
	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
	;;
darwin_arm64)
	mkerrors="$mkerrors -m64"
	mksysnum="./mksysnum_darwin.pl $(xcrun --show-sdk-path --sdk iphoneos)/usr/include/sys/syscall.h"
	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
	;;
dragonfly_amd64)
	mkerrors="$mkerrors -m64"
	mksyscall="./mksyscall.pl -dragonfly"
	mksysnum="curl -s 'http://gitweb.dragonflybsd.org/dragonfly.git/blob_plain/HEAD:/sys/kern/syscalls.master' | ./mksysnum_dragonfly.pl"
	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
	;;
freebsd_386)
	mkerrors="$mkerrors -m32"
	mksyscall="./mksyscall.pl -l32"
	mksysnum="curl -s 'http://svn.freebsd.org/base/stable/10/sys/kern/syscalls.master' | ./mksysnum_freebsd.pl"
	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
	;;
freebsd_amd64)
	mkerrors="$mkerrors -m64"
	mksysnum="curl -s 'http://svn.freebsd.org/base/stable/10/sys/kern/syscalls.master' | ./mksysnum_freebsd.pl"
	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
	;;
freebsd_arm)
	mkerrors="$mkerrors"
	mksyscall="./mksyscall.pl -l32 -arm"
	mksysnum="curl -s 'http://svn.freebsd.org/base/stable/10/sys/kern/syscalls.master' | ./mksysnum_freebsd.pl"
	# Let the type of C char be signed for making the bare syscall
	# API consistent across platforms.
	mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char"
	;;
linux_sparc64)
	GOOSARCH_in=syscall_linux_sparc64.go
	unistd_h=/usr/include/sparc64-linux-gnu/asm/unistd.h
	mkerrors="$mkerrors -m64"
	mksysnum="./mksysnum_linux.pl $unistd_h"
	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
	;;
netbsd_386)
	mkerrors="$mkerrors -m32"
	mksyscall="./mksyscall.pl -l32 -netbsd"
	mksysnum="curl -s 'http://cvsweb.netbsd.org/bsdweb.cgi/~checkout~/src/sys/kern/syscalls.master' | ./mksysnum_netbsd.pl"
	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
	;;
netbsd_amd64)
	mkerrors="$mkerrors -m64"
	mksyscall="./mksyscall.pl -netbsd"
	mksysnum="curl -s 'http://cvsweb.netbsd.org/bsdweb.cgi/~checkout~/src/sys/kern/syscalls.master' | ./mksysnum_netbsd.pl"
	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
	;;
netbsd_arm)
	mkerrors="$mkerrors"
	mksyscall="./mksyscall.pl -l32 -netbsd -arm"
	mksysnum="curl -s 'http://cvsweb.netbsd.org/bsdweb.cgi/~checkout~/src/sys/kern/syscalls.master' | ./mksysnum_netbsd.pl"
	# Let the type of C char be signed for making the bare syscall
	# API consistent across platforms.
	mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char"
	;;
openbsd_386)
	mkerrors="$mkerrors -m32"
	mksyscall="./mksyscall.pl -l32 -openbsd"
	mksysctl="./mksysctl_openbsd.pl"
	mksysnum="curl -s 'http://cvsweb.openbsd.org/cgi-bin/cvsweb/~checkout~/src/sys/kern/syscalls.master' | ./mksysnum_openbsd.pl"
	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
	;;
openbsd_amd64)
	mkerrors="$mkerrors -m64"
	mksyscall="./mksyscall.pl -openbsd"
	mksysctl="./mksysctl_openbsd.pl"
	mksysnum="curl -s 'http://cvsweb.openbsd.org/cgi-bin/cvsweb/~checkout~/src/sys/kern/syscalls.master' | ./mksysnum_openbsd.pl"
	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
	;;
openbsd_arm)
	mkerrors="$mkerrors"
	mksyscall="./mksyscall.pl -l32 -openbsd -arm"
	mksysctl="./mksysctl_openbsd.pl"
	mksysnum="curl -s 'http://cvsweb.openbsd.org/cgi-bin/cvsweb/~checkout~/src/sys/kern/syscalls.master' | ./mksysnum_openbsd.pl"
	# Let the type of C char be signed for making the bare syscall
	# API consistent across platforms.
	mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char"
	;;
solaris_amd64)
	mksyscall="./mksyscall_solaris.pl"
	mkerrors="$mkerrors -m64"
	mksysnum=
	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
	;;
*)
	echo 'unrecognized $GOOS_$GOARCH: ' "$GOOSARCH" 1>&2
	exit 1
	;;
esac

(
	if [ -n "$mkerrors" ]; then echo "$mkerrors |gofmt >$zerrors"; fi
	case "$GOOS" in
	*)
		syscall_goos="syscall_$GOOS.go"
		case "$GOOS" in
		darwin | dragonfly | freebsd | netbsd | openbsd)
			syscall_goos="syscall_bsd.go $syscall_goos"
			;;
		esac
		if [ -n "$mksyscall" ]; then echo "$mksyscall -tags $GOOS,$GOARCH $syscall_goos $GOOSARCH_in |gofmt >zsyscall_$GOOSARCH.go"; fi
		;;
	esac
	if [ -n "$mksysctl" ]; then echo "$mksysctl |gofmt >$zsysctl"; fi
	if [ -n "$mksysnum" ]; then echo "$mksysnum |gofmt >zsysnum_$GOOSARCH.go"; fi
	if [ -n "$mktypes" ]; then
		echo "$mktypes types_$GOOS.go | go run mkpost.go > ztypes_$GOOSARCH.go";
	fi
) | $run


#!/usr/bin/env bash
# Copyright 2009 The Go Authors. All rights reserved.
# Use of this source code is governed by a BSD-style
# license that can be found in the LICENSE file.

# Generate Go code listing errors and other #defined constant
# values (ENAMETOOLONG etc.), by asking the preprocessor
# about the definitions.

unset LANG
export LC_ALL=C
export LC_CTYPE=C

if test -z "$GOARCH" -o -z "$GOOS"; then
	echo 1>&2 "GOARCH or GOOS not defined in environment"
	exit 1
fi

# Check that we are using the new build system if we should
if [[ "$GOOS" = "linux" ]] && [[ "$GOARCH" != "sparc64" ]]; then
	if [[ "$GOLANG_SYS_BUILD" != "docker" ]]; then
		echo 1>&2 "In the new build system, mkerrors should not be called directly."
		echo 1>&2 "See README.md"
		exit 1
	fi
fi

CC=${CC:-cc}

if [[ "$GOOS" = "solaris" ]]; then
	# Assumes GNU versions of utilities in PATH.
	export PATH=/usr/gnu/bin:$PATH
fi

uname=$(uname)

includes_Darwin='
#define _DARWIN_C_SOURCE
#define KERNEL
#define _DARWIN_USE_64_BIT_INODE
#include <stdint.h>
#include <sys/attr.h>
#include <sys/types.h>
#include <sys/event.h>
#include <sys/ptrace.h>
#include <sys/socket.h>
#include <sys/sockio.h>
#include <sys/sysctl.h>
#include <sys/mman.h>
#include <sys/mount.h>
#include <sys/utsname.h>
#include <sys/wait.h>
#include <net/bpf.h>
#include <net/if.h>
#include <net/if_types.h>
#include <net/route.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <termios.h>
'

includes_DragonFly='
#include <sys/types.h>
#include <sys/event.h>
#include <sys/socket.h>
#include <sys/sockio.h>
#include <sys/sysctl.h>
#include <sys/mman.h>
#include <sys/wait.h>
#include <sys/ioctl.h>
#include <net/bpf.h>
#include <net/if.h>
#include <net/if_types.h>
#include <net/route.h>
#include <netinet/in.h>
#include <termios.h>
#include <netinet/ip.h>
#include <net/ip_mroute/ip_mroute.h>
'

includes_FreeBSD='
#include <sys/capability.h>
#include <sys/param.h>
#include <sys/types.h>
#include <sys/event.h>
#include <sys/socket.h>
#include <sys/sockio.h>
#include <sys/sysctl.h>
#include <sys/mman.h>
#include <sys/mount.h>
#include <sys/wait.h>
#include <sys/ioctl.h>
#include <net/bpf.h>
#include <net/if.h>
#include <net/if_types.h>
#include <net/route.h>
#include <netinet/in.h>
#include <termios.h>
#include <netinet/ip.h>
#include <netinet/ip_mroute.h>
#include <sys/extattr.h>

#if __FreeBSD__ >= 10
#define IFT_CARP	0xf8	// IFT_CARP is deprecated in FreeBSD 10
#undef SIOCAIFADDR
#define SIOCAIFADDR	_IOW(105, 26, struct oifaliasreq)	// ifaliasreq contains if_data
#undef SIOCSIFPHYADDR
#define SIOCSIFPHYADDR	_IOW(105, 70, struct oifaliasreq)	// ifaliasreq contains if_data
#endif
'

includes_Linux='
#define _LARGEFILE_SOURCE
#define _LARGEFILE64_SOURCE
#ifndef __LP64__
#define _FILE_OFFSET_BITS 64
#endif
#define _GNU_SOURCE

// <sys/ioctl.h> is broken on powerpc64, as it fails to include definitions of
// these structures. We just include them copied from <bits/termios.h>.
#if defined(__powerpc__)
struct sgttyb {
        char    sg_ispeed;
        char    sg_ospeed;
        char    sg_erase;
        char    sg_kill;
        short   sg_flags;
};

struct tchars {
        char    t_intrc;
        char    t_quitc;
        char    t_startc;
        char    t_stopc;
        char    t_eofc;
        char    t_brkc;
};

struct ltchars {
        char    t_suspc;
        char    t_dsuspc;
        char    t_rprntc;
        char    t_flushc;
        char    t_werasc;
        char    t_lnextc;
};
#endif

#include <bits/sockaddr.h>
#include <sys/epoll.h>
#include <sys/eventfd.h>
#include <sys/inotify.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <sys/mount.h>
#include <sys/prctl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <sys/xattr.h>
#include <linux/if.h>
#include <linux/if_alg.h>
#include <linux/if_arp.h>
#include <linux/if_ether.h>
#include <linux/if_tun.h>
#include <linux/if_packet.h>
#include <linux/if_addr.h>
#include <linux/falloc.h>
#include <linux/filter.h>
#include <linux/fs.h>
#include <linux/keyctl.h>
#include <linux/netlink.h>
#include <linux/perf_event.h>
#include <linux/random.h>
#include <linux/reboot.h>
#include <linux/rtnetlink.h>
#include <linux/ptrace.h>
#include <linux/sched.h>
#include <linux/seccomp.h>
#include <linux/sockios.h>
#include <linux/wait.h>
#include <linux/icmpv6.h>
#include <linux/serial.h>
#include <linux/can.h>
#include <linux/vm_sockets.h>
#include <linux/taskstats.h>
#include <linux/genetlink.h>
#include <linux/watchdog.h>
#include <net/route.h>
#include <asm/termbits.h>

#ifndef MSG_FASTOPEN
#define MSG_FASTOPEN    0x20000000
#endif

#ifndef PTRACE_GETREGS
#define PTRACE_GETREGS	0xc
#endif

#ifndef PTRACE_SETREGS
#define PTRACE_SETREGS	0xd
#endif

#ifndef SOL_NETLINK
#define SOL_NETLINK	270
#endif

#ifdef SOL_BLUETOOTH
// SPARC includes this in /usr/include/sparc64-linux-gnu/bits/socket.h
// but it is already in bluetooth_linux.go
#undef SOL_BLUETOOTH
#endif

// Certain constants are missing from the fs/crypto UAPI
#define FS_KEY_DESC_PREFIX              "fscrypt:"
#define FS_KEY_DESC_PREFIX_SIZE         8
#define FS_MAX_KEY_SIZE                 64
'

includes_NetBSD='
#include <sys/types.h>
#include <sys/param.h>
#include <sys/event.h>
#include <sys/mman.h>
#include <sys/socket.h>
#include <sys/sockio.h>
#include <sys/sysctl.h>
#include <sys/termios.h>
#include <sys/ttycom.h>
#include <sys/wait.h>
#include <net/bpf.h>
#include <net/if.h>
#include <net/if_types.h>
#include <net/route.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <netinet/ip_mroute.h>
#include <netinet/if_ether.h>

// Needed since <sys/param.h> refers to it...
#define schedppq 1
'

includes_OpenBSD='
#include <sys/types.h>
#include <sys/param.h>
#include <sys/event.h>
#include <sys/mman.h>
#include <sys/socket.h>
#include <sys/sockio.h>
#include <sys/sysctl.h>
#include <sys/termios.h>
#include <sys/ttycom.h>
#include <sys/wait.h>
#include <net/bpf.h>
#include <net/if.h>
#include <net/if_types.h>
#include <net/if_var.h>
#include <net/route.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <netinet/ip_mroute.h>
#include <netinet/if_ether.h>
#include <net/if_bridge.h>

// We keep some constants not supported in OpenBSD 5.5 and beyond for
// the promise of compatibility.
#define EMUL_ENABLED		0x1
#define EMUL_NATIVE		0x2
#define IPV6_FAITH		0x1d
#define IPV6_OPTIONS		0x1
#define IPV6_RTHDR_STRICT	0x1
#define IPV6_SOCKOPT_RESERVED1	0x3
#define SIOCGIFGENERIC		0xc020693a
#define SIOCSIFGENERIC		0x80206939
#define WALTSIG			0x4
'

includes_SunOS='
#include <limits.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/sockio.h>
#include <sys/mman.h>
#include <sys/wait.h>
#include <sys/ioctl.h>
#include <sys/mkdev.h>
#include <net/bpf.h>
#include <net/if.h>
#include <net/if_arp.h>
#include <net/if_types.h>
#include <net/route.h>
#include <netinet/in.h>
#include <termios.h>
#include <netinet/ip.h>
#include <netinet/ip_mroute.h>
'

includes='
#include <sys/types.h>
#include <sys/file.h>
#include <fcntl.h>
#include <dirent.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/ip6.h>
#include <netinet/tcp.h>
#include <errno.h>
#include <sys/signal.h>
#include <signal.h>
#include <sys/resource.h>
#include <time.h>
'
ccflags="$@"

# Write go tool cgo -godefs input.
(
	echo package unix
	echo
	echo '/*'
	indirect="includes_$(uname)"
	echo "${!indirect} $includes"
	echo '*/'
	echo 'import "C"'
	echo 'import "syscall"'
	echo
	echo 'const ('

	# The gcc command line prints all the #defines
	# it encounters while processing the input
	echo "${!indirect} $includes" | $CC -x c - -E -dM $ccflags |
	awk '
		$1 != "#define" || $2 ~ /\(/ || $3 == "" {next}

		$2 ~ /^E([ABCD]X|[BIS]P|[SD]I|S|FL)$/ {next}  # 386 registers
		$2 ~ /^(SIGEV_|SIGSTKSZ|SIGRT(MIN|MAX))/ {next}
		$2 ~ /^(SCM_SRCRT)$/ {next}
		$2 ~ /^(MAP_FAILED)$/ {next}
		$2 ~ /^ELF_.*$/ {next}# <asm/elf.h> contains ELF_ARCH, etc.

		$2 ~ /^EXTATTR_NAMESPACE_NAMES/ ||
		$2 ~ /^EXTATTR_NAMESPACE_[A-Z]+_STRING/ {next}

		$2 !~ /^ETH_/ &&
		$2 !~ /^EPROC_/ &&
		$2 !~ /^EQUIV_/ &&
		$2 !~ /^EXPR_/ &&
		$2 ~ /^E[A-Z0-9_]+$/ ||
		$2 ~ /^B[0-9_]+$/ ||
		$2 ~ /^(OLD|NEW)DEV$/ ||
		$2 == "BOTHER" ||
		$2 ~ /^CI?BAUD(EX)?$/ ||
		$2 == "IBSHIFT" ||
		$2 ~ /^V[A-Z0-9]+$/ ||
		$2 ~ /^CS[A-Z0-9]/ ||
		$2 ~ /^I(SIG|CANON|CRNL|UCLC|EXTEN|MAXBEL|STRIP|UTF8)$/ ||
		$2 ~ /^IGN/ ||
		$2 ~ /^IX(ON|ANY|OFF)$/ ||
		$2 ~ /^IN(LCR|PCK)$/ ||
		$2 ~ /(^FLU?SH)|(FLU?SH$)/ ||
		$2 ~ /^C(LOCAL|READ|MSPAR|RTSCTS)$/ ||
		$2 == "BRKINT" ||
		$2 == "HUPCL" ||
		$2 == "PENDIN" ||
		$2 == "TOSTOP" ||
		$2 == "XCASE" ||
		$2 == "ALTWERASE" ||
		$2 == "NOKERNINFO" ||
		$2 ~ /^PAR/ ||
		$2 ~ /^SIG[^_]/ ||
		$2 ~ /^O[CNPFPL][A-Z]+[^_][A-Z]+$/ ||
		$2 ~ /^(NL|CR|TAB|BS|VT|FF)DLY$/ ||
		$2 ~ /^(NL|CR|TAB|BS|VT|FF)[0-9]$/ ||
		$2 ~ /^O?XTABS$/ ||
		$2 ~ /^TC[IO](ON|OFF)$/ ||
		$2 ~ /^IN_/ ||
		$2 ~ /^LOCK_(SH|EX|NB|UN)$/ ||
		$2 ~ /^(AF|SOCK|SO|SOL|IPPROTO|IP|IPV6|ICMP6|TCP|EVFILT|NOTE|EV|SHUT|PROT|MAP|PACKET|MSG|SCM|MCL|DT|MADV|PR)_/ ||
		$2 ~ /^FALLOC_/ ||
		$2 == "ICMPV6_FILTER" ||
		$2 == "SOMAXCONN" ||
		$2 == "NAME_MAX" ||
		$2 == "IFNAMSIZ" ||
		$2 ~ /^CTL_(HW|KERN|MAXNAME|NET|QUERY)$/ ||
		$2 ~ /^KERN_(HOSTNAME|OS(RELEASE|TYPE)|VERSION)$/ ||
		$2 ~ /^HW_MACHINE$/ ||
		$2 ~ /^SYSCTL_VERS/ ||
		$2 ~ /^(MS|MNT|UMOUNT)_/ ||
		$2 ~ /^TUN(SET|GET|ATTACH|DETACH)/ ||
		$2 ~ /^(O|F|E?FD|NAME|S|PTRACE|PT)_/ ||
		$2 ~ /^LINUX_REBOOT_CMD_/ ||
		$2 ~ /^LINUX_REBOOT_MAGIC[12]$/ ||
		$2 !~ "NLA_TYPE_MASK" &&
		$2 ~ /^(NETLINK|NLM|NLMSG|NLA|IFA|IFAN|RT|RTCF|RTN|RTPROT|RTNH|ARPHRD|ETH_P)_/ ||
		$2 ~ /^SIOC/ ||
		$2 ~ /^TIOC/ ||
		$2 ~ /^TCGET/ ||
		$2 ~ /^TCSET/ ||
		$2 ~ /^TC(FLSH|SBRKP?|XONC)$/ ||
		$2 !~ "RTF_BITS" &&
		$2 ~ /^(IFF|IFT|NET_RT|RTM|RTF|RTV|RTA|RTAX)_/ ||
		$2 ~ /^BIOC/ ||
		$2 ~ /^RUSAGE_(SELF|CHILDREN|THREAD)/ ||
		$2 ~ /^RLIMIT_(AS|CORE|CPU|DATA|FSIZE|LOCKS|MEMLOCK|MSGQUEUE|NICE|NOFILE|NPROC|RSS|RTPRIO|RTTIME|SIGPENDING|STACK)|RLIM_INFINITY/ ||
		$2 ~ /^PRIO_(PROCESS|PGRP|USER)/ ||
		$2 ~ /^CLONE_[A-Z_]+/ ||
		$2 !~ /^(BPF_TIMEVAL)$/ &&
		$2 ~ /^(BPF|DLT)_/ ||
		$2 ~ /^CLOCK_/ ||
		$2 ~ /^CAN_/ ||
		$2 ~ /^CAP_/ ||
		$2 ~ /^ALG_/ ||
		$2 ~ /^FS_(POLICY_FLAGS|KEY_DESC|ENCRYPTION_MODE|[A-Z0-9_]+_KEY_SIZE|IOC_(GET|SET)_ENCRYPTION)/ ||
		$2 ~ /^GRND_/ ||
		$2 ~ /^KEY_(SPEC|REQKEY_DEFL)_/ ||
		$2 ~ /^KEYCTL_/ ||
		$2 ~ /^PERF_EVENT_IOC_/ ||
		$2 ~ /^SECCOMP_MODE_/ ||
		$2 ~ /^SPLICE_/ ||
		$2 ~ /^(VM|VMADDR)_/ ||
		$2 ~ /^IOCTL_VM_SOCKETS_/ ||
		$2 ~ /^(TASKSTATS|TS)_/ ||
		$2 ~ /^CGROUPSTATS_/ ||
		$2 ~ /^GENL_/ ||
		$2 ~ /^UTIME_/ ||
		$2 ~ /^XATTR_(CREATE|REPLACE)/ ||
		$2 ~ /^ATTR_(BIT_MAP_COUNT|(CMN|VOL|FILE)_)/ ||
		$2 ~ /^FSOPT_/ ||
		$2 ~ /^WDIOC_/ ||
		$2 !~ "WMESGLEN" &&
		$2 ~ /^W[A-Z0-9]+$/ ||
		$2 ~ /^BLK[A-Z]*(GET$|SET$|BUF$|PART$|SIZE)/ {printf("\t%s = C.%s\n", $2, $2)}
		$2 ~ /^__WCOREFLAG$/ {next}
		$2 ~ /^__W[A-Z0-9]+$/ {printf("\t%s = C.%s\n", substr($2,3), $2)}

		{next}
	' | sort

	echo ')'
) >_const.go

# Pull out the error names for later.
errors=$(
	echo '#include <errno.h>' | $CC -x c - -E -dM $ccflags |
	awk '$1=="#define" && $2 ~ /^E[A-Z0-9_]+$/ { print $2 }' |
	sort
)

# Pull out the signal names for later.
signals=$(
	echo '#include <signal.h>' | $CC -x c - -E -dM $ccflags |
	awk '$1=="#define" && $2 ~ /^SIG[A-Z0-9]+$/ { print $2 }' |
	egrep -v '(SIGSTKSIZE|SIGSTKSZ|SIGRT)' |
	sort
)

# Again, writing regexps to a file.
echo '#include <errno.h>' | $CC -x c - -E -dM $ccflags |
	awk '$1=="#define" && $2 ~ /^E[A-Z0-9_]+$/ { print "^\t" $2 "[ \t]*=" }' |
	sort >_error.grep
echo '#include <signal.h>' | $CC -x c - -E -dM $ccflags |
	awk '$1=="#define" && $2 ~ /^SIG[A-Z0-9]+$/ { print "^\t" $2 "[ \t]*=" }' |
	egrep -v '(SIGSTKSIZE|SIGSTKSZ|SIGRT)' |
	sort >_signal.grep

echo '// mkerrors.sh' "$@"
echo '// Code generated by the command above; see README.md. DO NOT EDIT.'
echo
echo "// +build ${GOARCH},${GOOS}"
echo
go tool cgo -godefs -- "$@" _const.go >_error.out
cat _error.out | grep -vf _error.grep | grep -vf _signal.grep
echo
echo '// Errors'
echo 'const ('
cat _error.out | grep -f _error.grep | sed 's/=\(.*\)/= syscall.Errno(\1)/'
echo ')'

echo
echo '// Signals'
echo 'const ('
cat _error.out | grep -f _signal.grep | sed 's/=\(.*\)/= syscall.Signal(\1)/'
echo ')'

# Run C program to print error and syscall strings.
(
	echo -E "
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <ctype.h>
#include <string.h>
#include <signal.h>

#define nelem(x) (sizeof(x)/sizeof((x)[0]))

enum { A = 'A', Z = 'Z', a = 'a', z = 'z' }; // avoid need for single quotes below

int errors[] = {
"
	for i in $errors
	do
		echo -E '	'$i,
	done

	echo -E "
};

int signals[] = {
"
	for i in $signals
	do
		echo -E '	'$i,
	done

	# Use -E because on some systems bash builtin interprets \n itself.
	echo -E '
};

static int
intcmp(const void *a, const void *b)
{
	return *(int*)a - *(int*)b;
}

int
main(void)
{
	int i, e;
	char buf[1024], *p;

	printf("\n\n// Error table\n");
	printf("var errors = [...]string {\n");
	qsort(errors, nelem(errors), sizeof errors[0], intcmp);
	for(i=0; i<nelem(errors); i++) {
		e = errors[i];
		if(i > 0 && errors[i-1] == e)
			continue;
		strcpy(buf, strerror(e));
		// lowercase first letter: Bad -> bad, but STREAM -> STREAM.
		if(A <= buf[0] && buf[0] <= Z && a <= buf[1] && buf[1] <= z)
			buf[0] += a - A;
		printf("\t%d: \"%s\",\n", e, buf);
	}
	printf("}\n\n");

	printf("\n\n// Signal table\n");
	printf("var signals = [...]string {\n");
	qsort(signals, nelem(signals), sizeof signals[0], intcmp);
	for(i=0; i<nelem(signals); i++) {
		e = signals[i];
		if(i > 0 && signals[i-1] == e)
			continue;
		strcpy(buf, strsignal(e));
		// lowercase first letter: Bad -> bad, but STREAM -> STREAM.
		if(A <= buf[0] && buf[0] <= Z && a <= buf[1] && buf[1] <= z)
			buf[0] += a - A;
		// cut trailing : number.
		p = strrchr(buf, ":"[0]);
		if(p)
			*p = '\0';
		printf("\t%d: \"%s\",\n", e, buf);
	}
	printf("}\n\n");

	return 0;
}

'
) >_errors.c

$CC $ccflags -o _errors _errors.c && $GORUN ./_errors && rm -f _errors.c _errors _const.go _error.grep _signal.grep _error.out


#!/bin/bash
# Copyright 2015-2017 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.

# Normalize to working directory being build root (up one level from ./scripts)
ROOT=$( cd "$( dirname "${BASH_SOURCE[0]}" )/.." && pwd )
cd "${ROOT}"

# Builds the ecs-cli binary from source in the specified destination paths.
mkdir -p $1

# Versioning stuff. We run the generator to setup the version and then always
# restore ourselves to a clean state
cp ecs-cli/modules/version/version.go ecs-cli/modules/version/_version.go
trap "cd \"${ROOT}\"; mv ecs-cli/modules/version/_version.go ecs-cli/modules/version/version.go" EXIT SIGHUP SIGINT SIGTERM

cd ./ecs-cli/modules/version/
go run gen/version-gen.go

cd "${ROOT}"

GOOS=$TARGET_GOOS CGO_ENABLED=0 go build -installsuffix cgo -a -ldflags '-s' -o $1/ecs-cli ./ecs-cli/


#!/bin/bash
# Copyright 2014-2017 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.

set -e

DRYRUN=true

AWS_PROFILE=""
AWS_REGION="us-west-2"
AMI_ID="ami-9ff7e8af" #amzn-ami-hvm-2015.09.0.x86_64-gp2
ARTIFACT_BUCKET=""
SOURCE_BUCKET=""
KEY_NAME=""
SECURITY_GROUP=""
INSTANCE_PROFILE=""

source $(dirname "${0}")/publish-functions.sh

usage() {
	echo "Usage: ${0} -a BUCKET -k SSH_KEY -s SECURITY_GROUP -i IAM_ROLE [OPTIONS]"
	echo
	echo "This script stages a new version of the Amazon ECS CLI"
	echo "built on a freshly-launched EC2 instance."
	echo "To run this script, you must have the following resources:"
	echo "* A local AWS profile with permissions for \"ec2:run-instances\","
	echo "  \"ec2:describe-instances\", \"s3:PutObject\", and \"s3:ListObjects\""
	echo "* An S3 bucket for the source"
	echo "* An S3 bucket for the artifact destination"
	echo "* An IAM profile with permissions to read from and write to the"
	echo "  source bucket (\"s3:GetObject\", \"s3:PutObject\", and \"s3:PutObjectAcl\") "
	echo "  and write to the destination S3 bucket (\"s3:PutObject\" and "
	echo "  \"s3:PutObjectAcl\")"
	echo
	echo "Options"
	echo "  -d  true|false      Dryrun (default is true)"
	echo "  -p  PROFILE         AWS CLI Profile (default is none)"
	echo "  -a  BUCKET          Artifact (Destination) AWS S3 Bucket"
	echo "  -t  BUCKET          Source AWS S3 Bucket"
	echo "  -k  SSH_KEY         SSH key name"
	echo "  -s  SECURITY_GROUP  Security group name"
	echo "  -i  IAM_ROLE        IAM Role name"
	echo "  -h                  Display this help message"
}

while getopts ":d:p:a:t:k:s:i:h" opt; do
	case ${opt} in
		d)
			if [[ "${OPTARG}" = "false" ]]; then
				DRYRUN=false
			fi
			;;
		p)
			AWS_PROFILE="${OPTARG}"
			;;
		a)
			ARTIFACT_BUCKET="${OPTARG}"
			;;
		t)
			SOURCE_BUCKET="${OPTARG}"
			;;
		k)
			KEY_NAME="${OPTARG}"
			;;
		s)
			SECURITY_GROUP="${OPTARG}"
			;;
		i)
			INSTANCE_PROFILE="${OPTARG}"
			;;
		\?)
			echo "Invalid option -${OPTARG}" >&2
			usage
			exit 1
			;;
		:)
			echo "Option -${OPTARG} requires an argument." >&2
			usage
			exit 1
			;;
		h)
			usage
			exit 0
			;;
	esac
done

if [ -z "${ARTIFACT_BUCKET}" ] \
	|| [ -z "${KEY_NAME}" ] \
	|| [ -z "${INSTANCE_PROFILE}" ] \
	|| [ -z "${SOURCE_BUCKET}" ]; then
	usage
	exit 1
fi

DIRTY_WARNING=$(cat <<EOW
***ERROR***
You currently have uncommitted or unstaged changes in your git repository.
Please commit, stash, or remove all uncommitted or unstaged files before
running this script.
EOW
)
if [[ -n "$(git status --porcelain)" ]]; then
	echo "$DIRTY_WARNING"
	exit 1
fi

commit=$(git rev-parse HEAD)
echo "Packaging ${commit} for staging..."

cli_dir=$(pwd)
tmpdir=$(mktemp -d)
# Fresh clone to ensure our build doesn't rely on anything outside of vcs
git clone --quiet "${cli_dir}" "${tmpdir}"
cd "${tmpdir}"
s3_source_prefix="s3://${SOURCE_BUCKET}/$(hostname)-${RANDOM}"
s3_source_gz="${s3_source_prefix}/${commit}.tgz"
source_gz=$(mktemp)
tar -cz -f "${source_gz}" "."

echo "Uploading ${source_gz} to ${s3_source_gz}..."
S3_ACL_OVERRIDE="private"
dexec s3_cp "${source_gz}" "${s3_source_gz}"
rm "${source_gz}"
cd "${cli_dir}"
rm -rf "${tmpdir}"

ec2_work_root="/var/lib/ec2-stage"
ec2_gopath="${ec2_work_root}/go"
ec2_build_root="${ec2_gopath}/src/github.com/aws"

userdata=$(cat << EOU
#!/bin/bash

mkdir -p ${ec2_work_root}
exec > >(tee -a ${ec2_work_root}/userdata.log)

yum -y install docker golang git
service docker start
aws s3 cp "${s3_source_gz}" "${ec2_work_root}/source.tgz"
mkdir -p ${ec2_build_root}
export GOPATH=${ec2_gopath}
cd ${ec2_build_root}
mkdir -p amazon-ecs-cli
cd amazon-ecs-cli
tar -xvz -f "${ec2_work_root}/source.tgz"
git checkout "${commit}"
scripts/stage.sh -b ${ARTIFACT_BUCKET} -d false
aws s3 cp "${ec2_work_root}/userdata.log" "${s3_source_prefix}/userdata.log"
shutdown -hP now
EOU
)

encoded_user_data=$(base64 <<< "${userdata}")

profile=""
if [[ -n "${AWS_PROFILE}" ]]; then
	profile="--profile=${AWS_PROFILE}"
fi

echo "Starting an EC2 instance with the following user-data:"
echo "======================================================"
echo "${userdata}"
echo "======================================================"
echo

ec2_instance_id=$(dexec aws ${profile} "--region=${AWS_REGION}" \
	ec2 run-instances \
	"--count=1" \
	"--image-id=${AMI_ID}" \
	"--key-name=${KEY_NAME}" \
	"--security-groups=${SECURITY_GROUP}" \
	"--user-data=${encoded_user_data}" \
	"--instance-type=t2.medium" \
	"--instance-initiated-shutdown-behavior=terminate" \
	"--iam-instance-profile=Name=${INSTANCE_PROFILE}" \
	"--query=Instances[0].InstanceId" \
	"--output=text" )

if ${DRYRUN} ; then
	ec2_instance_id="dryrun-ec2-instance-id"
fi

echo "Waiting for ${ec2_instance_id} to start..."
dexec aws ${profile} "--region=${AWS_REGION}" \
	"ec2" "wait" "instance-running" "--instance-ids=${ec2_instance_id}"

echo "Waiting for ${ec2_instance_id} to terminate..."
dexec aws ${profile} "--region=${AWS_REGION}" \
	"ec2" "wait" "instance-terminated" "--instance-ids=${ec2_instance_id}"

log=$(mktemp)

dexec s3_cp "${s3_source_prefix}/userdata.log" "${log}"
cat "${log}"
rm "${log}"


#!/bin/bash
# Copyright 2015-2017 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.
#
# This script generates a file in go with the license contents as a constant

set -e
outputfile=${1?Must provide an output file}
inputfile="$(<../../../../LICENSE)"

appendRepoLicense() {
  repo=$1
  inputfile+=$'\n'"***"$'\n'"$repo"$'\n\n'
  # Copy LICENSE* files
  for licensefile in $repo/LICENSE*; do
    if [ -f $licensefile ]; then
      inputfile+="$(<$licensefile)"$'\n'
    fi;
  done;

  # Copy COPYING* file
  if [ -f $repo/COPYING* ]; then
    inputfile+="$(<$repo/COPYING*)"$'\n'
  fi;

  # Copy NOTICE*
  if [ -f $repo/NOTICE* ]; then
    inputfile+="NOTICE file reads:"$'\n'
    inputfile+="$(<$repo/NOTICE*)"$'\n'
  fi;
}

for registry in github.com golang.org; do
  for user in ./../../../vendor/$registry/*; do
    for repo in $user/*; do
      appendRepoLicense $repo
    done;
  done;
done;

for repo in ./../../../vendor/gopkg.in/*; do
  appendRepoLicense $repo
done;

cat << EOF > "${outputfile}"
// Copyright 2015-2019 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.

package license

const License = \`$inputfile\`
EOF


#!/bin/bash
# Copyright 2015-2017 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.
#
# This script wraps the mockgen tool and inserts licensing information.

set -e
package=${1?Must provide package}
interfaces=${2?Must provide interface names}
outputfile=${3?Must provide an output file}
PROJECT_VENDOR="github.com\/aws\/amazon-ecs-cli\/ecs-cli\/vendor\/"

export PATH="${GOPATH//://bin:}/bin:$PATH"

data=$(
cat << EOF
// Copyright 2015-2019 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.

$(mockgen "$package" "$interfaces")
EOF
)

# Explicitly removing the vendor directory from the mock imports
# https://github.com/golang/mock/issues/30
echo "$data" | sed -e "s/${PROJECT_VENDOR}//" | goimports > "${outputfile}"


#!/bin/bash
# Copyright 2015-2017 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.

export VERSION=$(cat $(dirname "${0}")/../VERSION)

export ARTIFACT_TAG_LATEST="latest"
export ARTIFACT_TAG_SHA=$(git rev-parse --short=7 HEAD)
export ARTIFACT_TAG_VERSION="v${VERSION}"

dexec() {
	if ${DRYRUN} ; then
		echo "DRYRUN: ${@}" 1>&2
	else
		echo "RUNNING: ${@}" 1>&2
		"${@}"
	fi
}

check_md5() {
	test_md5="$(md5sum ${1} | sed 's/ .*//')"
	expected_md5="$(cat ${2})"
	if [ ! "${test_md5}" = "${expected_md5}" ]; then
		echo "Computed md5sum ${test_md5} did not match expected md5sum ${expected_md5}"
		return $(false)
	fi
	return $(true)
}

s3_cp() {
	profile=""
	if [[ ! -z "${AWS_PROFILE}" ]]; then
		profile="--profile=${AWS_PROFILE}"
	fi
	acl="public-read"
	if [[ ! -z "${S3_ACL_OVERRIDE}" ]]; then
		acl="${S3_ACL_OVERRIDE}"
	fi
	echo "Copying ${1} to ${2}"
	aws ${profile} s3 cp "${1}" "${2}" "--acl=${acl}"
}

s3_pull_push() {
	profile=""
	if [[ ! -z "${AWS_PROFILE}" ]]; then
		profile="--profile=${AWS_PROFILE}"
	fi
	if [[ ! -z "${AWS_PROFILE_PUSH}" ]]; then
		profile_push="--profile=${AWS_PROFILE_PUSH}"
	else
		profile_push=$profile
	fi
	acl="public-read"
	if [[ ! -z "${S3_ACL_OVERRIDE}" ]]; then
		acl="${S3_ACL_OVERRIDE}"
	fi
	echo "Copying ${1} to ${2}"
	# for partitioned regions, we cannot copy files between buckets directly. Save it locally and copy it over
	tmp=$(mktemp)
	aws ${profile} s3 cp "${1}" "${tmp}"
	aws ${profile_push} s3 cp "${tmp}" "${2}" "--acl=${acl}"
	rm $tmp
}


#!/bin/bash
# Copyright 2014-2017 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.

set -e

DRYRUN=true
ALLOW_DIRTY=false

AWS_PROFILE=""
S3_BUCKET=""
S3_ACL_OVERRIDE=""

source $(dirname "${0}")/publish-functions.sh

usage() {
	echo "Usage: ${0} -b BUCKET [OPTIONS]"
	echo
	echo "This script is responsible for staging new versions of the Amazon ECS CLI."
	echo "Push the image (and its md5sum) to S3 with -latest, -VERSION, and -SHA"
	echo
	echo "Options"
	echo "  -d  true|false  Dryrun (default is true)"
	echo "  -p  PROFILE     AWS CLI Profile (default is none)"
	echo "  -b  BUCKET      AWS S3 Bucket"
	echo "  -a  ACL         AWS S3 Object Canned ACL (default is public-read)"
	echo "  -i  true|false  Allow dirty builds"
	echo "  -h              Display this help message"
}

while getopts ":d:p:b:a:i:h" opt; do
	case ${opt} in
		d)
			if [[ "${OPTARG}" == "false" ]]; then
				DRYRUN=false
			fi
			;;
		p)
			AWS_PROFILE="${OPTARG}"
			;;
		b)
			S3_BUCKET="${OPTARG}"
			;;
		a)
			S3_ACL_OVERRIDE="${OPTARG}"
			;;
		i)
			if [[ "${OPTARG}" == "true" ]]; then
				ALLOW_DIRTY=true
			fi
			;;
		\?)
			echo "Invalid option -${OPTARG}" >&2
			usage
			exit 1
			;;
		:)
			echo "Option -${OPTARG} requires an argument." >&2
			usage
			exit 1
			;;
		h)
			usage
			exit 0
			;;
	esac
done

if [ -z "${S3_BUCKET}" ]; then
	usage
	exit 1
fi

DIRTY_WARNING=$(cat <<EOW
***WARNING***
You currently have uncommitted or unstaged changes in your git repository.
The release build will not include those and the result may behave differently
than expected due to that. Please commit, stash, or remove all uncommitted or
unstaged files before creating a release build.
EOW
)
[ ! -z "$(git status --porcelain)" ] && echo "$DIRTY_WARNING"

CWD=$(pwd)
clean_directory=""
if ! ${ALLOW_DIRTY}; then
	clean_directory=$(mktemp -d)
	echo "Cloning to a clean directory ${clean_directory}"
	git clone --quiet "${CWD}" "${clean_directory}"
	cd "${clean_directory}"
	export ECS_RELEASE="cleanbuild"
fi

make docker-build

publish_binary() {
	platform=$1
	extension=$2
	artifact="bin/${platform}/ecs-cli${extension}"
	artifact_md5="$(mktemp)"
	md5sum "${artifact}" | sed 's/ .*//' > "${artifact_md5}"

	for tag in ${ARTIFACT_TAG_VERSION} ${ARTIFACT_TAG_SHA} ${ARTIFACT_TAG_LATEST}; do
		key_name="ecs-cli-${platform}-${tag}${extension}"
		echo "Publishing as ${key_name} with md5sum $(cat ${artifact_md5})"
		dexec s3_cp "${artifact}" "s3://${S3_BUCKET}/${key_name}"
		dexec s3_cp "${artifact_md5}" "s3://${S3_BUCKET}/ecs-cli-${platform}-${tag}.md5"
	done

	rm "${artifact_md5}"
}

publish_binary "linux-amd64" ""
publish_binary "darwin-amd64" ""
publish_binary "windows-amd64" ".exe"

cd "${CWD}"

if [[ -n "${clean_directory}" ]]; then
	echo "Removing ${clean_directory}"
	rm -rf "${clean_directory}"
fi


#!/bin/bash
# usage: source these functions and set the s3 endpoint to
# either s3.<region>.amazonaws.com or s3.<region>.amazonaws.com.cn

# usage: retry <command>
function retry {
    local delay=900 # 60 * 15 = 15 minutes
    while true; do
        "$@" && break
        sleep $delay
    done
}

function failBadPGPSignature {
    echo "PGP Signature failed. retrying in $delay s" >&2
    return 1
}

function failBadConnection {
    echo "Couldn't download artifact $bn. Retrying in $delay s" >&2
    return 1
}

#usage: verifyAll <manifestFile>
function verifyAll {
    for artifact in `cat $1`
    do
        bn="$(basename $artifact)"
        echo "Downloading artifact $bn from endpoint https://$S3_ENDPOINT/$BUCKET"
        wget -q https://$S3_ENDPOINT/$BUCKET/$bn || failBadConnection || return 1
        echo "Downloading artifact signature $bn.asc from $S3_ENDPOINT_SIGNATURES"
        wget -q -T 300 https://$S3_ENDPOINT_SIGNATURES/$BUCKET/$bn.asc
        echo "verifying signature..."
        gpg --verify $bn.asc $bn || failBadPGPSignature || return 1
    done
}

function setupGPG {
    gpg --version
    mkdir ~/.gnupg
    echo "disable-ipv6" >> ~/.gnupg/dirmngr.conf
    gpg --keyserver hkp://pool.sks-keyservers.net --recv BCE9D9A42D51784F || exit 1
}

setupGPG
retry verifyAll $1


#!/bin/bash
# Copyright 2016-2017 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.

# Usage:
# build_binary.sh  <relative-path-to-binary-destination-from-build-root>
set -e

# Normalize to working directory being build root (up one level from ./scripts)
ROOT=$( cd "$( dirname "${BASH_SOURCE[0]}" )/.." && pwd )

cd "${ROOT}"
BINARY_DESTINATION_DIR=$1
mkdir -p ${BINARY_DESTINATION_DIR}

# Builds the handler binary from source in the specified destination paths
GOOS=$TARGET_GOOS CGO_ENABLED=0 go build -installsuffix cgo -a -ldflags '-s' -o ${BINARY_DESTINATION_DIR}/cluster-state-service-canary ./


#!/bin/bash
# Copyright 2016-2017 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.

# This script is meant for use inside the build dockerfile
# (scripts/dockerfiles/Dockerfile.build) and makes assumptions related to that.
# It should not be run on its own.

echo "Starting clean build"

cd /src/aws/amazon-ecs-cluster-state-service
DIRTY_WARNING=$(cat <<EOW
***WARNING***
You currently have uncommitted or unstaged changes in your git repository.
The release build will not include those and the result may behave differently
than expected due to that. Please commit, stash, or remove all uncommitted or
unstaged files before creating a release build.
EOW
)
[ ! -z "$(git status --porcelain)" ] && echo "$DIRTY_WARNING"

# Fresh clone to ensure our build doesn't rely on anything outside of vcs
git clone --quiet /src/aws/amazon-ecs-cluster-state-service /go/src/github.com/aws/amazon-ecs-cluster-state-service

cd /go/src/github.com/aws/amazon-ecs-cluster-state-service/canary
exec ./scripts/build_binary.sh /out


#!/bin/bash
# Copyright 2016-2017 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.

# Usage:
# build_binary.sh  <relative-path-to-binary-destination-from-build-root>
set -e

# Normalize to working directory being build root (up one level from ./scripts)
ROOT=$( cd "$( dirname "${BASH_SOURCE[0]}" )/.." && pwd )

cd "${ROOT}"
BINARY_DESTINATION_DIR=$1
mkdir -p ${BINARY_DESTINATION_DIR}

# Versioning: run the generator to setup the version and then always
# restore ourselves to a clean state
cp versioning/version.go versioning/_version.go
trap "mv versioning/_version.go versioning/version.go" EXIT SIGHUP SIGINT SIGTERM

cd versioning
go run gen/version-gen.go

cd "${ROOT}"

# Builds the handler binary from source in the specified destination paths
GOOS=$TARGET_GOOS CGO_ENABLED=0 go build -installsuffix cgo -a -ldflags '-s' -o ${BINARY_DESTINATION_DIR}/cluster-state-service ./
cp "${ROOT}/LICENSE"  ${BINARY_DESTINATION_DIR}/


#!/bin/bash
# Copyright 2016-2017 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.
#
# This script generates a file in go with the license contents as a constant

# Set language to C to make sorting consistent among different environments.
export LANG=C

set -e
outputfile=${1?Must provide an output file}
inputfile="$(<../LICENSE)"

appendRepoLicense() {
  repo=$1
  echo "Adding license for ${repo}"
  inputfile+=$'\n'"***"$'\n'"$repo"$'\n\n'
  # Copy LICENSE* files
  for licensefile in $repo/LICENSE*; do
    if [ -f $licensefile ]; then
      inputfile+="$(<$licensefile)"$'\n'
    fi;
  done;
  # Copy COPYING* file
  if [ -f $repo/COPYING* ]; then
    inputfile+="$(<$repo/COPYING*)"$'\n'
  fi;
}

for registry in github.com golang.org; do
  for user in ./../vendor/$registry/*; do
    for repo in $user/*; do
      if [[ $repo == *"go-buffruneio"* ]]; then
        # nop, since we add this explicitliy
	:
      else
        appendRepoLicense $repo
      fi
    done;
  done;
done;

for repo in ./../vendor/gopkg.in/* ./../vendor/google.golang.org/*; do
  appendRepoLicense $repo
done;

inputfile+="
***
./../vendor/github.com/pelletier/go-buffruneio

Copyright (c) 2016 Thomas Pelletier

Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the \"Software\"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

"

tr -d '\r' > "${outputfile}" << EOF
// Copyright 2016-2017 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.

package licenses

const License = \`$inputfile\`
EOF


#!/bin/bash
# Copyright 2016-2017 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.
#
# This script wraps the mockgen tool and inserts licensing information.

set -e
package=${1?Must provide package}
interfaces=${2?Must provide interface names}
outputfile=${3?Must provide an output file}
PROJECT_VENDOR="github.com\/aws\/amazon-ecs-cluster-state-service\/vendor\/"

export PATH="${GOPATH//://bin:}/bin:$PATH"

year="$(date '+%Y')"
data=$(
cat << EOF
// Copyright ${year} 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.

$(mockgen "${package}" "${interfaces}")
EOF
)

mkdir -p $(dirname ${outputfile})

# Explicitly removing the vendor directory from the mock imports
# https://github.com/golang/mock/issues/30
echo "$data" | sed -e "s/${PROJECT_VENDOR}//" | goimports > "${outputfile}"


#!/bin/bash
# Copyright 2016-2017 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.
#
# This script generates a file in go with the license contents as a constant

set -e

if [ -z "$1" ]
  then
    echo "Must provide at least one input directory"
    exit 1
fi

appendLicense(){
  echo "Slapping copyright notice on ${outputfile}"
  outputfile=${1?Must provide an output file}

  echo "// Copyright 2016-2017 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.

$(cat ${outputfile})" > ${outputfile}
}
for input in "$@"
do
  if [ -d ${input} ] ; then
    for file in `find ${input} -name "*.go"`; do
      if ! grep -q "// Copyright" ${file} ; then
        appendLicense ${file}
      fi
    done
  else
    if ! grep -q "// Copyright" ${input} ; then
      appendLicense ${input}
    fi
  fi
done


#!/bin/bash
# Copyright 2016-2017 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.

# Usage instructions - From one level above the scripts directory, running the following command generates the binary into <path-to-binary-destination>
#      . ./scripts/v1/generate_swagger_models.sh

# Normalize to working directory being build root (up one level from ./scripts)
ROOT=$( cd "$( dirname "${BASH_SOURCE[0]}" )/../.." && pwd )

GENERATED_DIR="${ROOT}/swagger/v1/generated"
cd "${GENERATED_DIR}"

# Remove models directory if it already exists
REMOVE_MODELS="rm -rf ./models ||:"
${REMOVE_MODELS}

# Remove client directory if it already exists
REMOVE_CLIENT="rm -rf ./client ||:"
${REMOVE_CLIENT}

# Generate models and client
SWAGGER_GENERATE="swagger generate client -f ../swagger.json -A ecs_css"
${SWAGGER_GENERATE}

cd ${ROOT}


#!/bin/bash

set -eu -o pipefail
dir=$(git rev-parse --show-toplevel)
scratch=$(mktemp -d -t tmp.XXXXXXXXXX)

function finish {
  rm -rf "$scratch"
}
trap finish EXIT SIGHUP SIGINT SIGTERM

cd "$scratch"
git clone https://github.com/json-schema-org/JSON-Schema-Test-Suite Suite
cp -r Suite/tests/draft4/* "$dir/fixtures/jsonschema_suite"
cp -a Suite/remotes "$dir/fixtures/jsonschema_suite"


#!/bin/bash

set -e

reference_ref=${1:-master}
reference_git=${2:-.}

if ! `hash benchstat 2>/dev/null`; then
    echo "Installing benchstat"
    go get golang.org/x/perf/cmd/benchstat
    go install golang.org/x/perf/cmd/benchstat
fi

tempdir=`mktemp -d /tmp/go-toml-benchmark-XXXXXX`
ref_tempdir="${tempdir}/ref"
ref_benchmark="${ref_tempdir}/benchmark-`echo -n ${reference_ref}|tr -s '/' '-'`.txt"
local_benchmark="`pwd`/benchmark-local.txt"

echo "=== ${reference_ref} (${ref_tempdir})"
git clone ${reference_git} ${ref_tempdir} >/dev/null 2>/dev/null
pushd ${ref_tempdir} >/dev/null
git checkout ${reference_ref} >/dev/null 2>/dev/null
go test -bench=. -benchmem | tee ${ref_benchmark}
popd >/dev/null

echo ""
echo "=== local"
go test -bench=. -benchmem  | tee ${local_benchmark}

echo ""
echo "=== diff"
benchstat -delta-test=none ${ref_benchmark} ${local_benchmark}


#!/bin/bash
# fail out of the script if anything here fails
set -e

# set the path to the present working directory
export GOPATH=`pwd`

function git_clone() {
  path=$1
  branch=$2
  version=$3
  if [ ! -d "src/$path" ]; then
    mkdir -p src/$path
    git clone https://$path.git src/$path
  fi
  pushd src/$path
  git checkout "$branch"
  git reset --hard "$version"
  popd
}

# Remove potential previous runs
rm -rf src test_program_bin toml-test

# Run go vet
go vet ./...

go get github.com/pelletier/go-buffruneio
go get github.com/davecgh/go-spew/spew
go get gopkg.in/yaml.v2
go get github.com/BurntSushi/toml

# get code for BurntSushi TOML validation
# pinning all to 'HEAD' for version 0.3.x work (TODO: pin to commit hash when tests stabilize)
git_clone github.com/BurntSushi/toml master HEAD
git_clone github.com/BurntSushi/toml-test master HEAD #was: 0.2.0 HEAD

# build the BurntSushi test application
go build -o toml-test github.com/BurntSushi/toml-test

# vendorize the current lib for testing
# NOTE: this basically mocks an install without having to go back out to github for code
mkdir -p src/github.com/pelletier/go-toml/cmd
mkdir -p src/github.com/pelletier/go-toml/query
cp *.go *.toml src/github.com/pelletier/go-toml
cp -R cmd/* src/github.com/pelletier/go-toml/cmd
cp -R query/* src/github.com/pelletier/go-toml/query
go build -o test_program_bin src/github.com/pelletier/go-toml/cmd/test_program.go

# Run basic unit tests
go test github.com/pelletier/go-toml -covermode=count -coverprofile=coverage.out
go test github.com/pelletier/go-toml/cmd/tomljson
go test github.com/pelletier/go-toml/query

# run the entire BurntSushi test suite
if [[ $# -eq 0 ]] ; then
  echo "Running all BurntSushi tests"
  ./toml-test ./test_program_bin | tee test_out
else
  # run a specific test
  test=$1
  test_path='src/github.com/BurntSushi/toml-test/tests'
  valid_test="$test_path/valid/$test"
  invalid_test="$test_path/invalid/$test"

  if [ -e "$valid_test.toml" ]; then
    echo "Valid Test TOML for $test:"
    echo "===="
    cat "$valid_test.toml"

    echo "Valid Test JSON for $test:"
    echo "===="
    cat "$valid_test.json"

    echo "Go-TOML Output for $test:"
    echo "===="
    cat "$valid_test.toml" | ./test_program_bin
  fi

  if [ -e "$invalid_test.toml" ]; then
    echo "Invalid Test TOML for $test:"
    echo "===="
    cat "$invalid_test.toml"

    echo "Go-TOML Output for $test:"
    echo "===="
    echo "go-toml Output:"
    cat "$invalid_test.toml" | ./test_program_bin
  fi
fi


#!/usr/bin/env bash
# Copyright 2009 The Go Authors. All rights reserved.
# Use of this source code is governed by a BSD-style
# license that can be found in the LICENSE file.

# The unix package provides access to the raw system call
# interface of the underlying operating system.  Porting Go to
# a new architecture/operating system combination requires
# some manual effort, though there are tools that automate
# much of the process.  The auto-generated files have names
# beginning with z.
#
# This script runs or (given -n) prints suggested commands to generate z files
# for the current system.  Running those commands is not automatic.
# This script is documentation more than anything else.
#
# * asm_${GOOS}_${GOARCH}.s
#
# This hand-written assembly file implements system call dispatch.
# There are three entry points:
#
# 	func Syscall(trap, a1, a2, a3 uintptr) (r1, r2, err uintptr);
# 	func Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr);
# 	func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2, err uintptr);
#
# The first and second are the standard ones; they differ only in
# how many arguments can be passed to the kernel.
# The third is for low-level use by the ForkExec wrapper;
# unlike the first two, it does not call into the scheduler to
# let it know that a system call is running.
#
# * syscall_${GOOS}.go
#
# This hand-written Go file implements system calls that need
# special handling and lists "//sys" comments giving prototypes
# for ones that can be auto-generated.  Mksyscall reads those
# comments to generate the stubs.
#
# * syscall_${GOOS}_${GOARCH}.go
#
# Same as syscall_${GOOS}.go except that it contains code specific
# to ${GOOS} on one particular architecture.
#
# * types_${GOOS}.c
#
# This hand-written C file includes standard C headers and then
# creates typedef or enum names beginning with a dollar sign
# (use of $ in variable names is a gcc extension).  The hardest
# part about preparing this file is figuring out which headers to
# include and which symbols need to be #defined to get the
# actual data structures that pass through to the kernel system calls.
# Some C libraries present alternate versions for binary compatibility
# and translate them on the way in and out of system calls, but
# there is almost always a #define that can get the real ones.
# See types_darwin.c and types_linux.c for examples.
#
# * zerror_${GOOS}_${GOARCH}.go
#
# This machine-generated file defines the system's error numbers,
# error strings, and signal numbers.  The generator is "mkerrors.sh".
# Usually no arguments are needed, but mkerrors.sh will pass its
# arguments on to godefs.
#
# * zsyscall_${GOOS}_${GOARCH}.go
#
# Generated by mksyscall.pl; see syscall_${GOOS}.go above.
#
# * zsysnum_${GOOS}_${GOARCH}.go
#
# Generated by mksysnum_${GOOS}.
#
# * ztypes_${GOOS}_${GOARCH}.go
#
# Generated by godefs; see types_${GOOS}.c above.

GOOSARCH="${GOOS}_${GOARCH}"

# defaults
mksyscall="./mksyscall.pl"
mkerrors="./mkerrors.sh"
zerrors="zerrors_$GOOSARCH.go"
mksysctl=""
zsysctl="zsysctl_$GOOSARCH.go"
mksysnum=
mktypes=
run="sh"

case "$1" in
-syscalls)
	for i in zsyscall*go
	do
		sed 1q $i | sed 's;^// ;;' | sh > _$i && gofmt < _$i > $i
		rm _$i
	done
	exit 0
	;;
-n)
	run="cat"
	shift
esac

case "$#" in
0)
	;;
*)
	echo 'usage: mkall.sh [-n]' 1>&2
	exit 2
esac

GOOSARCH_in=syscall_$GOOSARCH.go
case "$GOOSARCH" in
_* | *_ | _)
	echo 'undefined $GOOS_$GOARCH:' "$GOOSARCH" 1>&2
	exit 1
	;;
darwin_386)
	mkerrors="$mkerrors -m32"
	mksyscall="./mksyscall.pl -l32"
	mksysnum="./mksysnum_darwin.pl $(xcrun --show-sdk-path --sdk macosx)/usr/include/sys/syscall.h"
	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
	;;
darwin_amd64)
	mkerrors="$mkerrors -m64"
	mksysnum="./mksysnum_darwin.pl $(xcrun --show-sdk-path --sdk macosx)/usr/include/sys/syscall.h"
	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
	;;
darwin_arm)
	mkerrors="$mkerrors"
	mksysnum="./mksysnum_darwin.pl /usr/include/sys/syscall.h"
	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
	;;
darwin_arm64)
	mkerrors="$mkerrors -m64"
	mksysnum="./mksysnum_darwin.pl $(xcrun --show-sdk-path --sdk iphoneos)/usr/include/sys/syscall.h"
	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
	;;
dragonfly_386)
	mkerrors="$mkerrors -m32"
	mksyscall="./mksyscall.pl -l32 -dragonfly"
	mksysnum="curl -s 'http://gitweb.dragonflybsd.org/dragonfly.git/blob_plain/HEAD:/sys/kern/syscalls.master' | ./mksysnum_dragonfly.pl"
	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
	;;
dragonfly_amd64)
	mkerrors="$mkerrors -m64"
	mksyscall="./mksyscall.pl -dragonfly"
	mksysnum="curl -s 'http://gitweb.dragonflybsd.org/dragonfly.git/blob_plain/HEAD:/sys/kern/syscalls.master' | ./mksysnum_dragonfly.pl"
	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
	;;
freebsd_386)
	mkerrors="$mkerrors -m32"
	mksyscall="./mksyscall.pl -l32"
	mksysnum="curl -s 'http://svn.freebsd.org/base/stable/10/sys/kern/syscalls.master' | ./mksysnum_freebsd.pl"
	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
	;;
freebsd_amd64)
	mkerrors="$mkerrors -m64"
	mksysnum="curl -s 'http://svn.freebsd.org/base/stable/10/sys/kern/syscalls.master' | ./mksysnum_freebsd.pl"
	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
	;;
freebsd_arm)
	mkerrors="$mkerrors"
	mksyscall="./mksyscall.pl -l32 -arm"
	mksysnum="curl -s 'http://svn.freebsd.org/base/stable/10/sys/kern/syscalls.master' | ./mksysnum_freebsd.pl"
	# Let the type of C char be signed for making the bare syscall
	# API consistent across over platforms.
	mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char"
	;;
linux_386)
	mkerrors="$mkerrors -m32"
	mksyscall="./mksyscall.pl -l32"
	mksysnum="./mksysnum_linux.pl /usr/include/asm/unistd_32.h"
	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
	;;
linux_amd64)
	unistd_h=$(ls -1 /usr/include/asm/unistd_64.h /usr/include/x86_64-linux-gnu/asm/unistd_64.h 2>/dev/null | head -1)
	if [ "$unistd_h" = "" ]; then
		echo >&2 cannot find unistd_64.h
		exit 1
	fi
	mkerrors="$mkerrors -m64"
	mksysnum="./mksysnum_linux.pl $unistd_h"
	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
	;;
linux_arm)
	mkerrors="$mkerrors"
	mksyscall="./mksyscall.pl -l32 -arm"
	mksysnum="curl -s 'http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/plain/arch/arm/include/uapi/asm/unistd.h' | ./mksysnum_linux.pl -"
	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
	;;
linux_arm64)
	unistd_h=$(ls -1 /usr/include/asm/unistd.h /usr/include/asm-generic/unistd.h 2>/dev/null | head -1)
	if [ "$unistd_h" = "" ]; then
		echo >&2 cannot find unistd_64.h
		exit 1
	fi
	mksysnum="./mksysnum_linux.pl $unistd_h"
	# Let the type of C char be signed for making the bare syscall
	# API consistent across over platforms.
	mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char"
	;;
linux_ppc64)
	GOOSARCH_in=syscall_linux_ppc64x.go
	unistd_h=/usr/include/asm/unistd.h
	mkerrors="$mkerrors -m64"
	mksysnum="./mksysnum_linux.pl $unistd_h"
	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
	;;
linux_ppc64le)
	GOOSARCH_in=syscall_linux_ppc64x.go
	unistd_h=/usr/include/powerpc64le-linux-gnu/asm/unistd.h
	mkerrors="$mkerrors -m64"
	mksysnum="./mksysnum_linux.pl $unistd_h"
	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
	;;
linux_s390x)
	GOOSARCH_in=syscall_linux_s390x.go
	unistd_h=/usr/include/asm/unistd.h
	mkerrors="$mkerrors -m64"
	mksysnum="./mksysnum_linux.pl $unistd_h"
	# Let the type of C char be signed to make the bare sys
	# API more consistent between platforms.
	# This is a deliberate departure from the way the syscall
	# package generates its version of the types file.
	mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char"
	;;
linux_sparc64)
	GOOSARCH_in=syscall_linux_sparc64.go
	unistd_h=/usr/include/sparc64-linux-gnu/asm/unistd.h
	mkerrors="$mkerrors -m64"
	mksysnum="./mksysnum_linux.pl $unistd_h"
	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
	;;
netbsd_386)
	mkerrors="$mkerrors -m32"
	mksyscall="./mksyscall.pl -l32 -netbsd"
	mksysnum="curl -s 'http://cvsweb.netbsd.org/bsdweb.cgi/~checkout~/src/sys/kern/syscalls.master' | ./mksysnum_netbsd.pl"
	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
	;;
netbsd_amd64)
	mkerrors="$mkerrors -m64"
	mksyscall="./mksyscall.pl -netbsd"
	mksysnum="curl -s 'http://cvsweb.netbsd.org/bsdweb.cgi/~checkout~/src/sys/kern/syscalls.master' | ./mksysnum_netbsd.pl"
	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
	;;
openbsd_386)
	mkerrors="$mkerrors -m32"
	mksyscall="./mksyscall.pl -l32 -openbsd"
	mksysctl="./mksysctl_openbsd.pl"
	zsysctl="zsysctl_openbsd.go"
	mksysnum="curl -s 'http://cvsweb.openbsd.org/cgi-bin/cvsweb/~checkout~/src/sys/kern/syscalls.master' | ./mksysnum_openbsd.pl"
	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
	;;
openbsd_amd64)
	mkerrors="$mkerrors -m64"
	mksyscall="./mksyscall.pl -openbsd"
	mksysctl="./mksysctl_openbsd.pl"
	zsysctl="zsysctl_openbsd.go"
	mksysnum="curl -s 'http://cvsweb.openbsd.org/cgi-bin/cvsweb/~checkout~/src/sys/kern/syscalls.master' | ./mksysnum_openbsd.pl"
	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
	;;
solaris_amd64)
	mksyscall="./mksyscall_solaris.pl"
	mkerrors="$mkerrors -m64"
	mksysnum=
	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
	;;
*)
	echo 'unrecognized $GOOS_$GOARCH: ' "$GOOSARCH" 1>&2
	exit 1
	;;
esac

(
	if [ -n "$mkerrors" ]; then echo "$mkerrors |gofmt >$zerrors"; fi
	case "$GOOS" in
	*)
		syscall_goos="syscall_$GOOS.go"
		case "$GOOS" in
		darwin | dragonfly | freebsd | netbsd | openbsd)
			syscall_goos="syscall_bsd.go $syscall_goos"
			;;
		esac
		if [ -n "$mksyscall" ]; then echo "$mksyscall $syscall_goos $GOOSARCH_in |gofmt >zsyscall_$GOOSARCH.go"; fi
		;;
	esac
	if [ -n "$mksysctl" ]; then echo "$mksysctl |gofmt >$zsysctl"; fi
	if [ -n "$mksysnum" ]; then echo "$mksysnum |gofmt >zsysnum_$GOOSARCH.go"; fi
	if [ -n "$mktypes" ]; then
		echo "echo // +build $GOARCH,$GOOS > ztypes_$GOOSARCH.go";
		echo "$mktypes types_$GOOS.go | go run mkpost.go >>ztypes_$GOOSARCH.go";
	fi
) | $run


#!/usr/bin/env bash
# Copyright 2009 The Go Authors. All rights reserved.
# Use of this source code is governed by a BSD-style
# license that can be found in the LICENSE file.

# Generate Go code listing errors and other #defined constant
# values (ENAMETOOLONG etc.), by asking the preprocessor
# about the definitions.

unset LANG
export LC_ALL=C
export LC_CTYPE=C

if test -z "$GOARCH" -o -z "$GOOS"; then
	echo 1>&2 "GOARCH or GOOS not defined in environment"
	exit 1
fi

CC=${CC:-cc}

if [[ "$GOOS" -eq "solaris" ]]; then
	# Assumes GNU versions of utilities in PATH.
	export PATH=/usr/gnu/bin:$PATH
fi

uname=$(uname)

includes_Darwin='
#define _DARWIN_C_SOURCE
#define KERNEL
#define _DARWIN_USE_64_BIT_INODE
#include <sys/types.h>
#include <sys/event.h>
#include <sys/ptrace.h>
#include <sys/socket.h>
#include <sys/sockio.h>
#include <sys/sysctl.h>
#include <sys/mman.h>
#include <sys/wait.h>
#include <net/bpf.h>
#include <net/if.h>
#include <net/if_types.h>
#include <net/route.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <termios.h>
'

includes_DragonFly='
#include <sys/types.h>
#include <sys/event.h>
#include <sys/socket.h>
#include <sys/sockio.h>
#include <sys/sysctl.h>
#include <sys/mman.h>
#include <sys/wait.h>
#include <sys/ioctl.h>
#include <net/bpf.h>
#include <net/if.h>
#include <net/if_types.h>
#include <net/route.h>
#include <netinet/in.h>
#include <termios.h>
#include <netinet/ip.h>
#include <net/ip_mroute/ip_mroute.h>
'

includes_FreeBSD='
#include <sys/param.h>
#include <sys/types.h>
#include <sys/event.h>
#include <sys/socket.h>
#include <sys/sockio.h>
#include <sys/sysctl.h>
#include <sys/mman.h>
#include <sys/wait.h>
#include <sys/ioctl.h>
#include <net/bpf.h>
#include <net/if.h>
#include <net/if_types.h>
#include <net/route.h>
#include <netinet/in.h>
#include <termios.h>
#include <netinet/ip.h>
#include <netinet/ip_mroute.h>
#include <sys/extattr.h>

#if __FreeBSD__ >= 10
#define IFT_CARP	0xf8	// IFT_CARP is deprecated in FreeBSD 10
#undef SIOCAIFADDR
#define SIOCAIFADDR	_IOW(105, 26, struct oifaliasreq)	// ifaliasreq contains if_data
#undef SIOCSIFPHYADDR
#define SIOCSIFPHYADDR	_IOW(105, 70, struct oifaliasreq)	// ifaliasreq contains if_data
#endif
'

includes_Linux='
#define _LARGEFILE_SOURCE
#define _LARGEFILE64_SOURCE
#ifndef __LP64__
#define _FILE_OFFSET_BITS 64
#endif
#define _GNU_SOURCE

#include <bits/sockaddr.h>
#include <sys/epoll.h>
#include <sys/inotify.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <sys/mount.h>
#include <sys/prctl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <linux/if.h>
#include <linux/if_arp.h>
#include <linux/if_ether.h>
#include <linux/if_tun.h>
#include <linux/if_packet.h>
#include <linux/if_addr.h>
#include <linux/filter.h>
#include <linux/netlink.h>
#include <linux/reboot.h>
#include <linux/rtnetlink.h>
#include <linux/ptrace.h>
#include <linux/sched.h>
#include <linux/wait.h>
#include <linux/icmpv6.h>
#include <linux/serial.h>
#include <net/route.h>
#include <asm/termbits.h>

#ifndef MSG_FASTOPEN
#define MSG_FASTOPEN    0x20000000
#endif

#ifndef PTRACE_GETREGS
#define PTRACE_GETREGS	0xc
#endif

#ifndef PTRACE_SETREGS
#define PTRACE_SETREGS	0xd
#endif

#ifdef SOL_BLUETOOTH
// SPARC includes this in /usr/include/sparc64-linux-gnu/bits/socket.h
// but it is already in bluetooth_linux.go
#undef SOL_BLUETOOTH
#endif
'

includes_NetBSD='
#include <sys/types.h>
#include <sys/param.h>
#include <sys/event.h>
#include <sys/mman.h>
#include <sys/socket.h>
#include <sys/sockio.h>
#include <sys/sysctl.h>
#include <sys/termios.h>
#include <sys/ttycom.h>
#include <sys/wait.h>
#include <net/bpf.h>
#include <net/if.h>
#include <net/if_types.h>
#include <net/route.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <netinet/ip_mroute.h>
#include <netinet/if_ether.h>

// Needed since <sys/param.h> refers to it...
#define schedppq 1
'

includes_OpenBSD='
#include <sys/types.h>
#include <sys/param.h>
#include <sys/event.h>
#include <sys/mman.h>
#include <sys/socket.h>
#include <sys/sockio.h>
#include <sys/sysctl.h>
#include <sys/termios.h>
#include <sys/ttycom.h>
#include <sys/wait.h>
#include <net/bpf.h>
#include <net/if.h>
#include <net/if_types.h>
#include <net/if_var.h>
#include <net/route.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <netinet/ip_mroute.h>
#include <netinet/if_ether.h>
#include <net/if_bridge.h>

// We keep some constants not supported in OpenBSD 5.5 and beyond for
// the promise of compatibility.
#define EMUL_ENABLED		0x1
#define EMUL_NATIVE		0x2
#define IPV6_FAITH		0x1d
#define IPV6_OPTIONS		0x1
#define IPV6_RTHDR_STRICT	0x1
#define IPV6_SOCKOPT_RESERVED1	0x3
#define SIOCGIFGENERIC		0xc020693a
#define SIOCSIFGENERIC		0x80206939
#define WALTSIG			0x4
'

includes_SunOS='
#include <limits.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/sockio.h>
#include <sys/mman.h>
#include <sys/wait.h>
#include <sys/ioctl.h>
#include <net/bpf.h>
#include <net/if.h>
#include <net/if_arp.h>
#include <net/if_types.h>
#include <net/route.h>
#include <netinet/in.h>
#include <termios.h>
#include <netinet/ip.h>
#include <netinet/ip_mroute.h>
'

includes='
#include <sys/types.h>
#include <sys/file.h>
#include <fcntl.h>
#include <dirent.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/ip6.h>
#include <netinet/tcp.h>
#include <errno.h>
#include <sys/signal.h>
#include <signal.h>
#include <sys/resource.h>
#include <time.h>
'
ccflags="$@"

# Write go tool cgo -godefs input.
(
	echo package unix
	echo
	echo '/*'
	indirect="includes_$(uname)"
	echo "${!indirect} $includes"
	echo '*/'
	echo 'import "C"'
	echo 'import "syscall"'
	echo
	echo 'const ('

	# The gcc command line prints all the #defines
	# it encounters while processing the input
	echo "${!indirect} $includes" | $CC -x c - -E -dM $ccflags |
	awk '
		$1 != "#define" || $2 ~ /\(/ || $3 == "" {next}

		$2 ~ /^E([ABCD]X|[BIS]P|[SD]I|S|FL)$/ {next}  # 386 registers
		$2 ~ /^(SIGEV_|SIGSTKSZ|SIGRT(MIN|MAX))/ {next}
		$2 ~ /^(SCM_SRCRT)$/ {next}
		$2 ~ /^(MAP_FAILED)$/ {next}
		$2 ~ /^ELF_.*$/ {next}# <asm/elf.h> contains ELF_ARCH, etc.

		$2 ~ /^EXTATTR_NAMESPACE_NAMES/ ||
		$2 ~ /^EXTATTR_NAMESPACE_[A-Z]+_STRING/ {next}

		$2 !~ /^ETH_/ &&
		$2 !~ /^EPROC_/ &&
		$2 !~ /^EQUIV_/ &&
		$2 !~ /^EXPR_/ &&
		$2 ~ /^E[A-Z0-9_]+$/ ||
		$2 ~ /^B[0-9_]+$/ ||
		$2 == "BOTHER" ||
		$2 ~ /^CI?BAUD(EX)?$/ ||
		$2 == "IBSHIFT" ||
		$2 ~ /^V[A-Z0-9]+$/ ||
		$2 ~ /^CS[A-Z0-9]/ ||
		$2 ~ /^I(SIG|CANON|CRNL|UCLC|EXTEN|MAXBEL|STRIP|UTF8)$/ ||
		$2 ~ /^IGN/ ||
		$2 ~ /^IX(ON|ANY|OFF)$/ ||
		$2 ~ /^IN(LCR|PCK)$/ ||
		$2 ~ /(^FLU?SH)|(FLU?SH$)/ ||
		$2 ~ /^C(LOCAL|READ|MSPAR|RTSCTS)$/ ||
		$2 == "BRKINT" ||
		$2 == "HUPCL" ||
		$2 == "PENDIN" ||
		$2 == "TOSTOP" ||
		$2 == "XCASE" ||
		$2 == "ALTWERASE" ||
		$2 == "NOKERNINFO" ||
		$2 ~ /^PAR/ ||
		$2 ~ /^SIG[^_]/ ||
		$2 ~ /^O[CNPFPL][A-Z]+[^_][A-Z]+$/ ||
		$2 ~ /^(NL|CR|TAB|BS|VT|FF)DLY$/ ||
		$2 ~ /^(NL|CR|TAB|BS|VT|FF)[0-9]$/ ||
		$2 ~ /^O?XTABS$/ ||
		$2 ~ /^TC[IO](ON|OFF)$/ ||
		$2 ~ /^IN_/ ||
		$2 ~ /^LOCK_(SH|EX|NB|UN)$/ ||
		$2 ~ /^(AF|SOCK|SO|SOL|IPPROTO|IP|IPV6|ICMP6|TCP|EVFILT|NOTE|EV|SHUT|PROT|MAP|PACKET|MSG|SCM|MCL|DT|MADV|PR)_/ ||
		$2 == "ICMPV6_FILTER" ||
		$2 == "SOMAXCONN" ||
		$2 == "NAME_MAX" ||
		$2 == "IFNAMSIZ" ||
		$2 ~ /^CTL_(MAXNAME|NET|QUERY)$/ ||
		$2 ~ /^SYSCTL_VERS/ ||
		$2 ~ /^(MS|MNT)_/ ||
		$2 ~ /^TUN(SET|GET|ATTACH|DETACH)/ ||
		$2 ~ /^(O|F|FD|NAME|S|PTRACE|PT)_/ ||
		$2 ~ /^LINUX_REBOOT_CMD_/ ||
		$2 ~ /^LINUX_REBOOT_MAGIC[12]$/ ||
		$2 !~ "NLA_TYPE_MASK" &&
		$2 ~ /^(NETLINK|NLM|NLMSG|NLA|IFA|IFAN|RT|RTCF|RTN|RTPROT|RTNH|ARPHRD|ETH_P)_/ ||
		$2 ~ /^SIOC/ ||
		$2 ~ /^TIOC/ ||
		$2 ~ /^TCGET/ ||
		$2 ~ /^TCSET/ ||
		$2 ~ /^TC(FLSH|SBRKP?|XONC)$/ ||
		$2 !~ "RTF_BITS" &&
		$2 ~ /^(IFF|IFT|NET_RT|RTM|RTF|RTV|RTA|RTAX)_/ ||
		$2 ~ /^BIOC/ ||
		$2 ~ /^RUSAGE_(SELF|CHILDREN|THREAD)/ ||
		$2 ~ /^RLIMIT_(AS|CORE|CPU|DATA|FSIZE|NOFILE|STACK)|RLIM_INFINITY/ ||
		$2 ~ /^PRIO_(PROCESS|PGRP|USER)/ ||
		$2 ~ /^CLONE_[A-Z_]+/ ||
		$2 !~ /^(BPF_TIMEVAL)$/ &&
		$2 ~ /^(BPF|DLT)_/ ||
		$2 ~ /^CLOCK_/ ||
		$2 !~ "WMESGLEN" &&
		$2 ~ /^W[A-Z0-9]+$/ {printf("\t%s = C.%s\n", $2, $2)}
		$2 ~ /^__WCOREFLAG$/ {next}
		$2 ~ /^__W[A-Z0-9]+$/ {printf("\t%s = C.%s\n", substr($2,3), $2)}

		{next}
	' | sort

	echo ')'
) >_const.go

# Pull out the error names for later.
errors=$(
	echo '#include <errno.h>' | $CC -x c - -E -dM $ccflags |
	awk '$1=="#define" && $2 ~ /^E[A-Z0-9_]+$/ { print $2 }' |
	sort
)

# Pull out the signal names for later.
signals=$(
	echo '#include <signal.h>' | $CC -x c - -E -dM $ccflags |
	awk '$1=="#define" && $2 ~ /^SIG[A-Z0-9]+$/ { print $2 }' |
	egrep -v '(SIGSTKSIZE|SIGSTKSZ|SIGRT)' |
	sort
)

# Again, writing regexps to a file.
echo '#include <errno.h>' | $CC -x c - -E -dM $ccflags |
	awk '$1=="#define" && $2 ~ /^E[A-Z0-9_]+$/ { print "^\t" $2 "[ \t]*=" }' |
	sort >_error.grep
echo '#include <signal.h>' | $CC -x c - -E -dM $ccflags |
	awk '$1=="#define" && $2 ~ /^SIG[A-Z0-9]+$/ { print "^\t" $2 "[ \t]*=" }' |
	egrep -v '(SIGSTKSIZE|SIGSTKSZ|SIGRT)' |
	sort >_signal.grep

echo '// mkerrors.sh' "$@"
echo '// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT'
echo
echo "// +build ${GOARCH},${GOOS}"
echo
go tool cgo -godefs -- "$@" _const.go >_error.out
cat _error.out | grep -vf _error.grep | grep -vf _signal.grep
echo
echo '// Errors'
echo 'const ('
cat _error.out | grep -f _error.grep | sed 's/=\(.*\)/= syscall.Errno(\1)/'
echo ')'

echo
echo '// Signals'
echo 'const ('
cat _error.out | grep -f _signal.grep | sed 's/=\(.*\)/= syscall.Signal(\1)/'
echo ')'

# Run C program to print error and syscall strings.
(
	echo -E "
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <ctype.h>
#include <string.h>
#include <signal.h>

#define nelem(x) (sizeof(x)/sizeof((x)[0]))

enum { A = 'A', Z = 'Z', a = 'a', z = 'z' }; // avoid need for single quotes below

int errors[] = {
"
	for i in $errors
	do
		echo -E '	'$i,
	done

	echo -E "
};

int signals[] = {
"
	for i in $signals
	do
		echo -E '	'$i,
	done

	# Use -E because on some systems bash builtin interprets \n itself.
	echo -E '
};

static int
intcmp(const void *a, const void *b)
{
	return *(int*)a - *(int*)b;
}

int
main(void)
{
	int i, j, e;
	char buf[1024], *p;

	printf("\n\n// Error table\n");
	printf("var errors = [...]string {\n");
	qsort(errors, nelem(errors), sizeof errors[0], intcmp);
	for(i=0; i<nelem(errors); i++) {
		e = errors[i];
		if(i > 0 && errors[i-1] == e)
			continue;
		strcpy(buf, strerror(e));
		// lowercase first letter: Bad -> bad, but STREAM -> STREAM.
		if(A <= buf[0] && buf[0] <= Z && a <= buf[1] && buf[1] <= z)
			buf[0] += a - A;
		printf("\t%d: \"%s\",\n", e, buf);
	}
	printf("}\n\n");

	printf("\n\n// Signal table\n");
	printf("var signals = [...]string {\n");
	qsort(signals, nelem(signals), sizeof signals[0], intcmp);
	for(i=0; i<nelem(signals); i++) {
		e = signals[i];
		if(i > 0 && signals[i-1] == e)
			continue;
		strcpy(buf, strsignal(e));
		// lowercase first letter: Bad -> bad, but STREAM -> STREAM.
		if(A <= buf[0] && buf[0] <= Z && a <= buf[1] && buf[1] <= z)
			buf[0] += a - A;
		// cut trailing : number.
		p = strrchr(buf, ":"[0]);
		if(p)
			*p = '\0';
		printf("\t%d: \"%s\",\n", e, buf);
	}
	printf("}\n\n");

	return 0;
}

'
) >_errors.c

$CC $ccflags -o _errors _errors.c && $GORUN ./_errors && rm -f _errors.c _errors _const.go _error.grep _signal.grep _error.out


#!/bin/bash

# This script serves as an example to demonstrate how to generate the gRPC-Go
# interface and the related messages from .proto file.
#
# It assumes the installation of i) Google proto buffer compiler at
# https://github.com/google/protobuf (after v2.6.1) and ii) the Go codegen
# plugin at https://github.com/golang/protobuf (after 2015-02-20). If you have
# not, please install them first.
#
# We recommend running this script at $GOPATH/src.
#
# If this is not what you need, feel free to make your own scripts. Again, this
# script is for demonstration purpose.
#
proto=$1
protoc --go_out=plugins=grpc:. $proto


#!/bin/bash

set -e

workdir=.cover
profile="$workdir/cover.out"
mode=set
end2endtest="google.golang.org/grpc/test"

generate_cover_data() {
    rm -rf "$workdir"
    mkdir "$workdir"

    for pkg in "$@"; do
        if [ $pkg == "google.golang.org/grpc" -o $pkg == "google.golang.org/grpc/transport" -o $pkg == "google.golang.org/grpc/metadata" -o $pkg == "google.golang.org/grpc/credentials" ]
            then
                f="$workdir/$(echo $pkg | tr / -)"
                go test -covermode="$mode" -coverprofile="$f.cover" "$pkg"
                go test -covermode="$mode" -coverpkg "$pkg" -coverprofile="$f.e2e.cover" "$end2endtest"
        fi
    done

    echo "mode: $mode" >"$profile"
    grep -h -v "^mode:" "$workdir"/*.cover >>"$profile"
}

show_cover_report() {
    go tool cover -${1}="$profile"
}

push_to_coveralls() {
    goveralls -coverprofile="$profile"
}

generate_cover_data $(go list ./...)
show_cover_report func
case "$1" in
"")
    ;;
--html)
    show_cover_report html ;;
--coveralls)
    push_to_coveralls ;;
*)
    echo >&2 "error: invalid option: $1" ;;
esac
rm -rf "$workdir"


#!/bin/bash
# Copyright 2017 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.
#
# This script generates a file in go with the license contents as a constant

# Set language to C to make sorting consistent among different environments.
export LANG=C

vendor_relative_path="./../../vendor/"

set -e
outputfile=${1?Must provide an output file}
inputfile="$(<../../LICENSE)"

appendRepoLicense() {
  repo=$1

  sanitized_repo="${repo/${vendor_relative_path}/}"
  echo "Adding license for ${sanitized_repo}"
  inputfile+=$'\n'"***"$'\n'"${sanitized_repo}"$'\n\n'
  # Copy LICENSE* files
  for licensefile in $repo/LICENSE*; do
    if [ -f $licensefile ]; then
      inputfile+="$(<$licensefile)"$'\n'
    fi
  done
  # Copy COPYING* file
  if [ -f $repo/COPYING* ]; then
    inputfile+="$(<$repo/COPYING*)"$'\n'
  fi
}

for registry in github.com golang.org; do
  for user in ${vendor_relative_path}$registry/*; do
    for repo in $user/*; do
      if [[ $repo == *"go-buffruneio"* ]]; then
        # nop, since we add this explicitliy
	:
      else
        appendRepoLicense $repo
      fi
    done
  done
done

tr -d '\r' > "${outputfile}" << EOF
// Copyright 2017 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.

// Code generated by licenses.sh. DO NOT EDIT.

package licenses

const License = \`$inputfile\`
EOF


#!/usr/bin/env bash
set -e

cd "$(dirname "$(readlink -f "$BASH_SOURCE")")/.."

# see also ".mailmap" for how email addresses and names are deduplicated

{
	cat <<-'EOH'
	# This file lists all individuals having contributed content to the repository.
	# For how it is generated, see `hack/generate-authors.sh`.
	EOH
	echo
	git log --format='%aN <%aE>' | LC_ALL=C.UTF-8 sort -uf
} > AUTHORS