#!/bin/bash
# SPDX-License-Identifier: GPL-2.0+

# (C) Copyright 2015 Stephen Warren

# This script tests U-Boot's FAT filesystem code's ability to read non-
# contiguous files.

# When porting the ff.c FAT parsing code into U-Boot, it was found that ff.c
# always reads files cluster-by-cluster, which results in poor performance.
# This was solved by adding a patch to ff.c to coalesce reads of adjacent
# clusters. Since this patch needed to correctly handle non-contiguous files,
# this test was written to validate that.
#
# To execute the test, simply run it from the U-Boot source root directory:
#
#    cd u-boot
#    ./test/fs/fat-noncontig-test.sh
#
# The test will create a FAT filesystem image, record the CRC of a randomly
# generated file in the image, build U-Boot sandbox, invoke U-Boot sandbox to
# read the file and validate that the CRCs match. Expected output is shown
# below. The important part of the log is the penultimate line that contains
# either "PASS" or "FAILURE".
#
#    mkfs.fat 3.0.26 (2014-03-07)
#
#
#    U-Boot 2015.10-rc4-00018-g4b22a3e5513f (Oct 03 2015 - 13:49:23 -0600)
#
#    DRAM:  128 MiB
#    Using default environment
#
#    In:    serial
#    Out:   lcd
#    Err:   lcd
#    Net:   No ethernet found.
#    => host bind 0 sandbox/fat-noncontig.img
#    => load host 0:0 1000 noncontig.img
#    33584964 bytes read in 18 ms (1.7 GiB/s)
#    => crc32 1000 $filesize 0
#    crc32 for 00001000 ... 02008743 ==> 6a080523
#    => if itest.l *0 != 2305086a; then echo FAILURE; else echo PASS; fi
#    PASS
#    => reset
#
# All temporary files used by this script are created in ./sandbox to avoid
# polluting the source tree. test/fs/fs-test.sh also uses this directory for
# the same purpose.
#
# TODO: Integrate this (and many other corner-cases e.g. different types of
# FAT) with fs-test.sh so that a single script tests everything filesystem-
# related.

odir=sandbox
img=${odir}/fat-noncontig.img
mnt=${odir}/mnt
fill=/dev/urandom
testfn=noncontig.img
mnttestfn=${mnt}/${testfn}
crcaddr=0
loadaddr=1000

for prereq in fallocate mkfs.fat dd crc32; do
    if [ ! -x "`which $prereq`" ]; then
        echo "Missing $prereq binary. Exiting!"
        exit 1
    fi
done

make O=${odir} -s sandbox_defconfig && make O=${odir} -s -j8

mkdir -p ${mnt}
if [ ! -f ${img} ]; then
    fallocate -l 40M ${img}
    if [ $? -ne 0 ]; then
        echo fallocate failed - using dd instead
        dd if=/dev/zero of=${img} bs=1024 count=$((40 * 1024))
        if [ $? -ne 0 ]; then
            echo Could not create empty disk image
            exit $?
        fi
    fi
    mkfs.fat ${img}
    if [ $? -ne 0 ]; then
        echo Could not create FAT filesystem
        exit $?
    fi

    sudo mount -o loop,uid=$(id -u) ${img} ${mnt}
    if [ $? -ne 0 ]; then
        echo Could not mount test filesystem
        exit $?
    fi

    for ((sects=8; sects < 512; sects += 8)); do
        fn=${mnt}/keep-${sects}.img
        dd if=${fill} of=${fn} bs=512 count=${sects} >/dev/null 2>&1
        fn=${mnt}/remove-${sects}.img
        dd if=${fill} of=${fn} bs=512 count=${sects} >/dev/null 2>&1
    done

    rm -f ${mnt}/remove-*.img

    # 511 deliberately to trigger a file size that's not a multiple of the
    # sector size (ignoring sizes that are multiples of both).
    dd if=${fill} of=${mnttestfn} bs=511 >/dev/null 2>&1

    sudo umount ${mnt}
    if [ $? -ne 0 ]; then
        echo Could not unmount test filesystem
        exit $?
    fi
fi

sudo mount -o ro,loop,uid=$(id -u) ${img} ${mnt}
if [ $? -ne 0 ]; then
    echo Could not mount test filesystem
    exit $?
fi
crc=0x`crc32 ${mnttestfn}`
sudo umount ${mnt}
if [ $? -ne 0 ]; then
    echo Could not unmount test filesystem
    exit $?
fi

crc=`printf %02x%02x%02x%02x \
    $((${crc} & 0xff)) \
    $(((${crc} >> 8) & 0xff)) \
    $(((${crc} >> 16) & 0xff)) \
    $((${crc} >> 24))`

./sandbox/u-boot << EOF
host bind 0 ${img}
load host 0:0 ${loadaddr} ${testfn}
crc32 ${loadaddr} \$filesize ${crcaddr}
if itest.l *${crcaddr} != ${crc}; then echo FAILURE; else echo PASS; fi
reset
EOF
if [ $? -ne 0 ]; then
    echo U-Boot exit status indicates an error
    exit $?
fi


#!/bin/bash
# SPDX-License-Identifier: GPL-2.0+
#
# (C) Copyright 2014 Suriyan Ramasami

# Invoke this test script from U-Boot base directory as ./test/fs/fs-test.sh
# It currently tests the fs/sb and native commands for ext4 and fat partitions
# Expected results are as follows:
# EXT4 tests:
# fs-test.sb.ext4	Summary: PASS: 24 FAIL: 0
# fs-test.nonfs.ext4	Summary: PASS: 24 FAIL: 0
# fs-test.fs.ext4	Summary: PASS: 24 FAIL: 0
# FAT16 tests:
# fs-test.sb.fat16	Summary: PASS: 24 FAIL: 0
# fs-test.nonfs.fat16	Summary: PASS: 24 FAIL: 0
# fs-test.fs.fat16	Summary: PASS: 24 FAIL: 0
# FAT32 tests:
# fs-test.sb.fat32	Summary: PASS: 24 FAIL: 0
# fs-test.nonfs.fat32	Summary: PASS: 24 FAIL: 0
# fs-test.fs.fat32	Summary: PASS: 24 FAIL: 0
# --------------------------------------------
# Total Summary: TOTAL PASS: 216 TOTAL FAIL: 0
# --------------------------------------------

# pre-requisite binaries list.
PREREQ_BINS="md5sum mkfs mount umount dd fallocate mkdir"

# All generated output files from this test will be in $OUT_DIR
# Hence everything is sandboxed.
OUT_DIR="sandbox/test/fs"

# Location of generated sandbox u-boot
UBOOT="./sandbox/u-boot"

# Our mount directory will be in the sandbox
MOUNT_DIR="${OUT_DIR}/mnt"

# The file system image we create will have the $IMG prefix.
IMG="${OUT_DIR}/3GB"

# $SMALL_FILE is the name of the 1MB file in the file system image
SMALL_FILE="1MB.file"

# $BIG_FILE is the name of the 2.5GB file in the file system image
BIG_FILE="2.5GB.file"

# $MD5_FILE will have the expected md5s when we do the test
# They shall have a suffix which represents their file system (ext4/fat16/...)
MD5_FILE="${OUT_DIR}/md5s.list"

# $OUT shall be the prefix of the test output. Their suffix will be .out
OUT="${OUT_DIR}/fs-test"

# Full Path of the 1 MB file that shall be created in the fs image.
MB1="${MOUNT_DIR}/${SMALL_FILE}"
GB2p5="${MOUNT_DIR}/${BIG_FILE}"

# ************************
# * Functions start here *
# ************************

# Check if the prereq binaries exist, or exit
function check_prereq() {
	for prereq in $PREREQ_BINS; do
		if [ ! -x "`which $prereq`" ]; then
			echo "Missing $prereq binary. Exiting!"
			exit
		fi
	done

	# We use /dev/urandom to create files. Check if it exists.
	if [ ! -c /dev/urandom ]; then
		echo "Missing character special /dev/urandom. Exiting!"
		exit
	fi
}

# If 1st param is "clean", then clean out the generated files and exit
function check_clean() {
	if [ "$1" = "clean" ]; then
		rm -rf "$OUT_DIR"
		echo "Cleaned up generated files. Exiting"
		exit
	fi
}

# Generate sandbox U-Boot - gleaned from /test/dm/test-dm.sh
function compile_sandbox() {
	unset CROSS_COMPILE
	NUM_CPUS=$(nproc)
	make O=sandbox sandbox_config
	make O=sandbox -s -j${NUM_CPUS}

	# Check if U-Boot exists
	if [ ! -x "$UBOOT" ]; then
		echo "$UBOOT does not exist or is not executable"
		echo "Build error?"
		echo "Please run this script as ./test/fs/`basename $0`"
		exit
	fi
}

# Clean out all generated files other than the file system images
# We save time by not deleting and recreating the file system images
function prepare_env() {
	rm -f ${MD5_FILE}.* ${OUT}.*
	mkdir -p ${OUT_DIR}
}

# 1st parameter is the name of the image file to be created
# 2nd parameter is the filesystem - fat16 ext4 etc
# -F cant be used with fat as it means something else.
function create_image() {
	# Create image if not already present - saves time, while debugging
	case "$2" in
		fat16)
		MKFS_OPTION="-F 16"
		FS_TYPE="fat"
		;;
		fat32)
		MKFS_OPTION="-F 32"
		FS_TYPE="fat"
		;;
		ext4)
		MKFS_OPTION="-F"
		FS_TYPE="ext4"
		;;
	esac

	if [ ! -f "$1" ]; then
		fallocate -l 3G "$1" &> /dev/null
		if [ $? -ne 0 ]; then
			echo fallocate failed - using dd instead
			dd if=/dev/zero of=$1 bs=1024 count=$((3 * 1024 * 1024))
			if [ $? -ne 0 ]; then
				echo Could not create empty disk image
				exit $?
			fi
		fi
		mkfs -t "$FS_TYPE" $MKFS_OPTION "$1" &> /dev/null
		if [ $? -ne 0 -a "$FS_TYPE" = "fat" ]; then
			# If we fail and we did fat, try vfat.
			mkfs -t vfat $MKFS_OPTION "$1" &> /dev/null
		fi
		if [ $? -ne 0 ]; then
			echo Could not create filesystem
			exit $?
		fi
	fi
}

# 1st parameter is image file
# 2nd parameter is file system type - fat16/ext4/...
# 3rd parameter is name of small file
# 4th parameter is name of big file
# 5th parameter is fs/nonfs/sb - to dictate generic fs commands or
# otherwise or sb hostfs
# 6th parameter is the directory path for the files. Its "" for generic
# fs and ext4/fat and full patch for sb hostfs
# UBOOT is set in env
function test_image() {
	addr="0x01000008"
	length="0x00100000"

	case "$2" in
		fat*)
		FPATH=""
		PREFIX="fat"
		WRITE="write"
		;;

		ext4)
		# ext4 needs absolute path
		FPATH="/"
		PREFIX="ext4"
		WRITE="write"
		;;

		*)
		echo "Unhandled filesystem $2. Exiting!"
		exit
		;;
	esac

	case "$5" in
		fs)
		PREFIX=""
		WRITE="save"
		SUFFIX=" 0:0"
		;;

		nonfs)
		SUFFIX=" 0:0"
		;;

		sb)
		PREFIX="host "
		WRITE="save"
		SUFFIX="fs -"
		;;

		*)
		echo "Unhandled mode $5. Exiting!"
		exit
		;;

	esac

	# sb always uses full path to mointpoint, irrespective of filesystem
	if [ "$5" = "sb" ]; then
		FPATH=${6}/
	fi

	FILE_WRITE=${3}.w
	FILE_SMALL=$3
	FILE_BIG=$4

	# In u-boot commands, <interface> stands for host or hostfs
	# hostfs maps to the host fs.
	# host maps to the "host bind" that we do

	$UBOOT << EOF
sb=$5
setenv bind 'if test "\$sb" != sb; then host bind 0 "$1"; fi'
run bind
# Test Case 1 - ls
${PREFIX}ls host${SUFFIX} $6
# In addition, test with a nonexistent directory to see if we crash.
${PREFIX}ls host${SUFFIX} invalid_d
#
# We want ${PREFIX}size host 0:0 $3 for host commands and
# host size hostfs - $3 for hostfs commands.
# 1MB is 0x0010 0000
# Test Case 2a - size of small file
${PREFIX}size host${SUFFIX} ${FPATH}$FILE_SMALL
printenv filesize
setenv filesize
# Test Case 2b - size of small file via a path using '..'
${PREFIX}size host${SUFFIX} ${FPATH}SUBDIR/../$FILE_SMALL
printenv filesize
setenv filesize

# 2.5GB (1024*1024*2500) is 0x9C40 0000
# Test Case 3 - size of big file
${PREFIX}size host${SUFFIX} ${FPATH}$FILE_BIG
printenv filesize
setenv filesize

# Notes about load operation
# If I use 0x01000000 I get DMA misaligned error message
# Last two parameters are size and offset.

# Test Case 4a - Read full 1MB of small file
${PREFIX}load host${SUFFIX} $addr ${FPATH}$FILE_SMALL
printenv filesize
# Test Case 4b - Read full 1MB of small file
md5sum $addr \$filesize
setenv filesize

# Test Case 5a - First 1MB of big file
${PREFIX}load host${SUFFIX} $addr ${FPATH}$FILE_BIG $length 0x0
printenv filesize
# Test Case 5b - First 1MB of big file
md5sum $addr \$filesize
setenv filesize

# fails for ext as no offset support
# Test Case 6a - Last 1MB of big file
${PREFIX}load host${SUFFIX} $addr ${FPATH}$FILE_BIG $length 0x9C300000
printenv filesize
# Test Case 6b - Last 1MB of big file
md5sum $addr \$filesize
setenv filesize

# fails for ext as no offset support
# Test Case 7a - One from the last 1MB chunk of 2GB
${PREFIX}load host${SUFFIX} $addr ${FPATH}$FILE_BIG $length 0x7FF00000
printenv filesize
# Test Case 7b - One from the last 1MB chunk of 2GB
md5sum $addr \$filesize
setenv filesize

# fails for ext as no offset support
# Test Case 8a - One from the start 1MB chunk from 2GB
${PREFIX}load host${SUFFIX} $addr ${FPATH}$FILE_BIG $length 0x80000000
printenv filesize
# Test Case 8b - One from the start 1MB chunk from 2GB
md5sum $addr \$filesize
setenv filesize

# fails for ext as no offset support
# Test Case 9a - One 1MB chunk crossing the 2GB boundary
${PREFIX}load host${SUFFIX} $addr ${FPATH}$FILE_BIG $length 0x7FF80000
printenv filesize
# Test Case 9b - One 1MB chunk crossing the 2GB boundary
md5sum $addr \$filesize
setenv filesize

# Generic failure case
# Test Case 10 - 2MB chunk from the last 1MB of big file
${PREFIX}load host${SUFFIX} $addr ${FPATH}$FILE_BIG 0x00200000 0x9C300000
printenv filesize
#

# Read 1MB from small file
${PREFIX}load host${SUFFIX} $addr ${FPATH}$FILE_SMALL
# Write it back to test the writes
# Test Case 11a - Check that the write succeeded
${PREFIX}${WRITE} host${SUFFIX} $addr ${FPATH}$FILE_WRITE \$filesize
mw.b $addr 00 100
${PREFIX}load host${SUFFIX} $addr ${FPATH}$FILE_WRITE
# Test Case 11b - Check md5 of written to is same as the one read from
md5sum $addr \$filesize
setenv filesize
#

# Next test case checks writing a file whose dirent
# is the first in the block, which is always true for "."
# The write should fail, but the lookup should work
# Test Case 12 - Check directory traversal
${PREFIX}${WRITE} host${SUFFIX} $addr ${FPATH}. 0x10

# Read 1MB from small file
${PREFIX}load host${SUFFIX} $addr ${FPATH}$FILE_SMALL
# Write it via "same directory", i.e. "." dirent
# Test Case 13a - Check directory traversal
${PREFIX}${WRITE} host${SUFFIX} $addr ${FPATH}./${FILE_WRITE}2 \$filesize
mw.b $addr 00 100
${PREFIX}load host${SUFFIX} $addr ${FPATH}./${FILE_WRITE}2
# Test Case 13b - Check md5 of written to is same as the one read from
md5sum $addr \$filesize
setenv filesize
mw.b $addr 00 100
${PREFIX}load host${SUFFIX} $addr ${FPATH}${FILE_WRITE}2
# Test Case 13c - Check md5 of written to is same as the one read from
md5sum $addr \$filesize
setenv filesize
#
reset

EOF
}

# 1st argument is the name of the image file.
# 2nd argument is the file where we generate the md5s of the files
# generated with the appropriate start and length that we use to test.
# It creates the necessary files in the image to test.
# $GB2p5 is the path of the big file (2.5 GB)
# $MB1 is the path of the small file (1 MB)
# $MOUNT_DIR is the path we can use to mount the image file.
function create_files() {
	# Mount the image so we can populate it.
	mkdir -p "$MOUNT_DIR"
	sudo mount -o loop,rw "$1" "$MOUNT_DIR"

	# Create a subdirectory.
	sudo mkdir -p "$MOUNT_DIR/SUBDIR"

	# Create big file in this image.
	# Note that we work only on the start 1MB, couple MBs in the 2GB range
	# and the last 1 MB of the huge 2.5GB file.
	# So, just put random values only in those areas.
	if [ ! -f "${GB2p5}" ]; then
		sudo dd if=/dev/urandom of="${GB2p5}" bs=1M count=1 \
			&> /dev/null
		sudo dd if=/dev/urandom of="${GB2p5}" bs=1M count=2 seek=2047 \
			&> /dev/null
		sudo dd if=/dev/urandom of="${GB2p5}" bs=1M count=1 seek=2499 \
			&> /dev/null
	fi

	# Create a small file in this image.
	if [ ! -f "${MB1}" ]; then
		sudo dd if=/dev/urandom of="${MB1}" bs=1M count=1 \
			&> /dev/null
	fi

	# Delete the small file copies which possibly are written as part of a
	# previous test.
	sudo rm -f "${MB1}.w"
	sudo rm -f "${MB1}.w2"

	# Generate the md5sums of reads that we will test against small file
	dd if="${MB1}" bs=1M skip=0 count=1 2> /dev/null | md5sum > "$2"

	# Generate the md5sums of reads that we will test against big file
	# One from beginning of file.
	dd if="${GB2p5}" bs=1M skip=0 count=1 \
		2> /dev/null | md5sum >> "$2"

	# One from end of file.
	dd if="${GB2p5}" bs=1M skip=2499 count=1 \
		2> /dev/null | md5sum >> "$2"

	# One from the last 1MB chunk of 2GB
	dd if="${GB2p5}" bs=1M skip=2047 count=1 \
		2> /dev/null | md5sum >> "$2"

	# One from the start 1MB chunk from 2GB
	dd if="${GB2p5}" bs=1M skip=2048 count=1 \
		2> /dev/null | md5sum >> "$2"

	# One 1MB chunk crossing the 2GB boundary
	dd if="${GB2p5}" bs=512K skip=4095 count=2 \
		2> /dev/null | md5sum >> "$2"

	sync
	sudo umount "$MOUNT_DIR"
	rmdir "$MOUNT_DIR"
}

# 1st parameter is the text to print
# if $? is 0 its a pass, else a fail
# As a side effect it shall update env variable PASS and FAIL
function pass_fail() {
	if [ $? -eq 0 ]; then
		echo pass - "$1"
		PASS=$((PASS + 1))
	else
		echo FAIL - "$1"
		FAIL=$((FAIL + 1))
	fi
}

# 1st parameter is the string which leads to an md5 generation
# 2nd parameter is the file we grep, for that string
# 3rd parameter is the name of the file which has md5s in it
# 4th parameter is the line # in the md5 file that we match it against
# This function checks if the md5 of the file in the sandbox matches
# that calculated while generating the file
# 5th parameter is the string to print with the result
check_md5() {
	# md5sum in u-boot has output of form:
	# md5 for 01000008 ... 01100007 ==> <md5>
	# the 7th field is the actual md5
	md5_src=`grep -A2 "$1" "$2" | grep "md5 for" | tr -d '\r'`
	md5_src=($md5_src)
	md5_src=${md5_src[6]}

	# The md5 list, each line is of the form:
	# - <md5>
	# the 2nd field is the actual md5
	md5_dst=`sed -n $4p $3`
	md5_dst=($md5_dst)
	md5_dst=${md5_dst[0]}

	# For a pass they should match.
	[ "$md5_src" = "$md5_dst" ]
	pass_fail "$5"
}

# 1st parameter is the name of the output file to check
# 2nd parameter is the name of the file containing the md5 expected
# 3rd parameter is the name of the small file
# 4th parameter is the name of the big file
# 5th paramter is the name of the written file
# This function checks the output file for correct results.
function check_results() {
	echo "** Start $1"

	PASS=0
	FAIL=0

	# Check if the ls is showing correct results for 2.5 gb file
	grep -A7 "Test Case 1 " "$1" | egrep -iq "2621440000 *$4"
	pass_fail "TC1: ls of $4"

	# Check if the ls is showing correct results for 1 mb file
	grep -A7 "Test Case 1 " "$1" | egrep -iq "1048576 *$3"
	pass_fail "TC1: ls of $3"

	# Check size command on 1MB.file
	egrep -A3 "Test Case 2a " "$1" | grep -q "filesize=100000"
	pass_fail "TC2: size of $3"
	# Check size command on 1MB.file via a path using '..'
	egrep -A3 "Test Case 2b " "$1" | grep -q "filesize=100000"
	pass_fail "TC2: size of $3 via a path using '..'"

	# Check size command on 2.5GB.file
	egrep -A3 "Test Case 3 " "$1" | grep -q "filesize=9c400000"
	pass_fail "TC3: size of $4"

	# Check read full mb of 1MB.file
	grep -A4 "Test Case 4a " "$1" | grep -q "filesize=100000"
	pass_fail "TC4: load of $3 size"
	check_md5 "Test Case 4b " "$1" "$2" 1 "TC4: load from $3"

	# Check first mb of 2.5GB.file
	grep -A4 "Test Case 5a " "$1" | grep -q "filesize=100000"
	pass_fail "TC5: load of 1st MB from $4 size"
	check_md5 "Test Case 5b " "$1" "$2" 2 "TC5: load of 1st MB from $4"

	# Check last mb of 2.5GB.file
	grep -A4 "Test Case 6a " "$1" | grep -q "filesize=100000"
	pass_fail "TC6: load of last MB from $4 size"
	check_md5 "Test Case 6b " "$1" "$2" 3 "TC6: load of last MB from $4"

	# Check last 1mb chunk of 2gb from 2.5GB file
	grep -A4 "Test Case 7a " "$1" | grep -q "filesize=100000"
	pass_fail "TC7: load of last 1mb chunk of 2GB from $4 size"
	check_md5 "Test Case 7b " "$1" "$2" 4 \
		"TC7: load of last 1mb chunk of 2GB from $4"

	# Check first 1mb chunk after 2gb from 2.5GB file
	grep -A4 "Test Case 8a " "$1" | grep -q "filesize=100000"
	pass_fail "TC8: load 1st MB chunk after 2GB from $4 size"
	check_md5 "Test Case 8b " "$1" "$2" 5 \
		"TC8: load 1st MB chunk after 2GB from $4"

	# Check 1mb chunk crossing the 2gb boundary from 2.5GB file
	grep -A4 "Test Case 9a " "$1" | grep -q "filesize=100000"
	pass_fail "TC9: load 1MB chunk crossing 2GB boundary from $4 size"
	check_md5 "Test Case 9b " "$1" "$2" 6 \
		"TC9: load 1MB chunk crossing 2GB boundary from $4"

	# Check 2mb chunk from the last 1MB of 2.5GB file loads 1MB
	grep -A5 "Test Case 10 " "$1" | grep -q "filesize=100000"
	pass_fail "TC10: load 2MB from the last 1MB of $4 loads 1MB"

	# Check 1mb chunk write
	grep -A2 "Test Case 11a " "$1" | grep -q '1048576 bytes written'
	pass_fail "TC11: 1MB write to $3.w - write succeeded"
	check_md5 "Test Case 11b " "$1" "$2" 1 \
		"TC11: 1MB write to $3.w - content verified"

	# Check lookup of 'dot' directory
	grep -A4 "Test Case 12 " "$1" | grep -q 'Unable to write'
	pass_fail "TC12: 1MB write to . - write denied"

	# Check directory traversal
	grep -A2 "Test Case 13a " "$1" | grep -q '1048576 bytes written'
	pass_fail "TC13: 1MB write to ./$3.w2 - write succeeded"
	check_md5 "Test Case 13b " "$1" "$2" 1 \
		"TC13: 1MB read from ./$3.w2 - content verified"
	check_md5 "Test Case 13c " "$1" "$2" 1 \
		"TC13: 1MB read from $3.w2 - content verified"

	echo "** End $1"
}

# Takes in one parameter which is "fs" or "nonfs", which then dictates
# if a fs test (size/load/save) or a nonfs test (fatread/extread) needs to
# be performed.
function test_fs_nonfs() {
	echo "Creating files in $fs image if not already present."
	create_files $IMAGE $MD5_FILE_FS

	OUT_FILE="${OUT}.$1.${fs}.out"
	test_image $IMAGE $fs $SMALL_FILE $BIG_FILE $1 "" \
		> ${OUT_FILE} 2>&1
	# strip out noise from fs code
	grep -v -e "File System is consistent\|update journal finished" \
		-e "reading .*\.file\|writing .*\.file.w" \
		< ${OUT_FILE} > ${OUT_FILE}_clean
	check_results ${OUT_FILE}_clean $MD5_FILE_FS $SMALL_FILE \
		$BIG_FILE
	TOTAL_FAIL=$((TOTAL_FAIL + FAIL))
	TOTAL_PASS=$((TOTAL_PASS + PASS))
	echo "Summary: PASS: $PASS FAIL: $FAIL"
	echo "--------------------------------------------"
}

# ********************
# * End of functions *
# ********************

check_clean "$1"
check_prereq
compile_sandbox
prepare_env

# Track TOTAL_FAIL and TOTAL_PASS
TOTAL_FAIL=0
TOTAL_PASS=0

# In each loop, for a given file system image, we test both the
# fs command, like load/size/write, the file system specific command
# like: ext4load/ext4size/ext4write and the host load/ls/save commands.
for fs in ext4 fat16 fat32; do

	echo "Creating $fs image if not already present."
	IMAGE=${IMG}.${fs}.img
	MD5_FILE_FS="${MD5_FILE}.${fs}"
	create_image $IMAGE $fs

	# host commands test
	echo "Creating files in $fs image if not already present."
	create_files $IMAGE $MD5_FILE_FS

	# Lets mount the image and test host hostfs commands
	mkdir -p "$MOUNT_DIR"
	case "$fs" in
		fat*)
		uid="uid=`id -u`"
		;;
		*)
		uid=""
		;;
	esac
	sudo mount -o loop,rw,$uid "$IMAGE" "$MOUNT_DIR"
	sudo chmod 777 "$MOUNT_DIR"

	OUT_FILE="${OUT}.sb.${fs}.out"
	test_image $IMAGE $fs $SMALL_FILE $BIG_FILE sb `pwd`/$MOUNT_DIR \
		> ${OUT_FILE} 2>&1
	sudo umount "$MOUNT_DIR"
	rmdir "$MOUNT_DIR"

	check_results $OUT_FILE $MD5_FILE_FS $SMALL_FILE $BIG_FILE
	TOTAL_FAIL=$((TOTAL_FAIL + FAIL))
	TOTAL_PASS=$((TOTAL_PASS + PASS))
	echo "Summary: PASS: $PASS FAIL: $FAIL"
	echo "--------------------------------------------"

	test_fs_nonfs nonfs
	test_fs_nonfs fs
done

echo "Total Summary: TOTAL PASS: $TOTAL_PASS TOTAL FAIL: $TOTAL_FAIL"
echo "--------------------------------------------"
if [ $TOTAL_FAIL -eq 0 ]; then
	echo "PASSED"
	exit 0
else
	echo "FAILED"
	exit 1
fi


#!/bin/bash
# SPDX-License-Identifier: GPL-2.0+
#
# Written by Guilherme Maciel Ferreira <guilherme.maciel.ferreira@gmail.com>
#
# Sanity check for mkimage and dumpimage tools
#
# To run this:
#
# make O=sandbox sandbox_config
# make O=sandbox
# ./test/image/test-imagetools.sh

BASEDIR=sandbox
SRCDIR=${BASEDIR}/boot
IMAGE_NAME="v1.0-test"
IMAGE_MULTI=linux.img
IMAGE_FIT_ITS=linux.its
IMAGE_FIT_ITB=linux.itb
DATAFILE0=vmlinuz
DATAFILE1=initrd.img
DATAFILE2=System.map
DATAFILES="${DATAFILE0} ${DATAFILE1} ${DATAFILE2}"
TEST_OUT=test_output
MKIMAGE=${BASEDIR}/tools/mkimage
DUMPIMAGE=${BASEDIR}/tools/dumpimage
MKIMAGE_LIST=mkimage.list
DUMPIMAGE_LIST=dumpimage.list

# Remove all the files we created
cleanup()
{
	local file

	for file in ${DATAFILES}; do
		rm -f ${file} ${SRCDIR}/${file}
	done
	rm -f ${IMAGE_MULTI}
	rm -f ${DUMPIMAGE_LIST}
	rm -f ${MKIMAGE_LIST}
	rm -f ${TEST_OUT}
	rmdir ${SRCDIR}
}

# Check that two files are the same
assert_equal()
{
	if ! diff -u $1 $2; then
		echo "Failed."
		cleanup
		exit 1
	fi
}

# Create some test files
create_files()
{
	local file

	mkdir -p ${SRCDIR}
	for file in ${DATAFILES}; do
		head -c $RANDOM /dev/urandom >${SRCDIR}/${file}
	done
}

# Run a command, echoing it first
do_cmd()
{
	local cmd="$@"

	echo "# ${cmd}"
	${cmd} 2>&1
}

# Run a command, redirecting output
# Args:
#    redirect_file
#    command...
do_cmd_redir()
{
	local redir="$1"
	shift
	local cmd="$@"

	echo "# ${cmd}"
	${cmd} >${redir}
}

# Write files into an multi-file image
create_multi_image()
{
	local files="${SRCDIR}/${DATAFILE0}:${SRCDIR}/${DATAFILE1}"
	files+=":${SRCDIR}/${DATAFILE2}"

	echo -e "\nBuilding multi-file image..."
	do_cmd ${MKIMAGE} -A x86 -O linux -T multi -n \"${IMAGE_NAME}\" \
		-d ${files} ${IMAGE_MULTI}
	echo "done."
}

# Extract files from an multi-file image
extract_multi_image()
{
	echo -e "\nExtracting multi-file image contents..."
	do_cmd ${DUMPIMAGE} -T multi -p 0 -o ${DATAFILE0} ${IMAGE_MULTI}
	do_cmd ${DUMPIMAGE} -T multi -p 1 -o ${DATAFILE1} ${IMAGE_MULTI}
	do_cmd ${DUMPIMAGE} -T multi -p 2 -o ${DATAFILE2} ${IMAGE_MULTI}
	do_cmd ${DUMPIMAGE} -T multi -p 2 -o ${TEST_OUT} ${IMAGE_MULTI}
	echo "done."
}

# Write files into a FIT image
create_fit_image()
{
	echo " \
	/dts-v1/; \
	/ { \
	    description = \"FIT image\"; \
	    #address-cells = <1>; \
	\
	    images { \
	        kernel@1 { \
	            description = \"kernel\"; \
	            data = /incbin/(\"${DATAFILE0}\"); \
	            type = \"kernel\"; \
	            arch = \"sandbox\"; \
	            os = \"linux\"; \
	            compression = \"gzip\"; \
	            load = <0x40000>; \
	            entry = <0x8>; \
	        }; \
	        ramdisk@1 { \
	            description = \"filesystem\"; \
	            data = /incbin/(\"${DATAFILE1}\"); \
	            type = \"ramdisk\"; \
	            arch = \"sandbox\"; \
	            os = \"linux\"; \
	            compression = \"none\"; \
	            load = <0x80000>; \
	            entry = <0x16>; \
	        }; \
	        fdt@1 { \
	            description = \"device tree\"; \
	            data = /incbin/(\"${DATAFILE2}\"); \
	            type = \"flat_dt\"; \
	            arch = \"sandbox\"; \
	            compression = \"none\"; \
	        }; \
	    }; \
	    configurations { \
	        default = \"conf@1\"; \
	        conf@1 { \
	            kernel = \"kernel@1\"; \
	            fdt = \"fdt@1\"; \
	        }; \
	    }; \
	}; \
	" > ${IMAGE_FIT_ITS}

	echo -e "\nBuilding FIT image..."
	do_cmd ${MKIMAGE} -f ${IMAGE_FIT_ITS} ${IMAGE_FIT_ITB}
	echo "done."
}

# Extract files from a FIT image
extract_fit_image()
{
	echo -e "\nExtracting FIT image contents..."
	do_cmd ${DUMPIMAGE} -T flat_dt -p 0 -o ${DATAFILE0} ${IMAGE_FIT_ITB}
	do_cmd ${DUMPIMAGE} -T flat_dt -p 1 -o ${DATAFILE1} ${IMAGE_FIT_ITB}
	do_cmd ${DUMPIMAGE} -T flat_dt -p 2 -o ${DATAFILE2} ${IMAGE_FIT_ITB}
	do_cmd ${DUMPIMAGE} -T flat_dt -p 2 -o ${TEST_OUT} ${IMAGE_FIT_ITB}
	echo "done."
}

# List the contents of a file
# Args:
#    image filename
list_image()
{
	local image="$1"

	echo -e "\nListing image contents..."
	do_cmd_redir ${MKIMAGE_LIST} ${MKIMAGE} -l ${image}
	do_cmd_redir ${DUMPIMAGE_LIST} ${DUMPIMAGE} -l ${image}
	echo "done."
}

main()
{
	local file

	create_files

	# Compress and extract multi-file images, compare the result
	create_multi_image
	extract_multi_image
	for file in ${DATAFILES}; do
		assert_equal ${file} ${SRCDIR}/${file}
	done
	assert_equal ${TEST_OUT} ${DATAFILE2}

	# List contents of multi-file image and compares output from tools
	list_image ${IMAGE_MULTI}
	assert_equal ${DUMPIMAGE_LIST} ${MKIMAGE_LIST}

	# Compress and extract FIT images, compare the result
	create_fit_image
	extract_fit_image
	for file in ${DATAFILES}; do
		assert_equal ${file} ${SRCDIR}/${file}
	done
	assert_equal ${TEST_OUT} ${DATAFILE2}

	# List contents of FIT image and compares output from tools
	list_image ${IMAGE_FIT_ITB}
	assert_equal ${DUMPIMAGE_LIST} ${MKIMAGE_LIST}

	# Remove files created
	cleanup

	echo "Tests passed."
}

main


#!/bin/bash

# Test script to check uintptr_t and 64-bit types for warnings
#
# It builds a few boards with different toolchains. If there are no warnings
# then all is well.
#
# Usage:
#
# Make sure that your toolchains are correct at the bottom of this file
#
# Then:
#	./test/stdint/test-includes.sh

out=/tmp/test-includes.tmp

try_test() {
	local board=$1
	local arch=$2
	local soc=$3
	local gcc=$4
	local flags="$5"

	echo $@
	if ! which ${gcc} >/dev/null 2>&1; then
		echo "Not found: ${gcc}"
		return
	fi

	rm -rf ${out}
	mkdir -p ${out}
	touch ${out}/config.h
	mkdir -p ${out}/generated
	touch ${out}/generated/generic-asm-offsets.h
	mkdir -p ${out}/include/asm
	ln -s $(pwd)/arch/${arch}/include/asm/arch-${soc} \
			${out}/include/asm/arch

	cmd="${gcc} -c -D__KERNEL__ ${flags} \
		-fno-builtin -ffreestanding \
		-Iarch/${arch}/include \
		-Iinclude \
		-I${out} -I${out}/include \
		-include configs/${board}.h test/stdint/int-types.c \
		-o /dev/null"
	$cmd
}

try_both() {
	try_test $@
}

# board arch soc path-to-gcc
try_both sandbox sandbox - gcc
try_both coreboot x86 - x86_64-linux-gnu-gcc
try_both seaboard arm tegra20 /opt/linaro/gcc-linaro-arm-linux-gnueabihf-4.8-2013.08_linux/bin/arm-linux-gnueabihf-gcc


#!/bin/bash
# SPDX-License-Identifier: GPL-2.0+
# Copyright (c) 2013 The Chromium OS Authors.
#

# Simple test script for tracing with sandbox

TRACE_OPT="FTRACE=1"

BASE="$(dirname $0)/.."
. $BASE/common.sh

run_trace() {
	echo "Run trace"
	./${OUTPUT_DIR}/u-boot <<END
trace stats
hash sha256 0 10000
trace pause
trace stats
hash sha256 0 10000
trace stats
trace resume
hash sha256 0 10000
trace pause
trace stats
reset
END
}

check_results() {
	echo "Check results"

	# Expect sha256 to run 3 times, so we see the string 6 times
	if [ $(grep -c sha256 ${tmp}) -ne 6 ]; then
		fail "sha256 error"
	fi

	# 4 sets of results (output of 'trace stats')
	if [ $(grep -c "traced function calls" ${tmp}) -ne 4 ]; then
		fail "trace output error"
	fi

	# Check trace counts. We expect to see an increase in the number of
	# traced function calls between each 'trace stats' command, except
	# between calls 2 and 3, where tracing is paused.
	# This code gets the sign of the difference between each number and
	# its predecessor.
	counts="$(tr -d ',\r' <${tmp} | awk \
		'/traced function calls/ { diff = $1 - upto; upto = $1; \
		printf "%d ", diff < 0 ? -1 : (diff > 0 ? 1 : 0)}')"

	if [ "${counts}" != "1 1 0 1 " ]; then
		fail "trace collection error: ${counts}"
	fi
}

echo "Simple trace test / sanity check using sandbox"
echo
tmp="$(tempfile)"
build_uboot "${TRACE_OPT}"
run_trace >${tmp}
check_results ${tmp}
rm ${tmp}
echo "Test passed"


#!/bin/sh
# SPDX-License-Identifier: GPL-2.0+
#
# script to check whether the file exists in imximage.cfg for i.MX8M
#

file=$1

post_process=$2

blobs=`awk '/^SIGNED_HDMI/ {print $2} /^LOADER/ {print $2} /^SECOND_LOADER/ {print $2} /^DDR_FW/ {print $2}' $file`
for f in $blobs; do
	if [ $f = "spl/u-boot-spl-ddr.bin" ] || [ $f = "u-boot.itb" ]; then
		continue
	fi

	if [ ! -f $f ]; then
		echo "WARNING '$f' not found, resulting binary is not-functional" >&2
		exit 1
	fi
done

if [ $post_process = 1 ]; then
	if [ -f lpddr4_pmu_train_1d_imem.bin ]; then
		objcopy -I binary -O binary --pad-to 0x8000 --gap-fill=0x0 lpddr4_pmu_train_1d_imem.bin lpddr4_pmu_train_1d_imem_pad.bin
		objcopy -I binary -O binary --pad-to 0x4000 --gap-fill=0x0 lpddr4_pmu_train_1d_dmem.bin lpddr4_pmu_train_1d_dmem_pad.bin
		objcopy -I binary -O binary --pad-to 0x8000 --gap-fill=0x0 lpddr4_pmu_train_2d_imem.bin lpddr4_pmu_train_2d_imem_pad.bin
		cat lpddr4_pmu_train_1d_imem_pad.bin lpddr4_pmu_train_1d_dmem_pad.bin > lpddr4_pmu_train_1d_fw.bin
		cat lpddr4_pmu_train_2d_imem_pad.bin lpddr4_pmu_train_2d_dmem.bin > lpddr4_pmu_train_2d_fw.bin
		dd if=spl/u-boot-spl.bin of=spl/u-boot-spl-pad.bin bs=4 conv=sync
		cat spl/u-boot-spl-pad.bin lpddr4_pmu_train_1d_fw.bin lpddr4_pmu_train_2d_fw.bin > spl/u-boot-spl-ddr.bin
		rm -f lpddr4_pmu_train_1d_fw.bin lpddr4_pmu_train_2d_fw.bin lpddr4_pmu_train_1d_imem_pad.bin lpddr4_pmu_train_1d_dmem_pad.bin lpddr4_pmu_train_2d_imem_pad.bin spl/u-boot-spl-pad.bin
	fi
	if [ -f ddr4_imem_1d.bin ]; then
		objcopy -I binary -O binary --pad-to 0x8000 --gap-fill=0x0 ddr4_imem_1d.bin ddr4_imem_1d_pad.bin
		objcopy -I binary -O binary --pad-to 0x4000 --gap-fill=0x0 ddr4_dmem_1d.bin ddr4_dmem_1d_pad.bin
		objcopy -I binary -O binary --pad-to 0x8000 --gap-fill=0x0 ddr4_imem_2d.bin ddr4_imem_2d_pad.bin
		cat ddr4_imem_1d_pad.bin ddr4_dmem_1d_pad.bin > ddr4_1d_fw.bin
		cat ddr4_imem_2d_pad.bin ddr4_dmem_2d.bin > ddr4_2d_fw.bin
		dd if=spl/u-boot-spl.bin of=spl/u-boot-spl-pad.bin bs=4 conv=sync
		cat spl/u-boot-spl-pad.bin ddr4_1d_fw.bin ddr4_2d_fw.bin > spl/u-boot-spl-ddr.bin
		rm -f ddr4_1d_fw.bin ddr4_2d_fw.bin ddr4_imem_1d_pad.bin ddr4_dmem_1d_pad.bin ddr4_imem_2d_pad.bin spl/u-boot-spl-pad.bin
	fi
fi

exit 0


#!/bin/sh
# SPDX-License-Identifier: GPL-2.0+
#
# script to check whether the file exists in imximage.cfg for i.MX8
#
# usage: $0 <imximage.cfg>

file=$1

blobs=`awk '/^APPEND/ {print $2} /^IMAGE/ || /^DATA/ {print $3}' $file`
for f in $blobs; do
	tmp=$srctree/$f
	if [ $f = "u-boot-dtb.bin" ]; then
		continue
	fi

	if [ -f $f ]; then
		continue
	fi

	if [ ! -f $tmp ]; then
		echo "WARNING '$tmp' not found, resulting binary is not-functional" >&2
		exit 1
	fi

	sed -in "s;$f;$tmp;" $file
done

exit 0


#!/bin/sh
# SPDX-License-Identifier: GPL-2.0+
#
# script to generate FIT image source for K3 Family boards with
# ATF, OPTEE, SPL and multiple device trees (given on the command line).
# Inspired from board/sunxi/mksunxi_fit_atf.sh
#
# usage: $0 <atf_load_addr> <dt_name> [<dt_name> [<dt_name] ...]

[ -z "$ATF" ] && ATF="bl31.bin"

if [ ! -f $ATF ]; then
	echo "WARNING ATF file $ATF NOT found, resulting binary is non-functional" >&2
	ATF=/dev/null
fi

[ -z "$TEE" ] && TEE="bl32.bin"

if [ ! -f $TEE ]; then
	echo "WARNING OPTEE file $TEE NOT found, resulting might be non-functional" >&2
	TEE=/dev/null
fi

[ -z "$DM" ] && DM="dm.bin"

if [ ! -e $DM ]; then
	echo "WARNING DM file $DM NOT found, resulting might be non-functional" >&2
	DM=/dev/null
fi

if [ ! -z "$IS_HS" ]; then
	HS_APPEND=_HS
fi

cat << __HEADER_EOF
/dts-v1/;

/ {
	description = "Configuration to load ATF and SPL";
	#address-cells = <1>;

	images {
		atf {
			description = "ARM Trusted Firmware";
			data = /incbin/("$ATF");
			type = "firmware";
			arch = "arm64";
			compression = "none";
			os = "arm-trusted-firmware";
			load = <$1>;
			entry = <$1>;
		};
		tee {
			description = "OPTEE";
			data = /incbin/("$TEE");
			type = "tee";
			arch = "arm64";
			compression = "none";
			os = "tee";
			load = <0x9e800000>;
			entry = <0x9e800000>;
		};
		dm {
			description = "DM binary";
			data = /incbin/("$DM");
			type = "firmware";
			arch = "arm32";
			compression = "none";
			os = "DM";
			load = <0xa0000000>;
			entry = <0xa0000000>;
		};
		spl {
			description = "SPL (64-bit)";
			data = /incbin/("spl/u-boot-spl-nodtb.bin$HS_APPEND");
			type = "standalone";
			os = "U-Boot";
			arch = "arm64";
			compression = "none";
			load = <0x80080000>;
			entry = <0x80080000>;
		};
__HEADER_EOF

# shift through ATF load address in the command line arguments
shift

for dtname in $*
do
	cat << __FDT_IMAGE_EOF
		$(basename $dtname) {
			description = "$(basename $dtname .dtb)";
			data = /incbin/("$dtname$HS_APPEND");
			type = "flat_dt";
			arch = "arm";
			compression = "none";
		};
__FDT_IMAGE_EOF
done

cat << __CONF_HEADER_EOF
	};
	configurations {
		default = "$(basename $1)";

__CONF_HEADER_EOF

for dtname in $*
do
	cat << __CONF_SECTION_EOF
		$(basename $dtname) {
			description = "$(basename $dtname .dtb)";
			firmware = "atf";
			loadables = "tee", "dm", "spl";
			fdt = "$(basename $dtname)";
		};
__CONF_SECTION_EOF
done

cat << __ITS_EOF
	};
};
__ITS_EOF


#!/bin/bash
# SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
#
# Script to add K3 specific x509 cetificate to a binary.
#

# Variables
OUTPUT=tiboot3.bin
TEMP_X509=x509-temp.cert
CERT=certificate.bin
RAND_KEY=eckey.pem
LOADADDR=0x41c00000
BOOTCORE_OPTS=0
BOOTCORE=16
DEBUG_TYPE=0

gen_degen_template() {
cat << 'EOF' > degen-template.txt

asn1=SEQUENCE:rsa_key

[rsa_key]
version=INTEGER:0
modulus=INTEGER:0xDEGEN_MODULUS
pubExp=INTEGER:1
privExp=INTEGER:1
p=INTEGER:0xDEGEN_P
q=INTEGER:0xDEGEN_Q
e1=INTEGER:1
e2=INTEGER:1
coeff=INTEGER:0xDEGEN_COEFF
EOF
}

# Generate x509 Template
gen_template() {
cat << 'EOF' > x509-template.txt
 [ req ]
 distinguished_name     = req_distinguished_name
 x509_extensions        = v3_ca
 prompt                 = no
 dirstring_type         = nobmp

 [ req_distinguished_name ]
 C                      = US
 ST                     = TX
 L                      = Dallas
 O                      = Texas Instruments Incorporated
 OU                     = Processors
 CN                     = TI support
 emailAddress           = support@ti.com

 [ v3_ca ]
 basicConstraints = CA:true
 1.3.6.1.4.1.294.1.1 = ASN1:SEQUENCE:boot_seq
 1.3.6.1.4.1.294.1.2 = ASN1:SEQUENCE:image_integrity
 1.3.6.1.4.1.294.1.3 = ASN1:SEQUENCE:swrv
# 1.3.6.1.4.1.294.1.4 = ASN1:SEQUENCE:encryption
 1.3.6.1.4.1.294.1.8 = ASN1:SEQUENCE:debug

 [ boot_seq ]
 certType = INTEGER:TEST_CERT_TYPE
 bootCore = INTEGER:TEST_BOOT_CORE
 bootCoreOpts = INTEGER:TEST_BOOT_CORE_OPTS
 destAddr = FORMAT:HEX,OCT:TEST_BOOT_ADDR
 imageSize = INTEGER:TEST_IMAGE_LENGTH

 [ image_integrity ]
 shaType = OID:2.16.840.1.101.3.4.2.3
 shaValue = FORMAT:HEX,OCT:TEST_IMAGE_SHA_VAL

 [ swrv ]
 swrv = INTEGER:0

# [ encryption ]
# initalVector = FORMAT:HEX,OCT:TEST_IMAGE_ENC_IV
# randomString = FORMAT:HEX,OCT:TEST_IMAGE_ENC_RS
# iterationCnt = INTEGER:TEST_IMAGE_KEY_DERIVE_INDEX
# salt = FORMAT:HEX,OCT:TEST_IMAGE_KEY_DERIVE_SALT

 [ debug ]
 debugUID = FORMAT:HEX,OCT:0000000000000000000000000000000000000000000000000000000000000000
 debugType = INTEGER:TEST_DEBUG_TYPE
 coreDbgEn = INTEGER:0
 coreDbgSecEn = INTEGER:0
EOF
}

parse_key() {
	sed '/\ \ \ \ /s/://g' key.txt | awk  '!/\ \ \ \ / {printf("\n%s\n", $0)}; /\ \ \ \ / {printf("%s", $0)}' | sed 's/\ \ \ \ //g' | awk "/$1:/{getline; print}"
}

gen_degen_key() {
# Generate a 4096 bit RSA Key
	openssl genrsa -out key.pem 1024 >>/dev/null 2>&1
	openssl rsa -in key.pem -text -out key.txt >>/dev/null 2>&1
	DEGEN_MODULUS=$( parse_key 'modulus' )
	DEGEN_P=$( parse_key 'prime1' )
	DEGEN_Q=$( parse_key 'prime2' )
	DEGEN_COEFF=$( parse_key 'coefficient' )
	gen_degen_template

	sed -e "s/DEGEN_MODULUS/$DEGEN_MODULUS/"\
		-e "s/DEGEN_P/$DEGEN_P/" \
		-e "s/DEGEN_Q/$DEGEN_Q/" \
		-e "s/DEGEN_COEFF/$DEGEN_COEFF/" \
		 degen-template.txt > degenerateKey.txt

	openssl asn1parse -genconf degenerateKey.txt -out degenerateKey.der >>/dev/null 2>&1
	openssl rsa -in degenerateKey.der -inform DER -outform PEM -out $RAND_KEY >>/dev/null 2>&1
	KEY=$RAND_KEY
	rm key.pem key.txt degen-template.txt degenerateKey.txt degenerateKey.der
}

declare -A options_help
usage() {
	if [ -n "$*" ]; then
		echo "ERROR: $*"
	fi
	echo -n "Usage: $0 "
	for option in "${!options_help[@]}"
	do
		arg=`echo ${options_help[$option]}|cut -d ':' -f1`
		if [ -n "$arg" ]; then
			arg=" $arg"
		fi
		echo -n "[-$option$arg] "
	done
	echo
	echo -e "\nWhere:"
	for option in "${!options_help[@]}"
	do
		arg=`echo ${options_help[$option]}|cut -d ':' -f1`
		txt=`echo ${options_help[$option]}|cut -d ':' -f2`
		tb="\t\t\t"
		if [ -n "$arg" ]; then
			arg=" $arg"
			tb="\t"
		fi
		echo -e "   -$option$arg:$tb$txt"
	done
	echo
	echo "Examples of usage:-"
	echo "# Example of signing the SYSFW binary with rsa degenerate key"
	echo "    $0 -c 0 -b ti-sci-firmware-am6x.bin -o sysfw.bin -l 0x40000"
	echo "# Example of signing the SPL binary with rsa degenerate key"
	echo "    $0 -c 16 -b spl/u-boot-spl.bin -o tiboot3.bin -l 0x41c00000"
}

options_help[b]="bin_file:Bin file that needs to be signed"
options_help[k]="key_file:file with key inside it. If not provided script generates a rsa degenerate key."
options_help[o]="output_file:Name of the final output file. default to $OUTPUT"
options_help[c]="core_id:target core id on which the image would be running. Default to $BOOTCORE"
options_help[l]="loadaddr: Target load address of the binary in hex. Default to $LOADADDR"
options_help[d]="debug_type: Debug type, set to 4 to enable early JTAG. Default to $DEBUG_TYPE"

while getopts "b:k:o:c:l:d:h" opt
do
	case $opt in
	b)
		BIN=$OPTARG
	;;
	k)
		KEY=$OPTARG
	;;
	o)
		OUTPUT=$OPTARG
	;;
	l)
		LOADADDR=$OPTARG
	;;
	c)
		BOOTCORE=$OPTARG
	;;
	d)
		DEBUG_TYPE=$OPTARG
	;;
	h)
		usage
		exit 0
	;;
	\?)
		usage "Invalid Option '-$OPTARG'"
		exit 1
	;;
	:)
		usage "Option '-$OPTARG' Needs an argument."
		exit 1
	;;
	esac
done

if [ "$#" -eq 0 ]; then
	usage "Arguments missing"
	exit 1
fi

if [ -z "$BIN" ]; then
	usage "Bin file missing in arguments"
	exit 1
fi

# Generate rsa degenerate key if user doesn't provide a key
if [ -z "$KEY" ]; then
	gen_degen_key
fi

if [ $BOOTCORE == 0 ]; then	# BOOTCORE M3, loaded by ROM
	CERTTYPE=2
elif [ $BOOTCORE == 16 ]; then	# BOOTCORE R5, loaded by ROM
	CERTTYPE=1
else				# Non BOOTCORE, loaded by SYSFW
	BOOTCORE_OPTS_VER=$(printf "%01x" 1)
	# Add input args option for SET and CLR flags.
	BOOTCORE_OPTS_SETFLAG=$(printf "%08x" 0)
	BOOTCORE_OPTS_CLRFLAG=$(printf "%08x" 0x100) # Clear FLAG_ARMV8_AARCH32
	BOOTCORE_OPTS="0x$BOOTCORE_OPTS_VER$BOOTCORE_OPTS_SETFLAG$BOOTCORE_OPTS_CLRFLAG"
	# Set the cert type to zero.
	# We are not using public/private key store now
	CERTTYPE=$(printf "0x%08x" 0)
fi

SHA_VAL=`openssl dgst -sha512 -hex $BIN | sed -e "s/^.*= //g"`
BIN_SIZE=`cat $BIN | wc -c`
ADDR=`printf "%08x" $LOADADDR`

gen_cert() {
	#echo "Certificate being generated :"
	#echo "	LOADADDR = 0x$ADDR"
	#echo "	IMAGE_SIZE = $BIN_SIZE"
	#echo "	CERT_TYPE = $CERTTYPE"
	#echo "	DEBUG_TYPE = $DEBUG_TYPE"
	sed -e "s/TEST_IMAGE_LENGTH/$BIN_SIZE/"	\
		-e "s/TEST_IMAGE_SHA_VAL/$SHA_VAL/" \
		-e "s/TEST_CERT_TYPE/$CERTTYPE/" \
		-e "s/TEST_BOOT_CORE_OPTS/$BOOTCORE_OPTS/" \
		-e "s/TEST_BOOT_CORE/$BOOTCORE/" \
		-e "s/TEST_BOOT_ADDR/$ADDR/" \
		-e "s/TEST_DEBUG_TYPE/$DEBUG_TYPE/" \
		x509-template.txt > $TEMP_X509
	openssl req -new -x509 -key $KEY -nodes -outform DER -out $CERT -config $TEMP_X509 -sha512
}

gen_template
gen_cert
cat $CERT $BIN > $OUTPUT

# Remove all intermediate files
rm $TEMP_X509 $CERT x509-template.txt
if [ "$KEY" == "$RAND_KEY" ]; then
	rm $RAND_KEY
fi


#!/bin/bash
# SPDX-License-Identifier: GPL-2.0
#
######################################################
# Copyright (C) 2016 Marvell International Ltd.
#
# https://spdx.org/licenses
#
# Author: Konstantin Porotchkin kostap@marvell.com
#
# Version 0.3
#
# UART recovery downloader for Armada SoCs
#
######################################################

port=$1
file=$2
speed=$3

pattern_repeat=1500
default_baudrate=115200
tmpfile=/tmp/xmodem.pattern
tools=( dd stty sx minicom )

case "$3" in
    2)
        fast_baudrate=230400
        prefix="\xF2"
        ;;
    4)
        fast_baudrate=460800
        prefix="\xF4"
        ;;
    8)
    	fast_baudrate=921600
        prefix="\xF8"
        ;;
    *)
    	fast_baudrate=$default_baudrate
        prefix="\xBB"
esac

if [[ -z "$port" || -z "$file" ]]
then
    echo -e "\nMarvell recovery image downloader for Armada SoC family."
    echo -e "Command syntax:"
    echo -e "\t$(basename $0) <port> <file> [2|4|8]"
    echo -e "\tport  - serial port the target board is connected to"
    echo -e "\tfile  - recovery boot image for target download"
    echo -e "\t2|4|8 - times to increase the default serial port speed by"
    echo -e "For example - load the image over ttyUSB0 @ 460800 baud:"
    echo -e "$(basename $0) /dev/ttyUSB0 /tmp/flash-image.bin 4\n"
    echo -e "=====WARNING====="
    echo -e "- The speed-up option is not available in SoC families prior to A8K+"
    echo -e "- This utility is not compatible with Armada 37xx SoC family\n"
fi

# Sanity checks
if [ -c "$port" ]
then
   echo -e "Using device connected on serial port \"$port\""
else
   echo "Wrong serial port name!"
   exit 1
fi

if [ -f "$file" ]
then
   echo -e "Loading flash image file \"$file\""
else
   echo "File $file does not exist!"
   exit 1
fi

# Verify required tools installation
for tool in ${tools[@]}
do
    toolname=`which $tool`
    if [ -z "$toolname" ]
    then
        echo -e "Missing installation of \"$tool\" --> Exiting"
        exit 1
    fi
done

echo -e "Recovery will run at $fast_baudrate baud"
echo -e "========================================"

if [ -f "$tmpfile" ]
then
    rm -f $tmpfile
fi

# Send the escape sequence to target board using default debug port speed
stty -F $port raw ignbrk time 5 $default_baudrate
counter=0
while [ $counter -lt $pattern_repeat ]; do
    echo -n -e "$prefix\x11\x22\x33\x44\x55\x66\x77" >> $tmpfile
    let counter=counter+1
done

echo -en "Press the \"Reset\" button on the target board and "
echo -en "the \"Enter\" key on the host keyboard simultaneously"
read
dd if=$tmpfile of=$port &>/dev/null

# Speed up the binary image transfer
stty -F $port raw ignbrk time 5 $fast_baudrate
sx -vv $file > $port < $port
#sx-at91 $port $file

# Return the port to the default speed
stty -F $port raw ignbrk time 5 $default_baudrate

# Optional - fire up Minicom
minicom -D $port -b $default_baudrate


#!/bin/bash
# SPDX-License-Identifier: GPL-2.0+
# Copyright (C) 2018 Michal Simek <michal.simek@xilinx.com>
# Copyright (C) 2019 Luca Ceresoli <luca@lucaceresoli.net>

usage()
{
    cat <<EOF

Transform a pair of psu_init_gpl.c and .h files produced by the Xilinx
Vivado tool for ZynqMP into a smaller psu_init_gpl.c file that is almost
checkpatch compliant. Minor coding style might still be needed. Must be
run from the top-level U-Boot source directory.

Usage:   zynqmp_psu_init_minimize.sh INPUT_DIR OUTPUT_DIR
Example: zynqmp_psu_init_minimize.sh \\
                 /path/to/original/psu_init_gpl_c_and_h/ \\
                 board/xilinx/zynqmp/<my_board>/

Notes:   INPUT_DIR must contain both .c and .h files.
         If INPUT_DIR and OUTPUT_DIR are the same directory,
         psu_init_gpl.c will be overwritten.

EOF
}

set -o errexit -o errtrace
set -o nounset

if [ $# -ne 2 ]
then
    usage >&2
    exit 1
fi

IN="${1}/psu_init_gpl.c"
OUT="${2}/psu_init_gpl.c"
TMP=$(mktemp /tmp/psu_init_gpl.XXXXXX)
trap "rm ${TMP}" ERR

# Step through a temp file to allow both $IN!=$OUT and $IN==$OUT
sed -e '/sleep.h/d' \
    -e '/xil_io.h/d' \
    ${IN} >${TMP}
cp ${TMP} ${OUT}

# preprocess to expand defines, then remove cpp lines starting with '#'
gcc -I${1} -E ${OUT} -o ${TMP}
sed '/^#/d' ${TMP} >${OUT}

# Remove trivial code before psu_pll_init_data()
sed -ni '/psu_pll_init_data/,$p' ${OUT}

# Functions are lowercase in U-Boot, rename them
sed -i 's/PSU_Mask_Write/psu_mask_write/g' ${OUT}
sed -i 's/mask_pollOnValue/mask_pollonvalue/g' ${OUT}
sed -i 's/RegValue/regvalue/g' ${OUT}
sed -i 's/MaskStatus/maskstatus/g' ${OUT}

sed -i '/&= psu_peripherals_powerdwn_data()/d' ${OUT}

FUNCS_TO_REMOVE="psu_protection
psu_..._protection
psu_init_xppu_aper_ram
mask_delay(u32
mask_read(u32
mask_poll(u32
mask_pollonvalue(u32
psu_ps_pl_reset_config_data
psu_ps_pl_isolation_removal_data
psu_apply_master_tz
psu_post_config_data
psu_post_config_data
psu_peripherals_powerdwn_data
psu_init_ddr_self_refresh
xmpu
xppu
"
for i in $FUNCS_TO_REMOVE; do
sed -i "/$i/,/^}$/d" ${OUT}
done

scripts/Lindent ${OUT}

# Prepend 'static' to internal functions
sed -i 's/^.*data(void)$/static &/g' ${OUT}
sed -i 's/^.*psu_afi_config(void)$/static &/g' ${OUT}
sed -i 's/^void init_peripheral/static &/g' ${OUT}
sed -i 's/^int serdes/static &/g' ${OUT}
sed -i 's/^int init_serdes/static &/g' ${OUT}
sed -i 's/^unsigned long /static &/g' ${OUT}

sed -i 's/()$/(void)/g' ${OUT}
sed -i 's/0X/0x/g' ${OUT}

# return (0) -> return 0
sed -ri 's/return \(([0-9]+)\)/return \1/g' ${OUT}

# Add header
cat << EOF >${TMP}
// SPDX-License-Identifier: GPL-2.0+
/*
 * (c) Copyright 2015 Xilinx, Inc. All rights reserved.
 */

#include <asm/arch/psu_init_gpl.h>
#include <xil_io.h>

EOF

cat ${OUT} >>${TMP}
cp ${TMP} ${OUT}

# Temporarily convert newlines to do some mangling across lines
tr "\n" "\r" <${OUT} >${TMP}

# Cleanup empty loops. E.g.:
# |while (e) {|
# |           | ==> |while (e)|
# |    }      |     |    ;    |
# |           |
sed -i -r 's| \{\r+(\t*)\}\r\r|\n\1\t;\n|g' ${TMP}

# Remove empty line between variable declaration
sed -i -r 's|\r(\r\t(unsigned )?int )|\1|g' ${TMP}

# Remove empty lines at function beginning/end
sed -i -e 's|\r{\r\r|\r{\r|g' ${TMP}
sed -i -e 's|\r\r}\r|\r}\r|g' ${TMP}

# Remove empty lines after '{' line
sed -i -e 's| {\r\r| {\r|g' ${TMP}

# Remove braces {} around single statement blocks. E.g.:
# | while (e) { |    | while (e) |
# |     stg();  | => |     stg();|
# | }           |
sed -i -r 's| \{(\r[^\r]*;)\r\t*\}|\1|g' ${TMP}

# Remove Unnecessary parentheses around 'n_code <= 0x3C' and similar. E.g.:
# if ((p_code >= 0x26) && ...) -> if (p_code >= 0x26 && ...)
sed -i -r 's|\((._code .= [x[:xdigit:]]+)\)|\1|g' ${TMP}

# Convert back newlines
tr "\r" "\n" <${TMP} >${OUT}

rm ${TMP}


#!/bin/bash
# Copyright (c) Meta Platforms, Inc. and affiliates.
#
# This source code is licensed under the MIT license found in the
# LICENSE file in the root directory of this source tree.

# shellcheck disable=SC1090
source "$(dirname "$0")/common.sh"

alias thrift1=/opt/facebook/fbthrift/bin/thrift1

# Step 1: Stage compilation

# folly Cython
mkdir ./folly
cp -r \
/tmp/fbcode_builder_getdeps-ZsrcZbuildZfbcode_builder-root/repos/github.com-facebook-folly.git/folly/python/* ./folly

# fb303 thrift
mkdir -p ./fb303-thrift
cp -r  /opt/facebook/fb303/include/thrift-files/fb303 ./fb303-thrift/

# fbthrift Cython and thrift
cp -r  /opt/facebook/fbthrift/include/thrift/lib/ ./thrift
touch ./thrift/py3/__init__.py
touch ./thrift/__init__.py

mkdir /src/fbthrift-thrift
cp -r \
/tmp/fbcode_builder_getdeps-ZsrcZbuildZfbcode_builder-root/repos/github.com-facebook-fbthrift.git/thrift/lib/thrift/* \
/src/fbthrift-thrift

mkdir -p /src/thrift/py3
chown -R root /tmp/fbcode_builder_getdeps-ZsrcZbuildZfbcode_builder-root/repos/github.com-facebook-fbthrift.git/thrift/lib/py3/
cp -r \
/tmp/fbcode_builder_getdeps-ZsrcZbuildZfbcode_builder-root/repos/github.com-facebook-fbthrift.git/thrift/lib/py3/* \
/src/thrift/py3
touch /src/thrift/__init__.py

# Open/R thrift
mkdir -p ./openr-thrift/openr
cp -r /src/openr/if/ ./openr-thrift/openr/

# Neteng thrift
mkdir -p neteng-thrift/configerator/structs/neteng/config/
cp -r \
/tmp/fbcode_builder_getdeps-ZsrcZbuildZfbcode_builder-root/repos/github.com-facebook-openr.git/configerator/structs/neteng/config/routing_policy.thrift \
neteng-thrift/configerator/structs/neteng/config/

# HACK TO FIX CYTHON .pxd
cp /cython/Cython/Includes/libcpp/utility.pxd /usr/lib/python3/dist-packages/Cython/Includes/libcpp/utility.pxd

# Step 2. Generate mstch_cpp2 and mstch_py3 bindings

python3 /src/build/gen.py

# HACK TO FIX fbthrift-py/gen-cpp2/
echo " " > /src/fbthrift-thrift/gen-cpp2/metadata_metadata.h
echo " " > /src/fbthrift-thrift/gen-cpp2/metadata_types.h
echo " " > /src/fbthrift-thrift/gen-cpp2/metadata_types_custom_protocol.h

# Step 3. Generate clients.cpp

python3 /src/build/cython_compile.py

# Step 4. Compile .so

# shellcheck disable=SC2097,SC2098
env \
CC="/usr/bin/gcc-10" \
CXX="/usr/bin/g++-10" \
CFLAGS="-I. -Iopenr-thrift -Ifb303-thrift -Ineteng-thrift -std=c++20 -fcoroutines " \
CFLAGS="$CFLAGS -w -D_CPPLIB_VER=20" \
CXXFLAGS="$CFLAGS" \
python3 openr/py/setup.py build -j10


#!/bin/bash
# Copyright (c) Meta Platforms, Inc. and affiliates.
#
# This source code is licensed under the MIT license found in the
# LICENSE file in the root directory of this source tree.

# shellcheck disable=SC1090
source "$(dirname "$0")/common.sh"

# TODO: Get apt deb installing working - dies in Docker container with libzstd-dev fixed
# "$PYTHON3" "$GETDEPS" --allow-system-packages install-system-deps --recursive openr
# errorCheck "Failed to install-system-deps for openr"

"$PYTHON3" "$GETDEPS" --allow-system-packages build --no-tests --install-prefix "$INSTALL_PREFIX" \
--extra-cmake-defines "$EXTRA_CMAKE_DEFINES" openr
errorCheck "Failed to build openr"

# TODO: Maybe fix src-dir to be absolute reference to dirname $0's parent
"$PYTHON3" "$GETDEPS" fixup-dyn-deps --strip --src-dir=. openr _artifacts/linux  --project-install-prefix openr:"$INSTALL_PREFIX" --final-install-prefix "$INSTALL_PREFIX"
errorCheck "Failed to fixup-dyn-deps for openr"


#!/bin/bash
# Copyright (c) Meta Platforms, Inc. and affiliates.
#
# This source code is licensed under the MIT license found in the
# LICENSE file in the root directory of this source tree.

GETDEPS="$(dirname "$0")/fbcode_builder/getdeps.py"
INSTALL_PREFIX="/opt/facebook"
PYTHON3=$(command -v python3)
PIP3=$(command -v pip3)
# shellcheck disable=SC2089
EXTRA_CMAKE_DEFINES='{"CMAKE_POSITION_INDEPENDENT_CODE": "ON"}'

# shellcheck disable=SC2090
export GETDEPS INSTALL_PREFIX PYTHON3 PIP3 EXTRA_CMAKE_DEFINES

errorCheck() {
  return_code=$?
  if [ $return_code -ne 0 ]; then
    echo "[ERROR]: $1"
    exit $return_code
  fi
}

if [ "$PYTHON3" == "" ]; then
  echo "ERROR: No \`python3\` in PATH"
  exit 1
fi

if [ "$PIP3" == "" ]; then
  echo "ERROR: No \`pip3\` in PATH"
  exit 2
fi


#!/bin/bash
# Copyright (c) Meta Platforms, Inc. and affiliates.
#
# This source code is licensed under the MIT license found in the
# LICENSE file in the root directory of this source tree.

CFG_BASE="/config"
DEFAULT_CFG="/etc/openr.conf"
FB_BASE="/opt/facebook"
OPENR_CFG="${CFG_BASE}/openr.conf"

LIBSODIUM="${FB_BASE}/libsodium-*/lib/"
GLOG="${FB_BASE}/glog-*/lib/"
GFLAGS="${FB_BASE}/gflags-*/lib/"
SNAPPY="${FB_BASE}/snappy-*/lib/"

# Hack to fix environment for openr linking
for dep in $LIBSODIUM $GLOG $GFLAGS $SNAPPY
do
  evaled_path=$(eval echo "${dep}")
  export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:$evaled_path"
done
export PATH="${PATH}:${FB_BASE}/openr/sbin"

mkdir -p "$CFG_BASE"
if [ ! -s "$OPENR_CFG" ]
then
  echo "Copying default Open/R config - Please check settings!"
  cp -vp "$DEFAULT_CFG" "$CFG_BASE"
fi

echo "[$(date)] Attempting to start Open/R using $OPENR_CFG $*"
openr_bin -v 2 --config "$OPENR_CFG" "$@"


#!/bin/bash
# Copyright (c) Meta Platforms, Inc. and affiliates.
#
# This source code is licensed under the MIT license found in the
# LICENSE file in the root directory of this source tree.

#
# Simple Script to copy configs + start openr
#

CONFIG_DIR="/tmp/orie_configs"

if [ "$1" == "copy-conf" ]; then
    # No need to copy cofigs as root
    if [ "$USER" == "root" ]; then
        echo "!!-> Don't copy as root ..."
        exit 1
    fi

    # Copy configs to /tmp
    # Have to copy due to eden behviours

    config_dir="$HOME/fbsource/fbcode/openr/orie/labs/$2"
    if [ ! -e "$config_dir" ]; then
        echo "!!-> $config_dir does not exist"
        exit 2
    fi

    config_src="$(find "$config_dir" -name '*.conf' | tr '\n' ' ')"
    echo "--> Configuration being copied: $config_src to $CONFIG_DIR"
    mkdir -pv "$CONFIG_DIR"
    sudo chown "$USER" "$CONFIG_DIR"
    # shellcheck disable=SC2086
    cp -v $config_src "$CONFIG_DIR"
    exit $?
elif [ "$1" == "start" ]; then
    # Automagically selects config file depending on your netns name
    openr_binary="$HOME/fbsource/fbcode/buck-out/gen/openr/openr"
    config="$CONFIG_DIR/$(ip netns identify).conf"
    echo "--> Starting Open/R using --config=$config"
    "$openr_binary" \
        --config="$config" \
        --logtostderr \
        --v=2 \
        --enable_secure_thrift_server=false |& tee "/tmp/$(ip netns identify).log"
    exit $?
fi

echo "!!--> ERROR: Specify an option: copy-conf|start !!"
exit 69


```
sudo yum update &&
sudo yum -y upgrade &&
sudo yum -y install python36 python36-devel python36-libs &&
wget https://nodejs.org/dist/latest-v9.x/node-v9.11.2-linux-x64.tar.gz &&
tar -xzvf node-v9.11.2-linux-x64.tar.gz &&
cd node-v9.11.2-linux-x64 &&
sudo cp -r bin/* /usr/local/bin/ && sudo cp -r lib/* /usr/local/lib && sudo cp -r share/* /usr/local/share &&
cd .. &&
sudo yum install -y postgresql95 && sudo yum install postgresql95-server &&
sudo yum install -y libxml2 libxml2-devel &&
sudo yum install -y geos geos-devel &&

```


#!/usr/bin/env bash

/bin/systemctl start tasking-manager.service
/bin/sleep 10


#!/usr/bin/env bash

/bin/systemctl stop tasking-manager.service
/bin/sleep 10


#!/bin/bash -e
#
# Node.JS 10
# PostgreSQL 9.5

# Do not prompt to trust Github.com
/usr/bin/ssh-keyscan -t rsa github.com | sudo /usr/bin/tee -a /etc/ssh/ssh_known_hosts

# Do not prompt for answers
export DEBIAN_FRONTEND=noninteractive
export LC_ALL="en_US.UTF-8"
export LC_CTYPE="en_US.UTF-8"
export LC_ALL=C
sudo dpkg-reconfigure --frontend=noninteractive locales

sudo apt-get -y install \
    make build-essential \
    libssl-dev zlib1g-dev libbz2-dev \
    libreadline-dev libsqlite3-dev \
    llvm libncurses5-dev libncursesw5-dev \
    xz-utils tk-dev libffi-dev liblzma-dev

sudo apt-get -y update

echo "Upgrade Ubuntu packages.."
sudo DEBIAN_FRONTEND=noninteractive apt-get -y \
    -o Dpkg::Options::="--force-confdef" \
    -o Dpkg::Options::="--force-confold" upgrade

echo "Install basic utilities.."
sudo apt-get -y install \
    awscli \
    curl \
    git \
    ruby \
    unzip \
    wget \
    grub kpartx             # Dependencies for ec2-ami-tools

# Install Python3.6
wget https://www.python.org/ftp/python/3.6.9/Python-3.6.9.tgz
tar -xf Python-3.6.9.tgz && \
    cd Python-3.6.9 && \
    sudo ./configure --enable-optimizations --with-ensurepip=install && \
    sudo make altinstall

# Install mapping related stuff
# libgdal* - Geospatial Data Abstraction Library (GDAL)
# libgeos* - Geometry engine
# libproj* - Cartographic projects & translations between CRS
sudo apt-get -y install \
    libgdal-dev \
    libgeos-3.5.1 libgeos-dev \
    libproj12 libproj-dev \
    libxml2 libxml2-dev \
    libjson-c-dev

sudo apt-get -y install \
    postgresql-9.5 \
    postgresql-server-dev-9.5 \
    libpq-dev                    # PostgreSQL Library to C

# Setup Node.JS v10.x
curl -sL https://deb.nodesource.com/setup_10.x | sudo -E bash -
sudo apt-get -y install nodejs

# Install dependencies
sudo npm install gulp -g
sudo npm install browser-sync --save # Probably add this to package.json?

# sudo git clone --recursive https://github.com/hotosm/tasking-manager.git /tasking-manager
sudo git clone --recursive --single-branch \
    --branch deployment/hot-tasking-manager \
    https://github.com/hotosm/tasking-manager.git /tasking-manager

# inotify watches for filesystem (why?)
echo fs.inotify.max_user_watches=524288 | sudo tee -a /etc/sysctl.conf

# Local install of aws-cfn-bootstrap template
wget https://s3.amazonaws.com/cloudformation-examples/aws-cfn-bootstrap-latest.tar.gz
sudo pip2 install aws-cfn-bootstrap-latest.tar.gz

# EC2 AMI tools installation (why?)
wget https://s3.amazonaws.com/ec2-downloads/ec2-ami-tools.zip
sudo mkdir -p /usr/local/ec2
sudo unzip -qq ec2-ami-tools.zip -d /usr/local/ec2

# add to etc/profile.d/myenvvars.sh export variable EC2_AMITOOL_HOME
sudo touch /etc/profile.d/myenvvars.sh
echo "export EC2_AMITOOL_HOME=/usr/local/ec2/ec2-ami-tools-1.5.7" | sudo tee -a /etc/profile.d/myenvvars.sh
echo "export PATH=/usr/local/ec2/ec2-ami-tools-1.5.7/bin:$PATH:" | sudo tee -a /etc/profile.d/myenvvars.sh


#!/bin/bash -e
#
# Node.JS 10
# PostgreSQL 9.5

# Do not prompt to trust Github.com
/usr/bin/ssh-keyscan -t rsa github.com | sudo /usr/bin/tee -a /etc/ssh/ssh_known_hosts

# Do not prompt for answers
export DEBIAN_FRONTEND=noninteractive
export LC_ALL="en_US.UTF-8"
export LC_CTYPE="en_US.UTF-8"
export LC_ALL=C
sudo dpkg-reconfigure --frontend=noninteractive locales

# Add Third-party repository for Python 3.6 distribution
# Ubuntu 16.04 does not provide via repos.
sudo add-apt-repository ppa:jonathonf/python-3.6 -y
sudo apt-get -y update

echo "Upgrade Ubuntu packages.."
sudo DEBIAN_FRONTEND=noninteractive apt-get -y \
    -o Dpkg::Options::="--force-confdef" \
    -o Dpkg::Options::="--force-confold" upgrade

echo "Install basic utilities.."
sudo apt-get -y install \
    awscli \
    curl \
    git \
    ruby \
    unzip \
    wget \
    grub kpartx             # Dependencies for ec2-ami-tools

sudo apt-get -y install \
    python3.6 python3.6-dev \
    python3.6-venv \
    python-pip                 # Default python pip (why?)

# Install mapping related stuff
# libgdal1* - Geospatial Data Abstraction Library (GDAL)
# libgeos* - Geometry engine
# libproj* - Cartographic projects & translations between CRS
sudo apt-get -y install \
    libgdal1-dev \
    libgeos-3.5.0 libgeos-dev \
    libproj9 libproj-dev \
    libxml2 libxml2-dev \
    libjson-c-dev

sudo apt-get -y install \
    postgresql-9.5 \
    postgresql-server-dev-9.5 \
    libpq-dev                    # PostgreSQL Library to C

# Setup Node.JS v10.x
curl -sL https://deb.nodesource.com/setup_10.x | sudo -E bash -
sudo apt-get -y install nodejs

# sudo git clone --recursive https://github.com/hotosm/tasking-manager.git /tasking-manager
sudo git clone --recursive --single-branch \
    --branch deployment/hot-tasking-manager \
    https://github.com/hotosm/tasking-manager.git /tasking-manager

# inotify watches for filesystem (why?)
echo fs.inotify.max_user_watches=524288 | sudo tee -a /etc/sysctl.conf

# Local install of aws-cfn-bootstrap template
wget https://s3.amazonaws.com/cloudformation-examples/aws-cfn-bootstrap-latest.tar.gz
sudo pip2 install aws-cfn-bootstrap-latest.tar.gz

# EC2 AMI tools installation (why?)
wget https://s3.amazonaws.com/ec2-downloads/ec2-ami-tools.zip
sudo mkdir -p /usr/local/ec2
sudo unzip -qq ec2-ami-tools.zip -d /usr/local/ec2

# add to etc/profile.d/myenvvars.sh export variable EC2_AMITOOL_HOME
sudo touch /etc/profile.d/myenvvars.sh
echo "export EC2_AMITOOL_HOME=/usr/local/ec2/ec2-ami-tools-1.5.7" | sudo tee -a /etc/profile.d/myenvvars.sh
echo "export PATH=/usr/local/ec2/ec2-ami-tools-1.5.7/bin:$PATH:" | sudo tee -a /etc/profile.d/myenvvars.sh


NEW_DB='tm_new'

echo $NEW_DB
psql -U $DB_USER -d $DB -c "DROP DATABASE $NEW_DB"
psql -U $DB_USER -d $DB -c "CREATE DATABASE $NEW_DB"
psql -U $DB_USER -d $NEW_DB -c "CREATE EXTENSION postgis;"


do_dash() {
   echo "---------------------------------------------------------------"
}

do_dash; echo "\n Defining variables"

RDS_LIST=( "prod-05-jun" "prod-06-jun" "prod-07-jun" "prod-08-jun" "prod-09-jun"
           "prod-10-jun" "prod-11-jun" "prod-snapshot-before-12-jun-deploy" "prod-12-jun" )
FOLDER_PATH=dump/lost_projects

for HOST in "${RDS_LIST[@]}"; do
  echo $HOST
  do_dash; echo "Priority areas tables"
  TABLE=priority_areas
  FILE=$FOLDER_PATH/$HOST/$TABLE.csv
  psql "host=$TARGET_HOST.$ENDPOINT dbname=$DB user=$DB_USER password=$DB_PASSWORD" -c \
  	"\copy $TABLE FROM '$FILE' DELIMITER ',' CSV HEADER"

  ###############################################################################################

  do_dash; echo "Projects table"
  TABLE=projects
  FILE=$FOLDER_PATH/$HOST/$TABLE.csv
  psql "host=$TARGET_HOST.$ENDPOINT dbname=$DB user=$DB_USER password=$DB_PASSWORD" -c \
  	"\copy $TABLE FROM '$FILE' DELIMITER ',' CSV HEADER"

  ###############################################################################################

  do_dash; echo "Project allowed users"
  TABLE=project_allowed_users
  FILE=$FOLDER_PATH/$HOST/$TABLE.csv
  psql "host=$TARGET_HOST.$ENDPOINT dbname=$DB user=$DB_USER password=$DB_PASSWORD" -c \
  	"\copy $TABLE FROM '$FILE' DELIMITER ',' CSV HEADER"

  ###############################################################################################

  do_dash; echo "Tasks table"
  TABLE=tasks
  FILE=$FOLDER_PATH/$HOST/$TABLE.csv
  psql "host=$TARGET_HOST.$ENDPOINT dbname=$DB user=$DB_USER password=$DB_PASSWORD" -c \
  	"\copy $TABLE FROM '$FILE' DELIMITER ',' CSV HEADER"

  ###############################################################################################

  do_dash; echo "Task history"
  TABLE=task_history
  FILE=$FOLDER_PATH/$HOST/$TABLE.csv
  psql "host=$TARGET_HOST.$ENDPOINT dbname=$DB user=$DB_USER password=$DB_PASSWORD" -c \
  	"\copy $TABLE FROM '$FILE' DELIMITER ',' CSV HEADER"

  ###############################################################################################

  do_dash; echo "Task invalidation history"
  TABLE=task_invalidation_history
  FILE=$FOLDER_PATH/$HOST/$TABLE.csv
  psql "host=$TARGET_HOST.$ENDPOINT dbname=$DB user=$DB_USER password=$DB_PASSWORD" -c \
  	"\copy $TABLE FROM '$FILE' DELIMITER ',' CSV HEADER"

  ###############################################################################################

  do_dash; echo "Project priority areas"
  TABLE=project_priority_areas
  FILE=$FOLDER_PATH/$HOST/$TABLE.csv
  psql "host=$TARGET_HOST.$ENDPOINT dbname=$DB user=$DB_USER password=$DB_PASSWORD" -c \
  	"\copy $TABLE FROM '$FILE' DELIMITER ',' CSV HEADER"

  ###############################################################################################

  do_dash; echo "Project chat"
  TABLE=project_chat
  FILE=$FOLDER_PATH/$HOST/$TABLE.csv
  psql "host=$TARGET_HOST.$ENDPOINT dbname=$DB user=$DB_USER password=$DB_PASSWORD" -c \
  	"\copy $TABLE FROM '$FILE' DELIMITER ',' CSV HEADER"

  ###############################################################################################

  do_dash; echo "Project info"
  TABLE=project_info
  FILE=$FOLDER_PATH/$HOST/$TABLE.csv
  psql "host=$TARGET_HOST.$ENDPOINT dbname=$DB user=$DB_USER password=$DB_PASSWORD" -c \
  	"\copy $TABLE FROM '$FILE' DELIMITER ',' CSV HEADER"

  ###############################################################################################

  do_dash; echo "Messages"
  TABLE=messages
  FILE=$FOLDER_PATH/$HOST/$TABLE.csv
  psql "host=$TARGET_HOST.$ENDPOINT dbname=$DB user=$DB_USER password=$DB_PASSWORD" -c \
  	"CREATE TABLE temp_$TABLE(LIKE messages);"
  psql "host=$TARGET_HOST.$ENDPOINT dbname=$DB user=$DB_USER password=$DB_PASSWORD" -c \
    	"\copy temp_$TABLE FROM '$FILE' DELIMITER ',' CSV HEADER;"
  psql "host=$TARGET_HOST.$ENDPOINT dbname=$DB user=$DB_USER password=$DB_PASSWORD" -c \
      	"UPDATE $TABLE SET
      		task_id=temp_$TABLE.task_id,
      		project_id=temp_$TABLE.project_id
      	FROM temp_$TABLE
      	WHERE
      		temp_$TABLE.id=$TABLE.id
      	AND
      		temp_$TABLE.id IN (SELECT id FROM $TABLE);
      	INSERT INTO $TABLE SELECT * FROM temp_$TABLE WHERE id NOT IN (SELECT id FROM messages);
      	DROP TABLE temp_$TABLE;"

done


#!/bin/bash
#
# Script to install the Tasking Manager on Debian 10 Buster
# The script must be executed from the root of the project

# Ensure being run on the supported operating system
distribution=$(lsb_release -si)
version=$(lsb_release -sc)

if [ "$distribution" != "Debian" ] || [ "$version" != "buster" ]; then
  echo -e "ERROR: Your operating system is not supported by this installation script"
  exit
fi

# Make sure the system is up-to-date
sudo apt update && sudo apt -y upgrade &&

## Install general tools
sudo apt install -y build-essential curl git libgeos-dev software-properties-common &&

# Install Python and Node
curl -sL https://deb.nodesource.com/setup_10.x | sudo bash -
sudo apt install -y python3 python3-dev python3-venv nodejs &&

# Install the database
sudo apt install -y postgresql-10 libpq-dev postgresql-server-dev-10 postgresql-10-postgis-2.4 postgresql-10-postgis-scripts &&

## Obtain the tasking manager
git clone https://github.com/hotosm/tasking-manager.git &&

## Prepare the tasking manager
cd tasking-manager/ &&
python3 -m venv ./venv &&
. ./venv/bin/activate &&
pip install --upgrade pip &&
pip install -r requirements.txt &&

# Set up configuration
# Sets db endpoint to localhost.
if ! test -f tasking-manager.env
	then
    cp example.env tasking-manager.env
fi
. ./tasking-manager.env &&
sed -i '/POSTGRES_ENDPOINT/s/^# //g' tasking-manager.env &&

# Set up data base
if ! sudo -u postgres psql -c "SELECT u.usename FROM pg_catalog.pg_user u;" | grep -w -q $POSTGRES_USER
	then
		sudo -u postgres psql -c "CREATE USER $POSTGRES_USER WITH PASSWORD '$POSTGRES_PASSWORD';"
fi
if ! sudo -u postgres psql -c "SELECT datname FROM pg_database WHERE datistemplate = false;" | grep -w -q $POSTGRES_DB
	then
    sudo -u postgres createdb -T template0 $POSTGRES_DB -E UTF8 -O $POSTGRES_USER &&
    sudo -u postgres psql -d $POSTGRES_DB -c "CREATE EXTENSION postgis;"
fi

# Populate database
cd tests/database/ &&
sudo -u postgres psql -d $POSTGRES_DB -c "\i tasking-manager.sql" &&
for tbl in `sudo -u postgres psql -qAt -c "select tablename from pg_tables where schemaname = 'public';" $POSTGRES_DB`;
do  sudo -u postgres psql -c "alter table \"$tbl\" owner to $POSTGRES_USER" $POSTGRES_DB ; done &&
for tbl in `sudo -u postgres psql -qAt -c "select tablename from pg_tables where schemaname = 'topology';" $POSTGRES_DB`;
do  sudo -u postgres psql -c "alter table \"$tbl\" owner to $POSTGRES_USER" $POSTGRES_DB ; done &&
cd ../../ &&

# Upgrade database
./venv/bin/python3 manage.py db upgrade &&

# Assamble the tasking manager interface
cd frontend/ &&
npm install &&
npm run build &&
cd ../ &&

## Please edit the tasking-manager.env as indicated in the README.md ##

# Start the tasking manager
./venv/bin/python manage.py runserver -d


#!/bin/bash
#
# Script to install the Tasking Manager on Ubuntu 18.04
#

# Ensure being run on the supported operating system
distribution=$(lsb_release -si)
version=$(lsb_release -sc)

if [ "$distribution" != "Ubuntu" ] || [ "$version" != "bionic" ]; then
  echo -e "ERROR: Your operating system is not supported by this installation script"
  exit
fi

# Make sure the system is up-to-date
sudo apt update && sudo apt -y upgrade &&

# Install general tools
sudo apt install -y build-essential curl git &&

# Install Python and Node
curl -sL https://deb.nodesource.com/setup_10.x | sudo bash -
sudo apt install -y python3 python3-dev python3-venv nodejs &&

# Install the database
sudo apt install -y postgresql-10 libpq-dev postgresql-server-dev-10 postgresql-10-postgis-2.4 postgresql-10-postgis-scripts &&

## Obtain the tasking manager
git clone https://github.com/hotosm/tasking-manager.git &&

## Prepare the tasking manager
cd tasking-manager/ &&
python3 -m venv ./venv &&
. ./venv/bin/activate &&
pip install --upgrade pip &&
pip install -r requirements.txt &&
echo fs.inotify.max_user_watches=524288 | sudo tee -a /etc/sysctl.conf && sudo sysctl -p &&

# Set up configuration
# Sets db endpoint to localhost.
if ! test -f tasking-manager.env
	then
    cp example.env tasking-manager.env
fi
. ./tasking-manager.env &&
sed -i '/POSTGRES_ENDPOINT/s/^# //g' tasking-manager.env &&

# Set up data base
if ! sudo -u postgres psql -c "SELECT u.usename FROM pg_catalog.pg_user u;" | grep -w -q $POSTGRES_USER
	then
		sudo -u postgres psql -c "CREATE USER $POSTGRES_USER WITH PASSWORD '$POSTGRES_PASSWORD';"
fi
if ! sudo -u postgres psql -c "SELECT datname FROM pg_database WHERE datistemplate = false;" | grep -w -q $POSTGRES_DB
	then
    sudo -u postgres createdb -T template0 $POSTGRES_DB -E UTF8 -O $POSTGRES_USER &&
    sudo -u postgres psql -d $POSTGRES_DB -c "CREATE EXTENSION postgis;"
fi

# Populate database
cd tests/database/ &&
sudo -u postgres psql -d $POSTGRES_DB -c "\i tasking-manager.sql" &&
for tbl in `sudo -u postgres psql -qAt -c "select tablename from pg_tables where schemaname = 'public';" $POSTGRES_DB`;
do  sudo -u postgres psql -c "alter table \"$tbl\" owner to $POSTGRES_USER" $POSTGRES_DB ; done &&
for tbl in `sudo -u postgres psql -qAt -c "select tablename from pg_tables where schemaname = 'topology';" $POSTGRES_DB`;
do  sudo -u postgres psql -c "alter table \"$tbl\" owner to $POSTGRES_USER" $POSTGRES_DB ; done &&
cd ../../ &&

# Upgrade database
./venv/bin/python3 manage.py db upgrade &&

# Assamble the tasking manager interface
cd frontend/ &&
npm install &&
npm run build &&
cd ../ &&

## Please edit the tasking-manager.env as indicated in the README.md ##

# Start the tasking manager
./venv/bin/python manage.py runserver -d


#!/bin/bash -e
# Copyright (c) Facebook, Inc. and its affiliates.
#
# This source code is licensed under the MIT license found in the
# LICENSE file in the root directory of this source tree.
PTH="$(pwd)"
VERSION="$(python3 "$PTH/../src/version.py")"
DATETIME=$(date '+%a, %d %b %Y %H:%M:%S %z')

echo "Building fpp version $VERSION at $DATETIME"
mkdir -p "$PTH/usr/bin" &&
  mkdir -p "$PTH/usr/share/pathpicker/src/"

sed s#__version__#"$VERSION"# < "$PTH/DEBIAN/control" > "$PTH/DEBIAN/control.modif"
mv "$PTH/DEBIAN/control.modif" "$PTH/DEBIAN/control"

echo "===================="
echo "Control file is:"
echo "===================="
cat "$PTH/DEBIAN/control"
echo "===================="

cp -R "$PTH/../src" "$PTH/usr/share/pathpicker" &&
  cp "$PTH/../fpp" "$PTH/usr/share/pathpicker/fpp" &&
  cd "$PTH/usr/bin/"

echo "Creating symlink..."
ln -f -s ../share/pathpicker/fpp fpp
sed s#__version__#"$VERSION"# < "$PTH/usr/share/doc/pathpicker/changelog" > "$PTH/usr/share/doc/pathpicker/changelog.modif"
sed s#__date_timestamp__#"$DATETIME"# < "$PTH/usr/share/doc/pathpicker/changelog.modif" > "$PTH/usr/share/doc/pathpicker/changelog"

echo "===================="
echo "Changelog is:"
echo "===================="
cat  "$PTH/usr/share/doc/pathpicker/changelog"
echo "===================="

echo "Gziping..."
gzip -9 "$PTH/usr/share/doc/pathpicker/changelog" &&
  rm "$PTH/usr/share/doc/pathpicker/changelog.modif"

echo "Setting permissions..."
cd "$PTH"
find . -type d -exec chmod 755 {} \;
find . -type f -exec chmod 644 {} \;

echo "Building package..."
rm "$PTH/package.sh"
chmod 755 usr/share/pathpicker/fpp
fakeroot -- sh -c "chown -R root:root * && dpkg --build ./ ../pathpicker_${VERSION}_all.deb ;"
echo "Restoring template files..."
cd -
git checkout HEAD -- "$PTH/DEBIAN/control" "$PTH/usr/share/doc/pathpicker/changelog" "$PTH/package.sh"
chmod 777 "$PTH/package.sh"

echo 'Done! Check out fpp.deb'


#!/bin/bash
# Copyright (c) Facebook, Inc. and its affiliates.
#
# This source code is licensed under the MIT license found in the
# LICENSE file in the root directory of this source tree.
VERSION="$(python3 ./src/version.py)"
DEST="./dist/fpp.$VERSION.tar.gz"
mkdir -p ./dist/
tar -czf $DEST src/*.py fpp

sed -i '' -e "s#url .*#url \"https://github.com/facebook/PathPicker/releases/download/$VERSION/fpp.$VERSION.tar.gz\"#g" ./fpp.rb
HASH=$(cat $DEST | shasum -a 256 | cut -d " " -f 1)
sed -i '' -e "s#^  sha256 .*#  sha256 \"$HASH\"#g" ./fpp.rb

echo "Recipe updated with hash from $DEST"


#!/bin/bash
# Copyright (c) Facebook, Inc. and its affiliates.
#
# This source code is licensed under the MIT license found in the
# LICENSE file in the root directory of this source tree.
command -v a2x >/dev/null 2>&1 || { echo >&2 "I require a2x provided by asciidoc, but it's not installed.  Aborting."; exit 1; }
(cd src && python3 -m pathpicker.usage_strings > manpage.adoc)
a2x --format manpage "src/manpage.adoc" --destination-dir debian/usr/share/man/man1/


#!/bin/bash
# Copyright (c) Facebook, Inc. and its affiliates.
#
# This source code is licensed under the MIT license found in the
# LICENSE file in the root directory of this source tree.

set -e

# get the directory of this script so we can execute the related python
# http://stackoverflow.com/a/246128/212110
SOURCE=$0
# resolve $SOURCE until the file is no longer a symlink
while [ -h "$SOURCE" ]; do
  BASEDIR="$(cd -P "$(dirname "$SOURCE")" && pwd)"
  SOURCE="$(readlink "$SOURCE")"
  # if $SOURCE was a relative symlink, we need to resolve it relative to
  # the path where the symlink file was located
  [[ $SOURCE != /* ]] && SOURCE="$BASEDIR/$SOURCE"
done
BASEDIR="$(cd -P "$(dirname "$SOURCE")" && pwd)"
REPO_ROOT="$BASEDIR/.."

cd "$REPO_ROOT"

poetry install
poetry run mypy src
poetry run flake8 src
poetry run pylint src
poetry run pytest src/tests
poetry run vulture src


#!/usr/bin/env bash
# Copyright (c) Meta Platforms, Inc. and affiliates.
# All rights reserved.
#
# This source code is licensed under the BSD-style license found in the
# LICENSE file in the root directory of this source tree.

set -xeo pipefail

TOOLCHAIN_DIR=/opt/rh/devtoolset-8/root/usr/bin
if [[ -d "$TOOLCHAIN_DIR" ]]; then
    PATH="$TOOLCHAIN_DIR:$PATH"
fi

PROJECT_DIR=$(dirname "$0")
GETDEPS_PATHS=(
    "$PROJECT_DIR/build/fbcode_builder/getdeps.py"
    "$PROJECT_DIR/../../opensource/fbcode_builder/getdeps.py"
)

ROOT_DIR=$(pwd)
STAGE=${ROOT_DIR}/_build/
mkdir -p "$STAGE"

for getdeps in "${GETDEPS_PATHS[@]}"; do
    if [[ -x "$getdeps" ]]; then
        "$getdeps" build proxygen --current-project proxygen "$@" --install-prefix=${STAGE}
        exit 0
    fi
done

echo "Could not find getdeps.py!?" >&2
exit 1


#!/usr/bin/env bash
# Copyright (c) Meta Platforms, Inc. and affiliates.
# All rights reserved.
#
# This source code is licensed under the BSD-style license found in the
# LICENSE file in the root directory of this source tree.

## Run this script to build proxygen and run the tests. If you want to
## install proxygen to use in another C++ project on this machine, run
## the sibling file `reinstall.sh`.

# Obtain the base directory this script resides in.
BASE_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"

# Useful constants
COLOR_RED="\033[0;31m"
COLOR_GREEN="\033[0;32m"
COLOR_OFF="\033[0m"

function detect_platform() {
  unameOut="$(uname -s)"
  case "${unameOut}" in
      Linux*)     PLATFORM=Linux;;
      Darwin*)    PLATFORM=Mac;;
      *)          PLATFORM="UNKNOWN:${unameOut}"
  esac
  echo -e "${COLOR_GREEN}Detected platform: $PLATFORM ${COLOR_OFF}"
}

function install_dependencies_linux() {
  sudo apt-get install -yq \
    git \
    cmake \
    m4 \
    g++ \
    flex \
    bison \
    libgflags-dev \
    libgoogle-glog-dev \
    libkrb5-dev \
    libsasl2-dev \
    libnuma-dev \
    pkg-config \
    libssl-dev \
    libcap-dev \
    gperf \
    libevent-dev \
    libtool \
    libboost-all-dev \
    libjemalloc-dev \
    libsnappy-dev \
    wget \
    unzip \
    libiberty-dev \
    liblz4-dev \
    liblzma-dev \
    make \
    zlib1g-dev \
    binutils-dev \
    libsodium-dev \
    libdouble-conversion-dev
}

function install_dependencies_mac() {
  # install the default dependencies from homebrew
  brew install -f            \
    cmake                    \
    m4                       \
    boost                    \
    double-conversion        \
    gflags                   \
    glog                     \
    gperf                    \
    libevent                 \
    lz4                      \
    snappy                   \
    xz                       \
    openssl                  \
    libsodium

  brew link                 \
    cmake                   \
    boost                   \
    double-conversion       \
    gflags                  \
    glog                    \
    gperf                   \
    libevent                \
    lz4                     \
    snappy                  \
    openssl                 \
    xz                      \
    libsodium
}

function install_dependencies() {
  echo -e "${COLOR_GREEN}[ INFO ] install dependencies ${COLOR_OFF}"
  if [ "$PLATFORM" = "Linux" ]; then
    install_dependencies_linux
  elif [ "$PLATFORM" = "Mac" ]; then
    install_dependencies_mac
  else
    echo -e "${COLOR_RED}[ ERROR ] Unknown platform: $PLATFORM ${COLOR_OFF}"
    exit 1
  fi
}

function synch_dependency_to_commit() {
  # Utility function to synch a dependency to a specific commit. Takes two arguments:
  #   - $1: folder of the dependency's git repository
  #   - $2: path to the text file containing the desired commit hash
  if [ "$FETCH_DEPENDENCIES" = false ] ; then
    return
  fi
  DEP_REV=$(sed 's/Subproject commit //' "$2")
  pushd "$1"
  git fetch
  # Disable git warning about detached head when checking out a specific commit.
  git -c advice.detachedHead=false checkout "$DEP_REV"
  popd
}

function setup_fmt() {
  FMT_DIR=$DEPS_DIR/fmt
  FMT_BUILD_DIR=$DEPS_DIR/fmt/build/
  FMT_TAG=$(grep "subdir = " ../../build/fbcode_builder/manifests/fmt | cut -d "-" -f 2)
  if [ ! -d "$FMT_DIR" ] ; then
    echo -e "${COLOR_GREEN}[ INFO ] Cloning fmt repo ${COLOR_OFF}"
    git clone https://github.com/fmtlib/fmt.git  "$FMT_DIR"
  fi
  cd "$FMT_DIR"
  git fetch --tags
  git checkout "${FMT_TAG}"
  echo -e "${COLOR_GREEN}Building fmt ${COLOR_OFF}"
  mkdir -p "$FMT_BUILD_DIR"
  cd "$FMT_BUILD_DIR" || exit

  cmake                                           \
    -DCMAKE_PREFIX_PATH="$DEPS_DIR"               \
    -DCMAKE_INSTALL_PREFIX="$DEPS_DIR"            \
    -DCMAKE_BUILD_TYPE=RelWithDebInfo             \
    "$MAYBE_OVERRIDE_CXX_FLAGS"                   \
    -DFMT_DOC=OFF                                 \
    -DFMT_TEST=OFF                                \
    ..
  make -j "$JOBS"
  make install
  echo -e "${COLOR_GREEN}fmt is installed ${COLOR_OFF}"
  cd "$BWD" || exit
}

function setup_googletest() {
  GTEST_DIR=$DEPS_DIR/googletest
  GTEST_BUILD_DIR=$DEPS_DIR/googletest/build/
  GTEST_TAG=$(grep "subdir = " ../../build/fbcode_builder/manifests/googletest | cut -d "-" -f 2,3)
  if [ ! -d "$GTEST_DIR" ] ; then
    echo -e "${COLOR_GREEN}[ INFO ] Cloning googletest repo ${COLOR_OFF}"
    git clone https://github.com/google/googletest.git  "$GTEST_DIR"
  fi
  cd "$GTEST_DIR"
  git fetch --tags
  git checkout "${GTEST_TAG}"
  echo -e "${COLOR_GREEN}Building googletest ${COLOR_OFF}"
  mkdir -p "$GTEST_BUILD_DIR"
  cd "$GTEST_BUILD_DIR" || exit

  cmake                                           \
    -DCMAKE_PREFIX_PATH="$DEPS_DIR"               \
    -DCMAKE_INSTALL_PREFIX="$DEPS_DIR"            \
    -DCMAKE_BUILD_TYPE=RelWithDebInfo             \
    ..
  make -j "$JOBS"
  make install
  echo -e "${COLOR_GREEN}googletest is installed ${COLOR_OFF}"
  cd "$BWD" || exit
}

function setup_zstd() {
  ZSTD_DIR=$DEPS_DIR/zstd
  ZSTD_BUILD_DIR=$DEPS_DIR/zstd/build/cmake/builddir
  ZSTD_INSTALL_DIR=$DEPS_DIR
  ZSTD_TAG=$(grep "subdir = " ../../build/fbcode_builder/manifests/zstd | cut -d "-" -f 2 | cut -d "/" -f 1)
  if [ ! -d "$ZSTD_DIR" ] ; then
    echo -e "${COLOR_GREEN}[ INFO ] Cloning zstd repo ${COLOR_OFF}"
    git clone https://github.com/facebook/zstd.git "$ZSTD_DIR"
  fi
  cd "$ZSTD_DIR"
  git fetch --tags
  git checkout "v${ZSTD_TAG}"
  echo -e "${COLOR_GREEN}Building Zstd ${COLOR_OFF}"
  mkdir -p "$ZSTD_BUILD_DIR"
  cd "$ZSTD_BUILD_DIR" || exit
  cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo           \
    -DBUILD_TESTS=OFF                               \
    -DCMAKE_PREFIX_PATH="$ZSTD_INSTALL_DIR"         \
    -DCMAKE_INSTALL_PREFIX="$ZSTD_INSTALL_DIR"      \
    ${CMAKE_EXTRA_ARGS[@]+"${CMAKE_EXTRA_ARGS[@]}"} \
    ..
  make -j "$JOBS"
  make install
  echo -e "${COLOR_GREEN}Zstd is installed ${COLOR_OFF}"
  cd "$BWD" || exit
}

function setup_folly() {
  FOLLY_DIR=$DEPS_DIR/folly
  FOLLY_BUILD_DIR=$DEPS_DIR/folly/build/

  if [ ! -d "$FOLLY_DIR" ] ; then
    echo -e "${COLOR_GREEN}[ INFO ] Cloning folly repo ${COLOR_OFF}"
    git clone https://github.com/facebook/folly.git "$FOLLY_DIR"
  fi
  synch_dependency_to_commit "$FOLLY_DIR" "$BASE_DIR"/../build/deps/github_hashes/facebook/folly-rev.txt
  if [ "$PLATFORM" = "Mac" ]; then
    # Homebrew installs OpenSSL in a non-default location on MacOS >= Mojave
    # 10.14 because MacOS has its own SSL implementation.  If we find the
    # typical Homebrew OpenSSL dir, load OPENSSL_ROOT_DIR so that cmake
    # will find the Homebrew version.
    dir=/usr/local/opt/openssl
    if [ -d $dir ]; then
        export OPENSSL_ROOT_DIR=$dir
    fi
  fi
  echo -e "${COLOR_GREEN}Building Folly ${COLOR_OFF}"
  mkdir -p "$FOLLY_BUILD_DIR"
  cd "$FOLLY_BUILD_DIR" || exit
  MAYBE_DISABLE_JEMALLOC=""
  if [ "$NO_JEMALLOC" == true ] ; then
    MAYBE_DISABLE_JEMALLOC="-DFOLLY_USE_JEMALLOC=0"
  fi

  MAYBE_USE_STATIC_DEPS=""
  MAYBE_USE_STATIC_BOOST=""
  MAYBE_BUILD_SHARED_LIBS=""
  if [ "$BUILD_FOR_FUZZING" == true ] ; then
    MAYBE_USE_STATIC_DEPS="-DUSE_STATIC_DEPS_ON_UNIX=ON"
    MAYBE_USE_STATIC_BOOST="-DBOOST_LINK_STATIC=ON"
    MAYBE_BUILD_SHARED_LIBS="-DBUILD_SHARED_LIBS=OFF"
  fi

  cmake                                           \
    -DCMAKE_PREFIX_PATH="$DEPS_DIR"               \
    -DCMAKE_INSTALL_PREFIX="$DEPS_DIR"            \
    -DCMAKE_BUILD_TYPE=RelWithDebInfo             \
    -DBUILD_TESTS=OFF                             \
    "$MAYBE_USE_STATIC_DEPS"                      \
    "$MAYBE_USE_STATIC_BOOST"                     \
    "$MAYBE_BUILD_SHARED_LIBS"                    \
    "$MAYBE_OVERRIDE_CXX_FLAGS"                   \
    $MAYBE_DISABLE_JEMALLOC                       \
    ..
  make -j "$JOBS"
  make install
  echo -e "${COLOR_GREEN}Folly is installed ${COLOR_OFF}"
  cd "$BWD" || exit
}

function setup_fizz() {
  FIZZ_DIR=$DEPS_DIR/fizz
  FIZZ_BUILD_DIR=$DEPS_DIR/fizz/build/
  if [ ! -d "$FIZZ_DIR" ] ; then
    echo -e "${COLOR_GREEN}[ INFO ] Cloning fizz repo ${COLOR_OFF}"
    git clone https://github.com/facebookincubator/fizz "$FIZZ_DIR"
  fi
  synch_dependency_to_commit "$FIZZ_DIR" "$BASE_DIR"/../build/deps/github_hashes/facebookincubator/fizz-rev.txt
  echo -e "${COLOR_GREEN}Building Fizz ${COLOR_OFF}"
  mkdir -p "$FIZZ_BUILD_DIR"
  cd "$FIZZ_BUILD_DIR" || exit

  MAYBE_USE_STATIC_DEPS=""
  MAYBE_USE_SODIUM_STATIC_LIBS=""
  MAYBE_BUILD_SHARED_LIBS=""
  if [ "$BUILD_FOR_FUZZING" == true ] ; then
    MAYBE_USE_STATIC_DEPS="-DUSE_STATIC_DEPS_ON_UNIX=ON"
    MAYBE_USE_SODIUM_STATIC_LIBS="-Dsodium_USE_STATIC_LIBS=ON"
    MAYBE_BUILD_SHARED_LIBS="-DBUILD_SHARED_LIBS=OFF"
  fi

  cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo       \
    -DCMAKE_PREFIX_PATH="$DEPS_DIR"             \
    -DCMAKE_INSTALL_PREFIX="$DEPS_DIR"          \
    -DBUILD_TESTS=OFF                           \
    "$MAYBE_USE_STATIC_DEPS"                    \
    "$MAYBE_BUILD_SHARED_LIBS"                  \
    "$MAYBE_OVERRIDE_CXX_FLAGS"                 \
    "$MAYBE_USE_SODIUM_STATIC_LIBS"             \
    "$FIZZ_DIR/fizz"
  make -j "$JOBS"
  make install
  echo -e "${COLOR_GREEN}Fizz is installed ${COLOR_OFF}"
  cd "$BWD" || exit
}

function setup_wangle() {
  WANGLE_DIR=$DEPS_DIR/wangle
  WANGLE_BUILD_DIR=$DEPS_DIR/wangle/build/
  if [ ! -d "$WANGLE_DIR" ] ; then
    echo -e "${COLOR_GREEN}[ INFO ] Cloning wangle repo ${COLOR_OFF}"
    git clone https://github.com/facebook/wangle "$WANGLE_DIR"
  fi
  synch_dependency_to_commit "$WANGLE_DIR" "$BASE_DIR"/../build/deps/github_hashes/facebook/wangle-rev.txt
  echo -e "${COLOR_GREEN}Building Wangle ${COLOR_OFF}"
  mkdir -p "$WANGLE_BUILD_DIR"
  cd "$WANGLE_BUILD_DIR" || exit

  MAYBE_USE_STATIC_DEPS=""
  MAYBE_BUILD_SHARED_LIBS=""
  if [ "$BUILD_FOR_FUZZING" == true ] ; then
    MAYBE_USE_STATIC_DEPS="-DUSE_STATIC_DEPS_ON_UNIX=ON"
    MAYBE_BUILD_SHARED_LIBS="-DBUILD_SHARED_LIBS=OFF"
  fi

  cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo       \
    -DCMAKE_PREFIX_PATH="$DEPS_DIR"             \
    -DCMAKE_INSTALL_PREFIX="$DEPS_DIR"          \
    -DBUILD_TESTS=OFF                           \
    "$MAYBE_USE_STATIC_DEPS"                    \
    "$MAYBE_BUILD_SHARED_LIBS"                  \
    "$MAYBE_OVERRIDE_CXX_FLAGS"                 \
    "$WANGLE_DIR/wangle"
  make -j "$JOBS"
  make install
  echo -e "${COLOR_GREEN}Wangle is installed ${COLOR_OFF}"
  cd "$BWD" || exit
}

function setup_mvfst() {
  MVFST_DIR=$DEPS_DIR/mvfst
  MVFST_BUILD_DIR=$DEPS_DIR/mvfst/build/
  if [ ! -d "$MVFST_DIR" ] ; then
    echo -e "${COLOR_GREEN}[ INFO ] Cloning mvfst repo ${COLOR_OFF}"
    git clone https://github.com/facebookincubator/mvfst "$MVFST_DIR"
  fi
  synch_dependency_to_commit "$MVFST_DIR" "$BASE_DIR"/../build/deps/github_hashes/facebookincubator/mvfst-rev.txt
  echo -e "${COLOR_GREEN}Building Mvfst ${COLOR_OFF}"
  mkdir -p "$MVFST_BUILD_DIR"
  cd "$MVFST_BUILD_DIR" || exit

  MAYBE_USE_STATIC_DEPS=""
  MAYBE_BUILD_SHARED_LIBS=""
  if [ "$BUILD_FOR_FUZZING" == true ] ; then
    MAYBE_USE_STATIC_DEPS="-DUSE_STATIC_DEPS_ON_UNIX=ON"
    MAYBE_BUILD_SHARED_LIBS="-DBUILD_SHARED_LIBS=OFF"
  fi

  cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo       \
    -DCMAKE_PREFIX_PATH="$DEPS_DIR"             \
    -DCMAKE_INSTALL_PREFIX="$DEPS_DIR"          \
    -DBUILD_TESTS=OFF                           \
    "$MAYBE_USE_STATIC_DEPS"                    \
    "$MAYBE_BUILD_SHARED_LIBS"                  \
    "$MAYBE_OVERRIDE_CXX_FLAGS"                 \
    "$MVFST_DIR"
  make -j "$JOBS"
  make install
  echo -e "${COLOR_GREEN}Mvfst is installed ${COLOR_OFF}"
  cd "$BWD" || exit
}

# Parse args
JOBS=8
WITH_QUIC=false
INSTALL_DEPENDENCIES=true
FETCH_DEPENDENCIES=true
PREFIX=""
COMPILER_FLAGS=""
USAGE="./build.sh [-j num_jobs] [-q|--with-quic] [-m|--no-jemalloc] [--no-install-dependencies] [-p|--prefix] [-x|--compiler-flags] [--no-fetch-dependencies]"
while [ "$1" != "" ]; do
  case $1 in
    -j | --jobs ) shift
                  JOBS=$1
                  ;;
    -q | --with-quic )
                  WITH_QUIC=true
                  ;;
    -m | --no-jemalloc )
                  NO_JEMALLOC=true
                  ;;
    --no-install-dependencies )
                  INSTALL_DEPENDENCIES=false
          ;;
    --no-fetch-dependencies )
                  FETCH_DEPENDENCIES=false
          ;;
    --build-for-fuzzing )
                  BUILD_FOR_FUZZING=true
      ;;
    -t | --no-tests )
                  NO_BUILD_TESTS=true
      ;;
    -p | --prefix )
                  shift
                  PREFIX=$1
      ;;
    -x | --compiler-flags )
                  shift
                  COMPILER_FLAGS=$1
      ;;
    * )           echo $USAGE
                  exit 1
esac
shift
done

detect_platform

if [ "$INSTALL_DEPENDENCIES" == true ] ; then
  install_dependencies
fi

MAYBE_OVERRIDE_CXX_FLAGS=""
if [ -n "$COMPILER_FLAGS" ] ; then
  MAYBE_OVERRIDE_CXX_FLAGS="-DCMAKE_CXX_FLAGS=$COMPILER_FLAGS"
fi

BUILD_DIR=_build
mkdir -p $BUILD_DIR

set -e nounset
trap 'cd $BASE_DIR' EXIT
cd $BUILD_DIR || exit
BWD=$(pwd)
DEPS_DIR=$BWD/deps
mkdir -p "$DEPS_DIR"

# Must execute from the directory containing this script
cd "$(dirname "$0")"

setup_fmt
setup_googletest
setup_zstd
setup_folly
setup_fizz
setup_wangle
MAYBE_BUILD_QUIC=""
if [ "$WITH_QUIC" == true ] ; then
  setup_mvfst
  MAYBE_BUILD_QUIC="-DBUILD_QUIC=On"
fi

MAYBE_BUILD_FUZZERS=""
MAYBE_USE_STATIC_DEPS=""
MAYBE_LIB_FUZZING_ENGINE=""
MAYBE_BUILD_SHARED_LIBS=""
MAYBE_BUILD_TESTS="-DBUILD_TESTS=ON"
if [ "$NO_BUILD_TESTS" == true ] ; then
  MAYBE_BUILD_TESTS="-DBUILD_TESTS=OFF"
fi
if [ "$BUILD_FOR_FUZZING" == true ] ; then
  MAYBE_BUILD_FUZZERS="-DBUILD_FUZZERS=ON"
  MAYBE_USE_STATIC_DEPS="-DUSE_STATIC_DEPS_ON_UNIX=ON"
  MAYBE_LIB_FUZZING_ENGINE="-DLIB_FUZZING_ENGINE='$LIB_FUZZING_ENGINE'"
  MAYBE_BUILD_SHARED_LIBS="-DBUILD_SHARED_LIBS=OFF"
fi

if [ -z "$PREFIX" ]; then
  PREFIX=$BWD
fi

# Build proxygen with cmake
cd "$BWD" || exit
cmake                                     \
  -DCMAKE_BUILD_TYPE=RelWithDebInfo       \
  -DCMAKE_PREFIX_PATH="$DEPS_DIR"         \
  -DCMAKE_INSTALL_PREFIX="$PREFIX"        \
  "$MAYBE_BUILD_QUIC"                     \
  "$MAYBE_BUILD_TESTS"                    \
  "$MAYBE_BUILD_FUZZERS"                  \
  "$MAYBE_BUILD_SHARED_LIBS"              \
  "$MAYBE_OVERRIDE_CXX_FLAGS"             \
  "$MAYBE_USE_STATIC_DEPS"                \
  "$MAYBE_LIB_FUZZING_ENGINE"             \
  ../..

make -j "$JOBS"
echo -e "${COLOR_GREEN}Proxygen build is complete. To run unit test: \
  cd _build/ && make test ${COLOR_OFF}"


#!/usr/bin/env bash
# Copyright (c) Meta Platforms, Inc. and affiliates.
# All rights reserved.
#
# This source code is licensed under the BSD-style license found in the
# LICENSE file in the root directory of this source tree.

## Run this script to (re)install proxygen and its dependencies (fbthrift
## and folly). You must first compile all the dependencies before running this. This
## Usually this is done by first running `deps.sh`.

set -e
start_dir=$(pwd)
trap 'cd $start_dir' EXIT

# Must execute from the directory containing this script
cd "$(dirname "$0")"

cd _build
# Uninstall is expected to fail the first time
make uninstall || true
make install

# Make sure the libraries are available
# Linux only
/sbin/ldconfig || true


#!/usr/bin/env bash
# Copyright (c) Meta Platforms, Inc. and affiliates.
# All rights reserved.
#
# This source code is licensed under the BSD-style license found in the
# LICENSE file in the root directory of this source tree.

set -e

# Setup and validate arguments

if [ "x$1" != "x" ]; then
  ENUM_FILE_LIST="$1"
fi
if [ "x$2" != "x" ];then
  FBCODE_DIR="$2"
fi
if [ "x$3" != "x" ]; then
  OUTPUT_DIR="$3"
fi
if [ "x$4" != "x" ]; then
  GPERF="$4"
fi

# The `awk` scripts aren't nearly as hairy as it seems. The only real trick is
# the first line. We're processing two files -- the result of a `cat` pipeline
# above, plus a template. The "NR == FNR" compares the current file's
# line number with the total number of lines we've processed -- i.e., that test
# means "am I in the first file?" So we suck those lines aside. Then we process
# the second file, replacing "%%%%%" with some munging of the lines we sucked
# aside from the `cat` pipeline. They are written in awk since it isn't really
# worth the build system BS of calling out to Python (which is unfortunately
# particularly annoying in Facebook's internal build system) and more portable
# (and less hairy honestly) than the massive `sed` pipeline which used to be
# here. And it really isn't that bad, this is the sort of thing `awk` was
# designed for.

AWK_HEADER_SCRIPT='
  NR == FNR {
    n[FNR] = $1;
    max = FNR;
    next
  }
  $1 == "%%%%%" {
    for (i in n) {
      h = n[i];
      gsub("-", "_", h);
      gsub(":", "COLON_", h);
      print "  HTTP_HEADER_" toupper(h) " = " i+1 ","
    };
    next
  }
  $1 == "$$$$$" {
    print "  constexpr static uint64_t num_codes = " max+2 ";";
    next
  }
  {
    gsub("%%name%%", "HTTPCommonHeaders");
    gsub("%%name_enum%%", "HTTPHeaderCode");
    gsub("%%enum_prefix%%", "HTTP_HEADER");
    gsub("%%table_type_name%%", "HTTPCommonHeaderTableType");
    print
  }
'

AWK_SOURCE_SCRIPT='
  NR == FNR {
    n[FNR] = $1;
    next
  }
  $1 == "%%%%%" {
    print "%%";
    for (i in n) {
      h = n[i];
      gsub("-", "_", h);
      gsub(":", "COLON_", h);
      print n[i] ", HTTP_HEADER_" toupper(h)
    };
    print "%%";
    next
  }
  {
    gsub("%%name%%", "HTTPCommonHeaders");
    gsub("%%name_internal%%", "HTTPCommonHeadersInternal");
    gsub("%%name_container%%", "HTTPCommonHeaderName");
    gsub("%%name_enum%%", "HTTPHeaderCode");
    gsub("%%header%%", "proxygen/lib/http/HTTPCommonHeaders.h");
    gsub("%%enum_other%%", "HTTP_HEADER_OTHER");
    gsub("%%table_type_name%%", "HTTPCommonHeaderTableType");
    print
  }
'

# Load up the utility method for generating our desired perfect hash table
# shellcheck source=/dev/null
. "${FBCODE_DIR?}/proxygen/lib/utils/gen_perfect_hash_table.sh"

generate_perfect_hash_table \
  "${ENUM_FILE_LIST}" \
  "${FBCODE_DIR}/proxygen/lib/utils/perfect_hash_table_template.h" \
  "${AWK_HEADER_SCRIPT}" \
  "${OUTPUT_DIR}/HTTPCommonHeaders.h" \
  "${FBCODE_DIR}/proxygen/lib/utils/perfect_hash_table_template.cpp.gperf" \
  "${AWK_SOURCE_SCRIPT}" \
  "${OUTPUT_DIR?}/HTTPCommonHeaders.cpp" \
  "${GPERF}"


#!/usr/bin/env bash
# Copyright (c) Meta Platforms, Inc. and affiliates.
# All rights reserved.
#
# This source code is licensed under the BSD-style license found in the
# LICENSE file in the root directory of this source tree.

# Utility method for generating the header and source code for a generic perfect
# hash table data structure by leveraging gperf, input template header and gperf
# source files, and input word list files that respresent the enum fields.
function generate_perfect_hash_table {

  # $1 is a space separated list of files that store words that will correspond
  #    to output enum fields.
  # $2 is the path to the input template header file.
  # $3 is the path to the 'awk' script that will output format the template
  #    header file.
  # $4 is the desired output path of the generated header file.
  # $5 is the path to the input template gperf file.
  # $6 is the path to the 'awk' script that will format the template gperf file
  #    prior to it being passed to the gperf binary.
  # $7 is the desired output path of the generated source file.
  # $8 is the optional path to the gperf binary to use.

  # The inputs to 'cat' below are not quoted as they are space separated lists
  # of strings (files); 'cat' will concatenate them (if applicable) and pipe the
  # combined output onwards to 'awk'.

  # Generate output header file.
  LC_ALL=C sort -u ${1?} | awk "${3?}" - "${2?}" > "${4?}"

  # Generate output source file.
  # We also sub out the default 'FALLTHROUGH' comment statements as modern
  # compilers will raise warnings unless the fallthrough is explicit.
  LC_ALL=C sort -u ${1?} | awk "${6?}" - "${5?}" | \
  ${8:-gperf} -m5 -D --output-file="${7?}"
  perl -p -i -e "s/\/\*FALLTHROUGH\*\//FOLLY_FALLTHROUGH;/g" "${7?}"

  # Here we delete one of the comment lines gperf adds to the top of the file.
  # i.e. /* Command-line: .../gperf -m5 --output-file=...  */
  # The reason this line is removed is the '...'s are actually expanded to
  # absolute paths on the build machine which prevents buck's cache from being
  # used effectively.
  # Prefer perl to sed so that it works on both Mac and Linux.
  perl -n -i -e "print unless m /\\/* Command-line: /" "${7?}"
}


#!/bin/bash
# Copyright (c) Meta Platforms, Inc. and affiliates.
#
# This source code is licensed under the MIT license found in the
# LICENSE file in the root directory of this source tree.

set +e
python3 ../../tools/pysa_integration_tests/run.py \
    --skip-model-verification \
    --run-from-source

exit_code=$?

if [[ "$exit_code" != "0" ]]; then
    echo "--- raw_results.json --"
    cat raw_results.json
    echo "---"
fi

exit $exit_code


#!/bin/bash
# Copyright (c) Meta Platforms, Inc. and affiliates.
#
# This source code is licensed under the MIT license found in the
# LICENSE file in the root directory of this source tree.

# Source this file to run it:
# . ./setup.sh

pip install -r requirements.txt
rm ../../.pyre_configuration
echo '{
    "source_directories": ["."],
    "search_path": [
        "../../stubs/integration_test/fixture_stubs",
        {"site-package": "flask"},
        {"site-package": "werkzeug"},
        {"site-package": "jsonpickle"}
    ],
    "taint_models_path": "../../stubs"
}' > ./.pyre_configuration