#! /bin/bash

#Allow Exclamation points to be used in commands by turning off the history
set +H
DoDryRun=0

#Argument is a seed file
#Seed File format. Except for the first row, there are three colunms. one is the size, 
#one is the path. Third is the link destination which is Only valid for symlinks
#if the size is d, then the item is a directory
#if the size is fifo, then the item is a FIFO
#if the size is socket, then the item is a socket
#if the size is link, then the item is a symlink
#If the size is deny, then a permisson of 000 will be chmoded for the item
#rows have unix newlines, columns are separated by $'\r'
#For best handling in the array since spaces and tabs are used in test filenames
#Except the first row is the datestamp
SeedFile="$1"
if [[ (! -z $SeedFile) && (! -e "$SeedFile") ]]
then
  echo "$SeedFile does not exist"
  exit
fi

##########Test Parameters

#Control file names, only a subset of items to create
#names with non alpha-numeric chars, or if incorrect Unicode
#chars should be created in the names or not.
MAX_FILES_WITH_NONLETTERS=1024
MAX_FOLDERS_WITH_NONLETTERS=1024
TEST_INVALID_UNICODE_CHARS=0

#Control file name length, the maximum random length.
#or the outlier random length (if the random legnth generated is 0)
#Use the outlier length
MAX_FILE_LENGTH=10
FILE_LENGTH_IF_ZERO=255

#Number of items to create
LARGE_SUBIR_FILE_COUNT=1000
MAX_FILES_COUNT=3
MAX_FOLDER_COUNT=1000
MAX_FILE_COUNT=10000
MAX_SYMLINK_COUNT=10
MAX_DENY_COUNT=0

#Filesystem controls
DEFAULT_FS_SIZE=50G
DEFAULT_SOURCE_FS=ext4
DEFAULT_TARGET_FS=btrfs

##########

if [[ -z $SeedFile ]]
then
  DateStamp=$(date +%s)

  FS_SIZE=$DEFAULT_FS_SIZE
  SOURCE_FS=$DEFAULT_SOURCE_FS
  TARGET_FS=$DEFAULT_TARGET_FS
else
  SeedSettingsArray=$(head -1 $SeedFile)
  IFS=$'\r'
  SeedSettingsArray=($SeedSettingsArray)
  unset IFS

  DateStamp=${SeedSettingsArray[0]}
  FS_SIZE=${SeedSettingsArray[1]}
  if [[ -z $FS_SIZE ]]
  then
    FS_SIZE=$DEFAULT_FS_SIZE
  fi

  SOURCE_FS=${SeedSettingsArray[2]}
  if [[ -z $SOURCE_FS ]]
  then
    SOURCE_FS=$DEFAULT_SOURCE_FS
  fi

  TARGET_FS=${SeedSettingsArray[3]}
  if [[ -z $TARGET_FS ]]
  then
    TARGET_FS=$DEFAULT_TARGET_FS
  fi
fi



#Count Number of files and folders made
ItemCount=0
FolderCount=0
FileCount=0
SymlinkCount=0
DenyCount=0

if [[ -e /usr/lib/bash/mkdir ]]
then
  enable -f /usr/lib/bash/mkdir mkdir
fi

if [[ $TEST_INVALID_UNICODE_CHARS == 1 ]]
then
  OLD_LC_ALL=$LC_ALL
  OLD_LANG=$LANG

  LC_ALL=C
  LANG=C
fi

echo "Warning: This tries to create GB worth of files in /tmp."
echo "This is meant to try to assist with possibly replicating https://bugs.kde.org/show_bug.cgi?id=162211"
echo "Warning: This script when running without a seed file, generates many \$RANDOM numbers, which might use up entropy"
echo "You can specify a seed file as an argument to build a previously created copy source tree"
echo "It requires sudo access to mount and unmount the test loopback file systems it creates"
echo "This script runs kioclient as a user, but will prompt for sudo access to do things like mount and unmount the loopback filesystems."
echo ""
echo "This script runs faster with the bash-builtins package"
echo ""
echo "Press Enter..."
read a

echo "Workdir is /tmp/kiocopy/$DateStamp/"

mkdir /tmp/kiocopy
mkdir /tmp/kiocopy/$DateStamp
if [[ -z $SeedFile ]]
then
  echo $DateStamp$'\r'$FS_SIZE$'\r'$SOURCE_FS$'\r'$TARGET_FS > /tmp/kiocopy/$DateStamp/Seed.txt
fi

mkdir /tmp/kiocopy/$DateStamp/folder_src
mkdir /tmp/kiocopy/$DateStamp/folder_dest
mkdir /tmp/kiocopy/$DateStamp/logs
rm /tmp/kiocopy/$DateStamp/logs/self.log

#Function to create an image, (first argument), mount it to a path (second argument), with the specified type (third argument), and size (fourth argument)
function MountFSImage
{
  ImagePath=$1
  MountPath=$2
  FSType=$3
  FSSize=$4
  mountpoint -q "$MountPath"
  if [[ $? == 0 ]]
  then
    sudo umount "$MountPath"
  fi
  if [[ -e "$ImagePath" ]]
  then
    rm "$ImagePath"
  fi
  truncate --size "$FSSize" "$ImagePath"
  mkdir -p "$MountPath"
  if [[ $FSType == ntfs ]]
  then
    mkfs."$FSType" -F -Q "$ImagePath"
    sudo mount -o loop  "$ImagePath" "$MountPath"
    MountResult=$?
  elif [[ $FSType == fat ]]
  then
    mkfs."$FSType" "$ImagePath"
    sudo mount -o loop,rw,uid=$UID  "$ImagePath" "$MountPath"
    MountResult=$?
  else
    mkfs."$FSType" "$ImagePath"
    sudo mount -o loop  "$ImagePath" "$MountPath"
    MountResult=$?
  fi
  if [[ $MountResult != 0 ]]
  then
    echo "$ImagePath ( type: $FSType Size: $FSSize ) failed to mount at $MountPath"
    exit
  fi
  sudo chown $UID "$MountPath"
}

#Create the filesystems
MountFSImage /tmp/kiocopy/$DateStamp/fsimg_src /tmp/kiocopy/$DateStamp/folder_src  $SOURCE_FS $FS_SIZE
MountFSImage /tmp/kiocopy/$DateStamp/fsimg_dest /tmp/kiocopy/$DateStamp/folder_dest $TARGET_FS $FS_SIZE



mkdir /tmp/kiocopy/$DateStamp/folder_src/testdir

#Get the number of Bytes a char uses. Convert it to its raw UTF32 value.
#Determine hardcoded, the number of bytes needed for that UTF32 value for the UTF8 bytes the char actually is stored in
#Upper ASCII chars are 2 byte UTF chars
# 0XXXXXXX                            - 1 byte,   1 bit padding,   7 bits free, max 127
# 110XXXXX 10XXXXXX                   - 2 bytes,  5 bits padding, 11 bits free, max 2047
# 1110XXXX 10XXXXXX 10XXXXXX          - 3 bytes,  8 bits padding, 16 bits free, max 65535
# 11110XXX 10XXXXXX 10XXXXXX 10XXXXXX - 4 bytes, 11 bits padding, 21 bits free, max 1114111
# Thanks to https://naveenr.net/unicode-character-set-and-utf-8-utf-16-utf-32-encoding/
#First argument is the char, the second variable is the variable to populate with the number of bytes for that char
#Third is the optional argument is the name of the variable to populate the count with
function CharByteCount
{
  Byte=$1
  printf -v charvalue '%u' "'$Byte"

  #ASCII, 1 byte. Only lower ascii (0-127) seem to take 1 byte. 1 bit padding
  if [[ $charvalue -le 127 ]]
  then
    ByteCount=1
  #2 Bytes, 5 bits padded. Upper ASCII chars seem to be treated as 2 bytes too
  elif [[ $charvalue -le 2047 ]]
  then
    ByteCount=2
  #3 Bytes, 8 bits padded
  elif [[ $charvalue -le 65535 ]]
  then
    ByteCount=3
  #4 bytes, 11 bits padded, UTF32 max is 1114111
  elif [[ $charvalue -le 1114111 ]]
  then
    ByteCount=4
  fi


  if [[ ! -z $2 ]]
  then
    printf -v "$2" '%s' "$ByteCount"
  else
    echo "$ByteCount"
  fi
}

#Limit a given string to a number of given BYTES.
#First argument is the string
#Second argument is the number of bytes
#Third optional argument is the variable to populate with the string
function CapStringSize
{
  InString=$1
  MaxBytes=$2
  
  TotalByteCount=0
  TotalChars=${#InString}
  OutCappedString=""
  for (( StrItr=0 ; StrItr < $TotalChars ; StrItr++ ))
  do
    CurrentChar=${InString:$StrItr:1}
    CharByteCount "$CurrentChar" CharBytes
    ((TotalByteCount+=CharBytes))
    if [[ $TotalByteCount -le $MaxBytes ]]
    then
      OutCappedString+=$CurrentChar
    else
      break
    fi
  done

  if [[ ! -z $3 ]]
  then
    printf -v "$3" '%s' "$OutCappedString"
  else
    echo "$OutCappedString"
  fi
}

#Generate random char of type
#0=lowercase
#1=uppercase
#2=number
#4=silly chars that break scripts and parsing
#5=Odd ascii/unicode points
function CreateRandomChar {
  CharType=$1
  LowercaseChars=(a b c d e f g h i j k l m n o p q r s t u v w x y z)
  UppercaseChars=(A B C D E F G H I J K L M N O P Q R S T U V W X W Z)
  NumberChars=(0 1 2 3 4 5 6 7 8 9)
  WhitespaceChars=(" ")
  SillyChars=("\\" "\"" ";" ":" "&" "#" "*" "@" "~" "{" "}" "(" ")" "'" "?" "<" ">" " " $'\t' "." "," "-")
  OddChars=("©" "¾" "📋" "🐧" "䉎" "𖡒" "ԑ" "ij" "®" "╚" "â" "ä" "à" "å" "ç" "ê" "ë" "è" "ï" "î" "ì" "æ" "Ä" "Å" "Ä" "É" "Æ")
  if [[ $CharType == 0 ]]
  then
    MaxElement=${#LowercaseChars[@]}
    ChooseElement=$(( $RANDOM % $MaxElement ))
    ChooseChar=${LowercaseChars[$ChooseElement]}
  elif [[ $CharType == 1 ]]
  then
    MaxElement=${#UppercaseChars[@]}
    ChooseElement=$(( $RANDOM % $MaxElement ))
    ChooseChar=${UppercaseChars[$ChooseElement]}
  elif [[ $CharType == 2 ]]
  then
    MaxElement=${#NumberChars[@]}
    ChooseElement=$(( $RANDOM % $MaxElement ))
    ChooseChar=${NumberChars[$ChooseElement]}
  elif [[ $CharType == 3 ]]
  then
    MaxElement=${#SillyChars[@]}
    ChooseElement=$(( $RANDOM % $MaxElement ))
    ChooseChar=${SillyChars[$ChooseElement]}
  elif [[ $CharType == 4 ]]
  then
    MaxElement=${#OddChars[@]}
    ChooseElement=$(( $RANDOM % $MaxElement ))
    ChooseChar=${OddChars[$ChooseElement]}
  fi

  if [[ ! -z $2 ]]
  then
    printf -v "$2" '%s' "$ChooseChar"
  else
    echo "$ChooseChar"
  fi
}



#First argument if if should be a file name or folder name
#Second is argument with the name
function CreateObjectName {
  IsFile=$1
  if [[ $IsFile != 0 && $IsFile != 1 ]]
  then
    IsFile=0
  fi

  LengthHint=$(($RANDOM % $MAX_FILE_LENGTH))
  if [[ $LengthHint -eq 0 ]]
  then
    Length=$FILE_LENGTH_IF_ZERO
  else
    Length=$LengthHint
  fi

  NewName=""
  for (( CharItr=0 ; CharItr < $Length ; CharItr++ ))
  do
    #Dont flood with too many unreadable symbols, will make reading logs hard for devs, max it out
    if [[ $IsFile == 1 ]]
    then
      if [[ $FileCount -le $MAX_FILES_WITH_NONLETTERS ]]
      then
        NameCharType=$(($RANDOM % 5))
      else
        NameCharType=$(($RANDOM % 3))
      fi
    else
      if [[ $FolderCount -le $MAX_FOLDERS_WITH_NONLETTERS ]]
      then
        NameCharType=$(($RANDOM % 5))
      else
        NameCharType=$(($RANDOM % 3))
      fi
    fi
    CreateRandomChar $NameCharType NameChar
    NewName+=$NameChar
  done
  
  AddExt=$(( $RANDOM % 5 ))
  if [[ $AddExt == 1 ]]
  then
    ExtChar1Type=$(($RANDOM % 3))
    ExtChar2Type=$(($RANDOM % 3))
    ExtChar3Type=$(($RANDOM % 3))
    CreateRandomChar $ExtChar1Type ExtChar1
    CreateRandomChar $ExtChar2Type ExtChar2
    CreateRandomChar $ExtChar3Type ExtChar3
    NewName+="."
    NewName+=$ExtChar1
    NewName+=$ExtChar2
    NewName+=$ExtChar3
  fi

  if [[ ! -z $2 ]]
  then
    printf -v "$2" '%s' "$NewName"
  else
    echo "$NewName"
  fi
}

#This creates Folders, it randomly selects the index of a folder, grabs the name, creates a random folder name
#and creates the folder name, saving the full path to the array. this array of folders is used to create more folders
#since the full path is in the array, and the name gets added.
FolderList=()
FolderList+=("/tmp/kiocopy/$DateStamp/folder_src/testdir/")
function CreateSeededFolder {
  ArrFolderCount=${#FolderList[@]}
  DestFolderID=$(( $RANDOM*$RANDOM % $ArrFolderCount ))
  DestFolderName=${FolderList[$DestFolderID]}

  CreateObjectName 0 NewFolderName
  NewFolderName=$ItemCount$NewFolderName
  if [[ $TEST_INVALID_UNICODE_CHARS == 1 ]]
  then
    NewFolderName=${NewFolderName::255}
  else
    CapStringSize "$NewFolderName" 255 NewFolderName
  fi

  LastDestFolderName=${DestFolderName:$((${#DestFolderName} -1 )):1}
  if [[ $LastDestFolderName == "/" ]]
  then
    NewPath="$DestFolderName$NewFolderName"
  else
    NewPath="$DestFolderName/$NewFolderName"
  fi

  FolderList+=("$NewPath")
  ((ItemCount++))
  ((FolderCount++))

  echo "d"$'\r'"$NewPath" >> /tmp/kiocopy/$DateStamp/Seed.txt
}


#This creates files, it randomly selects the index of a folder, grabs the name, creates a random file name
#and creates the file, saving the full path to an array
FileList=()
function CreateSeededFile {
  ArrFolderCount=${#FolderList[@]}
  DestFolderID=$(( $RANDOM*$RANDOM % $ArrFolderCount ))
  DestFolderName=${FolderList[$DestFolderID]}

  CreateObjectName 1 NewFileName
  NewFileName=$ItemCount$NewFileName
  if [[ $TEST_INVALID_UNICODE_CHARS == 1 ]]
  then
    NewFileName=${NewFileName::255}
  else
    CapStringSize "$NewFileName" 255 NewFileName
  fi

  LastDestFolderName=${DestFolderName:$((${#DestFolderName} -1 )):1}
  if [[ $LastDestFolderName == "/" ]]
  then
    NewPath="$DestFolderName$NewFileName"
  else
    NewPath="$DestFolderName/$NewFileName"
  fi
  
  FileList+=("$NewPath")

  #Determine what the size of the file should be
  if [[ $FileCount -le 3 ]]
  then
    NewSize=1073741824
  elif [[ ($FileCount -gt 3) && ($FileCount -le 13) ]]
  then
    NewSize=104857600
  elif [[ ($FileCount -gt 13) && ($FileCount -le 10013) ]]
  then
    NewSize=0
  elif [[ ($FileCount -gt 10013) && ($FileCount -le 10113) ]]
  then
    NewSize=1048576
  elif [[ ($FileCount -gt 10113) && ($FileCount -le 10123) ]]
  then
    #NewSize=fifo
    NewSize=1024
  elif [[ ($FileCount -gt 10133) && ($FileCount -le 10143) ]]
  then
    #DestFolderName=${FolderList[0]}
    #NewPath="$DestFolderName$NewFileName"
    #NewSize=socket
    NewSize=1024
  else
    NewSize=1024
  fi
  ((ItemCount++))
  ((FileCount++))

  echo "$NewSize"$'\r'"$NewPath" >> /tmp/kiocopy/$DateStamp/Seed.txt
}

#Fill one folder with lots of files
FilesList=()
function CreateSeededFiles {
  ArrFolderCount=${#FolderList[@]}
  DestFolderID=$(( $RANDOM*$RANDOM % $ArrFolderCount ))
  DestFolderName=${FolderList[$DestFolderID]}

  CreateObjectName 1 NewFileName
  NewFileName=$ItemCount$NewFileName
  if [[ $TEST_INVALID_UNICODE_CHARS == 1 ]]
  then
    NewFileName=${NewFileName::240}
  else
    CapStringSize "$NewFileName" 240 NewFileName
  fi

  LastDestFolderName=${DestFolderName:$((${#DestFolderName} -1 )):1}
  if [[ $LastDestFolderName == "/" ]]
  then
    NewPath="$DestFolderName$NewFileName"
  else
    NewPath="$DestFolderName/$NewFileName"
  fi
  
  FilesList+=("$NewPath")

  NewSize=1024
  ((ItemCount++))

  for (( LargeFileItr=0 ; LargeFileItr < $LARGE_SUBIR_FILE_COUNT ; LargeFileItr++ ))
  do
    echo "$NewSize"$'\r'"$NewPath$LargeFileItr" >> /tmp/kiocopy/$DateStamp/Seed.txt
  done
}

#Create a live and dead symlink, for files or folers
SymlinkList=()
function CreateSeededSymlink {
  ArrFolderCount=${#FolderList[@]}
  ArrFileCount=${#FileList[@]}
  DestFolderID=$(( $RANDOM*$RANDOM % $ArrFolderCount ))
  DestFolderName=${FolderList[$DestFolderID]}

  ItemType=$(( $RANDOM % 2 ))
  if [[ $ItemType == 0 ]]
  then
    TargetItemID=$(( $RANDOM*$RANDOM % $ArrFolderCount ))
    TargetItemName=${FolderList[$TargetItemID]}
  else
    TargetItemID=$(( $RANDOM*$RANDOM % $ArrFileCount ))
    TargetItemName=${FileList[$TargetItemID]}
  fi

  CreateObjectName 0 NewSymlinkName
  NewSymlinkName=$ItemCount$NewSymlinkName
  if [[ $TEST_INVALID_UNICODE_CHARS == 1 ]]
  then
    NewSymlinkName=${NewSymlinkName::250}
  else
    CapStringSize "$NewSymlinkName" 250 NewSymlinkName
  fi

  LastDestFolderName=${DestFolderName:$((${#DestFolderName} -1 )):1}
  if [[ $LastDestFolderName == "/" ]]
  then
    NewPath="$DestFolderName$NewSymlinkName"
  else
    NewPath="$DestFolderName/$NewSymlinkName"
  fi

  SymlinkList+=("$NewPath")

  ((ItemCount++))
  ((SymlinkCount++))

  echo "link"$'\r'"$NewPath"$'\r'"$TargetItemName" >> /tmp/kiocopy/$DateStamp/Seed.txt
  echo "link"$'\r'"${NewPath}dead"$'\r'"${TargetItemName}dead" >> /tmp/kiocopy/$DateStamp/Seed.txt
}


DenyList=()
function CreateSeededDeny {
  ArrFolderCount=${#FolderList[@]}
  ArrFileCount=${#FileList[@]}

  ItemType=$(( $RANDOM % 2 ))
  if [[ $ItemType == 0 ]]
  then
    DenyItemID=$(( $RANDOM*$RANDOM % $ArrFolderCount ))
    DenyItemName=${FolderList[$DenyItemID]}
  else
    DenyItemID=$(( $RANDOM*$RANDOM % $ArrFileCount ))
    DenyItemName=${FileList[$DenyItemID]}
  fi

  #If the root object is denied, then the whole test won't work
  if [[ $DenyItemID != 0 ]]
  then
    DenyList+=($DenyItemName)
    ((DenyCount++))

    echo "deny"$'\r'"$DenyItemName" >> /tmp/kiocopy/$DateStamp/Seed.txt
  fi
}

if [[ -z $SeedFile ]]
then
  #Create the Folder Tree
  echo "Creating folder seeds..."
  for (( FolderItr=0 ; FolderItr < $MAX_FOLDER_COUNT ; FolderItr++ ))
  do
    CreateSeededFolder
  done

  #Create the files
  echo "Creating file seeds..."
  for (( FileItr=0 ; FileItr < $MAX_FILE_COUNT ; FileItr++ ))
  do
    CreateSeededFile
  done

  #Create a large amount of files in random folders
  echo "Creating multiple file seeds..."
  for (( FilesItr=0 ; FilesItr < $MAX_FILES_COUNT ; FilesItr++ ))
  do
    CreateSeededFiles
  done

  #Create symlinks
  echo "Creating symlink seeds..."
  for (( LinkItr=0 ; LinkItr < $MAX_SYMLINK_COUNT ; LinkItr++ ))
  do
    CreateSeededSymlink
  done

  #Create deny items
  echo "Creating deny seeds..."
  for (( DenyItr=0 ; DenyItr < $MAX_DENY_COUNT ; DenyItr++ ))
  do
    CreateSeededDeny
  done

  SeedFile=/tmp/kiocopy/$DateStamp/Seed.txt
fi

echo "Reading Seed File..."
IFS=$'\n'
SeedFileArray=($(cat "$SeedFile"))
unset IFS

#Create a 1024 byte variable
BYTE1024=$(for v in {1..1024};do echo -n 0 ; done)

echo "Creating objects in filesystem..."
for (( SeedItr=1 ; SeedItr < "${#SeedFileArray[@]}" ; SeedItr++ ))
do
  SeededItem="${SeedFileArray[$SeedItr]}"
  IFS=$'\r'
  SeedItemArray=($SeededItem)
  unset IFS

  ItemSize=${SeedItemArray[0]}
  ItemPath=${SeedItemArray[1]}
  ItemTarget=${SeedItemArray[2]}

  if [[ $ItemSize == d ]]
  then
    if [[ $DoDryRun == 1 ]]
    then
      echo "Would have created folder $ItemPath"
    else
      mkdir -p "$ItemPath"
      if [[ $? != 0 ]]
      then
        echo "Failed to create folder $ItemPath" >> /tmp/kiocopy/$DateStamp/logs/self.log
      fi
    fi
  elif [[ $ItemSize == link ]]
  then
    if [[ $DoDryRun == 1 ]]
    then
      echo "Would have created symlink at $ItemPath to $ItemTarget"
    else
      ln -s "$ItemTarget" "$ItemPath"
      if [[ $? != 0 ]]
      then
        echo "Failed to symlink at $ItemPath to $ItemTarget" >> /tmp/kiocopy/$DateStamp/logs/self.log
      fi
    fi
  elif [[ $ItemSize == fifo ]]
  then
    if [[ $DoDryRun == 1 ]]
    then
      echo "Would have created FIFO $ItemPath"
    else
      mkfifo "$ItemPath"
      if [[ $? != 0 ]]
      then
        echo "Failed to create FIFO $ItemPath" >> /tmp/kiocopy/$DateStamp/logs/self.log
      fi
    fi
  elif [[ $ItemSize == socket ]]
  then
    if [[ $DoDryRun == 1 ]]
    then
      echo "Would have created socket $ItemPath"
    else
      python -c "import socket as s; sock = s.socket(s.AF_UNIX); sock.bind('$ItemPath')"
      if [[ $? != 0 ]]
      then
        echo "Failed to create socket $ItemPath" >> /tmp/kiocopy/$DateStamp/logs/self.log
      fi
    fi
  elif [[ $ItemSize == 0 ]]
  then
    if [[ $DoDryRun == 1 ]]
    then
      echo "Would have fast created empty file $ItemPath"
    else
      echo -n > "$ItemPath"
      if [[ $? != 0 ]]
      then
        echo "Failed to fast create empty file $ItemPath" >> /tmp/kiocopy/$DateStamp/logs/self.log
      fi
    fi
  elif [[ $ItemSize == 1024 ]]
  then
    if [[ $DoDryRun == 1 ]]
    then
      echo "Would have fast created 1024 byte file $ItemPath"
    else
      echo -n $BYTE1024 > "$ItemPath"
      if [[ $? != 0 ]]
      then
        echo "Failed to fast created 1024 byte file $ItemPath" >> /tmp/kiocopy/$DateStamp/logs/self.log
      fi
    fi
  elif [[ $ItemSize == deny ]]
  then
    if [[ $DoDryRun == 1 ]]
    then
      echo "Would have denied access to $ItemPath"
    else
      chmod 000 "$ItemPath"
      if [[ $? != 0 ]]
      then
        echo "Failed to deny access to $ItemPath" >> /tmp/kiocopy/$DateStamp/logs/self.log
      fi
    fi
    else
    if [[ $DoDryRun == 1 ]]
    then
      echo "Would have created $ItemSize byte file $ItemPath"
    else
      fallocate -l $ItemSize "$ItemPath"
      if [[ $? != 0 ]]
      then
        echo "Failed to $ItemSize byte file $ItemPath" >> /tmp/kiocopy/$DateStamp/logs/self.log
      fi
    fi
  fi
done

if [[ $TEST_INVALID_UNICODE_CHARS == 1 ]]
then
  LC_ALL=$OLD_LC_ALL
  LANG=$OLD_LANG
fi

#The actual test for trying to copy the folders, along with post logging.
echo "Running the test..."
export KDE_FORK_SLAVES=1
export QT_LOGGING_RULES=kf5.kio.*=true
kioclient5 copy /tmp/kiocopy/$DateStamp/folder_src/testdir /tmp/kiocopy/$DateStamp/folder_dest &> /tmp/kiocopy/$DateStamp/logs/kioclient.log
echo "$?" >> /tmp/kiocopy/$DateStamp/logs/kioclient.log
#diff -rq /tmp/kiocopy/$DateStamp/folder_src/testdir /tmp/kiocopy/$DateStamp/folder_dest/testdir > /tmp/kiocopy/$DateStamp/logs/folderdiff.txt
tree -aF /tmp/kiocopy/$DateStamp/folder_src/testdir  > /tmp/kiocopy/$DateStamp/logs/src_tree.txt
tree -aF /tmp/kiocopy/$DateStamp/folder_dest/testdir > /tmp/kiocopy/$DateStamp/logs/dest_tree.txt

tree -asF /tmp/kiocopy/$DateStamp/folder_src/testdir  > /tmp/kiocopy/$DateStamp/logs/src_tree_size.txt
tree -asF /tmp/kiocopy/$DateStamp/folder_dest/testdir > /tmp/kiocopy/$DateStamp/logs/dest_tree_size.txt


echo "Job Done, see:
Log of kioclient: /tmp/kiocopy/$DateStamp/logs/kioclient.log
All Items list: /tmp/kiocopy/$DateStamp/logs/treelist.txt

Tree of the source: /tmp/kiocopy/$DateStamp/logs/src_tree.txt
Tree of the target: /tmp/kiocopy/$DateStamp/logs/dest_tree.txt

Tree of the source with sizes: /tmp/kiocopy/$DateStamp/logs/src_tree_size.txt
Tree of the target with sizes: /tmp/kiocopy/$DateStamp/logs/dest_tree_size.txt

Seed File: /tmp/kiocopy/$DateStamp/Seed.txt

"

ReportDateStamp=$(date +%s)
echo "Generating tar file. /tmp/kiocopy/$DateStamp/ReportFile_$ReportDateStamp.tar.xz"
tar -cavf /tmp/kiocopy/$DateStamp/ReportFile_$ReportDateStamp.tar.xz /tmp/kiocopy/$DateStamp/logs/kioclient.log /tmp/kiocopy/$DateStamp/logs/src_tree.txt /tmp/kiocopy/$DateStamp/logs/dest_tree.txt /tmp/kiocopy/$DateStamp/logs/src_tree_size.txt /tmp/kiocopy/$DateStamp/logs/dest_tree_size.txt "$SeedFile"

echo "Creation of /tmp/kiocopy/$DateStamp/ReportFile_$ReportDateStamp.tar.xz complete. Will now start diff for the overall tree. Press enter."
read a
diff -u /tmp/kiocopy/$DateStamp/logs/src_tree.txt /tmp/kiocopy/$DateStamp/logs/dest_tree.txt | more

echo "press enter"
read a

echo "Will now start diff for the size tree (directories excluded). Press enter."
read a
diff -u /tmp/kiocopy/$DateStamp/logs/src_tree_size.txt /tmp/kiocopy/$DateStamp/logs/dest_tree_size.txt | grep -v /$ | grep -v "^ " | grep -v "^@" | more

echo "Press enter to remove test file systems. Press CTRL+C to not."
read a
sudo umount /tmp/kiocopy/$DateStamp/fsimg_src
sudo umount /tmp/kiocopy/$DateStamp/fsimg_dest

rm /tmp/kiocopy/$DateStamp/fsimg_src
rm /tmp/kiocopy/$DateStamp/fsimg_dest