#!/bin/sh # Copyright (C) 2012-2013 Aleksey Lim # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . [ "${V}" ] && set -x PARCEL_SUFFIX=".parcel" info() { echo "-- $@" } phase() { echo " $@" } warning() { echo "-- $@" } abort() { rm -f *.sync echo "-- $@" [ "${V}" ] || echo " run \"V=1 $0 ${cmdline}\" to get full debugging output" exit 1 } help() { cat </dev/null 2>&1; then cmd="wget --output-document=${out_packet} --load-cookies=${cookie} --save-cookies=${cookie}" [ "${in_packet}" ] && cmd="${cmd} --post-file=${in_packet}" [ "${V}" ] && cmd="${cmd} --server-response" || cmd="${cmd} --quiet" else cmd="curl --output ${out_packet} --cookie ${cookie} --cookie-jar ${cookie}" [ "${in_packet}" ] && cmd="${cmd} -XPOST --data-binary @${in_packet}" [ "${V}" ] || cmd="${cmd} --silent" fi ${cmd} "${url}" || abort "Cannot run upload command" if [ -e "${out_packet}" ]; then if [ $(stat -c %s "${out_packet}") -eq 0 ]; then rm "${out_packet}" else if [ "${in_packet}" ]; then phase "Replace ${in_packet} with results" mv "${out_packet}" "${in_packet}" || abort "Cannot write to ${in_packet}" else out_filename="$(get_hostname $url)"$PARCEL_SUFFIX phase "Store results in ${out_filename}" mv "${out_packet}" "${out_filename}" || abort "Cannot write to ${out_filename}" fi fi fi if [ -e "${cookie}" ]; then if grep unset_sugar_network_pull "${cookie}" >/dev/null; then rm "${cookie}" elif grep sugar_network_pull "${cookie}" >/dev/null; then phase "Postpone pull with ${cookie}" else rm "${cookie}" fi fi if [ "${in_packet}" ]; then phase "Remove uploaded file" rm "${in_packet}" fi } pull() { local api_url="$1?cmd=pull" local cookie="$(get_hostname $1).cookie" while true; do local disk_free=$(df . --block-size=1 | tail -n1 | awk '{print $4}') [ $disk_free -gt $disk_limit ] || abort \ "No free disk space on $PWD, copy all *.cookie files" \ "to directory with more free space and re-run $0 from there" upload "${api_url}&accept_length=${disk_free}" "${cookie}" [ -e "${cookie}" ] || break delay=$(grep -o 'sugar_network_delay[[:space:]]*[0-9]\+' "${cookie}" 2>/dev/null | awk '{print $2}') if [ "${delay}" ]; then phase "Server started processing pull, check for results in ${delay} seconds" sleep ${delay} else phase "Pull postponed updates" fi done } sync_path="$1" clone_url="$2" cmdline="$@" FS= disk_limit=$(expr 1024 \* 1024 \* 10) if [ $# -eq 0 ]; then if [ "$(basename $(dirname $0))" = "sugar-network-sync" ]; then # Script was launched from sync directory, so, process sync sync_path="$(dirname $0)" else help exit 0 fi fi mkdir -p "${sync_path}" || abort "Cannot create ${sync_path} sync directory" cd "${sync_path}" || abort "Cannot switch to ${sync_path} sync directory" mountpoint="$(stat --printf %m .)" [ "${mountpoint}/sugar-network-sync" = "$PWD" ] || \ info "NOTICE To make $PWD directory capable for further auto synchronization, place it to the mount's root" if [ "${clone_url}" ]; then info "Clone master" pull "${clone_url}" exit 0 fi # Upload push packets at first for parcel in $(find -type f -name "*$PARCEL_SUFFIX" -printf '%f\n'); do api_url="$(get_header_key "${parcel}" api_url)" if [ -z "${api_url}" ]; then info "Skip ${parcel}, it is not intended for uploading" else info "Push ${parcel} to ${api_url}" upload "${api_url}?cmd=push" "$(get_hostname ${api_url}).cookie" "${parcel}" fi done # Using cookies from uploaded packets, download master data while true; do found= for cookie in $(find -type f -name '*.cookie'); do api_url="http://$(basename "${cookie}" .cookie)" info "Pull updates from ${api_url}" pull "${api_url}" found=1 done [ "${found}" ] || break done