#!/bin/bash ###################################################################### # ks-upf (ks-tools) - Upload common file(s) to server with rsync+ssh # # Date: 04-01-2022 # # Author: q3aql # # Contact: q3aql@duck.com # ###################################################################### VERSION="8.1" M_DATE="040122" # Global parameters. dirTemp="/tmp" listCompTemp="ks-tools.list-full" listCompTempTest="ks-tools.list-full.test" listTemp="ks-tools.list" dirConfig="${HOME}/.ks-tools" ksToolsTempFolder="/tmp/ks-tools" # Check cygwin alias (for Windows) if [ -f "/usr/bin/cygwin-alias.sh" ] ; then shopt -s expand_aliases cygwin="yes" source "/usr/bin/cygwin-alias.sh" else cygwin="no" fi # Function to remove spaces and symbols # Syntax: convertText "" function convertText() { wordToConvert=${1} ksToolsSedFile="${ksToolsTempFolder}/ks-tools-${RANDOM}.txt" mkdir -p ${ksToolsTempFolder} && chmod 777 -R ${ksToolsTempFolder} 2> /dev/null echo "${wordToConvert}" > ${ksToolsSedFile} # Borrar espacios sed -i 's/ /_/g' "${ksToolsSedFile}" &> /dev/null # Borrar simbolos symbolsList="[ ] @ { } | \ / ~ # $ % & ? ¿ = ( ) < > ! ¡" for findSymbol in ${symbolsList} ; do sed -i "s/${findSymbol}//g" "${ksToolsSedFile}" &> /dev/null done # Borrar el resto de simbolos sed -i 's/*//g' "${ksToolsSedFile}" &> /dev/null sed -i 's/"//g' "${ksToolsSedFile}" &> /dev/null sed -i "s/^//g" "${ksToolsSedFile}" &> /dev/null # Cambiar algunos simbolos sed -i 's/+/_/g' "${ksToolsSedFile}" &> /dev/null sed -i 's/:/-/g' "${ksToolsSedFile}" &> /dev/null sed -i 's/;/-/g' "${ksToolsSedFile}" &> /dev/null # Mostrar texto convertido wordToConvert=$(cat ${ksToolsSedFile}) echo ${wordToConvert} } # Function to list the files of a directory. # Syntax: listArchives function listArchives() { fail=1 formatFiles="" videoFiles="mp4 avi mpg mpeg mov wmv mkv ogv webm rm flv vob ts" formatFiles="${formatFiles} ${videoFiles}" audioFiles="mp3 wma ogg wav flac midi acc oga opus mp2 ra m4a mka ac3" formatFiles="${formatFiles} ${audioFiles}" compressFiles="zip rar 7z bz2 gz xz tar bzip2 gzip" formatFiles="${formatFiles} ${compressFiles}" open_libreOfficeFiles="odt ods odp odb odg" formatFiles="${formatFiles} ${open_libreOfficeFiles}" OfficeFiles="doc docx dotx dot docm dic thmx xlsx ppt pps pst mbd accdb msg" formatFiles="${formatFiles} ${OfficeFiles}" documentFiles="txt pdf rtf html php xml json css" formatFiles="${formatFiles} ${documentFiles}" pictureFiles="png jpg jpeg gif bmp raw xcf ppm pnm tiff ico tga pbm pgm svg psd" formatFiles="${formatFiles} ${pictureFiles}" executableFiles="exe msi run bin elf dmg deb rpm tgz ebuild flatpakref snap sh bash cmd bat AppImage jar" formatFiles="${formatFiles} ${executableFiles}" otherFiles="desktop lnk blend db c cpp cxx cc py rb dll so link network service ko list java" formatFiles="${formatFiles} ${otherFiles}" # Rename files cd "${1}" mkdir -p ${ksToolsTempFolder} ls -1 > ${ksToolsTempFolder}/rename-files.txt count=1 sizeFile=$(cat ${ksToolsTempFolder}/rename-files.txt | wc -l) while [ ${count} -le ${sizeFile} ] ; do fileToRename=$(cat ${ksToolsTempFolder}/rename-files.txt | head -${count} | tail -1) fileRenamed=$(convertText "${fileToRename}") if [ "${fileRenamed}" == "${fileToRename}" ] ; then echo "null" > /dev/null else mv "${fileToRename}" "${fileRenamed}" fi count=$(expr $count + 1) done # Scan audio files rm -rf ${dirTemp}/${listTemp} rm -rf ${dirTemp}/${listCompTemp} for format in ${formatFiles} ; do find "${1}"/*.${format} &> ${dirTemp}/${listCompTempTest} if [ $? -ne 0 ] ; then echo "null" > /dev/null else find "${1}"/*.${format} &>> ${dirTemp}/${listCompTemp} echo "+ File(s) in .${format} format found!" cd "${1}" && ls -1 *.${format} &>> ${dirTemp}/${listTemp} fail=0 fi done if [ ${fail} -eq 1 ] ; then echo "+ No common file(s) found!" echo "" exit else echo "" fi } # Function to count the found files. function countArchives() { totalArchives=$(cat ${dirTemp}/${listCompTemp} | wc -l) echo ${totalArchives} } # Function to show files with spaces. # Syntax: showFileWithSpace function showFileWithSpace() { FileName=$(cat ${dirTemp}/${listTemp} | head -${1} | tail -1) FileNoExtension=$(echo $FileName | cut -d "." -f 1) echo $FileNoExtension > ${dirTemp}/name.tmp sed -i 's/_/ /g' ${dirTemp}/name.tmp DisplayName=$(cat ${dirTemp}/name.tmp) rm -rf ${dirTemp}/name.tmp echo ${DisplayName} } # Function to show the name of the file. # Syntax: showFile function showFile() { archive=$(cat ${dirTemp}/${listTemp} | head -${1} | tail -1) echo ${archive} } # Function to show full file path. # Syntax: showPathFile function showPathFile() { pathFile=$(cat ${dirTemp}/${listCompTemp} | head -${1} | tail -1) echo ${pathFile} } # Function to send file to server. # Syntax: sendFile [file name] function sendFile() { correct=0 countSend=0 while [ ${correct} -eq 0 ] ; do #sshpass -p ${1} scp ${2} ${3}@${4}:${5} &> /dev/null comandOne="sshpass -p ${1} rsync -azL -e" comandTwo="--progress ${2} ${3}@${4}:${5}" ${comandOne} "ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null" ${comandTwo} 2> /dev/null sshpass -p ${1} ssh ${3}@${4} rm -rf ${5}/.${6}.* &> /dev/null OUTPUT=$? if [ "${cygwin}" == "yes" ] ; then echo "retry_disabled" > /dev/null correct=1 else if [ ${OUTPUT} -ne 0 ] ; then echo "Failure to send ${2}" echo "Retrying..." sshpass -p ${1} ssh ${3}@${4} rm -rf ${5}/.${6}.* &> /dev/null sleep 5 countSend=$(expr ${countSend} + 1) if [ ${countSend} -eq 3 ] ; then correct=1 fi else correct=1 fi fi done } # Function to check local and server checksum. # Syntax: checkChecksum function checkChecksum() { correct=0 countChecksum=0 echo -n "Checking checksum... " && sleep 4 echo "" if [ "${cygwin}" == "yes" ] ; then checksumLocal=$(md5sum ${2}) echo "Local checksum: ${checksumLocal}" echo "Server checksum: checksum_disabled" else while [ ${correct} -eq 0 ] ; do checksumServer=$(sshpass -p ${1} ssh ${3}@${4} md5sum ${5} 2> /dev/null) OUTPUT=$? if [ ${OUTPUT} -ne 0 ] ; then echo "Failed to get checksum for ${5}" echo "Retrying..." sleep 5 countChecksum=$(expr ${countChecksum} + 1) if [ ${countChecksum} -eq 3 ] ; then correct=1 fi else checksumLocal=$(md5sum ${2}) echo "Local checksum: ${checksumLocal}" echo "Server checksum: ${checksumServer}" correct=1 fi done fi } # Generate random codes function generate_codes() { chars="abcdefghijklmnopqrstywxz1234567890ABCDEFHIJKLMNOPQRSTYWXZ@/" long_code="${1}" for i in {1} ; do echo -n "${chars:RANDOM%${#chars}:1}" done } # Function to encrypt pass on config file # Syntax: encrypt_kstools function encrypt_kstools() { raw_pass="${1}" characters_pass_raw=$(echo ${raw_pass} | wc -m) characters_pass=$(expr ${characters_pass_raw} - 1) total_characters=0 mkdir -p ${HOME}/.ks-tools/ rm -rf ${HOME}/.ks-tools/.seq-codes while [ ${total_characters} -le ${characters_pass} ] ; do num_gen=$(echo -n ${RANDOM} | cut -c1) echo -n ${num_gen} >> ${HOME}/.ks-tools/.seq-codes total_characters=$(expr ${total_characters} + 1) done characters_seq_raw=$(cat ${HOME}/.ks-tools/.seq-codes 2> /dev/null | wc -m) characters_seq=$(expr ${characters_seq_raw} - 1) total_characters=1 encrypted_pass="" while [ ${total_characters} -le ${characters_pass} ] ; do num_seq_read=$(cat ${HOME}/.ks-tools/.seq-codes 2> /dev/null | cut -c${total_characters}) character=$(echo ${raw_pass} | cut -c${total_characters}) repeat_seq=0 while [ ${repeat_seq} -lt ${num_seq_read} ] ; do code_gen=$(generate_codes) encrypted_pass="${encrypted_pass}${code_gen}" repeat_seq=$(expr ${repeat_seq} + 1) done encrypted_pass="${encrypted_pass}${character}" total_characters=$(expr ${total_characters} + 1) done code_gen=$(generate_codes) encrypted_pass="${encrypted_pass}${code_gen}" echo ${encrypted_pass} } # Function to decrypt pass on config file # Syntax: decrypt_kstools function decrypt_kstools() { raw_pass_encrypted="${1}" total_characters=1 codes_seq=$(cat ${HOME}/.ks-tools/.seq-codes 2> /dev/null) num_codes_seq=$(cat ${HOME}/.ks-tools/.seq-codes 2> /dev/null | wc -m) pass_decrypt="" total_characters=1 pos_codes_pass=0 while [ ${total_characters} -lt ${num_codes_seq} ] ; do pos_codes=$(echo ${codes_seq} | cut -c${total_characters}) pos_codes_pass=$(expr ${pos_codes_pass} + ${pos_codes} + 1) pos_pass=$(expr ${raw_pass_encrypted} | cut -c${pos_codes_pass}) pass_decrypt="${pass_decrypt}${pos_pass}" total_characters=$(expr ${total_characters} + 1) done echo ${pass_decrypt} } # Function to show config function showConfig() { configAvailable=0 echo "" echo "* ks-upf (ks-tools) v${VERSION} (${M_DATE})" echo "" if [ -f ${dirConfig}/ks-upload-user ] ; then showUser=$(cat ${dirConfig}/ks-upload-user) echo "- Server User: ${showUser}" configAvailable=1 fi if [ -f ${dirConfig}/ks-upload-pass ] ; then readPasswordEncrypted=$(cat ${dirConfig}/ks-upload-pass) readPasswordDecrypted=$(decrypt_kstools "${readPasswordEncrypted}") readPasswordChars=$(echo ${readPasswordDecrypted} | wc -m) totalchars=0 showPassword="" while [ ${totalchars} -lt ${readPasswordChars} ] ; do showPassword="${showPassword}*" totalchars=$(expr ${totalchars} + 1) done echo "- Server Password: ${showPassword}" configAvailable=1 fi if [ -f ${dirConfig}/ks-upload-server ] ; then showServer=$(cat ${dirConfig}/ks-upload-server) echo "- URL (or IP) Server: ${showServer}" configAvailable=1 fi if [ -f ${dirConfig}/ks-upload-dirserver ] ; then showDirServer=$(cat ${dirConfig}/ks-upload-dirserver) echo "- Destination Path (Server): ${showDirServer}" configAvailable=1 fi if [ -f ${dirConfig}/ks-upload-dirlocal ] ; then showDirLocal=$(cat ${dirConfig}/ks-upload-dirlocal) echo "- Scan Path (Local): ${showDirLocal}" configAvailable=1 fi if [ ${configAvailable} -eq 0 ] ; then echo "* The configuration file does not exist!" fi echo "" exit } # Function to edit the configuration file function editConfig() { editConfig=0 while [ ${editConfig} -eq 0 ] ; do clear editUser=$(cat ${dirConfig}/ks-upload-user 2> /dev/null) readPasswordEncrypted=$(cat ${dirConfig}/ks-upload-pass) readPasswordDecrypted=$(decrypt_kstools "${readPasswordEncrypted}") readPasswordChars=$(echo ${readPasswordDecrypted} | wc -m) totalchars=0 editPassword="" while [ ${totalchars} -lt ${readPasswordChars} ] ; do editPassword="${editPassword}*" totalchars=$(expr ${totalchars} + 1) done editServer=$(cat ${dirConfig}/ks-upload-server 2> /dev/null) editDirServer=$(cat ${dirConfig}/ks-upload-dirserver 2> /dev/null) editDirLocal=$(cat ${dirConfig}/ks-upload-dirlocal 2> /dev/null) echo "" echo "* ks-upf (ks-tools) v${VERSION} (${M_DATE})" echo "" echo " 1 - Edit User (${editUser})" echo " 2 - Edit Password (${editPassword})" echo " 3 - Edit Server (${editServer})" echo " 4 - Edit Dest. Path (${editDirServer})" echo " 5 - Edit Local Path (${editDirLocal})" echo "" echo " 6 - Exit" echo "" echo -n "* Choose an option: " ; read EDIT echo "" if [ "${EDIT}" == "1" ] ; then echo -n "* Enter the server user: " ; read USER user=${USER} echo ${user} > ${dirConfig}/ks-upload-user elif [ "${EDIT}" == "2" ] ; then echo -n "* Enter the server key: " ; read PASS raw_password_enter=${PASS} encrypt_password_enter=$(encrypt_kstools "${raw_password_enter}") echo ${encrypt_password_enter} > ${dirConfig}/ks-upload-pass elif [ "${EDIT}" == "3" ] ; then echo -n "* Enter the server URL: " ; read SERVER server=${SERVER} echo ${server} > ${dirConfig}/ks-upload-server elif [ "${EDIT}" == "4" ] ; then echo -n "* Enter the path on the server: " ; read DIR_SERVER dirServer=${DIR_SERVER} echo ${dirServer} > ${dirConfig}/ks-upload-dirserver elif [ "${EDIT}" == "5" ] ; then echo -n "* Enter the local path to scan: " ; read DIR dirLocal=${DIR} echo ${dirLocal} > ${dirConfig}/ks-upload-dirlocal elif [ "${EDIT}" == "6" ] ; then editConfig=1 else echo "+ Invalid option!" echo -n "- Press ENTER to continue " ; read CONTINUE fi done exit } # Function to create initial config file. function createConfig() { # Start script clear echo "" echo "* ks-upf (ks-tools) v${VERSION} (${M_DATE})" echo "" checkDependencies # Ask the user and if it exists, read it from the config. if [ -f ${dirConfig}/ks-upload-user ] ; then echo "+ The USER configuration already exists (Use: 'ks-upf -e' for edit)" else echo -n "* Enter the server user: " ; read USER user=${USER} echo ${user} > ${dirConfig}/ks-upload-user fi # Ask the password and if it exists, read it from the config. if [ -f ${dirConfig}/ks-upload-pass ] ; then echo "+ The PASSWORD configuration already exists (Use: 'ks-upf -e' for edit)" else echo -n "* Enter the server password: " ; read PASS raw_password_enter=${PASS} encrypt_password_enter=$(encrypt_kstools "${raw_password_enter}") echo ${encrypt_password_enter} > ${dirConfig}/ks-upload-pass fi # Ask the server URL and if it exists, read it from the config. if [ -f ${dirConfig}/ks-upload-server ] ; then echo "+ The SERVER configuration already exists (Use: 'ks-upf -e' for edit)" else echo -n "* Enter the server URL: " ; read SERVER server=${SERVER} echo ${server} > ${dirConfig}/ks-upload-server fi # Ask the path on the server and if it exists, read it from the config. if [ -f ${dirConfig}/ks-upload-dirserver ] ; then echo "+ The SERVER PATH configuration already exists (Use: 'ks-upf -e' for edit)" else echo -n "* Enter the path on the server: " ; read DIR_SERVER dirServer=${DIR_SERVER} echo ${dirServer} > ${dirConfig}/ks-upload-dirserver fi # Ask the local path and if it exists, read it from the config. if [ -f ${dirConfig}/ks-upload-dirlocal ] ; then echo "+ The LOCAL PATH configuration already exists (Use: 'ks-upf -e' for edit)" else echo -n "* Enter the local path to scan: " ; read DIR dirLocal=${DIR} echo ${dirLocal} > ${dirConfig}/ks-upload-dirlocal fi echo "" } # Function to show version function showVersion() { echo "" echo "* ks-upf (ks-tools) v${VERSION} (${M_DATE})" echo "" exit } # Function to show help function showHelp() { echo "" echo "* ks-upf (ks-tools) v${VERSION} (${M_DATE})" echo "" echo "- Upload common file(s) to server with rsync+ssh" echo "" echo "+ Syntax:" echo "" echo " $ ks-upf -i - Start upload" echo " $ ks-upf -g - Create configuration" echo " $ ks-upf -r - Remove configuration" echo " $ ks-upf -c - Show configuration" echo " $ ks-upf -e - Edit configuration" echo " $ ks-upf -v - Show version" echo " $ ks-upf -h - Show help" echo "" exit } # Function to check if all the necessary tools # for the execution are installed. function checkDependencies() { dependence=0 echo -n "* Checking necessary tools... " sleep 3 && echo "" sshpass -h &> /dev/null OUTPUT=$? if [ ${OUTPUT} -ne 0 ] ; then echo "* The 'sshpass' tool is not installed!" dependence=1 fi md5sum --help &> /dev/null OUTPUT=$? if [ ${OUTPUT} -ne 0 ] ; then echo "* The 'md5sum' tool is not installed!" dependence=1 fi rsync --version &> /dev/null OUTPUT=$? if [ ${OUTPUT} -ne 0 ] ; then echo "* The 'rsync' tool is not installed!" dependence=1 fi if [ -f /usr/bin/scp ] ; then echo "OK" > /dev/null else echo "* The 'scp' tool is not installed!" dependence=1 fi if [ -f /usr/bin/ssh ] ; then echo "OK" > /dev/null else echo "* The 'ssh' tool is not installed!" dependence=1 fi if [ ${dependence} -eq 0 ] ; then echo "* Necessary tools installed!" echo "" else echo "" exit fi } # Function to migrate old configuration. if [ -f ${dirConfig}/USER ] ; then cat ${dirConfig}/USER > ${dirConfig}/ks-upload-user echo "* Migrating ${dirConfig}/USER > ${dirConfig}/ks-upload-user" rm -rf ${dirConfig}/USER sleep 1 fi if [ -f ${dirConfig}/PASS ] ; then echo "* Migrating ${dirConfig}/PASS > ${dirConfig}/ks-upload-pass" current_pass=$(cat ${dirConfig}/PASS) encrypt_kstools "${current_pass}" > ${dirConfig}/ks-upload-pass rm -rf ${dirConfig}/PASS sleep 1 fi if [ -f ${dirConfig}/SERVER ] ; then cat ${dirConfig}/SERVER > ${dirConfig}/ks-upload-server echo "* Migrating ${dirConfig}/SERVER > ${dirConfig}/ks-upload-server" rm -rf ${dirConfig}/SERVER sleep 1 fi if [ -f ${dirConfig}/DIR_SERVER ] ; then cat ${dirConfig}/DIR_SERVER > ${dirConfig}/ks-upload-dirserver echo "* Migrating ${dirConfig}/DIR_SERVER > ${dirConfig}/ks-upload-dirserver" rm -rf ${dirConfig}/DIR_SERVER sleep 1 fi if [ -f ${dirConfig}/DIR ] ; then cat ${dirConfig}/DIR > ${dirConfig}/ks-upload-dirlocal echo "* Migrating ${dirConfig}/DIR > ${dirConfig}/ks-upload-dirlocal" rm -rf ${dirConfig}/DIR sleep 1 fi # Check if the configuration directory exists. if [ -d ${dirConfig} ] ; then echo ${dirConfig} > /dev/null else mkdir -p ${dirConfig} fi # Delete the existing configuration. if [ "${1}" == "-r" ] ; then echo "" echo "* ks-upf (ks-tools) v${VERSION} (${M_DATE})" echo "" echo -n "* [Default: n] Are you sure you want to delete the configuration? (y/n): " ; read confirm if [ "${confirm}" == "y" ] ; then echo "" echo "+ Removing USER file configuration..." rm -rf ${dirConfig}/ks-upload-user echo "+ Removing PASSWORD file configuration..." rm -rf ${dirConfig}/ks-upload-pass echo "+ Removing SERVER file configuration..." rm -rf ${dirConfig}/ks-upload-server echo "+ Removing SERVER PATH file configuration..." rm -rf ${dirConfig}/ks-upload-dirserver echo "+ Removing LOCAL PATH file configuration..." rm -rf ${dirConfig}/ks-upload-dirlocal echo "* Removed all configuration" echo "" exit else echo "" echo "+ Remove configuration canceled" echo "" exit fi fi # Show configuration file if [ "${1}" == "-c" ] ; then showConfig # Show configuration file elif [ "${1}" == "-e" ] ; then editConfig # Show the version elif [ "${1}" == "-v" ] ; then showVersion # Show the help elif [ "${1}" == "-h" ] ; then showHelp elif [ "${1}" == "-g" ] ; then createConfig # Init elif [ "${1}" == "-i" ] ; then # Start script createConfig user=$(cat ${dirConfig}/ks-upload-user) raw_password=$(cat ${dirConfig}/ks-upload-pass) password=$(decrypt_kstools "${raw_password}") server=$(cat ${dirConfig}/ks-upload-server) dirServer=$(cat ${dirConfig}/ks-upload-dirserver) dirLocal=$(cat ${dirConfig}/ks-upload-dirlocal) # Call the functions to perform the whole process. echo -n "* Scanning ${dirLocal} " && sleep 4 echo "" if [ -d ${dirLocal} ] ; then listArchives "${dirLocal}" totalFiles=$(countArchives) count=1 echo "+ ${totalFiles} common file(s) found!" echo "" while [ ${count} -le ${totalFiles} ] ; do fullNameFile=$(showFile ${count}) fullPathFile=$(showPathFile ${count}) echo "Uploading '${fullNameFile}' " sendFile ${password} ${fullPathFile} ${user} ${server} ${dirServer} ${fullNameFile} checkChecksum ${password} ${fullPathFile} ${user} ${server} ${dirServer}/${fullNameFile} echo "" count=$(expr ${count} + 1) done else echo "* Directory ${dirLocal} does not exist!" echo "" exit fi # Show help else showHelp fi