Created
December 17, 2019 20:50
-
-
Save error454/324d63ba8263376507c91ba4ca3710e7 to your computer and use it in GitHub Desktop.
Dropbox FS Fix
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
############################################################################## | |
# Workaround for Dropbox daemon | |
# ----------------------------- | |
# Verified on Dropbox v77.4.131 | |
# Just make it executable (if need, using | |
# $ chmod a+x fix_dropbox | |
# ) and run it. | |
# Author: Здравко | |
# www.dropboxforum.com/t5/user/viewprofilepage/user-id/422790 | |
############################################################################## | |
# Figure out the target places. | |
USR_HOME=`realpath ~` | |
USR_LOCAL="$USR_HOME/.local" | |
USR_LOCAL_BIN="$USR_LOCAL/bin" | |
USR_LOCAL_LIB="$USR_LOCAL/lib" | |
DRB_REPLACEMENT="$USR_LOCAL_BIN/dropbox" | |
DRB_FIX_LIB="$USR_LOCAL_LIB/libdropbox_ext4.so" | |
USR_PROFILE="$USR_HOME/.profile" | |
# Dropbox's components | |
DBX_SHELL_BASE="/usr/bin" | |
DBX_SHELL="$DBX_SHELL_BASE/dropbox" | |
DBX_WEB_SRC_BASE="https://www.dropbox.com/download?dl=packages" | |
DBX_SCRIPT_ALT="dropbox.py" | |
DBX_WEB_src="$DBX_WEB_SRC_BASE/$DBX_SCRIPT_ALT" | |
DBX_SHELL_ALT="$USR_LOCAL_BIN/$DBX_SCRIPT_ALT" | |
############################################################################## | |
# Precheck and fix up some prerequisites. | |
# Ensure target directories are on their place. | |
if [[ ! -d $USR_LOCAL_BIN ]] | |
then | |
echo "The Directory \"$USR_LOCAL_BIN\" doesn't exist, going to create it." | |
mkdir -p $USR_LOCAL_BIN | |
if [[ $? -ne 0 || ! -d $USR_LOCAL_BIN ]] | |
then | |
echo "Directory \"$USR_LOCAL_BIN\" creation fail! Exit." | |
exit 1 | |
fi | |
fi | |
if [[ ! -d $USR_LOCAL_LIB ]] | |
then | |
echo "The Directory \"$USR_LOCAL_LIB\" doesn't exist, going to create it." | |
mkdir -p $USR_LOCAL_LIB | |
if [[ $? -ne 0 || ! -d $USR_LOCAL_LIB ]] | |
then | |
echo "Directory \"$USR_LOCAL_LIB\" creation fail! Exit." | |
exit 1 | |
fi | |
fi | |
# Ensure backup for any existing files. | |
if [[ -e $DRB_REPLACEMENT ]] | |
then | |
if [[ -f $DRB_REPLACEMENT ]] | |
then | |
echo "\"$DRB_REPLACEMENT\" already exist, going to back it up." | |
mv --backup=t -T $DRB_REPLACEMENT "${DRB_REPLACEMENT}.backup" | |
if [[ $? -ne 0 || -e $DRB_REPLACEMENT ]] | |
then | |
echo "Error backing up \"$DRB_REPLACEMENT\" file! Exit." | |
exit 1 | |
fi | |
else | |
echo "$DRB_REPLACEMENT is not regular file! Exit." | |
exit 1 | |
fi | |
fi | |
if [[ -e $DRB_FIX_LIB ]] | |
then | |
if [[ -f $DRB_FIX_LIB ]] | |
then | |
echo "\"$DRB_FIX_LIB\" already exist, going to back it up." | |
mv --backup=t -T $DRB_FIX_LIB "${DRB_FIX_LIB}.backup" | |
if [[ $? -ne 0 || -e $DRB_FIX_LIB ]] | |
then | |
echo "Error backing up \"$DRB_FIX_LIB\" file! Exit." | |
exit 1 | |
fi | |
else | |
echo "$DRB_FIX_LIB is not regular file! Exit." | |
exit 1 | |
fi | |
fi | |
# Ensure writing permissions. | |
if [[ ! -w $USR_LOCAL_BIN || ! -x $USR_LOCAL_BIN ]] | |
then | |
chmod u+rwx $USR_LOCAL_BIN | |
if [[ $? -ne 0 ]] | |
then | |
echo "The Directory \"$USR_LOCAL_BIN\" is inaccessible! Exit." | |
exit 1 | |
fi | |
fi | |
if [[ ! -w $USR_LOCAL_LIB || ! -x $USR_LOCAL_LIB ]] | |
then | |
chmod u+rwx $USR_LOCAL_LIB | |
if [[ $? -ne 0 ]] | |
then | |
echo "The Directory \"$USR_LOCAL_LIB\" is inaccessible! Exit." | |
exit 1 | |
fi | |
fi | |
# Check for preinstalled dropbox shell script. | |
if [[ ! -e $DBX_SHELL || ! -x $DBX_SHELL ]] | |
then | |
echo "Cannot find pre installed \"$DBX_SHELL\". Will trying alternative." | |
DBX_SHELL_BASE="$USR_LOCAL_BIN" | |
DBX_SHELL="$DBX_SHELL_ALT" | |
# Ensure backup for existing control script. | |
if [[ -e $DBX_SHELL_ALT ]] | |
then | |
if [[ -f $DBX_SHELL_ALT ]] | |
then | |
echo "\"$DBX_SHELL_ALT\" already exist, going to back it up." | |
mv --backup=t -T $DBX_SHELL_ALT "${DBX_SHELL_ALT}.backup" | |
if [[ $? -ne 0 || -e $DBX_SHELL_ALT ]] | |
then | |
echo "Error backing up \"$DBX_SHELL_ALT\" file! Exit." | |
exit 1 | |
fi | |
else | |
echo "$DBX_SHELL_ALT is not regular file! Exit." | |
exit 1 | |
fi | |
fi | |
fi | |
############################################################################## | |
# Generate actual workaround components. | |
# Fetch Dropbox control script (if need). | |
if [[ "$DBX_SHELL" == "$DBX_SHELL_ALT" ]] | |
then | |
if ! wget -q -O "$DBX_SHELL_ALT" "$DBX_WEB_SRC" | |
then | |
echo "Error while download \"$DBX_SHELL_ALT\" from \"$DBX_WEB_SRC\"! Exit." | |
exit 1 | |
fi | |
chmod a+x $DBX_SHELL_ALT | |
echo "Dropbox control script: \"$DBX_SHELL_ALT\" - ready for use." | |
fi | |
# Fixer - source and building. | |
gcc -shared -fPIC -ldl -xc -o $DRB_FIX_LIB - << EndOfSrc | |
// Functions replacements | |
#define _GNU_SOURCE | |
#include <stdlib.h> | |
#include <sys/vfs.h> | |
#include <linux/magic.h> | |
#include <dlfcn.h> | |
#include <sys/statvfs.h> | |
#include <stdarg.h> | |
static int (*orig_statfs)(const char *path, struct statfs *buf) = NULL; | |
static int (*orig_statfs64)(const char *path, struct statfs64 *buf) = NULL; | |
static int (*orig_open64)(const char *pathname, int flags, ...) = NULL; | |
int statfs(const char *path, struct statfs *buf) { | |
if (orig_statfs == NULL) { | |
orig_statfs = dlsym(RTLD_NEXT, "statfs"); | |
} | |
register int retval = orig_statfs(path, buf); | |
if (retval == 0) { | |
buf->f_type = EXT4_SUPER_MAGIC; | |
} | |
return retval; | |
} | |
int statfs64(const char *path, struct statfs64 *buf) { | |
if (orig_statfs64 == NULL) { | |
orig_statfs64 = dlsym(RTLD_NEXT, "statfs64"); | |
} | |
register int retval = orig_statfs64(path, buf); | |
if (retval == 0) { | |
buf->f_type = EXT4_SUPER_MAGIC; | |
} | |
return retval; | |
} | |
int open64(const char *pathname, int flags, ...) { | |
if (orig_open64 == NULL) { | |
orig_open64 = dlsym(RTLD_NEXT, "open64"); | |
} | |
register const char *p0 = "/proc/filesystems", *p1 = pathname; | |
while(*p0 && *p1 && *p0 == *p1) ++p0, ++p1; | |
if (*p0 == '\0' && *p1 == '\0') { | |
return -1; | |
} | |
va_list arg; | |
va_start(arg, flags); | |
mode_t mode = va_arg (arg, int); | |
va_end(arg); | |
return orig_open64(pathname, flags, mode); | |
} | |
EndOfSrc | |
if [[ $? -ne 0 ]] | |
then | |
echo "Error building \"$DRB_FIX_LIB\"! Exit." | |
exit 2 | |
fi | |
echo "\"$DRB_FIX_LIB\" - build and ready." | |
# Wrapper generating. | |
cat > $DRB_REPLACEMENT << WrapperHead | |
#!/bin/bash | |
if [ \$1 == "start" ] | |
then | |
sleep 1 | |
patchpath=\`realpath \$0\` | |
if echo \$(for i in \`ps -C dropbox -o pid\` | |
do ls -l /proc/\$i/exe 2>/dev/null | grep -v \$patchpath | |
done) | grep dropbox > /dev/null | |
then | |
timeout=300 | |
# Make sure there isn't any concurrent start operation in progress. | |
$DBX_SHELL running | |
while [[ \$? -eq 0 && \$timeout -ne 0 ]] | |
do | |
sleep 1 | |
((--timeout)) | |
if echo \$(for i in \`ps -C dropbox -o pid\` | |
do ls -l /proc/\$i/exe 2>/dev/null | grep -v \$patchpath | |
done) | grep dropbox > /dev/null | |
then | |
$DBX_SHELL running | |
fi | |
done | |
# If there is running application instance, force its stop. | |
$DBX_SHELL running | |
while [[ \$? -ne 0 && \$timeout -ne 0 ]] | |
do | |
$DBX_SHELL stop | |
sleep 1 | |
((--timeout)) | |
$DBX_SHELL running | |
done | |
# If something goes wrong... | |
if [[ \$timeout -eq 0 ]] | |
then | |
# ...notify somehow about. | |
title="Problem launching Dropbox" | |
mainmsg="Possible existing application instance dead" | |
submsg="Check that, clear and try start again" | |
if which notify-send > /dev/null | |
then notify-send --icon=dropbox "\$title" "<b>\$mainmsg\!</b>\n\$submsg." | |
elif which zenity > /dev/null | |
then zenity --error --title="\$title" --timeout=10 --width=380 \\ | |
--text="<span size=\"xx-large\"><b>\$mainmsg\!</b>\n\$submsg.</span>" \\ | |
2> /dev/null | |
else echo " \$title!" | |
echo "\$mainmsg." | |
echo "\$submsg." | |
fi | |
exit 1 | |
fi | |
else sleep 100 | |
fi | |
fi | |
WrapperHead | |
declare -p | grep "declare -x LD_PRELOAD" > /dev/null | |
if [[ $? -ne 0 ]] | |
then | |
echo "export LD_PRELOAD=$DRB_FIX_LIB" >> $DRB_REPLACEMENT | |
else | |
echo "LD_PRELOAD=$DRB_FIX_LIB:\$LD_PRELOAD" >> $DRB_REPLACEMENT | |
fi | |
echo "$DBX_SHELL \$@" >> $DRB_REPLACEMENT | |
chmod a+x $DRB_REPLACEMENT | |
echo "\"$DRB_REPLACEMENT\" - generated." | |
# Environment check and fixup (if need). | |
echo "" | |
echo "" | |
( | |
IFS=: | |
for a in $PATH | |
do | |
if [[ "$a" == "$USR_LOCAL_BIN" ]] | |
then | |
exit 0 | |
elif [[ "$a" == "$DBX_SHELL_BASE" ]] | |
then | |
break | |
fi | |
done | |
exit 1 | |
) | |
if [[ $? -ne 0 ]] | |
then | |
echo "" >> $USR_PROFILE | |
echo "" >> $USR_PROFILE | |
echo "# Add $USR_LOCAL_BIN to \$PATH environment variable." >> $USR_PROFILE | |
echo "# This addition is dedicated for Dropbox Workaround." >> $USR_PROFILE | |
echo "# Remove theses lines when they are no more needed." >> $USR_PROFILE | |
echo "PATH=\"$USR_LOCAL_BIN:\$PATH\"" >> $USR_PROFILE | |
echo "" >> $USR_PROFILE | |
echo "Your Dropbox is almost patched. You have to logout and login" | |
echo " (or on Your opinion - restart), so all changes to take effect." | |
echo "After Your next account login:" | |
fi | |
echo "Your Dropbox is already patched." | |
if [[ "$DBX_SHELL_BASE" == "$USR_LOCAL_BIN" ]] | |
then echo "Just type:" | |
else echo "Just start it from desktop GUI or type:" | |
fi | |
echo "\$ dropbox start" | |
echo "in console (append option -i, when launch for first time)." |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment