mirror of
https://github.com/meganz/MEGAcmd
synced 2025-08-22 01:47:24 +00:00
Merge branch 'develop' into feature/CMD-224_Expose_FUSE_functionalit_updated_wrft_develop_and_cmake_build
This commit is contained in:
commit
af2b2dcad4
1
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
1
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
@ -11,6 +11,7 @@ body:
|
||||
label: "MEGAcmd version"
|
||||
description: "Which version of MEGAcmd did you encountered this issue? (Can be looked up using the `version` command)"
|
||||
options:
|
||||
- 2.0.0
|
||||
- 1.7.0
|
||||
- 1.6.3
|
||||
- 1.6.2
|
||||
|
3
.gitignore
vendored
3
.gitignore
vendored
@ -66,6 +66,9 @@ megacmd_src_file_list.h
|
||||
# macOS packaging files and artifacts
|
||||
Info.plist
|
||||
|
||||
# Synology packaging files and artifacts
|
||||
/build/SynologyNAS/packages
|
||||
|
||||
# Git
|
||||
*_BACKUP_*
|
||||
*_BASE_*
|
||||
|
@ -9,8 +9,8 @@ execute_process(
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
|
||||
set(MEGACMD_MAJOR_VERSION 1)
|
||||
set(MEGACMD_MINOR_VERSION 7)
|
||||
set(MEGACMD_MAJOR_VERSION 2)
|
||||
set(MEGACMD_MINOR_VERSION 0)
|
||||
set(MEGACMD_MICRO_VERSION 0)
|
||||
|
||||
## Configure megacmdversion.h
|
||||
@ -28,6 +28,7 @@ list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/sdk/cmake/modules) # Mod
|
||||
|
||||
set(VCPKG_ROOT "${CMAKE_CURRENT_LIST_DIR}/../vcpkg" CACHE PATH "If set, it will build and use the VCPKG packages defined in the manifest file")
|
||||
|
||||
include(detect_host_architecture)
|
||||
|
||||
if (WIN32)
|
||||
execute_process(
|
||||
@ -183,6 +184,7 @@ add_library(LMEGAcmdCommonUtils STATIC)
|
||||
add_source_and_corresponding_header_to_target(LMEGAcmdCommonUtils
|
||||
PUBLIC
|
||||
"${ProjectDir}/src/megacmdcommonutils.cpp"
|
||||
"${ProjectDir}/src/megacmd_utf8.cpp"
|
||||
)
|
||||
|
||||
add_library(LMegacmdServer STATIC)
|
||||
@ -191,7 +193,6 @@ add_source_and_corresponding_header_to_target(LMegacmdServer
|
||||
"${ProjectDir}/src/megacmd.cpp"
|
||||
"${ProjectDir}/src/megacmdexecuter.cpp"
|
||||
"${ProjectDir}/src/megacmd_events.cpp"
|
||||
"${ProjectDir}/src/megacmdtransfermanager.cpp"
|
||||
"${ProjectDir}/src/megacmdlogger.cpp"
|
||||
"${ProjectDir}/src/megacmdsandbox.cpp"
|
||||
"${ProjectDir}/src/megacmdutils.cpp"
|
||||
@ -221,6 +222,23 @@ target_compile_definitions(LMegacmdServer
|
||||
$<$<BOOL:${USE_PCRE}>:USE_PCRE>
|
||||
)
|
||||
|
||||
if (NOT WIN32)
|
||||
if (ENABLE_ASAN)
|
||||
add_compile_options("-fsanitize=address" "-fno-omit-frame-pointer" "-fno-common")
|
||||
link_libraries("-fsanitize=address")
|
||||
endif()
|
||||
|
||||
if (ENABLE_UBSAN)
|
||||
add_compile_options("-fsanitize=undefined" "-fno-omit-frame-pointer")
|
||||
link_libraries("-fsanitize=undefined")
|
||||
endif()
|
||||
|
||||
if (ENABLE_TSAN)
|
||||
add_compile_options("-fsanitize=thread" "-fno-omit-frame-pointer")
|
||||
link_libraries("-fsanitize=thread")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if (APPLE)
|
||||
set(executablesType MACOSX_BUNDLE)
|
||||
endif()
|
||||
@ -317,6 +335,7 @@ if (ENABLE_MEGACMD_TESTS)
|
||||
add_executable(mega-cmd-tests-integration ${executablesType})
|
||||
add_source_and_corresponding_header_to_target(mega-cmd-tests-integration PRIVATE
|
||||
"${ProjectDir}/tests/integration/BasicTests.cpp"
|
||||
"${ProjectDir}/tests/integration/CatTests.cpp"
|
||||
"${ProjectDir}/tests/integration/ExportTests.cpp"
|
||||
"${ProjectDir}/tests/integration/SyncIssuesTests.cpp"
|
||||
"${ProjectDir}/tests/integration/SyncIgnoreTests.cpp"
|
||||
|
@ -196,11 +196,11 @@ And for **bash completion**, source `megacmd_completion.sh`:
|
||||
```
|
||||
source /Applications/MEGAcmd.app/Contents/macOS/megacmd_completion.sh
|
||||
```
|
||||
*Note for macOS Catalina or above*: since Catalina, macOS uses `zsh` as default shell. If you want to have auto completion, we strongly recommend you to use `bash` shell (just execute `bash` in your terminal).
|
||||
|
||||
## NAS systems
|
||||
Currently we have build scripts for **Synology** and **QNAP**, which can be found in the `build/<system>` folder along with instructions on how to set up the build. Typically this results in a 'package' which can then be manually installed in the NAS. To use MEGAcmd on those systems, ssh into the device and run the commands as normal (having first added their folder to your `PATH` variable).
|
||||
Currently we have build scripts for **Synology**, which can be found in the `build/SynologyNAS` folder along with instructions on how to set up the build. Typically this results in a 'package' which can then be manually installed in the NAS. To use MEGAcmd on those systems, ssh into the device and run the commands as normal (having first added their folder to your `PATH` variable).
|
||||
|
||||
*Important note for macOS Catalina or above: since Catalina, macOS uses `zsh` as default shell. If you want to have auto completion, we strongly recommend you to use `bash` shell (just execute `bash` in your terminal).
|
||||
|
||||
# Features:
|
||||
## Autocompletion:
|
||||
|
@ -1,6 +1,6 @@
|
||||
# MEGAcmd User Guide
|
||||
|
||||
This document relates to MEGAcmd version 1.7.0. It contains introductory information and the [Command Summary](#command-summary), with links to detailed command descriptions.
|
||||
This document relates to MEGAcmd version 2.0.0. It contains introductory information and the [Command Summary](#command-summary), with links to detailed command descriptions.
|
||||
|
||||
### What is it
|
||||
A command line tool to work with your MEGA account and files. The intent is to offer all the MEGA account functionality via command line. You can run it in [interactive](#interactive) mode where it processes all commands directly, or you can run its [scriptable](#scriptable) commands from your favourite Linux or Mac shell such as bash, or you can even run its commands in a Windows command prompt. And of course you can write scripts using those scriptable commands.
|
||||
@ -254,7 +254,7 @@ Verbosity: You can increase the amount of information given by any command by pa
|
||||
* [`help`](contrib/docs/commands/help.md)`[-f|-ff|--non-interactive|--upgrade|--paths] [--show-all-options]` Prints list of commands
|
||||
* [`https`](contrib/docs/commands/https.md)`[on|off]` Shows if HTTPS is used for transfers. Use "https on" to enable it.
|
||||
* [`info`](contrib/docs/commands/info.md)`remotepath1 remotepath2 ...` Prints media info of remote files
|
||||
* [`log`](contrib/docs/commands/log.md)`[-sc] level` Prints/Modifies the current logs level
|
||||
* [`log`](contrib/docs/commands/log.md)`[-sc] level` Prints/Modifies the log level
|
||||
* [`permissions`](contrib/docs/commands/permissions.md)`[(--files|--folders) [-s XXX]]` Shows/Establish default permissions for files and folders created by MEGAcmd.
|
||||
* [`proxy`](contrib/docs/commands/proxy.md)`[URL|--auto|--none] [--username=USERNAME --password=PASSWORD]` Show or sets proxy configuration
|
||||
* [`psa`](contrib/docs/commands/psa.md)`[--discard]` Shows the next available Public Service Announcement (PSA)
|
||||
|
@ -51,9 +51,9 @@ WORKDIR /usr/src/megacmd
|
||||
#ENV CXX "ccache g++-12"
|
||||
ENV CCACHE_DIR /tmp/ccache
|
||||
ENV VCPKG_DEFAULT_BINARY_CACHE /tmp/vcpkgcache
|
||||
ARG ENABLE_ASAN=ON
|
||||
ARG ENABLE_UBSAN=ON
|
||||
ARG ENABLE_TSAN=OFF
|
||||
ARG ENABLE_asan=OFF
|
||||
ARG ENABLE_ubsan=OFF
|
||||
ARG ENABLE_tsan=OFF
|
||||
ARG ENABLE_MEGACMD_TESTS=ON
|
||||
|
||||
COPY --from=src /usr/src/megacmd /usr/src/megacmd
|
||||
@ -73,10 +73,10 @@ RUN --mount=type=cache,target=/tmp/ccache \
|
||||
-DCMAKE_C_COMPILER_LAUNCHER=ccache \
|
||||
-DCMAKE_BUILD_TYPE=Debug \
|
||||
-DCMAKE_VERBOSE_MAKEFILE=ON \
|
||||
-D ENABLE_ASAN=${ENABLE_ASAN} -D \
|
||||
ENABLE_UBSAN=${ENABLE_UBSAN} -D \
|
||||
ENABLE_TSAN=${ENABLE_TSAN} -D \
|
||||
ENABLE_MEGACMD_TESTS=${ENABLE_MEGACMD_TESTS} \
|
||||
-DENABLE_ASAN=${ENABLE_asan} \
|
||||
-DENABLE_UBSAN=${ENABLE_ubsan} \
|
||||
-DENABLE_TSAN=${ENABLE_tsan} \
|
||||
-DENABLE_MEGACMD_TESTS=${ENABLE_MEGACMD_TESTS} \
|
||||
WITH_FUSE=ON \
|
||||
&& cmake --build /tmp/build -j$(nproc) --target mega-cmd mega-cmd-server mega-exec \
|
||||
mega-cmd-updater mega-cmd-tests-integration mega-cmd-tests-unit \
|
||||
|
@ -1,38 +0,0 @@
|
||||
# How to build MEGAcmd for QNAP NAS drives.
|
||||
|
||||
We follow the cross compiling system provided by QNAP, described at (https://www.qnap.com/event/dev/en/p_qdk.php#qdk_btn1_show)
|
||||
|
||||
Tested with ubuntu 16.04 as the build machine - others may work but that one does for sure.
|
||||
|
||||
There are two main steps. First, cross-compiling the executables, which can be done on Ubuntu 16.04 for example. Second, preparing a QNAP package including those binaries, which must be done on a QNAP NAS device.
|
||||
|
||||
|
||||
# Cross-compiling
|
||||
|
||||
This example is for ARM, x86 and x86_64 will be similar.
|
||||
|
||||
Cross compiling machine requirements:
|
||||
- **Most or all commands need to be run as 'sudo'**.
|
||||
- dos2unix
|
||||
- cross compiler from QNAP: install by following QNAP instructions to unzip one of these (available from qnap) in your `/opt/cross-project` folder
|
||||
- `cross-project-arm-20110901.tar.gz` (for x19 platform) or
|
||||
- `TS-x31+_cross-project-arm_al.20150909.tar.gz` (for x41+ platform)
|
||||
|
||||
Then copy or git clone the MEGAcmd project to /opt/cross-project/qnap/MEGAcmd. The sdk must be copied or cloned to the 'sdk' subfolder of that.
|
||||
|
||||
From the MEGAcmd folder, execute: <p>
|
||||
`./build/QNAP/build-marvell` (for x19 ARM platform) <p>
|
||||
`./build/QNAP/build-linaro` (for x41+ ARM platform) <p>
|
||||
which will result in the binaries and scripts ending up in the MEGAcmd/install folder and being copied to the megacmdpkg folder ready to build the package.
|
||||
|
||||
|
||||
# Building a QNAP package
|
||||
|
||||
This must be done on a QNAP NAS as it requires their QDK package. Download QDK_2.2.16.qpkg and use the QNAP package manager to manually install that.
|
||||
|
||||
Next, use `scp` or a similar tool to copy the MEGAcmd/build/QNAP_NAS/megacmdpkg folder to the NAS, followed by the contents of the MEGAcmd/install folder:
|
||||
`scp -r build/QNAP_NAS/megacmdpkg admin@10.12.0.248:/share/CACHEDEV1_DATA/.qpkg/QDK/`
|
||||
|
||||
On the NAS, using ssh or similar, run the `qbuild` command from the megacmdpkg folder. The package will be built and put in the 'build' subfolder.
|
||||
|
||||
|
@ -1,12 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
for architecture in arm x; do
|
||||
for width in 32 64; do
|
||||
platform=$architecture$width
|
||||
result=OK
|
||||
|
||||
./build-$platform.sh &> $platform.log || result=FAIL
|
||||
|
||||
echo "$platform: $result"
|
||||
done
|
||||
done
|
||||
|
@ -1,12 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
export ARCH=arm
|
||||
export BUILD_ARCH=32
|
||||
export HOST=arm-linux-gnueabihf
|
||||
export PATH=/opt/cross-project/arm/linaro/bin:$PATH
|
||||
export ConfigOpt="--host $HOST"
|
||||
export PLATFORM=arm-x41
|
||||
|
||||
source build-common.sh
|
||||
|
||||
build_all
|
||||
|
@ -1,12 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
export ARCH=aarch64
|
||||
export BUILD_ARCH=64
|
||||
export HOST=aarch64-QNAP-linux-gnu
|
||||
export PATH=/opt/cross-project/$HOST/bin:$PATH
|
||||
export ConfigOpt="--host $HOST"
|
||||
export PLATFORM=arm_64
|
||||
|
||||
source build-common.sh
|
||||
|
||||
build_all
|
||||
|
@ -1,263 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
build_all()
|
||||
{
|
||||
# Purge prior build artifacts.
|
||||
clean || die "Couldn't remove prior build artifacts"
|
||||
|
||||
# Make sure AR, CC and friends are correctly set.
|
||||
fix_environment
|
||||
|
||||
# Perform the build.
|
||||
build_sdk || die "Couldn't build the SDK"
|
||||
build_cmd || die "Couldn't build MEGAcmd"
|
||||
|
||||
# Package the build.
|
||||
package || die "Unable to create package"
|
||||
}
|
||||
|
||||
build_cmd()
|
||||
{
|
||||
local prefix="$PWD/sdk/sdk_build/install"
|
||||
local flag_gtest="--with-gtest=$prefix"
|
||||
local flag_freeimage="--with-freeimage=$prefix"
|
||||
local flag_tests="--enable-tests"
|
||||
local result=0
|
||||
|
||||
./autogen.sh
|
||||
|
||||
result=$?
|
||||
|
||||
if [ $result -ne 0 ]; then
|
||||
return $result
|
||||
fi
|
||||
|
||||
use_freeimage || flag_freeimage="--without-freeimage"
|
||||
|
||||
if ! use_gtest; then
|
||||
flag_gtest="--without-gtest"
|
||||
flag_tests="--disable-tests"
|
||||
fi
|
||||
|
||||
env AR=$AR \
|
||||
ARCH=$ARCH \
|
||||
CC=$CC \
|
||||
CFLAGS="$(compiler_flags $CFLAGS)" \
|
||||
CPPFLAGS="$(preprocessor_flags $CFLAGS $CPPFLAGS)" \
|
||||
CXX=$CXX \
|
||||
CXXFLAGS="$(compiler_flags $CXXFLAGS)" \
|
||||
LD=$LD \
|
||||
NM=$NM \
|
||||
OBJCXX=$CXX \
|
||||
OBJDUMP=$OBJDUMP \
|
||||
RANLIB=$RANLIB \
|
||||
STRIP=$STRIP \
|
||||
./configure $ConfigOpt \
|
||||
--disable-curl-checks \
|
||||
--disable-examples \
|
||||
--disable-shared \
|
||||
--enable-inotify \
|
||||
--enable-static \
|
||||
--enable-sync \
|
||||
--with-cares="$prefix" \
|
||||
--with-cryptopp="$prefix" \
|
||||
--with-curl="$prefix" \
|
||||
--with-libmediainfo="$prefix" \
|
||||
--with-libuv="$prefix" \
|
||||
--with-libzen="$prefix" \
|
||||
--with-openssl="$prefix" \
|
||||
--with-readline="$prefix" \
|
||||
--with-sodium="$prefix" \
|
||||
--with-sqlite="$prefix" \
|
||||
--with-termcap="$prefix" \
|
||||
--with-zlib="$prefix" \
|
||||
--without-ffmpeg \
|
||||
--without-libraw \
|
||||
--without-pcre \
|
||||
--without-pdfium \
|
||||
$flag_gtest \
|
||||
$flag_freeimage \
|
||||
$flag_tests
|
||||
|
||||
result=$?
|
||||
|
||||
if [ $result -ne 0 ]; then
|
||||
return $result
|
||||
fi
|
||||
|
||||
make
|
||||
|
||||
result=$?
|
||||
|
||||
return $result
|
||||
}
|
||||
|
||||
build_sdk()
|
||||
{
|
||||
local flag_configure_only="-c"
|
||||
local flag_cross_compiling="-X"
|
||||
local flag_disable_examples="-n"
|
||||
local flag_disable_freeimage=""
|
||||
local flag_enable_cares="-e"
|
||||
local flag_enable_cryptopp="-q"
|
||||
local flag_enable_curl="-g"
|
||||
local flag_enable_megaapi="-a"
|
||||
local flag_enable_readline="-R"
|
||||
local flag_enable_sodium="-u"
|
||||
local flag_enable_tests="-T"
|
||||
local flag_enable_uv="-v"
|
||||
local flag_openssl_assembly=""
|
||||
local flag_openssl_compiler="linux-generic$BUILD_ARCH"
|
||||
local result=0
|
||||
|
||||
pushd sdk || return
|
||||
|
||||
mkdir -p sdk_build/build || return
|
||||
mkdir -p sdk_build/install/lib || return
|
||||
|
||||
use_assembly || flag_openssl_assembly="no-asm"
|
||||
use_gtest || flag_enable_tests=""
|
||||
use_freeimage || flag_disable_freeimage="-f"
|
||||
|
||||
env AR=$AR \
|
||||
ARCH=$ARCH \
|
||||
CC=$CC \
|
||||
CFLAGS="$(compiler_flags $CFLAGS)" \
|
||||
CPPFLAGS="$(preprocessor_flags $CFLAGS $CPPFLAGS)" \
|
||||
CXX=$CXX \
|
||||
CXXFLAGS="$(compiler_flags $CXXFLAGS)" \
|
||||
LD=$LD \
|
||||
NM=$NM \
|
||||
OBJCXX=$CXX \
|
||||
OBJDUMP=$OBJDUMP \
|
||||
RANLIB=$RANLIB \
|
||||
STRIP=$STRIP \
|
||||
./contrib/build_sdk.sh -C "$ConfigOpt" \
|
||||
-O "$flag_openssl_compiler" \
|
||||
-S "$flag_openssl_assembly" \
|
||||
$flag_configure_only \
|
||||
$flag_cross_compiling \
|
||||
$flag_disable_examples \
|
||||
$flag_disable_freeimage \
|
||||
$flag_enable_cares \
|
||||
$flag_enable_cryptopp \
|
||||
$flag_enable_curl \
|
||||
$flag_enable_megaapi \
|
||||
$flag_enable_readline \
|
||||
$flag_enable_sodium \
|
||||
$flag_enable_tests \
|
||||
$flag_enable_uv
|
||||
|
||||
local result=$?
|
||||
|
||||
popd
|
||||
|
||||
return $result
|
||||
}
|
||||
|
||||
clean()
|
||||
{
|
||||
if [ -f Makefile ]; then
|
||||
make distclean || return
|
||||
fi
|
||||
|
||||
rm -rf $(package_directory)
|
||||
}
|
||||
|
||||
die()
|
||||
{
|
||||
echo "ERROR: $1"
|
||||
exit 1
|
||||
}
|
||||
|
||||
compiler_flags()
|
||||
{
|
||||
local result="$*"
|
||||
|
||||
# Strip preprocessor flags.
|
||||
result="$(echo $result | sed -e 's/ *-[DI][^ ]\+//g')"
|
||||
|
||||
# Strip NEON flags (as it breaks freeimage.)
|
||||
result="$(echo $result | sed -e 's/-mfpu=neon[^ ]*//g')"
|
||||
|
||||
# GCC's ARM ABI changed between 7.0 and 7.1.
|
||||
result="$result -Wno-psabi"
|
||||
|
||||
echo "$result"
|
||||
}
|
||||
|
||||
fix_environment()
|
||||
{
|
||||
export CC=$HOST-gcc
|
||||
export CXX=$HOST-g++
|
||||
|
||||
for tool in ar ld nm ranlib strip; do
|
||||
export ${tool^^}=$HOST-$tool
|
||||
done
|
||||
}
|
||||
|
||||
package()
|
||||
{
|
||||
directory=$(package_directory)
|
||||
|
||||
mkdir -p $directory || return
|
||||
|
||||
cp mega-cmd \
|
||||
mega-cmd-server \
|
||||
mega-exec \
|
||||
src/client/mega-* \
|
||||
$directory \
|
||||
|| return
|
||||
|
||||
sed -i -e "s/^QPKG_VER=.*/QPKG_VER=\"$(version)\"/" \
|
||||
$(package_root)/qpkg.cfg
|
||||
}
|
||||
|
||||
package_directory()
|
||||
{
|
||||
echo "$(package_root)/$PLATFORM"
|
||||
}
|
||||
|
||||
package_root()
|
||||
{
|
||||
echo build/QNAP_NAS/megacmdpkg
|
||||
}
|
||||
|
||||
preprocessor_flags()
|
||||
{
|
||||
echo "$*" | grep -o -E -- '-[DI][^ ]+' | xargs
|
||||
}
|
||||
|
||||
use_assembly()
|
||||
{
|
||||
test "$ARCH" != "x86_64"
|
||||
}
|
||||
|
||||
use_gtest()
|
||||
{
|
||||
false
|
||||
}
|
||||
|
||||
use_freeimage()
|
||||
{
|
||||
true
|
||||
}
|
||||
|
||||
version()
|
||||
{
|
||||
major=$(version_component MAJOR)
|
||||
minor=$(version_component MINOR)
|
||||
micro=$(version_component MICRO)
|
||||
|
||||
echo "$major.$minor.$micro"
|
||||
}
|
||||
|
||||
version_component()
|
||||
{
|
||||
sed -ne "s/.*$1_VERSION \([0-9]\+\).*/\1/p" \
|
||||
src/megacmdversion.h
|
||||
}
|
||||
|
||||
# Make sure we're at the root of the MEGAcmd source tree.
|
||||
cd ../..
|
||||
|
@ -1,12 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
export ARCH=x86
|
||||
export BUILD_ARCH=32
|
||||
export HOST=i686-QNAP-linux-gnu
|
||||
export PATH=/opt/cross-project/CT/$HOST/cross-tools/bin:$PATH
|
||||
export ConfigOpt="--host $HOST"
|
||||
export PLATFORM=$ARCH
|
||||
|
||||
source build-common.sh
|
||||
|
||||
build_all
|
||||
|
@ -1,12 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
export ARCH=x86_64
|
||||
export BUILD_ARCH=64
|
||||
export HOST=x86_64-QNAP-linux-gnu
|
||||
export PATH=/opt/cross-project/CT/$HOST/cross-tools/bin:$PATH
|
||||
export ConfigOpt="--host $HOST"
|
||||
export PLATFORM=$ARCH
|
||||
|
||||
source build-common.sh
|
||||
|
||||
build_all
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 7.3 KiB |
Binary file not shown.
Before Width: | Height: | Size: 5.4 KiB |
Binary file not shown.
Before Width: | Height: | Size: 2.6 KiB |
@ -1,141 +0,0 @@
|
||||
######################################################################
|
||||
# List of available definitions (it's not necessary to uncomment them)
|
||||
######################################################################
|
||||
###### Command definitions #####
|
||||
#CMD_AWK="/bin/awk"
|
||||
#CMD_CAT="/bin/cat"
|
||||
#CMD_CHMOD="/bin/chmod"
|
||||
#CMD_CHOWN="/bin/chown"
|
||||
#CMD_CP="/bin/cp"
|
||||
#CMD_CUT="/bin/cut"
|
||||
#CMD_DATE="/bin/date"
|
||||
#CMD_ECHO="/bin/echo"
|
||||
#CMD_EXPR="/usr/bin/expr"
|
||||
#CMD_FIND="/usr/bin/find"
|
||||
#CMD_GETCFG="/sbin/getcfg"
|
||||
#CMD_GREP="/bin/grep"
|
||||
#CMD_GZIP="/bin/gzip"
|
||||
#CMD_HOSTNAME="/bin/hostname"
|
||||
#CMD_LN="/bin/ln"
|
||||
#CMD_LOG_TOOL="/sbin/log_tool"
|
||||
#CMD_MD5SUM="/bin/md5sum"
|
||||
#CMD_MKDIR="/bin/mkdir"
|
||||
#CMD_MV="/bin/mv"
|
||||
#CMD_RM="/bin/rm"
|
||||
#CMD_RMDIR="/bin/rmdir"
|
||||
#CMD_SED="/bin/sed"
|
||||
#CMD_SETCFG="/sbin/setcfg"
|
||||
#CMD_SLEEP="/bin/sleep"
|
||||
#CMD_SORT="/usr/bin/sort"
|
||||
#CMD_SYNC="/bin/sync"
|
||||
#CMD_TAR="/bin/tar"
|
||||
#CMD_TOUCH="/bin/touch"
|
||||
#CMD_WGET="/usr/bin/wget"
|
||||
#CMD_WLOG="/sbin/write_log"
|
||||
#CMD_XARGS="/usr/bin/xargs"
|
||||
#CMD_7Z="/usr/local/sbin/7z"
|
||||
#
|
||||
###### System definitions #####
|
||||
#SYS_EXTRACT_DIR="$(pwd)"
|
||||
#SYS_CONFIG_DIR="/etc/config"
|
||||
#SYS_INIT_DIR="/etc/init.d"
|
||||
#SYS_STARTUP_DIR="/etc/rcS.d"
|
||||
#SYS_SHUTDOWN_DIR="/etc/rcK.d"
|
||||
#SYS_RSS_IMG_DIR="/home/httpd/RSS/images"
|
||||
#SYS_QPKG_DATA_FILE_GZIP="./data.tar.gz"
|
||||
#SYS_QPKG_DATA_FILE_BZIP2="./data.tar.bz2"
|
||||
#SYS_QPKG_DATA_FILE_7ZIP="./data.tar.7z"
|
||||
#SYS_QPKG_DATA_CONFIG_FILE="./conf.tar.gz"
|
||||
#SYS_QPKG_DATA_MD5SUM_FILE="./md5sum"
|
||||
#SYS_QPKG_DATA_PACKAGES_FILE="./Packages.gz"
|
||||
#SYS_QPKG_CONFIG_FILE="$SYS_CONFIG_DIR/qpkg.conf"
|
||||
#SYS_QPKG_CONF_FIELD_QPKGFILE="QPKG_File"
|
||||
#SYS_QPKG_CONF_FIELD_NAME="Name"
|
||||
#SYS_QPKG_CONF_FIELD_VERSION="Version"
|
||||
#SYS_QPKG_CONF_FIELD_ENABLE="Enable"
|
||||
#SYS_QPKG_CONF_FIELD_DATE="Date"
|
||||
#SYS_QPKG_CONF_FIELD_SHELL="Shell"
|
||||
#SYS_QPKG_CONF_FIELD_INSTALL_PATH="Install_Path"
|
||||
#SYS_QPKG_CONF_FIELD_CONFIG_PATH="Config_Path"
|
||||
#SYS_QPKG_CONF_FIELD_WEBUI="WebUI"
|
||||
#SYS_QPKG_CONF_FIELD_WEBPORT="Web_Port"
|
||||
#SYS_QPKG_CONF_FIELD_SERVICEPORT="Service_Port"
|
||||
#SYS_QPKG_CONF_FIELD_SERVICE_PIDFILE="Pid_File"
|
||||
#SYS_QPKG_CONF_FIELD_AUTHOR="Author"
|
||||
#SYS_QPKG_CONF_FIELD_RC_NUMBER="RC_Number"
|
||||
## The following variables are assigned values at run-time.
|
||||
#SYS_HOSTNAME=$($CMD_HOSTNAME)
|
||||
## Data file name (one of SYS_QPKG_DATA_FILE_GZIP, SYS_QPKG_DATA_FILE_BZIP2,
|
||||
## or SYS_QPKG_DATA_FILE_7ZIP)
|
||||
#SYS_QPKG_DATA_FILE=
|
||||
## Base location.
|
||||
#SYS_QPKG_BASE=""
|
||||
## Base location of QPKG installed packages.
|
||||
#SYS_QPKG_INSTALL_PATH=""
|
||||
## Location of installed software.
|
||||
#SYS_QPKG_DIR=""
|
||||
## If the QPKG should be enabled or disabled after the installation/upgrade.
|
||||
#SYS_QPKG_SERVICE_ENABLED=""
|
||||
## Architecture of the device the QPKG is installed on.
|
||||
#SYS_CPU_ARCH=""
|
||||
## Name and location of system shares
|
||||
#SYS_PUBLIC_SHARE=""
|
||||
#SYS_PUBLIC_PATH=""
|
||||
#SYS_DOWNLOAD_SHARE=""
|
||||
#SYS_DOWNLOAD_PATH=""
|
||||
#SYS_MULTIMEDIA_SHARE=""
|
||||
#SYS_MULTIMEDIA_PATH=""
|
||||
#SYS_RECORDINGS_SHARE=""
|
||||
#SYS_RECORDINGS_PATH=""
|
||||
#SYS_USB_SHARE=""
|
||||
#SYS_USB_PATH=""
|
||||
#SYS_WEB_SHARE=""
|
||||
#SYS_WEB_PATH=""
|
||||
## Path to ipkg or opkg package tool if installed.
|
||||
#CMD_PKG_TOOL=
|
||||
#
|
||||
######################################################################
|
||||
# All package specific functions shall call 'err_log MSG' if an error
|
||||
# is detected that shall terminate the installation.
|
||||
######################################################################
|
||||
#
|
||||
######################################################################
|
||||
# Define any package specific operations that shall be performed when
|
||||
# the package is removed.
|
||||
######################################################################
|
||||
#PKG_PRE_REMOVE="{
|
||||
#}"
|
||||
#
|
||||
#PKG_MAIN_REMOVE="{
|
||||
#}"
|
||||
#
|
||||
#PKG_POST_REMOVE="{
|
||||
#}"
|
||||
#
|
||||
######################################################################
|
||||
# Define any package specific initialization that shall be performed
|
||||
# before the package is installed.
|
||||
######################################################################
|
||||
#pkg_init(){
|
||||
#}
|
||||
#
|
||||
######################################################################
|
||||
# Define any package specific requirement checks that shall be
|
||||
# performed before the package is installed.
|
||||
######################################################################
|
||||
#pkg_check_requirement(){
|
||||
#}
|
||||
#
|
||||
######################################################################
|
||||
# Define any package specific operations that shall be performed when
|
||||
# the package is installed.
|
||||
######################################################################
|
||||
#pkg_pre_install(){
|
||||
#}
|
||||
#
|
||||
#pkg_install(){
|
||||
#}
|
||||
|
||||
pkg_post_install(){
|
||||
/usr/sbin/dbus-uuidgen --ensure=/etc/machine-id
|
||||
}
|
@ -1,2 +0,0 @@
|
||||
#!/bin/sh
|
||||
exit 0
|
@ -1,29 +0,0 @@
|
||||
# Name of the packaged application.
|
||||
QPKG_NAME="MEGAcmd"
|
||||
# Name of the display application.
|
||||
QPKG_DISPLAY_NAME="MEGAcmd"
|
||||
# Version of the packaged application.
|
||||
QPKG_VER="1.7.0"
|
||||
# Author or maintainer of the package
|
||||
QPKG_AUTHOR="Mega.nz"
|
||||
# One-line description of the packaged application
|
||||
QPKG_SUMMARY="Synchronise or backup your NAS folders to Mega.nz"
|
||||
|
||||
# Preferred number in start/stop sequence.
|
||||
QPKG_RC_NUM="101"
|
||||
# Init-script used to control the start and stop of the installed application.
|
||||
QPKG_SERVICE_PROGRAM="MEGAcmd.sh"
|
||||
|
||||
# Relative path to web interface
|
||||
QPKG_WEBUI="/MEGAcmd/"
|
||||
# Port number for the web interface.
|
||||
QPKG_WEB_PORT="-1"
|
||||
|
||||
#Desktop Application (since 4.1)
|
||||
# Set value to 1 means to open the QPKG's Web UI inside QTS desktop instead of new window.
|
||||
QPKG_DESKTOP_APP="1"
|
||||
|
||||
# Min/Max QTS version requirement
|
||||
QTS_MINI_VERSION="4.3.6"
|
||||
QTS_MAX_VERSION="6.0.0"
|
||||
|
@ -1,56 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
service_start()
|
||||
{
|
||||
web_config_add
|
||||
web_config_reload
|
||||
}
|
||||
|
||||
service_stop()
|
||||
{
|
||||
web_config_remove
|
||||
web_config_reload
|
||||
}
|
||||
|
||||
web_config_add()
|
||||
{
|
||||
local getcfg="/sbin/getcfg"
|
||||
local name="MEGAcmd"
|
||||
local conf="/etc/config/qpkg.conf"
|
||||
local root="$($getcfg $name Install_Path -f $conf)"
|
||||
|
||||
ln -sf $root /home/httpd/cgi-bin/qpkg
|
||||
ln -sf $root/web/apache-megacmd.conf /etc/default_config/apache/extra
|
||||
}
|
||||
|
||||
web_config_reload()
|
||||
{
|
||||
/etc/init.d/thttpd.sh reload
|
||||
/etc/init.d/stunnel.sh reload
|
||||
}
|
||||
|
||||
web_config_remove()
|
||||
{
|
||||
rm -f /etc/default_config/apache/extra/apache-megacmd.conf
|
||||
rm -f /home/httpd/cgi-bin/qpkg/MEGAcmd
|
||||
}
|
||||
|
||||
case "$1" in
|
||||
start)
|
||||
service_start
|
||||
;;
|
||||
stop)
|
||||
service_stop
|
||||
;;
|
||||
restart)
|
||||
service_stop
|
||||
service_start
|
||||
;;
|
||||
*)
|
||||
echo "Usage: $@ {start|stop|restart}"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
exit 0
|
||||
|
@ -1,7 +0,0 @@
|
||||
<IfModule alias_module>
|
||||
Alias /cgi-bin/MEGAcmd "/home/httpd/cgi-bin/qpkg/MEGAcmd/web"
|
||||
Alias /MEGAcmd "/home/httpd/cgi-bin/qpkg/MEGAcmd/web"
|
||||
ProxyPass /MEGAcmd !
|
||||
ProxyPass /cgi-bin/MEGAcmd !
|
||||
</IfModule>
|
||||
|
@ -1,72 +0,0 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>Welcome to MEGAcmd</title>
|
||||
<link rel="icon" href="https://mega.nz/favicon.ico?v=3" type="image/x-icon" />
|
||||
</head>
|
||||
<body>
|
||||
MEGAcmd is a command line tool. Now that it is installed, please connect to your QNAP NAS drive with ssh, PuTTY, or similar. The executables are at %%%.
|
||||
In order for the scripts to work, please add that path to your PATH. Please refer to the built-in help or to the <a href="https://github.com/meganz/MEGAcmd/blob/master/UserGuide.md" target="_blank">User Guide</a>.
|
||||
<p>
|
||||
Here is an example session:
|
||||
<p>
|
||||
<tt>
|
||||
<PRE>
|
||||
login as: admin
|
||||
admin@10.12.0.248's password:
|
||||
[~] # export PATH=/share/CACHEDEV1_DATA/.qpkg/MEGAcmd:$PATH
|
||||
[~] # mega-cmd
|
||||
|
||||
.=============================================================================.
|
||||
| __ __ _____ ____ _ _ |
|
||||
| | \/ | ___|/ ___| / \ ___ _ __ ___ __| | |
|
||||
| | |\/| | \ / | _ / _ \ / __| '_ ` _ \ / _` | |
|
||||
| | | | | /__\ |_| |/ ___ \ (__| | | | | | (_| | |
|
||||
| |_| |_|____|\____/_/ \_\___|_| |_| |_|\__,_| |
|
||||
| |
|
||||
| Welcome to MEGAcmd! A Command Line Interactive and Scriptable |
|
||||
| Application to interact with your MEGA account |
|
||||
| This is a BETA version, it might not be bug-free. |
|
||||
| Also, the signature/output of the commands may change in a future. |
|
||||
| Please write to support@mega.nz if you find any issue or |
|
||||
| have any suggestion concerning its functionalities. |
|
||||
| Enter "help --non-interactive" to learn how to use MEGAcmd with scripts. |
|
||||
| Enter "help" for basic info and a list of available commands. |
|
||||
`=============================================================================´
|
||||
[Initiating server in background. Log: /root/.megaCmd/megacmdserver.log]
|
||||
|
||||
MEGA CMD> help
|
||||
Here is the list of available commands and their usage
|
||||
Use "help -f" to get a brief description of the commands
|
||||
You can get further help on a specific command with "command" --help
|
||||
Alternatively, you can use "help" -ff to get a complete description of all commands
|
||||
Use "help --non-interactive" to learn how to use MEGAcmd with scripts
|
||||
Use "help --upgrade" to learn about the limitations and obtaining PRO accounts
|
||||
|
||||
Commands:
|
||||
attr graphics preview
|
||||
backup help put
|
||||
cancel https pwd
|
||||
cd import quit
|
||||
clear invite reload
|
||||
completion ipc rm
|
||||
confirm killsession session
|
||||
confirmcancel lcd share
|
||||
cp log showpcr
|
||||
debug login signup
|
||||
deleteversions logout speedlimit
|
||||
du lpwd sync
|
||||
errorcode ls thumbnail
|
||||
exclude masterkey transfers
|
||||
exit mkdir userattr
|
||||
export mount users
|
||||
find mv version
|
||||
ftp passwd webdav
|
||||
get permissions whoami
|
||||
|
||||
Verbosity: You can increase the amount of information given by any command by passing "-v" ("-vv", "-vvv", ...)
|
||||
MEGA CMD>
|
||||
</PRE>
|
||||
</tt>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -1,42 +1,35 @@
|
||||
# How to build MEGAcmd for Synology NAS drives.
|
||||
# How to build MEGAcmd for Synology NAS drives.
|
||||
|
||||
We follow the cross compiling system provided by Synology, described in their [developer-guide.pdf](https://global.download.synology.com/download/Document/DeveloperGuide/DSM_Developer_Guide.pdf) (also at https://originhelp.synology.com/developer-guide/getting_started/index.html).
|
||||
Tested with ubuntu 16.04 as the build machine - others may work but that one does for sure.
|
||||
|
||||
**All commands need to be run as 'sudo'**. We are going to set up a root folder /toolkit, and work out of that. The cross-compile system uses chroot to build inside a subfolder of that.
|
||||
We use docker to cross-compile MEGAcmd for Synology. To build for a specific platform, run:
|
||||
```
|
||||
docker build -t megacmd-dms-build-env -f $PWD/build/SynologyNAS/synology-cross-build.dockerfile $PWD --build-arg PLATFORM=<platform>
|
||||
```
|
||||
The `-t` argument tags the container with a name, whereas `-f` specifies the dockerfile. Note that the working directory has to be the MEGAcmd repository.
|
||||
|
||||
Copy this folder tree into /toolkit
|
||||
`cp -r ...git.../MEGAcmd/build/SynologyNAS/toolkit /`
|
||||
`cd /toolkit`
|
||||
|
||||
Copy the MEGACmd folder (and sdk subfolder) into it also. The sdk should already be in the 'sdk' subfolder of MEGAcmd
|
||||
`cp -r ...git.../MEGAcmd /toolkit/source/MEGAcmd/`
|
||||
|
||||
Get the Synology scripts
|
||||
`git clone https://github.com/SynologyOpenSource/pkgscripts-ng`
|
||||
The possible platforms are:
|
||||
```
|
||||
alpine alpine4k apollolake armada37xx armada38x avoton broadwell broadwellnk broadwellnkv2 broadwellntbap bromolow braswell denverton epyc7002 geminilake grantley kvmx64 monaco purley r1000 rtd1296 rtd1619b v1000
|
||||
```
|
||||
|
||||
After building successfully, we need to run the container so we can extract the generated package. To do so, run:
|
||||
```
|
||||
docker run -d --name megacmd-dms megacmd-dms-build-env
|
||||
```
|
||||
Then, copy the package folder to the current directory with:
|
||||
```
|
||||
docker cp megacmd-dms:/image/<platform> .
|
||||
```
|
||||
After copying, we can stop and remove the container if needed:
|
||||
```
|
||||
docker rm -f megacmd-dms
|
||||
```
|
||||
|
||||
The script `build/SynologyNAS/generate_pkg.sh` automates all of these steps, creating the necessary docker container, extracting the package from it, and deleting it afterwards. In this case, the package will be extracted to `build/SynologyNAS/packages`.
|
||||
|
||||
To install the package on your NAS device, login using the web interface. Navigate to the Package Manager, and click Manual Install. This will open up a menu which lets you choose a local file. Select your generated .pkg file, and install.
|
||||
|
||||
To actually run MEGAcmd, you'll need to enable a telnet or SSH connection in the Synology NAS, and run a remote terminal on it. Executables are available at `/volume1/@appstore/megacmdpkg`.
|
||||
|
||||
Download and install the cross-compile build enviroment for one or many targets. Using armada38x here for the platform, as that's the chip for a DS218j NAS which was tested first. 6.1 is the NAS OS version.
|
||||
`./pkgscripts-ng/EnvDeploy -v 6.1 -p armada38x`
|
||||
|
||||
Adjust the package details, including version number. Adjust OS version in 'depends' if building for a later OS than 6.1
|
||||
`vi ./source/MEGAcmd/INFO.sh`
|
||||
`vi ./source/MEGAcmd/SynoBuildConf/depends`
|
||||
|
||||
Run the build process
|
||||
`./pkgscripts-ng/PkgCreate.py MEGAcmd`
|
||||
Results can now be seen in /toolkit/build_env/ds.armada38x-6.1/source/MEGAcmd/MEGAcmd
|
||||
|
||||
Package up the executables and scripts, provided the build actually succeeded (though it may say it failed even though we force 'exit 0' from the build script)
|
||||
For official releases we may sign with an RSA key at this point, but were we are skipping signing with -S
|
||||
`./pkgscripts-ng/PkgCreate.py -i -S MEGAcmd`
|
||||
Package is now available at /toolkit/build_env/ds.armada38x-6.1/image/packages/
|
||||
Install on your NAS from its web browser interface, Package Manager, Manual Install button which lets you choose a local file
|
||||
|
||||
To actually run it, you'll need to enable telnet connections in the Synology NAS, then telnet to it. PuTTY works nicely for this.
|
||||
Executables are available at /volume1/@appstore/MEGAcmd/usr/local/bin
|
||||
If you want to make a clean build after making changes inside /toolkit/source, then get rid of this (substitute the platform appropriately), and re-run EnvDeploy:
|
||||
`rm -rf /toolkit/build_env/ds.armada38x-6.1`
|
||||
|
||||
# Notes
|
||||
|
||||
**Writable Home Directory**
|
||||
|
@ -1,22 +0,0 @@
|
||||
This directory contains scripts to build Synology packages on a continuous
|
||||
integration server such as Jenkins.
|
||||
|
||||
`trigger.sh` and `wait.sh` are run by a regular user where `trigger.sh`
|
||||
simply touches a file named `start` to indicate that the build should start.
|
||||
|
||||
`wait.sh` can then be run to check whether the build has finished by virtue
|
||||
of the modified time stamp of a file named `result`.
|
||||
|
||||
The actual build is performed by running `build.sh` as a root user. This
|
||||
build script is run through a daemon user when the `start` file changes its
|
||||
modified time stamp. Once finished, the build script will update the modified
|
||||
time stamp of `result` and populate the file with the status of the build
|
||||
artifacts.
|
||||
|
||||
The workflow is as follows:
|
||||
# Start daemon process that watches for `start`
|
||||
# `trigger.sh` is run that touches `start`
|
||||
# The daemon process commences the build
|
||||
# `wait.sh` is run to wait for the build to finish
|
||||
# The build finishes
|
||||
# `wait.sh` is notified and exits
|
@ -1,35 +0,0 @@
|
||||
#!/bin/bash
|
||||
# This scripts performs the build for all supported Synology platforms
|
||||
set -ex
|
||||
thisdir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
||||
|
||||
builddir=/toolkit
|
||||
rm -rf $builddir
|
||||
|
||||
# Clone MEGAcmd into the build dir
|
||||
mkdir -p $builddir/source/megacmdpkg
|
||||
cd $builddir/source/megacmdpkg
|
||||
git clone --recursive https://github.com/meganz/MEGAcmd.git
|
||||
|
||||
# Copy toolkit files into place and clone Synology scripts
|
||||
cd $builddir
|
||||
cp -r $builddir/source/megacmdpkg/MEGAcmd/build/SynologyNAS/toolkit/* .
|
||||
git clone https://github.com/SynologyOpenSource/pkgscripts-ng
|
||||
|
||||
# Create a link to the toolkit tarballs
|
||||
ln -s /toolkit_tarballs toolkit_tarballs
|
||||
|
||||
# Perform the actual build
|
||||
./build_all_synology_packages || true
|
||||
|
||||
# Collect results
|
||||
resultdir=synology_build_results
|
||||
|
||||
rm -rf $thisdir/images
|
||||
mkdir $thisdir/images
|
||||
cp -r $resultdir/image-* $thisdir/images
|
||||
|
||||
rm -f $thisdir/result
|
||||
touch $thisdir/result
|
||||
echo `ls -1 $resultdir/*.failed` >> $thisdir/result
|
||||
echo `ls -1 $resultdir/*.built` >> $thisdir/result
|
@ -1,5 +0,0 @@
|
||||
#!/bin/bash
|
||||
# This script triggers the build by touching `start`
|
||||
set -ex
|
||||
thisdir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
||||
touch $thisdir/start
|
@ -1,14 +0,0 @@
|
||||
#!/bin/bash
|
||||
# This script waits for the build to finish by checking for the modified
|
||||
# time stamps of `start` and `result`
|
||||
set -ex
|
||||
thisdir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
||||
|
||||
function modified_time_s {
|
||||
date +%s -r $1 2>/dev/null || echo -1
|
||||
}
|
||||
|
||||
while [ `modified_time_s $thisdir/start` -gt `modified_time_s $thisdir/result` ]; do
|
||||
sleep 1
|
||||
done
|
||||
echo "Build finished!"
|
85
build/SynologyNAS/dockerfile/synology-cross-build.dockerfile
Normal file
85
build/SynologyNAS/dockerfile/synology-cross-build.dockerfile
Normal file
@ -0,0 +1,85 @@
|
||||
# Dockerfile for cross-compiling MEGAcmd for Synology in its different architectures. See README.md for more info.
|
||||
FROM debian:12-slim
|
||||
|
||||
# Set default architecture
|
||||
ARG PLATFORM=alpine
|
||||
ENV PLATFORM=${PLATFORM}
|
||||
|
||||
RUN apt-get --quiet=2 update && DEBCONF_NOWARNINGS=yes apt-get --quiet=2 install \
|
||||
aria2 \
|
||||
autoconf \
|
||||
autoconf-archive \
|
||||
build-essential \
|
||||
ccache \
|
||||
cmake \
|
||||
curl \
|
||||
fakeroot \
|
||||
git \
|
||||
nasm \
|
||||
pkg-config \
|
||||
python3 \
|
||||
tar \
|
||||
unzip \
|
||||
wget \
|
||||
xz-utils \
|
||||
zip \
|
||||
1> /dev/null
|
||||
|
||||
ENV CCACHE_DIR=/tmp/ccache
|
||||
ENV VCPKG_DEFAULT_BINARY_CACHE=/tmp/vcpkgcache
|
||||
|
||||
# We don't wont a potential config coming from host machine to meddle with the build
|
||||
RUN rm sdk/include/mega/config.h || true
|
||||
|
||||
WORKDIR /mega
|
||||
RUN chmod 777 /mega
|
||||
|
||||
# Clone and checkout known pkgscripts baseline
|
||||
RUN git clone https://github.com/SynologyOpenSource/pkgscripts-ng.git pkgscripts \
|
||||
&& git -C ./pkgscripts checkout e1d9f52
|
||||
|
||||
COPY sdk/dockerfile/dms-toolchain.sh /mega/
|
||||
COPY sdk/dockerfile/dms-toolchains.conf /mega/
|
||||
COPY build/SynologyNAS/toolkit/source/MEGAcmd/SynoBuildConf/install /mega/spk_install.sh
|
||||
|
||||
RUN chmod +x /mega/dms-toolchain.sh
|
||||
RUN chmod +x /mega/spk_install.sh
|
||||
|
||||
COPY vcpkg.json ./vcpkg.json
|
||||
COPY build/clone_vcpkg_from_baseline.sh ./clone_vcpkg_from_baseline.sh
|
||||
RUN /mega/clone_vcpkg_from_baseline.sh /mega/vcpkg
|
||||
|
||||
WORKDIR /mega/megacmd
|
||||
COPY sdk ./sdk
|
||||
COPY src ./src
|
||||
COPY build ./build
|
||||
COPY contrib ./contrib
|
||||
COPY tests/common ./tests/common
|
||||
COPY CMakeLists.txt ./CMakeLists.txt
|
||||
COPY vcpkg.json ./vcpkg.json
|
||||
|
||||
RUN /mega/dms-toolchain.sh ${PLATFORM}
|
||||
|
||||
# Remove the dynamic version of libatomic to avoid compiling with it, which causes
|
||||
# execution to fail in the NAS because the shared library object cannot be found
|
||||
RUN find /mega/toolchain/ \( -type f -o -type l \) -name libatomic.so* -delete
|
||||
|
||||
RUN --mount=type=cache,target=/tmp/ccache \
|
||||
--mount=type=cache,target=/tmp/vcpkgcache \
|
||||
--mount=type=tmpfs,target=/tmp/build \
|
||||
cmake -B buildDMS \
|
||||
-DCMAKE_BUILD_TYPE=RelWithDebInfo \
|
||||
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
|
||||
-DCMAKE_C_COMPILER_LAUNCHER=ccache \
|
||||
-DENABLE_MEGACMD_TESTS=OFF \
|
||||
-DENABLE_ASAN=OFF \
|
||||
-DENABLE_UBSAN=OFF \
|
||||
-DENABLE_TSAN=OFF \
|
||||
-DCMAKE_VERBOSE_MAKEFILE=ON \
|
||||
-DVCPKG_CHAINLOAD_TOOLCHAIN_FILE=/mega/${PLATFORM}.toolchain.cmake \
|
||||
-DVCPKG_OVERLAY_TRIPLETS=/mega \
|
||||
-DVCPKG_ROOT=/mega/vcpkg \
|
||||
-DVCPKG_TARGET_TRIPLET=${PLATFORM} && \
|
||||
cmake --build buildDMS
|
||||
|
||||
RUN export PLATFORM=${PLATFORM} && /mega/spk_install.sh
|
35
build/SynologyNAS/generate_pkg.sh
Executable file
35
build/SynologyNAS/generate_pkg.sh
Executable file
@ -0,0 +1,35 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
|
||||
|
||||
|
||||
if [ "$#" -ne 1 ]; then
|
||||
echo "Usage: $0 <platform>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
PLATFORM="$1"
|
||||
CONTAINER="megacmd-${PLATFORM}-build-env"
|
||||
|
||||
cleanup() {
|
||||
echo "Cleaning up container..."
|
||||
docker rm -f $CONTAINER > /dev/null 2>&1 || true
|
||||
}
|
||||
trap cleanup EXIT
|
||||
|
||||
echo "Starting build for '${PLATFORM}'..."
|
||||
|
||||
BUILDER_PARAMETER="${DOCKER_CUSTOM_BUILDER:+--builder $DOCKER_CUSTOM_BUILDER --load}"
|
||||
MEGACMD_FOLDER="${SOURCE_PATH:-${SCRIPT_DIR}/../..}"
|
||||
OUTPUT_FOLDER="${OUTPUT_PATH:-${SCRIPT_DIR}/packages}"
|
||||
|
||||
docker buildx build $BUILDER_PARAMETER -t $CONTAINER \
|
||||
-f "$SCRIPT_DIR/dockerfile/synology-cross-build.dockerfile" \
|
||||
"${MEGACMD_FOLDER}" \
|
||||
--build-arg PLATFORM="$PLATFORM"
|
||||
|
||||
CONTAINER_ID=$(docker create $CONTAINER)
|
||||
mkdir -p "$OUTPUT_FOLDER"
|
||||
docker cp "${CONTAINER_ID}:/image/${PLATFORM}" "${OUTPUT_FOLDER}"/
|
||||
|
||||
echo "Extracted package for '${PLATFORM}'"
|
@ -1,162 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Where we are.
|
||||
declare -r TOOLKIT_DIR=/toolkit
|
||||
|
||||
# Where builds are performed.
|
||||
declare -r BUILD_DIR=${TOOLKIT_DIR}/build_env
|
||||
|
||||
# Where we can find necessary patches.
|
||||
declare -r PATCH_DIR=$TOOLKIT_DIR/patches
|
||||
|
||||
# Where we can find Synology's package scripts.
|
||||
declare -r PKGSCRIPTS_DIR=${TOOLKIT_DIR}/pkgscripts-ng
|
||||
|
||||
# What version of DSM are we targeting?
|
||||
declare -r DSM_VERSION=7.2
|
||||
|
||||
# For convenience.
|
||||
declare -r ENVDEPLOY="${PKGSCRIPTS_DIR}/EnvDeploy -v ${DSM_VERSION}"
|
||||
declare -r PKGCREATE="${PKGSCRIPTS_DIR}/PkgCreate.py -v ${DSM_VERSION}"
|
||||
|
||||
# Full list of platforms.
|
||||
all_platforms()
|
||||
{
|
||||
${ENVDEPLOY} -l |& cut -c 54-
|
||||
}
|
||||
|
||||
# Performs a build for the specified platform.
|
||||
build()
|
||||
{
|
||||
local -r platform="$1"
|
||||
local -r env_dir="$(environment_path ${platform})"
|
||||
local -r src_dir="${TOOLKIT_DIR}/source/MEGAcmd"
|
||||
|
||||
# Wipe prior SDK build state.
|
||||
rm -rf ${src_dir}/MEGAcmd/sdk/sdk_build
|
||||
|
||||
# Prepare build environment.
|
||||
deploy_environment ${platform}
|
||||
|
||||
# Prepare for SDK build.
|
||||
mkdir -p ${env_dir}/tmp/megasdkbuild
|
||||
|
||||
# Avoid downloading SDK's dependencies.
|
||||
cp ${TOOLKIT_DIR}/sdk_dep_tarballs/* \
|
||||
${env_dir}/tmp/megasdkbuild
|
||||
|
||||
# Create a standard place where patches can be found.
|
||||
mkdir -p ${env_dir}/tmp/megapatches
|
||||
|
||||
# Make sure no stale patches are present.
|
||||
rm -f ${env_dir}/tmp/megapatches/*
|
||||
|
||||
# Copy patches into environment, if any.
|
||||
if [ -d "${PATCH_DIR}" ]; then
|
||||
find ${PATCH_DIR} \
|
||||
-type f \
|
||||
-name '*.patch' \
|
||||
-exec cp {} ${env_dir}/tmp/megapatches \;
|
||||
fi
|
||||
|
||||
# Kick off the build.
|
||||
if ${PKGCREATE} -p ${platform} MEGAcmd; then
|
||||
local -r result_dir="${TOOLKIT_DIR}/results/${platform}"
|
||||
|
||||
mkdir -p ${result_dir}
|
||||
|
||||
cp -av ${env_dir}/image/* ${result_dir}
|
||||
|
||||
clean_environment ${platform}
|
||||
fi
|
||||
}
|
||||
|
||||
# Platforms we'll be building for.
|
||||
build_platforms()
|
||||
{
|
||||
local -r info_dir="${PKGSCRIPTS_DIR}/include"
|
||||
|
||||
# Output all non-x64 platforms.
|
||||
for platform in $(all_platforms); do
|
||||
info_path="${info_dir}/platform.${platform}"
|
||||
|
||||
if ! grep -q 'ARCH="x86_64"' ${info_path}; then
|
||||
echo ${platform}
|
||||
fi
|
||||
done
|
||||
|
||||
# Output a representative x64 platform.
|
||||
echo kvmx64
|
||||
}
|
||||
|
||||
# Discards the environment for the specified platform.
|
||||
clean_environment()
|
||||
{
|
||||
local -r platform="$1"
|
||||
local -r env_dir="$(environment_path ${platform})"
|
||||
|
||||
if grep -q "${env_dir}/proc" /etc/mtab; then
|
||||
umount ${env_dir}/proc
|
||||
fi
|
||||
|
||||
rm -rf ${env_dir}
|
||||
}
|
||||
|
||||
# Deploys the environment for the specified platform.
|
||||
deploy_environment()
|
||||
{
|
||||
local -r platform="$1"
|
||||
|
||||
clean_environment ${platform}
|
||||
|
||||
${ENVDEPLOY} -D \
|
||||
-p $1 \
|
||||
-t ${TOOLKIT_DIR}/toolkit_tarballs
|
||||
}
|
||||
|
||||
# Checks that a directory is present.
|
||||
check_directory()
|
||||
{
|
||||
if [ ! -d $1 ]; then
|
||||
echo "ERROR: Directory $1 does not exist."
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Path to the specified platform's environment.
|
||||
environment_path()
|
||||
{
|
||||
echo "${BUILD_DIR}/ds.$1-${DSM_VERSION}"
|
||||
}
|
||||
|
||||
if [ "$(id -u)" != "0" ]; then
|
||||
echo "You must be root to run this script."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
check_directory $TOOLKIT_DIR
|
||||
check_directory ${PKGSCRIPTS_DIR}
|
||||
check_directory $TOOLKIT_DIR/sdk_dep_tarballs
|
||||
check_directory $TOOLKIT_DIR/source/MEGAcmd
|
||||
check_directory $TOOLKIT_DIR/toolkit_tarballs
|
||||
|
||||
# Clear prior build results.
|
||||
rm -rf ${TOOLKIT_DIR}/results
|
||||
platforms=$(build_platforms)
|
||||
|
||||
# Try and build the packages.
|
||||
for platform in ${platforms}; do
|
||||
build ${platform}
|
||||
done
|
||||
|
||||
# Check whether all the packages were built.
|
||||
for platform in ${platforms}; do
|
||||
echo -n "${platform}: "
|
||||
|
||||
if [ -d "${TOOLKIT_DIR}/results/${platform}" ]; then
|
||||
echo "OK"
|
||||
else
|
||||
echo "FAIL"
|
||||
fi
|
||||
done
|
||||
|
@ -1,89 +0,0 @@
|
||||
#!/bin/bash
|
||||
set -o pipefail
|
||||
|
||||
# Prints a message and terminates the script.
|
||||
die()
|
||||
{
|
||||
local message="$1"
|
||||
|
||||
echo "${message}"
|
||||
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Checks if a command is present.
|
||||
present()
|
||||
{
|
||||
local program="$1"
|
||||
|
||||
if ! command -v "${program}" >/dev/null; then
|
||||
die "Couldn't find ${program}"
|
||||
fi
|
||||
}
|
||||
|
||||
# Get a list of toolchain URIs.
|
||||
toolchains()
|
||||
{
|
||||
local root="https://archive.synology.com/download/ToolChain/toolkit"
|
||||
local version="$1"
|
||||
local uri="${root}/${version}"
|
||||
|
||||
curl "${uri}" 2>/dev/null | pup 'a[href$=.txz] attr{href}'
|
||||
}
|
||||
|
||||
# Display usage.
|
||||
usage()
|
||||
{
|
||||
die "get-toolchains.sh -d DESTINATION -v X.Y"
|
||||
}
|
||||
|
||||
# Make sure aria2 is present.
|
||||
present aria2c
|
||||
|
||||
# Make sure pup is present.
|
||||
present pup
|
||||
|
||||
# Make sure xargs is present.
|
||||
present xargs
|
||||
|
||||
destination=""
|
||||
version=""
|
||||
|
||||
# Parse arguments.
|
||||
while getopts ":d:v:" arguments; do
|
||||
case "${arguments}" in
|
||||
d)
|
||||
destination="${OPTARG}"
|
||||
;;
|
||||
v)
|
||||
version="${OPTARG}"
|
||||
;;
|
||||
?)
|
||||
usage
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Did the user specify where we should store the toolchains?
|
||||
test -n "${destination}" || die "You must specify a destination."
|
||||
|
||||
# Did the user specify a DSM version?
|
||||
test -n "${version}" || die "You must specify a DSM version."
|
||||
|
||||
# Try and retrieve a list of toolchain URIs.
|
||||
uris="$(toolchains ${version})"
|
||||
|
||||
# Couldn't get a list of toolchains.
|
||||
test -n "${uris}" || die "Couldn't get toolchains for DSM${version}"
|
||||
|
||||
echo "Trying to download toolchains..."
|
||||
|
||||
# Try and download the toolchains.
|
||||
aria2c --continue=true \
|
||||
--dir=${destination} \
|
||||
--force-sequential=true \
|
||||
${uris} \
|
||||
|| die "Couldn't download toolchains."
|
||||
|
||||
echo "Toolchains downloaded."
|
||||
|
@ -1,17 +1,12 @@
|
||||
#!/bin/bash
|
||||
|
||||
source /pkgscripts/include/pkg_util.sh
|
||||
source /mega/pkgscripts/include/pkg_util.sh
|
||||
|
||||
package="megacmdpkg"
|
||||
version="1.7.0-0001"
|
||||
version="2.0.0-0001"
|
||||
displayname="MEGAcmd"
|
||||
maintainer="Mega NZ"
|
||||
|
||||
arch="$(pkg_get_platform)"
|
||||
if [ "$arch" = "kvmx64" ]; then
|
||||
arch="x86_64"
|
||||
fi
|
||||
|
||||
arch="$PLATFORM"
|
||||
description="MEGAcmd command line tool. Access your MEGA.nz secure cloud storage account and upload/download files, use its commands in scripts, automatically synchronise folders between your MEGA.nz account and your Synology NAS. Connect to your NAS via ssh or Putty to use the MEGAcmd commands. Run mega-help from the command line for documentation, or see our User Guide online."
|
||||
os_min_ver="7.0-40000"
|
||||
maintainer="Mega Ltd."
|
||||
|
@ -1,217 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
apply_patches()
|
||||
{
|
||||
test -d /tmp/megapatches || return
|
||||
|
||||
for patch in $(ls /tmp/megapatches/* 2> /dev/null); do
|
||||
patch -d / -i $patch -p 0 || return
|
||||
done
|
||||
}
|
||||
|
||||
build_cmd()
|
||||
{
|
||||
pushd MEGAcmd || return
|
||||
|
||||
local prefix="$PWD/sdk/sdk_build/install"
|
||||
local flag_gtest="--with-gtest=$prefix"
|
||||
local flag_freeimage="--with-freeimage=$prefix"
|
||||
local flag_tests="--enable-tests"
|
||||
local result=0
|
||||
|
||||
./autogen.sh
|
||||
|
||||
result=$?
|
||||
|
||||
if [ $result -ne 0 ]; then
|
||||
popd
|
||||
return $result
|
||||
fi
|
||||
|
||||
use_freeimage || flag_freeimage="--without-freeimage"
|
||||
|
||||
if ! use_gtest; then
|
||||
flag_gtest="--without-gtest"
|
||||
flag_tests="--disable-tests"
|
||||
fi
|
||||
|
||||
env AR=$AR \
|
||||
ARCH=$ARCH \
|
||||
CC=$CC \
|
||||
CFLAGS="$(compiler_flags $CFLAGS)" \
|
||||
CPPFLAGS="$(preprocessor_flags $CFLAGS $CPPFLAGS)" \
|
||||
CXX=$CXX \
|
||||
CXXFLAGS="$(compiler_flags -std=c++14 $CXXFLAGS)" \
|
||||
LD=$LD \
|
||||
NM=$NM \
|
||||
OBJCXX=$CXX \
|
||||
OBJDUMP=$OBJDUMP \
|
||||
RANLIB=$RANLIB \
|
||||
STRIP=$STRIP \
|
||||
./configure $ConfigOpt \
|
||||
--disable-curl-checks \
|
||||
--disable-examples \
|
||||
--disable-shared \
|
||||
--enable-inotify \
|
||||
--enable-static \
|
||||
--enable-sync \
|
||||
--with-cares="$prefix" \
|
||||
--with-cryptopp="$prefix" \
|
||||
--with-curl="$prefix" \
|
||||
--with-libmediainfo="$prefix" \
|
||||
--with-libuv="$prefix" \
|
||||
--with-libzen="$prefix" \
|
||||
--with-openssl="$prefix" \
|
||||
--with-readline="$prefix" \
|
||||
--with-sodium="$prefix" \
|
||||
--with-sqlite="$prefix" \
|
||||
--with-termcap="$prefix" \
|
||||
--with-zlib="$prefix" \
|
||||
--without-ffmpeg \
|
||||
--without-libraw \
|
||||
--without-pcre \
|
||||
--without-pdfium \
|
||||
$flag_gtest \
|
||||
$flag_freeimage \
|
||||
$flag_tests
|
||||
|
||||
result=$?
|
||||
|
||||
if [ $result -ne 0 ]; then
|
||||
popd
|
||||
return $result
|
||||
fi
|
||||
|
||||
make
|
||||
|
||||
result=$?
|
||||
|
||||
popd
|
||||
|
||||
return $result
|
||||
}
|
||||
|
||||
build_sdk()
|
||||
{
|
||||
local flag_configure_only="-c"
|
||||
local flag_cross_compiling="-X"
|
||||
local flag_disable_examples="-n"
|
||||
local flag_disable_freeimage=""
|
||||
local flag_enable_cares="-e"
|
||||
local flag_enable_cryptopp="-q"
|
||||
local flag_enable_curl="-g"
|
||||
local flag_enable_megaapi="-a"
|
||||
local flag_enable_sodium="-u"
|
||||
local flag_enable_tests="-T"
|
||||
local flag_enable_uv="-v"
|
||||
local flag_openssl_assembly=""
|
||||
local flag_openssl_compiler="linux-generic$BUILD_ARCH"
|
||||
local result=0
|
||||
|
||||
pushd MEGAcmd/sdk || return
|
||||
|
||||
mkdir -p sdk_build/build || return
|
||||
mkdir -p sdk_build/install/lib || return
|
||||
|
||||
use_assembly || flag_openssl_assembly="no-asm"
|
||||
use_gtest || flag_enable_tests=""
|
||||
use_freeimage || flag_disable_freeimage="-f"
|
||||
|
||||
env AR=$AR \
|
||||
ARCH=$ARCH \
|
||||
CC=$CC \
|
||||
CFLAGS="$(compiler_flags $CFLAGS)" \
|
||||
CPPFLAGS="$(preprocessor_flags $CFLAGS $CPPFLAGS)" \
|
||||
CXX=$CXX \
|
||||
CXXFLAGS="$(compiler_flags $CXXFLAGS)" \
|
||||
LD=$LD \
|
||||
NM=$NM \
|
||||
OBJCXX=$CXX \
|
||||
OBJDUMP=$OBJDUMP \
|
||||
RANLIB=$RANLIB \
|
||||
STRIP=$STRIP \
|
||||
./contrib/build_sdk.sh -C "$ConfigOpt" \
|
||||
-O "$flag_openssl_compiler" \
|
||||
-S "$flag_openssl_assembly" \
|
||||
$flag_configure_only \
|
||||
$flag_cross_compiling \
|
||||
$flag_disable_examples \
|
||||
$flag_disable_freeimage \
|
||||
$flag_enable_cares \
|
||||
$flag_enable_cryptopp \
|
||||
$flag_enable_curl \
|
||||
$flag_enable_megaapi \
|
||||
$flag_enable_sodium \
|
||||
$flag_enable_tests \
|
||||
$flag_enable_uv
|
||||
|
||||
local result=$?
|
||||
|
||||
popd
|
||||
|
||||
return $result
|
||||
}
|
||||
|
||||
die()
|
||||
{
|
||||
echo "ERROR: $1"
|
||||
exit 1
|
||||
}
|
||||
|
||||
compiler_flags()
|
||||
{
|
||||
local result="$*"
|
||||
|
||||
# Strip preprocessor flags.
|
||||
result="$(echo $result | sed -e 's/ *-[DI][^ ]\+//g')"
|
||||
|
||||
# Strip NEON flags (as it breaks freeimage.)
|
||||
result="$(echo $result | sed -e 's/-mfpu=neon[^ ]*//g')"
|
||||
|
||||
# GCC's ARM ABI changed between 7.0 and 7.1.
|
||||
result="$result -Wno-psabi"
|
||||
|
||||
echo "$result"
|
||||
}
|
||||
|
||||
fix_environment()
|
||||
{
|
||||
find /usr -type f -name '*.la' \
|
||||
| xargs sed -i -e 's!\(/[^/]\+\)\+\(/usr.*\)!\2!g'
|
||||
|
||||
find /usr -type f -name '*.la' \
|
||||
| xargs sed -i -e 's!/home/cpt/hi3535/x-tools!/usr/local!g'
|
||||
}
|
||||
|
||||
preprocessor_flags()
|
||||
{
|
||||
echo "$*" | grep -o -E -- '-[DI][^ ]+' | xargs
|
||||
}
|
||||
|
||||
use_assembly()
|
||||
{
|
||||
# kvmx64 doesn't support AESNI instructions.
|
||||
test "$PLATFORM_ABBR" != "kvmx64" \
|
||||
-a "$PLATFORM_ABBR" != "apollolake"
|
||||
}
|
||||
|
||||
use_gtest()
|
||||
{
|
||||
# The comcerto toolchain doesn't support all of C++11.
|
||||
test "$PLATFORM_ABBR" != "comcerto2k"
|
||||
}
|
||||
|
||||
use_freeimage()
|
||||
{
|
||||
true
|
||||
}
|
||||
|
||||
printenv
|
||||
|
||||
apply_patches || die "Couldn't apply SDK patches"
|
||||
|
||||
fix_environment
|
||||
|
||||
build_sdk || die "Couldn't build the SDK"
|
||||
build_cmd || die "Couldn't build MEGAcmd"
|
||||
|
@ -1,43 +1,35 @@
|
||||
#!/bin/bash
|
||||
|
||||
mkdir /ccache-tmp
|
||||
export CCACHE_DIR=/ccache-tmp
|
||||
#!/bin/bash
|
||||
|
||||
### Use PKG_DIR as working directory.
|
||||
PKG_DIR=/tmp/_test_spk
|
||||
rm -rf $PKG_DIR
|
||||
mkdir -p $PKG_DIR
|
||||
|
||||
### get spk packing functions
|
||||
source /pkgscripts/include/pkg_util.sh
|
||||
source /mega/pkgscripts/include/pkg_util.sh
|
||||
|
||||
create_inner_tarball() {
|
||||
local inner_tarball_dir=/tmp/_inner_tarball
|
||||
|
||||
### clear destination directory
|
||||
### Clear destination directory
|
||||
rm -rf $inner_tarball_dir && mkdir -p $inner_tarball_dir
|
||||
|
||||
pushd MEGAcmd
|
||||
|
||||
cp mega-cmd \
|
||||
mega-cmd-server \
|
||||
mega-exec \
|
||||
cp buildDMS/mega-cmd \
|
||||
buildDMS/mega-cmd-server \
|
||||
buildDMS/mega-exec \
|
||||
src/client/mega-* \
|
||||
"$inner_tarball_dir"
|
||||
|
||||
if [ -x "sdk/tests/test_integration" ]; then
|
||||
cp sdk/tests/test_integration \
|
||||
sdk/tests/test_unit \
|
||||
"$inner_tarball_dir"
|
||||
fi
|
||||
|
||||
popd
|
||||
|
||||
### create package.txz: $1=source_dir, $2=dest_dir
|
||||
### Create package.txz: $1=source_dir, $2=dest_dir
|
||||
pkg_make_package $inner_tarball_dir "${PKG_DIR}"
|
||||
}
|
||||
|
||||
create_spk(){
|
||||
get_platform_family() {
|
||||
plat_to_family "$PLATFORM"
|
||||
}
|
||||
|
||||
create_spk() {
|
||||
pushd build/SynologyNAS/toolkit/source/MEGAcmd
|
||||
|
||||
### Copy conf and scripts.
|
||||
cp -av conf $PKG_DIR/.
|
||||
cp -av scripts $PKG_DIR/.
|
||||
@ -50,12 +42,11 @@ create_spk(){
|
||||
./INFO.sh > INFO
|
||||
cp -av INFO ${PKG_DIR}
|
||||
|
||||
### Create the final spk.
|
||||
# pkg_make_spk <source path> <dest path> <spk file name>
|
||||
# Please put the result spk into /image/packages
|
||||
# spk name functions: pkg_get_spk_name pkg_get_spk_unified_name pkg_get_spk_family_name
|
||||
mkdir -p /image/packages
|
||||
pkg_make_spk ${PKG_DIR} "/image/packages" $(pkg_get_spk_family_name)
|
||||
### Create the final spk
|
||||
mkdir -p "/image/${PLATFORM}"
|
||||
pkg_make_spk ${PKG_DIR} "/image/${PLATFORM}" $(__get_spk_name get_platform_family INFO)
|
||||
|
||||
popd
|
||||
}
|
||||
|
||||
create_inner_tarball
|
||||
|
@ -25,12 +25,6 @@ VIAddVersionKey "FileDescription" "MEGAcmd"
|
||||
VIAddVersionKey "LegalCopyright" "MEGA Limited 2019"
|
||||
VIAddVersionKey "ProductName" "MEGAcmd"
|
||||
|
||||
; Version info
|
||||
VIProductVersion "1.7.0.0"
|
||||
VIAddVersionKey "FileVersion" "1.7.0.0"
|
||||
VIAddVersionKey "ProductVersion" "1.7.0.0"
|
||||
!define PRODUCT_VERSION "1.7.0"
|
||||
|
||||
!define PRODUCT_PUBLISHER "Mega Limited"
|
||||
!define PRODUCT_WEB_SITE "http://www.mega.nz"
|
||||
!define PRODUCT_DIR_REGKEY "Software\Microsoft\Windows\CurrentVersion\App Paths\MEGAcmdShell.exe"
|
||||
@ -56,6 +50,29 @@ VIAddVersionKey "ProductVersion" "1.7.0.0"
|
||||
|
||||
!define SRCDIR_BATFILES "..\src\client\win"
|
||||
|
||||
; Version info: get version directly from the binary
|
||||
!getdllversion "${SRCDIR_MEGACMD}/MEGAcmdServer.exe" Expv_
|
||||
VIAddVersionKey "FileVersion" "${Expv_1}.${Expv_2}.${Expv_3}.${Expv_4}"
|
||||
!ifdef VERSION_SUFFIX
|
||||
VIProductVersion "${Expv_1}.${Expv_2}.${Expv_3}.${Expv_4}-${VERSION_SUFFIX}"
|
||||
VIAddVersionKey "ProductVersion" "${Expv_1}.${Expv_2}.${Expv_3}.${Expv_4}-${VERSION_SUFFIX}"
|
||||
!define PRODUCT_VERSION "${Expv_1}.${Expv_2}.${Expv_3}-${VERSION_SUFFIX}"
|
||||
!else
|
||||
VIProductVersion "${Expv_1}.${Expv_2}.${Expv_3}.${Expv_4}"
|
||||
VIAddVersionKey "ProductVersion" "${Expv_1}.${Expv_2}.${Expv_3}.${Expv_4}"
|
||||
!define PRODUCT_VERSION "${Expv_1}.${Expv_2}.${Expv_3}"
|
||||
!endif
|
||||
|
||||
!define VcRedistBasePath "C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Redist\MSVC\14.42.34433"
|
||||
!define VcRedist32BasePath "${VcRedistBasePath}\x86"
|
||||
!define VcRedist32Path "${VcRedist32BasePath}\Microsoft.VC143.CRT"
|
||||
!define VcRedist64BasePath "${VcRedistBasePath}\x64"
|
||||
!define VcRedist64Path "${VcRedist64BasePath}\Microsoft.VC143.CRT"
|
||||
|
||||
!define WinRedistBasePath "C:\Program Files (x86)\Windows Kits\10\Redist\${WINKITVER}\ucrt\DLLs"
|
||||
!define WinRedist32BasePath "${winRedistBasePath}\x86"
|
||||
!define WinRedist64BasePath "${winRedistBasePath}\x64"
|
||||
|
||||
!define MULTIUSER_MUI
|
||||
!define MULTIUSER_INSTALLMODE_COMMANDLINE
|
||||
!define MULTIUSER_EXECUTIONLEVEL Standard
|
||||
@ -360,108 +377,108 @@ modeselected:
|
||||
SetOutPath "$INSTDIR"
|
||||
|
||||
!ifdef BUILD_X64_VERSION
|
||||
!insertmacro Install3264DLL "C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\VC\Redist\MSVC\14.29.30133\x64\Microsoft.VC142.CRT\vcruntime140.dll" "$INSTDIR\vcruntime140.dll"
|
||||
!insertmacro Install3264DLL "C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\VC\Redist\MSVC\14.29.30133\x64\Microsoft.VC142.CRT\vcruntime140_1.dll" "$INSTDIR\vcruntime140_1.dll"
|
||||
!insertmacro Install3264DLL "C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\VC\Redist\MSVC\14.29.30133\x64\Microsoft.VC142.CRT\msvcp140.dll" "$INSTDIR\msvcp140.dll"
|
||||
!insertmacro Install3264DLL "C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\VC\Redist\MSVC\14.29.30133\x64\Microsoft.VC142.CRT\msvcp140_1.dll" "$INSTDIR\msvcp140_1.dll"
|
||||
!insertmacro Install3264DLL "C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\VC\Redist\MSVC\14.29.30133\x64\Microsoft.VC142.CRT\msvcp140_2.dll" "$INSTDIR\msvcp140_2.dll"
|
||||
!insertmacro Install3264DLL "C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\VC\Redist\MSVC\14.29.30133\x64\Microsoft.VC142.CRT\msvcp140_atomic_wait.dll" "$INSTDIR\msvcp140_atomic_wait.dll"
|
||||
!insertmacro Install3264DLL "C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\VC\Redist\MSVC\14.29.30133\x64\Microsoft.VC142.CRT\msvcp140_codecvt_ids.dll" "$INSTDIR\msvcp140_codecvt_ids.dll"
|
||||
!insertmacro Install3264DLL "C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\VC\Redist\MSVC\14.29.30133\x64\Microsoft.VC142.CRT\concrt140.dll" "$INSTDIR\concrt140.dll"
|
||||
!insertmacro Install3264DLL "C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\VC\Redist\MSVC\14.29.30133\x64\Microsoft.VC142.CRT\vccorlib140.dll" "$INSTDIR\vccorlib140.dll"
|
||||
!insertmacro Install3264DLL "C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\VC\Redist\MSVC\14.29.30133\x64\Microsoft.VC142.OpenMP\vcomp140.dll" "$INSTDIR\vcomp140.dll"
|
||||
!insertmacro Install3264DLL "C:\Program Files (x86)\Windows Kits\10\Redist\${WINKITVER}\ucrt\DLLs\x64\ucrtbase.dll" "$INSTDIR\ucrtbase.dll"
|
||||
!insertmacro Install3264DLL "C:\Program Files (x86)\Windows Kits\10\Redist\${WINKITVER}\ucrt\DLLs\x64\api-ms-win-crt-utility-l1-1-0.dll" "$INSTDIR\api-ms-win-crt-utility-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "C:\Program Files (x86)\Windows Kits\10\Redist\${WINKITVER}\ucrt\DLLs\x64\api-ms-win-crt-time-l1-1-0.dll" "$INSTDIR\api-ms-win-crt-time-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "C:\Program Files (x86)\Windows Kits\10\Redist\${WINKITVER}\ucrt\DLLs\x64\api-ms-win-crt-string-l1-1-0.dll" "$INSTDIR\api-ms-win-crt-string-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "C:\Program Files (x86)\Windows Kits\10\Redist\${WINKITVER}\ucrt\DLLs\x64\api-ms-win-crt-stdio-l1-1-0.dll" "$INSTDIR\api-ms-win-crt-stdio-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "C:\Program Files (x86)\Windows Kits\10\Redist\${WINKITVER}\ucrt\DLLs\x64\api-ms-win-crt-runtime-l1-1-0.dll" "$INSTDIR\api-ms-win-crt-runtime-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "C:\Program Files (x86)\Windows Kits\10\Redist\${WINKITVER}\ucrt\DLLs\x64\api-ms-win-crt-process-l1-1-0.dll" "$INSTDIR\api-ms-win-crt-process-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "C:\Program Files (x86)\Windows Kits\10\Redist\${WINKITVER}\ucrt\DLLs\x64\api-ms-win-crt-private-l1-1-0.dll" "$INSTDIR\api-ms-win-crt-private-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "C:\Program Files (x86)\Windows Kits\10\Redist\${WINKITVER}\ucrt\DLLs\x64\api-ms-win-crt-multibyte-l1-1-0.dll" "$INSTDIR\api-ms-win-crt-multibyte-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "C:\Program Files (x86)\Windows Kits\10\Redist\${WINKITVER}\ucrt\DLLs\x64\api-ms-win-crt-math-l1-1-0.dll" "$INSTDIR\api-ms-win-crt-math-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "C:\Program Files (x86)\Windows Kits\10\Redist\${WINKITVER}\ucrt\DLLs\x64\api-ms-win-crt-locale-l1-1-0.dll" "$INSTDIR\api-ms-win-crt-locale-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "C:\Program Files (x86)\Windows Kits\10\Redist\${WINKITVER}\ucrt\DLLs\x64\api-ms-win-crt-heap-l1-1-0.dll" "$INSTDIR\api-ms-win-crt-heap-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "C:\Program Files (x86)\Windows Kits\10\Redist\${WINKITVER}\ucrt\DLLs\x64\api-ms-win-crt-filesystem-l1-1-0.dll" "$INSTDIR\api-ms-win-crt-filesystem-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "C:\Program Files (x86)\Windows Kits\10\Redist\${WINKITVER}\ucrt\DLLs\x64\api-ms-win-crt-environment-l1-1-0.dll" "$INSTDIR\api-ms-win-crt-environment-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "C:\Program Files (x86)\Windows Kits\10\Redist\${WINKITVER}\ucrt\DLLs\x64\api-ms-win-crt-convert-l1-1-0.dll" "$INSTDIR\api-ms-win-crt-convert-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "C:\Program Files (x86)\Windows Kits\10\Redist\${WINKITVER}\ucrt\DLLs\x64\api-ms-win-crt-conio-l1-1-0.dll" "$INSTDIR\api-ms-win-crt-conio-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "C:\Program Files (x86)\Windows Kits\10\Redist\${WINKITVER}\ucrt\DLLs\x64\api-ms-win-core-util-l1-1-0.dll" "$INSTDIR\api-ms-win-core-util-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "C:\Program Files (x86)\Windows Kits\10\Redist\${WINKITVER}\ucrt\DLLs\x64\api-ms-win-core-timezone-l1-1-0.dll" "$INSTDIR\api-ms-win-core-timezone-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "C:\Program Files (x86)\Windows Kits\10\Redist\${WINKITVER}\ucrt\DLLs\x64\api-ms-win-core-sysinfo-l1-1-0.dll" "$INSTDIR\api-ms-win-core-sysinfo-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "C:\Program Files (x86)\Windows Kits\10\Redist\${WINKITVER}\ucrt\DLLs\x64\api-ms-win-core-synch-l1-2-0.dll" "$INSTDIR\api-ms-win-core-synch-l1-2-0.dll"
|
||||
!insertmacro Install3264DLL "C:\Program Files (x86)\Windows Kits\10\Redist\${WINKITVER}\ucrt\DLLs\x64\api-ms-win-core-synch-l1-1-0.dll" "$INSTDIR\api-ms-win-core-synch-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "C:\Program Files (x86)\Windows Kits\10\Redist\${WINKITVER}\ucrt\DLLs\x64\api-ms-win-core-string-l1-1-0.dll" "$INSTDIR\api-ms-win-core-string-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "C:\Program Files (x86)\Windows Kits\10\Redist\${WINKITVER}\ucrt\DLLs\x64\api-ms-win-core-rtlsupport-l1-1-0.dll" "$INSTDIR\api-ms-win-core-rtlsupport-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "C:\Program Files (x86)\Windows Kits\10\Redist\${WINKITVER}\ucrt\DLLs\x64\api-ms-win-core-profile-l1-1-0.dll" "$INSTDIR\api-ms-win-core-profile-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "C:\Program Files (x86)\Windows Kits\10\Redist\${WINKITVER}\ucrt\DLLs\x64\api-ms-win-core-processthreads-l1-1-1.dll" "$INSTDIR\api-ms-win-core-processthreads-l1-1-1.dll"
|
||||
!insertmacro Install3264DLL "C:\Program Files (x86)\Windows Kits\10\Redist\${WINKITVER}\ucrt\DLLs\x64\api-ms-win-core-processthreads-l1-1-0.dll" "$INSTDIR\api-ms-win-core-processthreads-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "C:\Program Files (x86)\Windows Kits\10\Redist\${WINKITVER}\ucrt\DLLs\x64\api-ms-win-core-processenvironment-l1-1-0.dll" "$INSTDIR\api-ms-win-core-processenvironment-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "C:\Program Files (x86)\Windows Kits\10\Redist\${WINKITVER}\ucrt\DLLs\x64\api-ms-win-core-namedpipe-l1-1-0.dll" "$INSTDIR\api-ms-win-core-namedpipe-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "C:\Program Files (x86)\Windows Kits\10\Redist\${WINKITVER}\ucrt\DLLs\x64\api-ms-win-core-memory-l1-1-0.dll" "$INSTDIR\api-ms-win-core-memory-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "C:\Program Files (x86)\Windows Kits\10\Redist\${WINKITVER}\ucrt\DLLs\x64\api-ms-win-core-localization-l1-2-0.dll" "$INSTDIR\api-ms-win-core-localization-l1-2-0.dll"
|
||||
!insertmacro Install3264DLL "C:\Program Files (x86)\Windows Kits\10\Redist\${WINKITVER}\ucrt\DLLs\x64\api-ms-win-core-libraryloader-l1-1-0.dll" "$INSTDIR\api-ms-win-core-libraryloader-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "C:\Program Files (x86)\Windows Kits\10\Redist\${WINKITVER}\ucrt\DLLs\x64\api-ms-win-core-interlocked-l1-1-0.dll" "$INSTDIR\api-ms-win-core-interlocked-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "C:\Program Files (x86)\Windows Kits\10\Redist\${WINKITVER}\ucrt\DLLs\x64\api-ms-win-core-heap-l1-1-0.dll" "$INSTDIR\api-ms-win-core-heap-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "C:\Program Files (x86)\Windows Kits\10\Redist\${WINKITVER}\ucrt\DLLs\x64\api-ms-win-core-handle-l1-1-0.dll" "$INSTDIR\api-ms-win-core-handle-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "C:\Program Files (x86)\Windows Kits\10\Redist\${WINKITVER}\ucrt\DLLs\x64\api-ms-win-core-file-l2-1-0.dll" "$INSTDIR\api-ms-win-core-file-l2-1-0.dll"
|
||||
!insertmacro Install3264DLL "C:\Program Files (x86)\Windows Kits\10\Redist\${WINKITVER}\ucrt\DLLs\x64\api-ms-win-core-file-l1-2-0.dll" "$INSTDIR\api-ms-win-core-file-l1-2-0.dll"
|
||||
!insertmacro Install3264DLL "C:\Program Files (x86)\Windows Kits\10\Redist\${WINKITVER}\ucrt\DLLs\x64\api-ms-win-core-file-l1-1-0.dll" "$INSTDIR\api-ms-win-core-file-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "C:\Program Files (x86)\Windows Kits\10\Redist\${WINKITVER}\ucrt\DLLs\x64\api-ms-win-core-errorhandling-l1-1-0.dll" "$INSTDIR\api-ms-win-core-errorhandling-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "C:\Program Files (x86)\Windows Kits\10\Redist\${WINKITVER}\ucrt\DLLs\x64\api-ms-win-core-debug-l1-1-0.dll" "$INSTDIR\api-ms-win-core-debug-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "C:\Program Files (x86)\Windows Kits\10\Redist\${WINKITVER}\ucrt\DLLs\x64\api-ms-win-core-datetime-l1-1-0.dll" "$INSTDIR\api-ms-win-core-datetime-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "C:\Program Files (x86)\Windows Kits\10\Redist\${WINKITVER}\ucrt\DLLs\x64\api-ms-win-core-console-l1-1-0.dll" "$INSTDIR\api-ms-win-core-console-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "${VcRedist64Path}\vcruntime140.dll" "$INSTDIR\vcruntime140.dll"
|
||||
!insertmacro Install3264DLL "${VcRedist64Path}\vcruntime140_1.dll" "$INSTDIR\vcruntime140_1.dll"
|
||||
!insertmacro Install3264DLL "${VcRedist64Path}\msvcp140.dll" "$INSTDIR\msvcp140.dll"
|
||||
!insertmacro Install3264DLL "${VcRedist64Path}\msvcp140_1.dll" "$INSTDIR\msvcp140_1.dll"
|
||||
!insertmacro Install3264DLL "${VcRedist64Path}\msvcp140_2.dll" "$INSTDIR\msvcp140_2.dll"
|
||||
!insertmacro Install3264DLL "${VcRedist64Path}\msvcp140_atomic_wait.dll" "$INSTDIR\msvcp140_atomic_wait.dll"
|
||||
!insertmacro Install3264DLL "${VcRedist64Path}\msvcp140_codecvt_ids.dll" "$INSTDIR\msvcp140_codecvt_ids.dll"
|
||||
!insertmacro Install3264DLL "${VcRedist64Path}\concrt140.dll" "$INSTDIR\concrt140.dll"
|
||||
!insertmacro Install3264DLL "${VcRedist64Path}\vccorlib140.dll" "$INSTDIR\vccorlib140.dll"
|
||||
!insertmacro Install3264DLL "${VcRedist64BasePath}\Microsoft.VC143.OpenMP\vcomp140.dll" "$INSTDIR\vcomp140.dll"
|
||||
!insertmacro Install3264DLL "${WinRedist64BasePath}\ucrtbase.dll" "$INSTDIR\ucrtbase.dll"
|
||||
!insertmacro Install3264DLL "${WinRedist64BasePath}\api-ms-win-crt-utility-l1-1-0.dll" "$INSTDIR\api-ms-win-crt-utility-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "${WinRedist64BasePath}\api-ms-win-crt-time-l1-1-0.dll" "$INSTDIR\api-ms-win-crt-time-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "${WinRedist64BasePath}\api-ms-win-crt-string-l1-1-0.dll" "$INSTDIR\api-ms-win-crt-string-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "${WinRedist64BasePath}\api-ms-win-crt-stdio-l1-1-0.dll" "$INSTDIR\api-ms-win-crt-stdio-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "${WinRedist64BasePath}\api-ms-win-crt-runtime-l1-1-0.dll" "$INSTDIR\api-ms-win-crt-runtime-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "${WinRedist64BasePath}\api-ms-win-crt-process-l1-1-0.dll" "$INSTDIR\api-ms-win-crt-process-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "${WinRedist64BasePath}\api-ms-win-crt-private-l1-1-0.dll" "$INSTDIR\api-ms-win-crt-private-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "${WinRedist64BasePath}\api-ms-win-crt-multibyte-l1-1-0.dll" "$INSTDIR\api-ms-win-crt-multibyte-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "${WinRedist64BasePath}\api-ms-win-crt-math-l1-1-0.dll" "$INSTDIR\api-ms-win-crt-math-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "${WinRedist64BasePath}\api-ms-win-crt-locale-l1-1-0.dll" "$INSTDIR\api-ms-win-crt-locale-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "${WinRedist64BasePath}\api-ms-win-crt-heap-l1-1-0.dll" "$INSTDIR\api-ms-win-crt-heap-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "${WinRedist64BasePath}\api-ms-win-crt-filesystem-l1-1-0.dll" "$INSTDIR\api-ms-win-crt-filesystem-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "${WinRedist64BasePath}\api-ms-win-crt-environment-l1-1-0.dll" "$INSTDIR\api-ms-win-crt-environment-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "${WinRedist64BasePath}\api-ms-win-crt-convert-l1-1-0.dll" "$INSTDIR\api-ms-win-crt-convert-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "${WinRedist64BasePath}\api-ms-win-crt-conio-l1-1-0.dll" "$INSTDIR\api-ms-win-crt-conio-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "${WinRedist64BasePath}\api-ms-win-core-util-l1-1-0.dll" "$INSTDIR\api-ms-win-core-util-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "${WinRedist64BasePath}\api-ms-win-core-timezone-l1-1-0.dll" "$INSTDIR\api-ms-win-core-timezone-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "${WinRedist64BasePath}\api-ms-win-core-sysinfo-l1-1-0.dll" "$INSTDIR\api-ms-win-core-sysinfo-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "${WinRedist64BasePath}\api-ms-win-core-synch-l1-2-0.dll" "$INSTDIR\api-ms-win-core-synch-l1-2-0.dll"
|
||||
!insertmacro Install3264DLL "${WinRedist64BasePath}\api-ms-win-core-synch-l1-1-0.dll" "$INSTDIR\api-ms-win-core-synch-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "${WinRedist64BasePath}\api-ms-win-core-string-l1-1-0.dll" "$INSTDIR\api-ms-win-core-string-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "${WinRedist64BasePath}\api-ms-win-core-rtlsupport-l1-1-0.dll" "$INSTDIR\api-ms-win-core-rtlsupport-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "${WinRedist64BasePath}\api-ms-win-core-profile-l1-1-0.dll" "$INSTDIR\api-ms-win-core-profile-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "${WinRedist64BasePath}\api-ms-win-core-processthreads-l1-1-1.dll" "$INSTDIR\api-ms-win-core-processthreads-l1-1-1.dll"
|
||||
!insertmacro Install3264DLL "${WinRedist64BasePath}\api-ms-win-core-processthreads-l1-1-0.dll" "$INSTDIR\api-ms-win-core-processthreads-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "${WinRedist64BasePath}\api-ms-win-core-processenvironment-l1-1-0.dll" "$INSTDIR\api-ms-win-core-processenvironment-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "${WinRedist64BasePath}\api-ms-win-core-namedpipe-l1-1-0.dll" "$INSTDIR\api-ms-win-core-namedpipe-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "${WinRedist64BasePath}\api-ms-win-core-memory-l1-1-0.dll" "$INSTDIR\api-ms-win-core-memory-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "${WinRedist64BasePath}\api-ms-win-core-localization-l1-2-0.dll" "$INSTDIR\api-ms-win-core-localization-l1-2-0.dll"
|
||||
!insertmacro Install3264DLL "${WinRedist64BasePath}\api-ms-win-core-libraryloader-l1-1-0.dll" "$INSTDIR\api-ms-win-core-libraryloader-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "${WinRedist64BasePath}\api-ms-win-core-interlocked-l1-1-0.dll" "$INSTDIR\api-ms-win-core-interlocked-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "${WinRedist64BasePath}\api-ms-win-core-heap-l1-1-0.dll" "$INSTDIR\api-ms-win-core-heap-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "${WinRedist64BasePath}\api-ms-win-core-handle-l1-1-0.dll" "$INSTDIR\api-ms-win-core-handle-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "${WinRedist64BasePath}\api-ms-win-core-file-l2-1-0.dll" "$INSTDIR\api-ms-win-core-file-l2-1-0.dll"
|
||||
!insertmacro Install3264DLL "${WinRedist64BasePath}\api-ms-win-core-file-l1-2-0.dll" "$INSTDIR\api-ms-win-core-file-l1-2-0.dll"
|
||||
!insertmacro Install3264DLL "${WinRedist64BasePath}\api-ms-win-core-file-l1-1-0.dll" "$INSTDIR\api-ms-win-core-file-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "${WinRedist64BasePath}\api-ms-win-core-errorhandling-l1-1-0.dll" "$INSTDIR\api-ms-win-core-errorhandling-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "${WinRedist64BasePath}\api-ms-win-core-debug-l1-1-0.dll" "$INSTDIR\api-ms-win-core-debug-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "${WinRedist64BasePath}\api-ms-win-core-datetime-l1-1-0.dll" "$INSTDIR\api-ms-win-core-datetime-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "${WinRedist64BasePath}\api-ms-win-core-console-l1-1-0.dll" "$INSTDIR\api-ms-win-core-console-l1-1-0.dll"
|
||||
!else
|
||||
!insertmacro Install3264DLL "C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\VC\Redist\MSVC\14.29.30133\x86\Microsoft.VC142.CRT\vcruntime140.dll" "$INSTDIR\vcruntime140.dll"
|
||||
!insertmacro Install3264DLL "C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\VC\Redist\MSVC\14.29.30133\x86\Microsoft.VC142.CRT\msvcp140.dll" "$INSTDIR\msvcp140.dll"
|
||||
!insertmacro Install3264DLL "C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\VC\Redist\MSVC\14.29.30133\x86\Microsoft.VC142.CRT\msvcp140_1.dll" "$INSTDIR\msvcp140_1.dll"
|
||||
!insertmacro Install3264DLL "C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\VC\Redist\MSVC\14.29.30133\x86\Microsoft.VC142.CRT\msvcp140_2.dll" "$INSTDIR\msvcp140_2.dll"
|
||||
!insertmacro Install3264DLL "C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\VC\Redist\MSVC\14.29.30133\x86\Microsoft.VC142.CRT\msvcp140_atomic_wait.dll" "$INSTDIR\msvcp140_atomic_wait.dll"
|
||||
!insertmacro Install3264DLL "C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\VC\Redist\MSVC\14.29.30133\x86\Microsoft.VC142.CRT\msvcp140_codecvt_ids.dll" "$INSTDIR\msvcp140_codecvt_ids.dll"
|
||||
!insertmacro Install3264DLL "C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\VC\Redist\MSVC\14.29.30133\x86\Microsoft.VC142.CRT\concrt140.dll" "$INSTDIR\concrt140.dll"
|
||||
!insertmacro Install3264DLL "C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\VC\Redist\MSVC\14.29.30133\x86\Microsoft.VC142.CRT\vccorlib140.dll" "$INSTDIR\vccorlib140.dll"
|
||||
!insertmacro Install3264DLL "C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\VC\Redist\MSVC\14.29.30133\x86\Microsoft.VC142.OpenMP\vcomp140.dll" "$INSTDIR\vcomp140.dll"
|
||||
!insertmacro Install3264DLL "C:\Program Files (x86)\Windows Kits\10\Redist\${WINKITVER}\ucrt\DLLs\x86\ucrtbase.dll" "$INSTDIR\ucrtbase.dll"
|
||||
!insertmacro Install3264DLL "C:\Program Files (x86)\Windows Kits\10\Redist\${WINKITVER}\ucrt\DLLs\x86\api-ms-win-crt-utility-l1-1-0.dll" "$INSTDIR\api-ms-win-crt-utility-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "C:\Program Files (x86)\Windows Kits\10\Redist\${WINKITVER}\ucrt\DLLs\x86\api-ms-win-crt-time-l1-1-0.dll" "$INSTDIR\api-ms-win-crt-time-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "C:\Program Files (x86)\Windows Kits\10\Redist\${WINKITVER}\ucrt\DLLs\x86\api-ms-win-crt-string-l1-1-0.dll" "$INSTDIR\api-ms-win-crt-string-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "C:\Program Files (x86)\Windows Kits\10\Redist\${WINKITVER}\ucrt\DLLs\x86\api-ms-win-crt-stdio-l1-1-0.dll" "$INSTDIR\api-ms-win-crt-stdio-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "C:\Program Files (x86)\Windows Kits\10\Redist\${WINKITVER}\ucrt\DLLs\x86\api-ms-win-crt-runtime-l1-1-0.dll" "$INSTDIR\api-ms-win-crt-runtime-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "C:\Program Files (x86)\Windows Kits\10\Redist\${WINKITVER}\ucrt\DLLs\x86\api-ms-win-crt-process-l1-1-0.dll" "$INSTDIR\api-ms-win-crt-process-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "C:\Program Files (x86)\Windows Kits\10\Redist\${WINKITVER}\ucrt\DLLs\x86\api-ms-win-crt-private-l1-1-0.dll" "$INSTDIR\api-ms-win-crt-private-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "C:\Program Files (x86)\Windows Kits\10\Redist\${WINKITVER}\ucrt\DLLs\x86\api-ms-win-crt-multibyte-l1-1-0.dll" "$INSTDIR\api-ms-win-crt-multibyte-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "C:\Program Files (x86)\Windows Kits\10\Redist\${WINKITVER}\ucrt\DLLs\x86\api-ms-win-crt-math-l1-1-0.dll" "$INSTDIR\api-ms-win-crt-math-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "C:\Program Files (x86)\Windows Kits\10\Redist\${WINKITVER}\ucrt\DLLs\x86\api-ms-win-crt-locale-l1-1-0.dll" "$INSTDIR\api-ms-win-crt-locale-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "C:\Program Files (x86)\Windows Kits\10\Redist\${WINKITVER}\ucrt\DLLs\x86\api-ms-win-crt-heap-l1-1-0.dll" "$INSTDIR\api-ms-win-crt-heap-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "C:\Program Files (x86)\Windows Kits\10\Redist\${WINKITVER}\ucrt\DLLs\x86\api-ms-win-crt-filesystem-l1-1-0.dll" "$INSTDIR\api-ms-win-crt-filesystem-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "C:\Program Files (x86)\Windows Kits\10\Redist\${WINKITVER}\ucrt\DLLs\x86\api-ms-win-crt-environment-l1-1-0.dll" "$INSTDIR\api-ms-win-crt-environment-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "C:\Program Files (x86)\Windows Kits\10\Redist\${WINKITVER}\ucrt\DLLs\x86\api-ms-win-crt-convert-l1-1-0.dll" "$INSTDIR\api-ms-win-crt-convert-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "C:\Program Files (x86)\Windows Kits\10\Redist\${WINKITVER}\ucrt\DLLs\x86\api-ms-win-crt-conio-l1-1-0.dll" "$INSTDIR\api-ms-win-crt-conio-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "C:\Program Files (x86)\Windows Kits\10\Redist\${WINKITVER}\ucrt\DLLs\x86\api-ms-win-core-util-l1-1-0.dll" "$INSTDIR\api-ms-win-core-util-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "C:\Program Files (x86)\Windows Kits\10\Redist\${WINKITVER}\ucrt\DLLs\x86\api-ms-win-core-timezone-l1-1-0.dll" "$INSTDIR\api-ms-win-core-timezone-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "C:\Program Files (x86)\Windows Kits\10\Redist\${WINKITVER}\ucrt\DLLs\x86\api-ms-win-core-sysinfo-l1-1-0.dll" "$INSTDIR\api-ms-win-core-sysinfo-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "C:\Program Files (x86)\Windows Kits\10\Redist\${WINKITVER}\ucrt\DLLs\x86\api-ms-win-core-synch-l1-2-0.dll" "$INSTDIR\api-ms-win-core-synch-l1-2-0.dll"
|
||||
!insertmacro Install3264DLL "C:\Program Files (x86)\Windows Kits\10\Redist\${WINKITVER}\ucrt\DLLs\x86\api-ms-win-core-synch-l1-1-0.dll" "$INSTDIR\api-ms-win-core-synch-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "C:\Program Files (x86)\Windows Kits\10\Redist\${WINKITVER}\ucrt\DLLs\x86\api-ms-win-core-string-l1-1-0.dll" "$INSTDIR\api-ms-win-core-string-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "C:\Program Files (x86)\Windows Kits\10\Redist\${WINKITVER}\ucrt\DLLs\x86\api-ms-win-core-rtlsupport-l1-1-0.dll" "$INSTDIR\api-ms-win-core-rtlsupport-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "C:\Program Files (x86)\Windows Kits\10\Redist\${WINKITVER}\ucrt\DLLs\x86\api-ms-win-core-profile-l1-1-0.dll" "$INSTDIR\api-ms-win-core-profile-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "C:\Program Files (x86)\Windows Kits\10\Redist\${WINKITVER}\ucrt\DLLs\x86\api-ms-win-core-processthreads-l1-1-1.dll" "$INSTDIR\api-ms-win-core-processthreads-l1-1-1.dll"
|
||||
!insertmacro Install3264DLL "C:\Program Files (x86)\Windows Kits\10\Redist\${WINKITVER}\ucrt\DLLs\x86\api-ms-win-core-processthreads-l1-1-0.dll" "$INSTDIR\api-ms-win-core-processthreads-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "C:\Program Files (x86)\Windows Kits\10\Redist\${WINKITVER}\ucrt\DLLs\x86\api-ms-win-core-processenvironment-l1-1-0.dll" "$INSTDIR\api-ms-win-core-processenvironment-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "C:\Program Files (x86)\Windows Kits\10\Redist\${WINKITVER}\ucrt\DLLs\x86\api-ms-win-core-namedpipe-l1-1-0.dll" "$INSTDIR\api-ms-win-core-namedpipe-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "C:\Program Files (x86)\Windows Kits\10\Redist\${WINKITVER}\ucrt\DLLs\x86\api-ms-win-core-memory-l1-1-0.dll" "$INSTDIR\api-ms-win-core-memory-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "C:\Program Files (x86)\Windows Kits\10\Redist\${WINKITVER}\ucrt\DLLs\x86\api-ms-win-core-localization-l1-2-0.dll" "$INSTDIR\api-ms-win-core-localization-l1-2-0.dll"
|
||||
!insertmacro Install3264DLL "C:\Program Files (x86)\Windows Kits\10\Redist\${WINKITVER}\ucrt\DLLs\x86\api-ms-win-core-libraryloader-l1-1-0.dll" "$INSTDIR\api-ms-win-core-libraryloader-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "C:\Program Files (x86)\Windows Kits\10\Redist\${WINKITVER}\ucrt\DLLs\x86\api-ms-win-core-interlocked-l1-1-0.dll" "$INSTDIR\api-ms-win-core-interlocked-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "C:\Program Files (x86)\Windows Kits\10\Redist\${WINKITVER}\ucrt\DLLs\x86\api-ms-win-core-heap-l1-1-0.dll" "$INSTDIR\api-ms-win-core-heap-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "C:\Program Files (x86)\Windows Kits\10\Redist\${WINKITVER}\ucrt\DLLs\x86\api-ms-win-core-handle-l1-1-0.dll" "$INSTDIR\api-ms-win-core-handle-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "C:\Program Files (x86)\Windows Kits\10\Redist\${WINKITVER}\ucrt\DLLs\x86\api-ms-win-core-file-l2-1-0.dll" "$INSTDIR\api-ms-win-core-file-l2-1-0.dll"
|
||||
!insertmacro Install3264DLL "C:\Program Files (x86)\Windows Kits\10\Redist\${WINKITVER}\ucrt\DLLs\x86\api-ms-win-core-file-l1-2-0.dll" "$INSTDIR\api-ms-win-core-file-l1-2-0.dll"
|
||||
!insertmacro Install3264DLL "C:\Program Files (x86)\Windows Kits\10\Redist\${WINKITVER}\ucrt\DLLs\x86\api-ms-win-core-file-l1-1-0.dll" "$INSTDIR\api-ms-win-core-file-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "C:\Program Files (x86)\Windows Kits\10\Redist\${WINKITVER}\ucrt\DLLs\x86\api-ms-win-core-errorhandling-l1-1-0.dll" "$INSTDIR\api-ms-win-core-errorhandling-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "C:\Program Files (x86)\Windows Kits\10\Redist\${WINKITVER}\ucrt\DLLs\x86\api-ms-win-core-debug-l1-1-0.dll" "$INSTDIR\api-ms-win-core-debug-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "C:\Program Files (x86)\Windows Kits\10\Redist\${WINKITVER}\ucrt\DLLs\x86\api-ms-win-core-datetime-l1-1-0.dll" "$INSTDIR\api-ms-win-core-datetime-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "C:\Program Files (x86)\Windows Kits\10\Redist\${WINKITVER}\ucrt\DLLs\x86\api-ms-win-core-console-l1-1-0.dll" "$INSTDIR\api-ms-win-core-console-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "${VcRedist32Path}\vcruntime140.dll" "$INSTDIR\vcruntime140.dll"
|
||||
!insertmacro Install3264DLL "${VcRedist32Path}\msvcp140.dll" "$INSTDIR\msvcp140.dll"
|
||||
!insertmacro Install3264DLL "${VcRedist32Path}\msvcp140_1.dll" "$INSTDIR\msvcp140_1.dll"
|
||||
!insertmacro Install3264DLL "${VcRedist32Path}\msvcp140_2.dll" "$INSTDIR\msvcp140_2.dll"
|
||||
!insertmacro Install3264DLL "${VcRedist32Path}\msvcp140_atomic_wait.dll" "$INSTDIR\msvcp140_atomic_wait.dll"
|
||||
!insertmacro Install3264DLL "${VcRedist32Path}\msvcp140_codecvt_ids.dll" "$INSTDIR\msvcp140_codecvt_ids.dll"
|
||||
!insertmacro Install3264DLL "${VcRedist32Path}\concrt140.dll" "$INSTDIR\concrt140.dll"
|
||||
!insertmacro Install3264DLL "${VcRedist32Path}\vccorlib140.dll" "$INSTDIR\vccorlib140.dll"
|
||||
!insertmacro Install3264DLL "${VcRedist32BasePath}\Microsoft.VC143.OpenMP\vcomp140.dll" "$INSTDIR\vcomp140.dll"
|
||||
!insertmacro Install3264DLL "${WinRedist32BasePath}\ucrtbase.dll" "$INSTDIR\ucrtbase.dll"
|
||||
!insertmacro Install3264DLL "${WinRedist32BasePath}\api-ms-win-crt-utility-l1-1-0.dll" "$INSTDIR\api-ms-win-crt-utility-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "${WinRedist32BasePath}\api-ms-win-crt-time-l1-1-0.dll" "$INSTDIR\api-ms-win-crt-time-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "${WinRedist32BasePath}\api-ms-win-crt-string-l1-1-0.dll" "$INSTDIR\api-ms-win-crt-string-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "${WinRedist32BasePath}\api-ms-win-crt-stdio-l1-1-0.dll" "$INSTDIR\api-ms-win-crt-stdio-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "${WinRedist32BasePath}\api-ms-win-crt-runtime-l1-1-0.dll" "$INSTDIR\api-ms-win-crt-runtime-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "${WinRedist32BasePath}\api-ms-win-crt-process-l1-1-0.dll" "$INSTDIR\api-ms-win-crt-process-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "${WinRedist32BasePath}\api-ms-win-crt-private-l1-1-0.dll" "$INSTDIR\api-ms-win-crt-private-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "${WinRedist32BasePath}\api-ms-win-crt-multibyte-l1-1-0.dll" "$INSTDIR\api-ms-win-crt-multibyte-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "${WinRedist32BasePath}\api-ms-win-crt-math-l1-1-0.dll" "$INSTDIR\api-ms-win-crt-math-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "${WinRedist32BasePath}\api-ms-win-crt-locale-l1-1-0.dll" "$INSTDIR\api-ms-win-crt-locale-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "${WinRedist32BasePath}\api-ms-win-crt-heap-l1-1-0.dll" "$INSTDIR\api-ms-win-crt-heap-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "${WinRedist32BasePath}\api-ms-win-crt-filesystem-l1-1-0.dll" "$INSTDIR\api-ms-win-crt-filesystem-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "${WinRedist32BasePath}\api-ms-win-crt-environment-l1-1-0.dll" "$INSTDIR\api-ms-win-crt-environment-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "${WinRedist32BasePath}\api-ms-win-crt-convert-l1-1-0.dll" "$INSTDIR\api-ms-win-crt-convert-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "${WinRedist32BasePath}\api-ms-win-crt-conio-l1-1-0.dll" "$INSTDIR\api-ms-win-crt-conio-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "${WinRedist32BasePath}\api-ms-win-core-util-l1-1-0.dll" "$INSTDIR\api-ms-win-core-util-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "${WinRedist32BasePath}\api-ms-win-core-timezone-l1-1-0.dll" "$INSTDIR\api-ms-win-core-timezone-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "${WinRedist32BasePath}\api-ms-win-core-sysinfo-l1-1-0.dll" "$INSTDIR\api-ms-win-core-sysinfo-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "${WinRedist32BasePath}\api-ms-win-core-synch-l1-2-0.dll" "$INSTDIR\api-ms-win-core-synch-l1-2-0.dll"
|
||||
!insertmacro Install3264DLL "${WinRedist32BasePath}\api-ms-win-core-synch-l1-1-0.dll" "$INSTDIR\api-ms-win-core-synch-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "${WinRedist32BasePath}\api-ms-win-core-string-l1-1-0.dll" "$INSTDIR\api-ms-win-core-string-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "${WinRedist32BasePath}\api-ms-win-core-rtlsupport-l1-1-0.dll" "$INSTDIR\api-ms-win-core-rtlsupport-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "${WinRedist32BasePath}\api-ms-win-core-profile-l1-1-0.dll" "$INSTDIR\api-ms-win-core-profile-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "${WinRedist32BasePath}\api-ms-win-core-processthreads-l1-1-1.dll" "$INSTDIR\api-ms-win-core-processthreads-l1-1-1.dll"
|
||||
!insertmacro Install3264DLL "${WinRedist32BasePath}\api-ms-win-core-processthreads-l1-1-0.dll" "$INSTDIR\api-ms-win-core-processthreads-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "${WinRedist32BasePath}\api-ms-win-core-processenvironment-l1-1-0.dll" "$INSTDIR\api-ms-win-core-processenvironment-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "${WinRedist32BasePath}\api-ms-win-core-namedpipe-l1-1-0.dll" "$INSTDIR\api-ms-win-core-namedpipe-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "${WinRedist32BasePath}\api-ms-win-core-memory-l1-1-0.dll" "$INSTDIR\api-ms-win-core-memory-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "${WinRedist32BasePath}\api-ms-win-core-localization-l1-2-0.dll" "$INSTDIR\api-ms-win-core-localization-l1-2-0.dll"
|
||||
!insertmacro Install3264DLL "${WinRedist32BasePath}\api-ms-win-core-libraryloader-l1-1-0.dll" "$INSTDIR\api-ms-win-core-libraryloader-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "${WinRedist32BasePath}\api-ms-win-core-interlocked-l1-1-0.dll" "$INSTDIR\api-ms-win-core-interlocked-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "${WinRedist32BasePath}\api-ms-win-core-heap-l1-1-0.dll" "$INSTDIR\api-ms-win-core-heap-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "${WinRedist32BasePath}\api-ms-win-core-handle-l1-1-0.dll" "$INSTDIR\api-ms-win-core-handle-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "${WinRedist32BasePath}\api-ms-win-core-file-l2-1-0.dll" "$INSTDIR\api-ms-win-core-file-l2-1-0.dll"
|
||||
!insertmacro Install3264DLL "${WinRedist32BasePath}\api-ms-win-core-file-l1-2-0.dll" "$INSTDIR\api-ms-win-core-file-l1-2-0.dll"
|
||||
!insertmacro Install3264DLL "${WinRedist32BasePath}\api-ms-win-core-file-l1-1-0.dll" "$INSTDIR\api-ms-win-core-file-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "${WinRedist32BasePath}\api-ms-win-core-errorhandling-l1-1-0.dll" "$INSTDIR\api-ms-win-core-errorhandling-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "${WinRedist32BasePath}\api-ms-win-core-debug-l1-1-0.dll" "$INSTDIR\api-ms-win-core-debug-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "${WinRedist32BasePath}\api-ms-win-core-datetime-l1-1-0.dll" "$INSTDIR\api-ms-win-core-datetime-l1-1-0.dll"
|
||||
!insertmacro Install3264DLL "${WinRedist32BasePath}\api-ms-win-core-console-l1-1-0.dll" "$INSTDIR\api-ms-win-core-console-l1-1-0.dll"
|
||||
!endif
|
||||
|
||||
!ifndef BUILD_UNINSTALLER ; if building uninstaller, skip files below
|
||||
|
@ -1,3 +1,14 @@
|
||||
megacmd (2.0.0) stable; urgency=low
|
||||
|
||||
* New Sync Engine: See sync-issues and sync-ignore commands
|
||||
* Rotating Logger: Introduced a robust rotating logging system across all platforms for better performance and debugging
|
||||
* Platform-specific enhancements: Addressed various file descriptor issues on Linux and macOS, and improved non-ascii support on Windows
|
||||
* Improved overall reliability: Fixed memory leaks, resolved potential data races, and eliminated deadlock scenarios
|
||||
* Fixed an issue when handling double-quoted arguments
|
||||
* Various fixes and refinements to enhance usability and performance
|
||||
|
||||
-- MEGA Team <linux@mega.co.nz> Fri, 24 Jan 2025 13:20:06 +0100
|
||||
|
||||
megacmd (1.7.0) stable; urgency=low
|
||||
|
||||
* Improved startup time
|
||||
|
@ -5,6 +5,7 @@ VCPKG_ROOT := $(shell [ -f /opt/vcpkg.tar.gz ] && echo "-DVCPKG_ROOT=vcpkg" || e
|
||||
EXTRADEFINES := $(shell cat /etc/issue | grep "Ubuntu 1[2345789]\|Ubuntu 20.10\|Ubuntu 21\|Ubuntu 22.10\|Ubuntu 23\|Debian.* [789]" >/dev/null && echo "$$CPPFLAGS -DMEGACMD_DEPRECATED_OS" || echo "")
|
||||
DPKGXZ := $(shell cat /etc/issue | grep "Ubuntu 24\|Oracular Oriole\|Noble Numbat\|Ubuntu 23\|Mantic Minotaur\|Lunar Lobster\|Ubuntu 22\|Jammy Jellyfish\|Ubuntu 21.10" >/dev/null && echo "-- -Zxz" || echo "")
|
||||
#LDFLAGS := $(shell dpkg --print-architecture | grep -i "i386\|arm" >/dev/null && echo "" || echo "$$LDFLAGS -Wl,-rpath,/opt/megacmd/lib")
|
||||
EXPORT_VCPKG_FORCE_SYSTEM_BINARIES := $(shell uname -m | grep "armv7l" >/dev/null && echo "VCPKG_FORCE_SYSTEM_BINARIES=1" || echo "")
|
||||
DEB_TESTING := $(shell cat /etc/issue | grep "Debian" > /dev/null && cat /etc/apt/sources.list.d/debian.sources | grep -v "^\#" | grep testing > /dev/null && echo "testing")
|
||||
#TODO: Ensure raspbian builds with that export
|
||||
EXPORTCCMFPU := $(shell cat /etc/issue | grep "Raspbian GNU/Linux 12" >/dev/null && echo "export CC='cc -mfpu=vfp'" || echo ":")
|
||||
@ -34,7 +35,7 @@ build-stamp:
|
||||
fi
|
||||
|
||||
cmake --version
|
||||
cmake $(VCPKG_ROOT) -DCMAKE_VERBOSE_MAKEFILE=ON -DCMAKE_BUILD_TYPE=RelWithDebInfo -S $(CURDIR) -B $(CURDIR)/build_dir
|
||||
$(EXPORT_VCPKG_FORCE_SYSTEM_BINARIES) cmake $(VCPKG_ROOT) -DCMAKE_VERBOSE_MAKEFILE=ON -DCMAKE_BUILD_TYPE=RelWithDebInfo -S $(CURDIR) -B $(CURDIR)/build_dir
|
||||
cmake --build $(CURDIR)/build_dir -j$(NJOBS)
|
||||
cmake --install $(CURDIR)/build_dir --prefix $(CURDIR)/install_dir
|
||||
|
||||
|
@ -1,3 +1,13 @@
|
||||
Fri Jan 24 01:20:16 PM CET 2025 - linux@mega.co.nz
|
||||
- Update to version 2.0.0:
|
||||
* New Sync Engine: See sync-issues and sync-ignore commands
|
||||
* Rotating Logger: Introduced a robust rotating logging system across all platforms for better performance and debugging
|
||||
* Platform-specific enhancements: Addressed various file descriptor issues on Linux and macOS, and improved non-ascii support on Windows
|
||||
* Improved overall reliability: Fixed memory leaks, resolved potential data races, and eliminated deadlock scenarios
|
||||
* Fixed an issue when handling double-quoted arguments
|
||||
* Various fixes and refinements to enhance usability and performance
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Mon May 20 02:06:31 PM CEST 2024 - linux@mega.co.nz
|
||||
- Update to version 1.7.0:
|
||||
* Improved startup time
|
||||
|
@ -13,7 +13,7 @@ IF EXIST build-x64-windows-mega (
|
||||
|
||||
mkdir build-x64-windows-mega
|
||||
cd build-x64-windows-mega
|
||||
cmake -G "Visual Studio 16 2019" -A x64 -DCMAKE_VERBOSE_MAKEFILE="ON" -DCMAKE_CXX_FLAGS_RELWITHDEBINFO="/Zi /O2 /Ob2 /DNDEBUG" %VCPKG_ROOT_ARG% -DCMAKE_C_FLAGS_RELWITHDEBINFO="/Zi /O2 /Ob2 /DNDEBUG" -S "..\.." -B . || exit 1 /b
|
||||
cmake -G "Visual Studio 17 2022" -A x64 -DCMAKE_VERBOSE_MAKEFILE="ON" -DCMAKE_CXX_FLAGS_RELWITHDEBINFO="/Zi /O2 /Ob2 /DNDEBUG" %VCPKG_ROOT_ARG% -DCMAKE_C_FLAGS_RELWITHDEBINFO="/Zi /O2 /Ob2 /DNDEBUG" -S "..\.." -B . || exit 1 /b
|
||||
cmake --build . --config RelWithDebInfo --target mega-exec --target mega-cmd-server --target mega-cmd --target mega-cmd-updater -j%MEGA_CORES% || exit 1 /b
|
||||
cd ..
|
||||
|
||||
@ -28,6 +28,6 @@ IF EXIST build-x86-windows-mega (
|
||||
|
||||
mkdir build-x86-windows-mega
|
||||
cd build-x86-windows-mega
|
||||
cmake -G "Visual Studio 16 2019" -A Win32 -DCMAKE_VERBOSE_MAKEFILE="ON" -DCMAKE_CXX_FLAGS_RELWITHDEBINFO="/Zi /O2 /Ob2 /DNDEBUG" %VCPKG_ROOT_ARG% -DCMAKE_C_FLAGS_RELWITHDEBINFO="/Zi /O2 /Ob2 /DNDEBUG" -S "..\.." -B . || exit 1 /b
|
||||
cmake -G "Visual Studio 17 2022" -A Win32 -DCMAKE_VERBOSE_MAKEFILE="ON" -DCMAKE_CXX_FLAGS_RELWITHDEBINFO="/Zi /O2 /Ob2 /DNDEBUG" %VCPKG_ROOT_ARG% -DCMAKE_C_FLAGS_RELWITHDEBINFO="/Zi /O2 /Ob2 /DNDEBUG" -S "..\.." -B . || exit 1 /b
|
||||
cmake --build . --config RelWithDebInfo --target mega-exec --target mega-cmd-server --target mega-cmd --target mega-cmd-updater -j%MEGA_CORES% || exit 1 /b
|
||||
cd ..
|
||||
|
@ -1 +1 @@
|
||||
1.7.0
|
||||
2.0.0
|
||||
|
@ -1,96 +1,56 @@
|
||||
# Debugging MEGAcmd
|
||||
|
||||
There are two different kinds of logging messages:
|
||||
- MEGAcmd based: those messages reported by MEGAcmd itself.
|
||||
- MEGAcmd: these messages are reported by MEGAcmd itself. These messages will show information regarding the processing of user commands. They will be labeled with `cmd`.
|
||||
|
||||
These messages will show information regarding the processing of user commands.
|
||||
- SDK: these messages are reported by the sdk and its dependent libraries. These messages will show information regarding requests, transfers, network, etc. They will be labeled with `sdk`.
|
||||
|
||||
- SDK based: those messages reported by the sdk and dependent libraries.
|
||||
The MEGAcmd server logs messages depending on the level of log adjusted to those two categories. You can adjust the level of logging for those kinds with `log` command. Log levels range from FATAL (the lowest) to VERBOSE (the highest). The log level of each message is displayed after the cmd/sdk prefix.
|
||||
|
||||
These messages will show information regarding requests, transfers, network, etc.
|
||||
They will be labeled with `SDK:`.
|
||||
Here's an example of some random log messages:
|
||||
```
|
||||
2025-02-07_16-47-56.662269 cmd DBG Registering state listener petition with socket: 85 [comunicationsmanagerfilesockets.cpp:189]
|
||||
2025-02-07_16-47-56.662366 cmd DTL Unregistering no longer listening client. Original petition: registerstatelistener [comunicationsmanagerfilesockets.cpp:346]
|
||||
2025-02-07_16-47-56.662671 sdk INFO Request (RETRY_PENDING_CONNECTIONS) starting [megaapi_impl.cpp:16964]
|
||||
```
|
||||
The source file and line the message was logged from is appended at the end of the log message, to help developers quickly find out where they came from.
|
||||
|
||||
MEGAcmdServer logs messages depending on the level of log adjusted to those
|
||||
two categories. You can adjust the level of logging for those kinds with `log` command.
|
||||
Log levels range from FATAL (the lowest) to VERBOSE (the highest).
|
||||
|
||||
## How to access the logs
|
||||
|
||||
Accessing the logs depends on the platform you are in.
|
||||
Logs coming from MEGAcmd are written to the `megacmdserver.log` file. This file is not removed across restarts, so when it gets too large it is automatically compressed and renamed to include a timestamp (without stopping the logging).
|
||||
|
||||
### MacOS
|
||||
|
||||
By default, whenever MEGAcmdServer is executed, it will log the output to `$HOME/.megaCmd/megacmdserver.log`.
|
||||
|
||||
If you want to launch it manually execute in a terminal:
|
||||
|
||||
```
|
||||
export PATH=/Applications/MEGAcmd.app/Contents/MacOS:$PATH
|
||||
./mega-cmd
|
||||
```
|
||||
|
||||
### Linux
|
||||
By default, whenever MEGAcmdServer is executed, it will log the output to `$HOME/.megaCmd/megacmdserver.log`.
|
||||
|
||||
If you want to launch it manually execute in a terminal:
|
||||
|
||||
```
|
||||
mega-cmd-server
|
||||
```
|
||||
|
||||
### Windows
|
||||
|
||||
MEGAcmdServer is executed in the background without saving the log into a file. If you want to
|
||||
see the output you would need to execute the server (MEGAcmdServer.exe) manually.
|
||||
|
||||
## Accessing stdout and stderr
|
||||
|
||||
The standard output and error streams can be found in the `megacmdserver.log.out` and `megacmdserver.log.err` files, respectively. They're located in the same directories as the logs.
|
||||
The log file is located in `$HOME/.megaCmd` for Linux and macOS, and `%LOCALAPPDATA%\MEGAcmd\.megaCmd` for Windows.
|
||||
|
||||
## Verbosity on startup
|
||||
|
||||
You can start the server with higher level of verbosity in order to have log levels increased at startup.
|
||||
In Windows & Linux you will need to pass `--debug-full` as an argument to the executable (e.g: `MEGAcmdServer.exe --debug-full`).
|
||||
You can start the server with higher level of verbosity in order to have log levels increased at startup, regardless of the log level configured by the `log` command mentioned above.
|
||||
You will need to pass `--debug-full` as an argument to the executable (e.g: `MEGAcmdServer.exe --debug-full`). Alternatively, you can set the `MEGACMD_LOGLEVEL` environment variable to `FULLVERBOSE` before starting the server.
|
||||
|
||||
In MacOS, you can use `MEGACMD_LOGLEVEL` environment variable like this: `MEGACMD_LOGLEVEL=FULLDEBUG ./mega-cmd`.
|
||||
If you want other startup level of logging, you can use the following:
|
||||
* `--debug` or `MEGACMD_LOGLEVEL=DEBUG` will set
|
||||
```
|
||||
MEGAcmd log level = DEBUG
|
||||
SDK log level = DEFAULT
|
||||
```
|
||||
|
||||
If you want other startup level of loggin, you can use:
|
||||
* `--debug-full` or `MEGACMD_LOGLEVEL=DEBUG` will set
|
||||
```
|
||||
MEGAcmd log level = DEBUG
|
||||
SDK log level = DEBUG
|
||||
```
|
||||
|
||||
* `--debug`
|
||||
* `MEGACMD_LOGLEVEL=DEBUG`
|
||||
|
||||
This will set:
|
||||
|
||||
MEGAcmd log level = DEBUG
|
||||
SDK log level = DEFAULT
|
||||
|
||||
* `--debug-full`
|
||||
* `MEGACMD_LOGLEVEL=DEBUG`
|
||||
|
||||
This will set:
|
||||
|
||||
MEGAcmd log level = DEBUG
|
||||
SDK log level = DEBUG
|
||||
|
||||
* `--verbose`
|
||||
* `MEGACMD_LOGLEVEL=VERBOSE`
|
||||
|
||||
This will set:
|
||||
|
||||
MEGAcmd log level = VERBOSE
|
||||
SDK log level = DEFAULT
|
||||
|
||||
* `--verbose-full`
|
||||
* `MEGACMD_LOGLEVEL=FULLVERBOSE`
|
||||
|
||||
This will set:
|
||||
|
||||
MEGAcmd log level = VERBOSE
|
||||
SDK log level = VERBOSE
|
||||
* `--verbose` or `MEGACMD_LOGLEVEL=VERBOSE` will set
|
||||
```
|
||||
MEGAcmd log level = VERBOSE
|
||||
SDK log level = DEFAULT
|
||||
```
|
||||
|
||||
* `--verbose-full` or `MEGACMD_LOGLEVEL=FULLVERBOSE` will set
|
||||
```
|
||||
MEGAcmd log level = VERBOSE
|
||||
SDK log level = VERBOSE
|
||||
```
|
||||
|
||||
## Controlling verbosity of a single command
|
||||
|
||||
You can pass `-v` (`-vv`, `-vvv`, and so on for a more verbose output)
|
||||
to an specific command and it will use higher level of verbosity of MEGAcmd based messages.
|
||||
|
||||
In general, as we've mentioned before, lower verbosity log messages are not printed directly to the console. Only errors are. You can pass `-v`, `-vv`, and `-vvv` when running a command to ensure warning, debug, and verbose messages are printed (respectively). Note that this is only for the console; log level of `megacmdserver.log` will follow the rules explained above.
|
||||
|
@ -19,6 +19,7 @@ Options:
|
||||
|
||||
*If you serve more than one location, these parameters will be ignored and used those of the first location served.
|
||||
If you want to change those parameters, you need to stop serving all locations and configure them again.
|
||||
Note: FTP settings and locations will be saved for the next time you open MEGAcmd, but will be removed if you logout.
|
||||
|
||||
Caveat: This functionality is in BETA state. It might not be available on all platforms. If you experience any issue with this, please contact: support@mega.nz
|
||||
</pre>
|
||||
|
@ -12,5 +12,5 @@ It's only recommended to disable these features before uploading files
|
||||
with image or video extensions that are not really images or videos,
|
||||
or that are encrypted in the local drive so they can't be analyzed anyway.
|
||||
|
||||
Notice that this setting will be saved for the next time you open MEGAcmd
|
||||
Notice that this setting will be saved for the next time you open MEGAcmd, but will be removed if you logout.
|
||||
</pre>
|
||||
|
@ -6,5 +6,5 @@ Usage: `https [on|off]`
|
||||
HTTPS is not necesary since all data is stored and transfered encrypted.
|
||||
Enabling it will increase CPU usage and add network overhead.
|
||||
|
||||
Notice that this setting will be saved for the next time you open MEGAcmd
|
||||
Notice that this setting will be saved for the next time you open MEGAcmd, but will be removed if you logout.
|
||||
</pre>
|
||||
|
@ -1,5 +1,5 @@
|
||||
### log
|
||||
Prints/Modifies the current logs level
|
||||
Prints/Modifies the log level
|
||||
|
||||
Usage: `log [-sc] level`
|
||||
<pre>
|
||||
@ -8,6 +8,7 @@ Options:
|
||||
Messages captured by MEGAcmd server.
|
||||
-s SDK log level (lower level messages).
|
||||
Messages captured by the engine and libs
|
||||
Note: this setting will be saved for the next time you open MEGAcmd, but will be removed if you logout.
|
||||
|
||||
Regardless of the log level of the
|
||||
interactive shell, you can increase the amount of information given
|
||||
|
@ -11,4 +11,6 @@ URL Proxy URL (e.g: https://127.0.0.1:8080)
|
||||
--auto To use the proxy configured in your system
|
||||
--username=USERNAME The username, for authenticated proxies
|
||||
--password=PASSWORD The password, for authenticated proxies. Please, avoid using passwords containing " or '
|
||||
|
||||
Note: Proxy settings will be saved for the next time you open MEGAcmd, but will be removed if you logout.
|
||||
</pre>
|
||||
|
@ -3,9 +3,9 @@ Show all issues with current syncs
|
||||
|
||||
Usage: `sync-issues [[--detail (ID|--all)] [--limit=rowcount] [--disable-path-collapse]] | [--enable-warning|--disable-warning]`
|
||||
<pre>
|
||||
When MEGAcmd detects conflicts with the data it's synchronizing, a sync issue is triggered. Syncing is stopped, and no progress is made on the conflicting data.
|
||||
A notification will appear when sync issues are detected. Because the sync engine might clear the internal issue list when processing, the notification can appear even if there were already issues before.
|
||||
Note: the sync issue list might not contain the latest updated data. Some issues might still be being processing by the sync engine, and some might not have been removed yet.
|
||||
When MEGAcmd detects conflicts with the data it's synchronizing, a sync issue is triggered. Syncing is stopped on the conflicting data, and no progress is made. Recovering from an issue usually requires user intervention.
|
||||
A notification warning will appear whenever sync issues are detected. You can disable the warning if you wish. Note: the notification may appear even if there were already issues before.
|
||||
Note: the list of sync issues provides a snapshot of the issues detected at the moment of requesting it. Thus, it might not contain the latest updated data. Some issues might still be being processed by the sync engine, and some might not have been removed yet.
|
||||
|
||||
Options:
|
||||
--detail (ID | --all) Provides additional information on a particular sync issue.
|
||||
@ -16,14 +16,14 @@ Options:
|
||||
LAST_MODIFIED: The most recent date when this file or directory was updated.
|
||||
UPLOADED: For cloud paths, the date of upload or creation. Empty for local paths.
|
||||
SIZE: The size of the file. Empty for directories.
|
||||
TYPE: The type of the path (file or directory). This column is hidden if the information it's not relevant for the particular sync issue.
|
||||
TYPE: The type of the path (file or directory). This column is hidden if the information is not relevant for the particular sync issue.
|
||||
The "--all" argument can be used to show the details of all issues.
|
||||
--limit=rowcount Limits the amount of rows displayed. Can also be combined with "--detail".
|
||||
--limit=rowcount Limits the amount of rows displayed. Set to 0 to display unlimited rows. Default is 10. Can also be combined with "--detail".
|
||||
--disable-path-collapse Ensures all paths are fully shown. By default long paths are truncated for readability.
|
||||
--enable-warning Enables the notification that appears when issues are detected. This setting is stored locally for all users.
|
||||
--disable-warning Disables the notification that appears when issues are detected. This setting is stored locally for all users.
|
||||
--col-separator=X Use the string "X" as column separator. Otherwise, spaces will be added between columns to align them.
|
||||
--output-cols=COLUMN_NAME_1,COLUMN_NAME2,... Select which columns to show and their order.
|
||||
--enable-warning Enables the notification that appears when issues are detected. This setting is saved for the next time you open MEGAcmd, but will be removed if you logout.
|
||||
--disable-warning Disables the notification that appears when issues are detected. This setting is saved for the next time you open MEGAcmd, but will be removed if you logout.
|
||||
--col-separator=X Uses the string "X" as column separator. Otherwise, spaces will be added between columns to align them.
|
||||
--output-cols=COLUMN_NAME_1,COLUMN_NAME2,... Selects which columns to show and their order.
|
||||
|
||||
DISPLAYED columns:
|
||||
ISSUE_ID: A unique identifier of the sync issue. The ID can be used alongside the "--detail" argument.
|
||||
|
@ -20,8 +20,8 @@ Options:
|
||||
[deprecated] -r ID|localpath same as --enable.
|
||||
--path-display-size=N Use at least N characters for displaying paths.
|
||||
--show-handles Prints remote nodes handles (H:XXXXXXXX).
|
||||
--col-separator=X Use the string "X" as column separator. Otherwise, spaces will be added between columns to align them.
|
||||
--output-cols=COLUMN_NAME_1,COLUMN_NAME2,... Select which columns to show and their order.
|
||||
--col-separator=X Uses the string "X" as column separator. Otherwise, spaces will be added between columns to align them.
|
||||
--output-cols=COLUMN_NAME_1,COLUMN_NAME2,... Selects which columns to show and their order.
|
||||
|
||||
DISPLAYED columns:
|
||||
ID: an unique identifier of the sync.
|
||||
@ -31,7 +31,6 @@ DISPLAYED columns:
|
||||
Pending: Sync config has loaded but we have not attempted to start it yet.
|
||||
Loading: Sync is in the process of loading from disk.
|
||||
Running: Sync loaded and active.
|
||||
Paused: Sync loaded but sync logic is suspended for now..
|
||||
Suspended: Sync is not loaded, but it is on disk with the last known sync state.
|
||||
Disabled: Sync has been disabled (no state cached). Starting it is like configuring a brand new sync with those settings.
|
||||
STATUS: State of the sync, possible values:
|
||||
|
@ -18,8 +18,8 @@ Show options:
|
||||
--only-completed Show only completed download
|
||||
--limit=N Show only first N transfers
|
||||
--path-display-size=N Use at least N characters for displaying paths
|
||||
--col-separator=X Use the string "X" as column separator. Otherwise, spaces will be added between columns to align them.
|
||||
--output-cols=COLUMN_NAME_1,COLUMN_NAME2,... Select which columns to show and their order.
|
||||
--col-separator=X Uses the string "X" as column separator. Otherwise, spaces will be added between columns to align them.
|
||||
--output-cols=COLUMN_NAME_1,COLUMN_NAME2,... Selects which columns to show and their order.
|
||||
|
||||
TYPE legend correspondence:
|
||||
⇓ = Download transfer
|
||||
|
@ -18,6 +18,7 @@ Options:
|
||||
|
||||
*If you serve more than one location, these parameters will be ignored and use those of the first location served.
|
||||
If you want to change those parameters, you need to stop serving all locations and configure them again.
|
||||
Note: WEBDAV settings and locations will be saved for the next time you open MEGAcmd, but will be removed if you logout.
|
||||
|
||||
Caveat: This functionality is in BETA state. It might not be available on all platforms. If you experience any issue with this, please contact: support@mega.nz
|
||||
</pre>
|
||||
|
@ -1,23 +1,19 @@
|
||||
#version=1070000
|
||||
#version=2000000
|
||||
#baseurl=http://g.static.mega.co.nz/upd/mcmd/MEGAcmd.app/
|
||||
#Hash: note this is the hash of the public key assuming an "\n" at the end
|
||||
#pubkeysha256sum=1d3a6360832e193cb98707692c3816b5022ec976e2915cee60994ba20e292b4a
|
||||
Contents/Frameworks/libavcodec.59.dylib;Contents/Frameworks/libavcodec.59.dylib;7511963e256fb2c47fe34e9b18c9e877be908d287007b267ce6570b854715683
|
||||
Contents/Frameworks/libavdevice.59.dylib;Contents/Frameworks/libavdevice.59.dylib;a4c2e6c1329ad087769f9a2bbea0dc7fbbe4f5e078ad1e811da4386d28ade37d
|
||||
Contents/Frameworks/libavfilter.8.dylib;Contents/Frameworks/libavfilter.8.dylib;9d8318dd9b48115595d863ff8c43f3c1863b1be04e41055332ffc4bf4200fb8f
|
||||
Contents/Frameworks/libavformat.59.dylib;Contents/Frameworks/libavformat.59.dylib;5c58aa48366b61fdc6cd1a165df384191ac0e3e9a001e6e9fa273fd5673150a8
|
||||
Contents/Frameworks/libavutil.57.dylib;Contents/Frameworks/libavutil.57.dylib;f1a23a79d0ac9820a6e2bea188f413e8297027852b37277ce47207af4b11d68e
|
||||
Contents/Frameworks/libcares.2.dylib;Contents/Frameworks/libcares.2.dylib;881f830d96ebb3a65a610081af815c4078a648ec19c483c5433f96e5092844c5
|
||||
Contents/Frameworks/libcurl.4.dylib;Contents/Frameworks/libcurl.4.dylib;b7542b97fee9864cb78e562b3199d4533002e83962716873fb714cd6f4ad2eb1
|
||||
Contents/Frameworks/libswresample.4.dylib;Contents/Frameworks/libswresample.4.dylib;9f180e8d59887e13471e5edbae75eb564592d267cac00b6cd36cd292d40a1538
|
||||
Contents/Frameworks/libswscale.6.dylib;Contents/Frameworks/libswscale.6.dylib;5ee4b1982ca846d91f3d9e165a8b7c93248a8e6504d76e325b5ff03305953458
|
||||
Contents/Info.plist;Contents/Info.plist;2006b3f0fbe2a8b0d8df98226450d9e5c6d7a0032b12d5680601871bb18921e9
|
||||
Contents/Frameworks/libavcodec.59.37.100.dylib;Contents/Frameworks/libavcodec.59.37.100.dylib;2b51e739b34966ead1f17e50de30ff5b0a9d6d6841c66e5a1d898f5ad7696e79
|
||||
Contents/Frameworks/libavformat.59.27.100.dylib;Contents/Frameworks/libavformat.59.27.100.dylib;03e74e3c8701bffbd3487aa7fb602f2cc52c36b176818f4a7e490e8ffcf39650
|
||||
Contents/Frameworks/libavutil.57.28.100.dylib;Contents/Frameworks/libavutil.57.28.100.dylib;92366d200425ae969f934367405d3947f1b4b7f7e7287cb2955df76497654b62
|
||||
Contents/Frameworks/libswresample.4.7.100.dylib;Contents/Frameworks/libswresample.4.7.100.dylib;12abee82bda65f7295bbb73d8d4e66a952d31c1285377502e1aaf4323990f1bb
|
||||
Contents/Frameworks/libswscale.6.7.100.dylib;Contents/Frameworks/libswscale.6.7.100.dylib;58806c5775c0e436960f1e385b158a4de409cdd7aa743d70962ca8cc1d5b8431
|
||||
Contents/Info.plist;Contents/Info.plist;469bf08176fd57ff07441e05e872442c5a1a0a11dbe57333a4dc07793127379e
|
||||
Contents/MacOS/mega-attr;Contents/MacOS/mega-attr;a1f60255288b7f01eb9c43b1de59eeac50ad370c0853ee352a3aeefe13472b6c
|
||||
Contents/MacOS/mega-backup;Contents/MacOS/mega-backup;ef37df5a4d97a7729cb9414ce5c0639f2d9b0fd9d9ee138f7655af2580b33682
|
||||
Contents/MacOS/mega-cancel;Contents/MacOS/mega-cancel;343ab60a070927d55e83372c756213594d39cfc0d5b2e21a1f43c9c582098ef3
|
||||
Contents/MacOS/mega-cat;Contents/MacOS/mega-cat;cc6dc3c50adec44d7aa6436845603d9eb4e7688458632fd0bef4aa4c7d9e30af
|
||||
Contents/MacOS/mega-cd;Contents/MacOS/mega-cd;09af358bfb59012385bcf540045e017ec4aadfd5ab7a06f6bdaef4a6d5828c09
|
||||
Contents/MacOS/mega-cmd;Contents/MacOS/mega-cmd;94c1799c5bd9b3ba294b7ae244083fba326a92ea6a3ddd1209bc5256699cf9ba
|
||||
Contents/MacOS/mega-cmd;Contents/MacOS/mega-cmd;c3c8852d930fc4c87bb3ff67bb3abbe5f53121e34c1f6b61e37aa16782ead2a9
|
||||
Contents/MacOS/mega-confirm;Contents/MacOS/mega-confirm;62373fc155c0a2a2f1b67355a2570c4f812042f67272fc12afafabf60ed08318
|
||||
Contents/MacOS/mega-confirmcancel;Contents/MacOS/mega-confirmcancel;d81b018029c263ebe52fb6367ceafea3e0961416cb54dfbdf79a68416ef1ed9d
|
||||
Contents/MacOS/mega-cp;Contents/MacOS/mega-cp;7f999e5e030c3636f8e5cdbf44050c51bf6a0c05bdbbb85394616384690a925c
|
||||
@ -27,7 +23,7 @@ Contents/MacOS/mega-df;Contents/MacOS/mega-df;1c106981101143063c8b76f08c0df8e21b
|
||||
Contents/MacOS/mega-du;Contents/MacOS/mega-du;af7e98fdb28e70fbaf69fffdca4762956a4b00a086dd8c50f3de78e2bad7b457
|
||||
Contents/MacOS/mega-errorcode;Contents/MacOS/mega-errorcode;bdebcaefaa073d12707a6b9a0b3141754eb1637fa6a48c800a9bdbf5dd7511f8
|
||||
Contents/MacOS/mega-exclude;Contents/MacOS/mega-exclude;86c94893e7c380c29f9e36f624d6598ed836851ab95d491e74064a35d0d54aac
|
||||
Contents/MacOS/mega-exec;Contents/MacOS/mega-exec;ee96c5e86c6e51b6115258a2997a960a94a012b23aa635b8494308d8431b01f7
|
||||
Contents/MacOS/mega-exec;Contents/MacOS/mega-exec;34d1b38419ae374c701e33888b02eb910232a9a67c2766c0647adccdb3f9c922
|
||||
Contents/MacOS/mega-export;Contents/MacOS/mega-export;280e5ec5ed2339fee7c82716ff15cff86814fc1b89d34ddc7adacc4f10f2d3f4
|
||||
Contents/MacOS/mega-find;Contents/MacOS/mega-find;497b25404e2390e6415726b21a76d36f0e91a11929fb7487ab23fd77acce58a8
|
||||
Contents/MacOS/mega-ftp;Contents/MacOS/mega-ftp;55cfb9f97e6c8814a2e59f139fad1390bb9b0bcf7699b68f4ffc642e4f858393
|
||||
@ -63,6 +59,8 @@ Contents/MacOS/mega-share;Contents/MacOS/mega-share;63c4a6c1bf2868f5dac9fcb1a965
|
||||
Contents/MacOS/mega-showpcr;Contents/MacOS/mega-showpcr;7f6ef6eb29c53580bf4034d16dda0e053af7e186c019e982206d536984b1cbae
|
||||
Contents/MacOS/mega-signup;Contents/MacOS/mega-signup;ca94246b3f6311a7842f9eb0e84afd37b177a855cdcab31732241349c06cea47
|
||||
Contents/MacOS/mega-speedlimit;Contents/MacOS/mega-speedlimit;17154a2f88001d7c895d38c31c81957b0d6d6539fb4e3053b01728b9069bcbc2
|
||||
Contents/MacOS/mega-sync-ignore;Contents/MacOS/mega-sync-ignore;2363ee4e0b8fbe08b7c75af77b95299a1045eaa8d21e21711699727a7ecf4c33
|
||||
Contents/MacOS/mega-sync-issues;Contents/MacOS/mega-sync-issues;0e9dde40c8429860e27cffd4ba0d742e83b0e3d813b096b19375ae6424766816
|
||||
Contents/MacOS/mega-sync;Contents/MacOS/mega-sync;ad2340fe390ed1126da319eefcf11a7f94346ff0b90ff70162e929bb830c4875
|
||||
Contents/MacOS/mega-thumbnail;Contents/MacOS/mega-thumbnail;cc937f5076861b8879801af5efc32974e7564a918a527f08460a86e6c4dfb89a
|
||||
Contents/MacOS/mega-transfers;Contents/MacOS/mega-transfers;97d83c17ce3ba7c4a422d10b960d8a6808afedd929e5d0e9ce5d7a060a44840b
|
||||
@ -73,14 +71,12 @@ Contents/MacOS/mega-version;Contents/MacOS/mega-version;3c69fb0a46cdd9ffcc2a5560
|
||||
Contents/MacOS/mega-webdav;Contents/MacOS/mega-webdav;bcf797f1ca84d18d320457221e944c2f565797c2131bfeab895565ef643f79cc
|
||||
Contents/MacOS/mega-whoami;Contents/MacOS/mega-whoami;ba6144c61e81af13e2e797b6d1e600cfb00de0b47b02fd639373fbef4087730b
|
||||
Contents/MacOS/MEGAcmd;Contents/MacOS/MEGAcmd;427fda9b9d57298e7012081cd00d0efc823596403616e94602e86e5c8fac478d
|
||||
Contents/MacOS/MEGAcmdShell;Contents/MacOS/MEGAcmdShell;d872f64262ac93cd0e3cc5df8947b5477daf902f4320b30007aa1f5b7dbc7776
|
||||
Contents/MacOS/MEGAcmdUpdater;Contents/MacOS/MEGAcmdUpdater;8df893dfb1e472fb52b9f90268b8a74bde94705d51f97d76c970ff942d06efa9
|
||||
Contents/MacOS/MEGAcmdShell;Contents/MacOS/MEGAcmdShell;d9f1562a2b2ac67af3db6a5d1888e73c13840634fd36b30c66a3d9d3d0346091
|
||||
Contents/MacOS/MEGAcmdUpdater;Contents/MacOS/MEGAcmdUpdater;d1ba141e48d8048112ccf5b30ae119073061534770a6a3578dd62d3c8524704f
|
||||
Contents/MacOS/megacmd_completion.sh;Contents/MacOS/megacmd_completion.sh;35f87a3a37e303cf2e4c15f7fcc30a7ec3703c59a060c0a80a273be58fec744b
|
||||
Contents/PkgInfo;Contents/PkgInfo;7e50a30efad50208a173203ced60818d693bb61266b75aa10927d1a2adce80cb
|
||||
Contents/Resources/app.icns;Contents/Resources/app.icns;57d343b7b03e81c2eb8f5bd71002427160650572e4d9c01a94295b316f8330dd
|
||||
Contents/Resources/empty.lproj;Contents/Resources/empty.lproj;e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
|
||||
Contents/_CodeSignature/CodeDirectory;Contents/_CodeSignature/CodeDirectory;076110e4aeb72ef5c5da1ba33e0dea6f022d0b5b413a717b199bcea466df8110
|
||||
Contents/_CodeSignature/CodeRequirements-1;Contents/_CodeSignature/CodeRequirements-1;416aa75f08b2136092153866ae1cfe284e2d3fb1cb3938383baf122027bdc55b
|
||||
Contents/_CodeSignature/CodeDirectory;Contents/_CodeSignature/CodeDirectory;bb41fc27c14bd488ccb3b5820b99ddcf8fc82137525084d51cb9bad7fe83ccb9
|
||||
Contents/_CodeSignature/CodeRequirements-1;Contents/_CodeSignature/CodeRequirements-1;c4724569f7dbcf768f672e53121a496e188a5ecffd4f32323600ed23aa4c9d46
|
||||
Contents/_CodeSignature/CodeRequirements;Contents/_CodeSignature/CodeRequirements;badc6c4e7f899b7b1acead903f9e02ab8a1fdcce7bde4d85cb385fe778f647b7
|
||||
Contents/_CodeSignature/CodeResources;Contents/_CodeSignature/CodeResources;2bcc672bcd5a11c543d669eec2bdbf42d343e2fc8e5be78010f247fe188332de
|
||||
Contents/_CodeSignature/CodeSignature;Contents/_CodeSignature/CodeSignature;29d3978934f1c1083ee682e88f2c65cac8bc091c6cca542ad93c4c961f0638e2
|
||||
Contents/_CodeSignature/CodeResources;Contents/_CodeSignature/CodeResources;56953ca4059f067e0c03ff7e15063d604841af5b18f61f4e774ea20da2a52cf6
|
||||
Contents/_CodeSignature/CodeSignature;Contents/_CodeSignature/CodeSignature;a9a9bcfc2460896c707115a7420038a84377810054bb5fa3748eb2f39436bb13
|
||||
|
@ -1,126 +1,122 @@
|
||||
#version=1070000
|
||||
#version=2000000
|
||||
#baseurl=http://g.static.mega.co.nz/upd/wcmd/
|
||||
#Hash: note this is the hash of the public key assuming an "\n" at the end
|
||||
#pubkeysha256sum=1d3a6360832e193cb98707692c3816b5022ec976e2915cee60994ba20e292b4a
|
||||
api-ms-win-core-console-l1-1-0.dll;api-ms-win-core-console-l1-1-0.dll;213cdeffc15c734e42565c90512491113652de9e52694ae335131d0e24f91df7
|
||||
api-ms-win-core-datetime-l1-1-0.dll;api-ms-win-core-datetime-l1-1-0.dll;05baccf67fc6360068a9836a1a5ebf0e62697e92990665a6b73ce6c8a4a1b633
|
||||
api-ms-win-core-debug-l1-1-0.dll;api-ms-win-core-debug-l1-1-0.dll;1c2705257c272c7736ef10b81d65f28fc76b4d34412b8db72f5a23b530d847e8
|
||||
api-ms-win-core-errorhandling-l1-1-0.dll;api-ms-win-core-errorhandling-l1-1-0.dll;8b3669326bb61770fb013e4d9a9e1722a1c6e4699be4eb61a620bdb64871cb78
|
||||
api-ms-win-core-file-l1-1-0.dll;api-ms-win-core-file-l1-1-0.dll;6ff3ebd6589cc824e00a9fc548cfcaf8221e046a07f9fb822900d288b9010a2d
|
||||
api-ms-win-core-file-l1-2-0.dll;api-ms-win-core-file-l1-2-0.dll;62a4810420d997c7fdd9e86a42917a44b78fb367a9d3c0a204e44b3ff05de6d4
|
||||
api-ms-win-core-file-l2-1-0.dll;api-ms-win-core-file-l2-1-0.dll;6572965fd3909af60310db1e00c8820b2deef4864612e757d3babab896f59ed7
|
||||
api-ms-win-core-handle-l1-1-0.dll;api-ms-win-core-handle-l1-1-0.dll;cd5c2a10518023d9238f526af78d2fda8265cd10db0edd97be29049ed7aa331c
|
||||
api-ms-win-core-heap-l1-1-0.dll;api-ms-win-core-heap-l1-1-0.dll;ff80c5e44535b1b623a0320df677a6c6dd106f8a5e14cfee49cd3c9d47589646
|
||||
api-ms-win-core-interlocked-l1-1-0.dll;api-ms-win-core-interlocked-l1-1-0.dll;4c1e732b43efec26d8cc467a5ffc13f062b3e3111cf369a8c94253711c77c330
|
||||
api-ms-win-core-libraryloader-l1-1-0.dll;api-ms-win-core-libraryloader-l1-1-0.dll;bbdffc7563c7e4eabce9fc8ff8a3160c7e4d75d5bd50786cc6621e131f668d40
|
||||
api-ms-win-core-localization-l1-2-0.dll;api-ms-win-core-localization-l1-2-0.dll;3dd2e16b6f135cdd45bce4065f6493540ebbaf2f7f1553085a2442ea2cf80a10
|
||||
api-ms-win-core-memory-l1-1-0.dll;api-ms-win-core-memory-l1-1-0.dll;031b58e1621211ed8f41aed863e5e4c05c271d5fdf8abd51aa8e9d5eb3536511
|
||||
api-ms-win-core-namedpipe-l1-1-0.dll;api-ms-win-core-namedpipe-l1-1-0.dll;1920e3afa821558badeaba7bda9b8fe4ed5a5e7bdbb9f85b31d92fc0452030f4
|
||||
api-ms-win-core-processenvironment-l1-1-0.dll;api-ms-win-core-processenvironment-l1-1-0.dll;5009391754032b93bc3f950b5e17d4ed7bfd37941170f97f65c596d9ecdf8e75
|
||||
api-ms-win-core-processthreads-l1-1-0.dll;api-ms-win-core-processthreads-l1-1-0.dll;d7716ba9db032b306be6b48e93b379b4e0a9e763a12671441422507236abecb5
|
||||
api-ms-win-core-processthreads-l1-1-1.dll;api-ms-win-core-processthreads-l1-1-1.dll;3a5d176b1f2c97bca7d4e7a52590b84b726796191ae892d38ad757fd595f414d
|
||||
api-ms-win-core-profile-l1-1-0.dll;api-ms-win-core-profile-l1-1-0.dll;49e587c970471a29bc49b8ace18510b4bd2b1a561484314cddddd10fbf5334da
|
||||
api-ms-win-core-rtlsupport-l1-1-0.dll;api-ms-win-core-rtlsupport-l1-1-0.dll;0d365a06fad099cfa98dc2ddf0ca16dabbc5319b99c29b49be25f3c9809da2d9
|
||||
api-ms-win-core-string-l1-1-0.dll;api-ms-win-core-string-l1-1-0.dll;3c48d059b21126a3755e676758df54b6779c975d13cfd10990a3c29ccfd95571
|
||||
api-ms-win-core-synch-l1-1-0.dll;api-ms-win-core-synch-l1-1-0.dll;c8925ee61e3135aca8b56498c0304bf0db981930d1e3d36ccae2f84791c86908
|
||||
api-ms-win-core-synch-l1-2-0.dll;api-ms-win-core-synch-l1-2-0.dll;42367b6b7285bddc185c0badefe49e883646f574b1d7d832c226f2d1ce489c5b
|
||||
api-ms-win-core-sysinfo-l1-1-0.dll;api-ms-win-core-sysinfo-l1-1-0.dll;77b5019d54aa05ad70d0c1bec4a7ea5f3ba499b493c03ea198b27ceb8509d1af
|
||||
api-ms-win-core-timezone-l1-1-0.dll;api-ms-win-core-timezone-l1-1-0.dll;4f77abb5c5014769f907a194fd2e43b3c977df1fb87f8c98dd15a7b950d1e092
|
||||
api-ms-win-core-util-l1-1-0.dll;api-ms-win-core-util-l1-1-0.dll;8c2d5915b436c2848cefac33ae47e5ba1e96eba0310b9836f069bb5c767a7d42
|
||||
api-ms-win-crt-conio-l1-1-0.dll;api-ms-win-crt-conio-l1-1-0.dll;687be4f560dc3fb96bcda9332617a2d4b1d587411dd1c31ad088146ac0b24a76
|
||||
api-ms-win-crt-convert-l1-1-0.dll;api-ms-win-crt-convert-l1-1-0.dll;347ceeb26c97124fb49add1e773e24883e84bf9e23204291066855cd0baea173
|
||||
api-ms-win-crt-environment-l1-1-0.dll;api-ms-win-crt-environment-l1-1-0.dll;cf601a7b883bb4fb87c28b4a1d9f823d2454b298cdbcb4da4f508db8bd1278ba
|
||||
api-ms-win-crt-filesystem-l1-1-0.dll;api-ms-win-crt-filesystem-l1-1-0.dll;6cc23b34f63ba8861742c207f0020f7b89530d6cdd8469c567246a5879d62b82
|
||||
api-ms-win-crt-heap-l1-1-0.dll;api-ms-win-crt-heap-l1-1-0.dll;a3f13fa93131a17e05ad0c4253c34b4db30d15eae2b43c9d7ec56fdc6709d371
|
||||
api-ms-win-crt-locale-l1-1-0.dll;api-ms-win-crt-locale-l1-1-0.dll;4615ec9effc0c27fc0cfd23ad9d87534cbe745998b7d318ae84ece5ea1338551
|
||||
api-ms-win-crt-math-l1-1-0.dll;api-ms-win-crt-math-l1-1-0.dll;190a2cc8c8e47fcd4d07b4e260e247fb3b5fb4661aa50f7b05158cd062d80762
|
||||
api-ms-win-crt-multibyte-l1-1-0.dll;api-ms-win-crt-multibyte-l1-1-0.dll;b05a5303c9c1059216787e878884b96474480ae5505dc60be97095f8cdf876d5
|
||||
api-ms-win-crt-private-l1-1-0.dll;api-ms-win-crt-private-l1-1-0.dll;e5799a718cfa39b0b6ccdc88f3732cd5dd13c5e4a64de6cff4ed4eba20de3371
|
||||
api-ms-win-crt-process-l1-1-0.dll;api-ms-win-crt-process-l1-1-0.dll;194f04516084785a9650eac58777ae7acebd90d5fabc3e21cebdf705cc0d34b6
|
||||
api-ms-win-crt-runtime-l1-1-0.dll;api-ms-win-crt-runtime-l1-1-0.dll;078d2551f53ca55715f5c6a045de1260ce331b97fd6d047f8455e06d97ef88dc
|
||||
api-ms-win-crt-stdio-l1-1-0.dll;api-ms-win-crt-stdio-l1-1-0.dll;e6bab87156c9e7ae14ce36a754eb6891891a22ddfff584b706538152017fbb0f
|
||||
api-ms-win-crt-string-l1-1-0.dll;api-ms-win-crt-string-l1-1-0.dll;d343529d2a49cbb89d644deafce573b873ab45e0bf57e2d906b2f2a964d7bd9a
|
||||
api-ms-win-crt-time-l1-1-0.dll;api-ms-win-crt-time-l1-1-0.dll;704ad27cab084be488b5757395ad5129e28f57a7c6680976af0f096b3d536e66
|
||||
api-ms-win-crt-utility-l1-1-0.dll;api-ms-win-crt-utility-l1-1-0.dll;340ced80fbcfca804925ff680da1929f68b95959fd7e4d0c9f67322bb5fe2155
|
||||
avcodec-59.dll;avcodec-59.dll;972f2a85d787e01fad9587a86a66e307d102160298ebb24bdc1fadfda3cd139a
|
||||
avformat-59.dll;avformat-59.dll;bd1c608eb2a739d46c64668c8738d54c2e2c3ba42d8675e0d1fe5012dfd2d599
|
||||
avutil-57.dll;avutil-57.dll;ae7735084049d72d4f1dba73963faffce1a1a3ae24c0fd37ceb47705c90aa4d1
|
||||
cares.dll;cares.dll;7e04b2ab55612b3c71256da2a4a2a2f4ffa498d532459536dd4cd0dcdf2c4470
|
||||
concrt140.dll;concrt140.dll;1cddacbfb0c61652fcd543fef1e72cf649e27f3ee8f0d1c0d3988c0b5093e74e
|
||||
libcrypto-3.dll;libcrypto-3.dll;57ecc4490508ee741886912dfc3d59c88cf86eb733daf5c54a0a3f275e08512d
|
||||
libcurl.dll;libcurl.dll;f9fbaca3aea435b5ea73c91d3957b4d6e4022f0bf70d9fd43eccd93586a2e437
|
||||
libssl-3.dll;libssl-3.dll;ce9ba129dd8ea500ef44e8dcc326f752d6d2bc3e87ee2f0c7aff604b03d92496
|
||||
api-ms-win-core-console-l1-1-0.dll;api-ms-win-core-console-l1-1-0.dll;0dbd6a13824e330165c43c5117c9fa40f0a10cdc4c6510454f342f2e1a51613b
|
||||
api-ms-win-core-datetime-l1-1-0.dll;api-ms-win-core-datetime-l1-1-0.dll;286aca8a2ea785ced5570aa0f1071e19d4a3dd08071503cfc8bd0d61f0a954f3
|
||||
api-ms-win-core-debug-l1-1-0.dll;api-ms-win-core-debug-l1-1-0.dll;6107ef427edd7b89e0e8b8efd296e6481fe190e661bbffc7c24ee29faf314d46
|
||||
api-ms-win-core-errorhandling-l1-1-0.dll;api-ms-win-core-errorhandling-l1-1-0.dll;e26a8aeea94d3c91511651b556507b98eabfe811dae24a4ef3171f9ee76bb5b0
|
||||
api-ms-win-core-file-l1-1-0.dll;api-ms-win-core-file-l1-1-0.dll;e4bf8a3fa4f20e9ba6a18a9ffa6b0996cfcd642d2fc7daabd1f5a562a2605b72
|
||||
api-ms-win-core-file-l1-2-0.dll;api-ms-win-core-file-l1-2-0.dll;c35468a6aca68f379c1408031ebdf8d1d13ff0ddc34e981b5ac40f1fa28931c4
|
||||
api-ms-win-core-file-l2-1-0.dll;api-ms-win-core-file-l2-1-0.dll;e6a69128016cd321b406a2235d119b02d5140296ca2cd73d24fb0358a956ed21
|
||||
api-ms-win-core-handle-l1-1-0.dll;api-ms-win-core-handle-l1-1-0.dll;86395deb6ea7af94289e1661a178931878e04a1dc31a45e757904ceacf7c1942
|
||||
api-ms-win-core-heap-l1-1-0.dll;api-ms-win-core-heap-l1-1-0.dll;15c7b7eae718f91465fb9eea408ebd810f227276709120b1d62d5bacd2ebda6f
|
||||
api-ms-win-core-interlocked-l1-1-0.dll;api-ms-win-core-interlocked-l1-1-0.dll;89cdd11237e3a1c8b166a0a3d75140af78583a70a963c6b840b60771ff532a3e
|
||||
api-ms-win-core-libraryloader-l1-1-0.dll;api-ms-win-core-libraryloader-l1-1-0.dll;ccd4ba2311d007cc99ab37c4c11a8aaf0f8e004fce1d60bc30e45723a58ebcff
|
||||
api-ms-win-core-localization-l1-2-0.dll;api-ms-win-core-localization-l1-2-0.dll;4483be14a92203b0cfa4dbc635cedf584912d74c74fda3291c638294e70d2fc6
|
||||
api-ms-win-core-memory-l1-1-0.dll;api-ms-win-core-memory-l1-1-0.dll;8baa809ea5a3833f5533b17a206ace82481df8deb74dfacdbf7bd854e281b5e1
|
||||
api-ms-win-core-namedpipe-l1-1-0.dll;api-ms-win-core-namedpipe-l1-1-0.dll;9b3014a4345a2abf9c6f2e62de7c33d0f390949665617fb1c59f6885c85f21b7
|
||||
api-ms-win-core-processenvironment-l1-1-0.dll;api-ms-win-core-processenvironment-l1-1-0.dll;1457543a4dfad7766acaf5f9974667621e284087925c0946441a45ffde88b5c1
|
||||
api-ms-win-core-processthreads-l1-1-0.dll;api-ms-win-core-processthreads-l1-1-0.dll;de9913163ed36db9d6bc7926c1b392ec4d75e460835ba4b7a8e51fafe872109c
|
||||
api-ms-win-core-processthreads-l1-1-1.dll;api-ms-win-core-processthreads-l1-1-1.dll;f1ba9475a5ad7fee3826de5b2363b19d574e2c48ceb4f9effafa97a7fc2c2c95
|
||||
api-ms-win-core-profile-l1-1-0.dll;api-ms-win-core-profile-l1-1-0.dll;7ad3da8908e8f824dc53f9886ee69edf28dc513f970a2a53506a7ccb63a443b7
|
||||
api-ms-win-core-rtlsupport-l1-1-0.dll;api-ms-win-core-rtlsupport-l1-1-0.dll;240f3027579d782b55cf5f043e2bcaf96c58046f7eb1b9289895930ca38b6421
|
||||
api-ms-win-core-string-l1-1-0.dll;api-ms-win-core-string-l1-1-0.dll;780e6a825d4be11817c650ac544b85d3516a8a2dd2bf8150d2c782b7eb1d68aa
|
||||
api-ms-win-core-synch-l1-1-0.dll;api-ms-win-core-synch-l1-1-0.dll;08d9bcd59e447f3c99170ccdfede4d47737d3362398d25fc6c871fb3ec79d52e
|
||||
api-ms-win-core-synch-l1-2-0.dll;api-ms-win-core-synch-l1-2-0.dll;e42313934eb3de9129f95963589193b1341461e715b6b8ed06dc7bd910043249
|
||||
api-ms-win-core-sysinfo-l1-1-0.dll;api-ms-win-core-sysinfo-l1-1-0.dll;17b0ab4de61eec301a3db893a6aec480f84080a73ab4bd06657d1dd27404ea6f
|
||||
api-ms-win-core-timezone-l1-1-0.dll;api-ms-win-core-timezone-l1-1-0.dll;effa64deaa9871fce680fe4d0286234c604d420b6c2ecc05fac0c2f9de56cf33
|
||||
api-ms-win-core-util-l1-1-0.dll;api-ms-win-core-util-l1-1-0.dll;069d50a1253397985c9f774114534f0369ec8d178c1f07cacc1c4af3411dd57d
|
||||
api-ms-win-crt-conio-l1-1-0.dll;api-ms-win-crt-conio-l1-1-0.dll;d5571d47740d9bff9e13b49aa2be1657e08d819d6422fe352e83f006362e1296
|
||||
api-ms-win-crt-convert-l1-1-0.dll;api-ms-win-crt-convert-l1-1-0.dll;cd5003a91a604e1ffc72b63f4cd59caac1578a116d13064fa765318f97e43e00
|
||||
api-ms-win-crt-environment-l1-1-0.dll;api-ms-win-crt-environment-l1-1-0.dll;dcd2e26fd2964f722317f2fafbabbe8c2f61a96785f5bc0aeb2ce583469f2357
|
||||
api-ms-win-crt-filesystem-l1-1-0.dll;api-ms-win-crt-filesystem-l1-1-0.dll;52e5555f58e5803f41ba628e0150fea780defb2040dba6e81cdb6d05c16a0272
|
||||
api-ms-win-crt-heap-l1-1-0.dll;api-ms-win-crt-heap-l1-1-0.dll;6823f436c41df41252bbb4f16d8888e8020960afc0c217c0dfa1673c760c72b9
|
||||
api-ms-win-crt-locale-l1-1-0.dll;api-ms-win-crt-locale-l1-1-0.dll;fa285f2f45b36988d3b6486f8f8a6ab535ee80f232cf5d1aea9d85751ab34939
|
||||
api-ms-win-crt-math-l1-1-0.dll;api-ms-win-crt-math-l1-1-0.dll;12900f76f2874fb75d922e460c075334571d28b264ac2894a98b29da04d737f4
|
||||
api-ms-win-crt-multibyte-l1-1-0.dll;api-ms-win-crt-multibyte-l1-1-0.dll;0d3decb779c934ffd831eba92a80ecea9420d9839bb1fa879921e8dfa1ff6963
|
||||
api-ms-win-crt-private-l1-1-0.dll;api-ms-win-crt-private-l1-1-0.dll;1677c9571d17ebc1c4dbddd8a17833cc73780c19b52fcc68abf2a90f4665aa5f
|
||||
api-ms-win-crt-process-l1-1-0.dll;api-ms-win-crt-process-l1-1-0.dll;fd4e81019d0ddd13cc61fa5963d7d8cedb703f0ec952333170ad0b758eb1ff40
|
||||
api-ms-win-crt-runtime-l1-1-0.dll;api-ms-win-crt-runtime-l1-1-0.dll;55ade67a6e64caa2b624187f875ee562ffac8eac5a2d49d06d935c09812e2cf5
|
||||
api-ms-win-crt-stdio-l1-1-0.dll;api-ms-win-crt-stdio-l1-1-0.dll;1a01f3af5a35594b1b92c2e4a244b7d5c1ce1d6d75e394d8d45456fc19446a4c
|
||||
api-ms-win-crt-string-l1-1-0.dll;api-ms-win-crt-string-l1-1-0.dll;7edf261a399f10359bd833766bf0ae2254e86dc86305da28e69be8b731c78c48
|
||||
api-ms-win-crt-time-l1-1-0.dll;api-ms-win-crt-time-l1-1-0.dll;10bb36bb6f91219371fd5f93c5155aca4c65a0c665f8318a4b6c84763fc66430
|
||||
api-ms-win-crt-utility-l1-1-0.dll;api-ms-win-crt-utility-l1-1-0.dll;f07d088f2a5eea9413bc3aafbcaab9ae73ea8a1691026d5ee898a34c939d52a3
|
||||
avcodec-59.dll;avcodec-59.dll;d2855b02ad0a2e36fa1a267fbfd7a8bfd3b78da5f1383dc000202a6913ac1e11
|
||||
avformat-59.dll;avformat-59.dll;94d0bbba5f5a761cb7047bc005f999edb1ccff8e4b76b3a265906f76f3186c83
|
||||
avutil-57.dll;avutil-57.dll;3b905870f8d44107f6a04a3192b0de4ca35f2e80425e5a764a20d2b4c7302fe4
|
||||
concrt140.dll;concrt140.dll;0604ee7df2abb2272e2d6fc3615bbfc7c1e385bc9f7f3a3efb780570499055df
|
||||
MEGA Website.url;MEGA Website.url;7b5f1278de755dde65017404b662b6ab97fa7328974eec3872ce571f7e462dac
|
||||
mega-attr.bat;mega-attr.bat;89a1b21160a0e3890c45596d7832ff37474a2c3200423f23adee11ff676b295b
|
||||
mega-backup.bat;mega-backup.bat;167d72cbaa49b8c6c54d57ab44ad9e907f4bf9551460574f4231a9dd956c4c32
|
||||
mega-cancel.bat;mega-cancel.bat;aab45aa9eac5e0b9865f44a234f6c5cddbc3b2fcb14aa4fee101cbcef2ba37d8
|
||||
mega-cat.bat;mega-cat.bat;03d39664173b9baf2ae530b457510c4ee915e9060be46063511ed903d3afa265
|
||||
mega-cd.bat;mega-cd.bat;d3b331e8568b4aa59710b2a731541d625138fa0d37aa26fda679a6b8713827ad
|
||||
mega-confirm.bat;mega-confirm.bat;e45eeac40ace7b050f9747d79954c4b7bb82792b727a691799694f109938b338
|
||||
mega-confirmcancel.bat;mega-confirmcancel.bat;5c3128dfd3f4d604afa6e602aca4a346d758d889400eb74584c88f1e40fe9bac
|
||||
mega-cp.bat;mega-cp.bat;f5cc9ce16100354271c7b385377053076c486cba84f21151a65721d24caecf09
|
||||
mega-debug.bat;mega-debug.bat;df39fd5831826cb988eb5bfdfb4a98ca75eda8c03f6acdc286a7741448849c9b
|
||||
mega-deleteversions.bat;mega-deleteversions.bat;ac1d8b0b8458ec134d5c85fa863c3d8ed016e35454dedae79698ad0818919b7f
|
||||
mega-df.bat;mega-df.bat;b47b85efda1561b559c7d1a81e0d4b49958607f6e4933bf46f97f43c917f69a7
|
||||
mega-du.bat;mega-du.bat;fbb81f40c843fc33e57a23db01ee0f206c99c6ed75520a5594e0b3d525725215
|
||||
mega-errorcode.bat;mega-errorcode.bat;f5793c201602a3619cac14d31d0356d058d8128b13027b1e64073dd029193614
|
||||
mega-exclude.bat;mega-exclude.bat;a347a180847fa3dca00bc28dd1321f5b332fdf574c73ea2b30ef3fab63b2380b
|
||||
mega-export.bat;mega-export.bat;30fe5d62f0f47418dc83e03bc80977426010c8edcf01e4e7db820965e2781442
|
||||
mega-find.bat;mega-find.bat;0e683610f7369c674cebc1ecf8d6e030f0433226887b902e74fe1e174c23a6a7
|
||||
mega-ftp.bat;mega-ftp.bat;df52291409a56fd512402124a94b51dda27c0b5caf2c93d36932e6ce2268bb3c
|
||||
mega-get.bat;mega-get.bat;b309f0785461dbe35a63b0a674cc70381ef7f87720d2aa884a8dbc8ae3c2c42e
|
||||
mega-graphics.bat;mega-graphics.bat;d692deb721e9ac81db35e26542abbc64f26aebb0f232dab53d390de7a03461da
|
||||
mega-help.bat;mega-help.bat;8558ee2389b4493ff9b3d9bcab252564a817284583d651649ce79d7091ea45d3
|
||||
mega-https.bat;mega-https.bat;91c60eb7b5f95951e96a2437ee51dbae7821377e8e4864279b41c53791481b6a
|
||||
mega-import.bat;mega-import.bat;90eff64c5a742c7d96d87648a15bcb33145ebebab593f0c0161dae22880b90a0
|
||||
mega-invite.bat;mega-invite.bat;7d9713740d78deeabff15b6080a387460a315a680777d4f1e04c498f1b708826
|
||||
mega-ipc.bat;mega-ipc.bat;04fe985dcc18c3ab8dc4ecf5ebf61ed9dd4bafdcd0937c8d10235c98b2f4a9ae
|
||||
mega-killsession.bat;mega-killsession.bat;7b2aeb01bd57aa53f1d615294fa425aaa3d82f43474ed529d9a33efb873a183e
|
||||
mega-lcd.bat;mega-lcd.bat;776a5e227d275f6a777ea5c7886e69efe5b9ee9da3fd79700965f4809cde5d27
|
||||
mega-log.bat;mega-log.bat;4e703495f3616dd936afdfa2c32958189ae5e90328d9389b86e49a50654e6393
|
||||
mega-login.bat;mega-login.bat;9bc358f934bfbeb12347083aef6b7a6efe26846b83ce0e653a4b89c64ba89073
|
||||
mega-logout.bat;mega-logout.bat;ab36f1dcf6cfd93b95bf5394b1ef22deff505df685c9b0a36d25fa9c94f4b548
|
||||
mega-lpwd.bat;mega-lpwd.bat;6364d746c3f1f0329fd67cec0f6a1f09ae3e521f3ef37b0ab728009cf55c4a5c
|
||||
mega-ls.bat;mega-ls.bat;d57684855baf42e911b235c7ffb5a106aac875461d5faeb059c4d941e7b5cfd6
|
||||
mega-mediainfo.bat;mega-mediainfo.bat;59606376cabc50a19af3732cddbbcda40c59e0c85aa6bc0320420a6a19abca49
|
||||
mega-mkdir.bat;mega-mkdir.bat;690c56c5ebd58d596632a4ff28596df8aa478309fc979b9eb8b07fb89db4d944
|
||||
mega-mount.bat;mega-mount.bat;6f0a3e80dcde8611beb4ac1d9e575601997e58b9a4a17054c5cb4eedf6f8062f
|
||||
mega-mv.bat;mega-mv.bat;4e694c7eb85dcf55d7642f3504a5d63493e46ebd711735c57a45569ef2a7b88a
|
||||
mega-passwd.bat;mega-passwd.bat;0f5947f5dbd2543c49853451d6d0deb64b04796e4c61327a1b5aa1c295b2a861
|
||||
mega-preview.bat;mega-preview.bat;caed90cc51561edd29eb5e842c266add1bb477261cf5254a0e2c218ed0737b93
|
||||
mega-proxy.bat;mega-proxy.bat;a22417b2eccc3ab5a32aecee8bd004cbbef73fe80d58119d23223163985d1f6b
|
||||
mega-put.bat;mega-put.bat;a20fb6cf0d1e9c86de68b8665fbbf0974b04c69beccd41d7123f6b3004221beb
|
||||
mega-pwd.bat;mega-pwd.bat;38744af426f8304c5ee9c2857291225726bffe2788870f2cb9e6a3b8836297e6
|
||||
mega-quit.bat;mega-quit.bat;44026a4ab85bb59d02241e400848ac77be17c60fc86a0d07055e8ed8fe490ba2
|
||||
mega-reload.bat;mega-reload.bat;4a0231a6f5ccb7f5908a9d7f12987efa1b45ff2148214360b4a205f15e77075f
|
||||
mega-rm.bat;mega-rm.bat;1e55e2b5357bce9f5fa54d2a12801dfba6c70262a6ddceae4b227a014db0aa92
|
||||
mega-session.bat;mega-session.bat;20c963d0749b58afccdb7d45ff36451015689bec1c035ee7bf809c7ee5b6b483
|
||||
mega-share.bat;mega-share.bat;66fc8fa5564448729b569b843c158d933d8774666651f98cfbd757ea9d721d94
|
||||
mega-showpcr.bat;mega-showpcr.bat;e5d799f4ebb0f0a02c6c7efb0fd946a9a9f7b8283c5ccb697132974711060ccf
|
||||
mega-signup.bat;mega-signup.bat;f64064f35b2c464cb20fdcb70a8aa73856b6a8af65acd5be8d58b79df9889c1c
|
||||
mega-speedlimit.bat;mega-speedlimit.bat;c6f2a4b09f9249c4e77ad03cc0e15940f080c125187137bc88a7d2adf2a4916f
|
||||
mega-sync.bat;mega-sync.bat;c39719e5e79043b28a6368cdc942032bf5b2ab18fff2f66bd726058e9e921ef7
|
||||
mega-thumbnail.bat;mega-thumbnail.bat;58574690db6cfff0ffa7864a0a13265ae1bd37d5fc3b0d9e0c88a1f7d69c193d
|
||||
mega-transfers.bat;mega-transfers.bat;6f35a34033499938700e42f4123399f711003d2dab83ed50e69f7df5ecf976d8
|
||||
mega-tree.bat;mega-tree.bat;92a11c9ee2af4ffb55d05210813c7ff309f90274a1d211018acc2643367b2534
|
||||
mega-userattr.bat;mega-userattr.bat;a48dfc0e20bd69e3774d74860f2a74691addf9fbaae42c71450561a4d526f92a
|
||||
mega-users.bat;mega-users.bat;24d85b5700f05d7b638d294c87e8b8809df80f0611c63ee818f60ed487f1b4bc
|
||||
mega-version.bat;mega-version.bat;b69c2f0acc58d45ae4dae502892af08ce9abaa0de2433573a07e9a06fae3a255
|
||||
mega-webdav.bat;mega-webdav.bat;233717710c3ac45906e2cbd110a167d7779bd6697a508013c5b6559bbce97815
|
||||
mega-whoami.bat;mega-whoami.bat;b6ff6c05c78901dfc6291751bab1ae93a0ac836d8d506e57d2bb6fb927facc7d
|
||||
MEGAclient.exe;MEGAclient.exe;ec47410a39b921fa6e88237eeeb8b74bf598ab3bff2b736d766a09b557d41fff
|
||||
MEGAcmdServer.exe;MEGAcmdServer.exe;5267ce6ef96a186aabea878e57d9e80ede18c0d98e570f74a373827b33ec3599
|
||||
MEGAcmdShell.exe;MEGAcmdShell.exe;25473a6c0680518b277c162aca631a7f48b3d9a0b7ef0990aec95b3e3e5a79c1
|
||||
MEGAcmdUpdater.exe;MEGAcmdUpdater.exe;07ea647aa5d0b8f4c06589e0d963faec33762b48168bae5113f182898518b201
|
||||
msvcp140.dll;msvcp140.dll;5a6dfa5e1ffb6c1e7fc76bd121c6c91305e10dd75fc2124f79fee291a9dd9e86
|
||||
msvcp140_1.dll;msvcp140_1.dll;4e94f9c89188fba7cae4bde37cf824d654717731559d47985d2b0749cfb11aa6
|
||||
msvcp140_2.dll;msvcp140_2.dll;94a12bedb9a25393dc75fccde7243d5e90acf40b1f14406132a44ff42e220f2e
|
||||
msvcp140_atomic_wait.dll;msvcp140_atomic_wait.dll;641613d28d039af4c9efa79303b6f57825fe9f43c345fe06b45094d61c5e8a66
|
||||
msvcp140_codecvt_ids.dll;msvcp140_codecvt_ids.dll;74ee4398ae24c1b787af944d650aa345ba0e9787cd112542d782b714209e35cc
|
||||
swresample-4.dll;swresample-4.dll;4bc8c640aaa42aa5ef3e711b16c6e2de711a237abc10055c15564d91b49c1d60
|
||||
swscale-6.dll;swscale-6.dll;4d36dfed7746024d187420e8a98e5f080ce8f2ae0ff61541809130f5ca5067d3
|
||||
ucrtbase.dll;ucrtbase.dll;10f8f24aa678db8e38e6917748c52bbcd219161b9a07286d6f8093ab1d0318fa
|
||||
uninst.exe;uninst.exe;0c668357e06963fdf28dc80f6336336e452055cf76b0bd67c691906453e17e1b
|
||||
vccorlib140.dll;vccorlib140.dll;d43812f712f02a50017128463c357eae8f78b665353f889848f59a9faefd8ff7
|
||||
vcomp140.dll;vcomp140.dll;de30db4af8ae1790048168a13913318e66aa1d2feb0b45a62983c10caecd9772
|
||||
vcruntime140.dll;vcruntime140.dll;f1fd5f6ec1cfe0cc3b66b5322ac97568bc63b19c1e415b99aad7c69ddbafa33c
|
||||
mega-attr.bat;mega-attr.bat;7a5b5b221bc921a5eb98633f519b2141bd0daede6eae40cba113333992967de7
|
||||
mega-backup.bat;mega-backup.bat;d0df6b91202750d3b13071e3e231c1954ff032c1340cf051e968a91d74dbb80a
|
||||
mega-cancel.bat;mega-cancel.bat;fa68a5dd1e0051425c3e8c41f5695810eadc2058397046b1848a0599f47c9953
|
||||
mega-cat.bat;mega-cat.bat;6225ce58605e8795fe2e48220607ac193744cb313cd181fb6e90a190484a9bbf
|
||||
mega-cd.bat;mega-cd.bat;c102ccb99cf3e83b1eb0886b15ed5b3e5deff7b2fedfba9408558cd9aa8f1e18
|
||||
mega-confirm.bat;mega-confirm.bat;7ce93a6a402b631760477079861796cf1dd25517866cbd2d5be27635d7783fee
|
||||
mega-confirmcancel.bat;mega-confirmcancel.bat;dde5415005ad473cc98ef9b9b28f210350bb8d4efca6f4af8eb63d394efdf0e0
|
||||
mega-cp.bat;mega-cp.bat;36292230fd45e595e98667653646ee1baaa87bc4e9b22b566ec5bc0cc7347821
|
||||
mega-debug.bat;mega-debug.bat;423e02ee02c0d24e2aec7c02ebc295954d2d2ab3166f1174ef96fc5111179d0d
|
||||
mega-deleteversions.bat;mega-deleteversions.bat;c67afe7a90012f5885348d6ca6bb4abbf27f9b891ec61204fe53763281505c13
|
||||
mega-df.bat;mega-df.bat;b98a9f278dbc417aa51c4eb34af5cfe076be0e5700dbae1558b7aa381a926881
|
||||
mega-du.bat;mega-du.bat;1e91bfb1ad81e12c1068f42b612e95c986ff6807919195188f3a4cacf692183f
|
||||
mega-errorcode.bat;mega-errorcode.bat;d431d2d116ccfd9f01d4f54f9580fa89615848aa6814b7d8f2da347b3127050a
|
||||
mega-exclude.bat;mega-exclude.bat;ab9f76a28ba0a5efb0eb2e240e599409d6d6380a18dd680f93bc3d705409b299
|
||||
mega-export.bat;mega-export.bat;42dd5f70a8f78854e01b175fa7672b2a0d894da716a910807e2373e2dd983947
|
||||
mega-find.bat;mega-find.bat;08147ae1b71d69a09f48ea145f183fba304a2884e5b27953fc89943ba41df69c
|
||||
mega-ftp.bat;mega-ftp.bat;8c049a43a7f13856bf8f6667beb6a5496a4b0e111a5a3afb40b7c1f36b97e456
|
||||
mega-get.bat;mega-get.bat;2e40e197c0fa5b74cb164f2b696cc064de1b356c42450c1028e77568efdc1eff
|
||||
mega-graphics.bat;mega-graphics.bat;3c91e02f744d7b84cb76577bf354a54adce1562e7bfcea98588a3204a82ed396
|
||||
mega-help.bat;mega-help.bat;cef87d1319c235952d238bc5111935bc8312bb1cfc17d61e522151077857715e
|
||||
mega-https.bat;mega-https.bat;1cf2a5175ee289514f70c8f956145725dd501c3fd9860413bc77abc93022b57d
|
||||
mega-import.bat;mega-import.bat;3343902b8d3cbc6f62529d6920178f0e6042472f2772a08df15ed73121d04619
|
||||
mega-invite.bat;mega-invite.bat;20be9c6d549733269ac7a9ce7ab3928c29134625b1e84eb54e52cda192774a55
|
||||
mega-ipc.bat;mega-ipc.bat;7b29de9117b7b48d9e57ac6a0df6e7b229905ab3d5858daccb354116b0039ba3
|
||||
mega-killsession.bat;mega-killsession.bat;9f83aada9c370952e9b49a9c41eb7d98f30e5b024d070e371244ee6b76f64c96
|
||||
mega-lcd.bat;mega-lcd.bat;de56d34a0e884ce8691ebc86ac55832a5d8a22eb5eb5fdbe345d69301500f746
|
||||
mega-log.bat;mega-log.bat;ebbb6703ef76be60e030058b2ca56934fa573d9891096bfb43be5b7adcbc14cc
|
||||
mega-login.bat;mega-login.bat;af44e84d703d44e46e8aba3b9e6bc8d0d4304d143493fd14eaff70742013ab81
|
||||
mega-logout.bat;mega-logout.bat;b10da32e4da3c750ce8874222b7348a58c9c61f7d2ec11f73c91fc7d31722a02
|
||||
mega-lpwd.bat;mega-lpwd.bat;eefe4d679a99d507cf49d434746b22bc3d312802b9a4ac48824e0d363b8c1b12
|
||||
mega-ls.bat;mega-ls.bat;cfc0d9ce93645ae56a5e9e27a6d59090b615027a4678e4b8ab57f86b2c49d5ad
|
||||
mega-mediainfo.bat;mega-mediainfo.bat;7364d4c609c2030136837f70765586494d6951058530d828b75e57eedcac2626
|
||||
mega-mkdir.bat;mega-mkdir.bat;1535df364439afcf86860495c71eccb1b40cc202f30d3180a30b389298ffbbd9
|
||||
mega-mount.bat;mega-mount.bat;22b5c4a02c0df84d025b6315b8f8098b0be250b1237c8aad89f07c3b707073a7
|
||||
mega-mv.bat;mega-mv.bat;bd253db0f09da734afc3c6d31058fb20551fbc18197e85e9bdf52d62e00fdfaa
|
||||
mega-passwd.bat;mega-passwd.bat;3aa3bedfc45eaf3f1e1609fe96b028821a79d1915a5b930609a8ca2b3730c2dc
|
||||
mega-preview.bat;mega-preview.bat;54a263b9fe0ac933aa77b73a5219bb0fa813ea0501ba331dbfb7b16c61ea5cef
|
||||
mega-proxy.bat;mega-proxy.bat;f323cf922dee4aac447b504399c367ed45e752a6cbe0adec5c68a675611118b6
|
||||
mega-put.bat;mega-put.bat;ca3e2c5aa77a6b7b4a9a4d7699416e714a9aa027c7d68fda47023405716766f8
|
||||
mega-pwd.bat;mega-pwd.bat;cdf78fb7b00f2c50db3672a02923bfd05d380741b582570db194ccf7d4b22033
|
||||
mega-quit.bat;mega-quit.bat;bb82d8e26f81007f19683422bc021791d1ce74fd5f11f3c1c29307a6b98752f0
|
||||
mega-reload.bat;mega-reload.bat;9e0d368d6f7863944711697cf54e1201c405ab37b8f1ebbf520ad15d0c96f4fa
|
||||
mega-rm.bat;mega-rm.bat;7e503e07f13199e35faad58590b56938ab53b14745afa5f596f31f8921c72859
|
||||
mega-session.bat;mega-session.bat;91a24d34d4752deb4a76215f564f202edb9eaba2285b5f26f3f9dc40aad7c702
|
||||
mega-share.bat;mega-share.bat;270c97a6e71b03a67297a534dc1d7299fe801f9c654f68e0fbe0276a65921054
|
||||
mega-showpcr.bat;mega-showpcr.bat;39a7f816821855676392dcb437378bfbfa61a595748af6a4b82e43cd9704955d
|
||||
mega-signup.bat;mega-signup.bat;6e8c13eb91c9d38d2ce48c75c569bd151d3f3c7641e3b2b3ed04994ae3e4a33f
|
||||
mega-speedlimit.bat;mega-speedlimit.bat;c037351ecf3cd9fae0b1416b60cd651fe317fc57fd06f996c9b7f6450c9a07b3
|
||||
mega-sync.bat;mega-sync.bat;62a2334922a0ea0867b2a71a6900e44975b03612dbeeb181aca6d44d48222922
|
||||
mega-thumbnail.bat;mega-thumbnail.bat;8f7b42ac9e6358534bed0355e70b6f007070006f38328e35c860ff502d4768b4
|
||||
mega-transfers.bat;mega-transfers.bat;38b4bb079557909927336aeddda2c8f937b5d089b2bfe224cb0b895250b85d5e
|
||||
mega-tree.bat;mega-tree.bat;0f03785c46a12893100f360da48fb473de9011bffd9562a327aa76626078d263
|
||||
mega-userattr.bat;mega-userattr.bat;28cede25ba267f57d1c60b531764f1290a8fc78b64b1bcc307b0e23f5fea1bd2
|
||||
mega-users.bat;mega-users.bat;6f4499de547c0d5c5bcba21d5c226bb83a6f01909d9fc4cd1c578c4bdc8e6955
|
||||
mega-version.bat;mega-version.bat;2f1794963704f4dc65e23155ef1fb27788ea48e6099479c4809093f7281c28fc
|
||||
mega-webdav.bat;mega-webdav.bat;97c8f94a273c7d7d9e5b6b1929a8e227c3a15d6c09c8124f12d7fe3723a7beae
|
||||
mega-whoami.bat;mega-whoami.bat;48f9d5104bb5364f6831b11d9847871c528ad656655c3fa49ce9be70e932767f
|
||||
MEGAclient.exe;MEGAclient.exe;5ddd680fe8df08a840f96c337f8cff6d58cfbb958aa137f9787f980546d75dee
|
||||
MEGAcmdServer.exe;MEGAcmdServer.exe;fcc11cbbe4b26e37dd6a024f4ae8eb89c8b40395c042c5196a2e2fac29f1129f
|
||||
MEGAcmdShell.exe;MEGAcmdShell.exe;87372890ba45b72e3bd3645cf191f60148daaf8d6f9767998f660fa877799421
|
||||
MEGAcmdUpdater.exe;MEGAcmdUpdater.exe;646851e19053237a9412fa2a30d2e637e21ec22358306f5ec4e90f47091c5beb
|
||||
msvcp140.dll;msvcp140.dll;718812adb0d669eea9606432202371e358c7de6cdeafeddad222c36ae0d3f263
|
||||
msvcp140_1.dll;msvcp140_1.dll;1ed68ad44005f5db536d720c0dec06e3b096a9887f3412ca99277d520185aeb5
|
||||
msvcp140_2.dll;msvcp140_2.dll;505cbb87d025355e09eb25686e4b0f617f659af993f9699ad1846ddffc120212
|
||||
msvcp140_atomic_wait.dll;msvcp140_atomic_wait.dll;f4bc71d60fc5d28a6f6eff967428055f2cdd0189e5cb8d336842baa7a13de2bf
|
||||
msvcp140_codecvt_ids.dll;msvcp140_codecvt_ids.dll;4a5e991f66087466dc7105b5d67ecdf8c87a9cde085909036abebdf792fa191b
|
||||
swresample-4.dll;swresample-4.dll;27ff1406ae83ef1428516f8a39b46c89a09e7bb96ce0966d0039c411322442b4
|
||||
swscale-6.dll;swscale-6.dll;d9bfec0c01f9520980de59a64a2b72a1fc14327ce51f6178ea8ae69c309953f2
|
||||
ucrtbase.dll;ucrtbase.dll;9793b5f7890034ea345726fc9df07b79f518e1aebef2ab8b3d409f67465cefa9
|
||||
uninst.exe;uninst.exe;ddbaaeb10dca4112c290188155f1afc8acf30cf9eaa3519634fadae455c5301b
|
||||
vccorlib140.dll;vccorlib140.dll;cf8d3df3c5374afce1094666b34665dca65743be7cb2e6199131037a344c3d02
|
||||
vcomp140.dll;vcomp140.dll;c698b3eae090f07231560edbcb5fc3ae5aa6d30dbc3b3d75a7943e924b6b9158
|
||||
vcruntime140.dll;vcruntime140.dll;09d1e604e8cdd06176fcc3d3698861be20638a4391f9f2d9e23f868c1576ca94
|
||||
|
@ -1,127 +1,123 @@
|
||||
#version=1070000
|
||||
#version=2000000
|
||||
#baseurl=http://g.static.mega.co.nz/upd/wcmd64/
|
||||
#Hash: note this is the hash of the public key assuming an "\n" at the end
|
||||
#pubkeysha256sum=1d3a6360832e193cb98707692c3816b5022ec976e2915cee60994ba20e292b4a
|
||||
api-ms-win-core-console-l1-1-0.dll;api-ms-win-core-console-l1-1-0.dll;8f8b79150e850acc92fd6aab614f6e3759bea875134a62087d5dd65581e3001f
|
||||
api-ms-win-core-datetime-l1-1-0.dll;api-ms-win-core-datetime-l1-1-0.dll;913eaaa7997a6aee53574cffb83f9c9c1700b1d8b46744a5e12d76a1e53376fd
|
||||
api-ms-win-core-debug-l1-1-0.dll;api-ms-win-core-debug-l1-1-0.dll;58a8d69df60ecbee776cd9a74b2a32b14bf2b0bd92d527ec5f19502a0d3eb8e9
|
||||
api-ms-win-core-errorhandling-l1-1-0.dll;api-ms-win-core-errorhandling-l1-1-0.dll;46079c0a1b660fc187aafd760707f369d0b60d424d878c57685545a3fce95819
|
||||
api-ms-win-core-file-l1-1-0.dll;api-ms-win-core-file-l1-1-0.dll;5c9bc70586ad538b0df1fcf5d6f1f3527450ae16935aa34bd7eb494b4f1b2db9
|
||||
api-ms-win-core-file-l1-2-0.dll;api-ms-win-core-file-l1-2-0.dll;629e52ba4e2dca91b10ef7729a1722888e01284eed7dda6030d0a1ec46c94086
|
||||
api-ms-win-core-file-l2-1-0.dll;api-ms-win-core-file-l2-1-0.dll;dac867476caa42ff8df8f5dfe869ffd56a18dadee17d47889afb69ed6519afbf
|
||||
api-ms-win-core-handle-l1-1-0.dll;api-ms-win-core-handle-l1-1-0.dll;0b3dfb8554ead94d5da7859a12db353942406f9d1dfe3fac3d48663c233ea99d
|
||||
api-ms-win-core-heap-l1-1-0.dll;api-ms-win-core-heap-l1-1-0.dll;c43075b1d2386a8a262de628c93a65350e52eae82582b27f879708364b978e29
|
||||
api-ms-win-core-interlocked-l1-1-0.dll;api-ms-win-core-interlocked-l1-1-0.dll;c23fe8d5c3ca89189d11ec8df983cc144d168cb54d9eab5d9532767bcb2f1fa3
|
||||
api-ms-win-core-libraryloader-l1-1-0.dll;api-ms-win-core-libraryloader-l1-1-0.dll;f320f9c0463de641b396ce7561af995de32211e144407828b117088cf289df91
|
||||
api-ms-win-core-localization-l1-2-0.dll;api-ms-win-core-localization-l1-2-0.dll;8664222823e122fca724620fd8b72187fc5336c737d891d3cef85f4f533b8de2
|
||||
api-ms-win-core-memory-l1-1-0.dll;api-ms-win-core-memory-l1-1-0.dll;5d9767d8cca0fbfd5801bff2e0c2adddd1baaaa8175543625609abce1a9257bd
|
||||
api-ms-win-core-namedpipe-l1-1-0.dll;api-ms-win-core-namedpipe-l1-1-0.dll;8e015cdf2561450ed9a0773be1159463163c19eab2b6976155117d16c36519da
|
||||
api-ms-win-core-processenvironment-l1-1-0.dll;api-ms-win-core-processenvironment-l1-1-0.dll;058eb7ce88c22d2ff7d3e61e6593ca4e3d6df449f984bf251d9432665e1517d1
|
||||
api-ms-win-core-processthreads-l1-1-0.dll;api-ms-win-core-processthreads-l1-1-0.dll;a5b733e3dce21ab62bd4010f151b3578c6f1246da4a96d51ac60817865648dd3
|
||||
api-ms-win-core-processthreads-l1-1-1.dll;api-ms-win-core-processthreads-l1-1-1.dll;1ef06c600c451e66e744b2ca356b7f4b7b88ba2f52ec7795858d21525848ac8c
|
||||
api-ms-win-core-profile-l1-1-0.dll;api-ms-win-core-profile-l1-1-0.dll;e63550608dd58040304ea85367e9e0722038ba8e7dc7bf9d91c4d84f0ec65887
|
||||
api-ms-win-core-rtlsupport-l1-1-0.dll;api-ms-win-core-rtlsupport-l1-1-0.dll;91508ab353b90b30ff2551020e9755d7ab0e860308f16c2f6417dfb2e9a75014
|
||||
api-ms-win-core-string-l1-1-0.dll;api-ms-win-core-string-l1-1-0.dll;f3a7a9c98ebe915b1b57c16e27fffd4ddf31a82f0f21c06fe292878e48f5883e
|
||||
api-ms-win-core-synch-l1-1-0.dll;api-ms-win-core-synch-l1-1-0.dll;d6708d1254ed88a948871771d6d1296945e1aa3aeb7e33e16cc378f396c61045
|
||||
api-ms-win-core-synch-l1-2-0.dll;api-ms-win-core-synch-l1-2-0.dll;72c639d1afda32a65143bcbe016fe5d8b46d17924f5f5190eb04efe954c1199a
|
||||
api-ms-win-core-sysinfo-l1-1-0.dll;api-ms-win-core-sysinfo-l1-1-0.dll;76d8e4ed946deefeefa0d0012c276f0b61f3d1c84af00533f4931546cbb2f99e
|
||||
api-ms-win-core-timezone-l1-1-0.dll;api-ms-win-core-timezone-l1-1-0.dll;b0eda99eabd32fefecc478fd9fe7439a3f646a864fdab4ec3c1f18574b5f8b34
|
||||
api-ms-win-core-util-l1-1-0.dll;api-ms-win-core-util-l1-1-0.dll;f28a8fe2cd7e8e00b6d2ec273c16db6e6eea9b6b16f7f69887154b6228af981e
|
||||
api-ms-win-crt-conio-l1-1-0.dll;api-ms-win-crt-conio-l1-1-0.dll;e677497c1baefffb33a17d22a99b76b7fa7ae7a0c84e12fda27d9be5c3d104cf
|
||||
api-ms-win-crt-convert-l1-1-0.dll;api-ms-win-crt-convert-l1-1-0.dll;5cf5bbb861608131b5f560cbf34a3292c80886b7c75357acc779e0bf98e16639
|
||||
api-ms-win-crt-environment-l1-1-0.dll;api-ms-win-crt-environment-l1-1-0.dll;b7ee468f5b6c650dada7db3ad9e115a0e97135b3df095c3220dfd22ba277b607
|
||||
api-ms-win-crt-filesystem-l1-1-0.dll;api-ms-win-crt-filesystem-l1-1-0.dll;7102f8d9d0f3f689129d7fe071b234077fba4dd3687071d1e2aeaa137b123f86
|
||||
api-ms-win-crt-heap-l1-1-0.dll;api-ms-win-crt-heap-l1-1-0.dll;f5183b8d7462c01031992267fe85680ab9c5b279bedc0b25ab219f7c2184766f
|
||||
api-ms-win-crt-locale-l1-1-0.dll;api-ms-win-crt-locale-l1-1-0.dll;2eb96422375f1a7b687115b132a4005d2e7d3d5dc091fb0eb22a6471e712848e
|
||||
api-ms-win-crt-math-l1-1-0.dll;api-ms-win-crt-math-l1-1-0.dll;a768339f0b03674735404248a039ec8591fcba6ff61a3c6812414537badd23b0
|
||||
api-ms-win-crt-multibyte-l1-1-0.dll;api-ms-win-crt-multibyte-l1-1-0.dll;7101b3dff525ea47b7a40dd96544c944ae400447df7a6acd07363b6d7968b889
|
||||
api-ms-win-crt-private-l1-1-0.dll;api-ms-win-crt-private-l1-1-0.dll;785c49fd9f99c6eb636d78887aa186233e9304921dd835dee8f72e2609ff65c4
|
||||
api-ms-win-crt-process-l1-1-0.dll;api-ms-win-crt-process-l1-1-0.dll;3af38920e767bd9ebc08f88eaf2d08c748a267c7ec60eab41c49b3f282a4cf65
|
||||
api-ms-win-crt-runtime-l1-1-0.dll;api-ms-win-crt-runtime-l1-1-0.dll;d899c2f061952b3b97ab9cdbca2450290b0f005909ddd243ed0f4c511d32c198
|
||||
api-ms-win-crt-stdio-l1-1-0.dll;api-ms-win-crt-stdio-l1-1-0.dll;f9d3f380023a4c45e74170fe69b32bca506ee1e1fbe670d965d5b50c616da0cb
|
||||
api-ms-win-crt-string-l1-1-0.dll;api-ms-win-crt-string-l1-1-0.dll;1a916c0db285deb02c0b9df4d08dad5ea95700a6a812ea067bd637a91101a9f6
|
||||
api-ms-win-crt-time-l1-1-0.dll;api-ms-win-crt-time-l1-1-0.dll;b56bc94e8539603dd2f0fea2f25efd17966315067442507db4bffafcbc2955b0
|
||||
api-ms-win-crt-utility-l1-1-0.dll;api-ms-win-crt-utility-l1-1-0.dll;dd14133adf5c534539298422f6c4b52739f80aca8c5a85ca8c966dea9964ceb1
|
||||
avcodec-59.dll;avcodec-59.dll;45e50b64e064a5141a4df2879585157518b16844f6c91eda5586ae46cb943927
|
||||
avformat-59.dll;avformat-59.dll;70b978af3b037aa18d30a1efcd5ce64293258aa2f9ef66995326b155c3e11b14
|
||||
avutil-57.dll;avutil-57.dll;37f34550423d69506f18be89e33de605e0264b91124fb506c060f6ff68b0e3a1
|
||||
cares.dll;cares.dll;5cbb51e0feca7bf313f51c750b962a528e71a82d769871ee73f6cbabc6f8059c
|
||||
concrt140.dll;concrt140.dll;d1a9b1a0ebe71e886b42a59faa67d4bf7646c3f46e0153dd2519b0e77ebbcdc5
|
||||
libcrypto-3-x64.dll;libcrypto-3-x64.dll;dea680dfa433abb5749723ac8a4d91a0bcd1e1dcbb85a6bdd61161d6b9813128
|
||||
libcurl.dll;libcurl.dll;6fc08c9f74cdea3bbd493b294c0348f234caefe8cb6e155eede4ddfb1497e701
|
||||
libssl-3-x64.dll;libssl-3-x64.dll;8595d476b5318a127c8191da929878af83795a666fa901cdcff1770ff1a69c40
|
||||
api-ms-win-core-console-l1-1-0.dll;api-ms-win-core-console-l1-1-0.dll;22b0d0412c274a04d11d7fd3f6545eff245e6f032e21b86d920c2844dd1007c6
|
||||
api-ms-win-core-datetime-l1-1-0.dll;api-ms-win-core-datetime-l1-1-0.dll;631a106755f13a78032d7c17cd19c5185fe89d93fda2ac108c4f53e27dcdecdb
|
||||
api-ms-win-core-debug-l1-1-0.dll;api-ms-win-core-debug-l1-1-0.dll;1ce185afeea0a30a12b496d95df395c18bd0e99570c0ac3126758476d4b6aea0
|
||||
api-ms-win-core-errorhandling-l1-1-0.dll;api-ms-win-core-errorhandling-l1-1-0.dll;cdbc9ee30658188fd9af68ad52b5d8e7f59111191b0681ec2ed9095d9c85ebee
|
||||
api-ms-win-core-file-l1-1-0.dll;api-ms-win-core-file-l1-1-0.dll;f36025fd0715ec893c112f06472072c565385b8c5fa675cce5b4a9158bfb87e9
|
||||
api-ms-win-core-file-l1-2-0.dll;api-ms-win-core-file-l1-2-0.dll;3d95961590fe6da5c569bcb0a54651488e70dd7b15c257e1b9faf8a3cc0e63e4
|
||||
api-ms-win-core-file-l2-1-0.dll;api-ms-win-core-file-l2-1-0.dll;c6515fb573cd8190ebc401aab4646069066205ee9eeca548ae5ddbec3633336b
|
||||
api-ms-win-core-handle-l1-1-0.dll;api-ms-win-core-handle-l1-1-0.dll;523b4c1528aab62c5f8622e4e2c4a4ba0df43114098a05f0c58c69c716c42626
|
||||
api-ms-win-core-heap-l1-1-0.dll;api-ms-win-core-heap-l1-1-0.dll;4fff338c18ab8a1a37d1190e3b9edcca55afa86b0ba0f97d87c4c841e4e29678
|
||||
api-ms-win-core-interlocked-l1-1-0.dll;api-ms-win-core-interlocked-l1-1-0.dll;841aa4632552c47b43d453968da2c8d0861b1eb776d530a4e985d0290516d6c8
|
||||
api-ms-win-core-libraryloader-l1-1-0.dll;api-ms-win-core-libraryloader-l1-1-0.dll;e989c62edade6b3333d798e0481f4c2ec08f7d2a0c47acfcca2a869cd4b68a1f
|
||||
api-ms-win-core-localization-l1-2-0.dll;api-ms-win-core-localization-l1-2-0.dll;945dacfe53f62d83acd0537a6712658558faafb18f68b76b88127db78482fd8f
|
||||
api-ms-win-core-memory-l1-1-0.dll;api-ms-win-core-memory-l1-1-0.dll;a505bdf2e4dfd5120de230fd9d159ef75aa00fb3f98e24d259f5c0a456713c74
|
||||
api-ms-win-core-namedpipe-l1-1-0.dll;api-ms-win-core-namedpipe-l1-1-0.dll;b26de5e517b05e10ee34fdf4996f82c465668670329e7f19d21f39a7e39011e7
|
||||
api-ms-win-core-processenvironment-l1-1-0.dll;api-ms-win-core-processenvironment-l1-1-0.dll;32d11f07156248c7906027e0f17e93e51de848f136e6d3fd0d4f9d1ffb2c70da
|
||||
api-ms-win-core-processthreads-l1-1-0.dll;api-ms-win-core-processthreads-l1-1-0.dll;562e2619e1e685080faf2122c12ae3c35202ce34ce8330d1ff0a3b566095fd38
|
||||
api-ms-win-core-processthreads-l1-1-1.dll;api-ms-win-core-processthreads-l1-1-1.dll;73fabc60a9b24c1eb65ec886a59a190046af5853800572df1d48634417a15729
|
||||
api-ms-win-core-profile-l1-1-0.dll;api-ms-win-core-profile-l1-1-0.dll;2401cc9407ebb1fa60ddf520d422ec1eefec050dd9871554756c869c9b730558
|
||||
api-ms-win-core-rtlsupport-l1-1-0.dll;api-ms-win-core-rtlsupport-l1-1-0.dll;b5a61cd60ec9088ee27bf61d37c55abc9d6db3f722616d74fc191cf671a4902a
|
||||
api-ms-win-core-string-l1-1-0.dll;api-ms-win-core-string-l1-1-0.dll;7e97fbf5cee26ab01227d564f023337736310868c1cf23920e4dceeeb1c11701
|
||||
api-ms-win-core-synch-l1-1-0.dll;api-ms-win-core-synch-l1-1-0.dll;4f47aad2664ed21dd80d30ffd954a34503ffe2493bebb39da058d452212e75af
|
||||
api-ms-win-core-synch-l1-2-0.dll;api-ms-win-core-synch-l1-2-0.dll;a885774d4a5419db2e9f7fbd0ac06f7244e046aa614cd6585ab22fc428f2c7ee
|
||||
api-ms-win-core-sysinfo-l1-1-0.dll;api-ms-win-core-sysinfo-l1-1-0.dll;ac3b86a3e66c5ae2cb30d8a386b0574e6b59fe0f549120c16b7790c3489bc593
|
||||
api-ms-win-core-timezone-l1-1-0.dll;api-ms-win-core-timezone-l1-1-0.dll;003751ed79881bce98017b66206a2ba411321edd61fd51768779f29dfa99968d
|
||||
api-ms-win-core-util-l1-1-0.dll;api-ms-win-core-util-l1-1-0.dll;eb41c514f2660813fa6ac58a28bcd2adfb64552b945dfcad5123f51a1a71f863
|
||||
api-ms-win-crt-conio-l1-1-0.dll;api-ms-win-crt-conio-l1-1-0.dll;e7fc8d3956ce856b1ce0b8d16c10fa4c886a33717a64b818aa6d2492d7492429
|
||||
api-ms-win-crt-convert-l1-1-0.dll;api-ms-win-crt-convert-l1-1-0.dll;4d80b38c49c9e507190b133e97c7b06ac926c5e1d93095bef8e35c51e7be4e3c
|
||||
api-ms-win-crt-environment-l1-1-0.dll;api-ms-win-crt-environment-l1-1-0.dll;65eb6a1276426e0bffc0a7686770cae2fb15a0f819cab4b96003a292c483ec5d
|
||||
api-ms-win-crt-filesystem-l1-1-0.dll;api-ms-win-crt-filesystem-l1-1-0.dll;61424c4c6cf665ef1c6e092a105721813d495ff17d81c809b505acf9ac0c575a
|
||||
api-ms-win-crt-heap-l1-1-0.dll;api-ms-win-crt-heap-l1-1-0.dll;42fed4693a9f2ee8ebb29b34ac92aaef9ff070f609e0cbff74258f65ea53d666
|
||||
api-ms-win-crt-locale-l1-1-0.dll;api-ms-win-crt-locale-l1-1-0.dll;f2d099d580c733d3132ac3cd0179c7bfa0f1ed8f7bd063e411cd57e920510488
|
||||
api-ms-win-crt-math-l1-1-0.dll;api-ms-win-crt-math-l1-1-0.dll;8483828a6781dc3cc4a121e2a90f54abb6f6c42680a0634e02db8b736d16f877
|
||||
api-ms-win-crt-multibyte-l1-1-0.dll;api-ms-win-crt-multibyte-l1-1-0.dll;63c233965965c6eab235c0e1e7530788fee44d5cab910a2cd22d325334a3dce2
|
||||
api-ms-win-crt-private-l1-1-0.dll;api-ms-win-crt-private-l1-1-0.dll;65e8380924c6b54147185cfd84deb0795c617b8c316d3767daa616f9fd88d6c0
|
||||
api-ms-win-crt-process-l1-1-0.dll;api-ms-win-crt-process-l1-1-0.dll;f426c73f187c4c3c6759514c11f752a1f8411a1f4392bbee984652e62d2e7296
|
||||
api-ms-win-crt-runtime-l1-1-0.dll;api-ms-win-crt-runtime-l1-1-0.dll;21c3d46f74f4249c81d723373da639ac2fb2733a626ec11310df49874663d2bc
|
||||
api-ms-win-crt-stdio-l1-1-0.dll;api-ms-win-crt-stdio-l1-1-0.dll;e4a6bd5d65d39da4424ab7828959cfeb7c362e29008bc63ecf16fb3b20001807
|
||||
api-ms-win-crt-string-l1-1-0.dll;api-ms-win-crt-string-l1-1-0.dll;a1cf3656daa57afb840714f891e7f072ca56bf5838f525d4394c362ef5c8ed8f
|
||||
api-ms-win-crt-time-l1-1-0.dll;api-ms-win-crt-time-l1-1-0.dll;fc27f6061faf91d696a2b3685a3bfac4de49fbf78d578b9970e1ed21f683b209
|
||||
api-ms-win-crt-utility-l1-1-0.dll;api-ms-win-crt-utility-l1-1-0.dll;788611c05ef16759ac57df231b25b413be33fccabbeb446caaf4b5cbedd8e1dc
|
||||
avcodec-59.dll;avcodec-59.dll;512eccc75c494b7733c619bfa20aa7b2a5dda67d0be6e70dce7ef8ae97f313d8
|
||||
avformat-59.dll;avformat-59.dll;dc8b124d09871272470ef66cf7cce885b00af05c8512ce060271ba0f8b55df64
|
||||
avutil-57.dll;avutil-57.dll;00096750c7892e50c38981977354593efbd77d540935eb7a618778be072478d1
|
||||
concrt140.dll;concrt140.dll;e2e4609c569c69f7b1686f6d0e81ce62187ac5df05e0247954500053b3c3de3f
|
||||
MEGA Website.url;MEGA Website.url;7b5f1278de755dde65017404b662b6ab97fa7328974eec3872ce571f7e462dac
|
||||
mega-attr.bat;mega-attr.bat;89a1b21160a0e3890c45596d7832ff37474a2c3200423f23adee11ff676b295b
|
||||
mega-backup.bat;mega-backup.bat;167d72cbaa49b8c6c54d57ab44ad9e907f4bf9551460574f4231a9dd956c4c32
|
||||
mega-cancel.bat;mega-cancel.bat;aab45aa9eac5e0b9865f44a234f6c5cddbc3b2fcb14aa4fee101cbcef2ba37d8
|
||||
mega-cat.bat;mega-cat.bat;03d39664173b9baf2ae530b457510c4ee915e9060be46063511ed903d3afa265
|
||||
mega-cd.bat;mega-cd.bat;d3b331e8568b4aa59710b2a731541d625138fa0d37aa26fda679a6b8713827ad
|
||||
mega-confirm.bat;mega-confirm.bat;e45eeac40ace7b050f9747d79954c4b7bb82792b727a691799694f109938b338
|
||||
mega-confirmcancel.bat;mega-confirmcancel.bat;5c3128dfd3f4d604afa6e602aca4a346d758d889400eb74584c88f1e40fe9bac
|
||||
mega-cp.bat;mega-cp.bat;f5cc9ce16100354271c7b385377053076c486cba84f21151a65721d24caecf09
|
||||
mega-debug.bat;mega-debug.bat;df39fd5831826cb988eb5bfdfb4a98ca75eda8c03f6acdc286a7741448849c9b
|
||||
mega-deleteversions.bat;mega-deleteversions.bat;ac1d8b0b8458ec134d5c85fa863c3d8ed016e35454dedae79698ad0818919b7f
|
||||
mega-df.bat;mega-df.bat;b47b85efda1561b559c7d1a81e0d4b49958607f6e4933bf46f97f43c917f69a7
|
||||
mega-du.bat;mega-du.bat;fbb81f40c843fc33e57a23db01ee0f206c99c6ed75520a5594e0b3d525725215
|
||||
mega-errorcode.bat;mega-errorcode.bat;f5793c201602a3619cac14d31d0356d058d8128b13027b1e64073dd029193614
|
||||
mega-exclude.bat;mega-exclude.bat;a347a180847fa3dca00bc28dd1321f5b332fdf574c73ea2b30ef3fab63b2380b
|
||||
mega-export.bat;mega-export.bat;30fe5d62f0f47418dc83e03bc80977426010c8edcf01e4e7db820965e2781442
|
||||
mega-find.bat;mega-find.bat;0e683610f7369c674cebc1ecf8d6e030f0433226887b902e74fe1e174c23a6a7
|
||||
mega-ftp.bat;mega-ftp.bat;df52291409a56fd512402124a94b51dda27c0b5caf2c93d36932e6ce2268bb3c
|
||||
mega-get.bat;mega-get.bat;b309f0785461dbe35a63b0a674cc70381ef7f87720d2aa884a8dbc8ae3c2c42e
|
||||
mega-graphics.bat;mega-graphics.bat;d692deb721e9ac81db35e26542abbc64f26aebb0f232dab53d390de7a03461da
|
||||
mega-help.bat;mega-help.bat;8558ee2389b4493ff9b3d9bcab252564a817284583d651649ce79d7091ea45d3
|
||||
mega-https.bat;mega-https.bat;91c60eb7b5f95951e96a2437ee51dbae7821377e8e4864279b41c53791481b6a
|
||||
mega-import.bat;mega-import.bat;90eff64c5a742c7d96d87648a15bcb33145ebebab593f0c0161dae22880b90a0
|
||||
mega-invite.bat;mega-invite.bat;7d9713740d78deeabff15b6080a387460a315a680777d4f1e04c498f1b708826
|
||||
mega-ipc.bat;mega-ipc.bat;04fe985dcc18c3ab8dc4ecf5ebf61ed9dd4bafdcd0937c8d10235c98b2f4a9ae
|
||||
mega-killsession.bat;mega-killsession.bat;7b2aeb01bd57aa53f1d615294fa425aaa3d82f43474ed529d9a33efb873a183e
|
||||
mega-lcd.bat;mega-lcd.bat;776a5e227d275f6a777ea5c7886e69efe5b9ee9da3fd79700965f4809cde5d27
|
||||
mega-log.bat;mega-log.bat;4e703495f3616dd936afdfa2c32958189ae5e90328d9389b86e49a50654e6393
|
||||
mega-login.bat;mega-login.bat;9bc358f934bfbeb12347083aef6b7a6efe26846b83ce0e653a4b89c64ba89073
|
||||
mega-logout.bat;mega-logout.bat;ab36f1dcf6cfd93b95bf5394b1ef22deff505df685c9b0a36d25fa9c94f4b548
|
||||
mega-lpwd.bat;mega-lpwd.bat;6364d746c3f1f0329fd67cec0f6a1f09ae3e521f3ef37b0ab728009cf55c4a5c
|
||||
mega-ls.bat;mega-ls.bat;d57684855baf42e911b235c7ffb5a106aac875461d5faeb059c4d941e7b5cfd6
|
||||
mega-mediainfo.bat;mega-mediainfo.bat;59606376cabc50a19af3732cddbbcda40c59e0c85aa6bc0320420a6a19abca49
|
||||
mega-mkdir.bat;mega-mkdir.bat;690c56c5ebd58d596632a4ff28596df8aa478309fc979b9eb8b07fb89db4d944
|
||||
mega-mount.bat;mega-mount.bat;6f0a3e80dcde8611beb4ac1d9e575601997e58b9a4a17054c5cb4eedf6f8062f
|
||||
mega-mv.bat;mega-mv.bat;4e694c7eb85dcf55d7642f3504a5d63493e46ebd711735c57a45569ef2a7b88a
|
||||
mega-passwd.bat;mega-passwd.bat;0f5947f5dbd2543c49853451d6d0deb64b04796e4c61327a1b5aa1c295b2a861
|
||||
mega-preview.bat;mega-preview.bat;caed90cc51561edd29eb5e842c266add1bb477261cf5254a0e2c218ed0737b93
|
||||
mega-proxy.bat;mega-proxy.bat;a22417b2eccc3ab5a32aecee8bd004cbbef73fe80d58119d23223163985d1f6b
|
||||
mega-put.bat;mega-put.bat;a20fb6cf0d1e9c86de68b8665fbbf0974b04c69beccd41d7123f6b3004221beb
|
||||
mega-pwd.bat;mega-pwd.bat;38744af426f8304c5ee9c2857291225726bffe2788870f2cb9e6a3b8836297e6
|
||||
mega-quit.bat;mega-quit.bat;44026a4ab85bb59d02241e400848ac77be17c60fc86a0d07055e8ed8fe490ba2
|
||||
mega-reload.bat;mega-reload.bat;4a0231a6f5ccb7f5908a9d7f12987efa1b45ff2148214360b4a205f15e77075f
|
||||
mega-rm.bat;mega-rm.bat;1e55e2b5357bce9f5fa54d2a12801dfba6c70262a6ddceae4b227a014db0aa92
|
||||
mega-session.bat;mega-session.bat;20c963d0749b58afccdb7d45ff36451015689bec1c035ee7bf809c7ee5b6b483
|
||||
mega-share.bat;mega-share.bat;66fc8fa5564448729b569b843c158d933d8774666651f98cfbd757ea9d721d94
|
||||
mega-showpcr.bat;mega-showpcr.bat;e5d799f4ebb0f0a02c6c7efb0fd946a9a9f7b8283c5ccb697132974711060ccf
|
||||
mega-signup.bat;mega-signup.bat;f64064f35b2c464cb20fdcb70a8aa73856b6a8af65acd5be8d58b79df9889c1c
|
||||
mega-speedlimit.bat;mega-speedlimit.bat;c6f2a4b09f9249c4e77ad03cc0e15940f080c125187137bc88a7d2adf2a4916f
|
||||
mega-sync.bat;mega-sync.bat;c39719e5e79043b28a6368cdc942032bf5b2ab18fff2f66bd726058e9e921ef7
|
||||
mega-thumbnail.bat;mega-thumbnail.bat;58574690db6cfff0ffa7864a0a13265ae1bd37d5fc3b0d9e0c88a1f7d69c193d
|
||||
mega-transfers.bat;mega-transfers.bat;6f35a34033499938700e42f4123399f711003d2dab83ed50e69f7df5ecf976d8
|
||||
mega-tree.bat;mega-tree.bat;92a11c9ee2af4ffb55d05210813c7ff309f90274a1d211018acc2643367b2534
|
||||
mega-userattr.bat;mega-userattr.bat;a48dfc0e20bd69e3774d74860f2a74691addf9fbaae42c71450561a4d526f92a
|
||||
mega-users.bat;mega-users.bat;24d85b5700f05d7b638d294c87e8b8809df80f0611c63ee818f60ed487f1b4bc
|
||||
mega-version.bat;mega-version.bat;b69c2f0acc58d45ae4dae502892af08ce9abaa0de2433573a07e9a06fae3a255
|
||||
mega-webdav.bat;mega-webdav.bat;233717710c3ac45906e2cbd110a167d7779bd6697a508013c5b6559bbce97815
|
||||
mega-whoami.bat;mega-whoami.bat;b6ff6c05c78901dfc6291751bab1ae93a0ac836d8d506e57d2bb6fb927facc7d
|
||||
MEGAclient.exe;MEGAclient.exe;216b4f04c38d81371ecc9f0344c13133bfa43c2d643c37fadfa44de1bda35df0
|
||||
MEGAcmdServer.exe;MEGAcmdServer.exe;05241b87973924df675f2ae9560de1924e4a8f64abeca49c286b5c191fe155fd
|
||||
MEGAcmdShell.exe;MEGAcmdShell.exe;58438c8b77ce5f41866f85962c1b1d88d52723db895b1e39780760d3c3b032ad
|
||||
MEGAcmdUpdater.exe;MEGAcmdUpdater.exe;5ba09c067584bc4f32e58afbe1f4d5b2b1a023478af318b55c1e924f725b44d0
|
||||
msvcp140.dll;msvcp140.dll;e0a22a594e148fa55ceef3e49969bfa77011a801267a0bd7805b681b593c9d0b
|
||||
msvcp140_1.dll;msvcp140_1.dll;768e0829decea713afb35a7de07e276f051581c8ff2c17e1bae9b07dd1445dd0
|
||||
msvcp140_2.dll;msvcp140_2.dll;5c12eaef6db18b168f712bff9b55793e0effddf15b89552e7f5ca4f8f1887b9b
|
||||
msvcp140_atomic_wait.dll;msvcp140_atomic_wait.dll;0193cdcff562f12218ecab5841fd6bbc4d24295cd8e4dcae960e2fb47cceb662
|
||||
msvcp140_codecvt_ids.dll;msvcp140_codecvt_ids.dll;9c6c0d8fa51ecca5e274295cbd72d45be474f3c6ce1070ec5e90f70242ae7185
|
||||
swresample-4.dll;swresample-4.dll;6df991ae9d55d6bf107bca6ec1156ce6c53cc0feaa5052a3fb2e6cb5819cda3f
|
||||
swscale-6.dll;swscale-6.dll;94ffb8148bbccbd3c3382727775bb5ee70030d88ae940fa3ee00a00b9c66d4b7
|
||||
ucrtbase.dll;ucrtbase.dll;6238cbfe9f57c142b75e153c399c478d492252fda8cb40ee539c2dcb0f2eb232
|
||||
uninst.exe;uninst.exe;85da75f6601212bbd48fb9ae624284281dbe57fe570c58509c41e2f31f0b7c8a
|
||||
vccorlib140.dll;vccorlib140.dll;3e194d5ab03fdb1e97b0bae61070994013487c567f82c9338e7adc202f7d7d67
|
||||
vcomp140.dll;vcomp140.dll;d5aa2fc36a84144ca2a420b797f4e645fca530e0ff7bd01383010d5a81d194ef
|
||||
vcruntime140.dll;vcruntime140.dll;c179d8914ba8e57b2f8f4d6c101c2c550c7c6712a7f0f9920a97db340f9d9574
|
||||
vcruntime140_1.dll;vcruntime140_1.dll;7cf38d20d00b6640d510eab70171e1c6f8fa2e42040832e17c7433ab61d94a8e
|
||||
mega-attr.bat;mega-attr.bat;7a5b5b221bc921a5eb98633f519b2141bd0daede6eae40cba113333992967de7
|
||||
mega-backup.bat;mega-backup.bat;d0df6b91202750d3b13071e3e231c1954ff032c1340cf051e968a91d74dbb80a
|
||||
mega-cancel.bat;mega-cancel.bat;fa68a5dd1e0051425c3e8c41f5695810eadc2058397046b1848a0599f47c9953
|
||||
mega-cat.bat;mega-cat.bat;6225ce58605e8795fe2e48220607ac193744cb313cd181fb6e90a190484a9bbf
|
||||
mega-cd.bat;mega-cd.bat;c102ccb99cf3e83b1eb0886b15ed5b3e5deff7b2fedfba9408558cd9aa8f1e18
|
||||
mega-confirm.bat;mega-confirm.bat;7ce93a6a402b631760477079861796cf1dd25517866cbd2d5be27635d7783fee
|
||||
mega-confirmcancel.bat;mega-confirmcancel.bat;dde5415005ad473cc98ef9b9b28f210350bb8d4efca6f4af8eb63d394efdf0e0
|
||||
mega-cp.bat;mega-cp.bat;36292230fd45e595e98667653646ee1baaa87bc4e9b22b566ec5bc0cc7347821
|
||||
mega-debug.bat;mega-debug.bat;423e02ee02c0d24e2aec7c02ebc295954d2d2ab3166f1174ef96fc5111179d0d
|
||||
mega-deleteversions.bat;mega-deleteversions.bat;c67afe7a90012f5885348d6ca6bb4abbf27f9b891ec61204fe53763281505c13
|
||||
mega-df.bat;mega-df.bat;b98a9f278dbc417aa51c4eb34af5cfe076be0e5700dbae1558b7aa381a926881
|
||||
mega-du.bat;mega-du.bat;1e91bfb1ad81e12c1068f42b612e95c986ff6807919195188f3a4cacf692183f
|
||||
mega-errorcode.bat;mega-errorcode.bat;d431d2d116ccfd9f01d4f54f9580fa89615848aa6814b7d8f2da347b3127050a
|
||||
mega-exclude.bat;mega-exclude.bat;ab9f76a28ba0a5efb0eb2e240e599409d6d6380a18dd680f93bc3d705409b299
|
||||
mega-export.bat;mega-export.bat;42dd5f70a8f78854e01b175fa7672b2a0d894da716a910807e2373e2dd983947
|
||||
mega-find.bat;mega-find.bat;08147ae1b71d69a09f48ea145f183fba304a2884e5b27953fc89943ba41df69c
|
||||
mega-ftp.bat;mega-ftp.bat;8c049a43a7f13856bf8f6667beb6a5496a4b0e111a5a3afb40b7c1f36b97e456
|
||||
mega-get.bat;mega-get.bat;2e40e197c0fa5b74cb164f2b696cc064de1b356c42450c1028e77568efdc1eff
|
||||
mega-graphics.bat;mega-graphics.bat;3c91e02f744d7b84cb76577bf354a54adce1562e7bfcea98588a3204a82ed396
|
||||
mega-help.bat;mega-help.bat;cef87d1319c235952d238bc5111935bc8312bb1cfc17d61e522151077857715e
|
||||
mega-https.bat;mega-https.bat;1cf2a5175ee289514f70c8f956145725dd501c3fd9860413bc77abc93022b57d
|
||||
mega-import.bat;mega-import.bat;3343902b8d3cbc6f62529d6920178f0e6042472f2772a08df15ed73121d04619
|
||||
mega-invite.bat;mega-invite.bat;20be9c6d549733269ac7a9ce7ab3928c29134625b1e84eb54e52cda192774a55
|
||||
mega-ipc.bat;mega-ipc.bat;7b29de9117b7b48d9e57ac6a0df6e7b229905ab3d5858daccb354116b0039ba3
|
||||
mega-killsession.bat;mega-killsession.bat;9f83aada9c370952e9b49a9c41eb7d98f30e5b024d070e371244ee6b76f64c96
|
||||
mega-lcd.bat;mega-lcd.bat;de56d34a0e884ce8691ebc86ac55832a5d8a22eb5eb5fdbe345d69301500f746
|
||||
mega-log.bat;mega-log.bat;ebbb6703ef76be60e030058b2ca56934fa573d9891096bfb43be5b7adcbc14cc
|
||||
mega-login.bat;mega-login.bat;af44e84d703d44e46e8aba3b9e6bc8d0d4304d143493fd14eaff70742013ab81
|
||||
mega-logout.bat;mega-logout.bat;b10da32e4da3c750ce8874222b7348a58c9c61f7d2ec11f73c91fc7d31722a02
|
||||
mega-lpwd.bat;mega-lpwd.bat;eefe4d679a99d507cf49d434746b22bc3d312802b9a4ac48824e0d363b8c1b12
|
||||
mega-ls.bat;mega-ls.bat;cfc0d9ce93645ae56a5e9e27a6d59090b615027a4678e4b8ab57f86b2c49d5ad
|
||||
mega-mediainfo.bat;mega-mediainfo.bat;7364d4c609c2030136837f70765586494d6951058530d828b75e57eedcac2626
|
||||
mega-mkdir.bat;mega-mkdir.bat;1535df364439afcf86860495c71eccb1b40cc202f30d3180a30b389298ffbbd9
|
||||
mega-mount.bat;mega-mount.bat;22b5c4a02c0df84d025b6315b8f8098b0be250b1237c8aad89f07c3b707073a7
|
||||
mega-mv.bat;mega-mv.bat;bd253db0f09da734afc3c6d31058fb20551fbc18197e85e9bdf52d62e00fdfaa
|
||||
mega-passwd.bat;mega-passwd.bat;3aa3bedfc45eaf3f1e1609fe96b028821a79d1915a5b930609a8ca2b3730c2dc
|
||||
mega-preview.bat;mega-preview.bat;54a263b9fe0ac933aa77b73a5219bb0fa813ea0501ba331dbfb7b16c61ea5cef
|
||||
mega-proxy.bat;mega-proxy.bat;f323cf922dee4aac447b504399c367ed45e752a6cbe0adec5c68a675611118b6
|
||||
mega-put.bat;mega-put.bat;ca3e2c5aa77a6b7b4a9a4d7699416e714a9aa027c7d68fda47023405716766f8
|
||||
mega-pwd.bat;mega-pwd.bat;cdf78fb7b00f2c50db3672a02923bfd05d380741b582570db194ccf7d4b22033
|
||||
mega-quit.bat;mega-quit.bat;bb82d8e26f81007f19683422bc021791d1ce74fd5f11f3c1c29307a6b98752f0
|
||||
mega-reload.bat;mega-reload.bat;9e0d368d6f7863944711697cf54e1201c405ab37b8f1ebbf520ad15d0c96f4fa
|
||||
mega-rm.bat;mega-rm.bat;7e503e07f13199e35faad58590b56938ab53b14745afa5f596f31f8921c72859
|
||||
mega-session.bat;mega-session.bat;91a24d34d4752deb4a76215f564f202edb9eaba2285b5f26f3f9dc40aad7c702
|
||||
mega-share.bat;mega-share.bat;270c97a6e71b03a67297a534dc1d7299fe801f9c654f68e0fbe0276a65921054
|
||||
mega-showpcr.bat;mega-showpcr.bat;39a7f816821855676392dcb437378bfbfa61a595748af6a4b82e43cd9704955d
|
||||
mega-signup.bat;mega-signup.bat;6e8c13eb91c9d38d2ce48c75c569bd151d3f3c7641e3b2b3ed04994ae3e4a33f
|
||||
mega-speedlimit.bat;mega-speedlimit.bat;c037351ecf3cd9fae0b1416b60cd651fe317fc57fd06f996c9b7f6450c9a07b3
|
||||
mega-sync.bat;mega-sync.bat;62a2334922a0ea0867b2a71a6900e44975b03612dbeeb181aca6d44d48222922
|
||||
mega-thumbnail.bat;mega-thumbnail.bat;8f7b42ac9e6358534bed0355e70b6f007070006f38328e35c860ff502d4768b4
|
||||
mega-transfers.bat;mega-transfers.bat;38b4bb079557909927336aeddda2c8f937b5d089b2bfe224cb0b895250b85d5e
|
||||
mega-tree.bat;mega-tree.bat;0f03785c46a12893100f360da48fb473de9011bffd9562a327aa76626078d263
|
||||
mega-userattr.bat;mega-userattr.bat;28cede25ba267f57d1c60b531764f1290a8fc78b64b1bcc307b0e23f5fea1bd2
|
||||
mega-users.bat;mega-users.bat;6f4499de547c0d5c5bcba21d5c226bb83a6f01909d9fc4cd1c578c4bdc8e6955
|
||||
mega-version.bat;mega-version.bat;2f1794963704f4dc65e23155ef1fb27788ea48e6099479c4809093f7281c28fc
|
||||
mega-webdav.bat;mega-webdav.bat;97c8f94a273c7d7d9e5b6b1929a8e227c3a15d6c09c8124f12d7fe3723a7beae
|
||||
mega-whoami.bat;mega-whoami.bat;48f9d5104bb5364f6831b11d9847871c528ad656655c3fa49ce9be70e932767f
|
||||
MEGAclient.exe;MEGAclient.exe;5401d804c6873201476666f9190ce6a1e1f4b94b7988201cc632ac4a29320ccc
|
||||
MEGAcmdServer.exe;MEGAcmdServer.exe;46ee3cbb168bacfbc1ac7f6b35b3a34416bee9c85a66b14fe236c890088d5a46
|
||||
MEGAcmdShell.exe;MEGAcmdShell.exe;2bcb1f39d25151ae9c1565120973538c691fd352db1977b2be0faae6b7f88ebe
|
||||
MEGAcmdUpdater.exe;MEGAcmdUpdater.exe;475300b56fe62db463baf68e91267100fa949a1bfd995785f4e1c79179ff3125
|
||||
msvcp140.dll;msvcp140.dll;9057d39b36b6c7d054865ee2bf9cde7a490fe3b01ec4e82514687e24f576269f
|
||||
msvcp140_1.dll;msvcp140_1.dll;a65249861238e1c18b84ae5d112617c438d83a76b67eddc170ad82dbc2338665
|
||||
msvcp140_2.dll;msvcp140_2.dll;89e2e9a163165e20c540f9adea081e927ddfe4a556547b0f45f11586d4cce165
|
||||
msvcp140_atomic_wait.dll;msvcp140_atomic_wait.dll;fbf41e4b53f51bbf73fee37b6120103fea6b7d5ae29916f8ef50c50cfdedeead
|
||||
msvcp140_codecvt_ids.dll;msvcp140_codecvt_ids.dll;0e1d3d76e899a89fb3893fb13abae232ff62ad4f573214dd2f02b8398166bcc6
|
||||
swresample-4.dll;swresample-4.dll;ad2df528f8458fcec995f3d7afdd3161d6dea16cdd92694f12888f22994fc635
|
||||
swscale-6.dll;swscale-6.dll;1cdf13dd9ba8f50da5c228ad6f84f2c7d068eeffcc57bc429ff1d23b1309e06a
|
||||
ucrtbase.dll;ucrtbase.dll;91d027417ff2301b7135e864a5df6693488f8412ff87040f4897e0e03bc2577b
|
||||
uninst.exe;uninst.exe;581003e0efbef54d67066e048723d058dfa9717b22538cc8852457aa09720eed
|
||||
vccorlib140.dll;vccorlib140.dll;8903b5d88968791d2a93648a54a1ac3d1c708c579a72311ffe194f6d66903043
|
||||
vcomp140.dll;vcomp140.dll;036b9b3f7ece8dfd48aeccd77113721c5305043aaa9c64d1e72812252727aa7c
|
||||
vcruntime140.dll;vcruntime140.dll;da72e6677bd1bcd01c453c1998aaa19aeaf6659f4774cf6848409da8232a95b2
|
||||
vcruntime140_1.dll;vcruntime140_1.dll;26e470b29bed3d873e0c328186e53f95e9edbfe0b0fd0cda44743a0b1a04a828
|
||||
|
@ -4,6 +4,7 @@ pipeline {
|
||||
options {
|
||||
buildDiscarder(logRotator(numToKeepStr: '135', daysToKeepStr: '21'))
|
||||
gitLabConnection('GitLabConnectionJenkins')
|
||||
timestamps() // Add timestamps to all console output
|
||||
}
|
||||
|
||||
stages {
|
||||
@ -42,7 +43,7 @@ pipeline {
|
||||
axes {
|
||||
axis {
|
||||
name 'SANITIZERS'
|
||||
values 'ubsan', 'asan', 'tsan'
|
||||
values 'baseline', 'ubsan', 'asan', 'tsan'
|
||||
}
|
||||
axis {
|
||||
name 'BUILD_SYSTEM'
|
||||
@ -73,9 +74,9 @@ pipeline {
|
||||
timeout(time: 10, unit: 'MINUTES')
|
||||
}
|
||||
environment {
|
||||
ASAN_OPTIONS="atexit=1,print_stats=1,log_path=${megacmd_sources_workspace}/test-dir-${SANITIZERS}/results/mega-cmd-tests-unit-report"
|
||||
TSAN_OPTIONS="log_path=${megacmd_sources_workspace}/test-dir-${SANITIZERS}/results/mega-cmd-tests-unit-report"
|
||||
UBSAN_OPTIONS="log_path=${megacmd_sources_workspace}/test-dir-${SANITIZERS}/results/mega-cmd-tests-unit-report"
|
||||
ASAN_OPTIONS="print_stats=1,log_path=${megacmd_sources_workspace}/test-dir-${SANITIZERS}/results/unit-asan-report.log"
|
||||
TSAN_OPTIONS="log_path=${megacmd_sources_workspace}/test-dir-${SANITIZERS}/results/unit-tsan-report.log"
|
||||
UBSAN_OPTIONS="log_path=${megacmd_sources_workspace}/test-dir-${SANITIZERS}/results/unit-ubsan-report.log"
|
||||
HOME="${megacmd_sources_workspace}/test-dir-${SANITIZERS}"
|
||||
}
|
||||
steps {
|
||||
@ -90,6 +91,7 @@ pipeline {
|
||||
post {
|
||||
always {
|
||||
archiveArtifacts artifacts: "test-dir-${SANITIZERS}/.megaCmd/megacmdserver.log*", allowEmptyArchive: true
|
||||
archiveArtifacts artifacts: "test-dir-${SANITIZERS}/results/unit-*-report.log.*", allowEmptyArchive: true
|
||||
junit "test-dir-${SANITIZERS}/results/mega-cmd-tests-unit.xml"
|
||||
}
|
||||
}
|
||||
@ -108,9 +110,9 @@ pipeline {
|
||||
environment {
|
||||
MEGACMD_TEST_USER=''
|
||||
MEGACMD_TEST_PASS=credentials('MEGACMD_TESTS_PASSWORD')
|
||||
ASAN_OPTIONS="atexit=1,print_stats=1,log_path=${megacmd_sources_workspace}/test-dir-${SANITIZERS}/results/mega-cmd-tests-integration-report"
|
||||
TSAN_OPTIONS="log_path=${megacmd_sources_workspace}/test-dir-${SANITIZERS}/results/mega-cmd-tests-integration-report"
|
||||
UBSAN_OPTIONS="log_path=${megacmd_sources_workspace}/test-dir-${SANITIZERS}/results/mega-cmd-tests-integration-report"
|
||||
ASAN_OPTIONS="print_stats=1,log_path=${megacmd_sources_workspace}/test-dir-${SANITIZERS}/results/integration-asan-report.log"
|
||||
TSAN_OPTIONS="log_path=${megacmd_sources_workspace}/test-dir-${SANITIZERS}/results/integration-tsan-report.log"
|
||||
UBSAN_OPTIONS="log_path=${megacmd_sources_workspace}/test-dir-${SANITIZERS}/results/integration-ubsan-report.log"
|
||||
HOME="${megacmd_sources_workspace}/test-dir-${SANITIZERS}"
|
||||
}
|
||||
steps {
|
||||
@ -127,6 +129,7 @@ pipeline {
|
||||
post {
|
||||
always {
|
||||
archiveArtifacts "test-dir-${SANITIZERS}/.megaCmd/megacmdserver.log*"
|
||||
archiveArtifacts artifacts: "test-dir-${SANITIZERS}/results/integration-*-report.log.*", allowEmptyArchive: true
|
||||
junit "test-dir-${SANITIZERS}/results/mega-cmd-tests-integration.xml"
|
||||
}
|
||||
}
|
||||
@ -140,14 +143,18 @@ pipeline {
|
||||
}
|
||||
}
|
||||
options {
|
||||
timeout(time: 1, unit: 'HOURS')
|
||||
timeout(time: 2, unit: 'HOURS')
|
||||
}
|
||||
environment {
|
||||
MEGA_EMAILS=''
|
||||
MEGA_PWD=credentials('MEGACMD_TESTS_PASSWORD')
|
||||
MEGA_PWD_AUX=credentials('MEGACMD_TESTS_PASSWORD')
|
||||
ASAN_OPTIONS="print_stats=1,log_path=${megacmd_sources_workspace}/pytest-dir-${SANITIZERS}/results/pyserver-asan-report.log"
|
||||
TSAN_OPTIONS="log_path=${megacmd_sources_workspace}/pytest-dir-${SANITIZERS}/results/pyserver-tsan-report.log"
|
||||
UBSAN_OPTIONS="log_path=${megacmd_sources_workspace}/pytest-dir-${SANITIZERS}/results/pyserver-ubsan-report.log"
|
||||
HOME="${megacmd_sources_workspace}/pytest-dir-${SANITIZERS}"
|
||||
YES_I_KNOW_THIS_WILL_CLEAR_MY_MEGA_ACCOUNT=1
|
||||
VERBOSE=1
|
||||
}
|
||||
steps {
|
||||
dir("pytest-dir-${SANITIZERS}") {
|
||||
@ -158,20 +165,39 @@ pipeline {
|
||||
script {
|
||||
// Skipping the 'serving' test until CMD-389 is resolved
|
||||
for (test in ['misc', 'put', 'rm', 'find', 'get']) {
|
||||
stage("MEGAcmd Python ${test} test") {
|
||||
withEnv([
|
||||
"MEGA_EMAIL=${env.MEGA_EMAILS0}",
|
||||
"MEGA_EMAIL_AUX=${env.MEGA_EMAILS1}",
|
||||
"ASAN_OPTIONS=atexit=1,print_stats=1,log_path=${megacmd_sources_workspace}/pytest-dir-${SANITIZERS}/${test}-results/mega-cmd-tests-python-report",
|
||||
"TSAN_OPTIONS=log_path=${megacmd_sources_workspace}/pytest-dir-${SANITIZERS}/${test}-results/mega-cmd-tests-python-report",
|
||||
"UBSAN_OPTIONS=log_path=${megacmd_sources_workspace}/pytest-dir-${SANITIZERS}/${test}-results/mega-cmd-tests-python-report",
|
||||
"OUT_DIR_JUNIT_XML=${megacmd_sources_workspace}/pytest-dir-${SANITIZERS}/${test}-results"
|
||||
]) {
|
||||
dir("pytest-dir-${SANITIZERS}/working-dir") {
|
||||
sh "/usr/local/bin/megacmd_${test}_test.py"
|
||||
deleteDir()
|
||||
for (cmdshell in ['', 'cmdshell-']) {
|
||||
def testDir = "pytest-dir-${SANITIZERS}/${cmdshell}${test}-results"
|
||||
def asanOptions = "print_stats=1,log_path=${megacmd_sources_workspace}/${testDir}/py-asan-report.log"
|
||||
def tsanOptions = "log_path=${megacmd_sources_workspace}/${testDir}/py-tsan-report.log"
|
||||
def ubsanOptions = "log_path=${megacmd_sources_workspace}/${testDir}/py-ubsan-report.log"
|
||||
stage("MEGAcmd Python ${cmdshell}${test} test") {
|
||||
withEnv([
|
||||
"MEGA_EMAIL=${env.MEGA_EMAILS0}",
|
||||
"MEGA_EMAIL_AUX=${env.MEGA_EMAILS1}",
|
||||
"ASAN_OPTIONS=${asanOptions}",
|
||||
"TSAN_OPTIONS=${tsanOptions}",
|
||||
"UBSAN_OPTIONS=${ubsanOptions}",
|
||||
"OUT_DIR_JUNIT_XML=${megacmd_sources_workspace}/${testDir}"
|
||||
]) {
|
||||
def envStr = ''
|
||||
if (cmdshell != '') {
|
||||
envStr = "MEGACMDSHELL=/usr/bin/mega-cmd LSAN_OPTIONS=suppressions=${megacmd_sources_workspace}/${testDir}/suppressed_asan.txt "
|
||||
}
|
||||
try {
|
||||
dir("pytest-dir-${SANITIZERS}/working-dir") {
|
||||
// CMD-578 Fix readline leak instead of suppressing it
|
||||
writeFile file: "${megacmd_sources_workspace}/${testDir}/suppressed_asan.txt", text: 'leak:expand_prompt'
|
||||
|
||||
sh "/usr/local/bin/megacmd_${test}_test.py"
|
||||
}
|
||||
junit "${testDir}/TEST-*.xml"
|
||||
} finally {
|
||||
archiveArtifacts artifacts: "${testDir}/py-*-report.log.*", allowEmptyArchive: true
|
||||
dir("pytest-dir-${SANITIZERS}/working-dir") {
|
||||
deleteDir()
|
||||
}
|
||||
}
|
||||
}
|
||||
junit "pytest-dir-${SANITIZERS}/${test}-results/TEST-*.xml"
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -183,6 +209,7 @@ pipeline {
|
||||
sh "/usr/bin/mega-exec logout || true"
|
||||
sh "/usr/bin/mega-exec quit || true"
|
||||
archiveArtifacts "pytest-dir-${SANITIZERS}/.megaCmd/megacmdserver.log*"
|
||||
archiveArtifacts artifacts: "pytest-dir-${SANITIZERS}/results/pyserver-*-report.log.*", allowEmptyArchive: true
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -195,6 +222,7 @@ pipeline {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
post {
|
||||
always {
|
||||
script {
|
||||
|
@ -10,6 +10,7 @@ pipeline {
|
||||
booleanParam(name: 'IS_RELEASE_CANDIDATE', defaultValue: false, description: 'Is it a Release Candidate?')
|
||||
string(name: 'RELEASE_CANDIDATE_NAME', defaultValue: '', description: 'i.e: RC2, RC3 (only needed if IS_RELEASE_CANDIDATE is true)')
|
||||
booleanParam(name: 'CUSTOM_BUILD', defaultValue: true, description: 'If true, will use DISTRO_TO_BUILD If false, will build all distributions')
|
||||
choice(name: 'ARCH_TO_BUILD', choices: ['amd64', 'armhf'], description: 'Only used if CUSTOM_BUILD is true')
|
||||
string(name: 'DISTRO_TO_BUILD', defaultValue: 'xUbuntu_22.04', description: 'Only used if CUSTOM_BUILD is true')
|
||||
string(name: 'MEGACMD_BRANCH', defaultValue: "${env.BRANCH_NAME}", description: 'Which version of MEGAcmd should we build? Default is current branch.')
|
||||
string(name: 'SDK_BRANCH', defaultValue: ' ', description: 'Optionally, define a custom SDK branch.')
|
||||
@ -70,8 +71,8 @@ pipeline {
|
||||
steps {
|
||||
echo "Do Build for ${params.DISTRO_TO_BUILD}"
|
||||
dir(linux_sources_workspace) {
|
||||
lock(resource: "${params.DISTRO_TO_BUILD}-amd64-MEGAcmd-build", quantity: 1) {
|
||||
buildAndSignPackage("${params.DISTRO_TO_BUILD}", "amd64", "megacmd")
|
||||
lock(resource: "${params.DISTRO_TO_BUILD}-${params.ARCH_TO_BUILD}-MEGAcmd-build", quantity: 1) {
|
||||
buildAndSignPackage("${params.DISTRO_TO_BUILD}", "${params.ARCH_TO_BUILD}", "megacmd")
|
||||
}
|
||||
script{
|
||||
if ( params.IS_RELEASE_CANDIDATE == true) {
|
||||
@ -102,17 +103,44 @@ pipeline {
|
||||
axes {
|
||||
axis {
|
||||
name 'ARCHITECTURE';
|
||||
values 'amd64'
|
||||
values 'amd64','armhf'
|
||||
}
|
||||
axis {
|
||||
name 'DISTRO';
|
||||
values 'xUbuntu_24.10','xUbuntu_24.04', 'xUbuntu_22.04', 'xUbuntu_20.04',
|
||||
'Debian_11','Debian_12','Debian_testing',
|
||||
'DEB_Arch_Extra',
|
||||
'Raspbian_11', 'Raspbian_12',
|
||||
'Fedora_39', 'Fedora_40', 'Fedora_41',
|
||||
'openSUSE_Leap_15.5','openSUSE_Leap_15.6', 'openSUSE_Tumbleweed'
|
||||
}
|
||||
}
|
||||
excludes {
|
||||
exclude {
|
||||
axis {
|
||||
name 'ARCHITECTURE';
|
||||
values 'armhf'
|
||||
}
|
||||
axis {
|
||||
name 'DISTRO';
|
||||
values 'xUbuntu_24.10','xUbuntu_24.04', 'xUbuntu_22.04', 'xUbuntu_20.04',
|
||||
'Debian_11','Debian_12','Debian_testing',
|
||||
'DEB_Arch_Extra',
|
||||
'Fedora_39', 'Fedora_40', 'Fedora_41',
|
||||
'openSUSE_Leap_15.5','openSUSE_Leap_15.6', 'openSUSE_Tumbleweed'
|
||||
}
|
||||
}
|
||||
exclude {
|
||||
axis {
|
||||
name 'ARCHITECTURE';
|
||||
values 'amd64'
|
||||
}
|
||||
axis {
|
||||
name 'DISTRO';
|
||||
values 'Raspbian_11', 'Raspbian_12'
|
||||
}
|
||||
}
|
||||
}
|
||||
stages {
|
||||
stage('Build') {
|
||||
agent { label 'linux-testing-package-builder' }
|
||||
@ -136,7 +164,7 @@ pipeline {
|
||||
def MEGACMD_VERSION = getVersionFromHeader("CMakeLists.txt")
|
||||
withCredentials([string(credentialsId: 'MEGACMD_ARTIFACTORY_TOKEN', variable: 'MEGACMD_ARTIFACTORY_TOKEN')]) {
|
||||
sh 'jf rt del --url $REPO_URL --access-token $MEGACMD_ARTIFACTORY_TOKEN MEGAcmd-releases/$MEGACMD_VERSION/$RELEASE_CANDIDATE_NAME/linux/$DISTRO'
|
||||
sh "cd ${env.INTERNAL_REPO_PATH}/repo/private/$DISTRO && jf rt upload --url ${REPO_URL} --access-token ${MEGACMD_ARTIFACTORY_TOKEN} --regexp '((x86_64|amd64|i386)/megacmd.*deb\$|(x86_64|amd64|i386)/megacmd.*rpm\$|(x86_64|amd64|i386)/megacmd.*\\.pkg\\.tar\\.zst\$|(x86_64|amd64|i386)/megacmd.*\\.pkg\\.tar\\.xz\$)' MEGAcmd-releases/$MEGACMD_VERSION/$RELEASE_CANDIDATE_NAME/linux/$DISTRO/"
|
||||
sh "cd ${env.INTERNAL_REPO_PATH}/repo/private/$DISTRO && jf rt upload --url ${REPO_URL} --access-token ${MEGACMD_ARTIFACTORY_TOKEN} --regexp '((x86_64|amd64|i386|armhf)/megacmd.*deb\$|(x86_64|amd64|i386)/megacmd.*rpm\$|(x86_64|amd64|i386)/megacmd.*\\.pkg\\.tar\\.zst\$|(x86_64|amd64|i386)/megacmd.*\\.pkg\\.tar\\.xz\$)' MEGAcmd-releases/$MEGACMD_VERSION/$RELEASE_CANDIDATE_NAME/linux/$DISTRO/"
|
||||
}
|
||||
echo "Packages successfully uploaded. URL: [${env.REPO_URL}/MEGAcmd-releases/$MEGACMD_VERSION/$RELEASE_CANDIDATE_NAME/linux/$DISTRO/]"
|
||||
}
|
||||
@ -147,10 +175,15 @@ pipeline {
|
||||
}
|
||||
}
|
||||
}
|
||||
post {
|
||||
always {
|
||||
deleteDir()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def buildAndSignPackage(String distro, String architecture, String packageName) {
|
||||
sh "${env.BUILDTOOLS_PATH}/build/buildManager.sh -a ${architecture} -j 1 build ${distro} . ${packageName}"
|
||||
sh "${env.BUILDTOOLS_PATH}/build/buildManager.sh -a ${architecture} -j 2 build ${distro} . ${packageName}"
|
||||
sh "${env.BUILDTOOLS_PATH}/repo/repoManager.sh add ${env.INTERNAL_REPO_PATH}/builder/results/${distro}/${architecture}/${packageName}/ ${distro}"
|
||||
sh "SIGN_KEY_PATH=${env.INTERNAL_REPO_PATH}/sign_test/ ${env.BUILDTOOLS_PATH}/repo/repoManager.sh build -n ${distro}"
|
||||
}
|
||||
|
@ -151,4 +151,9 @@ pipeline {
|
||||
}
|
||||
}
|
||||
}
|
||||
post {
|
||||
always {
|
||||
deleteDir()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -75,9 +75,9 @@ pipeline {
|
||||
@echo on
|
||||
mkdir tmp
|
||||
set _MSPDBSRV_ENDPOINT_= ${BUILD_TAG}
|
||||
set TMP=${Workspace}\\tmp
|
||||
set TEMP=${Workspace}\\tmp
|
||||
set TMPDIR=${Workspace}\\tmp
|
||||
set TMP=${windows_sources_workspace}\\build\\tmp
|
||||
set TEMP=${windows_sources_workspace}\\build\\tmp
|
||||
set TMPDIR=${windows_sources_workspace}\\build\\tmp
|
||||
full_build_process.cmd ${params.ARCHITECTURE} nosign 2
|
||||
"""
|
||||
}
|
||||
@ -136,6 +136,11 @@ pipeline {
|
||||
}
|
||||
}
|
||||
}
|
||||
post {
|
||||
always {
|
||||
deleteDir()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def getVersionFromHeader(String versionFilePath) {
|
||||
|
@ -4,6 +4,7 @@ pipeline {
|
||||
options {
|
||||
buildDiscarder(logRotator(numToKeepStr: '135', daysToKeepStr: '21'))
|
||||
gitLabConnection('GitLabConnectionJenkins')
|
||||
timestamps() // Add timestamps to all console output
|
||||
}
|
||||
|
||||
stages {
|
||||
@ -106,7 +107,7 @@ pipeline {
|
||||
axes {
|
||||
axis {
|
||||
name 'SANITIZERS'
|
||||
values 'ubsan', 'asan', 'tsan'
|
||||
values 'baseline', 'ubsan', 'asan', 'tsan'
|
||||
}
|
||||
axis {
|
||||
name 'BUILD_SYSTEM'
|
||||
@ -122,7 +123,7 @@ pipeline {
|
||||
DOCKER_BUILDKIT=1
|
||||
}
|
||||
steps {
|
||||
sh "docker build -t meganz/megacmd-${BUILD_SYSTEM}-${SANITIZERS}:${env.BUILD_NUMBER} -f ${megacmd_sources_workspace}/build-with-docker/Dockerfile.${BUILD_SYSTEM} --build-arg=BUILD_OPT_SANITIZERS=${SANITIZERS} --ulimit=core=-1 --cpuset-cpus=0,1 -- ${megacmd_sources_workspace}"
|
||||
sh "docker build -t meganz/megacmd-${BUILD_SYSTEM}-${SANITIZERS}:${env.BUILD_NUMBER} -f ${megacmd_sources_workspace}/build-with-docker/Dockerfile.${BUILD_SYSTEM} --build-arg=ENABLE_${SANITIZERS}=ON --ulimit=core=-1 --cpuset-cpus=0,1 -- ${megacmd_sources_workspace}"
|
||||
}
|
||||
}
|
||||
stage("MEGAcmd unit tests") {
|
||||
@ -137,9 +138,9 @@ pipeline {
|
||||
timeout(time: 10, unit: 'MINUTES')
|
||||
}
|
||||
environment {
|
||||
ASAN_OPTIONS="atexit=1,print_stats=1,log_path=${megacmd_sources_workspace}/test-dir-${SANITIZERS}/results/mega-cmd-tests-unit-report"
|
||||
TSAN_OPTIONS="log_path=${megacmd_sources_workspace}/test-dir-${SANITIZERS}/results/mega-cmd-tests-unit-report"
|
||||
UBSAN_OPTIONS="log_path=${megacmd_sources_workspace}/test-dir-${SANITIZERS}/results/mega-cmd-tests-unit-report"
|
||||
ASAN_OPTIONS="print_stats=1,log_path=${megacmd_sources_workspace}/test-dir-${SANITIZERS}/results/unit-asan-report.log"
|
||||
TSAN_OPTIONS="log_path=${megacmd_sources_workspace}/test-dir-${SANITIZERS}/results/unit-tsan-report.log"
|
||||
UBSAN_OPTIONS="log_path=${megacmd_sources_workspace}/test-dir-${SANITIZERS}/results/unit-ubsan-report.log"
|
||||
HOME="${megacmd_sources_workspace}/test-dir-${SANITIZERS}"
|
||||
}
|
||||
steps {
|
||||
@ -164,6 +165,7 @@ pipeline {
|
||||
archiveArtifacts artifacts: "test-dir-${SANITIZERS}/.megaCmd/megacmdserver.log*", allowEmptyArchive: true
|
||||
archiveArtifacts artifacts: "**/core*zstd", allowEmptyArchive: true
|
||||
archiveArtifacts artifacts: "**/mega-cmd-tests-unit.zstd", allowEmptyArchive: true
|
||||
archiveArtifacts artifacts: "test-dir-${SANITIZERS}/results/unit-*-report.log.*", allowEmptyArchive: true
|
||||
junit "test-dir-${SANITIZERS}/results/mega-cmd-tests-unit.xml"
|
||||
}
|
||||
}
|
||||
@ -182,9 +184,9 @@ pipeline {
|
||||
environment {
|
||||
MEGACMD_TEST_USER=''
|
||||
MEGACMD_TEST_PASS=credentials('MEGACMD_TESTS_PASSWORD')
|
||||
ASAN_OPTIONS="atexit=1,print_stats=1,log_path=${megacmd_sources_workspace}/test-dir-${SANITIZERS}/results/mega-cmd-tests-integration-report"
|
||||
TSAN_OPTIONS="log_path=${megacmd_sources_workspace}/test-dir-${SANITIZERS}/results/mega-cmd-tests-integration-report"
|
||||
UBSAN_OPTIONS="log_path=${megacmd_sources_workspace}/test-dir-${SANITIZERS}/results/mega-cmd-tests-integration-report"
|
||||
ASAN_OPTIONS="print_stats=1,log_path=${megacmd_sources_workspace}/test-dir-${SANITIZERS}/results/integration-asan-report.log"
|
||||
TSAN_OPTIONS="log_path=${megacmd_sources_workspace}/test-dir-${SANITIZERS}/results/integration-tsan-report.log"
|
||||
UBSAN_OPTIONS="log_path=${megacmd_sources_workspace}/test-dir-${SANITIZERS}/results/integration-ubsan-report.log"
|
||||
HOME="${megacmd_sources_workspace}/test-dir-${SANITIZERS}"
|
||||
}
|
||||
steps {
|
||||
@ -211,6 +213,7 @@ pipeline {
|
||||
archiveArtifacts "test-dir-${SANITIZERS}/.megaCmd/megacmdserver.log*"
|
||||
archiveArtifacts artifacts: "**/core*zstd", allowEmptyArchive: true
|
||||
archiveArtifacts artifacts: "**/mega-cmd-tests-integration.zstd", allowEmptyArchive: true
|
||||
archiveArtifacts artifacts: "test-dir-${SANITIZERS}/results/integration-*-report.log.*", allowEmptyArchive: true
|
||||
junit "test-dir-${SANITIZERS}/results/mega-cmd-tests-integration.xml"
|
||||
}
|
||||
}
|
||||
@ -230,6 +233,9 @@ pipeline {
|
||||
MEGA_EMAILS=''
|
||||
MEGA_PWD=credentials('MEGACMD_TESTS_PASSWORD')
|
||||
MEGA_PWD_AUX=credentials('MEGACMD_TESTS_PASSWORD')
|
||||
ASAN_OPTIONS="print_stats=1,log_path=${megacmd_sources_workspace}/pytest-dir-${SANITIZERS}/results/pyserver-asan-report.log"
|
||||
TSAN_OPTIONS="log_path=${megacmd_sources_workspace}/pytest-dir-${SANITIZERS}/results/pyserver-tsan-report.log"
|
||||
UBSAN_OPTIONS="log_path=${megacmd_sources_workspace}/pytest-dir-${SANITIZERS}/results/pyserver-ubsan-report.log"
|
||||
HOME="${megacmd_sources_workspace}/pytest-dir-${SANITIZERS}"
|
||||
YES_I_KNOW_THIS_WILL_CLEAR_MY_MEGA_ACCOUNT=1
|
||||
VERBOSE=1
|
||||
@ -254,18 +260,21 @@ pipeline {
|
||||
for (test in ['misc', 'put', 'rm', 'find', 'get']) {
|
||||
for (cmdshell in ['', 'cmdshell-']) {
|
||||
def testDir = "pytest-dir-${SANITIZERS}/${cmdshell}${test}-results"
|
||||
def asanOptions = "print_stats=1,log_path=${megacmd_sources_workspace}/${testDir}/py-asan-report.log"
|
||||
def tsanOptions = "log_path=${megacmd_sources_workspace}/${testDir}/py-tsan-report.log"
|
||||
def ubsanOptions = "log_path=${megacmd_sources_workspace}/${testDir}/py-ubsan-report.log"
|
||||
stage("MEGAcmd Python ${cmdshell}${test} test") {
|
||||
withEnv([
|
||||
"MEGA_EMAIL=${env.MEGA_EMAILS0}",
|
||||
"MEGA_EMAIL_AUX=${env.MEGA_EMAILS1}",
|
||||
"ASAN_OPTIONS=atexit=1,print_stats=1,log_path=${megacmd_sources_workspace}/${testDir}/mega-cmd-tests-python-report",
|
||||
"TSAN_OPTIONS=log_path=${megacmd_sources_workspace}/${testDir}/mega-cmd-tests-python-report",
|
||||
"UBSAN_OPTIONS=log_path=${megacmd_sources_workspace}/${testDir}/mega-cmd-tests-python-report",
|
||||
"ASAN_OPTIONS=${asanOptions}",
|
||||
"TSAN_OPTIONS=${tsanOptions}",
|
||||
"UBSAN_OPTIONS=${ubsanOptions}",
|
||||
"OUT_DIR_JUNIT_XML=${megacmd_sources_workspace}/${testDir}"
|
||||
]) {
|
||||
def envStr = ''
|
||||
if (cmdshell != '') {
|
||||
envStr = 'MEGACMDSHELL=/usr/bin/mega-cmd '
|
||||
envStr = "MEGACMDSHELL=/usr/bin/mega-cmd "
|
||||
}
|
||||
try {
|
||||
dir("pytest-dir-${SANITIZERS}/working-dir") {
|
||||
@ -278,6 +287,7 @@ pipeline {
|
||||
}
|
||||
junit "${testDir}/TEST-*.xml"
|
||||
} finally {
|
||||
archiveArtifacts artifacts: "${testDir}/py-*-report.log.*", allowEmptyArchive: true
|
||||
dir("pytest-dir-${SANITIZERS}") {
|
||||
sh "find . -name core -exec zstd -z --fast=3 {} -o core_client_${cmdshell}${test}.zstd \\; -exec rm {} \\; || true"
|
||||
}
|
||||
@ -302,6 +312,7 @@ pipeline {
|
||||
|| true
|
||||
"""
|
||||
archiveArtifacts "pytest-dir-${SANITIZERS}/.megaCmd/megacmdserver.log*"
|
||||
archiveArtifacts artifacts: "pytest-dir-${SANITIZERS}/results/pyserver-*-report.log.*", allowEmptyArchive: true
|
||||
archiveArtifacts artifacts: "**/core*zstd", allowEmptyArchive: true
|
||||
archiveArtifacts artifacts: "**/mega-*.zstd", allowEmptyArchive: true
|
||||
}
|
||||
|
181
jenkinsfile/Jenkinsfile_MR_linux_packages
Normal file
181
jenkinsfile/Jenkinsfile_MR_linux_packages
Normal file
@ -0,0 +1,181 @@
|
||||
pipeline {
|
||||
agent { label "linux-testing-package-builder" }
|
||||
|
||||
options {
|
||||
buildDiscarder(logRotator(numToKeepStr: '135', daysToKeepStr: '21'))
|
||||
gitLabConnection('GitLabConnectionJenkins')
|
||||
timestamps() // Add timestamps to all console output
|
||||
}
|
||||
|
||||
stages {
|
||||
stage('Clean previous runs and update gitlab commit status') {
|
||||
steps {
|
||||
deleteDir()
|
||||
updateGitlabCommitStatus(name: 'Build linux packages', state: 'running')
|
||||
}
|
||||
}
|
||||
|
||||
stage('Get build parameters') {
|
||||
parallel {
|
||||
stage('Get build options') {
|
||||
steps {
|
||||
script{
|
||||
BUILD_OPTIONS = ' '
|
||||
env.ARCHITECTURE = sh(script: 'echo "$gitlabTriggerPhrase" | grep ARCHITECTURE | awk -F "ARCHITECTURE=" \'{print \$2}\' | cut -d"\\"" -f2 || :', returnStdout: true).trim()
|
||||
if (env.ARCHITECTURE == "")
|
||||
{ env.ARCHITECTURE = "amd64" }
|
||||
env.BUILD_OPTIONS = sh(script: 'echo "$gitlabTriggerPhrase" | grep BUILD_OPTIONS | awk -F "BUILD_OPTIONS=" \'{print \$2}\' | cut -d"\\"" -f2 || :', returnStdout: true).trim()
|
||||
env.DISTRIBUTION = sh(script: 'echo "$gitlabTriggerPhrase" | grep DISTRIBUTION | awk -F "DISTRIBUTION=" \'{print \$2}\' | cut -d\\" -f2', returnStdout: true).trim()
|
||||
if (env.DISTRIBUTION == "")
|
||||
{ env.DISTRIBUTION = "xUbuntu_22.04" }
|
||||
println BUILD_OPTIONS
|
||||
println DISTRIBUTION
|
||||
|
||||
}
|
||||
}
|
||||
post{
|
||||
always {
|
||||
script{
|
||||
if (currentBuild.currentResult == 'FAILURE'){
|
||||
addGitLabMRComment(comment: ":red_circle: ${env.JOB_NAME} FAILURE when getting the additional build parameters :worried:<br/>Build results: [Jenkins [${env.JOB_NAME} ${env.BUILD_DISPLAY_NAME}]](${env.RUN_DISPLAY_URL})<br/>Commit: ${env.GIT_COMMIT}" )
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stage('Get SDK branch'){
|
||||
steps {
|
||||
script{
|
||||
env.SDK_BRANCH = sh(script: 'echo "$gitlabMergeRequestDescription" | grep SDK_SUBMODULE_TEST | awk -F "SDK_SUBMODULE_TEST=" \'{print \$2}\' | cut -d" " -f1', returnStdout: true).trim()
|
||||
if (SDK_BRANCH == ""){
|
||||
echo "SDK_BRANCH was not found on description so develop will be used by default"
|
||||
env.SDK_BRANCH = "develop"
|
||||
}
|
||||
println SDK_BRANCH
|
||||
}
|
||||
}
|
||||
post{
|
||||
always {
|
||||
script{
|
||||
if (currentBuild.currentResult == 'FAILURE'){
|
||||
addGitLabMRComment(comment: ":red_circle: ${env.JOB_NAME} FAILURE when getting the SDK branch :worried:<br/>Build results: [Jenkins [${env.JOB_NAME} ${env.BUILD_DISPLAY_NAME}]](${env.RUN_DISPLAY_URL})<br/>Commit: ${env.GIT_COMMIT}" )
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stage('Checkout sources') {
|
||||
parallel {
|
||||
stage('Checkout MEGAcmd') {
|
||||
steps {
|
||||
checkout([
|
||||
$class: 'GitSCM',
|
||||
branches: [[name: "origin/${env.gitlabSourceBranch}"]],
|
||||
userRemoteConfigs: [[url: "${env.GIT_URL_MEGACMD}", credentialsId: "12492eb8-0278-4402-98f0-4412abfb65c1"]],
|
||||
extensions: [
|
||||
[$class: "UserIdentity",name: "jenkins", email: "jenkins@jenkins"],
|
||||
]
|
||||
])
|
||||
}
|
||||
}
|
||||
stage('Checkout SDK') {
|
||||
steps {
|
||||
dir('sdk') {
|
||||
checkout([
|
||||
$class: 'GitSCM',
|
||||
branches: [[name: "${SDK_BRANCH}"]],
|
||||
userRemoteConfigs: [[url: "${env.GIT_URL_SDK}", credentialsId: "12492eb8-0278-4402-98f0-4412abfb65c1"]],
|
||||
extensions: [
|
||||
[$class: "UserIdentity",name: "jenkins", email: "jenkins@jenkins"],
|
||||
[$class: "CloneOption", depth: 1, shallow: true, noTags: false, reference: '']
|
||||
]
|
||||
])
|
||||
}
|
||||
script {
|
||||
linux_sources_workspace = WORKSPACE
|
||||
sdk_sources_workspace = "${linux_sources_workspace}/sdk"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
stage('Build packages'){
|
||||
when {
|
||||
beforeAgent true
|
||||
expression { env.gitlabTriggerPhrase != null && (env.gitlabTriggerPhrase == 'trigger package' || env.gitlabTriggerPhrase.startsWith('trigger package linux')) }
|
||||
}
|
||||
stages{
|
||||
stage('Build linux package'){
|
||||
options {
|
||||
timeout(time: 600, unit: 'MINUTES')
|
||||
}
|
||||
steps {
|
||||
echo "Do Build for $DISTRIBUTION-$ARCHITECTURE"
|
||||
dir(linux_sources_workspace){
|
||||
lock(resource: "$DISTRIBUTION-$ARCHITECTURE-MEGAcmd-build", quantity: 1, ){
|
||||
sh "/opt/buildTools/build/buildManager.sh -a $ARCHITECTURE -j 3 build $DISTRIBUTION . megacmd"
|
||||
sh "/opt/buildTools/repo/repoManager.sh add /srv/builder/results/$DISTRIBUTION/$ARCHITECTURE/megacmd/ $DISTRIBUTION"
|
||||
sh "SIGN_KEY_PATH=/srv/sign_test/ /opt/buildTools/repo/repoManager.sh build -n $DISTRIBUTION"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
stage ('Upload Linux package') {
|
||||
steps {
|
||||
dir(linux_sources_workspace){
|
||||
script{
|
||||
withCredentials([string(credentialsId: 'MEGACMD_ARTIFACTORY_TOKEN', variable: 'MEGACMD_ARTIFACTORY_TOKEN')]) {
|
||||
sh """
|
||||
jf rt del \
|
||||
--url ${REPO_URL} \
|
||||
--access-token ${MEGACMD_ARTIFACTORY_TOKEN} \
|
||||
MEGAcmd-sprints/${env.gitlabMergeRequestIid}/linux/$DISTRIBUTION
|
||||
"""
|
||||
dir("/srv/repo/private/$DISTRIBUTION"){
|
||||
sh """
|
||||
jf rt upload \
|
||||
--url ${REPO_URL} \
|
||||
--access-token ${MEGACMD_ARTIFACTORY_TOKEN} \
|
||||
--regexp '(megacmd.*deb\$|megacmd.*rpm\$|megacmd.*\\.pkg\\.tar\\.zst\$|megacmd.*\\.pkg\\.tar\\.xz\$)' \
|
||||
MEGAcmd-sprints/${env.gitlabMergeRequestIid}/linux/$DISTRIBUTION/
|
||||
"""
|
||||
}
|
||||
}
|
||||
uploadPackagesExecuted = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
post {
|
||||
always {
|
||||
script {
|
||||
if (currentBuild.currentResult == 'SUCCESS') {
|
||||
addGitLabMRComment(comment: ":white_check_mark: ${currentBuild.projectName} :penguin: <b>LINUX</b> SUCCEEDED :muscle:<br/>Build results: [Jenkins [${currentBuild.displayName}]](${currentBuild.absoluteUrl})<br/>Commit: ${env.GIT_COMMIT}<br/>Packages URL: [${env.REPO_URL}/MEGAcmd-sprints/${env.gitlabMergeRequestIid}/linux/$DISTRIBUTION]" )
|
||||
updateGitlabCommitStatus(name: 'Build linux packages', state: 'success')
|
||||
}
|
||||
if (currentBuild.currentResult == 'FAILURE') {
|
||||
addGitLabMRComment(comment: ":red_circle: ${currentBuild.projectName} :penguin: <b>Linux</b> FAILURE :worried:<br/>Build results: [Jenkins [${currentBuild.displayName}]](${currentBuild.absoluteUrl})<br/>Commit: ${env.GIT_COMMIT}" )
|
||||
updateGitlabCommitStatus(name: 'Build linux packages', state: 'failed')
|
||||
}
|
||||
if (currentBuild.currentResult == 'ABORTED') {
|
||||
addGitLabMRComment(comment: ":interrobang: ${currentBuild.projectName} :penguin: <b>Linux</b> ABORTED :confused:<br/>Build results: [Jenkins [${currentBuild.displayName}]](${currentBuild.absoluteUrl})<br/>Commit: ${env.GIT_COMMIT}" )
|
||||
updateGitlabCommitStatus(name: 'Build linux packages', state: 'canceled')
|
||||
}
|
||||
if (currentBuild.currentResult == 'UNSTABLE') {
|
||||
addGitLabMRComment(comment: ":interrobang: ${currentBuild.projectName} :penguin: <b>Linux</b> UNSTABLE :confused:<br/>Build results: [Jenkins [${currentBuild.displayName}]](${currentBuild.absoluteUrl})<br/>Commit: ${env.GIT_COMMIT}" )
|
||||
updateGitlabCommitStatus(name: 'Build linux packages', state: 'failed')
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -8,6 +8,7 @@ pipeline {
|
||||
options {
|
||||
buildDiscarder(logRotator(numToKeepStr: '135', daysToKeepStr: '21'))
|
||||
gitLabConnection('GitLabConnectionJenkins')
|
||||
timestamps() // Add timestamps to all console output
|
||||
}
|
||||
|
||||
stages {
|
||||
@ -192,6 +193,7 @@ pipeline {
|
||||
updateGitlabCommitStatus(name: 'Build macos', state: 'failed')
|
||||
}
|
||||
}
|
||||
deleteDir()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -8,6 +8,7 @@ pipeline {
|
||||
options {
|
||||
buildDiscarder(logRotator(numToKeepStr: '135', daysToKeepStr: '21'))
|
||||
gitLabConnection('GitLabConnectionJenkins')
|
||||
timestamps() // Add timestamps to all console output
|
||||
}
|
||||
|
||||
stages {
|
||||
@ -224,6 +225,7 @@ pipeline {
|
||||
updateGitlabCommitStatus(name: 'Build windows', state: 'failed')
|
||||
}
|
||||
}
|
||||
deleteDir()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
2
sdk
2
sdk
@ -1 +1 @@
|
||||
Subproject commit e448c09e73a4496329f46e538f1f20143b618ed1
|
||||
Subproject commit ddaaf5e587055897f3054a52d4a6dc74d52bb732
|
@ -20,5 +20,9 @@
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
#ifdef WIN32
|
||||
megacmd::Instance<megacmd::WindowsConsoleController> windowsConsoleController;
|
||||
#endif
|
||||
|
||||
return megacmd::executeClient(argc, argv, COUT);
|
||||
}
|
||||
|
@ -144,8 +144,6 @@ wstring getWAbsPath(wstring localpath)
|
||||
}
|
||||
#endif
|
||||
|
||||
string clientID; //identifier for a registered state listener
|
||||
|
||||
string getAbsPath(string relativePath)
|
||||
{
|
||||
if (!relativePath.size())
|
||||
@ -220,7 +218,7 @@ string getAbsPath(string relativePath)
|
||||
|
||||
}
|
||||
|
||||
string parseArgs(int argc, char* argv[])
|
||||
string parseArgs(int argc, char* argv[], MegaCmdShellCommunications& comsManager)
|
||||
{
|
||||
vector<string> absolutedargs;
|
||||
int totalRealArgs = 0;
|
||||
@ -240,17 +238,10 @@ string parseArgs(int argc, char* argv[])
|
||||
|| !strcmp(argv[1],"login")
|
||||
|| !strcmp(argv[1],"reload") )
|
||||
{
|
||||
int waittime = 15000;
|
||||
while (waittime > 0 && !clientID.size())
|
||||
auto clientIdOpt = comsManager.tryToGetClientId();
|
||||
if (clientIdOpt)
|
||||
{
|
||||
sleepMilliSeconds(100);
|
||||
waittime -= 100;
|
||||
}
|
||||
if (clientID.size())
|
||||
{
|
||||
string sclientID = "--clientID=";
|
||||
sclientID+=clientID;
|
||||
absolutedargs.push_back(sclientID);
|
||||
absolutedargs.push_back("--clientID=" + *clientIdOpt);
|
||||
}
|
||||
}
|
||||
|
||||
@ -439,19 +430,23 @@ string parseArgs(int argc, char* argv[])
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
wstring parsewArgs(int argc, wchar_t* argv[])
|
||||
wstring parsewArgs(int argc, wchar_t* argv[], MegaCmdShellCommunications& comsManager)
|
||||
{
|
||||
// remove "-o path" argument if found:
|
||||
for (int i=1;i<argc;i++)
|
||||
{
|
||||
if (i<(argc-1) && !wcscmp(argv[i],L"-o"))
|
||||
if (i<(argc-1) && std::wstring_view(argv[i]) == L"-o")
|
||||
{
|
||||
if (i < (argc-2))
|
||||
argv[i]=argv[i+2];
|
||||
argc=argc-2;
|
||||
for (int j = i; j < argc - 2; ++j)
|
||||
{
|
||||
argv[j] = argv[j + 2];
|
||||
}
|
||||
argc -= 2;
|
||||
argv[argc] = nullptr;
|
||||
--i; // Stay at the same index to process the shifted arguments
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
vector<wstring> absolutedargs;
|
||||
int totalRealArgs = 0;
|
||||
if (argc>1)
|
||||
@ -472,18 +467,10 @@ wstring parsewArgs(int argc, wchar_t* argv[])
|
||||
|| !wcscmp(argv[1],L"login")
|
||||
|| !wcscmp(argv[1],L"reload") )
|
||||
{
|
||||
int waittime = 5000;
|
||||
while (waittime > 0 && !clientID.size())
|
||||
auto clientIdOpt = comsManager.tryToGetClientId();
|
||||
if (clientIdOpt)
|
||||
{
|
||||
sleepMilliSeconds(100);
|
||||
waittime -= 100;
|
||||
}
|
||||
if (clientID.size())
|
||||
{
|
||||
wstring sclientID = L"--clientID=";
|
||||
std::wstring wclientID(clientID.begin(), clientID.end());
|
||||
sclientID+=wclientID;
|
||||
absolutedargs.push_back(sclientID);
|
||||
absolutedargs.push_back(L"--clientID=" + std::wstring(clientIdOpt->begin(), clientIdOpt->end()));
|
||||
}
|
||||
}
|
||||
|
||||
@ -762,13 +749,10 @@ void statechangehandle(string statestring, MegaCmdShellCommunications & comsMana
|
||||
#ifdef _WIN32
|
||||
wstring wbuffer;
|
||||
stringtolocalw((const char*)os.str().data(),&wbuffer);
|
||||
int oldmode;
|
||||
std::lock_guard<std::mutex> stdOutLockGuard(comsManager.getStdoutLockGuard());
|
||||
oldmode = _setmode(_fileno(stdout), _O_U8TEXT);
|
||||
WindowsUtf8StdoutGuard utf8Guard;
|
||||
OUTSTREAM << wbuffer << flush;
|
||||
_setmode(_fileno(stdout), oldmode);
|
||||
|
||||
#else
|
||||
StdoutMutexGuard stdoutGuard;
|
||||
OUTSTREAM << os.str();
|
||||
#endif
|
||||
}
|
||||
@ -780,7 +764,7 @@ void statechangehandle(string statestring, MegaCmdShellCommunications & comsMana
|
||||
}
|
||||
else if (newstate.compare(0, strlen("login:"), "login:") == 0)
|
||||
{
|
||||
std::lock_guard<std::mutex> stdOutLockGuard(comsManager.getStdoutLockGuard());
|
||||
StdoutMutexGuard stdoutGuard;
|
||||
printCenteredContentsCerr(string("Resuming session ... ").c_str(), width, false);
|
||||
}
|
||||
else if (newstate.compare(0, strlen("message:"), "message:") == 0)
|
||||
@ -789,28 +773,25 @@ void statechangehandle(string statestring, MegaCmdShellCommunications & comsMana
|
||||
{
|
||||
lastMessage = newstate;
|
||||
|
||||
string contents = newstate.substr(strlen("message:"));
|
||||
std::string_view messageContents = std::string_view(newstate).substr(strlen("message:"));
|
||||
string contents = std::string(shown_partial_progress ? "\n": "").append(messageContents);
|
||||
replaceAll(contents, "%mega-%", "mega-");
|
||||
|
||||
|
||||
std::lock_guard<std::mutex> stdOutLockGuard(comsManager.getStdoutLockGuard());
|
||||
if (shown_partial_progress)
|
||||
{
|
||||
cerr << endl;
|
||||
}
|
||||
if (contents.find("-----") != 0)
|
||||
if (messageContents.rfind("-----", 0) != 0)
|
||||
{
|
||||
printCenteredContentsCerr(contents, width);
|
||||
}
|
||||
else
|
||||
{
|
||||
StdoutMutexGuard stdoutGuard;
|
||||
cerr << endl << contents << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (newstate.compare(0, strlen("clientID:"), "clientID:") == 0)
|
||||
{
|
||||
clientID = newstate.substr(strlen("clientID:")).c_str();
|
||||
std::string clientId = newstate.substr(strlen("clientID:"));
|
||||
comsManager.setClientIdPromise(clientId);
|
||||
}
|
||||
else if (newstate.compare(0, strlen("progress:"), "progress:") == 0)
|
||||
{
|
||||
@ -840,8 +821,6 @@ void statechangehandle(string statestring, MegaCmdShellCommunications & comsMana
|
||||
shown_partial_progress = false;
|
||||
}
|
||||
|
||||
|
||||
std::lock_guard<std::mutex> stdOutLockGuard(comsManager.getStdoutLockGuard());
|
||||
long long completed = received == SPROGRESS_COMPLETE ? PROGRESS_COMPLETE : charstoll(received.c_str());
|
||||
const char * progressTitle = title.empty() ? "TRANSFERRING" : title.c_str();
|
||||
printprogress(completed, charstoll(total.c_str()), progressTitle);
|
||||
@ -881,6 +860,14 @@ int executeClient(int argc, char* argv[], OUTSTREAMTYPE & outstream)
|
||||
{
|
||||
freopen(argv[i+1],"w",stdout);
|
||||
redirectedoutput = true;
|
||||
|
||||
for (int j = i; j < argc - 2; ++j)
|
||||
{
|
||||
argv[j] = argv[j + 2];
|
||||
}
|
||||
argc -= 2;
|
||||
argv[argc] = nullptr;
|
||||
--i; // Stay at the same index to process the shifted arguments
|
||||
}
|
||||
}
|
||||
|
||||
@ -915,10 +902,10 @@ int executeClient(int argc, char* argv[], OUTSTREAMTYPE & outstream)
|
||||
{
|
||||
return -3;
|
||||
}
|
||||
wstring wParsedArgs = parsewArgs(wargc, szArglist);
|
||||
wstring wParsedArgs = parsewArgs(wargc, szArglist, *comms);
|
||||
LocalFree(szArglist);
|
||||
#else
|
||||
string parsedArgs = parseArgs(argc,argv);
|
||||
string parsedArgs = parseArgs(argc, argv, *comms);
|
||||
#endif
|
||||
|
||||
bool isInloginInValidCommands = false;
|
||||
|
@ -18,20 +18,11 @@
|
||||
|
||||
#include "comunicationsmanager.h"
|
||||
|
||||
#include <regex>
|
||||
|
||||
using namespace mega;
|
||||
|
||||
namespace megacmd {
|
||||
OUTSTREAMTYPE &operator<<(OUTSTREAMTYPE &os, const CmdPetition& p)
|
||||
{
|
||||
return os << p.line;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
std::ostream &operator<<(std::ostream &os, const CmdPetition& p)
|
||||
{
|
||||
return os << p.line;
|
||||
}
|
||||
#endif
|
||||
|
||||
ComunicationsManager::ComunicationsManager()
|
||||
{
|
||||
@ -123,16 +114,6 @@ void ComunicationsManager::returnAndClosePetition(std::unique_ptr<CmdPetition> i
|
||||
{
|
||||
}
|
||||
|
||||
void ComunicationsManager::sendPartialOutput(CmdPetition *inf, OUTSTRING *s)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
void ComunicationsManager::sendPartialOutput(CmdPetition *inf, char *s, size_t size)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief getPetition
|
||||
@ -153,9 +134,57 @@ std::string ComunicationsManager::getUserResponse(CmdPetition *inf, string messa
|
||||
return string();
|
||||
}
|
||||
|
||||
void CmdPetition::setLine(std::string_view line)
|
||||
{
|
||||
mLine = line;
|
||||
}
|
||||
|
||||
std::string_view CmdPetition::getLine() const
|
||||
{
|
||||
return mLine;
|
||||
}
|
||||
|
||||
std::string_view CmdPetition::getUniformLine() const
|
||||
{
|
||||
return ltrim(std::string_view(line), 'X');
|
||||
return ltrim(std::string_view(mLine), 'X');
|
||||
}
|
||||
|
||||
std::string CmdPetition::getRedactedLine() const
|
||||
{
|
||||
const char* doNotRedactEnv = getenv("MEGACMD_DO_NOT_REDACT_LINES");
|
||||
if (doNotRedactEnv)
|
||||
{
|
||||
return mLine;
|
||||
}
|
||||
|
||||
static const std::string redacted = "$1<REDACTED>";
|
||||
static const std::string asterisks = "$1********";
|
||||
|
||||
static const std::regex fullCommandRegex(R"(^((X?)(passwd|login|confirm|confirmcancel)\s+).*$)");
|
||||
static const std::regex passwordRegex(R"((--password=)("[^"]+"|'[^']+'|\S+))");
|
||||
static const std::regex authRegex(R"((--auth-(code|key)=)\S+)");
|
||||
static const std::regex linkRegex(R"((https://mega\.nz/(file|folder)/[^#]+#)\S+)");
|
||||
static const std::regex oldLinkRegex(R"((https://mega\.nz/#F?![^!]+#)\S+)");
|
||||
static const std::regex encryptedLinkRegex(R"((https://mega\.nz/#P!)\S+)");
|
||||
|
||||
if (std::regex_match(mLine, fullCommandRegex))
|
||||
{
|
||||
return std::regex_replace(mLine, fullCommandRegex, redacted);
|
||||
}
|
||||
|
||||
std::string output = mLine;
|
||||
output = std::regex_replace(output, passwordRegex, asterisks);
|
||||
output = std::regex_replace(output, authRegex, asterisks);
|
||||
output = std::regex_replace(output, linkRegex, asterisks);
|
||||
output = std::regex_replace(output, oldLinkRegex, asterisks);
|
||||
output = std::regex_replace(output, encryptedLinkRegex, asterisks);
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
bool CmdPetition::isFromCmdShell() const
|
||||
{
|
||||
return startsWith(mLine, "X");
|
||||
}
|
||||
|
||||
MegaThread *CmdPetition::getPetitionThread() const
|
||||
|
@ -23,29 +23,33 @@
|
||||
#include "megacmdcommonutils.h"
|
||||
|
||||
namespace megacmd {
|
||||
struct CmdPetition
|
||||
class CmdPetition
|
||||
{
|
||||
std::string line;
|
||||
std::string mLine;
|
||||
|
||||
public:
|
||||
mega::MegaThread *petitionThread = nullptr;
|
||||
int clientID = -27;
|
||||
bool clientDisconnected = false;
|
||||
|
||||
virtual ~CmdPetition() = default;
|
||||
|
||||
void setLine(std::string_view line);
|
||||
std::string_view getLine() const;
|
||||
|
||||
// Remove the starting 'X' if present (petitions coming from interactive mode)
|
||||
std::string_view getUniformLine() const;
|
||||
|
||||
// Remove possible confidential info from the line
|
||||
std::string getRedactedLine() const;
|
||||
|
||||
bool isFromCmdShell() const;
|
||||
|
||||
mega::MegaThread *getPetitionThread() const;
|
||||
void setPetitionThread(mega::MegaThread *value);
|
||||
virtual std::string getPetitionDetails() const { return {}; }
|
||||
};
|
||||
|
||||
OUTSTREAMTYPE &operator<<(OUTSTREAMTYPE &os, CmdPetition const &p);
|
||||
|
||||
#ifdef _WIN32
|
||||
std::ostream &operator<<(std::ostream &os, CmdPetition const &p);
|
||||
#endif
|
||||
|
||||
class ComunicationsManager
|
||||
{
|
||||
private:
|
||||
@ -78,8 +82,8 @@ public:
|
||||
*/
|
||||
virtual void returnAndClosePetition(std::unique_ptr<CmdPetition> inf, OUTSTRINGSTREAM *s, int);
|
||||
|
||||
virtual void sendPartialOutput(CmdPetition *inf, OUTSTRING *s);
|
||||
virtual void sendPartialOutput(CmdPetition *inf, char *s, size_t size);
|
||||
virtual void sendPartialOutput(CmdPetition *inf, OUTSTRING *s) = 0;
|
||||
virtual void sendPartialOutput(CmdPetition *inf, char *s, size_t size, bool binaryContents = false) = 0;
|
||||
|
||||
|
||||
/**
|
||||
|
@ -241,7 +241,13 @@ void ComunicationsManagerFileSockets::returnAndClosePetition(std::unique_ptr<Cmd
|
||||
{
|
||||
LOG_err << "ERROR writing output Code to socket: " << errno;
|
||||
}
|
||||
n = send(socket, sout.data(), max(static_cast<size_t>(1), sout.size()), MSG_NOSIGNAL); // for some reason without the max recv never quits in the client for empty responses
|
||||
|
||||
if (sout.empty())
|
||||
{
|
||||
return; // socket shutdown will send EOF (0 bytes upon recv)
|
||||
}
|
||||
|
||||
n = send(socket, sout.data(), sout.size(), MSG_NOSIGNAL);
|
||||
if (n < 0)
|
||||
{
|
||||
LOG_err << "ERROR writing to socket: " << errno;
|
||||
@ -249,6 +255,11 @@ void ComunicationsManagerFileSockets::returnAndClosePetition(std::unique_ptr<Cmd
|
||||
}
|
||||
|
||||
void ComunicationsManagerFileSockets::sendPartialOutput(CmdPetition *inf, OUTSTRING *s)
|
||||
{
|
||||
sendPartialOutput(inf, s->data(), s->size());
|
||||
}
|
||||
|
||||
void ComunicationsManagerFileSockets::sendPartialOutput(CmdPetition *inf, char *s, size_t size, bool binaryContents)
|
||||
{
|
||||
if (inf->clientDisconnected)
|
||||
{
|
||||
@ -263,10 +274,15 @@ void ComunicationsManagerFileSockets::sendPartialOutput(CmdPetition *inf, OUTSTR
|
||||
return;
|
||||
}
|
||||
|
||||
if (s->size())
|
||||
if (!binaryContents && !isValidUtf8(s, size))
|
||||
{
|
||||
size_t size = s->size();
|
||||
std::cerr << "Attempt to sendPartialOutput of invalid utf8 of size " << size << std::endl;
|
||||
assert(false && "Attempt to sendPartialOutput of invalid utf8");
|
||||
return;
|
||||
}
|
||||
|
||||
if (size)
|
||||
{
|
||||
int outCode = MCMD_PARTIALOUT;
|
||||
auto n = send(connectedsocket, (void*)&outCode, sizeof( outCode ), MSG_NOSIGNAL);
|
||||
if (n < 0)
|
||||
@ -287,7 +303,7 @@ void ComunicationsManagerFileSockets::sendPartialOutput(CmdPetition *inf, OUTSTR
|
||||
}
|
||||
|
||||
|
||||
n = send(connectedsocket, s->data(), size, MSG_NOSIGNAL); // for some reason without the max recv never quits in the client for empty responses
|
||||
n = send(connectedsocket, s, size, MSG_NOSIGNAL); // for some reason without the max recv never quits in the client for empty responses
|
||||
|
||||
if (n < 0)
|
||||
{
|
||||
@ -297,8 +313,15 @@ void ComunicationsManagerFileSockets::sendPartialOutput(CmdPetition *inf, OUTSTR
|
||||
}
|
||||
}
|
||||
|
||||
int ComunicationsManagerFileSockets::informStateListener(CmdPetition *inf, const string &s)
|
||||
int ComunicationsManagerFileSockets::informStateListener(CmdPetition *inf, const std::string &s)
|
||||
{
|
||||
if (!isValidUtf8(s))
|
||||
{
|
||||
LOG_err << "Attempt to write an invalid utf-8 string of size " << s.size();
|
||||
assert(false && "Attempt to write an invalid utf-8 string");
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> g(informerMutex);
|
||||
LOG_verbose << "Inform State Listener: Output to write in socket " << ((CmdPetitionPosixSockets *)inf)->outSocket << ": <<" << s << ">>";
|
||||
|
||||
@ -320,12 +343,12 @@ int ComunicationsManagerFileSockets::informStateListener(CmdPetition *inf, const
|
||||
{
|
||||
if (errno == EPIPE) //socket closed
|
||||
{
|
||||
LOG_verbose << "Unregistering no longer listening client. Original petition: " << inf->line;
|
||||
LOG_verbose << "Unregistering no longer listening client. Original petition: " << inf->getRedactedLine();
|
||||
return -1;
|
||||
}
|
||||
else if (errno == EAGAIN || errno == EWOULDBLOCK) // timed out
|
||||
{
|
||||
LOG_warn << "Unregistering timed out listening client. Original petition: " << inf->line;
|
||||
LOG_warn << "Unregistering timed out listening client. Original petition: " << inf->getRedactedLine();
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
@ -361,7 +384,7 @@ std::unique_ptr<CmdPetition> ComunicationsManagerFileSockets::getPetition()
|
||||
}
|
||||
|
||||
sleep(1);
|
||||
inf->line = "ERROR";
|
||||
inf->setLine("ERROR");
|
||||
return inf;
|
||||
}
|
||||
|
||||
@ -399,13 +422,13 @@ std::unique_ptr<CmdPetition> ComunicationsManagerFileSockets::getPetition()
|
||||
if (n < 0)
|
||||
{
|
||||
LOG_fatal << "ERROR reading from socket at getPetition: " << errno;
|
||||
inf->line = "ERROR";
|
||||
inf->setLine("ERROR");
|
||||
close(newsockfd);
|
||||
return inf;
|
||||
}
|
||||
|
||||
inf->outSocket = newsockfd;
|
||||
inf->line = wholepetition;
|
||||
inf->setLine(wholepetition);
|
||||
|
||||
return inf;
|
||||
}
|
||||
|
@ -32,6 +32,7 @@ struct CmdPetitionPosixSockets: public CmdPetition
|
||||
|
||||
virtual ~CmdPetitionPosixSockets()
|
||||
{
|
||||
shutdown(outSocket, SHUT_RDWR);
|
||||
close(outSocket);
|
||||
}
|
||||
|
||||
@ -79,7 +80,8 @@ public:
|
||||
*/
|
||||
void returnAndClosePetition(std::unique_ptr<CmdPetition> inf, OUTSTRINGSTREAM *s, int) override;
|
||||
|
||||
virtual void sendPartialOutput(CmdPetition *inf, OUTSTRING *s);
|
||||
void sendPartialOutput(CmdPetition *inf, OUTSTRING *s) override;
|
||||
void sendPartialOutput(CmdPetition *inf, char *s, size_t size, bool binaryContents = false) override;
|
||||
|
||||
int informStateListener(CmdPetition *inf, const std::string &s) override;
|
||||
|
||||
|
@ -224,11 +224,16 @@ void ComunicationsManagerNamedPipes::returnAndClosePetition(std::unique_ptr<CmdP
|
||||
connectsucceeded = true;
|
||||
break;
|
||||
}
|
||||
else
|
||||
else if (ERRNO == ERROR_NO_DATA)
|
||||
{
|
||||
LOG_fatal << "ERROR on connecting to namedPipe " << outNamedPipe << ". errno: " << ERRNO << ". Attempts: " << attempts;
|
||||
break;
|
||||
}
|
||||
sleepMilliSeconds(500);
|
||||
else
|
||||
{ // Problem: this, caused by a client shutdown, entails trying to sendPartialOutput again (via MEGAcmdLogger::formatLogToStream)
|
||||
LOG_err << "ERROR on connecting to namedPipe " << outNamedPipe << ". errno: " << ERRNO << ". Attempts: " << attempts;
|
||||
assert(false);
|
||||
}
|
||||
sleepMilliSeconds(50);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -238,7 +243,7 @@ void ComunicationsManagerNamedPipes::returnAndClosePetition(std::unique_ptr<CmdP
|
||||
|
||||
if (!connectsucceeded)
|
||||
{
|
||||
LOG_fatal << "Return and close: Unable to connect on outnamedPipe " << outNamedPipe << " error: " << ERRNO;
|
||||
LOG_err << "Return and close: Unable to connect on outnamedPipe " << outNamedPipe << " error: " << ERRNO;
|
||||
return;
|
||||
}
|
||||
|
||||
@ -282,11 +287,16 @@ void ComunicationsManagerNamedPipes::sendPartialOutput(CmdPetition *inf, OUTSTRI
|
||||
connectsucceeded = true;
|
||||
break;
|
||||
}
|
||||
else if (ERRNO == ERROR_NO_DATA)
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
cerr << "ERROR on connecting to namedPipe " << outNamedPipe << ". errno: " << ERRNO << ". Attempts: " << attempts << endl;
|
||||
assert(false);
|
||||
}
|
||||
sleepMilliSeconds(500);
|
||||
sleepMilliSeconds(50);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -297,20 +307,7 @@ void ComunicationsManagerNamedPipes::sendPartialOutput(CmdPetition *inf, OUTSTRI
|
||||
if (!connectsucceeded)
|
||||
{
|
||||
cerr << "sendPartialOutput: Unable to connect on outnamedPipe " << outNamedPipe << " error: " << ERRNO << endl;
|
||||
if (errno == ERROR_NO_DATA) //TODO: pipe disconnected error?
|
||||
{
|
||||
std::cerr << "WARNING: Client disconnected, the rest of the output will be discarded" << endl;
|
||||
inf->clientDisconnected = true;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
int outCode = MCMD_PARTIALOUT;
|
||||
DWORD n;
|
||||
if (!WriteFile(outNamedPipe,(const char*)&outCode, sizeof(outCode), &n, NULL))
|
||||
{
|
||||
LOG_err << "ERROR writing output Code to namedPipe: " << ERRNO;
|
||||
if (errno == ERROR_NO_DATA) //TODO: pipe disconnected error?
|
||||
if (ERRNO == ERROR_NO_DATA)
|
||||
{
|
||||
std::cerr << "WARNING: Client disconnected, the rest of the output will be discarded" << endl;
|
||||
inf->clientDisconnected = true;
|
||||
@ -319,25 +316,46 @@ void ComunicationsManagerNamedPipes::sendPartialOutput(CmdPetition *inf, OUTSTRI
|
||||
}
|
||||
|
||||
string sutf8;
|
||||
localwtostring(s,&sutf8);
|
||||
localwtostring(s, &sutf8);
|
||||
assert(isValidUtf8(sutf8)); // above localwtostring should produce an empty string if the input had broken encoding or valid utf-8 otherwise
|
||||
|
||||
int outCode = MCMD_PARTIALOUT;
|
||||
DWORD n;
|
||||
if (!WriteFile(outNamedPipe,(const char*)&outCode, sizeof(outCode), &n, NULL))
|
||||
{
|
||||
std::cerr << "ERROR writing output Code to namedPipe: " << ERRNO << std::endl;
|
||||
if (ERRNO == ERROR_NO_DATA) //TODO: pipe disconnected error?
|
||||
{
|
||||
std::cerr << "WARNING: Client disconnected, the rest of the output will be discarded" << endl;
|
||||
inf->clientDisconnected = true;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
size_t size = sutf8.size() > 1 ? sutf8.size() : 1; // client does not like empty responses
|
||||
if (!WriteFile(outNamedPipe,(const char*)&size, sizeof(size), &n, NULL))
|
||||
{
|
||||
LOG_err << "ERROR writing output Code to namedPipe: " << ERRNO;
|
||||
std::cerr << "ERROR writing output Code to namedPipe: " << std::endl;
|
||||
return;
|
||||
}
|
||||
if (!WriteFile(outNamedPipe,sutf8.data(), DWORD(size), &n, NULL))
|
||||
{
|
||||
LOG_err << "ERROR writing to namedPipe: " << ERRNO;
|
||||
std::cerr << "ERROR writing to namedPipe: " << ERRNO << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ComunicationsManagerNamedPipes::sendPartialOutput(CmdPetition *inf, char *s, size_t size)
|
||||
void ComunicationsManagerNamedPipes::sendPartialOutput(CmdPetition *inf, char *s, size_t size, bool binaryContents)
|
||||
{
|
||||
HANDLE outNamedPipe = ((CmdPetitionNamedPipes *)inf)->outNamedPipe;
|
||||
|
||||
if (!binaryContents &&!isValidUtf8(s, size))
|
||||
{
|
||||
std::cerr << "Attempt to sendPartialOutput of invalid utf8 of size " << size << std::endl;
|
||||
assert(false && "Attempt to sendPartialOutput of invalid utf8");
|
||||
return;
|
||||
}
|
||||
|
||||
bool connectsucceeded = false;
|
||||
int attempts = 10;
|
||||
while (--attempts && !connectsucceeded)
|
||||
@ -350,6 +368,10 @@ void ComunicationsManagerNamedPipes::sendPartialOutput(CmdPetition *inf, char *s
|
||||
connectsucceeded = true;
|
||||
break;
|
||||
}
|
||||
else if (ERRNO == ERROR_NO_DATA)
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
cerr << "ERROR on connecting to namedPipe " << outNamedPipe << ". errno: " << ERRNO << ". Attempts: " << attempts << endl;
|
||||
@ -365,7 +387,7 @@ void ComunicationsManagerNamedPipes::sendPartialOutput(CmdPetition *inf, char *s
|
||||
if (!connectsucceeded)
|
||||
{
|
||||
cerr << "sendPartialOutput: Unable to connect on outnamedPipe " << outNamedPipe << " error: " << ERRNO << endl;
|
||||
if (errno == ERROR_NO_DATA)
|
||||
if (ERRNO == ERROR_NO_DATA)
|
||||
{
|
||||
std::cerr << "WARNING: Client disconnected, the rest of the output will be discarded" << endl;
|
||||
inf->clientDisconnected = true;
|
||||
@ -378,7 +400,7 @@ void ComunicationsManagerNamedPipes::sendPartialOutput(CmdPetition *inf, char *s
|
||||
if (!WriteFile(outNamedPipe,(const char*)&outCode, sizeof(outCode), &n, NULL))
|
||||
{
|
||||
LOG_err << "ERROR writing output Code to namedPipe: " << ERRNO;
|
||||
if (errno == ERROR_NO_DATA)
|
||||
if (ERRNO == ERROR_NO_DATA)
|
||||
{
|
||||
std::cerr << "WARNING: Client disconnected, the rest of the output will be discarded" << endl;
|
||||
inf->clientDisconnected = true;
|
||||
@ -400,6 +422,13 @@ void ComunicationsManagerNamedPipes::sendPartialOutput(CmdPetition *inf, char *s
|
||||
|
||||
int ComunicationsManagerNamedPipes::informStateListener(CmdPetition *inf, const string &s)
|
||||
{
|
||||
if (!isValidUtf8(s))
|
||||
{
|
||||
LOG_err << "Attempt to write an invalid utf8 string of size " << s.size();
|
||||
assert(false && "Attempt to write an invalid utf8 string");
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> g(*informerMutex);
|
||||
|
||||
LOG_verbose << "Inform State Listener: Output to write in namedPipe " << ((CmdPetitionNamedPipes *)inf)->outNamedPipe << ": <<" << s << ">>";
|
||||
@ -428,7 +457,7 @@ int ComunicationsManagerNamedPipes::informStateListener(CmdPetition *inf, const
|
||||
{
|
||||
if (ERRNO == 32 || ERRNO == 109 || (ERRNO == 232 && s == "ack")) //namedPipe closed | pipe has been ended
|
||||
{
|
||||
LOG_debug << "namedPipe closed. Client probably disconnected. Original petition: " << inf->line;
|
||||
LOG_debug << "namedPipe closed. Client probably disconnected. Original petition: " << inf->getRedactedLine();
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
@ -480,7 +509,7 @@ std::unique_ptr<CmdPetition> ComunicationsManagerNamedPipes::getPetition()
|
||||
if (!readok)
|
||||
{
|
||||
LOG_err << "Failed to read petition from named pipe. errno: L" << ERRNO;
|
||||
inf->line = "ERROR";
|
||||
inf->setLine("ERROR");
|
||||
return inf;
|
||||
}
|
||||
|
||||
@ -493,14 +522,14 @@ std::unique_ptr<CmdPetition> ComunicationsManagerNamedPipes::getPetition()
|
||||
if (!namedPipeValid(inf->outNamedPipe) || !namedPipe_id)
|
||||
{
|
||||
LOG_fatal << "ERROR creating output namedPipe at getPetition";
|
||||
inf->line = "ERROR";
|
||||
inf->setLine("ERROR");
|
||||
return inf;
|
||||
}
|
||||
|
||||
if(!WriteFile(pipeGeneral,(const char*)&namedPipe_id, sizeof( namedPipe_id ), &n, NULL))
|
||||
{
|
||||
LOG_fatal << "ERROR writing to namedPipe at getPetition: ERRNO = " << ERRNO;
|
||||
inf->line = "ERROR";
|
||||
inf->setLine("ERROR");
|
||||
return inf;
|
||||
}
|
||||
|
||||
@ -509,7 +538,7 @@ std::unique_ptr<CmdPetition> ComunicationsManagerNamedPipes::getPetition()
|
||||
LOG_fatal << " Error disconnecting from general pip. errno: " << ERRNO;
|
||||
}
|
||||
|
||||
inf->line = receivedutf8;
|
||||
inf->setLine(receivedutf8);
|
||||
|
||||
return inf;
|
||||
}
|
||||
|
@ -95,9 +95,8 @@ public:
|
||||
*/
|
||||
void returnAndClosePetition(std::unique_ptr<CmdPetition> inf, OUTSTRINGSTREAM *s, int) override;
|
||||
|
||||
void sendPartialOutput(CmdPetition *inf, OUTSTRING *s);
|
||||
|
||||
void sendPartialOutput(CmdPetition *inf, char *s, size_t size);
|
||||
void sendPartialOutput(CmdPetition *inf, OUTSTRING *s) override;
|
||||
void sendPartialOutput(CmdPetition *inf, char *s, size_t size, bool binaryContents = false) override;
|
||||
|
||||
|
||||
int informStateListener(CmdPetition *inf, const std::string &s) override;
|
||||
|
@ -16,8 +16,8 @@
|
||||
* program.
|
||||
*/
|
||||
|
||||
#include "configurationmanager.h"
|
||||
#include "megacmdcommonutils.h"
|
||||
#include "configurationmanager.h"
|
||||
#include "megacmdversion.h"
|
||||
#include "megacmdutils.h"
|
||||
#include "listeners.h"
|
||||
@ -25,7 +25,6 @@
|
||||
#include "sync_ignore.h"
|
||||
|
||||
#include <fstream>
|
||||
#include <filesystem>
|
||||
|
||||
#ifndef ERRNO
|
||||
#ifdef _WIN32
|
||||
@ -52,27 +51,13 @@
|
||||
#define PATH_MAX_LOCAL_BACKUP PATH_MAX
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32)
|
||||
#define unlink _unlink
|
||||
#endif
|
||||
|
||||
using namespace mega;
|
||||
namespace fs = std::filesystem;
|
||||
using namespace std;
|
||||
|
||||
namespace megacmd {
|
||||
|
||||
static const char* const LOCK_FILE_NAME = "lockMCMD";
|
||||
|
||||
|
||||
using namespace std;
|
||||
bool is_file_exist(const char *fileName)
|
||||
{
|
||||
std::ifstream infile(fileName);
|
||||
return infile.good();
|
||||
}
|
||||
|
||||
string ConfigurationManager::mConfigFolder;
|
||||
bool ConfigurationManager::hasBeenUpdated = false;
|
||||
#ifdef WIN32
|
||||
HANDLE ConfigurationManager::mLockFileHandle;
|
||||
#elif defined(LOCK_EX) && defined(LOCK_NB)
|
||||
@ -83,9 +68,9 @@ string ConfigurationManager::session;
|
||||
map<std::string, backup_struct *> ConfigurationManager::configuredBackups;
|
||||
std::recursive_mutex ConfigurationManager::settingsMutex;
|
||||
|
||||
std::string ConfigurationManager::getConfigFolder()
|
||||
fs::path ConfigurationManager::getConfigFolder()
|
||||
{
|
||||
if (!mConfigFolder.size())
|
||||
if (mConfigFolder.empty())
|
||||
{
|
||||
ConfigurationManager::loadConfigDir();
|
||||
}
|
||||
@ -102,6 +87,33 @@ static const char* const persistentmcmdconfigurationkeys[] =
|
||||
"autoupdate", "updaterregistered"
|
||||
};
|
||||
|
||||
void ConfigurationManager::createFolderIfNotExisting(const fs::path &folder)
|
||||
{
|
||||
std::error_code ec;
|
||||
auto createdOk = fs::create_directory(folder, ec);
|
||||
bool alreadyExisting = !createdOk && !ec;
|
||||
if (alreadyExisting)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
LOG_debug << "Creating directory " << folder;
|
||||
|
||||
if (!createdOk)
|
||||
{
|
||||
LOG_err << "Directory " << folder << " creation failed: " << errorCodeStr(ec);
|
||||
return;
|
||||
}
|
||||
|
||||
#ifndef WIN32
|
||||
fs::permissions(folder, fs::perms::owner_all, fs::perm_options::replace, ec);
|
||||
if (!ec)
|
||||
{
|
||||
LOG_warn << "Failed to set permissions on new folder " << folder << ": " << errorCodeStr(ec);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void ConfigurationManager::loadConfigDir()
|
||||
{
|
||||
auto dirs = PlatformDirectories::getPlatformSpecificDirectories();
|
||||
@ -113,79 +125,48 @@ void ConfigurationManager::loadConfigDir()
|
||||
return;
|
||||
}
|
||||
|
||||
auto fsAccess = std::make_unique<MegaFileSystemAccess>();
|
||||
fsAccess->setdefaultfolderpermissions(0700);
|
||||
LocalPath localConfigFolder = LocalPath::fromAbsolutePath(mConfigFolder);
|
||||
constexpr bool isHidden = true;
|
||||
constexpr bool reportExisting = false;
|
||||
if (!pathIsExistingDir(mConfigFolder.c_str()) && !fsAccess->mkdirlocal(localConfigFolder, isHidden, reportExisting))
|
||||
{
|
||||
LOG_err << "Config directory not created";
|
||||
}
|
||||
createFolderIfNotExisting(mConfigFolder);
|
||||
}
|
||||
|
||||
std::string ConfigurationManager::getAndCreateConfigDir()
|
||||
fs::path ConfigurationManager::getAndCreateConfigDir()
|
||||
{
|
||||
auto dirs = PlatformDirectories::getPlatformSpecificDirectories();
|
||||
auto configDir = dirs->configDirPath();
|
||||
const fs::path configDir = dirs->configDirPath();
|
||||
if (configDir.empty())
|
||||
{
|
||||
LOG_fatal << "Could not get config directory path";
|
||||
throw std::runtime_error("Could not get config directory path");
|
||||
}
|
||||
|
||||
auto fsAccess = std::make_unique<MegaFileSystemAccess>();
|
||||
fsAccess->setdefaultfolderpermissions(0700);
|
||||
LocalPath localConfigDir = LocalPath::fromAbsolutePath(configDir);
|
||||
if (!pathIsExistingDir(configDir.c_str()) && !fsAccess->mkdirlocal(localConfigDir, false, false))
|
||||
{
|
||||
LOG_err << "Config directory not created";
|
||||
}
|
||||
|
||||
createFolderIfNotExisting(configDir);
|
||||
return configDir;
|
||||
}
|
||||
|
||||
std::string ConfigurationManager::getAndCreateRuntimeDir()
|
||||
fs::path ConfigurationManager::getAndCreateRuntimeDir()
|
||||
{
|
||||
auto dirs = PlatformDirectories::getPlatformSpecificDirectories();
|
||||
auto runtimeDir = dirs->runtimeDirPath();
|
||||
const fs::path runtimeDir = dirs->runtimeDirPath();
|
||||
if (runtimeDir.empty())
|
||||
{
|
||||
LOG_fatal << "Could not get runtime directory path";
|
||||
throw std::runtime_error("Could not get runtime directory path");
|
||||
}
|
||||
|
||||
auto fsAccess = std::make_unique<MegaFileSystemAccess>();
|
||||
fsAccess->setdefaultfolderpermissions(0700);
|
||||
LocalPath localRuntimeDir = LocalPath::fromAbsolutePath(runtimeDir);
|
||||
if (!pathIsExistingDir(runtimeDir.c_str()) && !fsAccess->mkdirlocal(localRuntimeDir, false, false))
|
||||
{
|
||||
LOG_err << "Runtime directory not created";
|
||||
}
|
||||
|
||||
createFolderIfNotExisting(runtimeDir);
|
||||
return runtimeDir;
|
||||
}
|
||||
|
||||
std::string ConfigurationManager::getConfigFolderSubdir(const string &utf8Name)
|
||||
fs::path ConfigurationManager::getConfigFolderSubdir(const fs::path& subdirName)
|
||||
{
|
||||
auto dirs = PlatformDirectories::getPlatformSpecificDirectories();
|
||||
auto configDir = dirs->configDirPath();
|
||||
const fs::path configDir = dirs->configDirPath();
|
||||
assert(!configDir.empty());
|
||||
|
||||
MegaFileSystemAccess fsAccess;
|
||||
fsAccess.setdefaultfolderpermissions(0700);
|
||||
LocalPath configSubdir = LocalPath::fromAbsolutePath(configDir);
|
||||
fs::path configSubDir = configDir / subdirName;
|
||||
|
||||
configSubdir.appendWithSeparator(LocalPath::fromRelativePath(utf8Name), true);
|
||||
createFolderIfNotExisting(configSubDir);
|
||||
|
||||
constexpr bool isHidden = true;
|
||||
constexpr bool reportExisting = false;
|
||||
if (!pathIsExistingDir(configSubdir.toPath(false).c_str()) && !fsAccess.mkdirlocal(configSubdir, isHidden, reportExisting))
|
||||
{
|
||||
LOG_err << "State subfolder not created";
|
||||
}
|
||||
|
||||
return configSubdir.toPath(false);
|
||||
return configSubDir;
|
||||
}
|
||||
|
||||
void ConfigurationManager::saveSession(const char*session)
|
||||
@ -194,12 +175,10 @@ void ConfigurationManager::saveSession(const char*session)
|
||||
auto configDir = getAndCreateConfigDir();
|
||||
assert(!configDir.empty());
|
||||
|
||||
stringstream sessionfile;
|
||||
sessionfile << configDir << "/" << "session";
|
||||
LOG_debug << "Session file: " << sessionfile.str();
|
||||
|
||||
ofstream fo(sessionfile.str().c_str(), ios::out);
|
||||
const fs::path sessionFilePath = configDir / "session";
|
||||
LOG_debug << "Session file: " << sessionFilePath;
|
||||
|
||||
ofstream fo(sessionFilePath, ios::out);
|
||||
if (fo.is_open())
|
||||
{
|
||||
if (session)
|
||||
@ -210,7 +189,7 @@ void ConfigurationManager::saveSession(const char*session)
|
||||
}
|
||||
}
|
||||
|
||||
void ConfigurationManager::saveProperty(const char *property, const char *value)
|
||||
string ConfigurationManager::saveProperty(const char *property, const char *value)
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> g(settingsMutex);
|
||||
|
||||
@ -221,12 +200,12 @@ void ConfigurationManager::saveProperty(const char *property, const char *value)
|
||||
assert(!mConfigFolder.empty());
|
||||
|
||||
bool found = false;
|
||||
stringstream configFile;
|
||||
configFile << mConfigFolder << "/" << "megacmd.cfg";
|
||||
const fs::path configFilePath = mConfigFolder / "megacmd.cfg";
|
||||
|
||||
stringstream formerlines;
|
||||
ifstream infile(configFile.str().c_str());
|
||||
string line;
|
||||
|
||||
ifstream infile(configFilePath);
|
||||
string line, prevValue;
|
||||
while (getline(infile, line))
|
||||
{
|
||||
if (line.length() > 0 && line[0] != '#')
|
||||
@ -238,12 +217,10 @@ void ConfigurationManager::saveProperty(const char *property, const char *value)
|
||||
key = line.substr(0, pos);
|
||||
rtrimProperty(key, ' ');
|
||||
|
||||
if (!strcmp(key.c_str(), property))
|
||||
if (!strcmp(key.c_str(), property) && !found)
|
||||
{
|
||||
if (!found)
|
||||
{
|
||||
formerlines << property << "=" << value << endl;
|
||||
}
|
||||
formerlines << property << "=" << value << endl;
|
||||
prevValue = line.substr(pos + 1);
|
||||
found = true;
|
||||
}
|
||||
else
|
||||
@ -257,8 +234,8 @@ void ConfigurationManager::saveProperty(const char *property, const char *value)
|
||||
}
|
||||
}
|
||||
}
|
||||
ofstream fo(configFile.str().c_str());
|
||||
|
||||
ofstream fo(configFilePath);
|
||||
if (fo.is_open())
|
||||
{
|
||||
fo << formerlines.str();
|
||||
@ -268,6 +245,7 @@ void ConfigurationManager::saveProperty(const char *property, const char *value)
|
||||
}
|
||||
fo.close();
|
||||
}
|
||||
return prevValue;
|
||||
}
|
||||
|
||||
void ConfigurationManager::migrateSyncConfig(MegaApi *api)
|
||||
@ -338,17 +316,16 @@ void ConfigurationManager::saveSyncs(map<string, sync_struct *> *syncsmap)
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> g(settingsMutex);
|
||||
|
||||
stringstream syncsfile;
|
||||
if (mConfigFolder.empty())
|
||||
{
|
||||
loadConfigDir();
|
||||
}
|
||||
if (!mConfigFolder.empty())
|
||||
{
|
||||
syncsfile << mConfigFolder << "/" << "syncs";
|
||||
LOG_debug << "Syncs file: " << syncsfile.str();
|
||||
const fs::path syncsFilePath = mConfigFolder / "syncs";
|
||||
LOG_debug << "Syncs file: " << syncsFilePath;
|
||||
|
||||
ofstream fo(syncsfile.str().c_str(), ios::out | ios::binary);
|
||||
ofstream fo(syncsFilePath, ios::out | ios::binary);
|
||||
|
||||
if (fo.is_open())
|
||||
{
|
||||
@ -387,17 +364,16 @@ void ConfigurationManager::saveBackups(map<string, backup_struct *> *backupsmap)
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> g(settingsMutex);
|
||||
|
||||
stringstream backupsfile;
|
||||
if (mConfigFolder.empty())
|
||||
{
|
||||
loadConfigDir();
|
||||
}
|
||||
if (!mConfigFolder.empty())
|
||||
{
|
||||
backupsfile << mConfigFolder << "/" << "backups";
|
||||
LOG_debug << "Backups file: " << backupsfile.str();
|
||||
const fs::path backupsFilePath = mConfigFolder / "backups";
|
||||
LOG_debug << "Backups file: " << backupsFilePath;
|
||||
|
||||
ofstream fo(backupsfile.str().c_str(), ios::out | ios::binary);
|
||||
ofstream fo(backupsFilePath, ios::out | ios::binary);
|
||||
|
||||
if (fo.is_open())
|
||||
{
|
||||
@ -449,15 +425,15 @@ void ConfigurationManager::transitionLegacyExclusionRules(MegaApi& api)
|
||||
// and since we also need to manually read the legacy file, it's just easier to rely on our custom
|
||||
// method to generate the default file.
|
||||
|
||||
const string defaultMegaIgnorePath = MegaIgnoreFile::getDefaultPath();
|
||||
const fs::path defaultMegaIgnorePath = MegaIgnoreFile::getDefaultPath();
|
||||
if (fs::exists(defaultMegaIgnorePath))
|
||||
{
|
||||
LOG_debug << "Default .megaignore file already exists. Skipping legacy transition";
|
||||
return;
|
||||
}
|
||||
|
||||
const string excludeFilePath = mConfigFolder + "/excluded";
|
||||
const string hiddenExcludeFilePath = mConfigFolder + "/.excluded";
|
||||
const fs::path excludeFilePath = mConfigFolder / "excluded";
|
||||
const fs::path hiddenExcludeFilePath = mConfigFolder / ".excluded";
|
||||
if (!fs::exists(excludeFilePath))
|
||||
{
|
||||
LOG_debug << "Missing legacy exclude file. Skipping transition";
|
||||
@ -518,7 +494,7 @@ void ConfigurationManager::transitionLegacyExclusionRules(MegaApi& api)
|
||||
}
|
||||
|
||||
string message = "Your legacy sync exclusion rules have been ported to \"" +
|
||||
defaultMegaIgnorePath + "\"\n" +
|
||||
pathAsUtf8(defaultMegaIgnorePath) + "\"\n" +
|
||||
"See \"%mega-%sync-ignore\" for more info.";
|
||||
broadcastMessage(message, true);
|
||||
}
|
||||
@ -546,17 +522,16 @@ void ConfigurationManager::unloadConfiguration()
|
||||
void ConfigurationManager::loadsyncs()
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> g(settingsMutex);
|
||||
stringstream syncsfile;
|
||||
if (mConfigFolder.empty())
|
||||
{
|
||||
loadConfigDir();
|
||||
}
|
||||
if (!mConfigFolder.empty())
|
||||
{
|
||||
syncsfile << mConfigFolder << "/" << "syncs";
|
||||
LOG_debug << "Syncs file: " << syncsfile.str();
|
||||
const fs::path syncsFilePath = mConfigFolder / "syncs";
|
||||
LOG_debug << "Syncs file: " << syncsFilePath;
|
||||
|
||||
ifstream fi(syncsfile.str().c_str(), ios::in | ios::binary);
|
||||
ifstream fi(syncsFilePath, ios::in | ios::binary);
|
||||
|
||||
if (fi.is_open())
|
||||
{
|
||||
@ -623,17 +598,16 @@ void ConfigurationManager::loadsyncs()
|
||||
void ConfigurationManager::loadbackups()
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> g(settingsMutex);
|
||||
stringstream backupsfile;
|
||||
if (mConfigFolder.empty())
|
||||
{
|
||||
loadConfigDir();
|
||||
}
|
||||
if (!mConfigFolder.empty())
|
||||
{
|
||||
backupsfile << mConfigFolder << "/" << "backups";
|
||||
LOG_debug << "Backups file: " << backupsfile.str();
|
||||
const fs::path backupsFilePath = mConfigFolder / "backups";
|
||||
LOG_debug << "Backups file: " << backupsFilePath;
|
||||
|
||||
ifstream fi(backupsfile.str().c_str(), ios::in | ios::binary);
|
||||
ifstream fi(backupsFilePath, ios::in | ios::binary);
|
||||
|
||||
if (fi.is_open())
|
||||
{
|
||||
@ -698,20 +672,21 @@ void ConfigurationManager::loadConfiguration(bool debug)
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> g(settingsMutex);
|
||||
|
||||
// SESSION
|
||||
auto configDir = getAndCreateConfigDir();
|
||||
#ifdef _WIN32
|
||||
WindowsUtf8StdoutGuard utf8Guard;
|
||||
#endif
|
||||
|
||||
// SESSION
|
||||
const fs::path configDir = getAndCreateConfigDir();
|
||||
if (!configDir.empty())
|
||||
{
|
||||
stringstream sessionfile;
|
||||
sessionfile << configDir << "/" << "session";
|
||||
|
||||
const fs::path sessionFilePath = configDir / "session";
|
||||
if (debug)
|
||||
{
|
||||
std::cout << "Session file: " << sessionfile.str() << std::endl;
|
||||
COUT << "Session file: " << sessionFilePath << std::endl;
|
||||
}
|
||||
|
||||
ifstream fi(sessionfile.str().c_str(), ios::in);
|
||||
ifstream fi(sessionFilePath, ios::in);
|
||||
if (fi.is_open())
|
||||
{
|
||||
string line;
|
||||
@ -720,23 +695,22 @@ void ConfigurationManager::loadConfiguration(bool debug)
|
||||
session = line;
|
||||
if (debug)
|
||||
{
|
||||
std::cout << "Session read from configuration: " << line.substr(0, 5) << "..." << std::endl;
|
||||
COUT << "Session read from configuration: " << line.substr(0, 5) << "..." << std::endl;
|
||||
}
|
||||
}
|
||||
fi.close();
|
||||
}
|
||||
|
||||
// Check if version has been updated.
|
||||
stringstream versionionfile;
|
||||
if (mConfigFolder.empty())
|
||||
{
|
||||
loadConfigDir();
|
||||
}
|
||||
versionionfile << mConfigFolder << "/" << VERSION_FILE_NAME;
|
||||
const fs::path versionFilePath = mConfigFolder / VERSION_FILE_NAME;
|
||||
|
||||
// Get latest version if any.
|
||||
string latestVersion;
|
||||
ifstream fiVer(versionionfile.str().c_str());
|
||||
ifstream fiVer(versionFilePath);
|
||||
if (fiVer.is_open())
|
||||
{
|
||||
fiVer >> latestVersion;
|
||||
@ -748,12 +722,12 @@ void ConfigurationManager::loadConfiguration(bool debug)
|
||||
hasBeenUpdated = true;
|
||||
if (debug)
|
||||
{
|
||||
std::cout << "MEGAcmd has been updated." << std::endl;
|
||||
COUT << "MEGAcmd has been updated." << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
// Store current version.
|
||||
ofstream fo(versionionfile.str().c_str(), ios::out);
|
||||
ofstream fo(versionFilePath, ios::out);
|
||||
if (fo.is_open())
|
||||
{
|
||||
fo << MEGACMD_CODE_VERSION;
|
||||
@ -761,14 +735,14 @@ void ConfigurationManager::loadConfiguration(bool debug)
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "Could not write MEGAcmd version to " << versionionfile.str() << std::endl;
|
||||
CERR << "Could not write MEGAcmd version to " << versionFilePath << std::endl;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
std::cout << "Couldnt access data folder " << std::endl;
|
||||
COUT << "Couldnt access data folder " << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -781,13 +755,8 @@ bool ConfigurationManager::lockExecution()
|
||||
auto runtimeDir = getAndCreateRuntimeDir();
|
||||
if (runtimeDir != configDir)
|
||||
{
|
||||
auto lockFileAtConfigDir = std::string(configDir).append(1, LocalPath::localPathSeparator_utf8).append(LOCK_FILE_NAME);
|
||||
|
||||
static MegaFileSystemAccess fsAccess;
|
||||
LocalPath localPath = LocalPath::fromAbsolutePath(lockFileAtConfigDir);
|
||||
static std::unique_ptr<FileAccess> fa(fsAccess.newfileaccess());
|
||||
bool lockFileAtConfigDirExists = fa->isfile(localPath);
|
||||
if (lockFileAtConfigDirExists)
|
||||
const fs::path lockFileAtConfigDir = configDir / LOCK_FILE_NAME;
|
||||
if (fs::is_regular_file(lockFileAtConfigDir))
|
||||
{
|
||||
LOG_warn << "Found a lock file from a previous MEGAcmd version. Will try to acquire the lock and remove it";
|
||||
bool legacyLockResult = lockExecution(configDir);
|
||||
@ -809,23 +778,15 @@ bool ConfigurationManager::lockExecution()
|
||||
return lockExecution(runtimeDir);
|
||||
}
|
||||
|
||||
bool ConfigurationManager::lockExecution(const std::string &lockFileFolder)
|
||||
bool ConfigurationManager::lockExecution(const fs::path &lockFileFolder)
|
||||
{
|
||||
assert(!lockFileFolder.empty());
|
||||
|
||||
stringstream lockfile;
|
||||
#ifdef _WIN32
|
||||
lockfile << "\\\\?\\";
|
||||
lockfile << lockFileFolder << "\\" << LOCK_FILE_NAME;
|
||||
#else
|
||||
lockfile << lockFileFolder << "/" << LOCK_FILE_NAME;
|
||||
#endif
|
||||
LOG_info << "Lock file: " << lockfile.str();
|
||||
const fs::path lockFilePath = lockFileFolder / LOCK_FILE_NAME;
|
||||
LOG_info << "Lock file: " << lockFilePath;
|
||||
|
||||
#ifdef _WIN32
|
||||
string wlockfile;
|
||||
MegaApi::utf8ToUtf16(lockfile.str().c_str(), &wlockfile);
|
||||
mLockFileHandle = CreateFileW((LPCWSTR)(wlockfile).data(), GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
mLockFileHandle = CreateFileW(lockFilePath.wstring().c_str(), GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
if (mLockFileHandle == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
LOG_err << "ERROR creating lock file: " << ERRNO;
|
||||
@ -833,7 +794,7 @@ bool ConfigurationManager::lockExecution(const std::string &lockFileFolder)
|
||||
return false;
|
||||
}
|
||||
#elif defined(LOCK_EX) && defined(LOCK_NB)
|
||||
fd = open(lockfile.str().c_str(), O_RDWR | O_CREAT, 0666); // open or create lockfile
|
||||
fd = open(lockFilePath.string().c_str(), O_RDWR | O_CREAT, 0666); // open or create lockfile
|
||||
//check open success...
|
||||
if (flock(fd, LOCK_EX | LOCK_NB))
|
||||
{
|
||||
@ -848,8 +809,9 @@ bool ConfigurationManager::lockExecution(const std::string &lockFileFolder)
|
||||
}
|
||||
|
||||
#else
|
||||
ifstream fi(thelockfile.c_str());
|
||||
if(!fi.fail()){
|
||||
ifstream fi(lockFilePath);
|
||||
if(!fi.fail())
|
||||
{
|
||||
close(fd);
|
||||
return false;
|
||||
}
|
||||
@ -857,7 +819,7 @@ bool ConfigurationManager::lockExecution(const std::string &lockFileFolder)
|
||||
{
|
||||
fi.close();
|
||||
}
|
||||
ofstream fo(thelockfile.c_str());
|
||||
ofstream fo(lockFilePath);
|
||||
if (fo.is_open())
|
||||
{
|
||||
fo.close();
|
||||
@ -872,60 +834,56 @@ bool ConfigurationManager::unlockExecution()
|
||||
return unlockExecution(getAndCreateRuntimeDir());
|
||||
}
|
||||
|
||||
bool ConfigurationManager::unlockExecution(const std::string &lockFileFolder)
|
||||
bool ConfigurationManager::unlockExecution(const fs::path &lockFileFolder)
|
||||
{
|
||||
assert(!lockFileFolder.empty());
|
||||
|
||||
stringstream lockfile;
|
||||
lockfile << lockFileFolder << LocalPath::localPathSeparator_utf8 << LOCK_FILE_NAME;
|
||||
|
||||
#ifdef _WIN32
|
||||
CloseHandle(mLockFileHandle);
|
||||
#elif defined(LOCK_EX) && defined(LOCK_NB)
|
||||
flock(fd, LOCK_UN | LOCK_NB);
|
||||
close(fd);
|
||||
#endif
|
||||
bool succeeded = !unlink(lockfile.str().c_str());
|
||||
if (!succeeded)
|
||||
{
|
||||
LOG_err << " Failed to remove lock file, errno = " << errno;
|
||||
}
|
||||
|
||||
return succeeded;
|
||||
const fs::path lockFilePath = lockFileFolder / LOCK_FILE_NAME;
|
||||
if (std::error_code ec; !fs::remove(lockFilePath, ec))
|
||||
{
|
||||
LOG_err << "Failed to remove lock file, error = " << errorCodeStr(ec);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
string ConfigurationManager::getConfigurationSValue(string propertyName)
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> g(settingsMutex);
|
||||
|
||||
if (!mConfigFolder.size())
|
||||
if (mConfigFolder.empty())
|
||||
{
|
||||
loadConfigDir();
|
||||
}
|
||||
if (mConfigFolder.size())
|
||||
if (!mConfigFolder.empty())
|
||||
{
|
||||
stringstream configFile;
|
||||
configFile << mConfigFolder << "/" << "megacmd.cfg";
|
||||
return getPropertyFromFile(configFile.str().c_str(),propertyName.c_str());
|
||||
const fs::path configFilePath = mConfigFolder / "megacmd.cfg";
|
||||
return getPropertyFromFile(configFilePath, propertyName.c_str());
|
||||
}
|
||||
return string();
|
||||
return "";
|
||||
}
|
||||
|
||||
void ConfigurationManager::clearConfigurationFile()
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> g(settingsMutex);
|
||||
|
||||
if (!mConfigFolder.size())
|
||||
if (mConfigFolder.empty())
|
||||
{
|
||||
loadConfigDir();
|
||||
}
|
||||
if (mConfigFolder.size())
|
||||
if (!mConfigFolder.empty())
|
||||
{
|
||||
stringstream configFile;
|
||||
configFile << mConfigFolder << "/" << "megacmd.cfg";
|
||||
const fs::path configFilePath = mConfigFolder / "megacmd.cfg";
|
||||
ifstream infile(configFilePath);
|
||||
|
||||
stringstream formerlines;
|
||||
ifstream infile(configFile.str().c_str());
|
||||
string line;
|
||||
while (getline(infile, line))
|
||||
{
|
||||
@ -949,8 +907,8 @@ void ConfigurationManager::clearConfigurationFile()
|
||||
formerlines << line << endl;
|
||||
}
|
||||
}
|
||||
ofstream fo(configFile.str().c_str());
|
||||
|
||||
ofstream fo(configFilePath);
|
||||
if (fo.is_open())
|
||||
{
|
||||
fo << formerlines.str();
|
||||
|
@ -32,14 +32,15 @@ namespace megacmd {
|
||||
class ConfigurationManager
|
||||
{
|
||||
private:
|
||||
static std::string mConfigFolder;
|
||||
static bool hasBeenUpdated;
|
||||
inline static fs::path mConfigFolder;
|
||||
inline static bool hasBeenUpdated = false;
|
||||
#ifdef WIN32
|
||||
static HANDLE mLockFileHandle;
|
||||
#elif defined(LOCK_EX) && defined(LOCK_NB)
|
||||
static int fd;
|
||||
#endif
|
||||
|
||||
static void createFolderIfNotExisting(const fs::path &folder);
|
||||
static void loadConfigDir();
|
||||
|
||||
static void removeSyncConfig(sync_struct *syncToRemove);
|
||||
@ -47,8 +48,8 @@ private:
|
||||
#ifdef MEGACMD_TESTING_CODE
|
||||
public:
|
||||
#endif
|
||||
static bool lockExecution(const std::string &lockFileFolder);
|
||||
static bool unlockExecution(const std::string &lockFileFolder);
|
||||
static bool lockExecution(const fs::path &lockFileFolder);
|
||||
static bool unlockExecution(const fs::path &lockFileFolder);
|
||||
|
||||
public:
|
||||
static std::map<std::string, sync_struct *> oldConfiguredSyncs; //This will refer to old syncs from now on
|
||||
@ -73,14 +74,45 @@ public:
|
||||
|
||||
static void saveSession(const char*session);
|
||||
|
||||
static void saveProperty(const char* property, const char* value);
|
||||
static std::string /* prev value, if any */ saveProperty(const char* property, const char* value);
|
||||
|
||||
template<typename T>
|
||||
static void savePropertyValue(const char* property, T value)
|
||||
template<typename T,
|
||||
typename Opt_T = std::optional<typename std::conditional_t<std::is_same_v<std::decay_t<T>, const char*>, std::string, T>>>
|
||||
static Opt_T savePropertyValue(const char* property, const T& value)
|
||||
{
|
||||
std::ostringstream os;
|
||||
os << value;
|
||||
saveProperty(property,os.str().c_str());
|
||||
constexpr bool isStr = std::is_same_v<std::remove_cv_t<T>, std::string>;
|
||||
constexpr bool isConstChar = std::is_same_v<std::decay_t<T>, const char*>;
|
||||
|
||||
std::string prevValueStr;
|
||||
if constexpr (isStr)
|
||||
{
|
||||
prevValueStr = saveProperty(property, value.c_str());
|
||||
}
|
||||
else if constexpr (isConstChar)
|
||||
{
|
||||
prevValueStr = saveProperty(property, value);
|
||||
}
|
||||
else
|
||||
{
|
||||
prevValueStr = saveProperty(property, std::to_string(value).c_str());
|
||||
}
|
||||
|
||||
if (prevValueStr.empty())
|
||||
{
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
if constexpr (isStr || isConstChar)
|
||||
{
|
||||
return prevValueStr;
|
||||
}
|
||||
else
|
||||
{
|
||||
T prevValue;
|
||||
std::istringstream is(prevValueStr);
|
||||
is >> prevValue;
|
||||
return prevValue;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
@ -235,12 +267,12 @@ public:
|
||||
return toret;
|
||||
}
|
||||
|
||||
static std::string getConfigFolder();
|
||||
static fs::path getConfigFolder();
|
||||
|
||||
// creates a subfolder within the state dir and returns it (utf8)
|
||||
static std::string getConfigFolderSubdir(const std::string &utf8Name);
|
||||
static std::string getAndCreateRuntimeDir();
|
||||
static std::string getAndCreateConfigDir();
|
||||
static fs::path getConfigFolderSubdir(const fs::path& subdirName);
|
||||
static fs::path getAndCreateRuntimeDir();
|
||||
static fs::path getAndCreateConfigDir();
|
||||
|
||||
static bool getHasBeenUpdated();
|
||||
|
||||
|
@ -19,7 +19,6 @@
|
||||
#include "listeners.h"
|
||||
#include "configurationmanager.h"
|
||||
#include "megacmdutils.h"
|
||||
#include "megacmdtransfermanager.h"
|
||||
|
||||
#include <utility>
|
||||
|
||||
@ -139,10 +138,10 @@ void MegaCmdGlobalListener::onNodesUpdate(MegaApi *api, MegaNodeList *nodes)
|
||||
nFiles += details->getNumFiles(handle);
|
||||
nFolders += details->getNumFolders(handle);
|
||||
}
|
||||
auto inboxNode = std::unique_ptr<MegaNode>(api->getInboxNode());
|
||||
if (inboxNode != nullptr)
|
||||
auto vaultNode = std::unique_ptr<MegaNode>(api->getVaultNode());
|
||||
if (vaultNode != nullptr)
|
||||
{
|
||||
auto handle = inboxNode->getHandle();
|
||||
auto handle = vaultNode->getHandle();
|
||||
nFiles += details->getNumFiles(handle);
|
||||
nFolders += details->getNumFolders(handle);
|
||||
}
|
||||
@ -391,11 +390,6 @@ void MegaCmdGlobalListener::onEvent(MegaApi *api, MegaEvent *event)
|
||||
else if (event->getType() == MegaEvent::EVENT_NODES_CURRENT)
|
||||
{
|
||||
sandboxCMD->mNodesCurrentPromise.fulfil();
|
||||
#ifdef HAVE_DOWNLOADS_COMMAND
|
||||
// we need to cancel transfers here, because, even if fetchnodes finished, the actual transfer resumption
|
||||
// won't happen until all action packets are received. And cancellation of transfers need them to be loaded already
|
||||
std::thread([this](){sandboxCMD->cmdexecuter->cleanSlateTranfers();}).detach();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@ -522,6 +516,10 @@ void MegaCmdMegaListener::onSyncAdded(MegaApi *api, MegaSync *sync)
|
||||
sendEvent(StatsManager::MegacmdEvent::FIRST_CONFIGURED_SYNC, api, false);
|
||||
ConfigurationManager::savePropertyValue("firstSyncConfigured", true);
|
||||
}
|
||||
else
|
||||
{
|
||||
sendEvent(StatsManager::MegacmdEvent::SUBSEQUENT_CONFIGURED_SYNC, api, false);
|
||||
}
|
||||
}
|
||||
|
||||
void MegaCmdMegaListener::onSyncStateChanged(MegaApi *api, MegaSync *sync)
|
||||
@ -536,7 +534,7 @@ void MegaCmdMegaListener::onSyncStateChanged(MegaApi *api, MegaSync *sync)
|
||||
}
|
||||
auto msg = ss.str();
|
||||
|
||||
if (sync->getError() || sync->getRunState() >= MegaSync::RUNSTATE_PAUSED)
|
||||
if (sync->getError() || sync->getRunState() >= MegaSync::RUNSTATE_SUSPENDED)
|
||||
{
|
||||
broadcastDelayedMessage(msg, true);
|
||||
}
|
||||
@ -1142,13 +1140,6 @@ long long MegaCmdMultiTransferListener::getOngoingTotalBytes()
|
||||
return total;
|
||||
}
|
||||
|
||||
#ifdef HAVE_DOWNLOADS_COMMAND
|
||||
std::vector<DownloadId> MegaCmdMultiTransferListener::getStartedTransfers() const
|
||||
{
|
||||
return mStartedTransfers;
|
||||
}
|
||||
#endif
|
||||
|
||||
bool MegaCmdMultiTransferListener::getProgressinformed() const
|
||||
{
|
||||
return progressinformed;
|
||||
@ -1191,9 +1182,6 @@ void MegaCmdMultiTransferListener::onTransferStarted(const std::string &path, in
|
||||
{
|
||||
std::lock_guard<std::mutex> g(mStartedTransfersMutex);
|
||||
mStartedTransfersCount++;
|
||||
#ifdef HAVE_DOWNLOADS_COMMAND
|
||||
mStartedTransfers.emplace_back(DownloadId(tag,path));
|
||||
#endif
|
||||
mStartedConditionVariable.notify_one();
|
||||
}
|
||||
}
|
||||
@ -1212,13 +1200,6 @@ MegaCmdGlobalTransferListener::MegaCmdGlobalTransferListener(MegaApi *megaApi, M
|
||||
|
||||
void MegaCmdGlobalTransferListener::onTransferFinish(MegaApi* api, MegaTransfer *transfer, MegaError* error)
|
||||
{
|
||||
#ifdef HAVE_DOWNLOADS_COMMAND
|
||||
if (transfer->getType() == transfer->TYPE_DOWNLOAD && ConfigurationManager::getConfigurationValue("downloads_tracking_enabled", false))
|
||||
{
|
||||
DownloadsManager::Instance().onTransferFinish(api, transfer, error);
|
||||
}
|
||||
#endif
|
||||
|
||||
completedTransfersMutex.lock();
|
||||
completedTransfers.push_front(transfer->copy());
|
||||
|
||||
@ -1242,24 +1223,6 @@ void MegaCmdGlobalTransferListener::onTransferFinish(MegaApi* api, MegaTransfer
|
||||
completedTransfersMutex.unlock();
|
||||
}
|
||||
|
||||
void MegaCmdGlobalTransferListener::onTransferStart(MegaApi* api, MegaTransfer *transfer)
|
||||
{
|
||||
#ifdef HAVE_DOWNLOADS_COMMAND
|
||||
if (transfer->getType() == transfer->TYPE_DOWNLOAD && ConfigurationManager::getConfigurationValue("downloads_tracking_enabled", false))
|
||||
{
|
||||
DownloadsManager::Instance().onTransferStart(api, transfer);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
void MegaCmdGlobalTransferListener::onTransferUpdate(MegaApi* api, MegaTransfer *transfer)
|
||||
{
|
||||
#ifdef HAVE_DOWNLOADS_COMMAND
|
||||
if (transfer->getType() == transfer->TYPE_DOWNLOAD && ConfigurationManager::getConfigurationValue("downloads_tracking_enabled", false))
|
||||
{
|
||||
DownloadsManager::Instance().onTransferUpdate(api, transfer);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
void MegaCmdGlobalTransferListener::onTransferTemporaryError(MegaApi *api, MegaTransfer *transfer, MegaError* e)
|
||||
{
|
||||
if (e && e->getErrorCode() == MegaError::API_EOVERQUOTA && e->getValue())
|
||||
@ -1276,13 +1239,6 @@ void MegaCmdGlobalTransferListener::onTransferTemporaryError(MegaApi *api, MegaT
|
||||
sandboxCMD->timeOfOverquota = m_time(NULL);
|
||||
sandboxCMD->secondsOverQuota=e->getValue();
|
||||
}
|
||||
|
||||
#ifdef HAVE_DOWNLOADS_COMMAND
|
||||
if (transfer->getType() == transfer->TYPE_DOWNLOAD && ConfigurationManager::getConfigurationValue("downloads_tracking_enabled", false))
|
||||
{
|
||||
DownloadsManager::Instance().onTransferUpdate(api, transfer);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
bool MegaCmdGlobalTransferListener::onTransferData(MegaApi *api, MegaTransfer *transfer, char *buffer, size_t size) {return false;};
|
||||
@ -1302,14 +1258,14 @@ bool MegaCmdCatTransferListener::onTransferData(MegaApi *api, MegaTransfer *tran
|
||||
{
|
||||
if (!ls->isClientConnected())
|
||||
{
|
||||
LOG_debug << " CatTransfer listener, cancelled transfer due to client disconnected";
|
||||
LOG_verbose << " CatTransfer listener, cancelled transfer due to client disconnected";
|
||||
api->cancelTransfer(transfer);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
LOG_debug << " CatTransfer listener, streaming " << size << " bytes"; //TODO: verbose
|
||||
*ls << string(buffer,size);
|
||||
LOG_verbose << " CatTransfer listener, streaming " << size << " bytes";
|
||||
*ls << BinaryStringView(buffer, size);
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -1326,40 +1282,29 @@ ATransferListener::~ATransferListener()
|
||||
|
||||
}
|
||||
|
||||
|
||||
void ATransferListener::onTransferStart(MegaApi *api, MegaTransfer *transfer)
|
||||
{
|
||||
auto tag = transfer->getTag();
|
||||
#ifdef HAVE_DOWNLOADS_COMMAND
|
||||
if (transfer->getType() == transfer->TYPE_DOWNLOAD && ConfigurationManager::getConfigurationValue("downloads_tracking_enabled", false))
|
||||
{
|
||||
DownloadsManager::Instance().addNewTopLevelTransfer(api, transfer, tag, mPath);
|
||||
}
|
||||
#endif
|
||||
mMultiTransferListener->onTransferStarted(mPath, tag);
|
||||
mMultiTransferListener->onTransferStart(api, transfer);
|
||||
}
|
||||
|
||||
|
||||
void ATransferListener::onTransferFinish(MegaApi *api, MegaTransfer *transfer, MegaError *e)
|
||||
{
|
||||
static_cast<MegaTransferListener *>(mMultiTransferListener.get())->onTransferFinish(api, transfer, e);
|
||||
delete this;
|
||||
}
|
||||
|
||||
|
||||
void ATransferListener::onTransferUpdate(MegaApi *api, MegaTransfer *transfer)
|
||||
{
|
||||
mMultiTransferListener->onTransferUpdate(api, transfer);
|
||||
}
|
||||
|
||||
|
||||
void ATransferListener::onTransferTemporaryError(MegaApi *api, MegaTransfer *transfer, MegaError *e)
|
||||
{
|
||||
mMultiTransferListener->onTransferTemporaryError(api, transfer, e);
|
||||
}
|
||||
|
||||
|
||||
bool ATransferListener::onTransferData(MegaApi *api, MegaTransfer *transfer, char *buffer, size_t size)
|
||||
{
|
||||
return mMultiTransferListener->onTransferData(api, transfer, buffer, size);
|
||||
|
@ -21,8 +21,6 @@
|
||||
|
||||
#include "megacmdlogger.h"
|
||||
#include "megacmdsandbox.h"
|
||||
#include "megacmdtransfermanager.h"
|
||||
|
||||
|
||||
namespace megacmd {
|
||||
class MegaCmdSandbox;
|
||||
@ -150,10 +148,6 @@ private:
|
||||
std::condition_variable mStartedConditionVariable;
|
||||
unsigned mStartedTransfersCount = 0;
|
||||
|
||||
#ifdef HAVE_DOWNLOADS_COMMAND
|
||||
// string to tag map
|
||||
std::vector<DownloadId> mStartedTransfers;
|
||||
#endif
|
||||
public:
|
||||
MegaCmdMultiTransferListener(mega::MegaApi *megaApi, MegaCmdSandbox * sandboxCMD, mega::MegaTransferListener *listener = NULL, int clientID=-1);
|
||||
virtual ~MegaCmdMultiTransferListener();
|
||||
@ -180,10 +174,6 @@ public:
|
||||
|
||||
bool getProgressinformed() const;
|
||||
|
||||
#ifdef HAVE_DOWNLOADS_COMMAND
|
||||
std::vector<DownloadId> getStartedTransfers() const;
|
||||
#endif
|
||||
|
||||
protected:
|
||||
mega::MegaTransferListener *listener;
|
||||
};
|
||||
@ -301,14 +291,10 @@ public:
|
||||
virtual ~MegaCmdGlobalTransferListener();
|
||||
|
||||
//Transfer callbacks
|
||||
void onTransferStart(mega::MegaApi* api, mega::MegaTransfer *transfer);
|
||||
void onTransferFinish(mega::MegaApi* api, mega::MegaTransfer *transfer, mega::MegaError* error);
|
||||
|
||||
void onTransferUpdate(mega::MegaApi* api, mega::MegaTransfer *transfer);
|
||||
void onTransferTemporaryError(mega::MegaApi *api, mega::MegaTransfer *transfer, mega::MegaError* e);
|
||||
bool onTransferData(mega::MegaApi *api, mega::MegaTransfer *transfer, char *buffer, size_t size);
|
||||
|
||||
|
||||
protected:
|
||||
mega::MegaApi *megaApi;
|
||||
mega::MegaTransferListener *listener;
|
||||
|
435
src/megacmd.cpp
435
src/megacmd.cpp
@ -16,6 +16,7 @@
|
||||
* program.
|
||||
*/
|
||||
|
||||
#include "megacmdcommonutils.h"
|
||||
#include "megacmd.h"
|
||||
|
||||
#include "megaapi.h"
|
||||
@ -778,24 +779,6 @@ void insertValidParamsPerCommand(set<string> *validParams, string thecommand, se
|
||||
{
|
||||
validOptValues->insert("clientID");
|
||||
}
|
||||
#ifdef HAVE_DOWNLOADS_COMMAND
|
||||
else if ("downloads" == thecommand)
|
||||
{
|
||||
validParams->insert("show-subtransfers");
|
||||
validParams->insert("report-all");
|
||||
validParams->insert("disable-tracking");
|
||||
validParams->insert("enable-tracking");
|
||||
validParams->insert("query-enabled");
|
||||
|
||||
validParams->insert("enable-clean-slate");
|
||||
validParams->insert("disable-clean-slate");
|
||||
validParams->insert("purge");
|
||||
|
||||
validOptValues->insert("path-display-size");
|
||||
validOptValues->insert("col-separator");
|
||||
validOptValues->insert("output-cols");
|
||||
}
|
||||
#endif
|
||||
else if ("transfers" == thecommand)
|
||||
{
|
||||
validParams->insert("show-completed");
|
||||
@ -2013,12 +1996,6 @@ const char * getUsageStr(const char *command, const HelpFlags& flags)
|
||||
{
|
||||
return "transfers [-c TAG|-a] | [-r TAG|-a] | [-p TAG|-a] [--only-downloads | --only-uploads] [SHOWOPTIONS]";
|
||||
}
|
||||
#ifdef HAVE_DOWNLOADS_COMMAND
|
||||
if (!strcmp(command, "downloads"))
|
||||
{
|
||||
return "downloads [--purge|--enable-clean-slate|--disable-clean-slate|--enable-tracking|--disable-tracking|query-enabled|report-all| [id_1 id_2 ... id_n]] [SHOWOPTIONS]";
|
||||
}
|
||||
#endif
|
||||
if (((flags.win && !flags.readline) || flags.showAll) && !strcmp(command, "autocomplete"))
|
||||
{
|
||||
return "autocomplete [dos | unix]";
|
||||
@ -2175,7 +2152,7 @@ string getHelpStr(const char *command, const HelpFlags& flags = {})
|
||||
os << "with image or video extensions that are not really images or videos," << endl;
|
||||
os << "or that are encrypted in the local drive so they can't be analyzed anyway." << endl;
|
||||
os << endl;
|
||||
os << "Notice that this setting will be saved for the next time you open MEGAcmd" << endl;
|
||||
os << "Notice that this setting will be saved for the next time you open MEGAcmd, but will be removed if you logout." << endl;
|
||||
}
|
||||
else if (!strcmp(command, "signup"))
|
||||
{
|
||||
@ -2313,13 +2290,14 @@ string getHelpStr(const char *command, const HelpFlags& flags = {})
|
||||
}
|
||||
else if (!strcmp(command, "log"))
|
||||
{
|
||||
os << "Prints/Modifies the current logs level" << endl;
|
||||
os << "Prints/Modifies the log level" << endl;
|
||||
os << endl;
|
||||
os << "Options:" << endl;
|
||||
os << " -c" << "\t" << "CMD log level (higher level messages)." << endl;
|
||||
os << " " << "\t" << " Messages captured by MEGAcmd server." << endl;
|
||||
os << " -s" << "\t" << "SDK log level (lower level messages)." << endl;
|
||||
os << " " << "\t" << " Messages captured by the engine and libs" << endl;
|
||||
os << "Note: this setting will be saved for the next time you open MEGAcmd, but will be removed if you logout." << endl;
|
||||
|
||||
os << endl;
|
||||
os << "Regardless of the log level of the" << endl;
|
||||
@ -2525,7 +2503,7 @@ string getHelpStr(const char *command, const HelpFlags& flags = {})
|
||||
os << "HTTPS is not necesary since all data is stored and transfered encrypted." << endl;
|
||||
os << "Enabling it will increase CPU usage and add network overhead." << endl;
|
||||
os << endl;
|
||||
os << "Notice that this setting will be saved for the next time you open MEGAcmd" << endl;
|
||||
os << "Notice that this setting will be saved for the next time you open MEGAcmd, but will be removed if you logout." << endl;
|
||||
}
|
||||
else if (!strcmp(command, "deleteversions"))
|
||||
{
|
||||
@ -2573,6 +2551,7 @@ string getHelpStr(const char *command, const HelpFlags& flags = {})
|
||||
os << endl;
|
||||
os << "*If you serve more than one location, these parameters will be ignored and use those of the first location served." << endl;
|
||||
os << " If you want to change those parameters, you need to stop serving all locations and configure them again." << endl;
|
||||
os << "Note: WEBDAV settings and locations will be saved for the next time you open MEGAcmd, but will be removed if you logout." << endl;
|
||||
os << endl;
|
||||
os << "Caveat: This functionality is in BETA state. It might not be available on all platforms. If you experience any issue with this, please contact: support@mega.nz" << endl;
|
||||
os << endl;
|
||||
@ -2602,6 +2581,7 @@ string getHelpStr(const char *command, const HelpFlags& flags = {})
|
||||
os << endl;
|
||||
os << "*If you serve more than one location, these parameters will be ignored and used those of the first location served." << endl;
|
||||
os << " If you want to change those parameters, you need to stop serving all locations and configure them again." << endl;
|
||||
os << "Note: FTP settings and locations will be saved for the next time you open MEGAcmd, but will be removed if you logout." << endl;
|
||||
os << endl;
|
||||
os << "Caveat: This functionality is in BETA state. It might not be available on all platforms. If you experience any issue with this, please contact: support@mega.nz" << endl;
|
||||
os << endl;
|
||||
@ -2679,8 +2659,8 @@ string getHelpStr(const char *command, const HelpFlags& flags = {})
|
||||
os << " " << "\t" << "The \"--all\" argument can be used to show the details of all issues." << endl;
|
||||
os << " --limit=rowcount " << "\t" << "Limits the amount of rows displayed. Set to 0 to display unlimited rows. Default is 10. Can also be combined with \"--detail\"." << endl;
|
||||
os << " --disable-path-collapse " << "\t" << "Ensures all paths are fully shown. By default long paths are truncated for readability." << endl;
|
||||
os << " --enable-warning " << "\t" << "Enables the notification that appears when issues are detected. This setting is stored locally for all users." << endl;
|
||||
os << " --disable-warning " << "\t" << "Disables the notification that appears when issues are detected. This setting is stored locally for all users." << endl;
|
||||
os << " --enable-warning " << "\t" << "Enables the notification that appears when issues are detected. This setting is saved for the next time you open MEGAcmd, but will be removed if you logout." << endl;
|
||||
os << " --disable-warning " << "\t" << "Disables the notification that appears when issues are detected. This setting is saved for the next time you open MEGAcmd, but will be removed if you logout." << endl;
|
||||
printColumnDisplayerHelp(os);
|
||||
os << endl;
|
||||
os << "DISPLAYED columns:" << endl;
|
||||
@ -3023,6 +3003,8 @@ string getHelpStr(const char *command, const HelpFlags& flags = {})
|
||||
os << " --username=USERNAME" << "\t" << "The username, for authenticated proxies" << endl;
|
||||
os << " --password=PASSWORD" << "\t" << "The password, for authenticated proxies. Please, avoid using passwords containing \" or '" << endl;
|
||||
|
||||
os << endl;
|
||||
os << "Note: Proxy settings will be saved for the next time you open MEGAcmd, but will be removed if you logout." << endl;
|
||||
}
|
||||
else if (!strcmp(command, "cat"))
|
||||
{
|
||||
@ -3136,90 +3118,6 @@ string getHelpStr(const char *command, const HelpFlags& flags = {})
|
||||
os << "To only exit current shell and keep server running, use \"exit --only-shell\"" << endl;
|
||||
}
|
||||
}
|
||||
#ifdef HAVE_DOWNLOADS_COMMAND
|
||||
else if (!strcmp(command, "downloads"))
|
||||
{
|
||||
os << "Lists or configure downloads tracking and reporting." << endl;
|
||||
os << endl;
|
||||
os << "It will print the information regarding one or more downloads give their tags or object ids"<< endl;
|
||||
os << " (both will be reported when using \"get\" with -q)." << endl;
|
||||
os << "IMPORTANT: it is disabled by default, you need to enable it with \"downloads --enable-tracking\"." << endl;
|
||||
os << endl;
|
||||
os << "Options:" << endl;
|
||||
os << " --query-enabled" << "\t" << "Indicates if download tracking is enabled" << endl;
|
||||
os << " --enable-tracking" << "\t" << "Starts tracking downloads. It will store the information in a sqlite3 db" << endl;
|
||||
os << " --disable-tracking" << "\t" << "Stops tracking downloads. Notice, it will remove the associated database" << endl;
|
||||
os << " --enable-clean-slate" << "\t" << "Transfers from previous executions will be discarded upon restart" << endl;
|
||||
os << " --disable-clean-slate" << "\t" << "Transfers from previous executions will not be discarded upon restart" << endl;
|
||||
os << " --purge" << "\t" << "Cancells all onging transfers, and cleans all tracking (included persisted data)" << endl;
|
||||
|
||||
os << endl;
|
||||
os << "Show options:" << endl;
|
||||
os << " --report-all" << "\t" << "Prints a report of all active and finished downloads kept in memory" << endl;
|
||||
os << " --show-subtransfers" << "\t" << "Show information regarding transfers" << endl;
|
||||
os << " --path-display-size=N" << "\t" << "Use at least N characters for displaying paths" << endl;
|
||||
printColumnDisplayerHelp(os);
|
||||
os << endl;
|
||||
os << "Displaying cols:" << endl;
|
||||
os << " OBJECT_ID" << "\t" << "Id of the object (it will always be the same for the same download)" << endl;
|
||||
os << " SUB_STARTED" << "\t" << "Number of subtransfers started" << endl;
|
||||
os << " SUB_OK" << "\t" << "Number of subtransfers that completed ok" << endl;
|
||||
os << " SUB_FAIL" << "\t" << "Number of subtransfers that completed with some error" << endl;
|
||||
os << " SUBTRANSFER" << "\t" << "Tag of the subtransfers (only when using --show-subtransfers)" << endl;
|
||||
os << " ERROR_CODE" << "\t" << "Error of the transfer (if any)" << endl;
|
||||
os << " TYPE" << "\t" << "Type of transfer (see below)" << endl;
|
||||
os << " TAG" << "\t" << "A tag that uniquely identifies a tranfer in current execution of MEGAcmd" << endl;
|
||||
os << " SOURCEPATH" << "\t" << "Path of the folder/file downloaded" << endl;
|
||||
os << " DESTINYPATH" << "\t" << "Local path for the downloaded file/folder" << endl;
|
||||
os << " PROGRESS" << "\t" << "Human readable progress of the download" << endl;
|
||||
os << " STATE" << "\t" << "State of the transfer. " << endl;
|
||||
os << " " << "\t" << " Values:" << endl;
|
||||
os << " " << "\t" << " QUEUED:" << "\t" << "queued in the system, waiting for an slot to be assigned" << endl;
|
||||
os << " " << "\t" << " ACTIVE:" << "\t" << "doing I/O" << endl;
|
||||
os << " " << "\t" << " PAUSED:" << "\t" << "paused" << endl;
|
||||
os << " " << "\t" << " RETRYING:" << "\t" << "retrying after some potentially recoverable error" << endl;
|
||||
os << " " << "\t" << " COMPLETING:" << "\t" << "final stages (e.g: moving temporal transfer file to its final destination)" << endl;
|
||||
os << " " << "\t" << " COMPLETED:" << "\t" << "finished ok" << endl;
|
||||
os << " " << "\t" << " CANCELLED:" << "\t" << "cancelled" << endl;
|
||||
os << " " << "\t" << " FAILED:" << "\t" << "Failed (or subtransfers failed)" << endl;
|
||||
|
||||
os << " TRANSFERRED" << "\t" << "Number of bytes transferred" << endl;
|
||||
os << " TOTAL" << "\t" << "Number of total bytes to be transferred" << endl;
|
||||
os << endl;
|
||||
os << "TYPE legend correspondence:" << endl;
|
||||
#ifdef _WIN32
|
||||
|
||||
const string cD = getutf8fromUtf16(L"\u25bc");
|
||||
const string cU = getutf8fromUtf16(L"\u25b2");
|
||||
const string cS = getutf8fromUtf16(L"\u21a8");
|
||||
const string cB = getutf8fromUtf16(L"\u2191");
|
||||
#else
|
||||
const string cD = "\u21d3";
|
||||
const string cU = "\u21d1";
|
||||
const string cS = "\u21f5";
|
||||
const string cB = "\u23eb";
|
||||
#endif
|
||||
os << " " << cD <<" = \t" << "Download transfer" << endl;
|
||||
os << " " << cU <<" = \t" << "Upload transfer" << endl;
|
||||
os << " " << cS <<" = \t" << "Sync transfer. The transfer is done in the context of a synchronization" << endl;
|
||||
os << " " << cB <<" = \t" << "Backup transfer. The transfer is done in the context of a backup" << endl;
|
||||
|
||||
os << endl;
|
||||
os << "Configuration values" << endl;
|
||||
os << "In your configuration folder (HOME/Appdata) there is megacmd.cfg configuration file." << endl;
|
||||
os << "This are the properties used in the downloads tracking & report mechanism:" << endl;
|
||||
os << " downloads_tracking_enabled" << "\t" << "If downloads tracking is enabled. Default=0 (false)!" << endl;
|
||||
os << " downloads_tracking_max_finished_in_memory_high_threshold" << "\t" << "Max number of downloads to keep in memory. It this is surpassed, " << endl;
|
||||
os << " " << "\t" << "finished transfers will start to be deleted (first the least recently updated)." << endl;
|
||||
os << " " << "\t" << "Note: you can still get the information from the db using OJBECT_ID." << endl;
|
||||
os << " " << "\t" << "Default=40000" << endl;
|
||||
os << " downloads_tracking_max_finished_in_memory_low_threshold" << "\t" << "When pruning is executed it will clean until this threshold. Default=20000" << endl;
|
||||
os << " downloads_db_path" << "\t" << "Path to store tracking information of downloads. Default: ~/.megaCmd/downloads.db" << endl;
|
||||
os << " downloads_db_io_frequency_ms" << "\t" << "Frequency in milliseconds to commit pending changes in the database. Default=10000" << endl;
|
||||
os << " downloads_db_max_queued_changes" << "\t" << "Max allowed number of changes to be queued before writting. Default=1000" << endl;
|
||||
os << " downloads_cleanslate_enabled" << "\t" << "If transfers from previous executions will be discarded upon restart. Default=0 (false)" << endl;
|
||||
}
|
||||
#endif
|
||||
else if (!strcmp(command, "transfers"))
|
||||
{
|
||||
os << "List or operate with transfers" << endl;
|
||||
@ -3244,10 +3142,10 @@ string getHelpStr(const char *command, const HelpFlags& flags = {})
|
||||
os << "TYPE legend correspondence:" << endl;
|
||||
#ifdef _WIN32
|
||||
|
||||
const string cD = getutf8fromUtf16(L"\u25bc");
|
||||
const string cU = getutf8fromUtf16(L"\u25b2");
|
||||
const string cS = getutf8fromUtf16(L"\u21a8");
|
||||
const string cB = getutf8fromUtf16(L"\u2191");
|
||||
const string cD = utf16ToUtf8(L"\u25bc");
|
||||
const string cU = utf16ToUtf8(L"\u25b2");
|
||||
const string cS = utf16ToUtf8(L"\u21a8");
|
||||
const string cB = utf16ToUtf8(L"\u2191");
|
||||
#else
|
||||
const string cD = "\u21d3";
|
||||
const string cU = "\u21d1";
|
||||
@ -3833,32 +3731,32 @@ bool executeUpdater(bool *restartRequired, bool doNotInstall = false)
|
||||
|
||||
if ( pidupdater == 0 )
|
||||
{
|
||||
char * donotinstallstr = NULL;
|
||||
const char * donotinstallstr = NULL;
|
||||
if (doNotInstall)
|
||||
{
|
||||
donotinstallstr = "--do-not-install";
|
||||
}
|
||||
|
||||
auto versionStr = std::to_string(MEGACMD_CODE_VERSION);
|
||||
char* version = const_cast<char*>(versionStr.c_str());
|
||||
const char* version = const_cast<char*>(versionStr.c_str());
|
||||
|
||||
#ifdef __MACH__
|
||||
#ifndef NDEBUG
|
||||
char * args[] = {"./mega-cmd-updater", "--normal-update", donotinstallstr, "--version", version, NULL};
|
||||
const char * args[] = {"./mega-cmd-updater", "--normal-update", donotinstallstr, "--version", version, NULL};
|
||||
#else
|
||||
char * args[] = {"/Applications/MEGAcmd.app/Contents/MacOS/MEGAcmdUpdater", "--normal-update", donotinstallstr, "--version", version, NULL};
|
||||
const char * args[] = {"/Applications/MEGAcmd.app/Contents/MacOS/MEGAcmdUpdater", "--normal-update", donotinstallstr, "--version", version, NULL};
|
||||
#endif
|
||||
#else //linux doesn't use autoupdater: this is just for testing
|
||||
#ifndef NDEBUG
|
||||
char * args[] = {"./mega-cmd-updater", "--normal-update", donotinstallstr, "--version", version, NULL}; // notice: won't work after lcd
|
||||
const char * args[] = {"./mega-cmd-updater", "--normal-update", donotinstallstr, "--version", version, NULL}; // notice: won't work after lcd
|
||||
#else
|
||||
char * args[] = {"mega-cmd-updater", "--normal-update", donotinstallstr, "--version", version, NULL};
|
||||
const char * args[] = {"mega-cmd-updater", "--normal-update", donotinstallstr, "--version", version, NULL};
|
||||
#endif
|
||||
#endif
|
||||
|
||||
LOG_verbose << "Exec updater line: " << args[0] << " " << args[1] << " " << args[2];
|
||||
|
||||
if (execvp(args[0], args) < 0)
|
||||
if (execvp(args[0], const_cast<char* const*>(args)) < 0)
|
||||
{
|
||||
|
||||
LOG_err << " FAILED to initiate updater. errno = " << ERRNO;
|
||||
@ -3944,16 +3842,16 @@ bool restartServer()
|
||||
pid_t childid = fork();
|
||||
if ( childid ) //parent
|
||||
{
|
||||
char **argv = new char*[mcmdMainArgc+3];
|
||||
const char **argv = new const char*[mcmdMainArgc+3];
|
||||
int i = 0, j = 0;
|
||||
|
||||
#ifdef __linux__
|
||||
string executable = mcmdMainArgv[0];
|
||||
string executable = const_cast<char* const>(mcmdMainArgv[0]);
|
||||
if (executable.find("/") != 0)
|
||||
{
|
||||
executable.insert(0, getCurrentExecPath()+"/");
|
||||
}
|
||||
argv[0]=(char *)executable.c_str();
|
||||
argv[0] = executable.c_str();
|
||||
i++;
|
||||
j++;
|
||||
#endif
|
||||
@ -3970,12 +3868,11 @@ bool restartServer()
|
||||
}
|
||||
}
|
||||
|
||||
argv[j++]="--wait-for";
|
||||
argv[j++]=(char*)SSTR(childid).c_str();
|
||||
argv[j++]=NULL;
|
||||
|
||||
argv[j++] = "--wait-for";
|
||||
argv[j++] = std::to_string(childid).c_str();
|
||||
argv[j++] = NULL;
|
||||
LOG_debug << "Restarting the server : <" << argv[0] << ">";
|
||||
execv(argv[0],argv);
|
||||
execv(argv[0], const_cast<char* const*>(argv));
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -4015,8 +3912,33 @@ bool isBareCommand(const char *l, const string &command)
|
||||
return true;
|
||||
}
|
||||
|
||||
void MegaCmdExecuter::mayExecutePendingStuffInWorkerThread()
|
||||
{
|
||||
{ // send INVALID_UTF8_INCIDENCES if there have been incidences
|
||||
static std::mutex mutexSendEventInvalidUtf8Incidences;
|
||||
std::lock_guard<std::mutex> g(mutexSendEventInvalidUtf8Incidences);
|
||||
|
||||
if (auto incidencesFound = sInvalidUtf8Incidences.exchange(0))
|
||||
{
|
||||
static HammeringLimiter hammeringLimiter(10);
|
||||
if (!hammeringLimiter.runRecently())
|
||||
{
|
||||
LOG_err << "Invalid utf8 accumulated occurences: " << incidencesFound;
|
||||
sendEvent(StatsManager::MegacmdEvent::INVALID_UTF8_INCIDENCES, api, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
// add them again to the count, to be reconsidered later.
|
||||
sInvalidUtf8Incidences += incidencesFound;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static bool process_line(const std::string_view line)
|
||||
{
|
||||
cmdexecuter->mayExecutePendingStuffInWorkerThread();
|
||||
|
||||
const char* l = line.data();
|
||||
assert(line.size() == strlen(l)); // string_view does not guarantee null termination, which is depended upon
|
||||
switch (prompt)
|
||||
@ -4195,10 +4117,10 @@ void* doProcessLine(void* infRaw)
|
||||
LoggedStreamPartialOutputs ls(cm, inf.get());
|
||||
setCurrentThreadOutStream(ls);
|
||||
|
||||
setCurrentThreadIsCmdShell(!inf->line.empty() && inf->line[0] == 'X');
|
||||
setCurrentThreadIsCmdShell(inf->isFromCmdShell());
|
||||
|
||||
|
||||
LOG_verbose << " Processing " << inf->line << " in thread: " << MegaThread::currentThreadId() << " " << inf->getPetitionDetails();
|
||||
LOG_verbose << " Processing " << inf->getRedactedLine() << " in thread: " << MegaThread::currentThreadId() << " " << inf->getPetitionDetails();
|
||||
|
||||
doExit = process_line(inf->getUniformLine());
|
||||
|
||||
@ -4208,7 +4130,7 @@ void* doProcessLine(void* infRaw)
|
||||
LOG_verbose << " Exit registered upon process_line: " ;
|
||||
}
|
||||
|
||||
LOG_verbose << " Procesed " << inf->line << " in thread: " << MegaThread::currentThreadId() << " " << inf->getPetitionDetails();
|
||||
LOG_verbose << " Procesed " << inf->getRedactedLine() << " in thread: " << MegaThread::currentThreadId() << " " << inf->getPetitionDetails();
|
||||
|
||||
MegaThread * petitionThread = inf->getPetitionThread();
|
||||
|
||||
@ -4331,12 +4253,6 @@ void finalize(bool waitForRestartSignal_param)
|
||||
alreadyfinalized = true;
|
||||
LOG_info << "closing application ...";
|
||||
|
||||
#ifdef HAVE_DOWNLOADS_COMMAND
|
||||
LOG_debug << "Shuting down downloads manager";
|
||||
DownloadsManager::Instance().shutdown(false);
|
||||
LOG_debug << "Downloads manager shut down";
|
||||
#endif
|
||||
|
||||
delete_finished_threads();
|
||||
if (!consoleFailed)
|
||||
{
|
||||
@ -4384,6 +4300,7 @@ void finalize(bool waitForRestartSignal_param)
|
||||
#endif
|
||||
delete cm; //this needs to go after restartServer();
|
||||
LOG_debug << "resources have been cleaned ...";
|
||||
LOG_info << "----------------------------- program end -------------------------------";
|
||||
|
||||
MegaApi::removeLoggerObject(loggerCMD);
|
||||
delete loggerCMD;
|
||||
@ -4535,14 +4452,14 @@ void processCommandInPetitionQueues(std::unique_ptr<CmdPetition> inf)
|
||||
petitionThreads.emplace_back(petitionThread);
|
||||
inf->setPetitionThread(petitionThread);
|
||||
|
||||
LOG_verbose << "starting processing: <" << inf->line << ">";
|
||||
LOG_verbose << "starting processing: <" << inf->getRedactedLine() << ">";
|
||||
petitionThread->start(doProcessLine, (void*) inf.release());
|
||||
}
|
||||
|
||||
void processCommandLinePetitionQueues(std::string what)
|
||||
{
|
||||
auto inf = std::make_unique<CmdPetition>();
|
||||
inf->line = what;
|
||||
inf->setLine(what);
|
||||
inf->clientDisconnected = true; // There's no actual client
|
||||
inf->clientID = -3;
|
||||
processCommandInPetitionQueues(std::move(inf));
|
||||
@ -4585,7 +4502,7 @@ void megacmd()
|
||||
|
||||
CmdPetition* inf = infOwned.get();
|
||||
|
||||
LOG_verbose << "petition registered: " << inf->line;
|
||||
LOG_verbose << "petition registered: " << inf->getRedactedLine();
|
||||
delete_finished_threads();
|
||||
|
||||
if (inf->getUniformLine() == "ERROR")
|
||||
@ -4601,51 +4518,24 @@ void megacmd()
|
||||
continue;
|
||||
}
|
||||
|
||||
// communicate client ID
|
||||
string s = "clientID:";
|
||||
s+=SSTR(currentclientID);
|
||||
s+=(char)0x1F;
|
||||
inf->clientID = currentclientID;
|
||||
currentclientID++;
|
||||
cm->informStateListener(inf,s);
|
||||
{
|
||||
// Communicate client ID
|
||||
string clientIdStr = "clientID:" + std::to_string(currentclientID) + (char) 0x1F;
|
||||
inf->clientID = currentclientID;
|
||||
currentclientID++;
|
||||
cm->informStateListener(inf, clientIdStr);
|
||||
}
|
||||
|
||||
std::string s;
|
||||
|
||||
#if defined(_WIN32) || defined(__APPLE__)
|
||||
string message="";
|
||||
ostringstream os;
|
||||
MegaCmdListener *megaCmdListener = new MegaCmdListener(NULL);
|
||||
api->getLastAvailableVersion("BdARkQSQ",megaCmdListener);
|
||||
if (!megaCmdListener->trywait(2000))
|
||||
auto updatMsgOpt = lookForAvailableNewerVersions(api);
|
||||
//TODO: have this executed in worker thread instead (see MegaCmdExecuter::mayExecutePendingStuffInWorkerThread)
|
||||
// still store the update message to be consumed here
|
||||
if (updatMsgOpt)
|
||||
{
|
||||
if (!megaCmdListener->getError())
|
||||
{
|
||||
LOG_fatal << "No MegaError at getLastAvailableVersion: ";
|
||||
}
|
||||
else if (megaCmdListener->getError()->getErrorCode() != MegaError::API_OK)
|
||||
{
|
||||
LOG_debug << "Couldn't get latests available version: " << megaCmdListener->getError()->getErrorString();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (megaCmdListener->getRequest()->getNumber() != MEGACMD_CODE_VERSION)
|
||||
{
|
||||
os << "---------------------------------------------------------------------" << endl;
|
||||
os << "-- There is a new version available of megacmd: " << setw(12) << left << megaCmdListener->getRequest()->getName() << "--" << endl;
|
||||
os << "-- Please, update this one: See \"update --help\". --" << endl;
|
||||
os << "-- Or download the latest from https://mega.nz/cmd --" << endl;
|
||||
#if defined(__APPLE__)
|
||||
os << "-- Before installing enter \"exit\" to close MEGAcmd --" << endl;
|
||||
#endif
|
||||
os << "---------------------------------------------------------------------" << endl;
|
||||
}
|
||||
}
|
||||
delete megaCmdListener;
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_debug << "Couldn't get latests available version (petition timed out)";
|
||||
|
||||
api->removeRequestListener(megaCmdListener);
|
||||
delete megaCmdListener;
|
||||
os << *updatMsgOpt;
|
||||
}
|
||||
|
||||
int autoupdate = ConfigurationManager::getConfigurationValue("autoupdate", -1);
|
||||
@ -4659,14 +4549,13 @@ void megacmd()
|
||||
{
|
||||
startcheckingForUpdates();
|
||||
}
|
||||
message=os.str();
|
||||
|
||||
|
||||
auto message = os.str();
|
||||
if (message.size())
|
||||
{
|
||||
s += "message:";
|
||||
s+=message;
|
||||
s+=(char)0x1F;
|
||||
s += message;
|
||||
s += (char) 0x1F;
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -4692,7 +4581,7 @@ void megacmd()
|
||||
s += "Your Operative System is too old.\n";
|
||||
s += "You might not receive new updates for this application.\n";
|
||||
s += "We strongly recommend you to update to a new version.\n";
|
||||
s+=(char)0x1F;
|
||||
s += (char) 0x1F;
|
||||
}
|
||||
|
||||
if (sandboxCMD->storageStatus != MegaApi::STORAGE_STATE_GREEN)
|
||||
@ -4758,7 +4647,7 @@ void megacmd()
|
||||
s += "You can change your account plan to increase your quota limit.\n";
|
||||
}
|
||||
s += "See \"help --upgrade\" for further details.\n";
|
||||
s += (char)0x1F;
|
||||
s += (char) 0x1F;
|
||||
}
|
||||
|
||||
// if server resuming session, lets give him a very litle while before sending greeting message to the early clients
|
||||
@ -4779,7 +4668,7 @@ void megacmd()
|
||||
|
||||
for (auto m: greetingsAllClientMsgs)
|
||||
{
|
||||
cm->informStateListener(inf,m.append(1, (char)0x1F));
|
||||
cm->informStateListener(inf, m.append(1, (char)0x1F));
|
||||
}
|
||||
}
|
||||
|
||||
@ -4792,16 +4681,16 @@ void megacmd()
|
||||
}
|
||||
|
||||
// communicate status info
|
||||
s+= "prompt:";
|
||||
s+=dynamicprompt;
|
||||
s+=(char)0x1F;
|
||||
s += "prompt:";
|
||||
s += dynamicprompt;
|
||||
s += (char) 0x1F;
|
||||
|
||||
if (!sandboxCMD->getReasonblocked().size())
|
||||
{
|
||||
cmdexecuter->checkAndInformPSA(inf);
|
||||
}
|
||||
|
||||
cm->informStateListener(inf,s);
|
||||
cm->informStateListener(inf, s);
|
||||
}
|
||||
else
|
||||
{ // normal petition
|
||||
@ -4828,30 +4717,62 @@ void printWelcomeMsg()
|
||||
width--;
|
||||
#endif
|
||||
|
||||
COUT << endl;
|
||||
COUT << ".";
|
||||
for (unsigned int i = 0; i < width; i++)
|
||||
COUT << "=" ;
|
||||
COUT << ".";
|
||||
COUT << endl;
|
||||
printCenteredLine(" __ __ _____ ____ _ _ ",width);
|
||||
printCenteredLine("| \\/ | ___|/ ___| / \\ ___ _ __ ___ __| |",width);
|
||||
printCenteredLine("| |\\/| | \\ / | _ / _ \\ / __| '_ ` _ \\ / _` |",width);
|
||||
printCenteredLine("| | | | /__\\ |_| |/ ___ \\ (__| | | | | | (_| |",width);
|
||||
printCenteredLine("|_| |_|____|\\____/_/ \\_\\___|_| |_| |_|\\__,_|",width);
|
||||
std::ostringstream oss;
|
||||
|
||||
COUT << "|";
|
||||
oss << endl;
|
||||
oss << ".";
|
||||
for (unsigned int i = 0; i < width; i++)
|
||||
COUT << " " ;
|
||||
COUT << "|";
|
||||
COUT << endl;
|
||||
printCenteredLine("SERVER",width);
|
||||
oss << "=" ;
|
||||
oss << ".";
|
||||
oss << endl;
|
||||
printCenteredLine(oss, " __ __ _____ ____ _ _ ",width);
|
||||
printCenteredLine(oss, "| \\/ | ___|/ ___| / \\ ___ _ __ ___ __| |",width);
|
||||
printCenteredLine(oss, "| |\\/| | \\ / | _ / _ \\ / __| '_ ` _ \\ / _` |",width);
|
||||
printCenteredLine(oss, "| | | | /__\\ |_| |/ ___ \\ (__| | | | | | (_| |",width);
|
||||
printCenteredLine(oss, "|_| |_|____|\\____/_/ \\_\\___|_| |_| |_|\\__,_|",width);
|
||||
|
||||
COUT << "`";
|
||||
oss << "|";
|
||||
for (unsigned int i = 0; i < width; i++)
|
||||
COUT << "=" ;
|
||||
COUT << "´";
|
||||
COUT << endl;
|
||||
oss << " " ;
|
||||
oss << "|";
|
||||
oss << endl;
|
||||
printCenteredLine(oss, "SERVER",width);
|
||||
|
||||
oss << "`";
|
||||
for (unsigned int i = 0; i < width; i++)
|
||||
{
|
||||
oss << "=" ;
|
||||
}
|
||||
#ifndef _WIN32
|
||||
oss << "\u00b4\n";
|
||||
COUT << oss.str() << std::flush;
|
||||
#else
|
||||
WindowsUtf8StdoutGuard utf8Guard;
|
||||
// So far, all is ASCII.
|
||||
COUT << oss.str();
|
||||
|
||||
// Now let's tray the non ascii forward acute
|
||||
// We are about to write some non ascii character.
|
||||
// Let's set (from now on, the console code page to UTF-8 translation (65001)
|
||||
// but revert to the initial code page if outputing the special forward acute character
|
||||
// fails. <- This could happen, for instance in Windows 7.
|
||||
auto initialCP = GetConsoleOutputCP();
|
||||
bool codePageChangedSuccesfully = false;
|
||||
if (initialCP != CP_UTF8 && !getenv("MEGACMDSERVER_DONOT_SET_CONSOLE_CP"))
|
||||
{
|
||||
codePageChangedSuccesfully = SetConsoleOutputCP(CP_UTF8);
|
||||
}
|
||||
|
||||
if (!(COUT << L"\u00b4")) // failed to output using utf-8
|
||||
{
|
||||
if (codePageChangedSuccesfully) // revert codepage
|
||||
{
|
||||
SetConsoleOutputCP(initialCP);
|
||||
}
|
||||
COUT << "/";
|
||||
}
|
||||
COUT << std::endl;
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
@ -4994,7 +4915,7 @@ bool registerUpdater()
|
||||
stringSID = getCurrentSid();
|
||||
if (!stringSID)
|
||||
{
|
||||
MegaApi::log(MegaApi::LOG_LEVEL_ERROR, "Unable to get the current SID");
|
||||
LOG_err << "Unable to get the current SID";
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -5080,21 +5001,21 @@ bool registerUpdater()
|
||||
&pRegisteredTask)))
|
||||
{
|
||||
success = true;
|
||||
MegaApi::log(MegaApi::LOG_LEVEL_ERROR, "Update task registered OK");
|
||||
LOG_err << "Update task registered OK";
|
||||
}
|
||||
else
|
||||
{
|
||||
MegaApi::log(MegaApi::LOG_LEVEL_ERROR, "Error registering update task");
|
||||
LOG_err << "Error registering update task";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
MegaApi::log(MegaApi::LOG_LEVEL_ERROR, "Error creating update task");
|
||||
LOG_err << "Error creating update task";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
MegaApi::log(MegaApi::LOG_LEVEL_ERROR, "Error getting root task folder");
|
||||
LOG_err << "Error getting root task folder";
|
||||
}
|
||||
|
||||
if (pRegisteredTask)
|
||||
@ -5260,7 +5181,8 @@ void sendEvent(StatsManager::MegacmdEvent event, ::mega::MegaApi *megaApi, bool
|
||||
#ifdef _WIN32
|
||||
void uninstall()
|
||||
{
|
||||
MegaApi::removeRecursively(megacmd::ConfigurationManager::getConfigFolder().c_str());
|
||||
std::error_code ec; // to use the non-throwing overload below
|
||||
fs::remove_all(ConfigurationManager::getConfigFolder(), ec);
|
||||
|
||||
ITaskService *pService = NULL;
|
||||
ITaskFolder *pRootFolder = NULL;
|
||||
@ -5335,6 +5257,8 @@ int executeServer(int argc, char* argv[],
|
||||
setlocale(LC_ALL, "en-US");
|
||||
#endif
|
||||
|
||||
printWelcomeMsg();
|
||||
|
||||
// keep a copy of argc & argv in order to allow restarts
|
||||
mcmdMainArgv = argv;
|
||||
mcmdMainArgc = argc;
|
||||
@ -5363,11 +5287,14 @@ int executeServer(int argc, char* argv[],
|
||||
char userAgent[40];
|
||||
sprintf(userAgent, "MEGAcmd" MEGACMD_STRINGIZE(MEGACMD_USERAGENT_SUFFIX) "/%d.%d.%d.%d", MEGACMD_MAJOR_VERSION,MEGACMD_MINOR_VERSION,MEGACMD_MICRO_VERSION,MEGACMD_BUILD_ID);
|
||||
|
||||
LOG_debug << "----------------------------- program start -----------------------------";
|
||||
LOG_info << "----------------------- program start -----------------------";
|
||||
LOG_debug << "MEGAcmd version: " << MEGACMD_MAJOR_VERSION << "." << MEGACMD_MINOR_VERSION << "." << MEGACMD_MICRO_VERSION << "." << MEGACMD_BUILD_ID << ": code " << MEGACMD_CODE_VERSION;
|
||||
LOG_debug << "MEGA SDK version: " << SDK_COMMIT_HASH;
|
||||
|
||||
api = new MegaApi("BdARkQSQ", (MegaGfxProcessor*)NULL, ConfigurationManager::getAndCreateConfigDir().c_str(), userAgent);
|
||||
const fs::path configDirPath = ConfigurationManager::getAndCreateConfigDir();
|
||||
const std::string configDirStrUtf8 = pathAsUtf8(configDirPath);
|
||||
|
||||
api = new MegaApi("BdARkQSQ", configDirStrUtf8.c_str(), userAgent);
|
||||
|
||||
if (!debug_api_url.empty())
|
||||
{
|
||||
@ -5378,9 +5305,10 @@ int executeServer(int argc, char* argv[],
|
||||
|
||||
for (int i = 0; i < 5; i++)
|
||||
{
|
||||
MegaApi *apiFolder = new MegaApi("BdARkQSQ", (MegaGfxProcessor*)NULL,
|
||||
ConfigurationManager::getConfigFolderSubdir(std::string("apiFolder_").append(std::to_string(i))).c_str()
|
||||
, userAgent);
|
||||
const fs::path apiFolderPath = ConfigurationManager::getConfigFolderSubdir("apiFolder_" + std::to_string(i));
|
||||
const std::string apiFolderStrUtf8 = pathAsUtf8(apiFolderPath);
|
||||
|
||||
MegaApi *apiFolder = new MegaApi("BdARkQSQ", apiFolderStrUtf8.c_str(), userAgent);
|
||||
apiFolder->setLanguage(localecode.c_str());
|
||||
apiFolders.push(apiFolder);
|
||||
apiFolder->setLogLevel(MegaApi::LOG_LEVEL_MAX);
|
||||
@ -5455,9 +5383,6 @@ int executeServer(int argc, char* argv[],
|
||||
}
|
||||
#endif
|
||||
|
||||
printWelcomeMsg();
|
||||
|
||||
|
||||
int configuredProxyType = ConfigurationManager::getConfigurationValue("proxy_type", -1);
|
||||
auto configuredProxyUrl = ConfigurationManager::getConfigurationSValue("proxy_url");
|
||||
|
||||
@ -5509,4 +5434,54 @@ void stopServer()
|
||||
processCommandLinePetitionQueues("quit"); //TODO: have set doExit instead, and wake the loop.
|
||||
}
|
||||
|
||||
std::optional<std::string> lookForAvailableNewerVersions(::mega::MegaApi *api)
|
||||
{
|
||||
#ifdef __linux__
|
||||
return {}; // Linux updates are _announced_ via packages manageres
|
||||
#endif
|
||||
|
||||
//NOTE: expected to be called from main megacmd thread (no concurrency control required)
|
||||
static HammeringLimiter hammeringLimiter(300);
|
||||
if (hammeringLimiter.runRecently())
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
ostringstream os;
|
||||
auto megaCmdListener = std::make_unique<MegaCmdListener>(api);
|
||||
api->getLastAvailableVersion("BdARkQSQ", megaCmdListener.get());
|
||||
|
||||
if (megaCmdListener->trywait(2000)) //timed out:
|
||||
{
|
||||
LOG_debug << "Couldn't get latests available version (petition timed out)";
|
||||
api->removeRequestListener(megaCmdListener.get());
|
||||
return {};
|
||||
}
|
||||
|
||||
if (!megaCmdListener->getError())
|
||||
{
|
||||
LOG_fatal << "No MegaError at getLastAvailableVersion: ";
|
||||
}
|
||||
else if (megaCmdListener->getError()->getErrorCode() != MegaError::API_OK)
|
||||
{
|
||||
LOG_debug << "Couldn't get latests available version: " << megaCmdListener->getError()->getErrorString();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (megaCmdListener->getRequest()->getNumber() != MEGACMD_CODE_VERSION)
|
||||
{
|
||||
os << "---------------------------------------------------------------------" << endl;
|
||||
os << "-- There is a new version available of megacmd: " << setw(12) << left << megaCmdListener->getRequest()->getName() << "--" << endl;
|
||||
os << "-- Please, update this one: See \"update --help\". --" << endl;
|
||||
os << "-- Or download the latest from https://mega.nz/cmd --" << endl;
|
||||
#if defined(__APPLE__)
|
||||
os << "-- Before installing enter \"exit\" to close MEGAcmd --" << endl;
|
||||
#endif
|
||||
os << "---------------------------------------------------------------------" << endl;
|
||||
}
|
||||
return os.str();
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
} //end namespace
|
||||
|
@ -36,6 +36,8 @@ using std::locale;
|
||||
using std::stringstream;
|
||||
using std::exception;
|
||||
|
||||
#include "megacmdcommonutils.h"
|
||||
|
||||
#include "megaapi_impl.h"
|
||||
#include "megacmd_events.h"
|
||||
|
||||
@ -208,10 +210,16 @@ void* checkForUpdates(void *param);
|
||||
void stopcheckingForUpdates();
|
||||
void startcheckingForUpdates();
|
||||
|
||||
/**
|
||||
* @brief synchronously request the API for a a new version of MEGAcmd
|
||||
* It will skip the check if already checked in the past 5 minutes
|
||||
* @param api
|
||||
* @return a string with a msg with the announcement if a new version is available
|
||||
*/
|
||||
std::optional<std::string> lookForAvailableNewerVersions(::mega::MegaApi *api);
|
||||
|
||||
void informTransferUpdate(mega::MegaTransfer *transfer, int clientID);
|
||||
void informStateListenerByClientId(int clientID, std::string s);
|
||||
|
||||
|
||||
void informProgressUpdate(long long transferred, long long total, int clientID, std::string title = "");
|
||||
|
||||
void sendEvent(StatsManager::MegacmdEvent event, mega::MegaApi *megaApi, bool wait = true);
|
||||
|
@ -33,7 +33,16 @@ namespace megacmd::StatsManager {
|
||||
GENERATOR_MACRO(FIRST_CONFIGURED_SYNC , 98903, "MEGAcmd first sync configured") \
|
||||
GENERATOR_MACRO(WAITED_TOO_LONG_FOR_NODES_CURRENT , 98904, "MEGAcmd nodes current wait timed out") \
|
||||
GENERATOR_MACRO(ROOT_NODE_NOT_FOUND_AFTER_FETCHING , 98906, "MEGAcmd root node was not found after fetching nodes") \
|
||||
GENERATOR_MACRO(TRANSITIONING_PRE_SRW_EXCLUSIONS , 98907, "MEGAcmd transition of legacy exclusion rules started")
|
||||
GENERATOR_MACRO(TRANSITIONING_PRE_SRW_EXCLUSIONS , 98907, "MEGAcmd transition of legacy exclusion rules started") \
|
||||
GENERATOR_MACRO(FIRST_CONFIGURED_WEBDAV , 98908, "MEGAcmd first WebDAV location configured") \
|
||||
GENERATOR_MACRO(FIRST_CONFIGURED_FTP , 98909, "MEGAcmd first FTP location configured") \
|
||||
GENERATOR_MACRO(FIRST_CONFIGURED_SCHEDULED_BACKUP , 98910, "MEGAcmd first scheduled backup configured") \
|
||||
GENERATOR_MACRO(SUBSEQUENT_CONFIGURED_SYNC , 98911, "MEGAcmd subsequent sync configured") \
|
||||
GENERATOR_MACRO(SUBSEQUENT_CONFIGURED_WEBDAV , 98912, "MEGAcmd subsequent WebDAV location configured") \
|
||||
GENERATOR_MACRO(SUBSEQUENT_CONFIGURED_FTP , 98913, "MEGAcmd subsequent FPT location configured") \
|
||||
GENERATOR_MACRO(SUBSEQUENT_CONFIGURED_SCHEDULED_BACKUP , 98914, "MEGAcmd subsequent scheduled backup configured") \
|
||||
GENERATOR_MACRO(INVALID_UTF8_INCIDENCES , 98915, "MEGAcmd Found Invalid UTF-8 incidences") \
|
||||
|
||||
|
||||
static constexpr auto FIRST_EVENT_NUMBER = 98900u;
|
||||
|
||||
|
@ -13,6 +13,7 @@
|
||||
* program.
|
||||
*/
|
||||
|
||||
#include "megacmdcommonutils.h"
|
||||
#include "megacmd_rotating_logger.h"
|
||||
|
||||
#include <cassert>
|
||||
@ -23,10 +24,10 @@
|
||||
namespace {
|
||||
class ReopenScope final
|
||||
{
|
||||
OUTFSTREAMTYPE& mOutFile;
|
||||
const std::string mOutFilePath;
|
||||
std::ofstream& mOutFile;
|
||||
const fs::path mOutFilePath;
|
||||
public:
|
||||
ReopenScope(OUTFSTREAMTYPE& outFile, const std::string& outFilePath) :
|
||||
ReopenScope(std::ofstream& outFile, const fs::path& outFilePath) :
|
||||
mOutFile(outFile),
|
||||
mOutFilePath(outFilePath)
|
||||
{
|
||||
@ -38,17 +39,6 @@ public:
|
||||
mOutFile.open(mOutFilePath, std::ofstream::out | std::ofstream::app);
|
||||
}
|
||||
};
|
||||
|
||||
std::string outstringToString(const OUTSTRING& outstring)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
std::string str;
|
||||
megacmd::localwtostring(&outstring, &str);
|
||||
return str;
|
||||
#else
|
||||
return outstring;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
namespace megacmd {
|
||||
@ -360,13 +350,13 @@ void FileRotatingLoggedStream::mainLoop()
|
||||
{
|
||||
while (!shouldExit() || !mMessageBuffer.isEmpty())
|
||||
{
|
||||
std::string errorMessages;
|
||||
std::ostringstream errorStream;
|
||||
bool reopenFile = false;
|
||||
|
||||
if (!waitForOutputFile())
|
||||
{
|
||||
errorMessages += "Error writing to log file " + mOutputFilePath + '\n';
|
||||
errorMessages += "Re-opening...\n";
|
||||
errorStream << "Error writing to log file " << mOutputFilePath << '\n';
|
||||
errorStream << "Re-opening...\n";
|
||||
reopenFile = true;
|
||||
}
|
||||
|
||||
@ -387,8 +377,15 @@ void FileRotatingLoggedStream::mainLoop()
|
||||
mFileManager.rotateFiles();
|
||||
}
|
||||
|
||||
errorMessages += mFileManager.popErrors();
|
||||
std::cerr << errorMessages;
|
||||
errorStream << mFileManager.popErrors();
|
||||
#ifdef WIN32
|
||||
{
|
||||
WindowsUtf8StdoutGuard utf8Guard;
|
||||
std::wcerr << utf8StringToUtf16WString(errorStream.str().c_str()) << std::flush;
|
||||
}
|
||||
#else
|
||||
std::cerr << errorStream.str() << std::flush;
|
||||
#endif
|
||||
|
||||
if (!mOutputFile)
|
||||
{
|
||||
@ -405,7 +402,7 @@ void FileRotatingLoggedStream::mainLoop()
|
||||
continue;
|
||||
}
|
||||
}
|
||||
mOutputFile << errorMessages;
|
||||
mOutputFile << errorStream.str();
|
||||
|
||||
bool writeMessages = false;
|
||||
{
|
||||
@ -430,7 +427,7 @@ void FileRotatingLoggedStream::mainLoop()
|
||||
|
||||
FileRotatingLoggedStream::FileRotatingLoggedStream(const OUTSTRING& outputFilePath) :
|
||||
mMessageBuffer(500 * 1024 * 1024 /* 500MB */),
|
||||
mOutputFilePath(outstringToString(outputFilePath)),
|
||||
mOutputFilePath(outputFilePath),
|
||||
mOutputFile(outputFilePath, std::ofstream::out | std::ofstream::app),
|
||||
mFileManager(mOutputFilePath),
|
||||
mForceRenew(false),
|
||||
@ -466,6 +463,12 @@ const LoggedStream& FileRotatingLoggedStream::operator<<(std::string str) const
|
||||
return *this;
|
||||
}
|
||||
|
||||
const LoggedStream& FileRotatingLoggedStream::operator<<(BinaryStringView v) const
|
||||
{
|
||||
writeToBuffer(v.get().data(), v.get().size());
|
||||
return *this;
|
||||
}
|
||||
|
||||
const LoggedStream& FileRotatingLoggedStream::operator<<(std::string_view str) const
|
||||
{
|
||||
writeToBuffer(str.data(), str.size());
|
||||
@ -652,7 +655,8 @@ fs::path TimestampRotationEngine::rotateBaseFile(const fs::path& directory, cons
|
||||
const std::string timestampStr = timestampToString(Clock::now());
|
||||
|
||||
fs::path srcFilePath = directory / baseFilename;
|
||||
fs::path dstFilePath = srcFilePath.string() + "." + timestampStr;
|
||||
fs::path dstFilePath = srcFilePath;
|
||||
dstFilePath += "." + timestampStr;
|
||||
|
||||
std::error_code ec;
|
||||
|
||||
@ -787,7 +791,15 @@ void GzipCompressionEngine::gzipFile(const fs::path& srcFilePath, const fs::path
|
||||
}
|
||||
|
||||
auto gzdeleter = [] (gzFile_s* f) { if (f) gzclose(f); };
|
||||
std::unique_ptr<gzFile_s, decltype(gzdeleter)> gzFile(gzopen(dstFilePath.string().c_str(), "wb"), gzdeleter);
|
||||
auto gzOpenHelper = [](const fs::path& path) {
|
||||
#ifdef _WIN32
|
||||
return gzopen_w(path.wstring().c_str(), "wb");
|
||||
#else
|
||||
return gzopen(path.string().c_str(), "wb");
|
||||
#endif
|
||||
};
|
||||
std::unique_ptr<gzFile_s, decltype(gzdeleter)> gzFile(gzOpenHelper(dstFilePath), gzdeleter);
|
||||
|
||||
if (!gzFile)
|
||||
{
|
||||
mErrorStream << "Failed to open gzfile " << dstFilePath << " for writing" << std::endl;
|
||||
@ -886,7 +898,8 @@ void GzipCompressionEngine::cancelAll()
|
||||
void GzipCompressionEngine::compressFile(const fs::path& filePath)
|
||||
{
|
||||
std::error_code ec;
|
||||
fs::path tmpFilePath = filePath.string() + ".zipping";
|
||||
fs::path tmpFilePath = filePath;
|
||||
tmpFilePath += ".zipping";
|
||||
|
||||
// Ensure there is not a clashing .zipping file
|
||||
if (fs::exists(tmpFilePath, ec) && !ec)
|
||||
@ -906,7 +919,8 @@ void GzipCompressionEngine::compressFile(const fs::path& filePath)
|
||||
return;
|
||||
}
|
||||
|
||||
fs::path targetFilePath = filePath.string() + getExtension();
|
||||
fs::path targetFilePath = filePath;
|
||||
targetFilePath += getExtension();
|
||||
pushToQueue(tmpFilePath, targetFilePath);
|
||||
}
|
||||
}
|
||||
|
@ -22,12 +22,9 @@
|
||||
#include <condition_variable>
|
||||
#include <chrono>
|
||||
#include <thread>
|
||||
#include <filesystem>
|
||||
|
||||
#include "megacmdlogger.h"
|
||||
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
namespace megacmd {
|
||||
|
||||
template<size_t BlockSize>
|
||||
@ -128,8 +125,8 @@ class FileRotatingLoggedStream final : public LoggedStream
|
||||
{
|
||||
mutable MessageBuffer<1024> mMessageBuffer;
|
||||
|
||||
std::string mOutputFilePath;
|
||||
OUTFSTREAMTYPE mOutputFile;
|
||||
fs::path mOutputFilePath;
|
||||
std::ofstream mOutputFile;
|
||||
RotatingFileManager mFileManager;
|
||||
|
||||
mutable std::mutex mWriteMtx;
|
||||
@ -167,6 +164,7 @@ public:
|
||||
const LoggedStream& operator<<(const char& c) const override;
|
||||
const LoggedStream& operator<<(const char* str) const override;
|
||||
const LoggedStream& operator<<(std::string str) const override;
|
||||
const LoggedStream& operator<<(BinaryStringView v) const override;
|
||||
const LoggedStream& operator<<(std::string_view str) const override;
|
||||
const LoggedStream& operator<<(int v) const override;
|
||||
const LoggedStream& operator<<(unsigned int v) const override;
|
||||
@ -190,6 +188,8 @@ MessageBuffer<BlockSize>::MemoryBlock::MemoryBlock() :
|
||||
mSize(0),
|
||||
mMemoryAllocationFailed(false)
|
||||
{
|
||||
// Ensure null-termination even if the memory block is empty
|
||||
mBuffer[0] = '\0';
|
||||
}
|
||||
|
||||
template<size_t BlockSize>
|
||||
@ -231,6 +231,7 @@ void MessageBuffer<BlockSize>::MemoryBlock::appendData(const char* data, size_t
|
||||
|
||||
std::memcpy(&mBuffer[mSize], data, size);
|
||||
mSize += size;
|
||||
assert(mSize < BlockSize);
|
||||
|
||||
// Append null after the last character so the buffer
|
||||
// is properly treated as a C-string
|
||||
@ -289,7 +290,10 @@ typename MessageBuffer<BlockSize>::MemoryBlockList MessageBuffer<BlockSize>::pop
|
||||
std::lock_guard<std::mutex> lock(mListMtx);
|
||||
initialMemoryError = mInitialMemoryError;
|
||||
mInitialMemoryError = false;
|
||||
return std::move(mList);
|
||||
|
||||
MemoryBlockList poppedList;
|
||||
std::swap(poppedList, mList);
|
||||
return poppedList;
|
||||
}
|
||||
|
||||
template<size_t BlockSize>
|
||||
|
@ -16,9 +16,9 @@
|
||||
#include "megacmd.h"
|
||||
#include "megaapi.h"
|
||||
|
||||
|
||||
#include "megacmdlogger.h"
|
||||
#include "megacmd_rotating_logger.h"
|
||||
#include "configurationmanager.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
@ -54,23 +54,23 @@ bool extractargparam(vector<const char*>& args, const char *what, std::string& p
|
||||
std::pair<int/*sdk*/, int/*cmd*/> getLogLevels(std::vector<const char*>& args)
|
||||
{
|
||||
using mega::MegaApi;
|
||||
// default log levels
|
||||
int sdkLogLevel = MegaApi::LOG_LEVEL_ERROR;
|
||||
int cmdLogLevel = MegaApi::LOG_LEVEL_INFO;
|
||||
using megacmd::ConfigurationManager;
|
||||
|
||||
// for !Windows have DEBUG builds use debug level by default
|
||||
#if defined(DEBUG) && !defined(_WIN32)
|
||||
sdkLogLevel = MegaApi::LOG_LEVEL_DEBUG;
|
||||
cmdLogLevel = MegaApi::LOG_LEVEL_DEBUG;
|
||||
#ifndef DEBUG
|
||||
constexpr int defaultSdkLogLevel = (int) MegaApi::LOG_LEVEL_ERROR;
|
||||
#else
|
||||
constexpr int defaultSdkLogLevel = (int) MegaApi::LOG_LEVEL_DEBUG;
|
||||
#endif
|
||||
constexpr int defaultCmdLogLevel = (int) MegaApi::LOG_LEVEL_DEBUG;
|
||||
|
||||
int sdkLogLevel = ConfigurationManager::getConfigurationValue("sdkLogLevel", defaultSdkLogLevel);
|
||||
int cmdLogLevel = ConfigurationManager::getConfigurationValue("cmdLogLevel", defaultCmdLogLevel);
|
||||
|
||||
// read parameters from argumetns
|
||||
bool debug = extractarg(args, "--debug");
|
||||
bool debugfull = extractarg(args, "--debug-full");
|
||||
bool verbose = extractarg(args, "--verbose");
|
||||
bool verbosefull = extractarg(args, "--verbose-full");
|
||||
|
||||
// overridance by environment variable
|
||||
const char *envCmdLogLevel = getenv("MEGACMD_LOGLEVEL");
|
||||
if (envCmdLogLevel)
|
||||
{
|
||||
@ -170,6 +170,10 @@ void waitIfRequired(std::vector<const char*> &args)
|
||||
// - linux forking (clients into server)
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
#ifdef WIN32
|
||||
megacmd::Instance<megacmd::WindowsConsoleController> windowsConsoleController;
|
||||
#endif
|
||||
|
||||
std::vector<const char*> args;
|
||||
if (argc > 1)
|
||||
{
|
||||
@ -184,7 +188,7 @@ int main(int argc, char* argv[])
|
||||
|
||||
waitIfRequired(args);
|
||||
|
||||
constexpr bool logToCout = true;
|
||||
bool logToCout = !extractarg(args, "--do-not-log-to-stdout");
|
||||
auto logLevels = getLogLevels(args);
|
||||
int sdkLogLevel = logLevels.first;
|
||||
int cmdLogLevel = logLevels.second;
|
||||
|
271
src/megacmd_utf8.cpp
Normal file
271
src/megacmd_utf8.cpp
Normal file
@ -0,0 +1,271 @@
|
||||
/**
|
||||
* @file src/megacmd_utf8.cpp
|
||||
* @brief MEGAcmd: utf8 and console resources
|
||||
*
|
||||
* (c) 2013 by Mega Limited, Auckland, New Zealand
|
||||
*
|
||||
* This file is part of the MEGAcmd.
|
||||
*
|
||||
* MEGAcmd 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.
|
||||
*
|
||||
* @copyright Simplified (2-clause) BSD License.
|
||||
*
|
||||
* You should have received a copy of the license along with this
|
||||
* program.
|
||||
*/
|
||||
|
||||
#include "megacmd_utf8.h"
|
||||
|
||||
#ifdef WIN32
|
||||
#include <Shlwapi.h>
|
||||
#include <Shellapi.h>
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
namespace megacmd {
|
||||
|
||||
#ifdef _WIN32
|
||||
std::wostream & operator<< ( std::wostream & ostr, std::string const & str )
|
||||
{
|
||||
std::wstring toout;
|
||||
stringtolocalw(str.c_str(),&toout);
|
||||
ostr << toout;
|
||||
return ( ostr );
|
||||
}
|
||||
|
||||
std::wostream & operator<< ( std::wostream & ostr, const char * str )
|
||||
{
|
||||
std::wstring toout;
|
||||
stringtolocalw(str,&toout);
|
||||
ostr << toout;
|
||||
return ( ostr );
|
||||
}
|
||||
|
||||
// convert UTF-8 to Windows Unicode wstring (UTF-16)
|
||||
void stringtolocalw(const char* path, size_t lenutf8, std::wstring* local)
|
||||
{
|
||||
assert(isValidUtf8(std::string(path, lenutf8)));
|
||||
|
||||
// make space for the worst case
|
||||
local->resize((strlen(path) + 1) * sizeof(wchar_t));
|
||||
|
||||
int wchars_num = MultiByteToWideChar(CP_UTF8, 0, path, lenutf8 + 1, NULL,0);
|
||||
local->resize(wchars_num);
|
||||
|
||||
int len = MultiByteToWideChar(CP_UTF8, 0, path, lenutf8 + 1, (wchar_t*)local->data(), wchars_num);
|
||||
|
||||
if (len)
|
||||
{
|
||||
local->resize(len-1);
|
||||
}
|
||||
else
|
||||
{
|
||||
local->clear();
|
||||
}
|
||||
}
|
||||
|
||||
// convert UTF-8 to Windows Unicode wstring (UTF-16)
|
||||
void stringtolocalw(const char* path, std::wstring* local)
|
||||
{
|
||||
stringtolocalw(path, strlen(path), local);
|
||||
}
|
||||
|
||||
std::wstring utf8StringToUtf16WString(const char* str)
|
||||
{
|
||||
std::wstring toret;
|
||||
stringtolocalw(str, &toret);
|
||||
return toret;
|
||||
}
|
||||
|
||||
std::wstring utf8StringToUtf16WString(const char* str, size_t lenutf8)
|
||||
{
|
||||
std::wstring toret;
|
||||
stringtolocalw(str, lenutf8, &toret);
|
||||
return toret;
|
||||
}
|
||||
|
||||
void localwtostring(const std::wstring* wide, std::string *multibyte)
|
||||
{
|
||||
utf16ToUtf8(wide->data(), (int)wide->size(), multibyte);
|
||||
}
|
||||
|
||||
void utf16ToUtf8(const wchar_t* utf16data, int utf16size, std::string* utf8string)
|
||||
{
|
||||
if(!utf16size)
|
||||
{
|
||||
utf8string->clear();
|
||||
return;
|
||||
}
|
||||
|
||||
int size_needed = WideCharToMultiByte(CP_UTF8, 0, utf16data, utf16size, NULL, 0, NULL, NULL);
|
||||
utf8string->resize(size_needed);
|
||||
WideCharToMultiByte(CP_UTF8, 0, utf16data, utf16size, (char*)utf8string->data(), size_needed, NULL, NULL);
|
||||
assert(isValidUtf8(*utf8string));
|
||||
}
|
||||
|
||||
std::string utf16ToUtf8(const std::wstring &ws)
|
||||
{
|
||||
std::string utf8s;
|
||||
utf16ToUtf8(ws.c_str(), ws.size(), &utf8s);
|
||||
return utf8s;
|
||||
}
|
||||
|
||||
std::string utf16ToUtf8(const wchar_t *ws)
|
||||
{
|
||||
std::string utf8s;
|
||||
utf16ToUtf8(ws, int(wcslen(ws)), &utf8s);
|
||||
return utf8s;
|
||||
}
|
||||
|
||||
std::wstring nonMaxPathLimitedWstring(const fs::path &localpath)
|
||||
{
|
||||
static const std::wstring wprefix(LR"(\\?\)");
|
||||
if (localpath.wstring().rfind(wprefix, 0) == 0)
|
||||
{
|
||||
return localpath.wstring();
|
||||
}
|
||||
auto prefixedPathWstring = std::wstring(wprefix).append(localpath.wstring());
|
||||
assert(prefixedPathWstring.rfind(wprefix, 0) == 0);
|
||||
return prefixedPathWstring;
|
||||
}
|
||||
|
||||
fs::path nonMaxPathLimitedPath(const fs::path &localpath)
|
||||
{
|
||||
auto prefixedPath = fs::path(nonMaxPathLimitedWstring(localpath));
|
||||
assert(prefixedPath.wstring().rfind(LR"(\\?\)", 0) == 0);
|
||||
return prefixedPath;
|
||||
}
|
||||
|
||||
WindowsConsoleController::WindowsConsoleController()
|
||||
{
|
||||
if (!getenv("MEGACMD_DISABLE_UTF8_OUTPUT_MODE_BY_DEFAULT"))
|
||||
{
|
||||
// set default mode to U8TEXT.
|
||||
// PROs: we could actually get rid of _setmode to U8TEXT in WindowsUtf8StdoutGuard
|
||||
// CONS: any low level printing to stdout may crash if the mode is not _O_TEXT.
|
||||
// Even if we do not do that, for instance, gtests would do.
|
||||
auto OUTPUT_MODE = _O_U8TEXT;
|
||||
auto oldModeStdout = _setmode(_fileno(stdout), OUTPUT_MODE);
|
||||
auto oldModeStderr = _setmode(_fileno(stderr), OUTPUT_MODE);
|
||||
}
|
||||
|
||||
if (!getenv("MEGACMD_DISABLE_NARROW_OUTSTREAMS_INTERCEPTING"))
|
||||
{
|
||||
enableInterceptors(true);
|
||||
}
|
||||
}
|
||||
|
||||
void WindowsConsoleController::enableInterceptors(bool enable)
|
||||
{
|
||||
std::cout.flush();
|
||||
std::cerr.flush();
|
||||
|
||||
if (enable)
|
||||
{
|
||||
mInterceptCout.reset(new InterceptStreamBuffer(std::cout, std::wcout));
|
||||
mInterceptCerr.reset(new InterceptStreamBuffer(std::cerr, std::wcerr));
|
||||
}
|
||||
else
|
||||
{
|
||||
mInterceptCout.reset();
|
||||
mInterceptCerr.reset();
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
std::atomic<uint64_t> sInvalidUtf8Incidences = 0;
|
||||
|
||||
std::string pathAsUtf8(const fs::path& path)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
return utf16ToUtf8(path.wstring().c_str());
|
||||
#else
|
||||
return path.string();
|
||||
#endif
|
||||
}
|
||||
|
||||
bool isValidUtf8(const char* data, size_t size)
|
||||
{
|
||||
static bool disableUTF8Valiations = getenv("MEGACMD_DISABLE_UTF8_VALIDATIONS");
|
||||
if (disableUTF8Valiations)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
// checks that the byte starts with bits 10 (i.e. continuation bytes)
|
||||
auto check10 = [&data](size_t n) -> bool {
|
||||
return (data[n] & 0xc0) == 0x80;
|
||||
};
|
||||
|
||||
while (size)
|
||||
{
|
||||
const uint8_t lead = static_cast<uint8_t>(*data);
|
||||
|
||||
// 0xxxxxxx -> U+0000..U+007F (1-byte character)
|
||||
if (lead < 0x80)
|
||||
{
|
||||
++data;
|
||||
--size;
|
||||
continue;
|
||||
}
|
||||
// 110xxxxx -> U+0080..U+07FF (2-byte character)
|
||||
else if ((lead & 0xe0) == 0xc0)
|
||||
{
|
||||
// check codepoint is at least 0x80 and check continuation byte
|
||||
if (lead > 0xc1 && size >= 2 && check10(1))
|
||||
{
|
||||
data += 2;
|
||||
size -= 2;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
// 1110xxxx -> U+0800..U+FFFF (3-byte character)
|
||||
else if ((lead & 0xf0) == 0xe0)
|
||||
{
|
||||
// check continuation bytes
|
||||
if (size >= 3 && check10(1) && check10(2))
|
||||
{
|
||||
const auto secondByte = static_cast<uint8_t>(data[1]);
|
||||
|
||||
// check codepoint is at least 0x800 and not a surrogate codepoint in the range 0xd800-0xdfff
|
||||
if (((lead << 8) | secondByte) > 0xe09f &&
|
||||
(lead != 0xed || secondByte < 0xa0))
|
||||
{
|
||||
data += 3;
|
||||
size -= 3;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
// 11110xxx -> U+10000..U+10FFFF (4-byte character)
|
||||
else if ((lead & 0xf8) == 0xf0)
|
||||
{
|
||||
// check continuation bytes5
|
||||
if (size >= 4 && check10(1) && check10(2) && check10(3))
|
||||
{
|
||||
const auto firstHalf = (lead << 8) | static_cast<uint8_t>(data[1]);
|
||||
|
||||
// check codepoint is at least 0x10000 and not greater than 0x10FFFF (not encodable by UTF-16)
|
||||
if (firstHalf > 0xf08f && firstHalf < 0xf490)
|
||||
{
|
||||
data += 4;
|
||||
size -= 4;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sInvalidUtf8Incidences++;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
bool isValidUtf8(const std::string &str)
|
||||
{
|
||||
return isValidUtf8(str.data(), str.size());
|
||||
}
|
||||
|
||||
|
||||
} //end namespace
|
257
src/megacmd_utf8.h
Normal file
257
src/megacmd_utf8.h
Normal file
@ -0,0 +1,257 @@
|
||||
/**
|
||||
* @file src/megacmd_utf8.h
|
||||
* @brief MEGAcmd: utf8 and console resources
|
||||
*
|
||||
* (c) 2013 by Mega Limited, Auckland, New Zealand
|
||||
*
|
||||
* This file is part of the MEGAcmd.
|
||||
*
|
||||
* MEGAcmd 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.
|
||||
*
|
||||
* @copyright Simplified (2-clause) BSD License.
|
||||
*
|
||||
* You should have received a copy of the license along with this
|
||||
* program.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <iostream>
|
||||
#include <cassert>
|
||||
#include <mutex>
|
||||
#include <atomic>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <streambuf>
|
||||
#include <conio.h>
|
||||
#include <fstream>
|
||||
#include <iomanip>
|
||||
|
||||
#include <io.h>
|
||||
#include <fcntl.h>
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
#include <cwctype>
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <io.h>
|
||||
#include <stdio.h>
|
||||
#ifndef _O_U16TEXT
|
||||
#define _O_U16TEXT 0x00020000
|
||||
#endif
|
||||
#ifndef _O_U8TEXT
|
||||
#define _O_U8TEXT 0x00040000
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <filesystem>
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
namespace megacmd {
|
||||
|
||||
std::string pathAsUtf8(const fs::path& path);
|
||||
|
||||
extern std::atomic<uint64_t> sInvalidUtf8Incidences;
|
||||
bool isValidUtf8(const char* data, size_t size);
|
||||
bool isValidUtf8(const std::string &str);
|
||||
|
||||
struct StdoutMutexGuard
|
||||
{
|
||||
inline static std::recursive_mutex sSetmodeMtx;
|
||||
std::lock_guard<std::recursive_mutex> mGuard;
|
||||
|
||||
StdoutMutexGuard() : mGuard(sSetmodeMtx) {}
|
||||
};
|
||||
|
||||
/* platform dependent */
|
||||
#ifdef _WIN32
|
||||
|
||||
#define OUTSTREAMTYPE std::wostream
|
||||
#define OUTFSTREAMTYPE std::wofstream
|
||||
#define OUTSTRINGSTREAM std::wostringstream
|
||||
#define OUTSTRING std::wstring
|
||||
#define COUT std::wcout
|
||||
#define CERR std::wcerr
|
||||
|
||||
//override << operators for wostream for string and const char *
|
||||
std::wostream & operator<< ( std::wostream & ostr, std::string const & str );
|
||||
std::wostream & operator<< ( std::wostream & ostr, const char * str );
|
||||
|
||||
// UTF-8 to wstrings (UTF-16) conversions:
|
||||
void stringtolocalw(const char* path, std::wstring* local);
|
||||
void stringtolocalw(const char* path, size_t lenutf8, std::wstring* local);
|
||||
std::wstring utf8StringToUtf16WString(const char* str, size_t lenutf8);
|
||||
std::wstring utf8StringToUtf16WString(const char* path);
|
||||
|
||||
// convert Utf-16 wide chars to UTF-8 std::strings
|
||||
void localwtostring(const std::wstring* wide, std::string *multibyte);
|
||||
void utf16ToUtf8(const wchar_t* utf16data, int utf16size, std::string* utf8string);
|
||||
std::string utf16ToUtf8(const wchar_t *ws);
|
||||
std::string utf16ToUtf8(const std::wstring &ws);
|
||||
|
||||
std::wstring nonMaxPathLimitedWstring(const fs::path &localpath);
|
||||
fs::path nonMaxPathLimitedPath(const fs::path &localpath);
|
||||
|
||||
/***
|
||||
* operator<< overloads to ensure proper handling of paths and widestrings
|
||||
* This header would need to be included first in all project as a general rule, so that these are used
|
||||
* As a way to ensure this, we could only define fs namespace here.
|
||||
*
|
||||
* Note: beyond these, operator<< overloads for logging can be found at megacmdlogger.h
|
||||
**/
|
||||
//// This is expected to be used when trying to << a wstring (supposedly in UTF-16, into a ostream (string/file/cout/...)
|
||||
template <typename T>
|
||||
inline std::enable_if_t<std::is_same_v<std::decay_t<T>, std::wstring>, std::ostream&>
|
||||
operator<<(std::ostream& oss, const T& wstr)
|
||||
{
|
||||
static_assert(false); // Let's forbid this to better control that we just write utf8 std::strings in non wide streams (e.g cout)
|
||||
// Notice that in the end, in stdout we want to write widestrings (utf16) to wcout instead, to have console rendering properly.
|
||||
|
||||
// If we were to automatically support this we should convert them to utf8 string as follows:
|
||||
oss << megacmd::utf16ToUtf8(wstr);
|
||||
return oss;
|
||||
}
|
||||
} // end of namespace megacmd
|
||||
|
||||
namespace std::filesystem {
|
||||
|
||||
// overload that may be used when building some stringstream.
|
||||
// Note: LOG_xxx << path should are handled by SimpleLogger overloads, not this one
|
||||
inline std::ostream &operator<<(std::ostream& oss, const fs::path& path)
|
||||
{
|
||||
// caveat: outputting its contents (utf-8) to stdout would need to be done converting to utf-16 and using wcout
|
||||
// and a valid mode to stdout (See WindowsUtf8StdoutGuard)
|
||||
assert(&oss != &std::cout);
|
||||
assert(&oss != &std::cerr);
|
||||
|
||||
oss << megacmd::pathAsUtf8(path);
|
||||
return oss;
|
||||
}
|
||||
|
||||
} // end of namespace std::filesystem
|
||||
namespace megacmd {
|
||||
|
||||
/**
|
||||
* @brief This class is used to:
|
||||
* - guard no meddling while writting/setting output mode on stdout/stderr
|
||||
* - ensure setting the output modes to mOutputMode
|
||||
*/
|
||||
class OutputsModeGuard : public StdoutMutexGuard
|
||||
{
|
||||
unsigned int mOutputMode;
|
||||
int mOldModeStdout;
|
||||
int mOldModeStderr;
|
||||
public:
|
||||
OutputsModeGuard(unsigned int outputMode)
|
||||
: mOutputMode(outputMode)
|
||||
{
|
||||
fflush(stdout);
|
||||
fflush(stderr);
|
||||
mOldModeStdout = _setmode(_fileno(stdout), mOutputMode);
|
||||
mOldModeStderr = _setmode(_fileno(stderr), mOutputMode);
|
||||
assert(mOldModeStdout != -1);
|
||||
assert(mOldModeStderr != -1);
|
||||
}
|
||||
|
||||
virtual ~OutputsModeGuard()
|
||||
{
|
||||
fflush(stdout);
|
||||
fflush(stderr);
|
||||
_setmode(_fileno(stdout), mOldModeStdout);
|
||||
_setmode(_fileno(stderr), mOldModeStderr);
|
||||
}
|
||||
};
|
||||
|
||||
template <unsigned int OUTPUT_MODE>
|
||||
class WindowsOutputsModeGuardGeneric : public OutputsModeGuard
|
||||
{
|
||||
public:
|
||||
WindowsOutputsModeGuardGeneric()
|
||||
: OutputsModeGuard(OUTPUT_MODE)
|
||||
{}
|
||||
};
|
||||
|
||||
using WindowsUtf8StdoutGuard = WindowsOutputsModeGuardGeneric<_O_U8TEXT>;
|
||||
using WindowsNarrowStdoutGuard = WindowsOutputsModeGuardGeneric<_O_TEXT>;
|
||||
using WindowsBinaryStdoutGuard = WindowsOutputsModeGuardGeneric<O_BINARY>;
|
||||
|
||||
class InterceptStreamBuffer : public std::streambuf
|
||||
{
|
||||
private:
|
||||
std::streambuf* mOriginalStreamBuffer; // Store the original buffer
|
||||
std::ostream& mNarrowStream; // Reference to the original stream (e.g., std::cout)
|
||||
std::wostream& mWideOstream; // Reference to the original stream (e.g., std::cout)
|
||||
|
||||
bool hasNonAscii(const char* str, size_t length)
|
||||
{
|
||||
for (size_t i = 0; i < length; ++i)
|
||||
{
|
||||
if (static_cast<unsigned char>(str[i]) > 127)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public:
|
||||
InterceptStreamBuffer(std::ostream& outStream, std::wostream &wideStream)
|
||||
: mNarrowStream(outStream), mWideOstream(wideStream)
|
||||
{
|
||||
mOriginalStreamBuffer = mNarrowStream.rdbuf(); // Save the original buffer
|
||||
mNarrowStream.rdbuf(this); // Replace with this buffer
|
||||
}
|
||||
|
||||
~InterceptStreamBuffer()
|
||||
{
|
||||
mNarrowStream.rdbuf(mOriginalStreamBuffer); // Restore the original buffer on destruction
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual int overflow(int c) override
|
||||
{
|
||||
char cc = char(c);
|
||||
xsputn(&cc, 1);
|
||||
return c;
|
||||
}
|
||||
|
||||
virtual std::streamsize xsputn(const char* s, std::streamsize count) override
|
||||
{
|
||||
if (hasNonAscii(s, count)) // why cannot:
|
||||
{
|
||||
WindowsUtf8StdoutGuard utf8Guard;
|
||||
// assert(false && "This should ideally be controlled in calling code"); //TODO: enable this assert to fix cases in origin (assumed better performance)
|
||||
mWideOstream << utf8StringToUtf16WString(s, count);
|
||||
return count;
|
||||
}
|
||||
else
|
||||
{
|
||||
WindowsNarrowStdoutGuard narrowGuard;
|
||||
return mOriginalStreamBuffer->sputn(s, count); // This is protesting when having _setmode and doing cout << "odd" (odd number of chars)
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class WindowsConsoleController
|
||||
{
|
||||
std::unique_ptr<megacmd::InterceptStreamBuffer> mInterceptCout;
|
||||
std::unique_ptr<megacmd::InterceptStreamBuffer> mInterceptCerr;
|
||||
|
||||
public:
|
||||
WindowsConsoleController();
|
||||
void enableInterceptors(bool enable);
|
||||
};
|
||||
|
||||
#else
|
||||
#define OUTSTREAMTYPE std::ostream
|
||||
#define OUTFSTREAMTYPE std::ofstream
|
||||
#define OUTSTRINGSTREAM std::ostringstream
|
||||
#define OUTSTRING std::string
|
||||
#define COUT std::cout
|
||||
#define CERR std::cerr
|
||||
|
||||
#endif
|
||||
|
||||
}//end namespace
|
@ -45,99 +45,14 @@
|
||||
#include <regex> //split
|
||||
#include <random>
|
||||
|
||||
#ifdef _WIN32
|
||||
namespace mega {
|
||||
//override for the log. This is required for compiling, otherwise SimpleLog won't compile.
|
||||
std::ostringstream & operator<< ( std::ostringstream & ostr, const std::wstring & str)
|
||||
{
|
||||
std::string s;
|
||||
megacmd::localwtostring(&str,&s);
|
||||
ostr << s;
|
||||
return ( ostr );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
namespace megacmd {
|
||||
using namespace std;
|
||||
|
||||
#ifdef _WIN32
|
||||
std::wostream & operator<< ( std::wostream & ostr, std::string const & str )
|
||||
std::string errorCodeStr(const std::error_code& ec)
|
||||
{
|
||||
std::wstring toout;
|
||||
stringtolocalw(str.c_str(),&toout);
|
||||
ostr << toout;
|
||||
return ( ostr );
|
||||
return ec ? "(error: " + ec.message() + ")" : "";
|
||||
}
|
||||
|
||||
std::wostream & operator<< ( std::wostream & ostr, const char * str )
|
||||
{
|
||||
std::wstring toout;
|
||||
stringtolocalw(str,&toout);
|
||||
ostr << toout;
|
||||
return ( ostr );
|
||||
}
|
||||
|
||||
// convert UTF-8 to Windows Unicode wstring
|
||||
void stringtolocalw(const char* path, std::wstring* local)
|
||||
{
|
||||
// make space for the worst case
|
||||
local->resize((strlen(path) + 1) * sizeof(wchar_t));
|
||||
|
||||
int wchars_num = MultiByteToWideChar(CP_UTF8, 0, path,-1, NULL,0);
|
||||
local->resize(wchars_num);
|
||||
|
||||
int len = MultiByteToWideChar(CP_UTF8, 0, path,-1, (wchar_t*)local->data(), wchars_num);
|
||||
|
||||
if (len)
|
||||
{
|
||||
local->resize(len-1);
|
||||
}
|
||||
else
|
||||
{
|
||||
local->clear();
|
||||
}
|
||||
}
|
||||
|
||||
//widechar to utf8 string
|
||||
void localwtostring(const std::wstring* wide, std::string *multibyte)
|
||||
{
|
||||
if( !wide->empty() )
|
||||
{
|
||||
int size_needed = WideCharToMultiByte(CP_UTF8, 0, wide->data(), (int)wide->size(), NULL, 0, NULL, NULL);
|
||||
multibyte->resize(size_needed);
|
||||
WideCharToMultiByte(CP_UTF8, 0, wide->data(), (int)wide->size(), (char*)multibyte->data(), size_needed, NULL, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
// convert Windows Unicode to UTF-8
|
||||
void utf16ToUtf8(const wchar_t* utf16data, int utf16size, string* utf8string)
|
||||
{
|
||||
if(!utf16size)
|
||||
{
|
||||
utf8string->clear();
|
||||
return;
|
||||
}
|
||||
|
||||
utf8string->resize((utf16size + 1) * 4);
|
||||
|
||||
utf8string->resize(WideCharToMultiByte(CP_UTF8, 0, utf16data,
|
||||
utf16size,
|
||||
(char*)utf8string->data(),
|
||||
int(utf8string->size() + 1),
|
||||
NULL, NULL));
|
||||
}
|
||||
|
||||
std::string getutf8fromUtf16(const wchar_t *ws)
|
||||
{
|
||||
string utf8s;
|
||||
utf16ToUtf8(ws, int(wcslen(ws)), &utf8s);
|
||||
return utf8s;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
bool canWrite(string path)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
@ -750,7 +665,8 @@ string toLower(const std::string& str)
|
||||
return lower;
|
||||
}
|
||||
|
||||
void printCenteredLine(OUTSTREAMTYPE &os, string msj, unsigned int width, bool encapsulated)
|
||||
template <typename Stream_T>
|
||||
void printCenteredLine(Stream_T &os, string msj, unsigned int width, bool encapsulated)
|
||||
{
|
||||
unsigned int msjsize = getstringutf8size(msj);
|
||||
bool overflowed = false;
|
||||
@ -771,6 +687,10 @@ void printCenteredLine(OUTSTREAMTYPE &os, string msj, unsigned int width, bool e
|
||||
os << endl;
|
||||
}
|
||||
|
||||
// Instantiate those that can be used:
|
||||
template void printCenteredLine<OUTSTREAMTYPE>(OUTSTREAMTYPE &os, string msj, unsigned int width, bool encapsulated);
|
||||
template void printCenteredLine<std::ostringstream>(std::ostringstream &os, string msj, unsigned int width, bool encapsulated);
|
||||
|
||||
void printCenteredContents(OUTSTREAMTYPE &os, string msj, unsigned int width, bool encapsulated)
|
||||
{
|
||||
string headfoot = " ";
|
||||
@ -859,6 +779,9 @@ void printCenteredLine(string msj, unsigned int width, bool encapsulated)
|
||||
{
|
||||
OUTSTRINGSTREAM os;
|
||||
printCenteredLine(os, msj, width, encapsulated);
|
||||
#ifdef _WIN32
|
||||
WindowsUtf8StdoutGuard utf8Guard;
|
||||
#endif
|
||||
COUT << os.str();
|
||||
}
|
||||
|
||||
@ -866,6 +789,12 @@ void printCenteredContents(string msj, unsigned int width, bool encapsulated)
|
||||
{
|
||||
OUTSTRINGSTREAM os;
|
||||
printCenteredContents(os, msj, width, encapsulated);
|
||||
#ifdef _WIN32
|
||||
WindowsUtf8StdoutGuard utf8Guard;
|
||||
#else
|
||||
StdoutMutexGuard stdoutGuard;
|
||||
#endif
|
||||
|
||||
COUT << os.str();
|
||||
}
|
||||
|
||||
@ -873,6 +802,11 @@ void printCenteredContentsCerr(string msj, unsigned int width, bool encapsulated
|
||||
{
|
||||
OUTSTRINGSTREAM os;
|
||||
printCenteredContents(os, msj, width, encapsulated);
|
||||
#ifdef _WIN32
|
||||
WindowsUtf8StdoutGuard utf8Guard;
|
||||
#else
|
||||
StdoutMutexGuard stdoutGuard;
|
||||
#endif
|
||||
CERR << os.str();
|
||||
}
|
||||
|
||||
@ -912,6 +846,13 @@ void printPercentageLineCerr(const char *title, long long completed, long long t
|
||||
*ptr++ = '#';
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
WindowsUtf8StdoutGuard utf8Guard;
|
||||
#else
|
||||
StdoutMutexGuard stdoutGuard;
|
||||
#endif
|
||||
|
||||
// TODO: should this be CERR ? (`\r`) may not behave as wanted
|
||||
if (cleanLineAfter)
|
||||
{
|
||||
cerr << outputString << '\r' << flush;
|
||||
@ -1250,9 +1191,9 @@ string &trimProperty(string &what)
|
||||
return what;
|
||||
}
|
||||
|
||||
string getPropertyFromFile(const char *configFile, const char *propertyName)
|
||||
string getPropertyFromFile(const fs::path &configFilePath, const char *propertyName)
|
||||
{
|
||||
ifstream infile(configFile);
|
||||
ifstream infile(configFilePath);
|
||||
string line;
|
||||
|
||||
while (getline(infile, line))
|
||||
@ -1555,33 +1496,25 @@ std::unique_ptr<PlatformDirectories> PlatformDirectories::getPlatformSpecificDir
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
std::string WindowsDirectories::configDirPath()
|
||||
fs::path WindowsDirectories::configDirPath()
|
||||
{
|
||||
TCHAR szPath[MAX_PATH];
|
||||
std::string folder;
|
||||
wchar_t szPath[MAX_PATH];
|
||||
|
||||
if (!SUCCEEDED(GetModuleFileName(NULL, szPath, MAX_PATH)))
|
||||
if (GetModuleFileNameW(NULL, szPath, MAX_PATH) == 0)
|
||||
{
|
||||
return std::string();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (SUCCEEDED(PathRemoveFileSpec(szPath)))
|
||||
{
|
||||
if (PathAppend(szPath, TEXT(".megaCmd")))
|
||||
{
|
||||
utf16ToUtf8(szPath, lstrlen(szPath), &folder);
|
||||
}
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
auto suffix = getenv("MEGACMD_WORKING_FOLDER_SUFFIX");
|
||||
fs::path folder = fs::path(szPath).parent_path() / ".megaCmd";
|
||||
|
||||
auto suffix = _wgetenv(L"MEGACMD_WORKING_FOLDER_SUFFIX");
|
||||
if (suffix != nullptr)
|
||||
{
|
||||
folder += "_";
|
||||
folder += suffix;
|
||||
}
|
||||
|
||||
folder = nonMaxPathLimitedPath(folder); // prepend //?/
|
||||
return folder;
|
||||
}
|
||||
|
||||
@ -1626,7 +1559,7 @@ std::string PosixDirectories::homeDirPath()
|
||||
return std::string(pwd.pw_dir);
|
||||
}
|
||||
|
||||
std::string PosixDirectories::configDirPath()
|
||||
fs::path PosixDirectories::configDirPath()
|
||||
{
|
||||
std::string home = homeDirPath();
|
||||
if (home.empty())
|
||||
@ -1646,7 +1579,7 @@ string PosixDirectories::noHomeFallbackFolder()
|
||||
}
|
||||
|
||||
#ifdef __APPLE__
|
||||
std::string MacOSDirectories::runtimeDirPath()
|
||||
fs::path MacOSDirectories::runtimeDirPath()
|
||||
{
|
||||
std::string home = homeDirPath();
|
||||
if (home.empty())
|
||||
@ -1678,7 +1611,7 @@ std::string getOrCreateSocketPath(bool createDirectory)
|
||||
|
||||
static auto MAX_SOCKET_PATH = sizeof(sockaddr_un::sun_path) / sizeof(decltype(sockaddr_un::sun_path[0]));
|
||||
|
||||
if ((socketFolder.size() + 1 + sockname.size()) >= (MAX_SOCKET_PATH - 1))
|
||||
if ((socketFolder.string().size() + 1 + sockname.size()) >= (MAX_SOCKET_PATH - 1))
|
||||
{
|
||||
if (createDirectory)
|
||||
{
|
||||
@ -1708,7 +1641,7 @@ std::string getOrCreateSocketPath(bool createDirectory)
|
||||
}
|
||||
}
|
||||
|
||||
return socketFolder.append("/").append(sockname);
|
||||
return (socketFolder / sockname).string();
|
||||
}
|
||||
#endif // ifdef(_WIN32) else
|
||||
} //end namespace
|
||||
|
@ -19,6 +19,8 @@
|
||||
#ifndef MEGACMDCOMMONUTILS_H
|
||||
#define MEGACMDCOMMONUTILS_H
|
||||
|
||||
#include "megacmd_utf8.h"
|
||||
|
||||
#include <memory>
|
||||
#ifndef _WIN32
|
||||
#include <pwd.h>
|
||||
@ -38,6 +40,7 @@
|
||||
#include <condition_variable>
|
||||
#include <cassert>
|
||||
#include <optional>
|
||||
#include <thread>
|
||||
|
||||
#ifndef UNUSED
|
||||
#define UNUSED(x) (void)(x)
|
||||
@ -50,52 +53,12 @@
|
||||
using std::setw;
|
||||
using std::left;
|
||||
|
||||
#ifdef _WIN32
|
||||
namespace mega{
|
||||
|
||||
// Note: these was in megacmd namespace, but after one overload of operator<< was created within mega,
|
||||
// ADL did not seem to be able to find it when solving template resolution in loggin.h (namespace mega),
|
||||
// even for code coming from megacmd namespace.
|
||||
// placing this operator in mega namespace eases ADL lookup and allows compilation
|
||||
std::ostringstream & operator<< ( std::ostringstream & ostr, std::wstring const &str); //override for the log, otherwise SimpleLog won't compile.
|
||||
}
|
||||
#endif
|
||||
|
||||
namespace megacmd {
|
||||
|
||||
/* platform dependent */
|
||||
#ifdef _WIN32
|
||||
|
||||
#define OUTSTREAMTYPE std::wostream
|
||||
#define OUTFSTREAMTYPE std::wofstream
|
||||
#define OUTSTRINGSTREAM std::wostringstream
|
||||
#define OUTSTRING std::wstring
|
||||
#define COUT std::wcout
|
||||
#define CERR std::wcerr
|
||||
|
||||
//override << operators for wostream for string and const char *
|
||||
std::wostream & operator<< ( std::wostream & ostr, std::string const & str );
|
||||
std::wostream & operator<< ( std::wostream & ostr, const char * str );
|
||||
|
||||
void stringtolocalw(const char* path, std::wstring* local);
|
||||
void localwtostring(const std::wstring* wide, std::string *multibyte);
|
||||
std::string getutf8fromUtf16(const wchar_t *ws);
|
||||
void utf16ToUtf8(const wchar_t* utf16data, int utf16size, std::string* utf8string);
|
||||
|
||||
#else
|
||||
#define OUTSTREAMTYPE std::ostream
|
||||
#define OUTFSTREAMTYPE std::ofstream
|
||||
#define OUTSTRINGSTREAM std::ostringstream
|
||||
#define OUTSTRING std::string
|
||||
#define COUT std::cout
|
||||
#define CERR std::cerr
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef _WIN32
|
||||
#define ARRAYSIZE(a) (sizeof((a)) / sizeof(*(a)))
|
||||
#endif
|
||||
|
||||
namespace megacmd {
|
||||
|
||||
/* commands */
|
||||
static std::vector<std::string> validGlobalParameters {"v", "help"};
|
||||
static std::vector<std::string> localremotefolderpatterncommands {"sync", "fuse-add"};
|
||||
@ -131,11 +94,8 @@ static std::vector<std::string> loginInValidCommands { "log", "debug", "speedlim
|
||||
static std::vector<std::string> allValidCommands { "login", "signup", "confirm", "session", "mount", "ls", "cd", "log", "debug", "pwd", "lcd", "lpwd", "import", "masterkey",
|
||||
"put", "get", "attr", "userattr", "mkdir", "rm", "du", "mv", "cp", "sync", "sync-ignore", "export", "share", "invite", "ipc", "df",
|
||||
"showpcr", "users", "speedlimit", "killsession", "whoami", "help", "passwd", "reload", "logout", "version", "quit",
|
||||
"thumbnail", "preview", "find", "completion", "clear", "https", "sync-issues"
|
||||
#ifdef HAVE_DOWNLOADS_COMMAND
|
||||
, "downloads"
|
||||
#endif
|
||||
, "transfers", "exclude", "exit", "errorcode", "graphics",
|
||||
"thumbnail", "preview", "find", "completion", "clear", "https", "sync-issues",
|
||||
"transfers", "exclude", "exit", "errorcode", "graphics",
|
||||
"cancel", "confirmcancel", "cat", "tree", "psa", "proxy"
|
||||
, "mediainfo"
|
||||
#ifdef HAVE_LIBUV
|
||||
@ -168,6 +128,8 @@ static std::vector<std::string> allValidCommands { "login", "signup", "confirm",
|
||||
|
||||
static const int RESUME_SESSION_TIMEOUT = 10;
|
||||
|
||||
std::string errorCodeStr(const std::error_code& ec);
|
||||
|
||||
/* Files and folders */
|
||||
|
||||
//tests if a path is writable //TODO: move to fsAccess
|
||||
@ -259,7 +221,10 @@ OUTSTRING getRightAlignedStr(T what, int n)
|
||||
void printCenteredLine(std::string msj, unsigned int width, bool encapsulated = true);
|
||||
void printCenteredContents(std::string msj, unsigned int width, bool encapsulated = true);
|
||||
void printCenteredContentsCerr(std::string msj, unsigned int width, bool encapsulated = true);
|
||||
void printCenteredLine(OUTSTREAMTYPE &os, std::string msj, unsigned int width, bool encapsulated = true);
|
||||
|
||||
template <typename Stream_T>
|
||||
void printCenteredLine(Stream_T &os, std::string msj, unsigned int width, bool encapsulated = true);
|
||||
|
||||
void printCenteredContents(OUTSTREAMTYPE &os, std::string msj, unsigned int width, bool encapsulated = true);
|
||||
|
||||
template <typename WHERE>
|
||||
@ -319,11 +284,12 @@ std::string getCurrentExecPath();
|
||||
std::string <rimProperty(std::string &s, const char &c);
|
||||
std::string &rtrimProperty(std::string &s, const char &c);
|
||||
std::string &trimProperty(std::string &what);
|
||||
std::string getPropertyFromFile(const char *configFile, const char *propertyName);
|
||||
std::string getPropertyFromFile(const fs::path &configFilePath, const char *propertyName);
|
||||
|
||||
template <typename T>
|
||||
T getValueFromFile(const char *configFile, const char *propertyName, T defaultValue)
|
||||
T getValueFromFile(const fs::path &configFilePath, const char *propertyName, T defaultValue)
|
||||
{
|
||||
std::string propValue = getPropertyFromFile(configFile, propertyName);
|
||||
std::string propValue = getPropertyFromFile(configFilePath, propertyName);
|
||||
if (!propValue.size()) return defaultValue;
|
||||
|
||||
T i;
|
||||
@ -403,12 +369,14 @@ class PlatformDirectories
|
||||
{
|
||||
public:
|
||||
static std::unique_ptr<PlatformDirectories> getPlatformSpecificDirectories();
|
||||
virtual ~PlatformDirectories() = default;
|
||||
|
||||
/**
|
||||
* @brief runtimeDirPath returns the base path for storing runtime files:
|
||||
*
|
||||
* Meant for sockets, named pipes, file locks, command history, etc.
|
||||
*/
|
||||
virtual std::string runtimeDirPath()
|
||||
virtual fs::path runtimeDirPath()
|
||||
{
|
||||
return configDirPath();
|
||||
}
|
||||
@ -418,7 +386,7 @@ public:
|
||||
* Meant for user-editable configuration files, data files that should not be deleted
|
||||
* (session credentials, SDK workding directory, logs, etc).
|
||||
*/
|
||||
virtual std::string configDirPath() = 0;
|
||||
virtual fs::path configDirPath() = 0;
|
||||
};
|
||||
|
||||
template <typename T> size_t numberOfDigits(T num)
|
||||
@ -435,7 +403,7 @@ template <typename T> size_t numberOfDigits(T num)
|
||||
#ifdef _WIN32
|
||||
class WindowsDirectories : public PlatformDirectories
|
||||
{
|
||||
std::string configDirPath() override;
|
||||
fs::path configDirPath() override;
|
||||
};
|
||||
std::wstring getNamedPipeName();
|
||||
#else // !defined(_WIN32)
|
||||
@ -443,7 +411,7 @@ class PosixDirectories : public PlatformDirectories
|
||||
{
|
||||
public:
|
||||
std::string homeDirPath();
|
||||
virtual std::string configDirPath() override;
|
||||
virtual fs::path configDirPath() override;
|
||||
|
||||
static std::string noHomeFallbackFolder();
|
||||
|
||||
@ -451,7 +419,7 @@ public:
|
||||
#ifdef __APPLE__
|
||||
class MacOSDirectories : public PosixDirectories
|
||||
{
|
||||
std::string runtimeDirPath() override;
|
||||
fs::path runtimeDirPath() override;
|
||||
};
|
||||
#endif // defined(__APPLE__)
|
||||
std::string getOrCreateSocketPath(bool createDirectory);
|
||||
@ -563,5 +531,39 @@ public:
|
||||
~ScopeGuard() { mExitCb(); }
|
||||
};
|
||||
|
||||
template <typename _Rep, typename _Period, typename _Rep2, typename _Period2, typename Condition, typename What>
|
||||
void timelyRetry(const std::chrono::duration<_Rep, _Period> &maxTime, const std::chrono::duration<_Rep2, _Period2> &step
|
||||
, Condition&& endCondition, What&& what)
|
||||
{
|
||||
using Step_t = std::chrono::duration<_Rep2, _Period2>;
|
||||
for (auto timeLeft = std::chrono::duration_cast<Step_t>(maxTime); !endCondition() && timeLeft > Step_t(0); timeLeft -= step)
|
||||
{
|
||||
std::this_thread::sleep_for(step);
|
||||
what();
|
||||
}
|
||||
}
|
||||
|
||||
class HammeringLimiter
|
||||
{
|
||||
int mLimitSecs;
|
||||
std::optional<std::chrono::steady_clock::time_point> mLastCall;
|
||||
public:
|
||||
HammeringLimiter(int seconds) : mLimitSecs(seconds) {}
|
||||
|
||||
// Returns true if run recently (or sets the last call to current time otherwise)
|
||||
bool runRecently()
|
||||
{
|
||||
auto now = std::chrono::steady_clock::now();
|
||||
if (mLastCall && std::chrono::duration_cast<std::chrono::seconds>(now - *mLastCall).count() <= mLimitSecs)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
mLastCall = now;
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
}//end namespace
|
||||
|
||||
|
||||
#endif // MEGACMDCOMMONUTILS_H
|
||||
|
@ -22,7 +22,6 @@
|
||||
|
||||
#include "megacmdutils.h"
|
||||
#include "megacmdcommonutils.h"
|
||||
#include "megacmdtransfermanager.h"
|
||||
#include "configurationmanager.h"
|
||||
#include "megacmdlogger.h"
|
||||
#include "comunicationsmanager.h"
|
||||
@ -39,7 +38,6 @@
|
||||
#include <limits>
|
||||
#include <string>
|
||||
#include <ctime>
|
||||
#include <filesystem>
|
||||
#include <set>
|
||||
|
||||
#include <signal.h>
|
||||
@ -49,7 +47,6 @@
|
||||
using TI = TestInstruments;
|
||||
#endif
|
||||
|
||||
namespace fs = std::filesystem;
|
||||
using namespace mega;
|
||||
using namespace std;
|
||||
|
||||
@ -799,7 +796,7 @@ MegaNode * MegaCmdExecuter::getBaseNode(string thepath, string &rest, bool *isre
|
||||
}
|
||||
else if (thepath == "//in")
|
||||
{
|
||||
baseNode = api->getInboxNode();
|
||||
baseNode = api->getVaultNode();
|
||||
rest = "";
|
||||
}
|
||||
else if (thepath == "/")
|
||||
@ -814,7 +811,7 @@ MegaNode * MegaCmdExecuter::getBaseNode(string thepath, string &rest, bool *isre
|
||||
}
|
||||
else if (thepath.find("//in/") == 0 )
|
||||
{
|
||||
baseNode = api->getInboxNode();
|
||||
baseNode = api->getVaultNode();
|
||||
rest = thepath.substr(5);
|
||||
}
|
||||
else if (thepath.find("/") == 0 && !(thepath.find("//from/") == 0 ))
|
||||
@ -1628,9 +1625,11 @@ void MegaCmdExecuter::createOrModifyBackup(string local, string remote, string s
|
||||
{
|
||||
if (establishBackup(local, n.get(), period, speriod, numBackups))
|
||||
{
|
||||
mtxBackupsMap.lock();
|
||||
ConfigurationManager::saveBackups(&ConfigurationManager::configuredBackups);
|
||||
mtxBackupsMap.unlock();
|
||||
{
|
||||
std::lock_guard g(mtxBackupsMap);
|
||||
ConfigurationManager::saveBackups(&ConfigurationManager::configuredBackups);
|
||||
}
|
||||
|
||||
OUTSTREAM << "Backup established: " << local << " into " << remote << " period="
|
||||
<< ((period != -1)?getReadablePeriod(period/10):"\""+speriod+"\"")
|
||||
<< " Number-of-Backups=" << numBackups << endl;
|
||||
@ -2229,7 +2228,7 @@ void MegaCmdExecuter::actUponGetExtendedAccountDetails(std::unique_ptr<::mega::M
|
||||
<< getFixLengthString(SSTR(storageDetails->getNumFolders(n->getHandle())), 5, ' ', true) << " folder(s)" << endl;
|
||||
}
|
||||
|
||||
n = std::unique_ptr<MegaNode>(api->getInboxNode());
|
||||
n = std::unique_ptr<MegaNode>(api->getVaultNode());
|
||||
if (n)
|
||||
{
|
||||
OUTSTREAM << " In INBOX: " << getFixLengthString(sizeToText(storageDetails->getStorageUsed(n->getHandle())), 9, ' ', true) << "ytes in "
|
||||
@ -2612,13 +2611,6 @@ int MegaCmdExecuter::actUponLogin(SynchronousRequestListener *srl, int timeout)
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_DOWNLOADS_COMMAND
|
||||
bool downloads_tracking_enabled = ConfigurationManager::getConfigurationValue("downloads_tracking_enabled", false);
|
||||
if (downloads_tracking_enabled)
|
||||
{
|
||||
DownloadsManager::Instance().start();
|
||||
}
|
||||
#endif
|
||||
ConfigurationManager::migrateSyncConfig(api);
|
||||
|
||||
LOG_info << "Fetching nodes ... ";
|
||||
@ -2890,39 +2882,6 @@ void MegaCmdExecuter::fetchNodes(MegaApi *api, int clientID)
|
||||
#endif
|
||||
}
|
||||
|
||||
void MegaCmdExecuter::cleanSlateTranfers()
|
||||
{
|
||||
#ifdef HAVE_DOWNLOADS_COMMAND
|
||||
bool downloads_cleanslate = ConfigurationManager::getConfigurationValue("downloads_cleanslate_enabled", false);
|
||||
|
||||
if (downloads_cleanslate)
|
||||
{
|
||||
auto megaCmdListener = std::make_unique<MegaCmdListener>(nullptr);
|
||||
api->cancelTransfers(MegaTransfer::TYPE_DOWNLOAD, megaCmdListener.get());
|
||||
megaCmdListener->wait();
|
||||
if (checkNoErrors(megaCmdListener->getError(), "cancel all download transfers"))
|
||||
{
|
||||
LOG_debug << "Download transfers cancelled successfully.";
|
||||
}
|
||||
megaCmdListener.reset(new MegaCmdListener(nullptr));
|
||||
api->cancelTransfers(MegaTransfer::TYPE_UPLOAD, megaCmdListener.get());
|
||||
megaCmdListener->wait();
|
||||
if (checkNoErrors(megaCmdListener->getError(), "cancel all upload transfers"))
|
||||
{
|
||||
LOG_debug << "Upload transfers cancelled successfully.";
|
||||
}
|
||||
|
||||
{
|
||||
globalTransferListener->completedTransfersMutex.lock();
|
||||
globalTransferListener->completedTransfers.clear();
|
||||
globalTransferListener->completedTransfersMutex.unlock();
|
||||
}
|
||||
|
||||
DownloadsManager::Instance().purge();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void MegaCmdExecuter::actUponLogout(SynchronousRequestListener *srl, bool keptSession, int timeout)
|
||||
{
|
||||
if (!timeout)
|
||||
@ -2954,9 +2913,6 @@ void MegaCmdExecuter::actUponLogout(SynchronousRequestListener *srl, bool keptSe
|
||||
}
|
||||
ConfigurationManager::clearConfigurationFile();
|
||||
|
||||
#ifdef HAVE_DOWNLOADS_COMMAND
|
||||
DownloadsManager::Instance().shutdown(true);
|
||||
#endif
|
||||
mtxSyncMap.unlock();
|
||||
|
||||
// clear greetings (asuming they are account-related)
|
||||
@ -3465,9 +3421,9 @@ void MegaCmdExecuter::exportNode(MegaNode *n, int64_t expireTime, const std::opt
|
||||
"You are strictly prohibited from using the MEGA cloud service to infringe copyright.\n"
|
||||
"You may not upload, download, store, share, display, stream, distribute, email, link to, "
|
||||
"transmit or otherwise make available any files, data or content that infringes any copyright "
|
||||
"or other proprietary rights of any person or entity.");
|
||||
"or other proprietary rights of any person or entity.\n");
|
||||
|
||||
confirmationQuery += " Do you accept this terms? (Yes/No): ";
|
||||
confirmationQuery += "Do you accept these terms? (Yes/No): ";
|
||||
|
||||
const int confirmationResponse = askforConfirmation(confirmationQuery);
|
||||
if (confirmationResponse != MCMDCONFIRM_YES && confirmationResponse != MCMDCONFIRM_ALL)
|
||||
@ -4331,7 +4287,7 @@ void MegaCmdExecuter::printTransferColumnDisplayer(ColumnDisplayer *cd, MegaTran
|
||||
//Direction
|
||||
string type;
|
||||
#ifdef _WIN32
|
||||
type += getutf8fromUtf16((transfer->getType() == MegaTransfer::TYPE_DOWNLOAD)?L"\u25bc":L"\u25b2");
|
||||
type += utf16ToUtf8((transfer->getType() == MegaTransfer::TYPE_DOWNLOAD)?L"\u25bc":L"\u25b2");
|
||||
#else
|
||||
type += (transfer->getType() == MegaTransfer::TYPE_DOWNLOAD)?"\u21d3":"\u21d1";
|
||||
#endif
|
||||
@ -4341,7 +4297,7 @@ void MegaCmdExecuter::printTransferColumnDisplayer(ColumnDisplayer *cd, MegaTran
|
||||
if (transfer->isSyncTransfer())
|
||||
{
|
||||
#ifdef _WIN32
|
||||
type += getutf8fromUtf16(L"\u21a8");
|
||||
type += utf16ToUtf8(L"\u21a8");
|
||||
#else
|
||||
type += "\u21f5";
|
||||
#endif
|
||||
@ -4349,7 +4305,7 @@ void MegaCmdExecuter::printTransferColumnDisplayer(ColumnDisplayer *cd, MegaTran
|
||||
else if (transfer->isBackupTransfer())
|
||||
{
|
||||
#ifdef _WIN32
|
||||
type += getutf8fromUtf16(L"\u2191");
|
||||
type += utf16ToUtf8(L"\u2191");
|
||||
#else
|
||||
type += "\u23eb";
|
||||
#endif
|
||||
@ -5014,43 +4970,55 @@ bool MegaCmdExecuter::establishBackup(string pathToBackup, MegaNode *n, int64_t
|
||||
LOG_err << " Failed to expanse path";
|
||||
}
|
||||
|
||||
MegaCmdListener *megaCmdListener = new MegaCmdListener(api, NULL);
|
||||
api->setScheduledCopy(expansedAbsolutePath.toPath(false).c_str(), n, attendpastbackups, period, speriod.c_str(), numBackups, megaCmdListener);
|
||||
auto megaCmdListener = std::make_unique<MegaCmdListener>(api, nullptr);
|
||||
api->setScheduledCopy(expansedAbsolutePath.toPath(false).c_str(), n, attendpastbackups, period, speriod.c_str(), numBackups, megaCmdListener.get());
|
||||
megaCmdListener->wait();
|
||||
if (checkNoErrors(megaCmdListener->getError(), "establish backup"))
|
||||
{
|
||||
mtxBackupsMap.lock();
|
||||
|
||||
backup_struct *thebackup = NULL;
|
||||
if (ConfigurationManager::configuredBackups.find(megaCmdListener->getRequest()->getFile()) != ConfigurationManager::configuredBackups.end())
|
||||
backup_struct *thebackup = nullptr;
|
||||
bool sendBackupEvent = false;
|
||||
{
|
||||
thebackup = ConfigurationManager::configuredBackups[megaCmdListener->getRequest()->getFile()];
|
||||
if (thebackup->id == -1)
|
||||
std::lock_guard g(mtxBackupsMap);
|
||||
if (ConfigurationManager::configuredBackups.find(megaCmdListener->getRequest()->getFile()) != ConfigurationManager::configuredBackups.end())
|
||||
{
|
||||
thebackup = ConfigurationManager::configuredBackups[megaCmdListener->getRequest()->getFile()];
|
||||
if (thebackup->id == -1)
|
||||
{
|
||||
thebackup->id = backupcounter++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
thebackup = new backup_struct;
|
||||
thebackup->id = backupcounter++;
|
||||
ConfigurationManager::configuredBackups[megaCmdListener->getRequest()->getFile()] = thebackup;
|
||||
sendBackupEvent = true;
|
||||
}
|
||||
thebackup->active = true;
|
||||
thebackup->handle = megaCmdListener->getRequest()->getNodeHandle();
|
||||
thebackup->localpath = string(megaCmdListener->getRequest()->getFile());
|
||||
thebackup->numBackups = numBackups;
|
||||
thebackup->period = period;
|
||||
thebackup->speriod = speriod;
|
||||
thebackup->failed = false;
|
||||
thebackup->tag = megaCmdListener->getRequest()->getTransferTag();
|
||||
}
|
||||
|
||||
if (sendBackupEvent)
|
||||
{
|
||||
auto wasFirstBackupConfiguredOpt = ConfigurationManager::savePropertyValue("firstBackupConfigured", true);
|
||||
if (!wasFirstBackupConfiguredOpt || !*wasFirstBackupConfiguredOpt)
|
||||
{
|
||||
sendEvent(StatsManager::MegacmdEvent::FIRST_CONFIGURED_SCHEDULED_BACKUP, api, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
sendEvent(StatsManager::MegacmdEvent::SUBSEQUENT_CONFIGURED_SCHEDULED_BACKUP, api, false);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
thebackup = new backup_struct;
|
||||
thebackup->id = backupcounter++;
|
||||
ConfigurationManager::configuredBackups[megaCmdListener->getRequest()->getFile()] = thebackup;
|
||||
}
|
||||
thebackup->active = true;
|
||||
thebackup->handle = megaCmdListener->getRequest()->getNodeHandle();
|
||||
thebackup->localpath = string(megaCmdListener->getRequest()->getFile());
|
||||
thebackup->numBackups = numBackups;
|
||||
thebackup->period = period;
|
||||
thebackup->speriod = speriod;
|
||||
thebackup->failed = false;
|
||||
thebackup->tag = megaCmdListener->getRequest()->getTransferTag();
|
||||
|
||||
char * nodepath = api->getNodePath(n);
|
||||
std::unique_ptr<char[]> nodepath(api->getNodePath(n));
|
||||
LOG_info << "Added backup: " << megaCmdListener->getRequest()->getFile() << " to " << nodepath;
|
||||
mtxBackupsMap.unlock();
|
||||
delete []nodepath;
|
||||
delete megaCmdListener;
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
@ -5088,33 +5056,34 @@ bool MegaCmdExecuter::establishBackup(string pathToBackup, MegaNode *n, int64_t
|
||||
}
|
||||
}
|
||||
}
|
||||
delete megaCmdListener;
|
||||
return false;
|
||||
}
|
||||
|
||||
void MegaCmdExecuter::confirmCancel(const char* confirmlink, const char* pass)
|
||||
{
|
||||
MegaCmdListener *megaCmdListener = new MegaCmdListener(NULL);
|
||||
api->confirmCancelAccount(confirmlink, pass, megaCmdListener);
|
||||
auto megaCmdListener = std::make_unique<MegaCmdListener>(nullptr);
|
||||
api->confirmCancelAccount(confirmlink, pass, megaCmdListener.get());
|
||||
megaCmdListener->wait();
|
||||
|
||||
if (megaCmdListener->getError()->getErrorCode() == MegaError::API_ETOOMANY)
|
||||
{
|
||||
LOG_err << "Confirm cancel account failed: too many attempts";
|
||||
}
|
||||
else if (megaCmdListener->getError()->getErrorCode() == MegaError::API_ENOENT
|
||||
|| megaCmdListener->getError()->getErrorCode() == MegaError::API_EKEY)
|
||||
else if (megaCmdListener->getError()->getErrorCode() == MegaError::API_ENOENT ||
|
||||
megaCmdListener->getError()->getErrorCode() == MegaError::API_EKEY)
|
||||
{
|
||||
LOG_err << "Confirm cancel account failed: invalid link/password";
|
||||
}
|
||||
else if (checkNoErrors(megaCmdListener->getError(), "confirm cancel account"))
|
||||
// We consider ESID (bad session ID) as successful because of a data race in the SDK
|
||||
else if (megaCmdListener->getError()->getErrorCode() == MegaError::API_ESID ||
|
||||
checkNoErrors(megaCmdListener->getError(), "confirm cancel account"))
|
||||
{
|
||||
OUTSTREAM << "CONFIRM Account cancelled succesfully" << endl;
|
||||
MegaCmdListener *megaCmdListener2 = new MegaCmdListener(NULL);
|
||||
api->localLogout(megaCmdListener2);
|
||||
actUponLogout(megaCmdListener2, false);
|
||||
delete megaCmdListener2;
|
||||
|
||||
megaCmdListener = std::make_unique<MegaCmdListener>(nullptr);
|
||||
api->localLogout(megaCmdListener.get());
|
||||
actUponLogout(megaCmdListener.get(), false);
|
||||
}
|
||||
delete megaCmdListener;
|
||||
}
|
||||
|
||||
void MegaCmdExecuter::processPath(string path, bool usepcre, bool& firstone, void (*nodeprocessor)(MegaCmdExecuter *, MegaNode *, bool), MegaCmdExecuter *context)
|
||||
@ -5200,20 +5169,31 @@ void MegaCmdExecuter::removeWebdavLocation(MegaNode *n, bool firstone, string na
|
||||
|
||||
void MegaCmdExecuter::addWebdavLocation(MegaNode *n, bool firstone, string name)
|
||||
{
|
||||
char *actualNodePath = api->getNodePath(n);
|
||||
char *l = api->httpServerGetLocalWebDavLink(n);
|
||||
OUTSTREAM << "Serving via webdav " << (name.size()?name:actualNodePath) << ": " << l << endl;
|
||||
std::unique_ptr<char[]> actualNodePath(api->getNodePath(n));
|
||||
std::unique_ptr<char[]> l(api->httpServerGetLocalWebDavLink(n));
|
||||
|
||||
mtxWebDavLocations.lock();
|
||||
list<string> servedpaths = ConfigurationManager::getConfigurationValueList("webdav_served_locations");
|
||||
servedpaths.push_back(actualNodePath);
|
||||
servedpaths.sort();
|
||||
servedpaths.unique();
|
||||
ConfigurationManager::savePropertyValueList("webdav_served_locations", servedpaths);
|
||||
mtxWebDavLocations.unlock();
|
||||
OUTSTREAM << "Serving via webdav " << (name.size() ? name : actualNodePath.get()) << ": " << l.get() << endl;
|
||||
|
||||
delete []l;
|
||||
delete []actualNodePath;
|
||||
{
|
||||
std::lock_guard g(mtxWebDavLocations);
|
||||
list<string> servedpaths = ConfigurationManager::getConfigurationValueList("webdav_served_locations");
|
||||
|
||||
if (!ConfigurationManager::getConfigurationValue("firstWebDavConfigured", false))
|
||||
{
|
||||
sendEvent(StatsManager::MegacmdEvent::FIRST_CONFIGURED_WEBDAV, api, false);
|
||||
ConfigurationManager::savePropertyValue("firstWebDavConfigured", true);
|
||||
}
|
||||
else if (std::find(servedpaths.begin(), servedpaths.end(), actualNodePath.get()) == servedpaths.end())
|
||||
{
|
||||
// Send event only if not already on the list
|
||||
sendEvent(StatsManager::MegacmdEvent::SUBSEQUENT_CONFIGURED_WEBDAV, api, false);
|
||||
}
|
||||
|
||||
servedpaths.push_back(actualNodePath.get());
|
||||
servedpaths.sort();
|
||||
servedpaths.unique();
|
||||
ConfigurationManager::savePropertyValueList("webdav_served_locations", servedpaths);
|
||||
}
|
||||
}
|
||||
|
||||
void MegaCmdExecuter::removeFtpLocation(MegaNode *n, bool firstone, string name)
|
||||
@ -5248,20 +5228,31 @@ void MegaCmdExecuter::removeFtpLocation(MegaNode *n, bool firstone, string name)
|
||||
|
||||
void MegaCmdExecuter::addFtpLocation(MegaNode *n, bool firstone, string name)
|
||||
{
|
||||
char *actualNodePath = api->getNodePath(n);
|
||||
char *l = api->ftpServerGetLocalLink(n);
|
||||
OUTSTREAM << "Serving via ftp " << (name.size()?name:n->getName()) << ": " << l << endl;
|
||||
std::unique_ptr<char[]> actualNodePath(api->getNodePath(n));
|
||||
std::unique_ptr<char[]> l(api->ftpServerGetLocalLink(n));
|
||||
|
||||
mtxFtpLocations.lock();
|
||||
list<string> servedpaths = ConfigurationManager::getConfigurationValueList("ftp_served_locations");
|
||||
servedpaths.push_back(actualNodePath);
|
||||
servedpaths.sort();
|
||||
servedpaths.unique();
|
||||
ConfigurationManager::savePropertyValueList("ftp_served_locations", servedpaths);
|
||||
mtxFtpLocations.unlock();
|
||||
OUTSTREAM << "Serving via ftp " << (name.size() ? name : n->getName()) << ": " << l.get() << endl;
|
||||
|
||||
delete []l;
|
||||
delete []actualNodePath;
|
||||
{
|
||||
std::lock_guard g(mtxFtpLocations);
|
||||
list<string> servedpaths = ConfigurationManager::getConfigurationValueList("ftp_served_locations");
|
||||
|
||||
if (!ConfigurationManager::getConfigurationValue("firstFtpConfigured", false))
|
||||
{
|
||||
sendEvent(StatsManager::MegacmdEvent::FIRST_CONFIGURED_FTP, api, false);
|
||||
ConfigurationManager::savePropertyValue("firstFtpConfigured", true);
|
||||
}
|
||||
else if (std::find(servedpaths.begin(), servedpaths.end(), actualNodePath.get()) == servedpaths.end())
|
||||
{
|
||||
// Send event only if not already on the list
|
||||
sendEvent(StatsManager::MegacmdEvent::SUBSEQUENT_CONFIGURED_FTP, api, false);
|
||||
}
|
||||
|
||||
servedpaths.push_back(actualNodePath.get());
|
||||
servedpaths.sort();
|
||||
servedpaths.unique();
|
||||
ConfigurationManager::savePropertyValueList("ftp_served_locations", servedpaths);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@ -6674,18 +6665,7 @@ void MegaCmdExecuter::executecommand(vector<string> words, map<string, int> *clf
|
||||
}
|
||||
}
|
||||
|
||||
if (background) //TODO: do the same for uploads?
|
||||
{
|
||||
#ifdef HAVE_DOWNLOADS_COMMAND
|
||||
megaCmdMultiTransferListener->waitMultiStart();
|
||||
|
||||
for (auto & dlId : megaCmdMultiTransferListener->getStartedTransfers())
|
||||
{
|
||||
OUTSTREAM << "Started background transfer <" << dlId.mPath << ">. Tag = " << dlId.mTag << ". Object Identifier: " << dlId.getObjectID() << endl;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else
|
||||
if (!background)
|
||||
{
|
||||
megaCmdMultiTransferListener->waitMultiEnd();
|
||||
|
||||
@ -7013,53 +6993,49 @@ void MegaCmdExecuter::executecommand(vector<string> words, map<string, int> *clf
|
||||
}
|
||||
else if (words[0] == "log")
|
||||
{
|
||||
const bool cmdFlag = getFlag(clflags, "c");
|
||||
const bool sdkFlag = getFlag(clflags, "s");
|
||||
const bool noFlags = !cmdFlag && !sdkFlag;
|
||||
|
||||
if (words.size() == 1)
|
||||
{
|
||||
if (!getFlag(clflags, "s") && !getFlag(clflags, "c"))
|
||||
if (cmdFlag || noFlags)
|
||||
{
|
||||
OUTSTREAM << "MEGAcmd log level = " << getLogLevelStr(loggerCMD->getCmdLoggerLevel()) << endl;
|
||||
OUTSTREAM << "SDK log level = " << getLogLevelStr(loggerCMD->getSdkLoggerLevel()) << endl;
|
||||
}
|
||||
else if (getFlag(clflags, "s"))
|
||||
|
||||
if (sdkFlag || noFlags)
|
||||
{
|
||||
OUTSTREAM << "SDK log level = " << getLogLevelStr(loggerCMD->getSdkLoggerLevel()) << endl;
|
||||
}
|
||||
else if (getFlag(clflags, "c"))
|
||||
{
|
||||
OUTSTREAM << "MEGAcmd log level = " << getLogLevelStr(loggerCMD->getCmdLoggerLevel()) << endl;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int newLogLevel = getLogLevelNum(words[1].c_str());
|
||||
if (newLogLevel == -1)
|
||||
auto newLogLevelOpt = getLogLevelNum(words[1].c_str());
|
||||
if (!newLogLevelOpt)
|
||||
{
|
||||
setCurrentThreadOutCode(MCMD_EARGS);
|
||||
LOG_err << "Invalid log level";
|
||||
return;
|
||||
}
|
||||
newLogLevel = max(newLogLevel, (int)MegaApi::LOG_LEVEL_FATAL);
|
||||
newLogLevel = min(newLogLevel, (int)MegaApi::LOG_LEVEL_MAX);
|
||||
if (!getFlag(clflags, "s") && !getFlag(clflags, "c"))
|
||||
const int newLogLevel = *newLogLevelOpt;
|
||||
|
||||
if (cmdFlag || noFlags)
|
||||
{
|
||||
loggerCMD->setCmdLoggerLevel(newLogLevel);
|
||||
loggerCMD->setSdkLoggerLevel(newLogLevel);
|
||||
ConfigurationManager::savePropertyValue("cmdLogLevel", newLogLevel);
|
||||
|
||||
OUTSTREAM << "MEGAcmd log level = " << getLogLevelStr(loggerCMD->getCmdLoggerLevel()) << endl;
|
||||
OUTSTREAM << "SDK log level = " << getLogLevelStr(loggerCMD->getSdkLoggerLevel()) << endl;
|
||||
}
|
||||
else if (getFlag(clflags, "s"))
|
||||
|
||||
if (sdkFlag || noFlags)
|
||||
{
|
||||
loggerCMD->setSdkLoggerLevel(newLogLevel);
|
||||
ConfigurationManager::savePropertyValue("sdkLogLevel", newLogLevel);
|
||||
|
||||
OUTSTREAM << "SDK log level = " << getLogLevelStr(loggerCMD->getSdkLoggerLevel()) << endl;
|
||||
}
|
||||
else if (getFlag(clflags, "c"))
|
||||
{
|
||||
loggerCMD->setCmdLoggerLevel(newLogLevel);
|
||||
OUTSTREAM << "MEGAcmd log level = " << getLogLevelStr(loggerCMD->getCmdLoggerLevel()) << endl;
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
else if (words[0] == "pwd")
|
||||
{
|
||||
@ -9335,7 +9311,7 @@ void MegaCmdExecuter::executecommand(vector<string> words, map<string, int> *clf
|
||||
long long storageMax = details->getStorageMax();
|
||||
|
||||
unique_ptr<MegaNode> root(api->getRootNode());
|
||||
unique_ptr<MegaNode> inbox(api->getInboxNode());
|
||||
unique_ptr<MegaNode> inbox(api->getVaultNode());
|
||||
unique_ptr<MegaNode> rubbish(api->getRubbishNode());
|
||||
unique_ptr<MegaNodeList> inShares(api->getInShares());
|
||||
|
||||
@ -10040,7 +10016,7 @@ void MegaCmdExecuter::executecommand(vector<string> words, map<string, int> *clf
|
||||
}
|
||||
for (int i = 0; i < ocrl->size(); i++)
|
||||
{
|
||||
MegaContactRequest * cr = ocrl->get(i);
|
||||
auto cr = ocrl->get(i);
|
||||
OUTSTREAM << " " << getLeftAlignedStr(cr->getTargetEmail(),22);
|
||||
|
||||
char * sid = api->userHandleToBase64(cr->getHandle());
|
||||
@ -10068,7 +10044,7 @@ void MegaCmdExecuter::executecommand(vector<string> words, map<string, int> *clf
|
||||
|
||||
for (int i = 0; i < icrl->size(); i++)
|
||||
{
|
||||
MegaContactRequest * cr = icrl->get(i);
|
||||
auto cr = icrl->get(i);
|
||||
OUTSTREAM << " " << getLeftAlignedStr(cr->getSourceEmail(), 22);
|
||||
|
||||
MegaHandle id = cr->getHandle();
|
||||
@ -10142,101 +10118,6 @@ void MegaCmdExecuter::executecommand(vector<string> words, map<string, int> *clf
|
||||
|
||||
return;
|
||||
}
|
||||
#ifdef HAVE_DOWNLOADS_COMMAND
|
||||
else if (words[0] == "downloads")
|
||||
{
|
||||
if (getFlag(clflags, "purge"))
|
||||
{
|
||||
OUTSTREAM << "Cancelling and cleaning all transfers and history ..." << endl;
|
||||
cleanSlateTranfers();
|
||||
OUTSTREAM << "... done" << endl;
|
||||
return;
|
||||
}
|
||||
if (getFlag(clflags, "enable-clean-slate"))
|
||||
{
|
||||
bool downloads_cleanslate_enabled_before = ConfigurationManager::getConfigurationValue("downloads_cleanslate_enabled", false);
|
||||
|
||||
if (!downloads_cleanslate_enabled_before)
|
||||
{
|
||||
ConfigurationManager::savePropertyValue("downloads_cleanslate_enabled", true);
|
||||
}
|
||||
|
||||
OUTSTREAM << "Enabled clean slate: transfers from previous executions will be discarded upon restart" << endl;
|
||||
return;
|
||||
}
|
||||
else if (getFlag(clflags, "disable-clean-slate"))
|
||||
{
|
||||
bool downloads_cleanslate_enabled_before = ConfigurationManager::getConfigurationValue("downloads_cleanslate_enabled", false);
|
||||
|
||||
if (downloads_cleanslate_enabled_before)
|
||||
{
|
||||
ConfigurationManager::savePropertyValue("downloads_cleanslate_enabled", false);
|
||||
}
|
||||
OUTSTREAM << "Disabled clean slate: transfers from previous executions will not be discarded upon restart" << endl;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
bool queryEnabled = getFlag(clflags, "query-enabled");
|
||||
if (getFlag(clflags, "enable-tracking"))
|
||||
{
|
||||
bool downloads_tracking_enabled_before = ConfigurationManager::getConfigurationValue("downloads_tracking_enabled", false);
|
||||
|
||||
if (!downloads_tracking_enabled_before)
|
||||
{
|
||||
ConfigurationManager::savePropertyValue("downloads_tracking_enabled", true);
|
||||
DownloadsManager::Instance().start();
|
||||
}
|
||||
|
||||
queryEnabled = true;
|
||||
}
|
||||
else if (getFlag(clflags, "disable-tracking"))
|
||||
{
|
||||
bool downloads_tracking_enabled_before = ConfigurationManager::getConfigurationValue("downloads_tracking_enabled", false);
|
||||
|
||||
if (downloads_tracking_enabled_before)
|
||||
{
|
||||
ConfigurationManager::savePropertyValue("downloads_tracking_enabled", false);
|
||||
DownloadsManager::Instance().shutdown(true);
|
||||
}
|
||||
|
||||
queryEnabled = true;
|
||||
}
|
||||
|
||||
if (queryEnabled)
|
||||
{
|
||||
bool downloads_tracking_enabled = ConfigurationManager::getConfigurationValue("downloads_tracking_enabled", false);
|
||||
OUTSTREAM << "Download tracking is " << (downloads_tracking_enabled ? "enabled" : "disabled") << endl;
|
||||
return;
|
||||
}
|
||||
|
||||
if (getFlag(clflags, "report-all"))
|
||||
{
|
||||
OUTSTRINGSTREAM oss;
|
||||
DownloadsManager::Instance().printAll(oss, clflags, cloptions);
|
||||
OUTSTREAM << oss.str();
|
||||
return;
|
||||
}
|
||||
|
||||
/// report:
|
||||
if (words.size() < 2)
|
||||
{
|
||||
setCurrentThreadOutCode(MCMD_EARGS);
|
||||
LOG_err << " " << getUsageStr(words[0].c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
for (unsigned i = 1 ; i < words.size(); i++)
|
||||
{
|
||||
if (!words[i].empty())
|
||||
{
|
||||
OUTSTRINGSTREAM oss;
|
||||
DownloadsManager::Instance().printOne(oss, words[i], clflags, cloptions);
|
||||
OUTSTREAM << oss.str();
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
else if (words[0] == "transfers")
|
||||
{
|
||||
bool showcompleted = getFlag(clflags, "show-completed");
|
||||
@ -10800,13 +10681,28 @@ void MegaCmdExecuter::executecommand(vector<string> words, map<string, int> *clf
|
||||
return;
|
||||
}
|
||||
|
||||
auto syncIssues = mSyncIssuesManager.getSyncIssues();
|
||||
#ifdef MEGACMD_TESTING_CODE
|
||||
// Do not trust empty results (SDK may send them after spurious scans delayed 20ds. SDK-4813)
|
||||
timelyRetry(std::chrono::milliseconds(2300), std::chrono::milliseconds(200),
|
||||
[&syncIssues]() { return !syncIssues.empty(); },
|
||||
[this, &syncIssues, firstTime{true}]() mutable
|
||||
{
|
||||
if (firstTime)
|
||||
{
|
||||
LOG_warn << "sync-issues first retrieval returned empty";
|
||||
firstTime = false;
|
||||
}
|
||||
syncIssues = mSyncIssuesManager.getSyncIssues();
|
||||
LOG_warn << "sync-issues retrieval returned empty. Retried returned = " << syncIssues.size();
|
||||
});
|
||||
#endif
|
||||
|
||||
ColumnDisplayer cd(clflags, cloptions);
|
||||
|
||||
bool detailSyncIssue = getFlag(clflags, "detail");
|
||||
if (detailSyncIssue) // get the details of one or more issues
|
||||
{
|
||||
auto syncIssues = mSyncIssuesManager.getSyncIssues();
|
||||
|
||||
bool showAll = getFlag(clflags, "all");
|
||||
if (showAll)
|
||||
{
|
||||
@ -10840,7 +10736,6 @@ void MegaCmdExecuter::executecommand(vector<string> words, map<string, int> *clf
|
||||
}
|
||||
else // show all sync issues
|
||||
{
|
||||
auto syncIssues = mSyncIssuesManager.getSyncIssues();
|
||||
if (syncIssues.empty())
|
||||
{
|
||||
OUTSTREAM << "There are no sync issues" << endl;
|
||||
|
@ -19,8 +19,6 @@
|
||||
#ifndef MEGACMDEXECUTER_H
|
||||
#define MEGACMDEXECUTER_H
|
||||
|
||||
#include "megacmdtransfermanager.h"
|
||||
|
||||
#include "megacmdlogger.h"
|
||||
#include "megacmdsandbox.h"
|
||||
#include "listeners.h"
|
||||
@ -240,8 +238,7 @@ public:
|
||||
bool setProxy(const std::string &url, const std::string &username, const std::string &password, int proxyType);
|
||||
void fetchNodes(mega::MegaApi *api = nullptr, int clientID = -27);
|
||||
|
||||
|
||||
void cleanSlateTranfers();
|
||||
void mayExecutePendingStuffInWorkerThread();
|
||||
};
|
||||
|
||||
}//end namespace
|
||||
|
@ -21,23 +21,9 @@
|
||||
#include "megacmd_src_file_list.h"
|
||||
|
||||
#include <map>
|
||||
#include <filesystem>
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <fcntl.h>
|
||||
#include <io.h>
|
||||
#include <stdio.h>
|
||||
#ifndef _O_U16TEXT
|
||||
#define _O_U16TEXT 0x00020000
|
||||
#endif
|
||||
#ifndef _O_U8TEXT
|
||||
#define _O_U8TEXT 0x00040000
|
||||
#endif
|
||||
#endif
|
||||
|
||||
namespace fs = std::filesystem;
|
||||
using namespace mega;
|
||||
|
||||
namespace megacmd {
|
||||
@ -160,13 +146,12 @@ MegaCmdLogger::MegaCmdLogger() :
|
||||
{
|
||||
}
|
||||
|
||||
OUTSTRING MegaCmdLogger::getDefaultFilePath()
|
||||
fs::path MegaCmdLogger::getDefaultFilePath()
|
||||
{
|
||||
auto dirs = PlatformDirectories::getPlatformSpecificDirectories();
|
||||
assert(!dirs->configDirPath().empty());
|
||||
|
||||
auto logFilePath = fs::path(dirs->configDirPath()) / "megacmdserver.log";
|
||||
return logFilePath.native();
|
||||
assert(!dirs->configDirPath().empty());
|
||||
return dirs->configDirPath() / "megacmdserver.log";
|
||||
}
|
||||
|
||||
bool MegaCmdLogger::isMegaCmdSource(const std::string &source)
|
||||
@ -180,14 +165,47 @@ bool MegaCmdLogger::isMegaCmdSource(const std::string &source)
|
||||
return megaCmdSourceFiles.find(filename) != megaCmdSourceFiles.end();
|
||||
}
|
||||
|
||||
void MegaCmdLogger::formatLogToStream(LoggedStream &stream, std::string_view time, int logLevel, const char *source, const char *message)
|
||||
|
||||
const char * loglevelToShortPaddedString(int loglevel)
|
||||
{
|
||||
stream << "[";
|
||||
static constexpr std::array<const char*, 6> logLevels = {
|
||||
"CRIT ", // LOG_LEVEL_FATAL
|
||||
"ERR ", // LOG_LEVEL_ERROR
|
||||
"WARN ", // LOG_LEVEL_WARNING
|
||||
"INFO ", // LOG_LEVEL_INFO
|
||||
"DBG ", // LOG_LEVEL_DEBUG
|
||||
"DTL " // LOG_LEVEL_MAX
|
||||
};
|
||||
|
||||
assert (loglevel >= 0 && loglevel < static_cast<int>(logLevels.size()));
|
||||
return logLevels[static_cast<size_t>(loglevel)];
|
||||
}
|
||||
|
||||
void MegaCmdLogger::formatLogToStream(LoggedStream &stream, std::string_view time, int logLevel, const char *source, const char *message, bool surround)
|
||||
{
|
||||
if (surround)
|
||||
{
|
||||
stream << "[";
|
||||
}
|
||||
stream << time;
|
||||
if (!isMegaCmdSource(source))
|
||||
{
|
||||
stream << "SDK:";
|
||||
stream << " sdk ";
|
||||
}
|
||||
stream << SimpleLogger::toStr(LogLevel(logLevel)) << ": " << time << "] " << message << '\n';
|
||||
else
|
||||
{
|
||||
stream << " cmd ";
|
||||
}
|
||||
stream << loglevelToShortPaddedString(logLevel) << message;
|
||||
if (surround)
|
||||
{
|
||||
stream << "]";
|
||||
}
|
||||
else
|
||||
{
|
||||
stream << " [" << source << "]";
|
||||
}
|
||||
stream << '\n';
|
||||
|
||||
if (logLevel <= mFlushOnLevel)
|
||||
{
|
||||
@ -259,6 +277,13 @@ int MegaCmdSimpleLogger::getMaxLogLevel() const
|
||||
|
||||
void MegaCmdSimpleLogger::log(const char * /*time*/, int logLevel, const char *source, const char *message)
|
||||
{
|
||||
if (!isValidUtf8(message, strlen(message)))
|
||||
{
|
||||
constexpr const char* invalid = "<invalid utf8>";
|
||||
message = invalid;
|
||||
assert(false && "Attempt to log invalid utf8 string");
|
||||
}
|
||||
|
||||
if (shouldIgnoreMessage(logLevel, source, message))
|
||||
{
|
||||
return;
|
||||
@ -266,29 +291,23 @@ void MegaCmdSimpleLogger::log(const char * /*time*/, int logLevel, const char *s
|
||||
|
||||
if (shouldLogToStream(logLevel, source))
|
||||
{
|
||||
// log to _file_ (e.g: FileRotatingLoggedStream)
|
||||
const std::string nowTimeStr = getNowTimeStr();
|
||||
formatLogToStream(mLoggedStream, nowTimeStr, logLevel, source, message);
|
||||
|
||||
if (mLogToOutStream)
|
||||
if (mLogToOutStream) // log to stdout
|
||||
{
|
||||
#ifdef _WIN32
|
||||
std::lock_guard<std::mutex> g(mSetmodeMtx);
|
||||
int oldmode = _setmode(_fileno(stdout), _O_U8TEXT);
|
||||
WindowsUtf8StdoutGuard utf8Guard;
|
||||
#endif
|
||||
formatLogToStream(mOutStream, nowTimeStr, logLevel, source, message);
|
||||
|
||||
#ifdef _WIN32
|
||||
assert(oldmode != -1);
|
||||
_setmode(_fileno(stdout), oldmode);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if (shouldLogToClient(logLevel, source))
|
||||
{
|
||||
const std::string nowTimeStr = getNowTimeStr();
|
||||
assert(isMegaCmdSource(source)); // if this happens in the sdk thread, this shall be false
|
||||
formatLogToStream(OUTSTREAM, nowTimeStr, logLevel, source, message);
|
||||
formatLogToStream(OUTSTREAM, nowTimeStr, logLevel, source, message, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -19,12 +19,49 @@
|
||||
#ifndef MEGACMDLOGGER_H
|
||||
#define MEGACMDLOGGER_H
|
||||
|
||||
#include "megacmdcommonutils.h"
|
||||
|
||||
#include "megacmd.h"
|
||||
#include "comunicationsmanager.h"
|
||||
|
||||
#define OUTSTREAM getCurrentThreadOutStream()
|
||||
|
||||
namespace megacmd {
|
||||
|
||||
#ifdef WIN32
|
||||
inline ::mega::SimpleLogger &operator<<(::mega::SimpleLogger& sl, const fs::path& path)
|
||||
{
|
||||
return sl << megacmd::pathAsUtf8(path);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline std::enable_if_t<std::is_same_v<std::decay_t<T>, std::wstring>, ::mega::SimpleLogger &>
|
||||
operator<<(::mega::SimpleLogger& sl, const T& wstr)
|
||||
{
|
||||
return sl << megacmd::utf16ToUtf8(wstr);
|
||||
}
|
||||
#endif
|
||||
|
||||
// String used to transmit binary data
|
||||
class BinaryStringView
|
||||
{
|
||||
public:
|
||||
BinaryStringView(char *buffer, size_t size)
|
||||
: mValue(buffer, size)
|
||||
{}
|
||||
|
||||
const std::string_view& get() const {
|
||||
return mValue;
|
||||
}
|
||||
|
||||
std::string_view& get() {
|
||||
return mValue;
|
||||
}
|
||||
|
||||
private:
|
||||
std::string_view mValue;
|
||||
};
|
||||
|
||||
class LoggedStream
|
||||
{
|
||||
public:
|
||||
@ -40,6 +77,7 @@ public:
|
||||
virtual const LoggedStream& operator<<(std::wstring v) const = 0;
|
||||
#endif
|
||||
virtual const LoggedStream& operator<<(std::string v) const = 0;
|
||||
virtual const LoggedStream& operator<<(BinaryStringView v) const = 0;
|
||||
virtual const LoggedStream& operator<<(std::string_view v) const = 0;
|
||||
virtual const LoggedStream& operator<<(int v) const = 0;
|
||||
virtual const LoggedStream& operator<<(unsigned int v) const = 0;
|
||||
@ -66,6 +104,7 @@ public:
|
||||
#endif
|
||||
|
||||
const LoggedStream& operator<<(std::string v) const override { return *this; }
|
||||
const LoggedStream& operator<<(BinaryStringView v) const override { return *this; }
|
||||
const LoggedStream& operator<<(std::string_view v) const override { return *this; }
|
||||
const LoggedStream& operator<<(int v) const override { return *this; }
|
||||
const LoggedStream& operator<<(unsigned int v) const override { return *this; }
|
||||
@ -119,6 +158,15 @@ public:
|
||||
virtual const LoggedStream& operator<<(std::string_view v) const override { *out << v;return *this; }
|
||||
#endif
|
||||
virtual const LoggedStream& operator<<(std::string v) const override { *out << v;return *this; }
|
||||
virtual const LoggedStream& operator<<(BinaryStringView v) const override {
|
||||
#ifdef _WIN32
|
||||
assert(false && "wostream cannot take binary data directly");
|
||||
#else
|
||||
*out << v.get();
|
||||
#endif
|
||||
return *this;
|
||||
}
|
||||
|
||||
virtual const LoggedStream& operator<<(int v) const override { *out << v;return *this; }
|
||||
virtual const LoggedStream& operator<<(unsigned int v) const override { *out << v;return *this; }
|
||||
virtual const LoggedStream& operator<<(long unsigned int v) const override { *out << v;return *this; }
|
||||
@ -144,7 +192,7 @@ class LoggedStreamPartialOutputs : public LoggedStream
|
||||
{
|
||||
public:
|
||||
LoggedStreamPartialOutputs(ComunicationsManager *_cm, CmdPetition *_inf) : cm(_cm), inf(_inf) {}
|
||||
virtual bool isClientConnected() { return inf && !inf->clientDisconnected; }
|
||||
virtual bool isClientConnected() override { return inf && !inf->clientDisconnected; }
|
||||
|
||||
virtual const LoggedStream& operator<<(const char& v) const override { OUTSTRINGSTREAM os; os << v; OUTSTRING s = os.str(); cm->sendPartialOutput(inf, &s); return *this; }
|
||||
virtual const LoggedStream& operator<<(const char* v) const override { OUTSTRINGSTREAM os; os << v; OUTSTRING s = os.str(); cm->sendPartialOutput(inf, &s); return *this; }
|
||||
@ -155,6 +203,7 @@ public:
|
||||
#else
|
||||
virtual const LoggedStream& operator<<(std::string v) const override { cm->sendPartialOutput(inf, &v); return *this; }
|
||||
#endif
|
||||
virtual const LoggedStream& operator<<(BinaryStringView v) const override { cm->sendPartialOutput(inf, (char*) v.get().data(), v.get().size(), true); return *this; }
|
||||
virtual const LoggedStream& operator<<(std::string_view v) const override { cm->sendPartialOutput(inf, (char*) v.data(), v.size()); return *this; }
|
||||
|
||||
virtual const LoggedStream& operator<<(int v) const override { OUTSTRINGSTREAM os; os << v; OUTSTRING s = os.str(); cm->sendPartialOutput(inf, &s); return *this; }
|
||||
@ -216,7 +265,7 @@ class MegaCmdLogger : public mega::MegaLogger
|
||||
protected:
|
||||
static bool isMegaCmdSource(const std::string &source);
|
||||
|
||||
void formatLogToStream(LoggedStream& stream, std::string_view time, int logLevel, const char *source, const char *message);
|
||||
void formatLogToStream(LoggedStream& stream, std::string_view time, int logLevel, const char *source, const char *message, bool surround = false);
|
||||
bool shouldIgnoreMessage(int logLevel, const char *source, const char *message) const;
|
||||
|
||||
public:
|
||||
@ -235,16 +284,13 @@ public:
|
||||
|
||||
virtual int getMaxLogLevel() const { return std::max(mSdkLoggerLevel, mCmdLoggerLevel); }
|
||||
|
||||
static OUTSTRING getDefaultFilePath();
|
||||
static fs::path getDefaultFilePath();
|
||||
};
|
||||
|
||||
class MegaCmdSimpleLogger final : public MegaCmdLogger
|
||||
{
|
||||
#ifdef _WIN32
|
||||
std::mutex mSetmodeMtx;
|
||||
#endif
|
||||
LoggedStream &mLoggedStream;
|
||||
LoggedStreamOutStream mOutStream;
|
||||
LoggedStream &mLoggedStream; // to log into files (e.g. FileRotatingLoggedStream)
|
||||
LoggedStreamOutStream mOutStream; // to log into stdout
|
||||
bool mLogToOutStream;
|
||||
|
||||
bool shouldLogToStream(int logLevel, const char *source) const;
|
||||
|
@ -52,18 +52,6 @@
|
||||
#include <sys/types.h>
|
||||
#include <errno.h>
|
||||
#else
|
||||
#include <fcntl.h>
|
||||
#include <io.h>
|
||||
#include <stdio.h>
|
||||
#ifndef _O_U16TEXT
|
||||
#define _O_U16TEXT 0x00020000
|
||||
#endif
|
||||
#ifndef _O_U8TEXT
|
||||
#define _O_U8TEXT 0x00040000
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32)
|
||||
#define strdup _strdup
|
||||
#endif
|
||||
|
||||
@ -168,8 +156,8 @@ void console_setecho(bool echo)
|
||||
#endif
|
||||
}
|
||||
|
||||
bool alreadyFinished = false; //flag to show progress
|
||||
float percentDowloaded = 0.0; // to show progress
|
||||
std::atomic_bool alreadyFinished = false; //flag to show progress
|
||||
std::atomic<float> percentDowloaded = 0.0; // to show progress
|
||||
|
||||
// password change-related state information
|
||||
string oldpasswd;
|
||||
@ -182,10 +170,9 @@ static std::mutex handlerInstallerMutex;
|
||||
|
||||
static std::atomic_bool requirepromptinstall(true);
|
||||
|
||||
bool procesingline = false;
|
||||
bool promptreinstalledwhenprocessingline = false;
|
||||
|
||||
bool serverTryingToLog = false;
|
||||
std::atomic_bool procesingline = false;
|
||||
std::atomic_bool promptreinstalledwhenprocessingline = false;
|
||||
std::atomic_bool serverTryingToLog = false;
|
||||
|
||||
static char dynamicprompt[PROMPT_MAX_SIZE];
|
||||
|
||||
@ -253,7 +240,6 @@ void statechangehandle(string statestring, MegaCmdShellCommunications &comsManag
|
||||
{
|
||||
if (serverTryingToLog)
|
||||
{
|
||||
std::lock_guard<std::mutex> stdOutLockGuard(comsManager.getStdoutLockGuard());
|
||||
printCenteredContentsCerr(string("MEGAcmd Server is still trying to log in. Still, some commands are available.\n"
|
||||
"Type \"help\", to list them.").c_str(), width);
|
||||
}
|
||||
@ -279,11 +265,8 @@ void statechangehandle(string statestring, MegaCmdShellCommunications &comsManag
|
||||
#ifdef _WIN32
|
||||
wstring wbuffer;
|
||||
stringtolocalw((const char*)os.str().data(),&wbuffer);
|
||||
int oldmode;
|
||||
std::lock_guard<std::mutex> stdOutLockGuard(comsManager.getStdoutLockGuard());
|
||||
oldmode = _setmode(_fileno(stdout), _O_U8TEXT);
|
||||
WindowsUtf8StdoutGuard utf8Guard;
|
||||
OUTSTREAM << wbuffer << flush;
|
||||
_setmode(_fileno(stdout), oldmode);
|
||||
#else
|
||||
OUTSTREAM << os.str();
|
||||
#endif
|
||||
@ -297,21 +280,22 @@ void statechangehandle(string statestring, MegaCmdShellCommunications &comsManag
|
||||
{
|
||||
serverTryingToLog = true;
|
||||
|
||||
std::lock_guard<std::mutex> stdOutLockGuard(comsManager.getStdoutLockGuard());
|
||||
printCenteredContentsCerr(string("Resuming session ... ").c_str(), width, false);
|
||||
}
|
||||
else if (newstate.compare(0, strlen("message:"), "message:") == 0)
|
||||
{
|
||||
if (notRepeatedMessage(newstate)) //to avoid repeating messages
|
||||
{
|
||||
std::lock_guard<std::mutex> stdOutLockGuard(comsManager.getStdoutLockGuard());
|
||||
#ifdef _WIN32
|
||||
int oldmode = _setmode(_fileno(stdout), _O_U8TEXT);
|
||||
#endif
|
||||
string contents = newstate.substr(strlen("message:"));
|
||||
std::string_view messageContents = std::string_view(newstate).substr(strlen("message:"));
|
||||
string contents(messageContents);
|
||||
replaceAll(contents, "%mega-%", "");
|
||||
|
||||
if (contents.find("-----") != 0)
|
||||
#ifdef _WIN32
|
||||
WindowsUtf8StdoutGuard utf8Guard;
|
||||
#else
|
||||
StdoutMutexGuard stdoutGuard;
|
||||
#endif
|
||||
if (messageContents.rfind("-----", 0) != 0)
|
||||
{
|
||||
if (!procesingline || promptreinstalledwhenprocessingline || shown_partial_progress)
|
||||
{
|
||||
@ -332,10 +316,6 @@ void statechangehandle(string statestring, MegaCmdShellCommunications &comsManag
|
||||
requirepromptinstall = true;
|
||||
OUTSTREAM << endl << contents << endl;
|
||||
}
|
||||
#ifdef _WIN32
|
||||
_setmode(_fileno(stdout), oldmode);
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
else if (newstate.compare(0, strlen("clientID:"), "clientID:") == 0)
|
||||
@ -370,7 +350,6 @@ void statechangehandle(string statestring, MegaCmdShellCommunications &comsManag
|
||||
shown_partial_progress = false;
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> stdOutLockGuard(comsManager.getStdoutLockGuard());
|
||||
long long completed = received == SPROGRESS_COMPLETE ? PROGRESS_COMPLETE : charstoll(received.c_str());
|
||||
const char * progressTitle = title.empty() ? "TRANSFERRING" : title.c_str();
|
||||
printprogress(completed, charstoll(total.c_str()), progressTitle);
|
||||
@ -631,48 +610,11 @@ void install_rl_handler(const char *theprompt, bool external)
|
||||
promptreinstalledwhenprocessingline = true;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
wstring wswhat;
|
||||
stringtolocalw(theprompt,&wswhat);
|
||||
const wchar_t *what = wswhat.c_str();
|
||||
|
||||
|
||||
// escape characters that break readline input (e.g. Chinese ones. e.g \x242ee)
|
||||
wstring output = escapereadlinebreakers(what);
|
||||
|
||||
// give readline something it understands
|
||||
what = output.c_str();
|
||||
size_t buffer_size;
|
||||
#ifdef _TRUNCATE
|
||||
wcstombs_s(&buffer_size, NULL, 0, what, _TRUNCATE);
|
||||
#else
|
||||
buffer_size=output.size()*sizeof(wchar_t)*2;
|
||||
#endif
|
||||
|
||||
if (buffer_size) //coversion is ok
|
||||
{
|
||||
// do the actual conversion
|
||||
char *buffer = new char[buffer_size];
|
||||
#ifdef _TRUNCATE
|
||||
wcstombs_s(&buffer_size, buffer, buffer_size,what, _TRUNCATE);
|
||||
#else
|
||||
wcstombs(buffer, what, buffer_size);
|
||||
#endif
|
||||
|
||||
rl_callback_handler_install(buffer, store_line);
|
||||
}
|
||||
else
|
||||
{
|
||||
rl_callback_handler_install("INVALID_PROMPT: ", store_line);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
rl_restore_prompt();
|
||||
rl_callback_handler_install(theprompt, store_line);
|
||||
|
||||
handlerOverridenByExternalThread = external;
|
||||
requirepromptinstall = false;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
void redisplay_prompt()
|
||||
@ -868,7 +810,6 @@ void changedir(const string& where)
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#ifndef NO_READLINE
|
||||
char* remote_completion(const char* text, int state)
|
||||
{
|
||||
@ -888,16 +829,7 @@ char* remote_completion(const char* text, int state)
|
||||
|
||||
string outputcommand;
|
||||
|
||||
#ifdef _WIN32
|
||||
#ifdef __MINGW32__
|
||||
wstring soss=oss.str();
|
||||
localwtostring(&soss,&outputcommand);
|
||||
#else
|
||||
localwtostring(&oss.str(),&outputcommand);
|
||||
#endif
|
||||
#else
|
||||
outputcommand = oss.str();
|
||||
#endif
|
||||
outputcommand = oss.str();
|
||||
|
||||
if (outputcommand == "MEGACMD_USE_LOCAL_COMPLETION")
|
||||
{
|
||||
@ -967,78 +899,6 @@ void printHistory()
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
/**
|
||||
* @brief getcharacterreadlineUTF16support
|
||||
* while this works, somehow arrows and other readline stuff is disabled using this one.
|
||||
* @param stream
|
||||
* @return
|
||||
*/
|
||||
int getcharacterreadlineUTF16support (FILE *stream)
|
||||
{
|
||||
int result;
|
||||
char b[10];
|
||||
memset(b,0,10);
|
||||
|
||||
while (1)
|
||||
{
|
||||
int oldmode = _setmode(_fileno(stream), _O_U16TEXT);
|
||||
|
||||
result = read (fileno (stream), &b, 10);
|
||||
_setmode(_fileno(stream), oldmode);
|
||||
|
||||
if (result == 0)
|
||||
{
|
||||
return (EOF);
|
||||
}
|
||||
|
||||
// convert the UTF16 string to widechar
|
||||
size_t wbuffer_size;
|
||||
#ifdef _TRUNCATE
|
||||
mbstowcs_s(&wbuffer_size, NULL, 0, b, _TRUNCATE);
|
||||
#else
|
||||
wbuffer_size=10;
|
||||
#endif
|
||||
wchar_t *wbuffer = new wchar_t[wbuffer_size];
|
||||
|
||||
#ifdef _TRUNCATE
|
||||
mbstowcs_s(&wbuffer_size, wbuffer, wbuffer_size, b, _TRUNCATE);
|
||||
#else
|
||||
mbstowcs(wbuffer, b, wbuffer_size);
|
||||
#endif
|
||||
|
||||
// convert the UTF16 widechar to UTF8 string
|
||||
string receivedutf8;
|
||||
utf16ToUtf8(wbuffer, wbuffer_size,&receivedutf8);
|
||||
|
||||
if (strlen(receivedutf8.c_str()) > 1) //multi byte utf8 sequence: place the UTF8 characters into rl buffer one by one
|
||||
{
|
||||
for (unsigned int i=0;i< strlen(receivedutf8.c_str());i++)
|
||||
{
|
||||
rl_line_buffer[rl_end++] = receivedutf8.c_str()[i];
|
||||
rl_point=rl_end;
|
||||
}
|
||||
rl_line_buffer[rl_end] = '\0';
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (result =! 0)
|
||||
{
|
||||
return (b[0]);
|
||||
}
|
||||
|
||||
/* If zero characters are returned, then the file that we are
|
||||
reading from is empty! Return EOF in that case. */
|
||||
if (result == 0)
|
||||
{
|
||||
return (EOF);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void wait_for_input(int readline_fd)
|
||||
{
|
||||
fd_set fds;
|
||||
@ -1051,17 +911,13 @@ void wait_for_input(int readline_fd)
|
||||
{
|
||||
if (ERRNO != EINTR) //syscall
|
||||
{
|
||||
#ifdef _WIN32
|
||||
if (ERRNO != WSAENOTSOCK) // it enters here since it is not a socket. Alt: Use WaitForMultipleObjectsEx
|
||||
#endif
|
||||
cerr << "Error at select at wait_for_input errno: " << ERRNO << endl;
|
||||
cerr << "Error at select at wait_for_input errno: " << ERRNO << endl;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
|
||||
|
||||
vector<autocomplete::ACState::Completion> remote_completion(string linetocomplete)
|
||||
{
|
||||
using namespace autocomplete;
|
||||
@ -1600,33 +1456,6 @@ void process_line(const char * line)
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
#ifdef HAVE_DOWNLOADS_COMMAND
|
||||
else if ( (words[0] == "downloads"))
|
||||
{
|
||||
string toexec;
|
||||
|
||||
if (!strstr (commandtoexec,"path-display-size"))
|
||||
{
|
||||
unsigned int width = getNumberOfCols(75);
|
||||
int pathSize = int((width-46)/2);
|
||||
|
||||
toexec+=words[0];
|
||||
toexec+=" --path-display-size=";
|
||||
toexec+=SSTR(pathSize);
|
||||
toexec+=" ";
|
||||
if (strlen(commandtoexec)>(words[0].size()+1))
|
||||
{
|
||||
toexec+=commandtoexec+words[0].size()+1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
toexec+=commandtoexec;
|
||||
}
|
||||
|
||||
comms->executeCommand(toexec.c_str(), readresponse);
|
||||
}
|
||||
#endif
|
||||
else if ( (words[0] == "transfers"))
|
||||
{
|
||||
string toexec;
|
||||
@ -2057,42 +1886,63 @@ void printWelcomeMsg(unsigned int width)
|
||||
width = getNumberOfCols(75);
|
||||
}
|
||||
|
||||
COUT << endl;
|
||||
COUT << ".";
|
||||
for (unsigned int i = 0; i < width; i++)
|
||||
COUT << "=" ;
|
||||
COUT << ".";
|
||||
COUT << endl;
|
||||
printCenteredLine(" __ __ _____ ____ _ _ ",width);
|
||||
printCenteredLine("| \\/ | ___|/ ___| / \\ ___ _ __ ___ __| |",width);
|
||||
printCenteredLine("| |\\/| | \\ / | _ / _ \\ / __| '_ ` _ \\ / _` |",width);
|
||||
printCenteredLine("| | | | /__\\ |_| |/ ___ \\ (__| | | | | | (_| |",width);
|
||||
printCenteredLine("|_| |_|____|\\____/_/ \\_\\___|_| |_| |_|\\__,_|",width);
|
||||
std::ostringstream oss;
|
||||
|
||||
COUT << "|";
|
||||
oss << endl;
|
||||
oss << ".";
|
||||
for (unsigned int i = 0; i < width; i++)
|
||||
COUT << " " ;
|
||||
COUT << "|";
|
||||
COUT << endl;
|
||||
printCenteredLine("Welcome to MEGAcmd! A Command Line Interactive and Scriptable",width);
|
||||
printCenteredLine("Application to interact with your MEGA account.",width);
|
||||
printCenteredLine("Please write to support@mega.nz if you find any issue or",width);
|
||||
printCenteredLine("have any suggestion concerning its functionalities.",width);
|
||||
printCenteredLine("Enter \"help --non-interactive\" to learn how to use MEGAcmd with scripts.",width);
|
||||
printCenteredLine("Enter \"help\" for basic info and a list of available commands.",width);
|
||||
oss << "=" ;
|
||||
oss << ".";
|
||||
oss << endl;
|
||||
printCenteredLine(oss, " __ __ _____ ____ _ _ ",width);
|
||||
printCenteredLine(oss, "| \\/ | ___|/ ___| / \\ ___ _ __ ___ __| |",width);
|
||||
printCenteredLine(oss, "| |\\/| | \\ / | _ / _ \\ / __| '_ ` _ \\ / _` |",width);
|
||||
printCenteredLine(oss, "| | | | /__\\ |_| |/ ___ \\ (__| | | | | | (_| |",width);
|
||||
printCenteredLine(oss, "|_| |_|____|\\____/_/ \\_\\___|_| |_| |_|\\__,_|",width);
|
||||
|
||||
oss << "|";
|
||||
for (unsigned int i = 0; i < width; i++)
|
||||
oss << " " ;
|
||||
oss << "|";
|
||||
oss << endl;
|
||||
printCenteredLine(oss, "Welcome to MEGAcmd! A Command Line Interactive and Scriptable",width);
|
||||
printCenteredLine(oss, "Application to interact with your MEGA account.",width);
|
||||
printCenteredLine(oss, "Please write to support@mega.nz if you find any issue or",width);
|
||||
printCenteredLine(oss, "have any suggestion concerning its functionalities.",width);
|
||||
printCenteredLine(oss, "Enter \"help --non-interactive\" to learn how to use MEGAcmd with scripts.",width);
|
||||
printCenteredLine(oss, "Enter \"help\" for basic info and a list of available commands.",width);
|
||||
|
||||
#if defined(_WIN32) && defined(NO_READLINE)
|
||||
printCenteredLine("Unicode support in the console is improved, see \"help --unicode\"", width);
|
||||
printCenteredLine(oss, "Unicode support in the console is improved, see \"help --unicode\"", width);
|
||||
#elif defined(_WIN32)
|
||||
printCenteredLine("Enter \"help --unicode\" for info regarding non-ASCII support.",width);
|
||||
printCenteredLine(oss, "Enter \"help --unicode\" for info regarding non-ASCII support.",width);
|
||||
#endif
|
||||
|
||||
COUT << "`";
|
||||
oss << "`";
|
||||
for (unsigned int i = 0; i < width; i++)
|
||||
COUT << "=" ;
|
||||
COUT << "´";
|
||||
COUT << endl;
|
||||
{
|
||||
oss << "=" ;
|
||||
}
|
||||
|
||||
#ifndef _WIN32
|
||||
oss << "\u00b4\n";
|
||||
COUT << oss.str() << std::flush;
|
||||
#else
|
||||
WindowsUtf8StdoutGuard utf8Guard;
|
||||
// So far, all is ASCII.
|
||||
COUT << oss.str();
|
||||
|
||||
// Now let's tray the non ascii forward acute. Note: codepage should have been set to UTF-8
|
||||
// set via console->setShellConsole(CP_UTF8, GetConsoleOutputCP());
|
||||
assert(GetConsoleOutputCP() == CP_UTF8);
|
||||
|
||||
if (!(COUT << L"\u00b4")) // still, Windows 7 or depending on the fonts, the console may struggle to render this
|
||||
{
|
||||
COUT << "/"; //fallback character
|
||||
}
|
||||
|
||||
COUT << endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
int quote_detector(char *line, int index)
|
||||
@ -2122,52 +1972,6 @@ bool runningInBackground()
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
void mycompletefunct(char **c, int num_matches, int max_length)
|
||||
{
|
||||
int cols = 80;
|
||||
|
||||
#if defined( RL_ISSTATE ) && defined( RL_STATE_INITIALIZED )
|
||||
int rows = 1;
|
||||
|
||||
if (RL_ISSTATE(RL_STATE_INITIALIZED))
|
||||
{
|
||||
rl_resize_terminal();
|
||||
rl_get_screen_size(&rows, &cols);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
// max_length is not trustworthy
|
||||
for (int i=1; i <= num_matches; i++) //contrary to what the documentation says, num_matches is not the size of c (but num_matches+1), current text is preappended in c[0]
|
||||
{
|
||||
max_length = max(max_length,(int)strlen(c[i]));
|
||||
}
|
||||
|
||||
OUTSTREAM << endl;
|
||||
|
||||
int nelements_per_col = max(1,(cols-1)/(max_length+1));
|
||||
for (int i=1; i <= num_matches; i++) //contrary to what the documentation says, num_matches is not the size of c (but num_matches+1), current text is preappended in c[0]
|
||||
{
|
||||
string option = c[i];
|
||||
|
||||
{
|
||||
std::lock_guard<std::mutex> stdOutLockGuard(comms->getStdoutLockGuard());
|
||||
OUTSTREAM << setw(min(cols-1,max_length+1)) << left;
|
||||
int oldmode = _setmode(_fileno(stdout), _O_U16TEXT);
|
||||
OUTSTREAM << c[i];
|
||||
_setmode(_fileno(stdout), oldmode);
|
||||
}
|
||||
|
||||
if ( (i%nelements_per_col == 0) && (i != num_matches))
|
||||
{
|
||||
OUTSTREAM << endl;
|
||||
}
|
||||
}
|
||||
OUTSTREAM << endl;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef NO_READLINE
|
||||
std::string readresponse(const char* question)
|
||||
{
|
||||
@ -2187,8 +1991,22 @@ std::string readresponse(const char* question)
|
||||
#else
|
||||
std::string readresponse(const char* question)
|
||||
{
|
||||
COUT << question << flush;
|
||||
console->updateInputPrompt(question);
|
||||
std::string questionStr(question);
|
||||
size_t pos = questionStr.rfind('\n');
|
||||
|
||||
if (pos != std::string::npos)
|
||||
{
|
||||
std::string questionPrev = questionStr.substr(0, pos);
|
||||
std::string prompt = questionStr.substr(pos + 1);
|
||||
|
||||
COUT << questionPrev << std::endl;
|
||||
console->updateInputPrompt(prompt);
|
||||
}
|
||||
else
|
||||
{
|
||||
console->updateInputPrompt(questionStr);
|
||||
}
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if (char* line = console->checkForCompletedInputLine())
|
||||
@ -2213,12 +2031,6 @@ using namespace megacmd;
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
|
||||
#if defined(_WIN32) && !defined(NO_READLINE)
|
||||
// Set Environment's default locale
|
||||
setlocale(LC_ALL, "en-US");
|
||||
rl_completion_display_matches_hook = mycompletefunct;
|
||||
#endif
|
||||
|
||||
// intialize the comms object
|
||||
#if defined(_WIN32)
|
||||
comms = new MegaCmdShellCommunicationsNamedPipes();
|
||||
|
@ -31,17 +31,6 @@
|
||||
#ifdef _WIN32
|
||||
#include <shlobj.h> //SHGetFolderPath
|
||||
#include <Shlwapi.h> //PathAppend
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <io.h>
|
||||
#include <stdio.h>
|
||||
#ifndef _O_U16TEXT
|
||||
#define _O_U16TEXT 0x00020000
|
||||
#endif
|
||||
#ifndef _O_U8TEXT
|
||||
#define _O_U8TEXT 0x00040000
|
||||
#endif
|
||||
|
||||
#else
|
||||
#include <fcntl.h>
|
||||
|
||||
@ -67,31 +56,28 @@
|
||||
#define ENOTCONN 107
|
||||
#endif
|
||||
|
||||
namespace megacmd {
|
||||
using namespace std;
|
||||
|
||||
namespace megacmd {
|
||||
|
||||
#ifndef _WIN32
|
||||
string createAndRetrieveConfigFolder()
|
||||
{
|
||||
auto dirs = PlatformDirectories::getPlatformSpecificDirectories();
|
||||
#ifdef _WIN32
|
||||
// We don't create the folder: Windows is currently using the folder
|
||||
// of the executable.
|
||||
return dirs->configDirPath();
|
||||
#else
|
||||
auto dir = dirs->configDirPath();
|
||||
struct stat st = {};
|
||||
auto dir = dirs->configDirPath().string();
|
||||
|
||||
struct stat st = {};
|
||||
if (stat(dir.c_str(), &st) == -1)
|
||||
{
|
||||
mkdir(dir.c_str(), 0700);
|
||||
}
|
||||
return dir;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <sys/wait.h>
|
||||
|
||||
bool is_pid_running(pid_t pid) {
|
||||
|
||||
while(waitpid(-1, 0, WNOHANG) > 0) {
|
||||
@ -179,6 +165,7 @@ SOCKET MegaCmdShellCommunicationsPosix::createSocket(int number, bool initialize
|
||||
|
||||
std::vector<const char*> argsVector{
|
||||
executable,
|
||||
"--do-not-log-to-stdout",
|
||||
nullptr
|
||||
};
|
||||
|
||||
@ -434,7 +421,7 @@ int MegaCmdShellCommunicationsPosix::executeCommand(string command, std::string
|
||||
n = recv(thesock, (char *)&partialoutsize, sizeof(partialoutsize), MSG_NOSIGNAL);
|
||||
if (n && partialoutsize > 0)
|
||||
{
|
||||
std::lock_guard<std::mutex> stdOutLockGuard(getStdoutLockGuard());
|
||||
StdoutMutexGuard stdOutLockGuard;
|
||||
do{
|
||||
char *buffer = new char[partialoutsize+1];
|
||||
n = recv(thesock, (char *)buffer, partialoutsize, MSG_NOSIGNAL);
|
||||
@ -512,7 +499,7 @@ int MegaCmdShellCommunicationsPosix::executeCommand(string command, std::string
|
||||
{
|
||||
if (n != 1 || buffer[0] != 0) //To avoid outputing 0 char in binary outputs
|
||||
{
|
||||
std::lock_guard<std::mutex> stdOutLockGuard(getStdoutLockGuard());
|
||||
StdoutMutexGuard stdOutLockGuard;
|
||||
output << string(buffer,n) << flush;
|
||||
}
|
||||
}
|
||||
@ -664,6 +651,7 @@ bool MegaCmdShellCommunications::registerForStateChanges(bool interactive, State
|
||||
mListenerThread->join();
|
||||
}
|
||||
|
||||
mClientIdPromise = std::promise<std::string>();
|
||||
auto resultRegistration = registerForStateChangesImpl(interactive, initiateServer);
|
||||
if (!resultRegistration)
|
||||
{
|
||||
@ -790,9 +778,19 @@ void MegaCmdShellCommunications::setForRegisterAgain(bool dontWait)
|
||||
}
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> MegaCmdShellCommunications::getStdoutLockGuard()
|
||||
void MegaCmdShellCommunications::setClientIdPromise(const std::string& clientId)
|
||||
{
|
||||
return std::lock_guard<std::mutex>(mStdoutMutex);
|
||||
mClientIdPromise.set_value(clientId);
|
||||
}
|
||||
|
||||
std::optional<std::string> MegaCmdShellCommunications::tryToGetClientId(std::chrono::seconds waitForSecs)
|
||||
{
|
||||
auto f = mClientIdPromise.get_future();
|
||||
if (f.wait_for(waitForSecs) == std::future_status::timeout)
|
||||
{
|
||||
return std::nullopt;
|
||||
}
|
||||
return f.get();
|
||||
}
|
||||
|
||||
MegaCmdShellCommunications::~MegaCmdShellCommunications()
|
||||
|
@ -140,6 +140,9 @@ public:
|
||||
bool registerRequired();
|
||||
void setForRegisterAgain(bool dontWait = false);
|
||||
|
||||
void setClientIdPromise(const std::string& clientId);
|
||||
std::optional<std::string> tryToGetClientId(std::chrono::seconds waitForSecs = std::chrono::seconds(15));
|
||||
|
||||
std::lock_guard<std::mutex> getStdoutLockGuard();
|
||||
|
||||
private:
|
||||
@ -149,6 +152,8 @@ private:
|
||||
|
||||
std::mutex mStdoutMutex;
|
||||
|
||||
std::promise<std::string> mClientIdPromise;
|
||||
|
||||
std::unique_ptr<std::thread> mListenerThread;
|
||||
|
||||
std::mutex mRegistrationMutex;
|
||||
|
@ -34,16 +34,6 @@
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <io.h>
|
||||
#include <stdio.h>
|
||||
#ifndef _O_U16TEXT
|
||||
#define _O_U16TEXT 0x00020000
|
||||
#endif
|
||||
#ifndef _O_U8TEXT
|
||||
#define _O_U8TEXT 0x00040000
|
||||
#endif
|
||||
|
||||
namespace megacmd {
|
||||
|
||||
bool MegaCmdShellCommunicationsNamedPipes::confirmResponse; //TODO: do all this only in parent class
|
||||
@ -494,6 +484,8 @@ int MegaCmdShellCommunicationsNamedPipes::executeCommand(string command, std::st
|
||||
closeNamedPipe(theNamedPipe);
|
||||
});
|
||||
|
||||
bool isCat = command.rfind("cat", 0) == 0 || wcommand.rfind(L"cat", 0) == 0;
|
||||
|
||||
if (interactiveshell)
|
||||
{
|
||||
command="X"+command;
|
||||
@ -545,7 +537,8 @@ int MegaCmdShellCommunicationsNamedPipes::executeCommand(string command, std::st
|
||||
return -1;
|
||||
}
|
||||
|
||||
bool binaryoutput = !wcommand.compare(0, 3, L"cat") && redirectedstdout;
|
||||
bool binaryoutput = isCat && redirectedstdout;
|
||||
bool shouldPrintAdditionalLine = false;
|
||||
|
||||
while (outcode == MCMD_REQCONFIRM || outcode == MCMD_REQSTRING || outcode == MCMD_PARTIALOUT)
|
||||
{
|
||||
@ -558,16 +551,16 @@ int MegaCmdShellCommunicationsNamedPipes::executeCommand(string command, std::st
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
if (partialoutsize > 0)
|
||||
{
|
||||
std::lock_guard<std::mutex> stdOutLockGuard(getStdoutLockGuard());
|
||||
|
||||
int oldmode = 0;
|
||||
|
||||
std::unique_ptr<OutputsModeGuard> outputModeGuard;
|
||||
if (binaryoutput)
|
||||
{
|
||||
oldmode = _setmode(_fileno(stdout), O_BINARY);
|
||||
outputModeGuard.reset(new WindowsBinaryStdoutGuard());
|
||||
}
|
||||
else
|
||||
{
|
||||
outputModeGuard.reset(new WindowsUtf8StdoutGuard());
|
||||
}
|
||||
|
||||
size_t BUFFERSIZE = 10024;
|
||||
@ -577,10 +570,11 @@ int MegaCmdShellCommunicationsNamedPipes::executeCommand(string command, std::st
|
||||
readok = ReadFile(newNamedPipe, buffer, DWORD(std::min(BUFFERSIZE,partialoutsize)),&n,NULL);
|
||||
if (readok)
|
||||
{
|
||||
|
||||
if (binaryoutput)
|
||||
{
|
||||
Instance<WindowsConsoleController>::Get().enableInterceptors(false);
|
||||
std::cout << string(buffer,n) << flush;
|
||||
Instance<WindowsConsoleController>::Get().enableInterceptors(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -588,18 +582,15 @@ int MegaCmdShellCommunicationsNamedPipes::executeCommand(string command, std::st
|
||||
|
||||
wstring wbuffer;
|
||||
stringtolocalw((const char*)&buffer,&wbuffer);
|
||||
int oldmode;
|
||||
oldmode = _setmode(_fileno(stdout), _O_U8TEXT);
|
||||
output << wbuffer << flush;
|
||||
_setmode(_fileno(stdout), oldmode);
|
||||
}
|
||||
partialoutsize-=n;
|
||||
}
|
||||
} while(n != 0 && partialoutsize && n !=SOCKET_ERROR);
|
||||
|
||||
if (binaryoutput)
|
||||
if (isCat && !binaryoutput && interactiveshell)
|
||||
{
|
||||
_setmode(_fileno(stdout), oldmode);
|
||||
shouldPrintAdditionalLine = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -680,25 +671,8 @@ int MegaCmdShellCommunicationsNamedPipes::executeCommand(string command, std::st
|
||||
stringtolocalw((const char*)&buffer,&wbuffer);
|
||||
int oldmode;
|
||||
|
||||
std::lock_guard<std::mutex> stdOutLockGuard(getStdoutLockGuard());
|
||||
|
||||
// if (interactiveshell || outputtobinaryorconsole())
|
||||
// {
|
||||
// In non-interactive mode, at least in powershell, when outputting to a file/pipe, things get rough
|
||||
// Powershell tries to interpret the output as a string and would meddle with the UTF16 encoding, resulting
|
||||
// in unusable output, So we disable the UTF-16 in such cases (this might cause that the output could be truncated!).
|
||||
// oldmode = _setmode(_fileno(stdout), _O_U16TEXT);
|
||||
// }
|
||||
|
||||
|
||||
oldmode = _setmode(_fileno(stdout), _O_U8TEXT);
|
||||
WindowsUtf8StdoutGuard utf8Guard;
|
||||
output << wbuffer << flush;
|
||||
_setmode(_fileno(stdout), oldmode);
|
||||
|
||||
// if (interactiveshell || outputtobinaryorconsole() || true)
|
||||
// {
|
||||
// _setmode(_fileno(stdout), oldmode);
|
||||
// }
|
||||
}
|
||||
if (readok && n == BUFFERSIZE)
|
||||
{
|
||||
@ -720,6 +694,12 @@ int MegaCmdShellCommunicationsNamedPipes::executeCommand(string command, std::st
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (shouldPrintAdditionalLine)
|
||||
{
|
||||
WindowsUtf8StdoutGuard utf8Guard;
|
||||
output << std::endl;
|
||||
}
|
||||
|
||||
return outcode;
|
||||
}
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,703 +0,0 @@
|
||||
/**
|
||||
* @file src/megacmdtransfermanager.h
|
||||
* @brief MEGAcmd: Executer of the commands
|
||||
*
|
||||
* (c) 2013 by Mega Limited, Auckland, New Zealand
|
||||
*
|
||||
* This file is part of the MEGAcmd.
|
||||
*
|
||||
* MEGAcmd 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.
|
||||
*
|
||||
* @copyright Simplified (2-clause) BSD License.
|
||||
*
|
||||
* You should have received a copy of the license along with this
|
||||
* program.
|
||||
*/
|
||||
|
||||
|
||||
#ifdef HAVE_DOWNLOADS_COMMAND
|
||||
#pragma once
|
||||
|
||||
#include "megacmdcommonutils.h"
|
||||
|
||||
#include "mega/types.h" //make_unique
|
||||
#include "megaapi.h"
|
||||
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include <sqlite3.h> //TODO: move all these to a separate source file
|
||||
#include <condition_variable>
|
||||
#include <thread>
|
||||
|
||||
using namespace mega;
|
||||
using std::map;
|
||||
using std::string;
|
||||
|
||||
namespace megacmd {
|
||||
|
||||
static void printTransferColumnDisplayer(ColumnDisplayer *cd, mega::MegaTransfer *transfer,
|
||||
const std::string &source, bool printstate=true);
|
||||
|
||||
class DownloadId
|
||||
{
|
||||
public:
|
||||
int mTag; //tag for active/finished transfers in current execution
|
||||
std::string mPath; // the path used to initiate the dl (or the objectId if loaded from db)
|
||||
|
||||
|
||||
DownloadId(int tag, const std::string &path)
|
||||
: mTag(tag), mPath(path){}
|
||||
|
||||
DownloadId() : DownloadId(-1,""){}
|
||||
|
||||
|
||||
bool operator<(const DownloadId& r) const
|
||||
{
|
||||
return std::tie(mTag, mPath)
|
||||
< std::tie(r.mTag, r.mPath);
|
||||
}
|
||||
|
||||
|
||||
// this returns an id that is always the same for the same path
|
||||
std::string getObjectID() const;
|
||||
|
||||
static bool isObjectID(const string &what);
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
class DataBaseEntry
|
||||
{
|
||||
public:
|
||||
constexpr static int INVALID_DB_ID = 0;
|
||||
|
||||
int64_t dbid() const;
|
||||
void setDbid(const int64_t &dbid);
|
||||
private:
|
||||
int64_t mDbid = INVALID_DB_ID;
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief The information we want to keep of a transfer
|
||||
*/
|
||||
class TransferInfo : public DataBaseEntry
|
||||
{
|
||||
long mSubTransfersStarted = 0;
|
||||
long mSubTransfersFinishedOk = 0;
|
||||
long mSubTransfersFinishedWithFailure = 0;
|
||||
int mFinalError = API_OK;
|
||||
|
||||
string mSourcePath; //full path for files
|
||||
|
||||
|
||||
map<int, std::shared_ptr<TransferInfo>> mSubTransfersInfo; //subtransferInfo by tag
|
||||
TransferInfo *mParent = nullptr; //for child transfers
|
||||
|
||||
std::mutex mTransferMutex;
|
||||
std::unique_ptr<MegaTransfer> mTransfer; // a copy of a transfer
|
||||
|
||||
DownloadId mId; //For main transfers
|
||||
|
||||
int64_t mLastUpdate; //timestamp of the last update
|
||||
|
||||
|
||||
//MegaTransfer interface
|
||||
int getType() const;
|
||||
int64_t getStartTime() const;
|
||||
long long getTransferredBytes() const;
|
||||
long long getTotalBytes() const;
|
||||
const char *getPath() const;
|
||||
const char *getParentPath() const;
|
||||
MegaHandle getNodeHandle() const;
|
||||
MegaHandle getParentHandle() const;
|
||||
long long getStartPos() const;
|
||||
long long getEndPos() const;
|
||||
const char *getFileName() const;
|
||||
int getNumRetry() const;
|
||||
int getMaxRetries() const;
|
||||
int getTag() const;
|
||||
long long getSpeed() const;
|
||||
long long getMeanSpeed() const;
|
||||
long long getDeltaSize() const;
|
||||
int64_t getUpdateTime() const;
|
||||
MegaNode *getPublicMegaNode() const;
|
||||
bool isSyncTransfer() const;
|
||||
bool isStreamingTransfer() const;
|
||||
bool isFinished() const;
|
||||
bool isBackupTransfer() const;
|
||||
bool isForeignOverquota() const;
|
||||
bool isForceNewUpload() const;
|
||||
char *getLastBytes() const;
|
||||
MegaError getLastError() const;
|
||||
const MegaError *getLastErrorExtended() const;
|
||||
bool isFolderTransfer() const;
|
||||
int getFolderTransferTag() const;
|
||||
const char *getAppData() const;
|
||||
int getState() const;
|
||||
unsigned long long getPriority() const;
|
||||
long long getNotificationNumber() const;
|
||||
bool getTargetOverride() const;
|
||||
|
||||
|
||||
void addToColumnDisplayer(ColumnDisplayer &cd);
|
||||
|
||||
void initialize(MegaApi *api, MegaTransfer *transfer, DownloadId *id);
|
||||
|
||||
public:
|
||||
|
||||
//regular ctors
|
||||
//Despite receiving transfer object here, updateTransfer(transfer, ...) will be required afterwards
|
||||
// Reason: updateTransfer will trigger IO writer update, and that requires a shared pointer from this class,
|
||||
// which is not available in ctor.
|
||||
TransferInfo(MegaApi * api, MegaTransfer *transfer, DownloadId *id = nullptr);
|
||||
TransferInfo(MegaApi * api, MegaTransfer *transfer, TransferInfo *parent); //ctor for subtransfers
|
||||
|
||||
//ctor for loading from db
|
||||
TransferInfo(const std::string &serializedTransfer, int64_t lastUpdate, TransferInfo *parent, const std::string &objectId);
|
||||
|
||||
// updates TransferInfo, requires a shared pointer to it
|
||||
void updateTransfer(MegaTransfer *transfer, const std::shared_ptr<TransferInfo> &transferInfo, MegaError *error = nullptr);
|
||||
|
||||
void addSubTransfer(const std::shared_ptr<TransferInfo> &transferInfo);
|
||||
void onSubTransferStarted(MegaApi *api, MegaTransfer *subtransfer);
|
||||
void onSubTransferFinish(MegaTransfer *subtransfer, MegaError *error);
|
||||
void onSubTransferUpdate(MegaTransfer *subtransfer);
|
||||
|
||||
void print(OUTSTREAMTYPE &os, std::map<std::string, int> *clflags, std::map<std::string, std::string> *cloptions, bool printHeader = true);
|
||||
|
||||
std::string serializedTransferData();
|
||||
|
||||
DownloadId getId() const;
|
||||
int64_t getParentDbId() const;
|
||||
int64_t getLastUpdate() const;
|
||||
|
||||
void onPersisted();
|
||||
};
|
||||
|
||||
OUTSTREAMTYPE &operator<<(OUTSTREAMTYPE &os, const DownloadId &p);
|
||||
|
||||
using MapOfDlTransfers = std::map<DownloadId, std::shared_ptr<TransferInfo>>;
|
||||
|
||||
class DownloadsManager
|
||||
{
|
||||
private:
|
||||
std::recursive_mutex mTransfersMutex;
|
||||
|
||||
MapOfDlTransfers mTransfers; //here's the ownership of the objects
|
||||
|
||||
std::map<int, MapOfDlTransfers::iterator> mActiveTransfers; //All active transfers added
|
||||
|
||||
std::map<int, MapOfDlTransfers::iterator> mFinishedTransfers; //All finished transfers in current run
|
||||
std::queue<int> mFinishedTransfersQueue; //Finished transfers in order of insertion
|
||||
|
||||
//Map betwen OID -> TransferInfo
|
||||
// since 2 transfer can have the same OID, it will be keep the last recently updated
|
||||
std::map<std::string, MapOfDlTransfers::iterator> mTransfersInMemory;
|
||||
|
||||
//a collection of transfers that were initiated, but still are not added
|
||||
// we need to store this because onTransferFinish of the listener created in downloadNode happens
|
||||
// after the global onTransferFinish listener. i.e: we cannot tell if these transfers will
|
||||
// be handled by the second or were added elswhere (from resumption) and have no associated path
|
||||
std::map<int, std::unique_ptr<MegaTransfer>> mNewUnHandledTransfers;
|
||||
|
||||
|
||||
|
||||
unsigned mMaxAllowedTransfer = 9999999;
|
||||
unsigned mLowthresholdMaxAllowedTransfers = 999999;
|
||||
|
||||
public:
|
||||
static DownloadsManager& Instance();
|
||||
|
||||
void start();
|
||||
void shutdown(bool loginout);
|
||||
|
||||
void recoverUnHandleTransfer(MegaApi *api, MegaTransfer *transfer);
|
||||
|
||||
MapOfDlTransfers::iterator addNewTopLevelTransfer(MegaApi *api, MegaTransfer *transfer,int tag, const std::string &path);
|
||||
|
||||
void onTransferStart(MegaApi *api, MegaTransfer *transfer);
|
||||
|
||||
void onTransferUpdate(MegaApi *api, MegaTransfer *transfer);
|
||||
|
||||
void onTransferFinish(MegaApi *api, ::mega::MegaTransfer *transfer, ::mega::MegaError* error);
|
||||
|
||||
void printAll(OUTSTREAMTYPE &os, map<std::string, int> *clflags, map<std::string, std::string> *cloptions);
|
||||
void printOne(OUTSTREAMTYPE &os, std::string objectIDorTag, map<string, int> *clflags, map<string, string> *cloptions);
|
||||
|
||||
void purge();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @brief Extract parameters from a serialized string
|
||||
*
|
||||
*/
|
||||
class ParamReader
|
||||
{
|
||||
private:
|
||||
char *mStart; //starting of the buffer
|
||||
char *mP; //position of the buffer
|
||||
char *mEnd; //end of the buffer
|
||||
|
||||
bool mDuplicateConstCharPointers; //whether to dup const char * or just use pointers to the buffer
|
||||
|
||||
public:
|
||||
ParamReader(const string ¶ms, bool duplicateConstCharPointer = false);
|
||||
|
||||
void advance(size_t size);
|
||||
void advanceString(); //advances while != \0;
|
||||
const char *read(size_t size);
|
||||
|
||||
size_t sizeRead()
|
||||
{
|
||||
assert (mP>=mStart);
|
||||
return mP-mStart;
|
||||
}
|
||||
|
||||
friend ParamReader& operator>> (ParamReader&, MegaTransfer *&);
|
||||
// friend ParamReader& operator>> (ParamReader&, MegaError *&);
|
||||
friend ParamReader& operator>> (ParamReader&, const char *&);
|
||||
friend ParamReader& operator>> (ParamReader&, char *&);
|
||||
friend ParamReader& operator>> (ParamReader&, string &);
|
||||
|
||||
template <typename T>
|
||||
friend ParamReader& operator>> (ParamReader&, std::unique_ptr<T>&);
|
||||
|
||||
template <typename T>
|
||||
friend ParamReader& operator>> (ParamReader&, T &);
|
||||
};
|
||||
|
||||
|
||||
template <typename T>
|
||||
ParamReader& operator>>(ParamReader& x, std::unique_ptr<T>& n)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
auto prev = x.mDuplicateConstCharPointers;
|
||||
x.mDuplicateConstCharPointers = true;
|
||||
#endif
|
||||
|
||||
T *pointer = nullptr;
|
||||
|
||||
x >> pointer;
|
||||
n.reset(pointer);
|
||||
|
||||
#ifdef DEBUG
|
||||
x.mDuplicateConstCharPointers = prev;
|
||||
#endif
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
ParamReader& operator>> (ParamReader& x, T &o)
|
||||
{
|
||||
if (x.mP + + sizeof(T) <= x.mEnd)
|
||||
{
|
||||
memcpy(&o,x.mP, sizeof(T));
|
||||
x.advance(sizeof(T));
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
class ParamWriter
|
||||
{
|
||||
private:
|
||||
string &mOut;
|
||||
|
||||
public:
|
||||
ParamWriter(string &where);
|
||||
friend ParamWriter& operator<<(ParamWriter&, MegaTransfer *&);
|
||||
friend ParamWriter& operator<<(ParamWriter&, const char *);
|
||||
friend ParamWriter& operator<<(ParamWriter&, char *);
|
||||
friend ParamWriter& operator<<(ParamWriter&, const string&);
|
||||
|
||||
|
||||
void write(const char *buffer, size_t size);
|
||||
|
||||
template <typename T>
|
||||
friend ParamWriter& operator<<(ParamWriter&, const T &s);
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
ParamWriter& operator<<(ParamWriter& x, const T &s)
|
||||
{
|
||||
static_assert(!std::is_pointer<T>::value, "Param writer not implemented for this type of pointer");
|
||||
|
||||
x.mOut.append(reinterpret_cast<const char *>(&s), sizeof(T));
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
|
||||
|
||||
class MegaErrorWithCtor : public MegaError
|
||||
{
|
||||
public:
|
||||
MegaErrorWithCtor() : MegaError(API_OK){};
|
||||
};
|
||||
|
||||
class MegaTransferHeldInString : public MegaTransfer
|
||||
{
|
||||
private:
|
||||
string mSerialized;
|
||||
|
||||
int mType;
|
||||
const char * mTransferString = nullptr;
|
||||
// const char * mtoString = nullptr;
|
||||
// const char * m__str__ = nullptr;
|
||||
// const char * m__toString = nullptr;
|
||||
int64_t mStartTime;
|
||||
long long mTransferredBytes;
|
||||
long long mTotalBytes;
|
||||
const char * mPath = nullptr;
|
||||
const char * mParentPath = nullptr;
|
||||
MegaHandle mNodeHandle;
|
||||
MegaHandle mParentHandle;
|
||||
long long mStartPos;
|
||||
long long mEndPos;
|
||||
const char * mFileName = nullptr;
|
||||
// MegaTransferListener * mListener = nullptr;
|
||||
int mNumRetry;
|
||||
int mMaxRetries;
|
||||
int mTag;
|
||||
long long mSpeed;
|
||||
long long mMeanSpeed;
|
||||
long long mDeltaSize;
|
||||
int64_t mUpdateTime;
|
||||
// MegaNode * mPublicMegaNode = nullptr;
|
||||
bool misSyncTransfer;
|
||||
bool misBackupTransfer;
|
||||
bool misForeignOverquota;
|
||||
bool misForceNewUpload;
|
||||
bool misStreamingTransfer;
|
||||
bool misFinished;
|
||||
char * mLastBytes = nullptr;
|
||||
// MegaError mLastError;
|
||||
// const MegaError * mLastErrorExtended = nullptr;
|
||||
bool misFolderTransfer;
|
||||
int mFolderTransferTag;
|
||||
const char * mAppData = nullptr;
|
||||
int mState;
|
||||
unsigned long long mPriority;
|
||||
long long mNotificationNumber;
|
||||
bool mTarOverride;
|
||||
|
||||
|
||||
public:
|
||||
MegaTransferHeldInString(const string &s, size_t *size_read = nullptr);
|
||||
|
||||
virtual MegaTransfer *copy() override
|
||||
{
|
||||
return new MegaTransferHeldInString(mSerialized);
|
||||
}
|
||||
virtual int getType() const override
|
||||
{
|
||||
return mType;
|
||||
}
|
||||
virtual const char *getTransferString() const override
|
||||
{
|
||||
return mTransferString;
|
||||
}
|
||||
virtual const char *toString() const override
|
||||
{
|
||||
assert(false && "unimplemented");
|
||||
return nullptr;
|
||||
}
|
||||
virtual const char *__str__() const override
|
||||
{
|
||||
assert(false && "unimplemented");
|
||||
return nullptr;
|
||||
}
|
||||
virtual const char *__toString() const override
|
||||
{
|
||||
assert(false && "unimplemented");
|
||||
return nullptr;
|
||||
}
|
||||
virtual int64_t getStartTime() const override
|
||||
{
|
||||
return mStartTime;
|
||||
}
|
||||
virtual long long getTransferredBytes() const override
|
||||
{
|
||||
return mTransferredBytes;
|
||||
}
|
||||
virtual long long getTotalBytes() const override
|
||||
{
|
||||
return mTotalBytes;
|
||||
}
|
||||
virtual const char *getPath() const override
|
||||
{
|
||||
return mPath;
|
||||
}
|
||||
virtual const char *getParentPath() const override
|
||||
{
|
||||
return mParentPath;
|
||||
}
|
||||
virtual MegaHandle getNodeHandle() const override
|
||||
{
|
||||
return mNodeHandle;
|
||||
}
|
||||
virtual MegaHandle getParentHandle() const override
|
||||
{
|
||||
return mParentHandle;
|
||||
}
|
||||
virtual long long getStartPos() const override
|
||||
{
|
||||
return mStartPos;
|
||||
}
|
||||
virtual long long getEndPos() const override
|
||||
{
|
||||
return mEndPos;
|
||||
}
|
||||
virtual const char *getFileName() const override
|
||||
{
|
||||
return mFileName;
|
||||
}
|
||||
virtual MegaTransferListener *getListener() const override
|
||||
{
|
||||
assert(false && "unimplemented");
|
||||
return nullptr;
|
||||
}
|
||||
virtual int getNumRetry() const override
|
||||
{
|
||||
return mNumRetry;
|
||||
}
|
||||
virtual int getMaxRetries() const override
|
||||
{
|
||||
return mMaxRetries;
|
||||
}
|
||||
virtual int getTag() const override
|
||||
{
|
||||
return mTag;
|
||||
}
|
||||
virtual long long getSpeed() const override
|
||||
{
|
||||
return mSpeed;
|
||||
}
|
||||
virtual long long getMeanSpeed() const override
|
||||
{
|
||||
return mMeanSpeed;
|
||||
}
|
||||
virtual long long getDeltaSize() const override
|
||||
{
|
||||
return mDeltaSize;
|
||||
}
|
||||
virtual int64_t getUpdateTime() const override
|
||||
{
|
||||
return mUpdateTime;
|
||||
}
|
||||
virtual MegaNode *getPublicMegaNode() const override
|
||||
{
|
||||
assert(false && "unimplemented");
|
||||
return nullptr;
|
||||
}
|
||||
virtual bool isSyncTransfer() const override
|
||||
{
|
||||
return misSyncTransfer;
|
||||
}
|
||||
virtual bool isBackupTransfer() const override
|
||||
{
|
||||
return misBackupTransfer;
|
||||
}
|
||||
virtual bool isForeignOverquota() const override
|
||||
{
|
||||
return misForeignOverquota;
|
||||
}
|
||||
virtual bool isForceNewUpload() const override
|
||||
{
|
||||
return misForceNewUpload;
|
||||
}
|
||||
virtual bool isStreamingTransfer() const override
|
||||
{
|
||||
return misStreamingTransfer;
|
||||
}
|
||||
virtual bool isFinished() const override
|
||||
{
|
||||
return misFinished;
|
||||
}
|
||||
virtual char *getLastBytes() const override
|
||||
{
|
||||
return mLastBytes;
|
||||
}
|
||||
virtual MegaError getLastError() const override
|
||||
{
|
||||
assert(false && "unimplemented");
|
||||
return MegaErrorWithCtor(); //TODO: remove this and do actually serialize the error (not too costly)
|
||||
}
|
||||
virtual const MegaError *getLastErrorExtended() const override
|
||||
{
|
||||
assert(false && "unimplemented");
|
||||
return nullptr;
|
||||
}
|
||||
virtual bool isFolderTransfer() const override
|
||||
{
|
||||
return misFolderTransfer;
|
||||
}
|
||||
virtual int getFolderTransferTag() const override
|
||||
{
|
||||
return mFolderTransferTag;
|
||||
}
|
||||
virtual const char *getAppData() const override
|
||||
{
|
||||
return mAppData;
|
||||
}
|
||||
virtual int getState() const override
|
||||
{
|
||||
return mState;
|
||||
}
|
||||
virtual unsigned long long getPriority() const override
|
||||
{
|
||||
return mPriority;
|
||||
}
|
||||
virtual long long getNotificationNumber() const override
|
||||
{
|
||||
return mNotificationNumber;
|
||||
}
|
||||
virtual bool getTargetOverride() const override
|
||||
{
|
||||
return mTarOverride;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
class CommitGuard
|
||||
{
|
||||
private:
|
||||
sqlite3 *mDb = nullptr;
|
||||
bool mVacuum = false;
|
||||
|
||||
public:
|
||||
CommitGuard(sqlite3 *db, bool shrinkDb = false)
|
||||
:mDb(db), mVacuum(shrinkDb)
|
||||
{
|
||||
sqlite3_exec(mDb, "BEGIN", 0, 0, NULL);
|
||||
}
|
||||
|
||||
~CommitGuard()
|
||||
{
|
||||
sqlite3_exec(mDb, "COMMIT", 0, 0, NULL);
|
||||
|
||||
if (mVacuum)
|
||||
{
|
||||
sqlite3_exec(mDb, "VACUUM", 0, 0, NULL);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @brief Transfer Info persistency action
|
||||
*/
|
||||
class TransferInfoIOAction
|
||||
{
|
||||
public:
|
||||
enum Action
|
||||
{
|
||||
Write = 0,
|
||||
Remove = 1,
|
||||
};
|
||||
private:
|
||||
Action mAction;
|
||||
std::weak_ptr<TransferInfo> mTransferInfo;
|
||||
std::shared_ptr<TransferInfo> mTransferInfoOwned;
|
||||
public:
|
||||
TransferInfoIOAction(Action action, std::shared_ptr<TransferInfo> transferInfo, bool giveOwnership = false)
|
||||
: mAction(action), mTransferInfo(transferInfo)
|
||||
{
|
||||
if (giveOwnership)
|
||||
{
|
||||
mTransferInfoOwned = transferInfo; //thus, we keep a reference of the transferInfo
|
||||
}
|
||||
}
|
||||
Action action() const;
|
||||
std::weak_ptr<TransferInfo> transferInfo() const;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Class for persisting data transferInfos
|
||||
*/
|
||||
class TransferInfoIOWriter
|
||||
{
|
||||
private:
|
||||
std::deque<TransferInfoIOAction> mActions;
|
||||
TransferInfoIOAction getNextAction();
|
||||
bool hasActions();
|
||||
std::mutex mActionsMutex;
|
||||
std::mutex mIOMutex;
|
||||
std::condition_variable mIOcv;
|
||||
bool mFinished = false;
|
||||
int64_t mIOScheduleMs = 0;
|
||||
uint64_t mIOMaxActionBeforeNotifying = 0;
|
||||
std::unique_ptr<std::thread> mThreadIoProcessor;
|
||||
|
||||
std::string mTransferInfoDbPath;
|
||||
|
||||
// std::shared_ptr<LRUListCache<TransferInfo, std::string>> mTransferInfoCache;
|
||||
|
||||
//sqlite3 specific:
|
||||
bool initializeSqlite();
|
||||
bool doWrite(std::shared_ptr<TransferInfo> transferInfo);
|
||||
std::shared_ptr<std::string> doRead(std::shared_ptr<TransferInfo> transferInfo);
|
||||
bool doRemove(std::shared_ptr<TransferInfo> transferInfo);
|
||||
sqlite3 *db = nullptr;
|
||||
int64_t mLastId = 0;
|
||||
|
||||
bool mInitialized = false;
|
||||
|
||||
std::shared_ptr<TransferInfo> loadTransferInfo(const std::string &objectId);
|
||||
std::vector<std::shared_ptr<TransferInfo>> loadSubTransfers(TransferInfo *parent);
|
||||
|
||||
// Initiates mThreadIoProcessor thread loop finish.
|
||||
void end();
|
||||
|
||||
public:
|
||||
|
||||
static TransferInfoIOWriter& Instance();
|
||||
bool start();
|
||||
void shutdown(bool loginout = false);
|
||||
void loopIOActionProcessor();
|
||||
|
||||
std::string transferInfoDbPath() const;
|
||||
|
||||
~TransferInfoIOWriter();
|
||||
|
||||
/**
|
||||
* @brief queues writting a transferInfo
|
||||
* @param transferInfo
|
||||
* @return
|
||||
*/
|
||||
bool write(std::shared_ptr<TransferInfo> transferInfo);
|
||||
|
||||
/**
|
||||
* @brief queues removing a transferInfo
|
||||
* @param transferInfo
|
||||
* @return
|
||||
*/
|
||||
bool remove(std::shared_ptr<TransferInfo> transferInfo, bool delayNotification = false);
|
||||
|
||||
void forceExecution();
|
||||
|
||||
/**
|
||||
* @brief reads synchronously from db
|
||||
* @param transferInfo
|
||||
* @return
|
||||
*/
|
||||
std::shared_ptr<TransferInfo> read(const std::string &objectId);
|
||||
|
||||
// clean queues and empties db
|
||||
bool purge();
|
||||
|
||||
};
|
||||
|
||||
|
||||
}//end namespace
|
||||
|
||||
#endif
|
@ -223,7 +223,7 @@ const char * getLogLevelStr(int loglevel)
|
||||
}
|
||||
}
|
||||
|
||||
int getLogLevelNum(const char* level)
|
||||
std::optional<int> getLogLevelNum(const char* level)
|
||||
{
|
||||
if (!strcmp(level, "FATAL") || !strcmp(level, "fatal"))
|
||||
{
|
||||
@ -251,13 +251,14 @@ int getLogLevelNum(const char* level)
|
||||
}
|
||||
|
||||
int i = -1;
|
||||
istringstream is(level);
|
||||
is >> i;
|
||||
if (i == 0 && strcmp(level,"0"))
|
||||
|
||||
std::istringstream is(level);
|
||||
if (!(is >> i))
|
||||
{
|
||||
return -1;
|
||||
return {};
|
||||
}
|
||||
return i;
|
||||
|
||||
return std::clamp(i, (int) MegaApi::LOG_LEVEL_FATAL, (int) MegaApi::LOG_LEVEL_MAX);
|
||||
}
|
||||
|
||||
|
||||
@ -1250,15 +1251,4 @@ mega::MegaHandle base64ToSyncBackupId(const std::string &shandle)
|
||||
{
|
||||
return MegaApi::base64ToUserHandle(shandle.c_str());
|
||||
}
|
||||
|
||||
bool pathIsExistingDir(std::string path)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
replaceAll(path, "/", "\\");
|
||||
#endif
|
||||
LocalPath abs = LocalPath::fromAbsolutePath(path);
|
||||
::mega::MegaFileSystemAccess fsa;
|
||||
std::unique_ptr<::mega::FileAccess> fa = fsa.newfileaccess();
|
||||
return fa->isfolder(abs);
|
||||
}
|
||||
}//end namespace
|
||||
|
@ -42,7 +42,6 @@ const char* getAccessLevelStr(int level);
|
||||
GENERATOR_MACRO(RUNSTATE_PENDING, "Pending", "Sync config has loaded but we have not attempted to start it yet")\
|
||||
GENERATOR_MACRO(RUNSTATE_LOADING, "Loading", "Sync is in the process of loading from disk")\
|
||||
GENERATOR_MACRO(RUNSTATE_RUNNING, "Running", "Sync loaded and active")\
|
||||
GENERATOR_MACRO(RUNSTATE_PAUSED, "Paused", "Sync loaded but sync logic is suspended for now.")\
|
||||
GENERATOR_MACRO(RUNSTATE_SUSPENDED, "Suspended", "Sync is not loaded, but it is on disk with the last known sync state")\
|
||||
GENERATOR_MACRO(RUNSTATE_DISABLED, "Disabled", "Sync has been disabled (no state cached). Starting it is like configuring a brand new sync with those settings")\
|
||||
|
||||
@ -72,7 +71,7 @@ const char * getErrorCodeStr(mega::MegaError *e);
|
||||
|
||||
const char * getLogLevelStr(int loglevel);
|
||||
|
||||
int getLogLevelNum(const char* level);
|
||||
std::optional<int> getLogLevelNum(const char* level);
|
||||
|
||||
const char * getShareLevelStr(int sharelevel);
|
||||
|
||||
@ -152,7 +151,5 @@ bool getMinAndMaxSize(std::string sizestring, int64_t *minSize, int64_t *maxSize
|
||||
std::string readablePermissions(int permvalue);
|
||||
int permissionsFromReadable(std::string permissions);
|
||||
|
||||
bool pathIsExistingDir(std::string path);
|
||||
|
||||
}//end namespace
|
||||
#endif // MEGACMDUTILS_H
|
||||
|
@ -25,13 +25,12 @@
|
||||
namespace megacmd {
|
||||
|
||||
const char * const megacmdchangelog =
|
||||
"Improved startup time""\n"
|
||||
"Reduced memory consumption: cached metadata is no longer loaded at startup""\n"
|
||||
"Fixes and improvements in whoami, ls, backup and export commands""\n"
|
||||
"Fixed several memory leaks and improved overall memory consumption""\n"
|
||||
"Fixed file permissions on Unix""\n"
|
||||
"Added support for the Apple silicon (M1)""\n"
|
||||
"Many other fixes and improvements"
|
||||
"New Sync Engine: See sync-issues and sync-ignore commands""\n"
|
||||
"Rotating Logger: Introduced a robust rotating logging system across all platforms for better performance and debugging""\n"
|
||||
"Platform-specific enhancements: Addressed various file descriptor issues on Linux and macOS, and improved non-ascii support on Windows""\n"
|
||||
"Improved overall reliability: Fixed memory leaks, resolved potential data races, and eliminated deadlock scenarios""\n"
|
||||
"Fixed an issue when handling double-quoted arguments""\n"
|
||||
"Various fixes and refinements to enhance usability and performance"
|
||||
;
|
||||
|
||||
}//end namespace
|
||||
|
@ -71,7 +71,7 @@ void printSyncHeader(ColumnDisplayer &cd)
|
||||
cd.addHeader("REMOTEPATH", false);
|
||||
}
|
||||
|
||||
void printSingleSync(mega::MegaApi& api, mega::MegaSync& sync, mega::MegaNode& node, long long nFiles, long long nFolders, ColumnDisplayer &cd, bool showHandle, int syncIssuesCount)
|
||||
void printSingleSync(mega::MegaApi& api, mega::MegaSync& sync, mega::MegaNode* node, long long nFiles, long long nFolders, ColumnDisplayer &cd, bool showHandle, int syncIssuesCount)
|
||||
{
|
||||
cd.addValue("ID", getSyncId(sync));
|
||||
cd.addValue("LOCALPATH", sync.getLocalFolder());
|
||||
@ -106,7 +106,7 @@ void printSingleSync(mega::MegaApi& api, mega::MegaSync& sync, mega::MegaNode& n
|
||||
cd.addValue("ERROR", syncIssuesMsg);
|
||||
}
|
||||
|
||||
cd.addValue("SIZE", sizeToText(api.getSize(&node)));
|
||||
cd.addValue("SIZE", sizeToText(node ? api.getSize(node) : 0));
|
||||
cd.addValue("FILES", std::to_string(nFiles));
|
||||
cd.addValue("DIRS", std::to_string(nFolders));
|
||||
}
|
||||
@ -176,7 +176,7 @@ void printSync(mega::MegaApi& api, ColumnDisplayer& cd, bool showHandle, mega::M
|
||||
printSyncHeader(cd);
|
||||
|
||||
unsigned int syncIssuesCount = syncIssues.getSyncIssuesCount(sync);
|
||||
printSingleSync(api, sync, *node, nFiles, nFolders, cd, showHandle, syncIssuesCount);
|
||||
printSingleSync(api, sync, node.get(), nFiles, nFolders, cd, showHandle, syncIssuesCount);
|
||||
}
|
||||
|
||||
void printSyncList(mega::MegaApi& api, ColumnDisplayer& cd, bool showHandles, const mega::MegaSyncList& syncList, const SyncIssueList& syncIssues)
|
||||
@ -204,7 +204,7 @@ void printSyncList(mega::MegaApi& api, ColumnDisplayer& cd, bool showHandles, co
|
||||
}
|
||||
|
||||
unsigned int syncIssuesCount = syncIssues.getSyncIssuesCount(sync);
|
||||
printSingleSync(api, sync, *node, nFiles, nFolders, cd, showHandles, syncIssuesCount);
|
||||
printSingleSync(api, sync, node.get(), nFiles, nFolders, cd, showHandles, syncIssuesCount);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -16,13 +16,11 @@
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <filesystem>
|
||||
|
||||
#include "megacmdcommonutils.h"
|
||||
#include "sync_issues.h"
|
||||
|
||||
using namespace megacmd;
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
namespace SyncCommand
|
||||
{
|
||||
|
@ -18,13 +18,11 @@
|
||||
#include <fstream>
|
||||
#include <cstring>
|
||||
#include <regex>
|
||||
#include <filesystem>
|
||||
|
||||
#include "megacmdcommonutils.h"
|
||||
#include "megacmdlogger.h"
|
||||
|
||||
using namespace megacmd;
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
namespace {
|
||||
|
||||
@ -46,13 +44,13 @@ void trimSpaces(std::string& str)
|
||||
str.erase(end, str.end());
|
||||
}
|
||||
|
||||
std::unique_lock<std::mutex> getFileLock(const std::string& str)
|
||||
std::unique_lock<std::mutex> getFileLock(const fs::path& path)
|
||||
{
|
||||
static std::mutex mapMutex;
|
||||
static std::map<std::string, std::mutex> fileMutexMap;
|
||||
static std::map<fs::path, std::mutex> fileMutexMap;
|
||||
|
||||
std::lock_guard mapLock(mapMutex);
|
||||
return std::unique_lock(fileMutexMap[str]);
|
||||
return std::unique_lock(fileMutexMap[path]);
|
||||
}
|
||||
|
||||
void executeAdd(MegaIgnoreFile& megaIgnoreFile, const std::set<std::string>& filters)
|
||||
@ -138,7 +136,7 @@ void executeCommand(const Args& args)
|
||||
return;
|
||||
}
|
||||
|
||||
std::string megaIgnoreFilePath;
|
||||
fs::path megaIgnoreFilePath;
|
||||
bool isDefault = true;
|
||||
if (args.mMegaIgnoreDirPath.empty())
|
||||
{
|
||||
@ -146,21 +144,24 @@ void executeCommand(const Args& args)
|
||||
}
|
||||
else
|
||||
{
|
||||
megaIgnoreFilePath = args.mMegaIgnoreDirPath + "/.megaignore";
|
||||
megaIgnoreFilePath = args.mMegaIgnoreDirPath / ".megaignore";
|
||||
isDefault = false;
|
||||
}
|
||||
|
||||
if (!fs::exists(megaIgnoreFilePath))
|
||||
std::error_code ec;
|
||||
if (!fs::exists(megaIgnoreFilePath, ec))
|
||||
{
|
||||
setCurrentThreadOutCode(MCMD_NOTFOUND);
|
||||
if (isDefault)
|
||||
{
|
||||
// For the default file to be created, a sync that DOES NOT already contain a .megaignore file has to be added
|
||||
LOG_err << "Default .megaignore file does not exist (will be created when a new sync is added)";
|
||||
LOG_err << "Default .megaignore file does not exist (will be created when a new sync is added)"
|
||||
<< ( ec ? std::string(": ").append(errorCodeStr(ec).c_str()) : "");
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_err << "Mega ignore file \"" << megaIgnoreFilePath << "\" does not exist";
|
||||
LOG_err << "Mega ignore file \"" << megaIgnoreFilePath << "\" does not exist"
|
||||
<< ( ec ? std::string(": ").append(errorCodeStr(ec).c_str()) : "");
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -211,11 +212,10 @@ void MegaIgnoreFile::loadFilters(std::ifstream& file)
|
||||
}
|
||||
}
|
||||
|
||||
std::string MegaIgnoreFile::getDefaultPath()
|
||||
fs::path MegaIgnoreFile::getDefaultPath()
|
||||
{
|
||||
auto platformDirs = megacmd::PlatformDirectories::getPlatformSpecificDirectories();
|
||||
auto configDirPath = platformDirs->configDirPath();
|
||||
return configDirPath + "/.megaignore.default";
|
||||
return platformDirs->configDirPath() / ".megaignore.default";
|
||||
}
|
||||
|
||||
bool MegaIgnoreFile::isValidFilter(const std::string& filter)
|
||||
@ -224,15 +224,21 @@ bool MegaIgnoreFile::isValidFilter(const std::string& filter)
|
||||
return std::regex_match(filter, filterRegex);
|
||||
}
|
||||
|
||||
MegaIgnoreFile::MegaIgnoreFile(const std::string& path) :
|
||||
MegaIgnoreFile::MegaIgnoreFile(const fs::path& path) :
|
||||
mPath(path),
|
||||
mValid(false)
|
||||
{
|
||||
auto fileLock = getFileLock(mPath);
|
||||
if (fs::exists(mPath))
|
||||
std::error_code ec;
|
||||
if (fs::exists(mPath, ec))
|
||||
{
|
||||
loadFromPath();
|
||||
}
|
||||
else if (ec)
|
||||
{
|
||||
LOG_err << "MegaIgnoreFile existence check failure: " << mPath << ": " << errorCodeStr(ec);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
createWithBOM();
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user