Sanitizer: Restore Missing File Extensions

You can find an introduction on how to use Sanitizer here: Sanitizer: How to Use

Please note: This article is only for a worst-case scenario when the vault has been partially deleted. With the decryptVault command of Sanitizer, you can decrypt the complete vault and restore inaccessible data that would’ve been otherwise lost. After decrypting a vault via this method, it can be useful to restore the file extensions of the unknown names.

After using the decryptVault command of Sanitizer on a broken vault, you may see a lost+found directory with folders and files that have unknown names. These names are not decryptable anymore because the corresponding parent directories (more precisely, the directory ids) are missing. See: https://cryptomator.org/architecture/#nameEncryption

With this shell script, you can try to recover the extensions of the files with unknown names. We may integrate this option into Sanitizer in a future version. Unfortunately, we don’t have a script for Windows.

Save the script below as e.g. RestoreMissingFileExtension.sh and then make it executable:

chmod +x RestoreMissingFileExtension.sh

After that, you can run this script on the decrypted vault:

./RestoreMissingFileExtension.sh /path/to/vault-decrypted

Be very careful that you don’t run this script on “any” directory. Do not run it if you don’t know what you’re doing. The script will recursively go through the target directory and add missing file extensions that are recoverable.

Script: Restore Missing File Extension

#!/bin/bash
# modified from: https://unix.stackexchange.com/a/225485

# Set the location of your mime-types file here. On some OS X installations,
# you may find such a file at /etc/apache2/mime.types; On some linux distros,
# it can be found at /etc/mime.types
MIMETYPE_FILE="/etc/apache2/mime.types"
if [ ! -f "$MIMETYPE_FILE" ]; then
  echo "Could not find the mime.types file. Please set the MIMETYPE_FILE variable in this script."
  exit 1
fi

TARGET_DIR="$1"
if [ "$TARGET_DIR" == "" ]; then
  echo "No target directory given. Usage: $(basename "$0") <directory>"
  exit 2
elif [[ "$TARGET_DIR" == "/" ]]; then
  echo "You do not want to run this script on root. Usage: $(basename "$0") <directory>"
  exit 2
fi

find $TARGET_DIR -print0 | while IFS= read -r -d '' TARGET_FILE
do
  if [ ! -f "$TARGET_FILE" ]; then
    continue;
  fi

  TARGET_FILE_BASE=$(basename "$TARGET_FILE")
  TARGET_FILE_EXTENSION="${TARGET_FILE_BASE##*.}"
  if [[ "$TARGET_FILE_BASE" != "$TARGET_FILE_EXTENSION" ]]; then
    echo ${TARGET_FILE} already has extension
    continue;
  fi

  MIME=`file -b --mime-type $TARGET_FILE`
  if [[ "${MIME}" == "" ]]; then
    echo "Could not find MIME-type: ${TARGET_FILE}"
    continue;
  fi

  EXT=$(grep "${MIME}" "${MIMETYPE_FILE}" | sed '/^#/ d' | grep -m 1 "${MIME}" | awk '{print $2}')
  if [[ "$EXT" == "" ]]; then
    echo "Could not find extension for MIME-Type ${MIME}: ${TARGET_FILE}"
    continue;
  fi

  echo "Renaming ${TARGET_FILE} to ${TARGET_FILE}.${EXT}"
  mv "${TARGET_FILE}" "${TARGET_FILE}.${EXT}"
done