├── .gitignore ├── LICENSE ├── Makefile ├── cli.c ├── doc └── crypto.txt ├── mbedtls-1.3.10.patch ├── papi.c ├── papi.h ├── pcache.c ├── pcache.h ├── pcallbacks.c ├── pcallbacks.h ├── pcloudcrypto.c ├── pcloudcrypto.h ├── pcompat.c ├── pcompat.h ├── pcompiler.h ├── pcrc32c.c ├── pcrc32c.h ├── pcrypto.c ├── pcrypto.h ├── pdatabase.h ├── pdiff.c ├── pdiff.h ├── pdownload.c ├── pdownload.h ├── pfileops.c ├── pfileops.h ├── pfolder.c ├── pfolder.h ├── pfs.c ├── pfs.h ├── pfscrypto.c ├── pfscrypto.h ├── pfsfake.c ├── pfsfolder.c ├── pfsfolder.h ├── pfsstatic.c ├── pfsstatic.h ├── pfstasks.c ├── pfstasks.h ├── pfsupload.c ├── pfsupload.h ├── pfsxattr.c ├── pfsxattr.h ├── pintervaltree.c ├── pintervaltree.h ├── plibs.c ├── plibs.h ├── plist.c ├── plist.h ├── plocalnotify.c ├── plocalnotify.h ├── plocalscan.c ├── plocalscan.h ├── plocks.c ├── plocks.h ├── pmemlock.c ├── pmemlock.h ├── pnetlibs.c ├── pnetlibs.h ├── pnotifications.c ├── pnotifications.h ├── pp2p.c ├── pp2p.h ├── ppagecache.c ├── ppagecache.h ├── ppassword.c ├── ppassword.h ├── ppassworddict.h ├── prunratelimit.c ├── prunratelimit.h ├── pscanexts.h ├── pscanner.c ├── pscanner.h ├── psettings.c ├── psettings.h ├── pssl-mbedtls.c ├── pssl-mbedtls.h ├── pssl-openssl.c ├── pssl-openssl.h ├── pssl-securetransport.c ├── pssl-securetransport.h ├── pssl.c ├── pssl.h ├── psslcerts.h ├── pstatus.c ├── pstatus.h ├── psyncer.c ├── psyncer.h ├── psynclib.c ├── psynclib.h ├── ptasks.c ├── ptasks.h ├── ptimer.c ├── ptimer.h ├── ptree.c ├── ptree.h ├── pupload.c └── pupload.h /.gitignore: -------------------------------------------------------------------------------- 1 | *.o 2 | *.a 3 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2013-2014 Anton Titov. 2 | * Copyright (c) 2013-2014 pCloud Ltd. 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * * Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * * Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * * Neither the name of pCloud Ltd nor the 13 | * names of its contributors may be used to endorse or promote products 14 | * derived from this software without specific prior written permission. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | * DISCLAIMED. IN NO EVENT SHALL pCloud Ltd BE LIABLE FOR ANY 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | CC=cc 2 | AR=ar rcu 3 | RANLIB=ranlib 4 | USESSL=openssl 5 | 6 | #CFLAGS=-Wall -Wpointer-arith -O2 -g -fsanitize=address -mtune=core2 7 | CFLAGS=-Wall -Wpointer-arith -O2 -g -fno-stack-protector -fomit-frame-pointer -mtune=core2 8 | #CFLAGS=-O2 -g -pg 9 | 10 | LIB_A=psynclib.a 11 | 12 | ifeq ($(OS),Windows_NT) 13 | CFLAGS += -DP_OS_WINDOWS 14 | LIB_A=psynclib.dll 15 | AR=$(CC) -shared -o 16 | RANLIB=strip --strip-unneeded 17 | LDFLAGS=-s 18 | else 19 | UNAME_S := $(shell uname -s) 20 | UNAME_V := $(shell uname -v) 21 | ifeq ($(UNAME_S),Linux) 22 | CFLAGS += -DP_OS_LINUX 23 | ifneq (,$(findstring Debian,$(UNAME_V))) 24 | CFLAGS += -DP_OS_DEBIAN 25 | endif 26 | LDFLAGS += -lssl -lcrypto -lfuse -lpthread -lsqlite3 27 | endif 28 | ifeq ($(UNAME_S),Darwin) 29 | CFLAGS += -DP_OS_MACOSX -I/usr/local/ssl/include/ 30 | CFLAGS += -DP_OS_MACOSX -I/usr/local/include/osxfuse/ 31 | LDFLAGS += -lssl -lcrypto -losxfuse -lsqlite3 -framework Cocoa -L/usr/local/ssl/lib 32 | #USESSL=securetransport 33 | endif 34 | endif 35 | 36 | OBJ=pcompat.o psynclib.o plocks.o plibs.o pcallbacks.o pdiff.o pstatus.o papi.o ptimer.o pupload.o pdownload.o pfolder.o\ 37 | psyncer.o ptasks.o psettings.o pnetlibs.o pcache.o pscanner.o plist.o plocalscan.o plocalnotify.o pp2p.o\ 38 | pcrypto.o pssl.o pfileops.o ptree.o ppassword.o prunratelimit.o pmemlock.o pnotifications.o 39 | 40 | OBJFS=pfs.o ppagecache.o pfsfolder.o pfstasks.o pfsupload.o pintervaltree.o pfsxattr.o pcloudcrypto.o pfscrypto.o pcrc32c.o pfsstatic.o plocks.o 41 | 42 | OBJNOFS=pfsfake.o 43 | 44 | ifeq ($(USESSL),openssl) 45 | OBJ += pssl-openssl.o 46 | CFLAGS += -DP_SSL_OPENSSL 47 | endif 48 | ifeq ($(USESSL),securetransport) 49 | OBJ += pssl-securetransport.o 50 | CFLAGS += -DP_SSL_SECURETRANSPORT 51 | endif 52 | ifeq ($(USESSL),mbed) 53 | OBJ += pssl-mbedtls.o 54 | CFLAGS += -DP_SSL_MBEDTLS -I../../mbedtls-1.3.10/include/ 55 | endif 56 | 57 | all: $(LIB_A) 58 | 59 | $(LIB_A): $(OBJ) $(OBJNOFS) 60 | $(AR) $@ $(OBJ) $(OBJNOFS) 61 | $(RANLIB) $@ 62 | 63 | fs: $(OBJ) $(OBJFS) 64 | $(AR) $(LIB_A) $(OBJ) $(OBJFS) 65 | $(RANLIB) $(LIB_A) 66 | 67 | cli: fs 68 | $(CC) $(CFLAGS) -o cli cli.c $(LIB_A) $(LDFLAGS) 69 | 70 | clean: 71 | rm -f *~ *.o $(LIB_A) 72 | 73 | -------------------------------------------------------------------------------- /cli.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "psynclib.h" 4 | 5 | int main() 6 | { 7 | psync_init(); 8 | psync_start_sync(NULL, NULL); 9 | psync_fs_start(); 10 | printf("Press enter to exit/umount\n"); 11 | getc(stdin); 12 | psync_fs_stop(); 13 | psync_destroy(); 14 | return 0; 15 | } 16 | -------------------------------------------------------------------------------- /doc/crypto.txt: -------------------------------------------------------------------------------- 1 | File encryption format 2 | 3 | We have a global AES-256 key and 128 bit global (for the file) IV. 4 | 5 | Sector = 4096 bytes. 6 | 7 | The file is split in 4096-byte blocks. Each block is encrypted using 8 | AES256-CTR. 9 | 10 | For every block there's one SIGN 128-bit block, the format for which is: 11 | 12 | hmac-sha1 13 | and over it, in the beginning: 14 | 2 bits revision length (1, 2 or 3 bytes) 15 | next 6 bits as from hmac-sha 16 | 1,2 or 3 bytes revision 17 | 18 | the hmac-sha1 is calculated on the following, concatenated: 19 | data; 20 | sector id (64 bit); 21 | revision id (32 bit). 22 | 23 | the secret is the per-file IV. 24 | 25 | (sector id is the consecutive number of 4k sector of DATA/plaintext in 26 | the file, starting from 0 (zero) ) 27 | 28 | For the AES256-CTR, the IV is the 128 bit SIGN block. 29 | 30 | The SIGN blocks are written for every 256 blocks after them in a 4KB 31 | block, encrypted using AES-ECB. They cannot repeat, as the sector number 32 | is different for each one. 33 | 34 | 35 | The SIGN blocks create a hash tree. The first level is the SIGN blocks, 36 | the second level is blocks of hmac-sha1 of every 256 lower-level SIGN 37 | blocks (a sector), the third is hmac-sha1 of the lower level of 256 38 | hmac-sha1 blocks, and up to until you're left with only one block, which 39 | is at the end of the file. All such blocks are encrypted with 40 | AES256-ECB. 41 | 42 | 43 | On every change of a block, the revision is increased with 1. On 44 | revision overflow (2^24) the file SHOULD be reencrypted with a different 45 | IV. 46 | 47 | Every read reads at least 4KB, the block with the SIGN block related to 48 | it, and the upper level of the SIGN, to verify them. 49 | -------------------------------------------------------------------------------- /mbedtls-1.3.10.patch: -------------------------------------------------------------------------------- 1 | --- mbedtls-1.3.10/library/pkparse.c 2015-02-10 18:00:42.000000000 +0200 2 | +++ mbedtls-1.3.10p/library/pkparse.c 2015-05-10 18:59:43.911605796 +0300 3 | @@ -1243,6 +1243,17 @@ 4 | 5 | ret = pk_parse_subpubkey( &p, p + keylen, ctx ); 6 | 7 | +#if defined(POLARSSL_RSA_C) 8 | + if( ret != 0 ) 9 | + { 10 | + pk_init_ctx( ctx, pk_info_from_type( POLARSSL_PK_RSA ) ); 11 | + p = (unsigned char *) key; 12 | + ret = pk_get_rsapubkey( &p, p + keylen, pk_rsa( *ctx ) ); 13 | + if( ret != 0) 14 | + pk_free( ctx ); 15 | + } 16 | +#endif /* POLARSSL_RSA_C */ 17 | + 18 | #if defined(POLARSSL_PEM_PARSE_C) 19 | pem_free( &pem ); 20 | #endif 21 | -------------------------------------------------------------------------------- /papi.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2013 Anton Titov. 2 | * Copyright (c) 2013 pCloud Ltd. 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * * Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * * Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * * Neither the name of pCloud Ltd nor the 13 | * names of its contributors may be used to endorse or promote products 14 | * derived from this software without specific prior written permission. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | * DISCLAIMED. IN NO EVENT SHALL pCloud Ltd BE LIABLE FOR ANY 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | #ifndef _PSYNC_API_H 29 | #define _PSYNC_API_H 30 | 31 | #include "pcompat.h" 32 | #include "pcompiler.h" 33 | #include 34 | #include 35 | 36 | #define PARAM_STR 0 37 | #define PARAM_NUM 1 38 | #define PARAM_BOOL 2 39 | 40 | #define PARAM_ARRAY 3 41 | #define PARAM_HASH 4 42 | #define PARAM_DATA 5 43 | 44 | #define PARAM_END 255 45 | 46 | #define PTR_OK ((binresult *)1) 47 | 48 | #define ASYNC_RES_NEEDMORE 0 49 | #define ASYNC_RES_READY 1 50 | 51 | typedef struct { 52 | uint16_t paramtype; 53 | uint16_t paramnamelen; 54 | uint32_t opts; 55 | const char *paramname; 56 | union { 57 | uint64_t num; 58 | const char *str; 59 | }; 60 | } binparam; 61 | 62 | struct _binresult; 63 | 64 | typedef struct _hashpair { 65 | const char *key; 66 | struct _binresult *value; 67 | } hashpair; 68 | 69 | typedef struct _binresult{ 70 | uint32_t type; 71 | uint32_t length; 72 | union { 73 | uint64_t num; 74 | const char str[8]; 75 | struct _binresult **array; 76 | struct _hashpair *hash; 77 | }; 78 | } binresult; 79 | 80 | typedef struct { 81 | binresult *result; 82 | uint32_t state; 83 | uint32_t bytesread; 84 | uint32_t bytestoread; 85 | uint32_t respsize; 86 | unsigned char *data; 87 | } async_result_reader; 88 | 89 | #define P_STR(name, val) {PARAM_STR, strlen(name), strlen(val), (name), {(uint64_t)((uintptr_t)(val))}} 90 | #define P_LSTR(name, val, len) {PARAM_STR, strlen(name), (len), (name), {(uint64_t)((uintptr_t)(val))}} 91 | #define P_NUM(name, val) {PARAM_NUM, strlen(name), 0, (name), {(val)}} 92 | #define P_BOOL(name, val) {PARAM_BOOL, strlen(name), 0, (name), {(val)?1:0}} 93 | 94 | #define send_command(sock, cmd, params) do_send_command(sock, cmd, strlen(cmd), params, sizeof(params)/sizeof(binparam), -1, 1) 95 | #define send_command_no_res(sock, cmd, params) do_send_command(sock, cmd, strlen(cmd), params, sizeof(params)/sizeof(binparam), -1, 0) 96 | 97 | #define send_command_thread(sock, cmd, params) do_send_command(sock, cmd, strlen(cmd), params, sizeof(params)/sizeof(binparam), -1, 1|2) 98 | #define send_command_no_res_thread(sock, cmd, params) do_send_command(sock, cmd, strlen(cmd), params, sizeof(params)/sizeof(binparam), -1, 2) 99 | 100 | #define prepare_command_data_alloc(cmd, params, datalen, alloclen, retlen) \ 101 | do_prepare_command(cmd, strlen(cmd), params, sizeof(params)/sizeof(binparam), datalen, alloclen, retlen) 102 | 103 | #define psync_find_result(res, name, type) psync_do_find_result(res, name, type, __FILE__, __FUNCTION__, __LINE__) 104 | #define psync_check_result(res, name, type) psync_do_check_result(res, name, type, __FILE__, __FUNCTION__, __LINE__) 105 | 106 | psync_socket *psync_api_connect(int usessl); 107 | void psync_api_conn_fail_inc(); 108 | void psync_api_conn_fail_reset(); 109 | 110 | binresult *get_result(psync_socket *sock) PSYNC_NONNULL(1); 111 | binresult *get_result_thread(psync_socket *sock) PSYNC_NONNULL(1); 112 | void async_result_reader_init(async_result_reader *reader) PSYNC_NONNULL(1); 113 | void async_result_reader_destroy(async_result_reader *reader) PSYNC_NONNULL(1); 114 | int get_result_async(psync_socket *sock, async_result_reader *reader) PSYNC_NONNULL(1, 2); 115 | unsigned char *do_prepare_command(const char *command, size_t cmdlen, const binparam *params, size_t paramcnt, int64_t datalen, size_t additionalalloc, size_t *retlen); 116 | binresult *do_send_command(psync_socket *sock, const char *command, size_t cmdlen, const binparam *params, size_t paramcnt, int64_t datalen, int readres) PSYNC_NONNULL(1, 2); 117 | const binresult *psync_do_find_result(const binresult *res, const char *name, uint32_t type, const char *file, const char *function, int unsigned line) PSYNC_NONNULL(2) PSYNC_PURE; 118 | const binresult *psync_do_check_result(const binresult *res, const char *name, uint32_t type, const char *file, const char *function, int unsigned line) PSYNC_NONNULL(2) PSYNC_PURE; 119 | 120 | #endif -------------------------------------------------------------------------------- /pcache.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2014 Anton Titov. 2 | * Copyright (c) 2014 pCloud Ltd. 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * * Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * * Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * * Neither the name of pCloud Ltd nor the 13 | * names of its contributors may be used to endorse or promote products 14 | * derived from this software without specific prior written permission. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | * DISCLAIMED. IN NO EVENT SHALL pCloud Ltd BE LIABLE FOR ANY 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | #ifndef _PSYNC_CACHE_H 29 | #define _PSYNC_CACHE_H 30 | 31 | #include 32 | 33 | typedef void (*psync_cache_free_callback)(void *); 34 | 35 | void psync_cache_init(); 36 | void *psync_cache_get(const char *key); 37 | int psync_cache_has(const char *key); 38 | void psync_cache_add(const char *key, void *ptr, time_t freeafter, psync_cache_free_callback freefunc, uint32_t maxkeys); 39 | void psync_cache_add_free(char *key, void *ptr, time_t freeafter, psync_cache_free_callback freefunc, uint32_t maxkeys); 40 | void psync_cache_del(const char *key); 41 | void psync_cache_clean_all(); 42 | void psync_cache_clean_starting_with(const char *prefix); 43 | void psync_cache_clean_starting_with_one_of(const char **prefixes, size_t cnt); 44 | 45 | #endif -------------------------------------------------------------------------------- /pcallbacks.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2013-2014 Anton Titov. 2 | * Copyright (c) 2013-2014 pCloud Ltd. 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * * Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * * Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * * Neither the name of pCloud Ltd nor the 13 | * names of its contributors may be used to endorse or promote products 14 | * derived from this software without specific prior written permission. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | * DISCLAIMED. IN NO EVENT SHALL pCloud Ltd BE LIABLE FOR ANY 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | #ifndef _PSYNC_CALLBACKS_H 29 | #define _PSYNC_CALLBACKS_H 30 | 31 | #include "psynclib.h" 32 | 33 | void psync_callbacks_get_status(pstatus_t *status); 34 | void psync_set_status_callback(pstatus_change_callback_t callback); 35 | void psync_send_status_update(); 36 | void psync_set_event_callback(pevent_callback_t callback); 37 | void psync_send_event_by_id(psync_eventtype_t eventid, psync_syncid_t syncid, const char *localpath, psync_fileorfolderid_t remoteid); 38 | void psync_send_event_by_path(psync_eventtype_t eventid, psync_syncid_t syncid, const char *localpath, psync_fileorfolderid_t remoteid, const char *remotepath); 39 | void psync_send_eventid(psync_eventtype_t eventid); 40 | void psync_send_eventdata(psync_eventtype_t eventid, void *eventdata); 41 | 42 | #endif 43 | -------------------------------------------------------------------------------- /pcloudcrypto.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2014 Anton Titov. 2 | * Copyright (c) 2014 pCloud Ltd. 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * * Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * * Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * * Neither the name of pCloud Ltd nor the 13 | * names of its contributors may be used to endorse or promote products 14 | * derived from this software without specific prior written permission. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | * DISCLAIMED. IN NO EVENT SHALL pCloud Ltd BE LIABLE FOR ANY 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | #ifndef _PCLOUD_CRYPTO_H 29 | #define _PCLOUD_CRYPTO_H 30 | 31 | #include "pcompiler.h" 32 | #include "pfs.h" 33 | #include "pcrypto.h" 34 | #include "papi.h" 35 | 36 | #define PSYNC_CRYPTO_SYM_FLAG_ISDIR 1 37 | 38 | #define PSYNC_CRYPTO_SECTOR_SIZE 4096 39 | 40 | #define PSYNC_CRYPTO_MAX_ERROR 511 41 | 42 | #define PSYNC_CRYPTO_UNLOADED_SECTOR_ENCODER ((psync_crypto_aes256_sector_encoder_decoder_t)(PSYNC_CRYPTO_MAX_ERROR+1)) 43 | #define PSYNC_CRYPTO_LOADING_SECTOR_ENCODER ((psync_crypto_aes256_sector_encoder_decoder_t)(PSYNC_CRYPTO_MAX_ERROR+2)) 44 | #define PSYNC_CRYPTO_FAILED_SECTOR_ENCODER ((psync_crypto_aes256_sector_encoder_decoder_t)(PSYNC_CRYPTO_MAX_ERROR+3)) 45 | 46 | void psync_cloud_crypto_clean_cache(); 47 | 48 | int psync_cloud_crypto_setup(const char *password, const char *hint); 49 | int psync_cloud_crypto_get_hint(char **hint); 50 | int psync_cloud_crypto_start(const char *password); 51 | int psync_cloud_crypto_stop(); 52 | int psync_cloud_crypto_isstarted(); 53 | int psync_cloud_crypto_reset(); 54 | int psync_cloud_crypto_mkdir(psync_folderid_t folderid, const char *name, const char **err, psync_folderid_t *newfolderid); 55 | 56 | psync_crypto_aes256_text_decoder_t psync_cloud_crypto_get_folder_decoder(psync_fsfolderid_t folderid); 57 | void psync_cloud_crypto_release_folder_decoder(psync_fsfolderid_t folderid, psync_crypto_aes256_text_decoder_t decoder); 58 | char *psync_cloud_crypto_decode_filename(psync_crypto_aes256_text_decoder_t decoder, const char *name); 59 | 60 | psync_crypto_aes256_text_encoder_t psync_cloud_crypto_get_folder_encoder(psync_fsfolderid_t folderid); 61 | void psync_cloud_crypto_release_folder_encoder(psync_fsfolderid_t folderid, psync_crypto_aes256_text_encoder_t encoder); 62 | char *psync_cloud_crypto_encode_filename(psync_crypto_aes256_text_encoder_t encoder, const char *name); 63 | 64 | psync_crypto_aes256_sector_encoder_decoder_t psync_cloud_crypto_get_file_encoder(psync_fsfileid_t fileid, uint64_t hash, int nonetwork); 65 | psync_crypto_aes256_sector_encoder_decoder_t psync_cloud_crypto_get_file_encoder_from_binresult(psync_fileid_t fileid, binresult *res); 66 | void psync_cloud_crypto_release_file_encoder(psync_fsfileid_t fileid, uint64_t hash, psync_crypto_aes256_sector_encoder_decoder_t encoder); 67 | 68 | char *psync_cloud_crypto_get_file_encoded_key(psync_fsfileid_t fileid, uint64_t hash, size_t *keylen); 69 | char *psync_cloud_crypto_get_new_encoded_key(uint32_t flags, size_t *keylen); 70 | char *psync_cloud_crypto_get_new_encoded_and_plain_key(uint32_t flags, size_t *keylen, psync_symmetric_key_t *deckey); 71 | 72 | static inline int psync_crypto_is_error(const void *ptr){ 73 | return (uintptr_t)ptr<=PSYNC_CRYPTO_MAX_ERROR; 74 | } 75 | 76 | static inline int psync_crypto_to_error(const void *ptr){ 77 | return -((int)(uintptr_t)ptr); 78 | } 79 | 80 | 81 | #endif 82 | -------------------------------------------------------------------------------- /pcompiler.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2013-2014 Anton Titov. 2 | * Copyright (c) 2013-2014 pCloud Ltd. 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * * Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * * Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * * Neither the name of pCloud Ltd nor the 13 | * names of its contributors may be used to endorse or promote products 14 | * derived from this software without specific prior written permission. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | * DISCLAIMED. IN NO EVENT SHALL pCloud Ltd BE LIABLE FOR ANY 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | #ifndef _PSYNC_COMPILER_H 29 | #define _PSYNC_COMPILER_H 30 | 31 | #if defined(_MSC_VER) 32 | #include 33 | #endif 34 | 35 | #if !defined(__has_attribute) 36 | #if defined(__GNUC__) 37 | #define __has_attribute(x) 1 38 | #else 39 | #define __has_attribute(x) 0 40 | #endif 41 | #else 42 | #if defined(__GNUC__) && !__has_attribute(malloc) 43 | #undef __has_attribute 44 | #define __has_attribute(x) 1 45 | #endif 46 | #endif 47 | 48 | #ifndef __has_builtin 49 | #if defined(__GNUC__) 50 | #define __has_builtin(x) 1 51 | #else 52 | #define __has_builtin(x) 0 53 | #endif 54 | #endif 55 | 56 | #if __has_builtin(__builtin_expect) 57 | #define likely(expr) __builtin_expect(!!(expr), 1) 58 | #define unlikely(expr) __builtin_expect(!!(expr), 0) 59 | #else 60 | #define likely(expr) (expr) 61 | #define unlikely(expr) (expr) 62 | #endif 63 | 64 | #if __has_builtin(__builtin_prefetch) 65 | #define psync_prefetch(expr) __builtin_prefetch(expr) 66 | #elif defined(_MSC_VER) 67 | #define psync_prefetch(expr) _mm_prefetch((char *)(expr), _MM_HINT_T0) 68 | #else 69 | #define psync_prefetch(expr) ((void)0) 70 | #endif 71 | 72 | #if defined(_MSC_VER) 73 | #define PSYNC_THREAD __declspec(thread) 74 | #define PSYNC_NOINLINE __declspec(noinline) 75 | #else 76 | #if __has_attribute(noinline) 77 | #define PSYNC_NOINLINE __attribute__((noinline)) 78 | #else 79 | #define PSYNC_NOINLINE 80 | #endif 81 | #define PSYNC_THREAD __thread 82 | #endif 83 | 84 | #if __has_attribute(malloc) 85 | #define PSYNC_MALLOC __attribute__((malloc)) 86 | #else 87 | #define PSYNC_MALLOC 88 | #endif 89 | 90 | #if __has_attribute(sentinel) 91 | #define PSYNC_SENTINEL __attribute__ ((sentinel)) 92 | #else 93 | #define PSYNC_SENTINEL 94 | #endif 95 | 96 | #if __has_attribute(pure) 97 | #define PSYNC_PURE __attribute__ ((pure)) 98 | #else 99 | #define PSYNC_PURE 100 | #endif 101 | 102 | #if __has_attribute(const) 103 | #define PSYNC_CONST __attribute__ ((const)) 104 | #else 105 | #define PSYNC_CONST 106 | #endif 107 | 108 | #if __has_attribute(cold) 109 | #define PSYNC_COLD __attribute__ ((cold)) 110 | #else 111 | #define PSYNC_COLD 112 | #endif 113 | 114 | #if __has_attribute(format) 115 | #define PSYNC_FORMAT(a, b, c) __attribute__ ((format (a, b, c))) 116 | #else 117 | #define PSYNC_FORMAT(a, b, c) 118 | #endif 119 | 120 | #if __has_attribute(nonnull) 121 | #define PSYNC_NONNULL(...) __attribute__ ((nonnull (__VA_ARGS__))) 122 | #else 123 | #define PSYNC_NONNULL(...) 124 | #endif 125 | 126 | #if __has_attribute(packed) 127 | #define PSYNC_PACKED_STRUCT struct __attribute__ ((packed)) 128 | #elif defined(_MSC_VER) 129 | #define PSYNC_PACKED_STRUCT __declspec(align(1)) struct 130 | #else 131 | #define PSYNC_PACKED_STRUCT struct 132 | #endif 133 | 134 | #if _MSC_VER >= 1500 && _MSC_VER < 1600 135 | #define inline __inline 136 | #define restrict __restrict 137 | #elif __GNUC__ >= 3 138 | #define inline __inline 139 | #define restrict __restrict 140 | #elif __STDC_VERSION__!=199901L 141 | #define inline 142 | #define restrict 143 | #endif 144 | 145 | #if defined(__clang__) || defined(_MSC_VER) 146 | #define psync_alignof __alignof 147 | #elif defined(__GNUC__) 148 | #define psync_alignof __alignof__ 149 | #else 150 | #define psync_alignof(t) offsetof(struct {char a; t b;}, b) 151 | #endif 152 | 153 | #endif 154 | -------------------------------------------------------------------------------- /pcrc32c.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2014 Anton Titov. 2 | * Copyright (c) 2014 pCloud Ltd. 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * * Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * * Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * * Neither the name of pCloud Ltd nor the 13 | * names of its contributors may be used to endorse or promote products 14 | * derived from this software without specific prior written permission. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | * DISCLAIMED. IN NO EVENT SHALL pCloud Ltd BE LIABLE FOR ANY 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | #ifndef _PSYNC_CRC32_H 29 | #define _PSYNC_CRC32_H 30 | 31 | #include 32 | #include 33 | 34 | #define PSYNC_CRC_INITIAL 0 35 | 36 | #define PSYNC_FAST_HASH256_LEN 32 37 | #define PSYNC_FAST_HASH256_HEXLEN 64 38 | 39 | #define PSYNC_FAST_HASH256_BLOCK_LEN 64 40 | 41 | typedef struct{ 42 | uint64_t state[6]; 43 | uint64_t length; 44 | union { 45 | uint64_t buff64[PSYNC_FAST_HASH256_BLOCK_LEN/sizeof(uint64_t)]; 46 | unsigned char buff[PSYNC_FAST_HASH256_BLOCK_LEN]; 47 | }; 48 | } psync_fast_hash256_ctx; 49 | 50 | uint32_t psync_crc32c(uint32_t crc, const void *ptr, size_t len); 51 | 52 | /* psync_fast_hash256 is supposed to be fast, non-cryptographic strength, non-collision resistant hash function 53 | * with large output. Think of it as CRC32 but faster, with 256bit output and for cases that you can't live with 54 | * the chances of CRC32 _random_ collision. It is intended for large inputs, finalization is relatively expensive. 55 | */ 56 | 57 | void psync_fast_hash256_init(psync_fast_hash256_ctx *ctx); 58 | void psync_fast_hash256_init_seed(psync_fast_hash256_ctx *ctx, const void *seed, size_t seedlen); 59 | void psync_fast_hash256_update(psync_fast_hash256_ctx *ctx, const void *data, size_t len); 60 | void psync_fast_hash256_final(void *hash, psync_fast_hash256_ctx *ctx); 61 | 62 | #endif 63 | -------------------------------------------------------------------------------- /pcrypto.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2014 Anton Titov. 2 | * Copyright (c) 2014 pCloud Ltd. 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * * Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * * Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * * Neither the name of pCloud Ltd nor the 13 | * names of its contributors may be used to endorse or promote products 14 | * derived from this software without specific prior written permission. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | * DISCLAIMED. IN NO EVENT SHALL pCloud Ltd BE LIABLE FOR ANY 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | #ifndef _PSYNC_CRYPTO_H 29 | #define _PSYNC_CRYPTO_H 30 | 31 | #include "pssl.h" 32 | 33 | #define PSYNC_CRYPTO_AUTH_SIZE (PSYNC_AES256_BLOCK_SIZE*2) 34 | 35 | #define PSYNC_CRYPTO_MAX_HASH_TREE_LEVEL 6 36 | 37 | typedef struct { 38 | uint64_t masterauthoff; 39 | uint64_t plainsize; 40 | uint64_t lastauthsectoroff[PSYNC_CRYPTO_MAX_HASH_TREE_LEVEL]; 41 | uint16_t lastauthsectorlen[PSYNC_CRYPTO_MAX_HASH_TREE_LEVEL]; 42 | uint8_t treelevels; 43 | uint8_t needmasterauth; 44 | } psync_crypto_offsets_t; 45 | 46 | typedef unsigned char psync_crypto_sector_auth_t[PSYNC_CRYPTO_AUTH_SIZE]; 47 | 48 | typedef struct { 49 | psync_aes256_encoder encoder; 50 | union { 51 | long unsigned __aligner; 52 | unsigned char iv[PSYNC_AES256_BLOCK_SIZE]; 53 | }; 54 | } psync_crypto_aes256_key_struct_t, *psync_crypto_aes256_ctr_encoder_decoder_t; 55 | 56 | typedef struct { 57 | psync_aes256_encoder encoder; 58 | unsigned long ivlen; 59 | unsigned char iv[]; 60 | } psync_crypto_aes256_key_var_iv_struct_t, *psync_crypto_aes256_text_encoder_t, *psync_crypto_aes256_text_decoder_t; 61 | 62 | 63 | typedef struct { 64 | psync_aes256_encoder encoder; 65 | psync_aes256_decoder decoder; 66 | unsigned long ivlen; 67 | unsigned char iv[]; 68 | } psync_crypto_aes256_enc_dec_var_iv_struct_t, *psync_crypto_aes256_sector_encoder_decoder_t; 69 | 70 | #define psync_crypto_aes256_text_gen_key psync_crypto_aes256_ctr_gen_key 71 | #define psync_crypto_aes256_sector_gen_key psync_crypto_aes256_ctr_gen_key 72 | 73 | #define PSYNC_CRYPTO_INVALID_ENCODER NULL 74 | #define PSYNC_CRYPTO_INVALID_REVISIONID ((uint32_t)-1) 75 | 76 | psync_symmetric_key_t psync_crypto_aes256_gen_key_len(size_t len); 77 | psync_symmetric_key_t psync_crypto_aes256_ctr_gen_key(); 78 | psync_crypto_aes256_ctr_encoder_decoder_t psync_crypto_aes256_ctr_encoder_decoder_create(psync_symmetric_key_t key); 79 | void psync_crypto_aes256_ctr_encoder_decoder_free(psync_crypto_aes256_ctr_encoder_decoder_t enc); 80 | void psync_crypto_aes256_ctr_encode_decode_inplace(psync_crypto_aes256_ctr_encoder_decoder_t enc, void *data, size_t datalen, uint64_t dataoffset); 81 | 82 | psync_crypto_aes256_text_encoder_t psync_crypto_aes256_text_encoder_create(psync_symmetric_key_t key); 83 | void psync_crypto_aes256_text_encoder_free(psync_crypto_aes256_text_encoder_t enc); 84 | psync_crypto_aes256_text_decoder_t psync_crypto_aes256_text_decoder_create(psync_symmetric_key_t key); 85 | void psync_crypto_aes256_text_decoder_free(psync_crypto_aes256_text_decoder_t enc); 86 | void psync_crypto_aes256_encode_text(psync_crypto_aes256_text_encoder_t enc, const unsigned char *txt, size_t txtlen, unsigned char **out, size_t *outlen); 87 | unsigned char *psync_crypto_aes256_decode_text(psync_crypto_aes256_text_decoder_t enc, const unsigned char *data, size_t datalen); 88 | 89 | psync_crypto_aes256_sector_encoder_decoder_t psync_crypto_aes256_sector_encoder_decoder_create(psync_symmetric_key_t key); 90 | void psync_crypto_aes256_sector_encoder_decoder_free(psync_crypto_aes256_sector_encoder_decoder_t enc); 91 | void psync_crypto_aes256_encode_sector(psync_crypto_aes256_sector_encoder_decoder_t enc, const unsigned char *data, size_t datalen, 92 | unsigned char *out, psync_crypto_sector_auth_t authout, uint64_t sectorid); 93 | int psync_crypto_aes256_decode_sector(psync_crypto_aes256_sector_encoder_decoder_t enc, const unsigned char *data, size_t datalen, 94 | unsigned char *out, const psync_crypto_sector_auth_t auth, uint64_t sectorid); 95 | void psync_crypto_sign_auth_sector(psync_crypto_aes256_sector_encoder_decoder_t enc, const unsigned char *data, size_t datalen, psync_crypto_sector_auth_t authout); 96 | #endif 97 | -------------------------------------------------------------------------------- /pdiff.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2013 Anton Titov. 2 | * Copyright (c) 2013 pCloud Ltd. 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * * Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * * Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * * Neither the name of pCloud Ltd nor the 13 | * names of its contributors may be used to endorse or promote products 14 | * derived from this software without specific prior written permission. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | * DISCLAIMED. IN NO EVENT SHALL pCloud Ltd BE LIABLE FOR ANY 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | #ifndef _PSYNC_DIFF_H 29 | #define _PSYNC_DIFF_H 30 | 31 | #include "papi.h" 32 | 33 | void psync_diff_init(); 34 | void psync_diff_lock(); 35 | void psync_diff_unlock(); 36 | void psync_diff_create_file(const binresult *meta); 37 | void psync_diff_update_file(const binresult *meta); 38 | void psync_diff_delete_file(const binresult *meta); 39 | void psync_diff_update_folder(const binresult *meta); 40 | void psync_diff_delete_folder(const binresult *meta); 41 | 42 | 43 | #endif 44 | -------------------------------------------------------------------------------- /pdownload.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2013 Anton Titov. 2 | * Copyright (c) 2013 pCloud Ltd. 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * * Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * * Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * * Neither the name of pCloud Ltd nor the 13 | * names of its contributors may be used to endorse or promote products 14 | * derived from this software without specific prior written permission. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | * DISCLAIMED. IN NO EVENT SHALL pCloud Ltd BE LIABLE FOR ANY 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | #ifndef _PSYNC_DOWNLOAD_H 29 | #define _PSYNC_DOWNLOAD_H 30 | 31 | #include "psynclib.h" 32 | #include "psettings.h" 33 | #include "pssl.h" 34 | 35 | typedef unsigned char psync_hex_hash[PSYNC_HASH_DIGEST_HEXLEN]; 36 | 37 | typedef struct { 38 | size_t hashcnt; 39 | psync_hex_hash hashes[]; 40 | } downloading_files_hashes; 41 | 42 | void psync_download_init(); 43 | void psync_wake_download(); 44 | void psync_delete_download_tasks_for_file(psync_fileid_t fileid); 45 | void psync_stop_file_download(psync_fileid_t fileid, psync_syncid_t syncid); 46 | void psync_stop_sync_download(psync_syncid_t syncid); 47 | void psync_stop_all_download(); 48 | downloading_files_hashes *psync_get_downloading_hashes(); 49 | 50 | #endif -------------------------------------------------------------------------------- /pfileops.c: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2014 Anton Titov. 2 | * Copyright (c) 2014 pCloud Ltd. 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * * Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * * Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * * Neither the name of pCloud Ltd nor the 13 | * names of its contributors may be used to endorse or promote products 14 | * derived from this software without specific prior written permission. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | * DISCLAIMED. IN NO EVENT SHALL pCloud Ltd BE LIABLE FOR ANY 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | #include "pfileops.h" 29 | #include "plibs.h" 30 | #include "pdiff.h" 31 | #include "pfolder.h" 32 | 33 | void psync_ops_create_folder_in_db(const binresult *meta){ 34 | psync_sql_res *res; 35 | const binresult *name; 36 | uint64_t userid, perms, flags; 37 | flags=0; 38 | if ((name=psync_check_result(meta, "encrypted", PARAM_BOOL)) && name->num) 39 | flags|=PSYNC_FOLDER_FLAG_ENCRYPTED; 40 | res=psync_sql_prep_statement("INSERT OR IGNORE INTO folder (id, parentfolderid, userid, permissions, name, ctime, mtime, flags) VALUES (?, ?, ?, ?, ?, ?, ?, ?)"); 41 | if (psync_find_result(meta, "ismine", PARAM_BOOL)->num){ 42 | userid=psync_my_userid; 43 | perms=PSYNC_PERM_ALL; 44 | } 45 | else{ 46 | userid=psync_find_result(meta, "userid", PARAM_NUM)->num; 47 | perms=psync_get_permissions(meta); 48 | } 49 | name=psync_find_result(meta, "name", PARAM_STR); 50 | psync_sql_bind_uint(res, 1, psync_find_result(meta, "folderid", PARAM_NUM)->num); 51 | psync_sql_bind_uint(res, 2, psync_find_result(meta, "parentfolderid", PARAM_NUM)->num); 52 | psync_sql_bind_uint(res, 3, userid); 53 | psync_sql_bind_uint(res, 4, perms); 54 | psync_sql_bind_lstring(res, 5, name->str, name->length); 55 | psync_sql_bind_uint(res, 6, psync_find_result(meta, "created", PARAM_NUM)->num); 56 | psync_sql_bind_uint(res, 7, psync_find_result(meta, "modified", PARAM_NUM)->num); 57 | psync_sql_bind_uint(res, 8, flags); 58 | psync_sql_run_free(res); 59 | } 60 | 61 | void psync_ops_update_folder_in_db(const binresult *meta){ 62 | psync_diff_update_folder(meta); 63 | } 64 | 65 | void psync_ops_delete_folder_from_db(const binresult *meta){ 66 | psync_diff_delete_folder(meta); 67 | } 68 | 69 | void psync_ops_create_file_in_db(const binresult *meta){ 70 | psync_diff_create_file(meta); 71 | } 72 | 73 | void psync_ops_update_file_in_db(const binresult *meta){ 74 | psync_diff_update_file(meta); 75 | } 76 | 77 | void psync_ops_delete_file_from_db(const binresult *meta){ 78 | psync_diff_delete_file(meta); 79 | } 80 | -------------------------------------------------------------------------------- /pfileops.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2013-2014 Anton Titov. 2 | * Copyright (c) 2013-2014 pCloud Ltd. 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * * Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * * Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * * Neither the name of pCloud Ltd nor the 13 | * names of its contributors may be used to endorse or promote products 14 | * derived from this software without specific prior written permission. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | * DISCLAIMED. IN NO EVENT SHALL pCloud Ltd BE LIABLE FOR ANY 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | #ifndef _PSYNC_FILEOPS_H 29 | #define _PSYNC_FILEOPS_H 30 | 31 | #include "pcompiler.h" 32 | #include "papi.h" 33 | #include "psettings.h" 34 | #include "psynclib.h" 35 | 36 | #define PSYNC_INVALID_FOLDERID ((psync_folderid_t)-1) 37 | #define PSYNC_INVALID_PATH NULL 38 | 39 | static inline uint64_t psync_get_permissions(const binresult *meta){ 40 | return 41 | (psync_find_result(meta, "canread", PARAM_BOOL)->num?PSYNC_PERM_READ:0)+ 42 | (psync_find_result(meta, "canmodify", PARAM_BOOL)->num?PSYNC_PERM_MODIFY:0)+ 43 | (psync_find_result(meta, "candelete", PARAM_BOOL)->num?PSYNC_PERM_DELETE:0)+ 44 | (psync_find_result(meta, "cancreate", PARAM_BOOL)->num?PSYNC_PERM_CREATE:0); 45 | } 46 | 47 | void psync_ops_create_folder_in_db(const binresult *meta); 48 | void psync_ops_update_folder_in_db(const binresult *meta); 49 | void psync_ops_delete_folder_from_db(const binresult *meta); 50 | void psync_ops_create_file_in_db(const binresult *meta); 51 | void psync_ops_update_file_in_db(const binresult *meta); 52 | void psync_ops_delete_file_from_db(const binresult *meta); 53 | 54 | #endif -------------------------------------------------------------------------------- /pfolder.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2013-2014 Anton Titov. 2 | * Copyright (c) 2013-2014 pCloud Ltd. 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * * Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * * Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * * Neither the name of pCloud Ltd nor the 13 | * names of its contributors may be used to endorse or promote products 14 | * derived from this software without specific prior written permission. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | * DISCLAIMED. IN NO EVENT SHALL pCloud Ltd BE LIABLE FOR ANY 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | #ifndef _PSYNC_FOLDER_H 29 | #define _PSYNC_FOLDER_H 30 | 31 | #include "pcompiler.h" 32 | #include "psynclib.h" 33 | 34 | #define PSYNC_INVALID_FOLDERID ((psync_folderid_t)-1) 35 | #define PSYNC_INVALID_PATH NULL 36 | 37 | #define PSYNC_FOLDER_FLAG_ENCRYPTED 1 38 | #define PSYNC_FOLDER_FLAG_INVISIBLE 2 39 | 40 | psync_folderid_t psync_get_folderid_by_path(const char *path) PSYNC_NONNULL(1) PSYNC_PURE; 41 | psync_folderid_t psync_get_folderid_by_path_or_create(const char *path) PSYNC_NONNULL(1); 42 | char *psync_get_path_by_folderid(psync_folderid_t folderid, size_t *retlen); 43 | char *psync_get_path_by_folderid_sep(psync_folderid_t folderid, const char *sep, size_t *retlen); 44 | char *psync_get_path_by_fileid(psync_fileid_t fileid, size_t *retlen); 45 | char *psync_local_path_for_local_folder(psync_folderid_t localfolderid, psync_syncid_t syncid, size_t *retlen); 46 | char *psync_local_path_for_local_file(psync_fileid_t localfileid, size_t *retlen); 47 | //char *psync_local_path_for_remote_folder(psync_folderid_t folderid, psync_syncid_t syncid, size_t *retlen); 48 | //char *psync_local_path_for_remote_file(psync_fileid_t fileid, psync_syncid_t syncid, size_t *retlen); 49 | //char *psync_local_path_for_remote_file_or_folder_by_name(psync_folderid_t parentfolderid, const char *filename, psync_syncid_t syncid, size_t *retlen); 50 | pfolder_list_t *psync_list_remote_folder(psync_folderid_t folderid, psync_listtype_t listtype); 51 | pfolder_list_t *psync_list_local_folder(const char *path, psync_listtype_t listtype) PSYNC_NONNULL(1); 52 | pentry_t *psync_folder_stat_path(const char *remotepath); 53 | 54 | psync_folder_list_t *psync_list_get_list(); 55 | 56 | #endif 57 | -------------------------------------------------------------------------------- /pfs.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2013-2014 Anton Titov. 2 | * Copyright (c) 2013-2014 pCloud Ltd. 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * * Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * * Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * * Neither the name of pCloud Ltd nor the 13 | * names of its contributors may be used to endorse or promote products 14 | * derived from this software without specific prior written permission. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | * DISCLAIMED. IN NO EVENT SHALL pCloud Ltd BE LIABLE FOR ANY 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | #ifndef _PSYNC_FS_H 29 | #define _PSYNC_FS_H 30 | 31 | #include "psynclib.h" 32 | #include "ptree.h" 33 | #include "pintervaltree.h" 34 | #include "papi.h" 35 | #include "psettings.h" 36 | #include "pfsfolder.h" 37 | #include "pfstasks.h" 38 | #include "pcompat.h" 39 | #include "pcrypto.h" 40 | #include "pcrc32c.h" 41 | #include 42 | 43 | #if defined(P_OS_POSIX) 44 | #define psync_fs_need_per_folder_refresh() psync_fs_need_per_folder_refresh_f() 45 | #define psync_fs_need_per_folder_refresh_const() 1 46 | #else 47 | #define psync_fs_need_per_folder_refresh() (psync_invalidate_os_cache_needed() && psync_fs_need_per_folder_refresh_f()) 48 | #define psync_fs_need_per_folder_refresh_const() 1 49 | #endif 50 | 51 | extern char *psync_fake_prefix; 52 | extern size_t psync_fake_prefix_len; 53 | 54 | typedef struct { 55 | uint64_t frompage; 56 | uint64_t topage; 57 | uint64_t length; 58 | uint64_t requestedto; 59 | uint64_t id; 60 | time_t lastuse; 61 | } psync_file_stream_t; 62 | 63 | typedef struct { 64 | pthread_cond_t cond; 65 | uint64_t extendto; 66 | uint64_t extendedto; 67 | uint32_t waiters; 68 | int error; 69 | unsigned char ready; 70 | unsigned char kill; 71 | } psync_enc_file_extender_t; 72 | 73 | typedef struct { 74 | psync_tree tree; 75 | psync_file_stream_t streams[PSYNC_FS_FILESTREAMS_CNT]; 76 | pthread_mutex_t mutex; 77 | psync_interval_tree_t *writeintervals; 78 | psync_fstask_folder_t *currentfolder; 79 | char *currentname; 80 | psync_fsfileid_t fileid; 81 | psync_fsfileid_t remotefileid; 82 | union { 83 | uint64_t hash; 84 | const char *staticdata; 85 | }; 86 | uint64_t initialsize; 87 | uint64_t currentsize; 88 | uint64_t laststreamid; 89 | uint64_t indexoff; 90 | union { 91 | uint64_t writeid; 92 | time_t staticctime; 93 | }; 94 | time_t currentsec; 95 | time_t origctime; 96 | psync_file_t datafile; 97 | psync_file_t indexfile; 98 | uint32_t refcnt; 99 | uint32_t condwaiters; 100 | uint32_t runningreads; 101 | uint32_t currentspeed; 102 | uint32_t bytesthissec; 103 | unsigned char modified; 104 | unsigned char newfile; 105 | unsigned char releasedforupload; 106 | unsigned char deleted; 107 | unsigned char encrypted; 108 | unsigned char throttle; 109 | unsigned char staticfile; 110 | /* 111 | * for non-encrypted files only offsetof(psync_openfile_t, encoder) bytes are allocated 112 | * keep all fields for encryption after encoder 113 | */ 114 | psync_crypto_aes256_sector_encoder_decoder_t encoder; 115 | psync_tree *sectorsinlog; 116 | psync_interval_tree_t *authenticatedints; 117 | psync_fast_hash256_ctx loghashctx; 118 | psync_enc_file_extender_t *extender; 119 | psync_file_t logfile; 120 | uint32_t logoffset; 121 | } psync_openfile_t; 122 | 123 | typedef struct { 124 | uint64_t offset; 125 | uint64_t length; 126 | } psync_fs_index_record; 127 | 128 | typedef struct { 129 | int dummy[0]; 130 | } psync_fs_index_header; 131 | 132 | int psync_fs_crypto_err_to_errno(int cryptoerr); 133 | int psync_fs_update_openfile(uint64_t taskid, uint64_t writeid, psync_fileid_t newfileid, uint64_t hash, uint64_t size, time_t ctime); 134 | //void psync_fs_uploading_openfile(uint64_t taskid); 135 | int psync_fs_rename_openfile_locked(psync_fsfileid_t fileid, psync_fsfolderid_t folderid, const char *name); 136 | void psync_fs_mark_openfile_deleted(uint64_t taskid); 137 | int64_t psync_fs_get_file_writeid(uint64_t taskid); 138 | int64_t psync_fs_load_interval_tree(psync_file_t fd, uint64_t size, psync_interval_tree_t **tree); 139 | int psync_fs_remount(); 140 | void psync_fs_inc_of_refcnt_locked(psync_openfile_t *of); 141 | void psync_fs_inc_of_refcnt(psync_openfile_t *of); 142 | void psync_fs_dec_of_refcnt(psync_openfile_t *of); 143 | void psync_fs_inc_of_refcnt_and_readers(psync_openfile_t *of); 144 | void psync_fs_dec_of_refcnt_and_readers(psync_openfile_t *of); 145 | 146 | void psync_fs_refresh(); 147 | int psync_fs_need_per_folder_refresh_f(); 148 | void psync_fs_refresh_folder(psync_folderid_t folderid); 149 | 150 | void psync_fs_pause_until_login(); 151 | void psync_fs_clean_tasks(); 152 | 153 | #endif 154 | -------------------------------------------------------------------------------- /pfscrypto.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2014 Anton Titov. 2 | * Copyright (c) 2014 pCloud Ltd. 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * * Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * * Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * * Neither the name of pCloud Ltd nor the 13 | * names of its contributors may be used to endorse or promote products 14 | * derived from this software without specific prior written permission. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | * DISCLAIMED. IN NO EVENT SHALL pCloud Ltd BE LIABLE FOR ANY 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | #ifndef _PSYNC_FSCRYPTO_H 29 | #define _PSYNC_FSCRYPTO_H 30 | 31 | #include "pfs.h" 32 | #include "pcloudcrypto.h" 33 | 34 | #define PSYNC_CRYPTO_MAX_SECTORID (UINT32_MAX-1) 35 | #define PSYNC_CRYPTO_INVALID_SECTORID (UINT32_MAX) 36 | 37 | #define PSYNC_CRYPTO_HASH_TREE_SECTORS (PSYNC_CRYPTO_SECTOR_SIZE/PSYNC_CRYPTO_AUTH_SIZE) 38 | 39 | typedef uint32_t psync_crypto_sectorid_t; 40 | typedef int32_t psync_crypto_sectorid_diff_t; 41 | 42 | typedef struct { 43 | psync_tree tree; 44 | psync_crypto_sectorid_t sectorid; 45 | uint32_t logoffset; 46 | psync_crypto_sector_auth_t auth; 47 | } psync_sector_inlog_t; 48 | 49 | typedef psync_crypto_sector_auth_t psync_crypto_auth_sector_t[PSYNC_CRYPTO_HASH_TREE_SECTORS]; 50 | 51 | int psync_fs_crypto_init_log(psync_openfile_t *of); 52 | int psync_fs_crypto_read_newfile_locked(psync_openfile_t *of, char *buf, uint64_t size, uint64_t offset); 53 | int psync_fs_crypto_write_newfile_locked(psync_openfile_t *of, const char *buf, uint64_t size, uint64_t offset); 54 | int psync_fs_crypto_read_modified_locked(psync_openfile_t *of, char *buf, uint64_t size, uint64_t offset); 55 | int psync_fs_crypto_write_modified_locked(psync_openfile_t *of, const char *buf, uint64_t size, uint64_t offset); 56 | int psync_fs_crypto_ftruncate(psync_openfile_t *of, uint64_t size); 57 | int psync_fs_crypto_flush_file(psync_openfile_t *of); 58 | 59 | psync_crypto_sectorid_t psync_fs_crypto_data_sectorid_by_sectorid(psync_crypto_sectorid_t sectorid); 60 | void psync_fs_crypto_offsets_by_plainsize(uint64_t size, psync_crypto_offsets_t *offsets); 61 | uint64_t psync_fs_crypto_plain_size(uint64_t cryptosize); 62 | uint64_t psync_fs_crypto_crypto_size(uint64_t plainsize); 63 | void psync_fs_crypto_get_auth_sector_off(psync_crypto_sectorid_t sectorid, uint32_t level, psync_crypto_offsets_t *offsets, 64 | uint64_t *offset, uint32_t *size, uint32_t *authid); 65 | 66 | void psync_fs_crypto_check_logs(); 67 | 68 | #endif 69 | -------------------------------------------------------------------------------- /pfsfake.c: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2013-2014 Anton Titov. 2 | * Copyright (c) 2013-2014 pCloud Ltd. 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * * Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * * Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * * Neither the name of pCloud Ltd nor the 13 | * names of its contributors may be used to endorse or promote products 14 | * derived from this software without specific prior written permission. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | * DISCLAIMED. IN NO EVENT SHALL pCloud Ltd BE LIABLE FOR ANY 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | #include "psynclib.h" 29 | 30 | int psync_fs_remount(){ 31 | return 0; 32 | } 33 | 34 | int psync_fs_isstarted(){ 35 | return 0; 36 | } 37 | 38 | int psync_fs_start(){ 39 | return -1; 40 | } 41 | 42 | void psync_fs_stop(){ 43 | } 44 | 45 | char *psync_fs_getmountpoint(){ 46 | return NULL; 47 | } 48 | 49 | char *psync_fs_get_path_by_folderid(psync_folderid_t folderid){ 50 | return NULL; 51 | } 52 | 53 | void psync_fs_refresh(){ 54 | } 55 | 56 | void psync_fs_file_deleted(psync_fileid_t fileid){ 57 | } 58 | 59 | void psync_fs_folder_deleted(psync_folderid_t folderid){ 60 | } 61 | 62 | void psync_fs_task_deleted(uint64_t taskid){ 63 | } 64 | 65 | int psync_fs_need_per_folder_refresh_f(){ 66 | return 0; 67 | } 68 | 69 | void psync_fs_refresh_folder(psync_folderid_t folderid){ 70 | } 71 | 72 | void psync_pagecache_resize_cache(){ 73 | } 74 | 75 | int psync_cloud_crypto_setup(const char *password){ 76 | return PSYNC_CRYPTO_SETUP_NOT_SUPPORTED; 77 | } 78 | 79 | void psync_pagecache_clean_cache(){ 80 | } 81 | 82 | void psync_fs_pause_until_login(){ 83 | } 84 | 85 | void psync_fs_clean_tasks(){ 86 | } 87 | -------------------------------------------------------------------------------- /pfsfolder.c: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2014 Anton Titov. 2 | * Copyright (c) 2014 pCloud Ltd. 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * * Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * * Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * * Neither the name of pCloud Ltd nor the 13 | * names of its contributors may be used to endorse or promote products 14 | * derived from this software without specific prior written permission. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | * DISCLAIMED. IN NO EVENT SHALL pCloud Ltd BE LIABLE FOR ANY 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | #include "pfsfolder.h" 29 | #include "plibs.h" 30 | #include "psettings.h" 31 | #include "pfstasks.h" 32 | #include "pfolder.h" 33 | #include "pcloudcrypto.h" 34 | #include "pfs.h" 35 | #include 36 | 37 | static PSYNC_THREAD int cryptoerr=0; 38 | 39 | static char *get_encname_for_folder(psync_fsfolderid_t folderid, const char *path, size_t len){ 40 | char *name, *encname; 41 | psync_crypto_aes256_text_encoder_t enc; 42 | enc=psync_cloud_crypto_get_folder_encoder(folderid); 43 | if (psync_crypto_is_error(enc)){ 44 | cryptoerr=psync_crypto_to_error(enc); 45 | return NULL; 46 | } 47 | name=psync_strndup(path, len); 48 | encname=psync_cloud_crypto_encode_filename(enc, name); 49 | psync_cloud_crypto_release_folder_encoder(folderid, enc); 50 | psync_free(name); 51 | return encname; 52 | } 53 | 54 | static psync_fspath_t *ret_folder_data(psync_fsfolderid_t folderid, const char *name, uint32_t permissions, uint32_t flags, uint32_t shareid){ 55 | psync_fspath_t *ret; 56 | if (flags&PSYNC_FOLDER_FLAG_ENCRYPTED && strncmp(psync_fake_prefix, name, psync_fake_prefix_len)){ 57 | psync_crypto_aes256_text_encoder_t enc; 58 | char *encname; 59 | size_t len; 60 | enc=psync_cloud_crypto_get_folder_encoder(folderid); 61 | if (psync_crypto_is_error(enc)){ 62 | cryptoerr=psync_crypto_to_error(enc); 63 | return NULL; 64 | } 65 | encname=psync_cloud_crypto_encode_filename(enc, name); 66 | psync_cloud_crypto_release_folder_encoder(folderid, enc); 67 | len=strlen(encname); 68 | ret=(psync_fspath_t *)psync_malloc(sizeof(psync_fspath_t)+len+1); 69 | memcpy(ret+1, encname, len+1); 70 | psync_free(encname); 71 | ret->folderid=folderid; 72 | ret->name=(char *)(ret+1); 73 | ret->shareid=shareid; 74 | ret->permissions=permissions; 75 | ret->flags=flags; 76 | } 77 | else{ 78 | ret=psync_new(psync_fspath_t); 79 | ret->folderid=folderid; 80 | ret->name=name; 81 | ret->shareid=shareid; 82 | ret->permissions=permissions; 83 | ret->flags=flags; 84 | } 85 | return ret; 86 | } 87 | 88 | PSYNC_NOINLINE void do_check_userid(uint64_t userid, uint64_t folderid, uint32_t *shareid){ 89 | psync_sql_res *res; 90 | psync_uint_row row; 91 | res=psync_sql_query_rdlock("SELECT id FROM sharedfolder WHERE userid=? AND folderid=?"); 92 | psync_sql_bind_uint(res, 1, userid); 93 | psync_sql_bind_uint(res, 2, folderid); 94 | if ((row=psync_sql_fetch_rowint(res))) 95 | *shareid=row[0]; 96 | else 97 | debug(D_WARNING, "came up to a folder %lu owned by userid %lu but can't find it in sharedfolder", (unsigned long)folderid, (unsigned long)userid); 98 | psync_sql_free_result(res); 99 | } 100 | 101 | static void check_userid(uint64_t userid, uint64_t folderid, uint32_t *shareid){ 102 | if (userid==psync_my_userid || *shareid) 103 | return; 104 | else 105 | do_check_userid(userid, folderid, shareid); 106 | } 107 | 108 | psync_fspath_t *psync_fsfolder_resolve_path(const char *path){ 109 | psync_fsfolderid_t cfolderid; 110 | const char *sl; 111 | psync_fstask_folder_t *folder; 112 | psync_fstask_mkdir_t *mk; 113 | psync_sql_res *res; 114 | psync_uint_row row; 115 | char *ename; 116 | size_t len, elen; 117 | uint32_t permissions, flags, shareid; 118 | int hasit; 119 | cryptoerr=0; 120 | res=NULL; 121 | if (*path!='/') 122 | return NULL; 123 | cfolderid=0; 124 | shareid=0; 125 | permissions=PSYNC_PERM_ALL; 126 | flags=0; 127 | while (1){ 128 | while (*path=='/') 129 | path++; 130 | if (*path==0){ 131 | if (res) 132 | psync_sql_free_result(res); 133 | return NULL; 134 | } 135 | sl=strchr(path, '/'); 136 | if (sl) 137 | len=sl-path; 138 | else{ 139 | if (res) 140 | psync_sql_free_result(res); 141 | return ret_folder_data(cfolderid, path, permissions, flags, shareid); 142 | } 143 | if (!res) 144 | res=psync_sql_query_rdlock("SELECT id, permissions, flags, userid FROM folder WHERE parentfolderid=? AND name=?"); 145 | else 146 | psync_sql_reset(res); 147 | psync_sql_bind_int(res, 1, cfolderid); 148 | if (flags&PSYNC_FOLDER_FLAG_ENCRYPTED){ 149 | ename=get_encname_for_folder(cfolderid, path, len); 150 | if (!ename) 151 | break; 152 | elen=strlen(ename); 153 | psync_sql_bind_lstring(res, 2, ename, elen); 154 | } 155 | else{ 156 | psync_sql_bind_lstring(res, 2, path, len); 157 | ename=(char *)path; 158 | elen=len; 159 | } 160 | row=psync_sql_fetch_rowint(res); 161 | folder=psync_fstask_get_folder_tasks_rdlocked(cfolderid); 162 | if (folder){ 163 | char *name=psync_strndup(ename, elen); 164 | if ((mk=psync_fstask_find_mkdir(folder, name, 0))){ 165 | if (mk->flags&PSYNC_FOLDER_FLAG_INVISIBLE){ 166 | psync_free(name); 167 | break; 168 | } 169 | cfolderid=mk->folderid; 170 | flags=mk->flags; 171 | hasit=1; 172 | } 173 | else if (row && !psync_fstask_find_rmdir(folder, name, 0)){ 174 | cfolderid=row[0]; 175 | permissions&=row[1]; 176 | flags=row[2]; 177 | hasit=1; 178 | check_userid(row[3], row[0], &shareid); 179 | } 180 | else 181 | hasit=0; 182 | psync_free(name); 183 | } 184 | else{ 185 | if (row){ 186 | cfolderid=row[0]; 187 | permissions=row[1]; 188 | flags=row[2]; 189 | check_userid(row[3], row[0], &shareid); 190 | hasit=1; 191 | } 192 | else 193 | hasit=0; 194 | } 195 | if (ename!=path) 196 | psync_free(ename); 197 | if (!hasit) 198 | break; 199 | path+=len; 200 | } 201 | if (res) 202 | psync_sql_free_result(res); 203 | return NULL; 204 | } 205 | 206 | psync_fsfolderid_t psync_fsfolderid_by_path(const char *path, uint32_t *pflags){ 207 | psync_fsfolderid_t cfolderid; 208 | const char *sl; 209 | psync_fstask_folder_t *folder; 210 | psync_fstask_mkdir_t *mk; 211 | psync_sql_res *res; 212 | psync_uint_row row; 213 | char *ename; 214 | size_t len, elen; 215 | uint32_t flags; 216 | int hasit; 217 | res=NULL; 218 | cryptoerr=0; 219 | if (*path!='/') 220 | return PSYNC_INVALID_FSFOLDERID; 221 | cfolderid=0; 222 | flags=0; 223 | while (1){ 224 | while (*path=='/') 225 | path++; 226 | if (*path==0){ 227 | if (res) 228 | psync_sql_free_result(res); 229 | if (pflags) 230 | *pflags=flags; 231 | return cfolderid; 232 | } 233 | sl=strchr(path, '/'); 234 | if (sl) 235 | len=sl-path; 236 | else 237 | len=strlen(path); 238 | if (!res) 239 | res=psync_sql_query_rdlock("SELECT id, flags FROM folder WHERE parentfolderid=? AND name=?"); 240 | else 241 | psync_sql_reset(res); 242 | psync_sql_bind_int(res, 1, cfolderid); 243 | if (flags&PSYNC_FOLDER_FLAG_ENCRYPTED){ 244 | ename=get_encname_for_folder(cfolderid, path, len); 245 | if (!ename) 246 | break; 247 | elen=strlen(ename); 248 | psync_sql_bind_lstring(res, 2, ename, elen); 249 | } 250 | else{ 251 | psync_sql_bind_lstring(res, 2, path, len); 252 | ename=(char *)path; 253 | elen=len; 254 | } 255 | row=psync_sql_fetch_rowint(res); 256 | folder=psync_fstask_get_folder_tasks_locked(cfolderid); 257 | if (folder){ 258 | char *name=psync_strndup(ename, elen); 259 | if ((mk=psync_fstask_find_mkdir(folder, name, 0))){ 260 | cfolderid=mk->folderid; 261 | flags=mk->flags; 262 | hasit=1; 263 | } 264 | else if (row && !psync_fstask_find_rmdir(folder, name, 0)){ 265 | cfolderid=row[0]; 266 | flags=row[1]; 267 | hasit=1; 268 | } 269 | else 270 | hasit=0; 271 | psync_fstask_release_folder_tasks_locked(folder); 272 | psync_free(name); 273 | } 274 | else{ 275 | if (row){ 276 | cfolderid=row[0]; 277 | flags=row[1]; 278 | hasit=1; 279 | } 280 | else 281 | hasit=0; 282 | } 283 | if (ename!=path) 284 | psync_free(ename); 285 | if (!hasit) 286 | break; 287 | path+=len; 288 | } 289 | if (res) 290 | psync_sql_free_result(res); 291 | return PSYNC_INVALID_FSFOLDERID; 292 | } 293 | 294 | int psync_fsfolder_crypto_error(){ 295 | return cryptoerr; 296 | } -------------------------------------------------------------------------------- /pfsfolder.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2014 Anton Titov. 2 | * Copyright (c) 2014 pCloud Ltd. 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * * Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * * Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * * Neither the name of pCloud Ltd nor the 13 | * names of its contributors may be used to endorse or promote products 14 | * derived from this software without specific prior written permission. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | * DISCLAIMED. IN NO EVENT SHALL pCloud Ltd BE LIABLE FOR ANY 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | #ifndef _PSYNC_FSFOLDER_H 29 | #define _PSYNC_FSFOLDER_H 30 | 31 | #include 32 | #include 33 | 34 | typedef int64_t psync_fsfolderid_t; 35 | typedef int64_t psync_fsfileid_t; 36 | 37 | #define PSYNC_INVALID_FSFOLDERID INT64_MIN 38 | 39 | typedef struct { 40 | psync_fsfolderid_t folderid; 41 | const char *name; 42 | uint32_t shareid; 43 | uint16_t permissions; 44 | uint16_t flags; 45 | } psync_fspath_t; 46 | 47 | psync_fspath_t *psync_fsfolder_resolve_path(const char *path); 48 | psync_fsfolderid_t psync_fsfolderid_by_path(const char *path, uint32_t *pflags); 49 | int psync_fsfolder_crypto_error(); 50 | 51 | 52 | #endif -------------------------------------------------------------------------------- /pfsstatic.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2014 Anton Titov. 2 | * Copyright (c) 2014 pCloud Ltd. 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * * Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * * Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * * Neither the name of pCloud Ltd nor the 13 | * names of its contributors may be used to endorse or promote products 14 | * derived from this software without specific prior written permission. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | * DISCLAIMED. IN NO EVENT SHALL pCloud Ltd BE LIABLE FOR ANY 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | #ifndef _PSYNC_FSSTATIC_H 29 | #define _PSYNC_FSSTATIC_H 30 | 31 | void psync_fsstatic_add_files(); 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /pfstasks.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2014 Anton Titov. 2 | * Copyright (c) 2014 pCloud Ltd. 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * * Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * * Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * * Neither the name of pCloud Ltd nor the 13 | * names of its contributors may be used to endorse or promote products 14 | * derived from this software without specific prior written permission. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | * DISCLAIMED. IN NO EVENT SHALL pCloud Ltd BE LIABLE FOR ANY 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | #ifndef _PSYNC_FSTASKS_H 29 | #define _PSYNC_FSTASKS_H 30 | 31 | #include "pfsfolder.h" 32 | #include "ptree.h" 33 | #include "psynclib.h" 34 | #include 35 | #include 36 | #include 37 | 38 | #define PSYNC_FS_TASK_MKDIR 1 39 | #define PSYNC_FS_TASK_RMDIR 2 40 | #define PSYNC_FS_TASK_CREAT 3 41 | #define PSYNC_FS_TASK_UNLINK 4 42 | #define PSYNC_FS_TASK_RENFILE_FROM 5 43 | #define PSYNC_FS_TASK_RENFILE_TO 6 44 | #define PSYNC_FS_TASK_RENFOLDER_FROM 7 45 | #define PSYNC_FS_TASK_RENFOLDER_TO 8 46 | #define PSYNC_FS_TASK_MODIFY 9 47 | #define PSYNC_FS_TASK_UN_SET_REV 10 48 | 49 | typedef struct { 50 | psync_tree tree; 51 | psync_fsfolderid_t folderid; 52 | uint64_t taskid; 53 | time_t ctime; 54 | time_t mtime; 55 | uint32_t subdircnt; 56 | uint32_t flags; 57 | char name[]; 58 | } psync_fstask_mkdir_t; 59 | 60 | typedef struct { 61 | psync_tree tree; 62 | psync_fsfolderid_t folderid; 63 | uint64_t taskid; 64 | char name[]; 65 | } psync_fstask_rmdir_t; 66 | 67 | typedef struct { 68 | psync_tree tree; 69 | psync_fsfileid_t fileid; 70 | uint64_t taskid; 71 | char name[]; 72 | } psync_fstask_creat_t; 73 | 74 | typedef struct { 75 | const void *data; 76 | size_t datalen; 77 | time_t ctime; 78 | } psync_fstask_local_creat_t; 79 | 80 | typedef struct { 81 | psync_tree tree; 82 | psync_fsfileid_t fileid; 83 | uint64_t taskid; 84 | char name[]; 85 | } psync_fstask_unlink_t; 86 | 87 | typedef struct { 88 | psync_tree tree; 89 | psync_fsfolderid_t folderid; 90 | psync_tree *mkdirs; 91 | psync_tree *rmdirs; 92 | psync_tree *creats; 93 | psync_tree *unlinks; 94 | uint32_t taskscnt; 95 | uint32_t refcnt; 96 | } psync_fstask_folder_t; 97 | 98 | static inline size_t psync_fstask_creat_local_offset(size_t namelen){ 99 | return (offsetof(psync_fstask_creat_t, name)+namelen+psync_alignof(psync_fstask_local_creat_t))/ 100 | psync_alignof(psync_fstask_local_creat_t)*psync_alignof(psync_fstask_local_creat_t); 101 | } 102 | 103 | static inline psync_fstask_local_creat_t *psync_fstask_creat_len_get_local(psync_fstask_creat_t *cr, size_t namelen){ 104 | return (psync_fstask_local_creat_t *)(((char *)cr)+psync_fstask_creat_local_offset(namelen)); 105 | } 106 | 107 | static inline psync_fstask_local_creat_t *psync_fstask_creat_get_local(psync_fstask_creat_t *cr){ 108 | return psync_fstask_creat_len_get_local(cr, strlen(cr->name)); 109 | } 110 | 111 | void psync_fstask_init(); 112 | 113 | psync_fstask_folder_t *psync_fstask_get_or_create_folder_tasks(psync_fsfolderid_t folderid); 114 | psync_fstask_folder_t *psync_fstask_get_folder_tasks(psync_fsfolderid_t folderid); 115 | void psync_fstask_release_folder_tasks(psync_fstask_folder_t *folder); 116 | psync_fstask_folder_t *psync_fstask_get_ref_locked(psync_fstask_folder_t *folder); 117 | psync_fstask_folder_t *psync_fstask_get_or_create_folder_tasks_locked(psync_fsfolderid_t folderid); 118 | psync_fstask_folder_t *psync_fstask_get_folder_tasks_locked(psync_fsfolderid_t folderid); 119 | psync_fstask_folder_t *psync_fstask_get_folder_tasks_rdlocked(psync_fsfolderid_t folderid); 120 | void psync_fstask_release_folder_tasks_locked(psync_fstask_folder_t *folder); 121 | 122 | void psync_fstask_folder_created(psync_folderid_t parentfolderid, uint64_t taskid, psync_folderid_t folderid, const char *name); 123 | void psync_fstask_folder_deleted(psync_folderid_t parentfolderid, uint64_t taskid, const char *name); 124 | void psync_fstask_file_created(psync_folderid_t parentfolderid, uint64_t taskid, const char *name, psync_fileid_t fileid); 125 | void psync_fstask_file_modified(psync_folderid_t parentfolderid, uint64_t taskid, const char *name, psync_fileid_t fileid); 126 | void psync_fstask_file_deleted(psync_folderid_t parentfolderid, uint64_t taskid, const char *name); 127 | void psync_fstask_file_renamed(psync_folderid_t folderid, uint64_t taskid, const char *name, uint64_t frtaskid); 128 | void psync_fstask_folder_renamed(psync_folderid_t parentfolderid, uint64_t taskid, const char *name, uint64_t frtaskid); 129 | 130 | psync_fstask_mkdir_t *psync_fstask_find_mkdir(psync_fstask_folder_t *folder, const char *name, uint64_t taskid); 131 | psync_fstask_rmdir_t *psync_fstask_find_rmdir(psync_fstask_folder_t *folder, const char *name, uint64_t taskid); 132 | psync_fstask_creat_t *psync_fstask_find_creat(psync_fstask_folder_t *folder, const char *name, uint64_t taskid); 133 | psync_fstask_unlink_t *psync_fstask_find_unlink(psync_fstask_folder_t *folder, const char *name, uint64_t taskid); 134 | 135 | psync_fstask_mkdir_t *psync_fstask_find_mkdir_by_folderid(psync_fstask_folder_t *folder, psync_fsfolderid_t folderid); 136 | psync_fstask_creat_t *psync_fstask_find_creat_by_fileid(psync_fstask_folder_t *folder, psync_fsfileid_t fileid); 137 | 138 | int psync_fstask_mkdir(psync_fsfolderid_t folderid, const char *name, uint32_t folderflags); 139 | int psync_fstask_can_rmdir(psync_fsfolderid_t folderid, const char *name); 140 | int psync_fstask_rmdir(psync_fsfolderid_t folderid, const char *name); 141 | psync_fstask_creat_t *psync_fstask_add_creat(psync_fstask_folder_t *folder, const char *name, const char *encsymkey, size_t encsymkeylen); 142 | void psync_fstask_inject_creat(psync_fstask_folder_t *folder, psync_fstask_creat_t *cr); 143 | void psync_fstask_inject_unlink(psync_fstask_folder_t *folder, psync_fstask_unlink_t *un); 144 | psync_fstask_creat_t *psync_fstask_add_modified_file(psync_fstask_folder_t *folder, const char *name, psync_fsfileid_t fileid, 145 | uint64_t hash, const char *encsymkey, size_t encsymkeylen); 146 | 147 | int psync_fstask_add_local_creat_static(psync_fsfolderid_t folderid, const char *name, const void *data, size_t datalen); 148 | 149 | 150 | int psync_fstask_can_unlink(psync_fsfolderid_t folderid, const char *name); 151 | int psync_fstask_unlink(psync_fsfolderid_t folderid, const char *name); 152 | int psync_fstask_rename_file(psync_fsfileid_t fileid, psync_fsfolderid_t parentfolderid, const char *name, psync_fsfolderid_t to_folderid, const char *new_name); 153 | int psync_fstask_rename_folder(psync_fsfolderid_t folderid, psync_fsfolderid_t parentfolderid, const char *name, psync_fsfolderid_t to_folderid, 154 | const char *new_name, uint32_t targetflags); 155 | 156 | void psync_fstask_clean(); 157 | 158 | void psync_fstask_add_banned_folders(); 159 | 160 | #endif 161 | -------------------------------------------------------------------------------- /pfsupload.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2014 Anton Titov. 2 | * Copyright (c) 2014 pCloud Ltd. 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * * Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * * Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * * Neither the name of pCloud Ltd nor the 13 | * names of its contributors may be used to endorse or promote products 14 | * derived from this software without specific prior written permission. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | * DISCLAIMED. IN NO EVENT SHALL pCloud Ltd BE LIABLE FOR ANY 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | #ifndef _PSYNC_FSUPLOAD_H 29 | #define _PSYNC_FSUPLOAD_H 30 | 31 | #include "psynclib.h" 32 | 33 | void psync_fsupload_init(); 34 | void psync_fsupload_wake(); 35 | void psync_fsupload_stop_upload_locked(uint64_t taskid); 36 | int psync_fsupload_in_current_small_uploads_batch_locked(uint64_t taskid); 37 | 38 | #endif -------------------------------------------------------------------------------- /pfsxattr.h: -------------------------------------------------------------------------------- 1 | #ifndef _PSYNC_FSXATTR_H 2 | #define _PSYNC_FSXATTR_H 3 | 4 | #include "pcompat.h" 5 | #include "psynclib.h" 6 | 7 | #if defined(P_OS_MACOSX) 8 | #define PFS_XATTR_IGN , uint32_t ign 9 | #else 10 | #define PFS_XATTR_IGN 11 | #endif 12 | 13 | int psync_fs_setxattr(const char *path, const char *name, const char *value, size_t size, int flags PFS_XATTR_IGN); 14 | int psync_fs_getxattr(const char *path, const char *name, char *value, size_t size PFS_XATTR_IGN); 15 | int psync_fs_listxattr(const char *path, char *list, size_t size); 16 | int psync_fs_removexattr(const char *path, const char *name); 17 | 18 | void psync_fs_file_deleted(psync_fileid_t fileid); 19 | void psync_fs_folder_deleted(psync_folderid_t folderid); 20 | void psync_fs_task_deleted(uint64_t taskid); 21 | 22 | void psync_fs_task_to_file(uint64_t taskid, psync_fileid_t fileid); 23 | void psync_fs_task_to_folder(uint64_t taskid, psync_folderid_t folderid); 24 | void psync_fs_static_to_task(uint64_t statictaskid, uint64_t taskid); 25 | void psync_fs_file_to_task(psync_fileid_t fileid, uint64_t taskid); 26 | 27 | #endif -------------------------------------------------------------------------------- /pintervaltree.c: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2014 Anton Titov. 2 | * Copyright (c) 2014 pCloud Ltd. 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * * Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * * Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * * Neither the name of pCloud Ltd nor the 13 | * names of its contributors may be used to endorse or promote products 14 | * derived from this software without specific prior written permission. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | * DISCLAIMED. IN NO EVENT SHALL pCloud Ltd BE LIABLE FOR ANY 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | #include "pintervaltree.h" 29 | #include "plibs.h" 30 | 31 | static psync_interval_tree_t *psync_interval_tree_new(uint64_t from, uint64_t to){ 32 | psync_interval_tree_t *tree=psync_new(psync_interval_tree_t); 33 | tree->from=from; 34 | tree->to=to; 35 | return psync_interval_tree_element(psync_tree_get_add_after(PSYNC_TREE_EMPTY, NULL, &tree->tree)); 36 | } 37 | 38 | static psync_interval_tree_t *psync_interval_new(uint64_t from, uint64_t to){ 39 | psync_interval_tree_t *tree=psync_new(psync_interval_tree_t); 40 | tree->from=from; 41 | tree->to=to; 42 | return tree; 43 | } 44 | 45 | static psync_interval_tree_t *psync_interval_tree_consume_intervals(psync_interval_tree_t *tree, psync_interval_tree_t *e){ 46 | psync_interval_tree_t *next; 47 | while ((next=psync_interval_tree_get_next(e))){ 48 | if (next->from>e->to) 49 | break; 50 | psync_interval_tree_del(&tree, next); 51 | if (next->to>=e->to){ 52 | e->to=next->to; 53 | psync_free(next); 54 | break; 55 | } 56 | psync_free(next); 57 | } 58 | return tree; 59 | } 60 | 61 | static psync_interval_tree_t *psync_interval_tree_get_add(psync_interval_tree_t *tree, uint64_t from, uint64_t to){ 62 | // debug(D_NOTICE, "adding interval %lu %lu", from, to); 63 | assert(to>from); 64 | if (unlikely(!tree)) 65 | return psync_interval_tree_new(from, to); 66 | else{ 67 | psync_interval_tree_t *e, *e2; 68 | e=tree; 69 | while (1){ 70 | assert(from<=to); 71 | if (e->from<=from && e->to>=from){ 72 | if (e->to>=to) 73 | return tree; 74 | e->to=to; 75 | return psync_interval_tree_consume_intervals(tree, e); 76 | } 77 | else if (e->from>from){ 78 | if (e->tree.left) 79 | e=psync_interval_tree_element(e->tree.left); 80 | else if (e->from<=to && e->to>=to){ 81 | e->from=from; 82 | return tree; 83 | } 84 | else{ 85 | e2=psync_interval_new(from, to); 86 | return psync_interval_tree_consume_intervals(psync_interval_tree_element(psync_tree_get_add_before(&tree->tree, &e->tree, &e2->tree)), e2); 87 | } 88 | } 89 | else{ 90 | assert(e->totree.right) 92 | e=psync_interval_tree_element(e->tree.right); 93 | else{ 94 | e2=psync_interval_new(from, to); 95 | return psync_interval_tree_consume_intervals(psync_interval_tree_element(psync_tree_get_add_after(&tree->tree, &e->tree, &e2->tree)), e2); 96 | } 97 | } 98 | } 99 | } 100 | } 101 | 102 | void psync_interval_tree_add(psync_interval_tree_t **tree, uint64_t from, uint64_t to){ 103 | *tree=psync_interval_tree_get_add(*tree, from, to); 104 | } 105 | 106 | void psync_interval_tree_remove(psync_interval_tree_t **tree, uint64_t from, uint64_t to){ 107 | psync_interval_tree_t *tr, *ntr; 108 | tr=psync_interval_tree_first_interval_containing_or_after(*tree, from); 109 | while (tr){ 110 | if (tr->fromto>to){ 111 | // the only case we have to split interval 112 | psync_tree_add_after((psync_tree **)tree, &tr->tree, &psync_interval_new(to, tr->to)->tree); 113 | tr->to=from; 114 | break; 115 | } 116 | ntr=psync_interval_tree_get_next(tr); 117 | if (from<=tr->from && tr->fromfrom=to; 119 | if (tr->from>=tr->to) 120 | psync_interval_tree_del(tree, tr); 121 | } 122 | else if (tr->fromto=from; 124 | else 125 | break; 126 | tr=ntr; 127 | } 128 | } 129 | 130 | void psync_interval_tree_free(psync_interval_tree_t *tree){ 131 | if (tree) 132 | psync_tree_for_each_element_call_safe(&tree->tree, psync_interval_tree_t, tree, psync_free); 133 | } 134 | 135 | static psync_interval_tree_t *psync_interval_tree_get_cut_end(psync_interval_tree_t *tree, uint64_t end){ 136 | psync_interval_tree_t *last, *prev; 137 | last=psync_interval_tree_get_last(tree); 138 | while (last && last->to>end){ 139 | if (last->fromto=end; 141 | break; 142 | } 143 | prev=psync_interval_tree_get_prev(last); 144 | tree=psync_interval_tree_element(psync_tree_get_del(&tree->tree, &last->tree)); 145 | psync_free(last); 146 | last=prev; 147 | } 148 | return tree; 149 | } 150 | 151 | void psync_interval_tree_cut_end(psync_interval_tree_t **tree, uint64_t end){ 152 | *tree=psync_interval_tree_get_cut_end(*tree, end); 153 | } 154 | -------------------------------------------------------------------------------- /pintervaltree.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2014 Anton Titov. 2 | * Copyright (c) 2014 pCloud Ltd. 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * * Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * * Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * * Neither the name of pCloud Ltd nor the 13 | * names of its contributors may be used to endorse or promote products 14 | * derived from this software without specific prior written permission. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | * DISCLAIMED. IN NO EVENT SHALL pCloud Ltd BE LIABLE FOR ANY 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | #ifndef _PSYNC_INTERVALTREE_H 29 | #define _PSYNC_INTERVALTREE_H 30 | 31 | #include "ptree.h" 32 | #include 33 | 34 | typedef struct { 35 | psync_tree tree; 36 | uint64_t from; 37 | uint64_t to; 38 | } psync_interval_tree_t; 39 | 40 | #define psync_interval_tree_element(a) psync_tree_element(a, psync_interval_tree_t, tree) 41 | #define psync_interval_tree_for_each(a, l) for (a=psync_interval_tree_get_first(l); a!=NULL; a=psync_interval_tree_get_next(a)) 42 | 43 | static inline psync_interval_tree_t *psync_interval_tree_get_first(psync_interval_tree_t *tree){ 44 | return psync_interval_tree_element(psync_tree_get_first(&tree->tree)); 45 | } 46 | 47 | static inline psync_interval_tree_t *psync_interval_tree_get_last(psync_interval_tree_t *tree){ 48 | return psync_interval_tree_element(psync_tree_get_last(&tree->tree)); 49 | } 50 | 51 | static inline psync_interval_tree_t *psync_interval_tree_get_next(psync_interval_tree_t *tree){ 52 | return psync_interval_tree_element(psync_tree_get_next(&tree->tree)); 53 | } 54 | 55 | static inline psync_interval_tree_t *psync_interval_tree_get_prev(psync_interval_tree_t *tree){ 56 | return psync_interval_tree_element(psync_tree_get_prev(&tree->tree)); 57 | } 58 | 59 | static inline void psync_interval_tree_del(psync_interval_tree_t **tree, psync_interval_tree_t *node){ 60 | *tree=psync_interval_tree_element(psync_tree_get_del(&(*tree)->tree, &node->tree)); 61 | } 62 | 63 | static inline psync_interval_tree_t *psync_interval_tree_first_interval_containing_or_after(psync_interval_tree_t *tree, uint64_t point){ 64 | while (tree){ 65 | if (point>=tree->to){ 66 | if (tree->tree.right) 67 | tree=psync_interval_tree_element(tree->tree.right); 68 | else{ 69 | tree=psync_interval_tree_get_next(tree); 70 | break; 71 | } 72 | } 73 | else if (point>=tree->from || !tree->tree.left) 74 | break; 75 | else 76 | tree=psync_interval_tree_element(tree->tree.left); 77 | } 78 | return tree; 79 | } 80 | 81 | void psync_interval_tree_add(psync_interval_tree_t **tree, uint64_t from, uint64_t to); 82 | void psync_interval_tree_remove(psync_interval_tree_t **tree, uint64_t from, uint64_t to); 83 | void psync_interval_tree_free(psync_interval_tree_t *tree); 84 | void psync_interval_tree_cut_end(psync_interval_tree_t **tree, uint64_t end); 85 | 86 | #endif 87 | -------------------------------------------------------------------------------- /plist.c: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2014 Anton Titov. 2 | * Copyright (c) 2014 pCloud Ltd. 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * * Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * * Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * * Neither the name of pCloud Ltd nor the 13 | * names of its contributors may be used to endorse or promote products 14 | * derived from this software without specific prior written permission. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | * DISCLAIMED. IN NO EVENT SHALL pCloud Ltd BE LIABLE FOR ANY 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | #include "pcompat.h" 29 | #include "plist.h" 30 | 31 | /* Fairly simple in-place merge sort with constant storage requirements. 32 | * 33 | * Recursive approach might would use O(log N) storage on the stack but may 34 | * have better cache locality for lists that do not fit in processor cache, 35 | * may benefit from precise in-half splitting and can go without needless 36 | * iterating of the list to reach the half of it. 37 | */ 38 | 39 | void psync_list_sort(psync_list *l, psync_list_compare cmp){ 40 | psync_list *ls, *l1, *l2, **tail; 41 | psync_uint_t depth, cnt, i, l1len, l2len; 42 | if (psync_list_isempty(l)) 43 | return; 44 | ls=l->next; 45 | l->prev->next=NULL; 46 | depth=1; 47 | while (1){ 48 | l1=ls; 49 | tail=&ls; 50 | cnt=0; 51 | while (l1){ 52 | cnt++; 53 | l2=l1; 54 | for (i=0; inext; 56 | if (!l2){ 57 | *tail=l1; 58 | goto nol2; 59 | } 60 | l1len=i; 61 | l2len=depth; 62 | while (1){ 63 | if (cmp(l1, l2)<=0){ 64 | l1len--; 65 | *tail=l1; 66 | tail=&l1->next; 67 | if (!l1len) 68 | goto l1fin; 69 | l1=l1->next; 70 | } 71 | else{ 72 | l2len--; 73 | *tail=l2; 74 | tail=&l2->next; 75 | l2=l2->next; 76 | if (!l2len || !l2) 77 | goto l2fin; 78 | } 79 | } 80 | l2fin: 81 | *tail=l1; 82 | for (i=0; inext; 84 | tail=&l1->next; 85 | l1=l2; 86 | continue; 87 | l1fin: 88 | *tail=l2; 89 | for (i=0; l2->next && inext; 91 | tail=&l2->next; 92 | l1=l2->next; 93 | } 94 | *tail=NULL; 95 | nol2: 96 | if (cnt<=1) 97 | break; 98 | depth*=2; 99 | } 100 | l->next=ls; 101 | l1=l; 102 | while (ls){ 103 | ls->prev=l1; 104 | l1=ls; 105 | ls=ls->next; 106 | } 107 | l1->next=l; 108 | l->prev=l1; 109 | } 110 | 111 | void psync_list_extract_repeating(psync_list *l1, psync_list *l2, psync_list *extracted1, psync_list *extracted2, psync_list_compare cmp){ 112 | psync_list *li1, *li2, *ln1, *ln2; 113 | int cr; 114 | psync_list_sort(l1, cmp); 115 | psync_list_sort(l2, cmp); 116 | li1=l1->next; 117 | li2=l2->next; 118 | while (li1!=l1 && li2!=l2){ 119 | cr=cmp(li1, li2); 120 | if (cr<0) 121 | li1=li1->next; 122 | else if (cr>0) 123 | li2=li2->next; 124 | else{ 125 | ln1=li1->next; 126 | ln2=li2->next; 127 | psync_list_del(li1); 128 | psync_list_add_tail(extracted1, li1); 129 | psync_list_del(li2); 130 | psync_list_add_tail(extracted2, li2); 131 | li1=ln1; 132 | li2=ln2; 133 | } 134 | } 135 | } 136 | 137 | -------------------------------------------------------------------------------- /plist.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2013 Anton Titov. 2 | * Copyright (c) 2013 pCloud Ltd. 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * * Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * * Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * * Neither the name of pCloud Ltd nor the 13 | * names of its contributors may be used to endorse or promote products 14 | * derived from this software without specific prior written permission. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | * DISCLAIMED. IN NO EVENT SHALL pCloud Ltd BE LIABLE FOR ANY 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | #ifndef _PSYNC_LIST_H 29 | #define _PSYNC_LIST_H 30 | 31 | #include 32 | #include "pcompiler.h" 33 | 34 | typedef struct _psync_list { 35 | struct _psync_list *next; 36 | struct _psync_list *prev; 37 | } psync_list; 38 | 39 | typedef int (*psync_list_compare)(const psync_list *, const psync_list *); 40 | 41 | #define psync_list_init(l)\ 42 | do {\ 43 | (l)->next=(l);\ 44 | (l)->prev=(l);\ 45 | } while (0) 46 | 47 | #define PSYNC_LIST_STATIC_INIT(l) {&l, &l} 48 | 49 | #define psync_list_isempty(l) ((l)->next==(l)) 50 | #define psync_list_is_head(l, e) ((l)->next==(e)) 51 | #define psync_list_is_tail(l, e) ((l)->prev==(e)) 52 | 53 | static inline void psync_list_add_between(psync_list *l1, psync_list *l2, psync_list *a){ 54 | a->next=l2; 55 | a->prev=l1; 56 | l1->next=a; 57 | l2->prev=a; 58 | } 59 | 60 | #define psync_list_add_head(l, a) psync_list_add_between(l, (l)->next, a) 61 | #define psync_list_add_tail(l, a) psync_list_add_between((l)->prev, l, a) 62 | #define psync_list_add_before(e, a) psync_list_add_between((e)->prev, e, a) 63 | #define psync_list_add_after(e, a) psync_list_add_between(e, (e)->next, a) 64 | 65 | #define psync_list_del(a)\ 66 | do {\ 67 | (a)->next->prev=(a)->prev;\ 68 | (a)->prev->next=(a)->next;\ 69 | } while (0) 70 | 71 | #define psync_list_element(a, t, n) ((t *)((char *)(a)-offsetof(t, n))) 72 | 73 | #define psync_list_for_each(a, l) for (a=(l)->next; psync_prefetch(a->next), a!=(l); a=a->next) 74 | #define psync_list_for_each_safe(a, b, l) for (a=(l)->next, b=a->next; psync_prefetch(b), a!=(l); a=b, b=b->next) 75 | #define psync_list_for_each_element(a, l, t, n) for (a=psync_list_element((l)->next, t, n);\ 76 | psync_prefetch(a->n.next), &a->n!=(l);\ 77 | a=psync_list_element(a->n.next, t, n)) 78 | 79 | #define psync_list_for_each_element_call(l, t, n, c)\ 80 | do {\ 81 | psync_list *___tmpa, *___tmpb;\ 82 | psync_list_for_each_safe(___tmpa, ___tmpb, l)\ 83 | c(psync_list_element(___tmpa, t, n));\ 84 | } while (0) 85 | 86 | static inline psync_list *psync_list_remove_head(psync_list *l){ 87 | l=l->next; 88 | psync_list_del(l); 89 | return l; 90 | } 91 | 92 | #define psync_list_remove_head_element(l, t, n) psync_list_element(psync_list_remove_head(l), t, n) 93 | 94 | void psync_list_sort(psync_list *l, psync_list_compare cmp); 95 | void psync_list_extract_repeating(psync_list *l1, psync_list *l2, psync_list *extracted1, psync_list *extracted2, psync_list_compare cmp); 96 | 97 | #endif 98 | -------------------------------------------------------------------------------- /plocalnotify.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2014 Anton Titov. 2 | * Copyright (c) 2014 pCloud Ltd. 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * * Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * * Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * * Neither the name of pCloud Ltd nor the 13 | * names of its contributors may be used to endorse or promote products 14 | * derived from this software without specific prior written permission. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | * DISCLAIMED. IN NO EVENT SHALL pCloud Ltd BE LIABLE FOR ANY 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | #ifndef _PSYNC_LOCALNOTIFY_H 29 | #define _PSYNC_LOCALNOTIFY_H 30 | 31 | #include "psynclib.h" 32 | 33 | int psync_localnotify_init(); 34 | void psync_localnotify_add_sync(psync_syncid_t syncid); 35 | void psync_localnotify_del_sync(psync_syncid_t syncid); 36 | 37 | 38 | #endif 39 | -------------------------------------------------------------------------------- /plocalscan.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2014 Anton Titov. 2 | * Copyright (c) 2014 pCloud Ltd. 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * * Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * * Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * * Neither the name of pCloud Ltd nor the 13 | * names of its contributors may be used to endorse or promote products 14 | * derived from this software without specific prior written permission. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | * DISCLAIMED. IN NO EVENT SHALL pCloud Ltd BE LIABLE FOR ANY 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | #ifndef _PSYNC_LOCALSCAN_H 29 | #define _PSYNC_LOCALSCAN_H 30 | 31 | void psync_localscan_init(); 32 | void psync_wake_localscan(); 33 | void psync_restart_localscan(); 34 | void psync_stop_localscan(); 35 | void psync_resume_localscan(); 36 | 37 | #endif -------------------------------------------------------------------------------- /plocks.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2015 Anton Titov. 2 | * Copyright (c) 2015 pCloud Ltd. 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * * Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * * Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * * Neither the name of pCloud Ltd nor the 13 | * names of its contributors may be used to endorse or promote products 14 | * derived from this software without specific prior written permission. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | * DISCLAIMED. IN NO EVENT SHALL pCloud Ltd BE LIABLE FOR ANY 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | #ifndef _PSYNC_LOCKS_H 29 | #define _PSYNC_LOCKS_H 30 | 31 | #include 32 | 33 | typedef struct { 34 | unsigned rcount; 35 | unsigned rwait; 36 | unsigned wcount; 37 | unsigned wwait; 38 | unsigned opts; 39 | pthread_key_t cntkey; 40 | pthread_mutex_t mutex; 41 | pthread_cond_t rcond; 42 | pthread_cond_t wcond; 43 | } psync_rwlock_t; 44 | 45 | void psync_rwlock_init(psync_rwlock_t *rw); 46 | void psync_rwlock_destroy(psync_rwlock_t *rw); 47 | void psync_rwlock_rdlock(psync_rwlock_t *rw); 48 | int psync_rwlock_tryrdlock(psync_rwlock_t *rw); 49 | int psync_rwlock_timedrdlock(psync_rwlock_t *rw, const struct timespec *abstime); 50 | void psync_rwlock_rdlock_starvewr(psync_rwlock_t *rw); 51 | void psync_rwlock_wrlock(psync_rwlock_t *rw); 52 | int psync_rwlock_trywrlock(psync_rwlock_t *rw); 53 | int psync_rwlock_timedwrlock(psync_rwlock_t *rw, const struct timespec *abstime); 54 | void psync_rwlock_rslock(psync_rwlock_t *rw); 55 | int psync_rwlock_towrlock(psync_rwlock_t *rw); 56 | void psync_rwlock_unlock(psync_rwlock_t *rw); 57 | unsigned psync_rwlock_num_waiters(psync_rwlock_t *rw); 58 | int psync_rwlock_holding_rdlock(psync_rwlock_t *rw); 59 | int psync_rwlock_holding_lock(psync_rwlock_t *rw); 60 | 61 | 62 | #endif 63 | -------------------------------------------------------------------------------- /pmemlock.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2015 Anton Titov. 2 | * Copyright (c) 2015 pCloud Ltd. 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * * Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * * Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * * Neither the name of pCloud Ltd nor the 13 | * names of its contributors may be used to endorse or promote products 14 | * derived from this software without specific prior written permission. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | * DISCLAIMED. IN NO EVENT SHALL pCloud Ltd BE LIABLE FOR ANY 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | #ifndef _PSYNC_MEMLOCK_H 29 | #define _PSYNC_MEMLOCK_H 30 | 31 | #include 32 | 33 | void psync_locked_init(); 34 | 35 | int psync_mem_lock(void *ptr, size_t size); 36 | int psync_mem_unlock(void *ptr, size_t size); 37 | 38 | void *psync_locked_malloc(size_t size); 39 | void psync_locked_free(void *ptr); 40 | 41 | #endif 42 | -------------------------------------------------------------------------------- /pnetlibs.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2013-2014 Anton Titov. 2 | * Copyright (c) 2013-2014 pCloud Ltd. 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * * Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * * Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * * Neither the name of pCloud Ltd nor the 13 | * names of its contributors may be used to endorse or promote products 14 | * derived from this software without specific prior written permission. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | * DISCLAIMED. IN NO EVENT SHALL pCloud Ltd BE LIABLE FOR ANY 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | #ifndef _PSYNC_NETLIBS_H 29 | #define _PSYNC_NETLIBS_H 30 | 31 | #include "pcompat.h" 32 | #include "psynclib.h" 33 | #include "plist.h" 34 | #include "papi.h" 35 | 36 | #define PSYNC_NET_OK 0 37 | #define PSYNC_NET_PERMFAIL -1 38 | #define PSYNC_NET_TEMPFAIL -2 39 | 40 | typedef uint64_t psync_uploadid_t; 41 | 42 | typedef struct { 43 | psync_socket *sock; 44 | char *readbuff; 45 | int64_t contentlength; 46 | uint64_t readbytes; 47 | uint32_t keepalive; 48 | uint32_t readbuffoff; 49 | uint32_t readbuffsize; 50 | char cachekey[]; 51 | } psync_http_socket; 52 | 53 | #define PSYNC_RANGE_TRANSFER 0 54 | #define PSYNC_RANGE_COPY 1 55 | 56 | typedef struct { 57 | psync_list list; 58 | uint64_t off; 59 | uint64_t len; 60 | uint32_t type; 61 | const char *filename; 62 | } psync_range_list_t; 63 | 64 | #define PSYNC_URANGE_UPLOAD 0 65 | #define PSYNC_URANGE_COPY_FILE 1 66 | #define PSYNC_URANGE_COPY_UPLOAD 2 67 | #define PSYNC_URANGE_LAST 3 68 | 69 | typedef struct { 70 | psync_list list; 71 | uint64_t uploadoffset; 72 | uint64_t off; 73 | uint64_t len; 74 | union { 75 | uint64_t uploadid; 76 | struct { 77 | psync_fileid_t fileid; 78 | uint64_t hash; 79 | } file; 80 | }; 81 | uint32_t type; 82 | uint32_t id; 83 | } psync_upload_range_list_t; 84 | 85 | typedef struct { 86 | psync_list list; 87 | char filename[]; 88 | } psync_file_lock_t; 89 | 90 | void psync_netlibs_init(); 91 | 92 | psync_socket *psync_apipool_get(); 93 | psync_socket *psync_apipool_get_from_cache(); 94 | void psync_apipool_prepare(); 95 | void psync_apipool_release(psync_socket *api); 96 | void psync_apipool_release_bad(psync_socket *api); 97 | 98 | int psync_rmdir_with_trashes(const char *path); 99 | int psync_rmdir_recursive(const char *path); 100 | 101 | void psync_set_local_full(int over); 102 | int psync_handle_api_result(uint64_t result); 103 | int psync_get_remote_file_checksum(psync_fileid_t fileid, unsigned char *hexsum, uint64_t *fsize, uint64_t *hash); 104 | int psync_get_local_file_checksum(const char *restrict filename, unsigned char *restrict hexsum, uint64_t *restrict fsize); 105 | int psync_get_local_file_checksum_part(const char *restrict filename, unsigned char *restrict hexsum, uint64_t *restrict fsize, 106 | unsigned char *restrict phexsum, uint64_t pfsize); 107 | int psync_copy_local_file_if_checksum_matches(const char *source, const char *destination, const unsigned char *hexsum, uint64_t fsize); 108 | int psync_file_writeall_checkoverquota(psync_file_t fd, const void *buf, size_t count); 109 | 110 | int psync_set_default_sendbuf(psync_socket *sock); 111 | int psync_socket_readall_download(psync_socket *sock, void *buff, int num); 112 | int psync_socket_readall_download_thread(psync_socket *sock, void *buff, int num); 113 | int psync_socket_writeall_upload(psync_socket *sock, const void *buff, int num); 114 | 115 | psync_http_socket *psync_http_connect(const char *host, const char *path, uint64_t from, uint64_t to); 116 | void psync_http_close(psync_http_socket *http); 117 | int psync_http_readall(psync_http_socket *http, void *buff, int num); 118 | void psync_http_connect_and_cache_host(const char *host); 119 | psync_http_socket *psync_http_connect_multihost(const binresult *hosts, const char **host); 120 | psync_http_socket *psync_http_connect_multihost_from_cache(const binresult *hosts, const char **host); 121 | int psync_http_request(psync_http_socket *sock, const char *host, const char *path, uint64_t from, uint64_t to); 122 | int psync_http_next_request(psync_http_socket *sock); 123 | int psync_http_request_readall(psync_http_socket *http, void *buff, int num); 124 | 125 | char *psync_url_decode(const char *s); 126 | 127 | int psync_net_download_ranges(psync_list *ranges, psync_fileid_t fileid, uint64_t filehash, uint64_t filesize, char *const *files, uint32_t filecnt); 128 | int psync_net_scan_file_for_blocks(psync_socket *api, psync_list *rlist, psync_fileid_t fileid, uint64_t filehash, psync_file_t fd); 129 | int psync_net_scan_upload_for_blocks(psync_socket *api, psync_list *rlist, psync_uploadid_t uploadid, psync_file_t fd); 130 | 131 | int psync_is_revision_of_file(const unsigned char *localhashhex, uint64_t filesize, psync_fileid_t fileid, int *isrev); 132 | 133 | psync_file_lock_t *psync_lock_file(const char *path); 134 | void psync_unlock_file(psync_file_lock_t *lock); 135 | 136 | int psync_get_upload_checksum(psync_uploadid_t uploadid, unsigned char *uhash, uint64_t *usize); 137 | 138 | void psync_process_api_error(uint64_t result); 139 | 140 | #endif 141 | -------------------------------------------------------------------------------- /pnotifications.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2015 Anton Titov. 2 | * Copyright (c) 2015 pCloud Ltd. 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * * Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * * Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * * Neither the name of pCloud Ltd nor the 13 | * names of its contributors may be used to endorse or promote products 14 | * derived from this software without specific prior written permission. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | * DISCLAIMED. IN NO EVENT SHALL pCloud Ltd BE LIABLE FOR ANY 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | #ifndef _PSYNC_NOTIFICATIONS_H 29 | #define _PSYNC_NOTIFICATIONS_H 30 | 31 | #include "psynclib.h" 32 | #include "papi.h" 33 | 34 | int psync_notifications_running(); 35 | const char *psync_notifications_get_thumb_size(); 36 | void psync_notifications_notify(binresult *res); 37 | void psync_notifications_set_callback(pnotification_callback_t notification_callback, const char *thumbsize); 38 | psync_notification_list_t *psync_notifications_get(); 39 | void psync_notifications_clean(); 40 | 41 | #endif 42 | -------------------------------------------------------------------------------- /pp2p.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2014 Anton Titov. 2 | * Copyright (c) 2014 pCloud Ltd. 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * * Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * * Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * * Neither the name of pCloud Ltd nor the 13 | * names of its contributors may be used to endorse or promote products 14 | * derived from this software without specific prior written permission. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | * DISCLAIMED. IN NO EVENT SHALL pCloud Ltd BE LIABLE FOR ANY 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | #ifndef _PSYNC_P2P_H 29 | #define _PSYNC_P2P_H 30 | 31 | #include "psynclib.h" 32 | 33 | void psync_p2p_init(); 34 | void psync_p2p_change(); 35 | int psync_p2p_check_download(psync_fileid_t fileid, const unsigned char *filehashhex, uint64_t fsize, const char *filename); 36 | 37 | #endif -------------------------------------------------------------------------------- /ppagecache.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2014 Anton Titov. 2 | * Copyright (c) 2014 pCloud Ltd. 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * * Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * * Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * * Neither the name of pCloud Ltd nor the 13 | * names of its contributors may be used to endorse or promote products 14 | * derived from this software without specific prior written permission. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | * DISCLAIMED. IN NO EVENT SHALL pCloud Ltd BE LIABLE FOR ANY 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | #ifndef _PSYNC_PAGECACHE_H 29 | #define _PSYNC_PAGECACHE_H 30 | 31 | #include "pfs.h" 32 | 33 | typedef struct { 34 | uint64_t offset; 35 | uint64_t size; 36 | char *buf; 37 | } psync_pagecache_read_range; 38 | 39 | void psync_pagecache_init(); 40 | int psync_pagecache_flush(); 41 | int psync_pagecache_read_modified_locked(psync_openfile_t *of, char *buf, uint64_t size, uint64_t offset); 42 | int psync_pagecache_read_unmodified_locked(psync_openfile_t *of, char *buf, uint64_t size, uint64_t offset); 43 | int psync_pagecache_read_unmodified_encrypted_locked(psync_openfile_t *of, char *buf, uint64_t size, uint64_t offset); 44 | int psync_pagecache_readv_locked(psync_openfile_t *of, psync_pagecache_read_range *ranges, int cnt); 45 | void psync_pagecache_creat_to_pagecache(uint64_t taskid, uint64_t hash); 46 | void psync_pagecache_modify_to_pagecache(uint64_t taskid, uint64_t hash, uint64_t oldhash); 47 | int psync_pagecache_have_all_pages_in_cache(uint64_t hash, uint64_t size); 48 | int psync_pagecache_copy_all_pages_from_cache_to_file_locked(psync_openfile_t *of, uint64_t hash, uint64_t size); 49 | int psync_pagecache_lock_pages_in_cache(); 50 | void psync_pagecache_unlock_pages_from_cache(); 51 | void psync_pagecache_resize_cache(); 52 | uint64_t psync_pagecache_free_from_read_cache(uint64_t size); 53 | void psync_pagecache_clean_cache(); 54 | 55 | #endif 56 | -------------------------------------------------------------------------------- /ppassword.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2014 Anton Titov. 2 | * Copyright (c) 2014 pCloud Ltd. 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * * Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * * Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * * Neither the name of pCloud Ltd nor the 13 | * names of its contributors may be used to endorse or promote products 14 | * derived from this software without specific prior written permission. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | * DISCLAIMED. IN NO EVENT SHALL pCloud Ltd BE LIABLE FOR ANY 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | #ifndef _PSYNC_PASSWORD_H 29 | #define _PSYNC_PASSWORD_H 30 | 31 | #include 32 | 33 | uint64_t psync_password_score(const char *password); 34 | 35 | #endif -------------------------------------------------------------------------------- /prunratelimit.c: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2015 Anton Titov. 2 | * Copyright (c) 2015 pCloud Ltd. 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * * Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * * Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * * Neither the name of pCloud Ltd nor the 13 | * names of its contributors may be used to endorse or promote products 14 | * derived from this software without specific prior written permission. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | * DISCLAIMED. IN NO EVENT SHALL pCloud Ltd BE LIABLE FOR ANY 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | #include "plibs.h" 29 | #include "prunratelimit.h" 30 | #include "ptimer.h" 31 | #include "ptree.h" 32 | 33 | typedef struct { 34 | psync_tree tree; 35 | psync_run_ratelimit_callback0 call; 36 | const char *name; 37 | unsigned char scheduled; 38 | } psync_rr_tree_node; 39 | 40 | static pthread_mutex_t task_mutex=PTHREAD_MUTEX_INITIALIZER; 41 | static psync_tree *tasks=PSYNC_TREE_EMPTY; 42 | 43 | static void psync_run_ratelimited_timer(psync_timer_t timer, void *ptr){ 44 | psync_rr_tree_node *node; 45 | const char *name; 46 | psync_run_ratelimit_callback0 call; 47 | int run; 48 | node=(psync_rr_tree_node *)ptr; 49 | pthread_mutex_lock(&task_mutex); 50 | if (node->scheduled){ 51 | run=1; 52 | node->scheduled=0; 53 | call=node->call; 54 | name=node->name; 55 | } 56 | else{ 57 | run=0; 58 | psync_tree_del(&tasks, &node->tree); 59 | } 60 | pthread_mutex_unlock(&task_mutex); 61 | if (run){ 62 | debug(D_NOTICE, "running %s in a thread", name); 63 | psync_run_thread(name, call); 64 | } 65 | else{ 66 | psync_timer_stop(timer); 67 | psync_free(node); 68 | } 69 | } 70 | 71 | void psync_run_ratelimited(const char *name, psync_run_ratelimit_callback0 call, uint32_t minintervalsec, int runinthread){ 72 | psync_tree *tr, **addto; 73 | psync_rr_tree_node *node; 74 | int found; 75 | found=0; 76 | pthread_mutex_lock(&task_mutex); 77 | tr=tasks; 78 | if (tr){ 79 | while (1){ 80 | node=psync_tree_element(tr, psync_rr_tree_node, tree); 81 | if (callcall){ 82 | if (tr->left) 83 | tr=tr->left; 84 | else{ 85 | addto=&tr->left; 86 | break; 87 | } 88 | } 89 | else if (call>node->call){ 90 | if (tr->right) 91 | tr=tr->right; 92 | else{ 93 | addto=&tr->right; 94 | break; 95 | } 96 | } 97 | else{ 98 | found=1; 99 | break; 100 | } 101 | } 102 | } 103 | else 104 | addto=&tasks; 105 | if (found){ 106 | if (node->scheduled) 107 | debug(D_NOTICE, "skipping run of %s as it is already scheduled", name); 108 | else{ 109 | debug(D_NOTICE, "scheduling run of %s on existing timer", name); 110 | node->scheduled=1; 111 | } 112 | } 113 | else{ 114 | node=psync_new(psync_rr_tree_node); 115 | node->call=call; 116 | node->name=name; 117 | node->scheduled=0; 118 | *addto=&node->tree; 119 | psync_tree_added_at(&tasks, tr, &node->tree); 120 | } 121 | pthread_mutex_unlock(&task_mutex); 122 | if (!found){ 123 | if (runinthread){ 124 | debug(D_NOTICE, "running %s in a thread", name); 125 | psync_run_thread(name, call); 126 | } 127 | else{ 128 | debug(D_NOTICE, "running %s on this thread", name); 129 | call(); 130 | } 131 | psync_timer_register(psync_run_ratelimited_timer, minintervalsec, node); 132 | } 133 | } 134 | -------------------------------------------------------------------------------- /prunratelimit.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2015 Anton Titov. 2 | * Copyright (c) 2015 pCloud Ltd. 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * * Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * * Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * * Neither the name of pCloud Ltd nor the 13 | * names of its contributors may be used to endorse or promote products 14 | * derived from this software without specific prior written permission. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | * DISCLAIMED. IN NO EVENT SHALL pCloud Ltd BE LIABLE FOR ANY 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | #ifndef _PSYNC_RUNRATELIMIT_H 29 | #define _PSYNC_RUNRATELIMIT_H 30 | 31 | #include 32 | 33 | typedef void (*psync_run_ratelimit_callback0)(); 34 | 35 | void psync_run_ratelimited(const char *name, psync_run_ratelimit_callback0 call, uint32_t minintervalsec, int runinthread); 36 | 37 | #endif 38 | -------------------------------------------------------------------------------- /pscanexts.h: -------------------------------------------------------------------------------- 1 | #define PSYNC_SCAN_EXTENSIONS_CNT 166 2 | #define PSYNC_SCAN_TYPES_CNT 5 3 | 4 | static const char *psync_scan_typenames[PSYNC_SCAN_TYPES_CNT]={"other files", "pictures", "videos", "music files", "documents"}; 5 | 6 | static const uint32_t psync_scan_extensions[PSYNC_SCAN_EXTENSIONS_CNT]={ 7 | 438 /* au */, 8 | 540 /* dl */, 9 | 550 /* dv */, 10 | 651 /* gl */, 11 | 1029 /* qt */, 12 | 1047 /* ra */, 13 | 1059 /* rm */, 14 | 1139 /* ts */, 15 | 1244 /* wm */, 16 | 6131 /* 3gp */, 17 | 15536 /* abw */, 18 | 15778 /* aif */, 19 | 15938 /* amr */, 20 | 16036 /* ape */, 21 | 16125 /* art */, 22 | 16145 /* asc */, 23 | 16148 /* asf */, 24 | 16166 /* asx */, 25 | 16262 /* avi */, 26 | 16292 /* awb */, 27 | 16328 /* axa */, 28 | 16349 /* axv */, 29 | 17305 /* bmp */, 30 | 17480 /* brf */, 31 | 18220 /* caf */, 32 | 18343 /* cdr */, 33 | 18345 /* cdt */, 34 | 18789 /* cpt */, 35 | 18836 /* cr2 */, 36 | 18866 /* crw */, 37 | 18884 /* csd */, 38 | 19885 /* dif */, 39 | 19938 /* djv */, 40 | 20104 /* doc */, 41 | 20121 /* dot */, 42 | 21587 /* erf */, 43 | 22737 /* fli */, 44 | 22750 /* flv */, 45 | 23992 /* gif */, 46 | 24369 /* gsm */, 47 | 26517 /* ico */, 48 | 26582 /* ief */, 49 | 28285 /* jng */, 50 | 28357 /* jpe */, 51 | 28359 /* jpg */, 52 | 29184 /* kar */, 53 | 29739 /* kpr */, 54 | 29741 /* kpt */, 55 | 29848 /* ksp */, 56 | 29984 /* kwd */, 57 | 30000 /* kwt */, 58 | 31207 /* lsf */, 59 | 31225 /* lsx */, 60 | 31666 /* m3u */, 61 | 31683 /* m4a */, 62 | 32017 /* mdb */, 63 | 32204 /* mid */, 64 | 32296 /* mkv */, 65 | 32392 /* mng */, 66 | 32444 /* mov */, 67 | 32452 /* mp2 */, 68 | 32453 /* mp3 */, 69 | 32454 /* mp4 */, 70 | 32464 /* mpe */, 71 | 32466 /* mpg */, 72 | 32481 /* mpv */, 73 | 32626 /* mts */, 74 | 32776 /* mxu */, 75 | 33427 /* nef */, 76 | 34755 /* odb */, 77 | 34756 /* odc */, 78 | 34762 /* odi */, 79 | 34766 /* odm */, 80 | 34769 /* odp */, 81 | 34772 /* ods */, 82 | 34773 /* odt */, 83 | 34865 /* oga */, 84 | 34871 /* ogg */, 85 | 34886 /* ogv */, 86 | 35274 /* orc */, 87 | 35277 /* orf */, 88 | 35353 /* oth */, 89 | 35361 /* otp */, 90 | 35364 /* ots */, 91 | 35365 /* ott */, 92 | 36031 /* pat */, 93 | 36061 /* pbm */, 94 | 36109 /* pcx */, 95 | 36128 /* pdf */, 96 | 36246 /* pgm */, 97 | 36437 /* pls */, 98 | 36499 /* png */, 99 | 36505 /* pnm */, 100 | 36549 /* pot */, 101 | 36579 /* ppm */, 102 | 36585 /* pps */, 103 | 36586 /* ppt */, 104 | 36681 /* psd */, 105 | 38762 /* ram */, 106 | 38768 /* ras */, 107 | 38973 /* rgb */, 108 | 39458 /* rtf */, 109 | 40207 /* sco */, 110 | 40222 /* sd2 */, 111 | 40252 /* sdw */, 112 | 40352 /* sgl */, 113 | 40418 /* sid */, 114 | 40603 /* snd */, 115 | 40697 /* spx */, 116 | 40767 /* srt */, 117 | 40844 /* stw */, 118 | 40902 /* svg */, 119 | 40976 /* sxg */, 120 | 40992 /* sxw */, 121 | 41789 /* tif */, 122 | 42154 /* tsa */, 123 | 42175 /* tsv */, 124 | 42358 /* txt */, 125 | 45616 /* wav */, 126 | 45618 /* wax */, 127 | 46039 /* wma */, 128 | 46060 /* wmv */, 129 | 46062 /* wmx */, 130 | 46395 /* wvx */, 131 | 47013 /* xbm */, 132 | 47372 /* xlb */, 133 | 47389 /* xls */, 134 | 47390 /* xlt */, 135 | 47531 /* xpm */, 136 | 47781 /* xwd */, 137 | 583799 /* aifc */, 138 | 583802 /* aiff */, 139 | 684197 /* chrt */, 140 | 737737 /* djvu */, 141 | 743871 /* docm */, 142 | 743882 /* docx */, 143 | 744500 /* dotm */, 144 | 744511 /* dotx */, 145 | 840986 /* flac */, 146 | 1049226 /* jpeg */, 147 | 1170265 /* m2ts */, 148 | 1191567 /* midi */, 149 | 1201185 /* mpeg */, 150 | 1201253 /* mpga */, 151 | 1352336 /* potm */, 152 | 1352347 /* potx */, 153 | 1353002 /* ppam */, 154 | 1353668 /* ppsm */, 155 | 1353679 /* ppsx */, 156 | 1353705 /* pptm */, 157 | 1353716 /* pptx */, 158 | 1499596 /* sldm */, 159 | 1499607 /* sldx */, 160 | 1513410 /* svgz */, 161 | 1541413 /* text */, 162 | 1546209 /* tiff */, 163 | 1688854 /* wbmp */, 164 | 1692551 /* webm */, 165 | 1752750 /* xlam */, 166 | 1753405 /* xlsb */, 167 | 1753416 /* xlsm */, 168 | 1753427 /* xlsx */, 169 | 1753453 /* xltm */, 170 | 1753464 /* xltx */, 171 | 44416554 /* movie */, 172 | 44443856 /* mpega */ 173 | }; 174 | 175 | static const uint8_t psync_scan_types[PSYNC_SCAN_EXTENSIONS_CNT]={ 176 | 3, 177 | 2, 178 | 2, 179 | 2, 180 | 2, 181 | 3, 182 | 3, 183 | 2, 184 | 2, 185 | 2, 186 | 4, 187 | 3, 188 | 3, 189 | 3, 190 | 1, 191 | 4, 192 | 2, 193 | 2, 194 | 2, 195 | 3, 196 | 3, 197 | 2, 198 | 1, 199 | 4, 200 | 3, 201 | 1, 202 | 1, 203 | 1, 204 | 1, 205 | 1, 206 | 3, 207 | 2, 208 | 1, 209 | 4, 210 | 4, 211 | 1, 212 | 2, 213 | 2, 214 | 1, 215 | 3, 216 | 1, 217 | 1, 218 | 1, 219 | 1, 220 | 1, 221 | 3, 222 | 4, 223 | 4, 224 | 4, 225 | 4, 226 | 4, 227 | 2, 228 | 2, 229 | 3, 230 | 3, 231 | 4, 232 | 3, 233 | 2, 234 | 2, 235 | 2, 236 | 3, 237 | 3, 238 | 2, 239 | 2, 240 | 2, 241 | 2, 242 | 2, 243 | 2, 244 | 1, 245 | 4, 246 | 4, 247 | 1, 248 | 4, 249 | 4, 250 | 4, 251 | 4, 252 | 3, 253 | 3, 254 | 2, 255 | 3, 256 | 1, 257 | 4, 258 | 4, 259 | 4, 260 | 4, 261 | 1, 262 | 1, 263 | 1, 264 | 4, 265 | 1, 266 | 3, 267 | 1, 268 | 1, 269 | 4, 270 | 1, 271 | 4, 272 | 4, 273 | 1, 274 | 3, 275 | 1, 276 | 1, 277 | 4, 278 | 3, 279 | 3, 280 | 4, 281 | 4, 282 | 3, 283 | 3, 284 | 3, 285 | 4, 286 | 4, 287 | 1, 288 | 4, 289 | 4, 290 | 1, 291 | 2, 292 | 2, 293 | 4, 294 | 3, 295 | 3, 296 | 3, 297 | 2, 298 | 2, 299 | 2, 300 | 1, 301 | 4, 302 | 4, 303 | 4, 304 | 1, 305 | 1, 306 | 3, 307 | 3, 308 | 4, 309 | 1, 310 | 4, 311 | 4, 312 | 4, 313 | 4, 314 | 3, 315 | 1, 316 | 2, 317 | 3, 318 | 2, 319 | 3, 320 | 4, 321 | 4, 322 | 4, 323 | 4, 324 | 4, 325 | 4, 326 | 4, 327 | 4, 328 | 4, 329 | 1, 330 | 4, 331 | 1, 332 | 1, 333 | 2, 334 | 4, 335 | 4, 336 | 4, 337 | 4, 338 | 4, 339 | 4, 340 | 2, 341 | 3 342 | }; 343 | 344 | static const uint8_t psync_character_map[256]={ 345 | 0, 346 | 0, 347 | 0, 348 | 0, 349 | 0, 350 | 0, 351 | 0, 352 | 0, 353 | 0, 354 | 0, 355 | 0, 356 | 0, 357 | 0, 358 | 0, 359 | 0, 360 | 0, 361 | 0, 362 | 0, 363 | 0, 364 | 0, 365 | 0, 366 | 0, 367 | 0, 368 | 0, 369 | 0, 370 | 0, 371 | 0, 372 | 0, 373 | 0, 374 | 0, 375 | 0, 376 | 0, 377 | 0, 378 | 0, 379 | 0, 380 | 0, 381 | 0, 382 | 0, 383 | 0, 384 | 0, 385 | 0, 386 | 0, 387 | 0, 388 | 0, 389 | 0, 390 | 0, 391 | 0, 392 | 0, 393 | 1, 394 | 2, 395 | 3, 396 | 4, 397 | 5, 398 | 6, 399 | 7, 400 | 8, 401 | 9, 402 | 10, 403 | 0, 404 | 0, 405 | 0, 406 | 0, 407 | 0, 408 | 0, 409 | 0, 410 | 11, 411 | 12, 412 | 13, 413 | 14, 414 | 15, 415 | 16, 416 | 17, 417 | 18, 418 | 19, 419 | 20, 420 | 21, 421 | 22, 422 | 23, 423 | 24, 424 | 25, 425 | 26, 426 | 27, 427 | 28, 428 | 29, 429 | 30, 430 | 31, 431 | 32, 432 | 33, 433 | 34, 434 | 35, 435 | 36, 436 | 0, 437 | 0, 438 | 0, 439 | 0, 440 | 0, 441 | 0, 442 | 11, 443 | 12, 444 | 13, 445 | 14, 446 | 15, 447 | 16, 448 | 17, 449 | 18, 450 | 19, 451 | 20, 452 | 21, 453 | 22, 454 | 23, 455 | 24, 456 | 25, 457 | 26, 458 | 27, 459 | 28, 460 | 29, 461 | 30, 462 | 31, 463 | 32, 464 | 33, 465 | 34, 466 | 35, 467 | 36, 468 | 0, 469 | 0, 470 | 0, 471 | 0, 472 | 0, 473 | 0, 474 | 0, 475 | 0, 476 | 0, 477 | 0, 478 | 0, 479 | 0, 480 | 0, 481 | 0, 482 | 0, 483 | 0, 484 | 0, 485 | 0, 486 | 0, 487 | 0, 488 | 0, 489 | 0, 490 | 0, 491 | 0, 492 | 0, 493 | 0, 494 | 0, 495 | 0, 496 | 0, 497 | 0, 498 | 0, 499 | 0, 500 | 0, 501 | 0, 502 | 0, 503 | 0, 504 | 0, 505 | 0, 506 | 0, 507 | 0, 508 | 0, 509 | 0, 510 | 0, 511 | 0, 512 | 0, 513 | 0, 514 | 0, 515 | 0, 516 | 0, 517 | 0, 518 | 0, 519 | 0, 520 | 0, 521 | 0, 522 | 0, 523 | 0, 524 | 0, 525 | 0, 526 | 0, 527 | 0, 528 | 0, 529 | 0, 530 | 0, 531 | 0, 532 | 0, 533 | 0, 534 | 0, 535 | 0, 536 | 0, 537 | 0, 538 | 0, 539 | 0, 540 | 0, 541 | 0, 542 | 0, 543 | 0, 544 | 0, 545 | 0, 546 | 0, 547 | 0, 548 | 0, 549 | 0, 550 | 0, 551 | 0, 552 | 0, 553 | 0, 554 | 0, 555 | 0, 556 | 0, 557 | 0, 558 | 0, 559 | 0, 560 | 0, 561 | 0, 562 | 0, 563 | 0, 564 | 0, 565 | 0, 566 | 0, 567 | 0, 568 | 0, 569 | 0, 570 | 0, 571 | 0, 572 | 0, 573 | 0, 574 | 0, 575 | 0, 576 | 0, 577 | 0, 578 | 0, 579 | 0, 580 | 0, 581 | 0, 582 | 0, 583 | 0, 584 | 0, 585 | 0, 586 | 0, 587 | 0, 588 | 0, 589 | 0, 590 | 0, 591 | 0, 592 | 0, 593 | 0, 594 | 0, 595 | 0, 596 | 0, 597 | 0, 598 | 0, 599 | 0, 600 | 0 601 | }; 602 | -------------------------------------------------------------------------------- /pscanner.c: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2013-2014 Anton Titov. 2 | * Copyright (c) 2013-2014 pCloud Ltd. 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * * Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * * Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * * Neither the name of pCloud Ltd nor the 13 | * names of its contributors may be used to endorse or promote products 14 | * derived from this software without specific prior written permission. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | * DISCLAIMED. IN NO EVENT SHALL pCloud Ltd BE LIABLE FOR ANY 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | #include "pcompat.h" 29 | #include "pscanner.h" 30 | #include "pscanexts.h" 31 | #include "plist.h" 32 | #include "plibs.h" 33 | #include "psettings.h" 34 | #include 35 | #include 36 | 37 | typedef struct { 38 | psync_list nextfolder; 39 | psync_list subfolders; 40 | const char *path; 41 | size_t pathlen; 42 | uint32_t filecnt[PSYNC_SCAN_TYPES_CNT]; 43 | } scan_folder; 44 | 45 | typedef struct { 46 | psync_list list; 47 | scan_folder *folder; 48 | uint32_t filecnt; 49 | } suggested_folder; 50 | 51 | 52 | #define _IPATTERN(x) {x, sizeof(x)-1} 53 | struct { 54 | const char *str; 55 | size_t len; 56 | } ignore_patters[]={ 57 | _IPATTERN(".*") 58 | }; 59 | 60 | static uint32_t get_ext_id(const char *ext){ 61 | uint32_t n; 62 | uint8_t ch, c; 63 | n=0; 64 | while ((ch=(unsigned char)*ext++)){ 65 | n*=37; 66 | c=psync_character_map[ch]; 67 | if (c) 68 | n+=c; 69 | else 70 | return 0; 71 | } 72 | return n; 73 | } 74 | 75 | static uint32_t get_extid_type(uint32_t extid){ 76 | psync_uint_t lo, hi, mid; 77 | uint32_t n; 78 | lo=0; 79 | hi=PSYNC_SCAN_EXTENSIONS_CNT; 80 | while (hi>lo){ 81 | mid=(lo+hi)/2; 82 | n=psync_scan_extensions[mid]; 83 | if (extid>n) 84 | lo=mid+1; 85 | else if (extidname, ignore_patters[i].str, ignore_patters[i].len)) 107 | return; 108 | if (st->isfolder){ 109 | scan_folder *nf; 110 | char *path; 111 | size_t l, o; 112 | l=strlen(st->name); 113 | o=f->pathlen; 114 | nf=(scan_folder *)psync_malloc(sizeof(scan_folder)+o+l+2); 115 | psync_list_init(&nf->subfolders); 116 | path=(char *)(nf+1); 117 | memcpy(path, f->path, o); 118 | path[o++]=PSYNC_DIRECTORY_SEPARATORC; 119 | memcpy(path+o, st->name, l); 120 | o+=l; 121 | path[o]=0; 122 | nf->path=path; 123 | nf->pathlen=o; 124 | memset(&nf->filecnt, 0, sizeof(nf->filecnt)); 125 | psync_list_add_tail(&f->subfolders, &nf->nextfolder); 126 | } 127 | else 128 | f->filecnt[get_file_type(st->name)]++; 129 | } 130 | 131 | static void scan_folder_by_ptr(scan_folder *f){ 132 | psync_list *e; 133 | // debug(D_NOTICE, "scanning directory %s", f->path); 134 | psync_list_dir_fast(f->path, dir_scan, f); 135 | psync_list_for_each(e, &f->subfolders) 136 | scan_folder_by_ptr(psync_list_element(e, scan_folder, nextfolder)); 137 | } 138 | 139 | static void add_subfolder_counts(scan_folder *f){ 140 | psync_list *e; 141 | scan_folder *s; 142 | psync_uint_t i; 143 | psync_list_for_each(e, &f->subfolders){ 144 | s=psync_list_element(e, scan_folder, nextfolder); 145 | add_subfolder_counts(s); 146 | for (i=0; ifilecnt[i]+=s->filecnt[i]; 148 | } 149 | } 150 | 151 | static void suggest_folders(scan_folder *f, psync_list *suggestions){ 152 | psync_list *e; 153 | suggested_folder *s; 154 | psync_uint_t i; 155 | uint32_t sum; 156 | sum=0; 157 | for (i=1; ifilecnt[i]; 159 | if (sum>=PSYNC_SCANNER_MIN_FILES && sum>=(f->filecnt[0]+sum)*PSYNC_SCANNER_PERCENT/100){ 160 | // debug(D_NOTICE, "suggesting %s sum %u", f->path, sum); 161 | s=psync_new(suggested_folder); 162 | s->folder=f; 163 | s->filecnt=sum; 164 | psync_list_add_tail(suggestions, &s->list); 165 | return; 166 | } 167 | psync_list_for_each(e, &f->subfolders) 168 | suggest_folders(psync_list_element(e, scan_folder, nextfolder), suggestions); 169 | } 170 | 171 | static int sort_comp_rev(const psync_list *l1, const psync_list *l2){ 172 | return (int)(psync_list_element(l2, suggested_folder, list)->filecnt)-(int)(psync_list_element(l1, suggested_folder, list)->filecnt); 173 | } 174 | 175 | static int sort_comp_tuple_rev(const void *p1, const void *p2){ 176 | return *((int *)p2)-*((int *)p1); 177 | } 178 | 179 | static void free_folder(scan_folder *f){ 180 | psync_list_for_each_element_call(&f->subfolders, scan_folder, nextfolder, free_folder); 181 | psync_free(f); 182 | } 183 | 184 | psuggested_folders_t *psync_scanner_scan_folder(const char *path){ 185 | scan_folder *f; 186 | psync_list suggestions; 187 | suggested_folder *s, *sf[PSYNC_SCANNER_MAX_SUGGESTIONS]; 188 | psync_uint_t cnt, i; 189 | size_t off, ln; 190 | psuggested_folders_t *ret; 191 | char *str; 192 | char *descs[PSYNC_SCANNER_MAX_SUGGESTIONS]; 193 | size_t descslen[PSYNC_SCANNER_MAX_SUGGESTIONS]; 194 | char buff[256]; 195 | uint32_t scnt[PSYNC_SCAN_TYPES_CNT][2]; 196 | f=psync_new(scan_folder); 197 | psync_list_init(&f->nextfolder); 198 | psync_list_init(&f->subfolders); 199 | f->path=path; 200 | f->pathlen=strlen(path); 201 | memset(&f->filecnt, 0, sizeof(f->filecnt)); 202 | scan_folder_by_ptr(f); 203 | add_subfolder_counts(f); 204 | psync_list_init(&suggestions); 205 | suggest_folders(f, &suggestions); 206 | psync_list_sort(&suggestions, sort_comp_rev); 207 | cnt=0; 208 | ln=0; 209 | psync_list_for_each_element(s, &suggestions, suggested_folder, list){ 210 | off=0; 211 | for (i=0; ifolder->filecnt[i]; 213 | scnt[i][1]=i; 214 | } 215 | qsort(scnt, PSYNC_SCAN_TYPES_CNT, sizeof(scnt[0]), sort_comp_tuple_rev); 216 | for (i=0; i=PSYNC_SCANNER_MIN_DISPLAY){ 218 | off+=psync_slprintf(buff+off, sizeof(buff)-off, "%u %s, ", (unsigned)scnt[i][0], psync_scan_typenames[scnt[i][1]]); 219 | if (off>=sizeof(buff)) 220 | break; 221 | } 222 | if (off) 223 | off-=2; 224 | buff[off]=0; 225 | ln+=s->folder->pathlen+off+2; 226 | sf[cnt]=s; 227 | descslen[cnt]=off+1; 228 | descs[cnt]=psync_malloc(descslen[cnt]); 229 | memcpy(descs[cnt], buff, descslen[cnt]); 230 | if (++cnt>=PSYNC_SCANNER_MAX_SUGGESTIONS) 231 | break; 232 | } 233 | ret=psync_malloc(offsetof(psuggested_folders_t, entries)+sizeof(psuggested_folder_t)*cnt+ln); 234 | str=((char *)ret)+offsetof(psuggested_folders_t, entries)+sizeof(psuggested_folder_t)*cnt; 235 | ret->entrycnt=cnt; 236 | for (i=0; ientries[i].localpath=str; 238 | memcpy(str, sf[i]->folder->path, sf[i]->folder->pathlen+1); 239 | str+=sf[i]->folder->pathlen+1; 240 | ret->entries[i].name=strrchr(ret->entries[i].localpath, PSYNC_DIRECTORY_SEPARATORC); 241 | if (ret->entries[i].name) 242 | ret->entries[i].name++; 243 | else{ 244 | ret->entries[i].name=strrchr(ret->entries[i].localpath, '/'); 245 | if (ret->entries[i].name) 246 | ret->entries[i].name++; 247 | } 248 | ret->entries[i].description=str; 249 | memcpy(str, descs[i], descslen[i]); 250 | str+=descslen[i]; 251 | psync_free(descs[i]); 252 | debug(D_NOTICE, "suggesting %s (%s, %s)", ret->entries[i].localpath, ret->entries[i].name, ret->entries[i].description); 253 | } 254 | psync_list_for_each_element_call(&suggestions, suggested_folder, list, psync_free); 255 | free_folder(f); 256 | return ret; 257 | } 258 | -------------------------------------------------------------------------------- /pscanner.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2013-2014 Anton Titov. 2 | * Copyright (c) 2013-2014 pCloud Ltd. 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * * Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * * Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * * Neither the name of pCloud Ltd nor the 13 | * names of its contributors may be used to endorse or promote products 14 | * derived from this software without specific prior written permission. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | * DISCLAIMED. IN NO EVENT SHALL pCloud Ltd BE LIABLE FOR ANY 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | #ifndef _PSYNC_SCANNER_H 29 | #define _PSYNC_SCANNER_H 30 | 31 | #include "psynclib.h" 32 | 33 | psuggested_folders_t *psync_scanner_scan_folder(const char *path); 34 | 35 | #endif -------------------------------------------------------------------------------- /pssl-mbedtls.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2015 Anton Titov. 2 | * Copyright (c) 2015 pCloud Ltd. 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * * Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * * Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * * Neither the name of pCloud Ltd nor the 13 | * names of its contributors may be used to endorse or promote products 14 | * derived from this software without specific prior written permission. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | * DISCLAIMED. IN NO EVENT SHALL pCloud Ltd BE LIABLE FOR ANY 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | #ifndef _PSYNC_MBEDTLS_H 29 | #define _PSYNC_MBEDTLS_H 30 | 31 | #include "plibs.h" 32 | #include 33 | #include 34 | #include 35 | #include 36 | 37 | #define PSYNC_INVALID_RSA NULL 38 | #define PSYNC_INVALID_SYM_KEY NULL 39 | 40 | #define PSYNC_SHA1_BLOCK_LEN 64 41 | #define PSYNC_SHA1_DIGEST_LEN 20 42 | #define PSYNC_SHA1_DIGEST_HEXLEN 40 43 | #define psync_sha1_ctx sha1_context 44 | #define psync_sha1(data, datalen, checksum) sha1(data, datalen, checksum) 45 | #define psync_sha1_init(pctx) sha1_starts(pctx) 46 | #define psync_sha1_update(pctx, data, datalen) sha1_update(pctx, (const unsigned char *)data, datalen) 47 | #define psync_sha1_final(checksum, pctx) sha1_finish(pctx, checksum) 48 | 49 | #define PSYNC_SHA512_BLOCK_LEN 128 50 | #define PSYNC_SHA512_DIGEST_LEN 64 51 | #define PSYNC_SHA512_DIGEST_HEXLEN 128 52 | #define psync_sha512_ctx sha512_context 53 | #define psync_sha512(data, datalen, checksum) sha512(data, datalen, checksum, 0) 54 | #define psync_sha512_init(pctx) sha512_starts(pctx, 0) 55 | #define psync_sha512_update(pctx, data, datalen) sha512_update(pctx, (const unsigned char *)data, datalen) 56 | #define psync_sha512_final(checksum, pctx) sha512_finish(pctx, checksum) 57 | 58 | typedef rsa_context *psync_rsa_t; 59 | typedef rsa_context *psync_rsa_publickey_t; 60 | typedef rsa_context *psync_rsa_privatekey_t; 61 | 62 | typedef struct { 63 | size_t keylen; 64 | unsigned char key[]; 65 | } psync_symmetric_key_struct_t, *psync_symmetric_key_t; 66 | 67 | typedef aes_context *psync_aes256_encoder; 68 | typedef aes_context *psync_aes256_decoder; 69 | 70 | 71 | #if defined(__GNUC__) && (defined(__amd64__) || defined(__x86_64__) || defined(__i386__)) 72 | #define PSYNC_AES_HW 73 | #define PSYNC_AES_HW_GCC 74 | #elif defined(_MSC_VER) 75 | #define PSYNC_AES_HW 76 | #define PSYNC_AES_HW_MSC 77 | #endif 78 | 79 | #if defined(PSYNC_AES_HW) 80 | extern int psync_ssl_hw_aes; 81 | 82 | void psync_aes256_encode_block_hw(psync_aes256_encoder enc, const unsigned char *src, unsigned char *dst); 83 | void psync_aes256_decode_block_hw(psync_aes256_decoder enc, const unsigned char *src, unsigned char *dst); 84 | void psync_aes256_encode_2blocks_consec_hw(psync_aes256_encoder enc, const unsigned char *src, unsigned char *dst); 85 | void psync_aes256_decode_2blocks_consec_hw(psync_aes256_decoder enc, const unsigned char *src, unsigned char *dst); 86 | void psync_aes256_decode_4blocks_consec_xor_hw(psync_aes256_decoder enc, const unsigned char *src, unsigned char *dst, unsigned char *bxor); 87 | void psync_aes256_decode_4blocks_consec_xor_sw(psync_aes256_decoder enc, const unsigned char *src, unsigned char *dst, unsigned char *bxor); 88 | 89 | static inline void psync_aes256_encode_block(psync_aes256_encoder enc, const unsigned char *src, unsigned char *dst){ 90 | if (likely(psync_ssl_hw_aes)) 91 | psync_aes256_encode_block_hw(enc, src, dst); 92 | else 93 | aes_crypt_ecb(enc, AES_ENCRYPT, src, dst); 94 | } 95 | 96 | static inline void psync_aes256_decode_block(psync_aes256_decoder enc, const unsigned char *src, unsigned char *dst){ 97 | if (likely(psync_ssl_hw_aes)) 98 | psync_aes256_decode_block_hw(enc, src, dst); 99 | else 100 | aes_crypt_ecb(enc, AES_DECRYPT, src, dst); 101 | } 102 | 103 | static inline void psync_aes256_encode_2blocks_consec(psync_aes256_decoder enc, const unsigned char *src, unsigned char *dst){ 104 | if (likely(psync_ssl_hw_aes)) 105 | psync_aes256_encode_2blocks_consec_hw(enc, src, dst); 106 | else{ 107 | aes_crypt_ecb(enc, AES_ENCRYPT, src, dst); 108 | aes_crypt_ecb(enc, AES_ENCRYPT, src+PSYNC_AES256_BLOCK_SIZE, dst+PSYNC_AES256_BLOCK_SIZE); 109 | } 110 | } 111 | 112 | static inline void psync_aes256_decode_2blocks_consec(psync_aes256_decoder enc, const unsigned char *src, unsigned char *dst){ 113 | if (likely(psync_ssl_hw_aes)) 114 | psync_aes256_decode_2blocks_consec_hw(enc, src, dst); 115 | else{ 116 | aes_crypt_ecb(enc, AES_DECRYPT, src, dst); 117 | aes_crypt_ecb(enc, AES_DECRYPT, src+PSYNC_AES256_BLOCK_SIZE, dst+PSYNC_AES256_BLOCK_SIZE); 118 | } 119 | } 120 | 121 | static inline void psync_aes256_decode_4blocks_consec_xor(psync_aes256_decoder enc, const unsigned char *src, unsigned char *dst, unsigned char *bxor){ 122 | if (psync_ssl_hw_aes) 123 | psync_aes256_decode_4blocks_consec_xor_hw(enc, src, dst, bxor); 124 | else 125 | psync_aes256_decode_4blocks_consec_xor_sw(enc, src, dst, bxor); 126 | } 127 | 128 | #else 129 | 130 | static inline void psync_aes256_encode_block(psync_aes256_encoder enc, const unsigned char *src, unsigned char *dst){ 131 | aes_crypt_ecb(enc, AES_ENCRYPT, src, dst); 132 | } 133 | 134 | static inline void psync_aes256_decode_block(psync_aes256_decoder enc, const unsigned char *src, unsigned char *dst){ 135 | aes_crypt_ecb(enc, AES_DECRYPT, src, dst); 136 | } 137 | 138 | static inline void psync_aes256_decode_2blocks_consec(psync_aes256_decoder enc, const unsigned char *src, unsigned char *dst){ 139 | aes_crypt_ecb(enc, AES_DECRYPT, src, dst); 140 | aes_crypt_ecb(enc, AES_DECRYPT, src+PSYNC_AES256_BLOCK_SIZE, dst+PSYNC_AES256_BLOCK_SIZE); 141 | } 142 | 143 | static inline void void psync_aes256_decode_4blocks_consec_xor(psync_aes256_decoder enc, const unsigned char *src, unsigned char *dst, unsigned char *bxor){ 144 | unsigned long i; 145 | aes_crypt_ecb(enc, AES_DECRYPT, src, dst); 146 | aes_crypt_ecb(enc, AES_DECRYPT, src+PSYNC_AES256_BLOCK_SIZE, dst+PSYNC_AES256_BLOCK_SIZE); 147 | aes_crypt_ecb(enc, AES_DECRYPT, src+PSYNC_AES256_BLOCK_SIZE*2, dst+PSYNC_AES256_BLOCK_SIZE*2); 148 | aes_crypt_ecb(enc, AES_DECRYPT, src+PSYNC_AES256_BLOCK_SIZE*3, dst+PSYNC_AES256_BLOCK_SIZE*3); 149 | for (i=0; i 34 | #include 35 | #include 36 | #include 37 | 38 | typedef RSA *psync_rsa_t; 39 | typedef RSA *psync_rsa_publickey_t; 40 | typedef RSA *psync_rsa_privatekey_t; 41 | 42 | typedef struct { 43 | size_t keylen; 44 | unsigned char key[]; 45 | } psync_symmetric_key_struct_t, *psync_symmetric_key_t; 46 | 47 | typedef AES_KEY *psync_aes256_encoder; 48 | typedef AES_KEY *psync_aes256_decoder; 49 | 50 | #define PSYNC_INVALID_RSA NULL 51 | #define PSYNC_INVALID_SYM_KEY NULL 52 | 53 | #define PSYNC_SHA1_BLOCK_LEN 64 54 | #define PSYNC_SHA1_DIGEST_LEN 20 55 | #define PSYNC_SHA1_DIGEST_HEXLEN 40 56 | #define psync_sha1_ctx SHA_CTX 57 | #define psync_sha1(data, datalen, checksum) SHA1(data, datalen, checksum) 58 | #define psync_sha1_init(pctx) SHA1_Init(pctx) 59 | #define psync_sha1_update(pctx, data, datalen) SHA1_Update(pctx, data, datalen) 60 | #define psync_sha1_final(checksum, pctx) SHA1_Final(checksum, pctx) 61 | 62 | #define PSYNC_SHA512_BLOCK_LEN 128 63 | #define PSYNC_SHA512_DIGEST_LEN 64 64 | #define PSYNC_SHA512_DIGEST_HEXLEN 128 65 | #define psync_sha512_ctx SHA512_CTX 66 | #define psync_sha512(data, datalen, checksum) SHA512(data, datalen, checksum) 67 | #define psync_sha512_init(pctx) SHA512_Init(pctx) 68 | #define psync_sha512_update(pctx, data, datalen) SHA512_Update(pctx, data, datalen) 69 | #define psync_sha512_final(checksum, pctx) SHA512_Final(checksum, pctx) 70 | 71 | /* AES_encrypt/AES_decrypt do not use hardware acceleration, do it ourselves */ 72 | 73 | #if defined(__GNUC__) && (defined(__amd64__) || defined(__x86_64__) || defined(__i386__)) 74 | #define PSYNC_AES_HW 75 | #define PSYNC_AES_HW_GCC 76 | #elif defined(_MSC_VER) 77 | #define PSYNC_AES_HW 78 | #define PSYNC_AES_HW_MSC 79 | #endif 80 | 81 | #if defined(PSYNC_AES_HW) 82 | extern int psync_ssl_hw_aes; 83 | 84 | void psync_aes256_encode_block_hw(psync_aes256_encoder enc, const unsigned char *src, unsigned char *dst); 85 | void psync_aes256_decode_block_hw(psync_aes256_decoder enc, const unsigned char *src, unsigned char *dst); 86 | void psync_aes256_encode_2blocks_consec_hw(psync_aes256_encoder enc, const unsigned char *src, unsigned char *dst); 87 | void psync_aes256_decode_2blocks_consec_hw(psync_aes256_decoder enc, const unsigned char *src, unsigned char *dst); 88 | void psync_aes256_decode_4blocks_consec_xor_hw(psync_aes256_decoder enc, const unsigned char *src, unsigned char *dst, unsigned char *bxor); 89 | void psync_aes256_decode_4blocks_consec_xor_sw(psync_aes256_decoder enc, const unsigned char *src, unsigned char *dst, unsigned char *bxor); 90 | 91 | static inline void psync_aes256_encode_block(psync_aes256_encoder enc, const unsigned char *src, unsigned char *dst){ 92 | if (likely(psync_ssl_hw_aes)) 93 | psync_aes256_encode_block_hw(enc, src, dst); 94 | else 95 | AES_encrypt(src, dst, enc); 96 | } 97 | 98 | static inline void psync_aes256_decode_block(psync_aes256_decoder enc, const unsigned char *src, unsigned char *dst){ 99 | if (likely(psync_ssl_hw_aes)) 100 | psync_aes256_decode_block_hw(enc, src, dst); 101 | else 102 | AES_decrypt(src, dst, enc); 103 | } 104 | 105 | static inline void psync_aes256_encode_2blocks_consec(psync_aes256_decoder enc, const unsigned char *src, unsigned char *dst){ 106 | if (likely(psync_ssl_hw_aes)) 107 | psync_aes256_encode_2blocks_consec_hw(enc, src, dst); 108 | else{ 109 | AES_encrypt(src, dst, enc); 110 | AES_encrypt(src+PSYNC_AES256_BLOCK_SIZE, dst+PSYNC_AES256_BLOCK_SIZE, enc); 111 | } 112 | } 113 | 114 | static inline void psync_aes256_decode_2blocks_consec(psync_aes256_decoder enc, const unsigned char *src, unsigned char *dst){ 115 | if (likely(psync_ssl_hw_aes)) 116 | psync_aes256_decode_2blocks_consec_hw(enc, src, dst); 117 | else{ 118 | AES_decrypt(src, dst, enc); 119 | AES_decrypt(src+PSYNC_AES256_BLOCK_SIZE, dst+PSYNC_AES256_BLOCK_SIZE, enc); 120 | } 121 | } 122 | 123 | static inline void psync_aes256_decode_4blocks_consec_xor(psync_aes256_decoder enc, const unsigned char *src, unsigned char *dst, unsigned char *bxor){ 124 | if (psync_ssl_hw_aes) 125 | psync_aes256_decode_4blocks_consec_xor_hw(enc, src, dst, bxor); 126 | else 127 | psync_aes256_decode_4blocks_consec_xor_sw(enc, src, dst, bxor); 128 | } 129 | 130 | #else 131 | 132 | static inline void psync_aes256_encode_block(psync_aes256_encoder enc, const unsigned char *src, unsigned char *dst){ 133 | AES_encrypt(src, dst, enc); 134 | } 135 | 136 | static inline void psync_aes256_decode_block(psync_aes256_decoder enc, const unsigned char *src, unsigned char *dst){ 137 | AES_decrypt(src, dst, enc); 138 | } 139 | 140 | static inline void psync_aes256_decode_2blocks_consec(psync_aes256_decoder enc, const unsigned char *src, unsigned char *dst){ 141 | AES_decrypt(src, dst, enc); 142 | AES_decrypt(src+PSYNC_AES256_BLOCK_SIZE, dst+PSYNC_AES256_BLOCK_SIZE, enc); 143 | } 144 | 145 | static inline void void psync_aes256_decode_4blocks_consec_xor(psync_aes256_decoder enc, const unsigned char *src, unsigned char *dst, unsigned char *bxor){ 146 | unsigned long i; 147 | AES_decrypt(src, dst, enc); 148 | AES_decrypt(src+PSYNC_AES256_BLOCK_SIZE, dst+PSYNC_AES256_BLOCK_SIZE, enc); 149 | AES_decrypt(src+PSYNC_AES256_BLOCK_SIZE*2, dst+PSYNC_AES256_BLOCK_SIZE*2, enc); 150 | AES_decrypt(src+PSYNC_AES256_BLOCK_SIZE*3, dst+PSYNC_AES256_BLOCK_SIZE*3, enc); 151 | for (i=0; i 32 | #include 33 | #include 34 | 35 | typedef struct { 36 | SecKeyRef public_key; 37 | SecKeyRef private_key; 38 | } psync_rsa_struct_t, *psync_rsa_t; 39 | 40 | typedef SecKeyRef psync_rsa_publickey_t; 41 | typedef SecKeyRef psync_rsa_privatekey_t; 42 | 43 | typedef struct { 44 | size_t keylen; 45 | unsigned char key[]; 46 | } psync_symmetric_key_struct_t, *psync_symmetric_key_t; 47 | 48 | typedef CCCryptorRef psync_aes256_encoder; 49 | typedef CCCryptorRef psync_aes256_decoder; 50 | 51 | #define PSYNC_INVALID_RSA NULL 52 | #define PSYNC_INVALID_SYM_KEY NULL 53 | 54 | #define PSYNC_SHA1_BLOCK_LEN 64 55 | #define PSYNC_SHA1_DIGEST_LEN 20 56 | #define PSYNC_SHA1_DIGEST_HEXLEN 40 57 | #define psync_sha1_ctx CC_SHA1_CTX 58 | #define psync_sha1(data, datalen, checksum) CC_SHA1(data, datalen, checksum) 59 | #define psync_sha1_init(pctx) CC_SHA1_Init(pctx) 60 | #define psync_sha1_update(pctx, data, datalen) CC_SHA1_Update(pctx, data, datalen) 61 | #define psync_sha1_final(checksum, pctx) CC_SHA1_Final(checksum, pctx) 62 | 63 | static inline void psync_aes256_encode_block(psync_aes256_encoder enc, const unsigned char *src, unsigned char *dst){ 64 | size_t n; 65 | CCCryptorUpdate(enc, src, 16, dst, 16, &n); 66 | } 67 | 68 | static inline void psync_aes256_decode_block(psync_aes256_decoder enc, const unsigned char *src, unsigned char *dst){ 69 | size_t n; 70 | CCCryptorUpdate(enc, src, 16, dst, 16, &n); 71 | } 72 | 73 | 74 | #endif -------------------------------------------------------------------------------- /pssl.c: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2014 Anton Titov. 2 | * Copyright (c) 2014 pCloud Ltd. 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * * Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * * Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * * Neither the name of pCloud Ltd nor the 13 | * names of its contributors may be used to endorse or promote products 14 | * derived from this software without specific prior written permission. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | * DISCLAIMED. IN NO EVENT SHALL pCloud Ltd BE LIABLE FOR ANY 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | #include "pssl.h" 29 | #include "psynclib.h" 30 | #include "pmemlock.h" 31 | #include 32 | #include 33 | 34 | static void psync_ssl_free_psync_encrypted_data_t(psync_encrypted_data_t e){ 35 | psync_ssl_memclean(e->data, e->datalen); 36 | psync_locked_free(e); 37 | } 38 | 39 | void psync_ssl_rsa_free_binary(psync_binary_rsa_key_t bin){ 40 | psync_ssl_free_psync_encrypted_data_t(bin); 41 | } 42 | 43 | void psync_ssl_free_symmetric_key(psync_symmetric_key_t key){ 44 | psync_ssl_memclean(key->key, key->keylen); 45 | psync_locked_free(key); 46 | } 47 | 48 | psync_encrypted_symmetric_key_t psync_ssl_alloc_encrypted_symmetric_key(size_t len){ 49 | psync_encrypted_symmetric_key_t ret; 50 | ret=psync_malloc(offsetof(psync_encrypted_data_struct_t, data)+len); 51 | ret->datalen=len; 52 | return ret; 53 | } 54 | 55 | psync_encrypted_symmetric_key_t psync_ssl_copy_encrypted_symmetric_key(psync_encrypted_symmetric_key_t src){ 56 | psync_encrypted_symmetric_key_t ret; 57 | ret=psync_malloc(offsetof(psync_encrypted_data_struct_t, data)+src->datalen); 58 | ret->datalen=src->datalen; 59 | memcpy(ret->data, src->data, src->datalen); 60 | return ret; 61 | } 62 | -------------------------------------------------------------------------------- /pssl.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2013-2014 Anton Titov. 2 | * Copyright (c) 2013-2014 pCloud Ltd. 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * * Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * * Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * * Neither the name of pCloud Ltd nor the 13 | * names of its contributors may be used to endorse or promote products 14 | * derived from this software without specific prior written permission. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | * DISCLAIMED. IN NO EVENT SHALL pCloud Ltd BE LIABLE FOR ANY 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | #ifndef _PSYNC_SSL_H 29 | #define _PSYNC_SSL_H 30 | 31 | #include "pcompiler.h" 32 | #include "pcompat.h" 33 | 34 | #define PSYNC_AES256_BLOCK_SIZE 16 35 | #define PSYNC_AES256_KEY_SIZE 32 36 | 37 | #if defined(P_SSL_OPENSSL) 38 | #include "pssl-openssl.h" 39 | #elif defined(P_SSL_MBEDTLS) 40 | #include "pssl-mbedtls.h" 41 | #elif defined(P_SSL_SECURETRANSPORT) 42 | #include "pssl-securetransport.h" 43 | #else 44 | #error "Please specify SSL library to use" 45 | #include "pssl-openssl.h" 46 | #endif 47 | 48 | extern PSYNC_THREAD int psync_ssl_errno; 49 | 50 | #define PSYNC_SSL_ERR_WANT_READ 1 51 | #define PSYNC_SSL_ERR_WANT_WRITE 2 52 | #define PSYNC_SSL_ERR_UNKNOWN 3 53 | 54 | #define PSYNC_SSL_NEED_FINISH -2 55 | #define PSYNC_SSL_FAIL -1 56 | #define PSYNC_SSL_SUCCESS 0 57 | 58 | typedef struct { 59 | size_t datalen; 60 | unsigned char data[]; 61 | } psync_encrypted_data_struct_t, *psync_encrypted_data_t; 62 | 63 | typedef psync_encrypted_data_t psync_encrypted_symmetric_key_t; 64 | typedef psync_encrypted_data_t psync_binary_rsa_key_t; 65 | 66 | #define PSYNC_INVALID_ENC_SYM_KEY NULL 67 | #define PSYNC_INVALID_ENCODER NULL 68 | #define PSYNC_INVALID_BIN_RSA NULL 69 | 70 | #define psync_ssl_alloc_binary_rsa psync_ssl_alloc_encrypted_symmetric_key 71 | 72 | int psync_ssl_init(); 73 | void psync_ssl_memclean(void *ptr, size_t len); 74 | int psync_ssl_connect(psync_socket_t sock, void **sslconn, const char *hostname); 75 | int psync_ssl_connect_finish(void *sslconn, const char *hostname); 76 | void psync_ssl_free(void *sslconn); 77 | int psync_ssl_shutdown(void *sslconn); 78 | int psync_ssl_pendingdata(void *sslconn); 79 | int psync_ssl_read(void *sslconn, void *buf, int num); 80 | int psync_ssl_write(void *sslconn, const void *buf, int num); 81 | 82 | void psync_ssl_rand_strong(unsigned char *buf, int num); 83 | void psync_ssl_rand_weak(unsigned char *buf, int num); 84 | 85 | psync_rsa_t psync_ssl_gen_rsa(int bits); 86 | void psync_ssl_free_rsa(psync_rsa_t rsa); 87 | psync_rsa_publickey_t psync_ssl_rsa_get_public(psync_rsa_t rsa); 88 | void psync_ssl_rsa_free_public(psync_rsa_publickey_t key); 89 | psync_rsa_privatekey_t psync_ssl_rsa_get_private(psync_rsa_t rsa); 90 | void psync_ssl_rsa_free_private(psync_rsa_privatekey_t key); 91 | psync_binary_rsa_key_t psync_ssl_rsa_public_to_binary(psync_rsa_publickey_t rsa); 92 | psync_binary_rsa_key_t psync_ssl_rsa_private_to_binary(psync_rsa_privatekey_t rsa); 93 | psync_rsa_publickey_t psync_ssl_rsa_load_public(const unsigned char *keydata, size_t keylen); 94 | psync_rsa_privatekey_t psync_ssl_rsa_load_private(const unsigned char *keydata, size_t keylen); 95 | psync_rsa_publickey_t psync_ssl_rsa_binary_to_public(psync_binary_rsa_key_t bin); 96 | psync_rsa_privatekey_t psync_ssl_rsa_binary_to_private(psync_binary_rsa_key_t bin); 97 | void psync_ssl_rsa_free_binary(psync_binary_rsa_key_t bin); 98 | 99 | psync_symmetric_key_t psync_ssl_gen_symmetric_key_from_pass(const char *password, size_t keylen, const unsigned char *salt, size_t saltlen, size_t iterations); 100 | psync_encrypted_symmetric_key_t psync_ssl_alloc_encrypted_symmetric_key(size_t len); 101 | psync_encrypted_symmetric_key_t psync_ssl_copy_encrypted_symmetric_key(psync_encrypted_symmetric_key_t src); 102 | void psync_ssl_free_symmetric_key(psync_symmetric_key_t key); 103 | 104 | psync_encrypted_symmetric_key_t psync_ssl_rsa_encrypt_data(psync_rsa_publickey_t rsa, const unsigned char *data, size_t datalen); 105 | psync_symmetric_key_t psync_ssl_rsa_decrypt_data(psync_rsa_privatekey_t rsa, const unsigned char *data, size_t datalen); 106 | psync_encrypted_symmetric_key_t psync_ssl_rsa_encrypt_symmetric_key(psync_rsa_publickey_t rsa, const psync_symmetric_key_t key); 107 | psync_symmetric_key_t psync_ssl_rsa_decrypt_symmetric_key(psync_rsa_privatekey_t rsa, const psync_encrypted_symmetric_key_t enckey); 108 | 109 | psync_aes256_encoder psync_ssl_aes256_create_encoder(psync_symmetric_key_t key); 110 | void psync_ssl_aes256_free_encoder(psync_aes256_encoder aes); 111 | psync_aes256_encoder psync_ssl_aes256_create_decoder(psync_symmetric_key_t key); 112 | void psync_ssl_aes256_free_decoder(psync_aes256_encoder aes); 113 | 114 | #endif 115 | -------------------------------------------------------------------------------- /pstatus.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2013-2014 Anton Titov. 2 | * Copyright (c) 2013-2014 pCloud Ltd. 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * * Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * * Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * * Neither the name of pCloud Ltd nor the 13 | * names of its contributors may be used to endorse or promote products 14 | * derived from this software without specific prior written permission. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | * DISCLAIMED. IN NO EVENT SHALL pCloud Ltd BE LIABLE FOR ANY 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | #ifndef _PSYNC_STATUS_H 29 | #define _PSYNC_STATUS_H 30 | 31 | #include "pcompiler.h" 32 | #include 33 | 34 | #define PSTATUS_NUM_STATUSES 6 35 | 36 | #define PSTATUS_TYPE_RUN 0 37 | #define PSTATUS_TYPE_ONLINE 1 38 | #define PSTATUS_TYPE_AUTH 2 39 | #define PSTATUS_TYPE_ACCFULL 3 40 | #define PSTATUS_TYPE_DISKFULL 4 41 | #define PSTATUS_TYPE_LOCALSCAN 5 42 | 43 | #define PSTATUS_INVALID 0 44 | 45 | #define PSTATUS_RUN_RUN 1 46 | #define PSTATUS_RUN_PAUSE 2 47 | #define PSTATUS_RUN_STOP 4 48 | 49 | #define PSTATUS_ONLINE_CONNECTING 1 50 | #define PSTATUS_ONLINE_SCANNING 2 51 | #define PSTATUS_ONLINE_ONLINE 4 52 | #define PSTATUS_ONLINE_OFFLINE 8 53 | 54 | #define PSTATUS_AUTH_PROVIDED 1 55 | #define PSTATUS_AUTH_REQUIRED 2 56 | #define PSTATUS_AUTH_MISMATCH 4 57 | #define PSTATUS_AUTH_BADLOGIN 8 58 | #define PSTATUS_AUTH_BADTOKEN 16 59 | 60 | #define PSTATUS_ACCFULL_QUOTAOK 1 61 | #define PSTATUS_ACCFULL_OVERQUOTA 2 62 | 63 | #define PSTATUS_DISKFULL_OK 1 64 | #define PSTATUS_DISKFULL_FULL 2 65 | 66 | #define PSTATUS_LOCALSCAN_SCANNING 1 67 | #define PSTATUS_LOCALSCAN_READY 2 68 | 69 | #define PSTATUS_COMBINE(type, statuses) (((type)<<24)+(statuses)) 70 | 71 | void psync_status_init(); 72 | void psync_status_recalc_to_download(); 73 | void psync_status_recalc_to_upload(); 74 | void psync_status_recalc_to_upload_async(); 75 | uint32_t psync_status_get(uint32_t statusid); 76 | void psync_set_status(uint32_t statusid, uint32_t status); 77 | void psync_wait_status(uint32_t statusid, uint32_t status); 78 | void psync_terminate_status_waiters(); 79 | void psync_wait_statuses_array(const uint32_t *combinedstatuses, uint32_t cnt); 80 | void psync_wait_statuses(uint32_t first, ...); 81 | int psync_statuses_ok_array(const uint32_t *combinedstatuses, uint32_t cnt); 82 | 83 | void psync_status_set_download_speed(uint32_t speed); 84 | void psync_status_set_upload_speed(uint32_t speed);; 85 | 86 | void psync_status_send_update(); 87 | 88 | static inline int psync_status_is_offline(){ 89 | return psync_status_get(PSTATUS_TYPE_ONLINE)==PSTATUS_ONLINE_OFFLINE; 90 | } 91 | #endif -------------------------------------------------------------------------------- /psyncer.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2013-2014 Anton Titov. 2 | * Copyright (c) 2013-2014 pCloud Ltd. 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * * Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * * Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * * Neither the name of pCloud Ltd nor the 13 | * names of its contributors may be used to endorse or promote products 14 | * derived from this software without specific prior written permission. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | * DISCLAIMED. IN NO EVENT SHALL pCloud Ltd BE LIABLE FOR ANY 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | #ifndef _PSYNC_SYNCER_H 29 | #define _PSYNC_SYNCER_H 30 | 31 | #include "psynclib.h" 32 | 33 | void psync_syncer_init(); 34 | void psync_syncer_new(psync_syncid_t syncid); 35 | 36 | void psync_increase_local_folder_taskcnt(psync_folderid_t lfolderid); 37 | void psync_decrease_local_folder_taskcnt(psync_folderid_t lfolderid); 38 | psync_folderid_t psync_create_local_folder_in_db(psync_syncid_t syncid, psync_folderid_t folderid, psync_folderid_t localparentfolderid, const char *name); 39 | void psync_add_folder_for_downloadsync(psync_syncid_t syncid, psync_synctype_t synctype, psync_folderid_t folderid, psync_folderid_t lfoiderid); 40 | 41 | void psync_add_folder_to_downloadlist(psync_folderid_t folderid); 42 | void psync_del_folder_from_downloadlist(psync_folderid_t folderid); 43 | int psync_is_folder_in_downloadlist(psync_folderid_t folderid); 44 | 45 | int psync_str_is_prefix(const char *str1, const char *str2); 46 | void psync_syncer_check_delayed_syncs(); 47 | 48 | #endif -------------------------------------------------------------------------------- /ptasks.c: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2013-2014 Anton Titov. 2 | * Copyright (c) 2013-2014 pCloud Ltd. 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * * Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * * Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * * Neither the name of pCloud Ltd nor the 13 | * names of its contributors may be used to endorse or promote products 14 | * derived from this software without specific prior written permission. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | * DISCLAIMED. IN NO EVENT SHALL pCloud Ltd BE LIABLE FOR ANY 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | #include "ptasks.h" 29 | #include "plibs.h" 30 | #include "pdownload.h" 31 | #include "pupload.h" 32 | #include "pstatus.h" 33 | #include "pcallbacks.h" 34 | 35 | static void create_task1(psync_uint_t type, psync_syncid_t syncid, uint64_t entryid, uint64_t localentryid){ 36 | psync_sql_res *res; 37 | res=psync_sql_prep_statement("INSERT INTO task (type, syncid, itemid, localitemid) VALUES (?, ?, ?, ?)"); 38 | psync_sql_bind_uint(res, 1, type); 39 | psync_sql_bind_uint(res, 2, syncid); 40 | psync_sql_bind_uint(res, 3, entryid); 41 | psync_sql_bind_uint(res, 4, localentryid); 42 | psync_sql_run_free(res); 43 | } 44 | 45 | static void create_task2(psync_uint_t type, psync_syncid_t syncid, uint64_t entryid, uint64_t localentryid, uint64_t newitemid, const char *name){ 46 | psync_sql_res *res; 47 | res=psync_sql_prep_statement("INSERT INTO task (type, syncid, itemid, localitemid, newitemid, name) VALUES (?, ?, ?, ?, ?, ?)"); 48 | psync_sql_bind_uint(res, 1, type); 49 | psync_sql_bind_uint(res, 2, syncid); 50 | psync_sql_bind_uint(res, 3, entryid); 51 | psync_sql_bind_uint(res, 4, localentryid); 52 | psync_sql_bind_uint(res, 5, newitemid); 53 | psync_sql_bind_string(res, 6, name); 54 | psync_sql_run_free(res); 55 | } 56 | 57 | static void create_task3(psync_uint_t type, psync_syncid_t syncid, uint64_t entryid, uint64_t localentryid, const char *name){ 58 | psync_sql_res *res; 59 | res=psync_sql_prep_statement("INSERT INTO task (type, syncid, itemid, localitemid, name) VALUES (?, ?, ?, ?, ?)"); 60 | psync_sql_bind_uint(res, 1, type); 61 | psync_sql_bind_uint(res, 2, syncid); 62 | psync_sql_bind_uint(res, 3, entryid); 63 | psync_sql_bind_uint(res, 4, localentryid); 64 | psync_sql_bind_string(res, 5, name); 65 | psync_sql_run_free(res); 66 | } 67 | 68 | static void create_task4(psync_uint_t type, uint64_t entryid, const char *name){ 69 | psync_sql_res *res; 70 | res=psync_sql_prep_statement("INSERT INTO task (type, itemid, localitemid, name) VALUES (?, ?, 0, ?)"); 71 | psync_sql_bind_uint(res, 1, type); 72 | psync_sql_bind_uint(res, 2, entryid); 73 | psync_sql_bind_string(res, 3, name); 74 | psync_sql_run_free(res); 75 | } 76 | 77 | static void create_task5(psync_uint_t type, psync_syncid_t syncid, uint64_t entryid){ 78 | psync_sql_res *res; 79 | res=psync_sql_prep_statement("INSERT INTO task (type, syncid, itemid, localitemid) VALUES (?, ?, ?, 0)"); 80 | psync_sql_bind_uint(res, 1, type); 81 | psync_sql_bind_uint(res, 2, syncid); 82 | psync_sql_bind_uint(res, 3, entryid); 83 | psync_sql_run_free(res); 84 | } 85 | 86 | static void create_task6(psync_uint_t type, psync_syncid_t syncid, uint64_t entryid, const char *name){ 87 | psync_sql_res *res; 88 | res=psync_sql_prep_statement("INSERT INTO task (type, syncid, itemid, localitemid, name) VALUES (?, ?, ?, 0, ?)"); 89 | psync_sql_bind_uint(res, 1, type); 90 | psync_sql_bind_uint(res, 2, syncid); 91 | psync_sql_bind_uint(res, 3, entryid); 92 | psync_sql_bind_string(res, 4, name); 93 | psync_sql_run_free(res); 94 | } 95 | 96 | void psync_task_create_local_folder(psync_syncid_t syncid, psync_folderid_t folderid, psync_folderid_t localfolderid){ 97 | create_task1(PSYNC_CREATE_LOCAL_FOLDER, syncid, folderid, localfolderid); 98 | } 99 | 100 | void psync_task_delete_local_folder(psync_syncid_t syncid, psync_folderid_t folderid, psync_folderid_t localfolderid, const char *remotepath){ 101 | create_task3(PSYNC_DELETE_LOCAL_FOLDER, syncid, folderid, localfolderid, remotepath); 102 | } 103 | 104 | void psync_task_delete_local_folder_recursive(psync_syncid_t syncid, psync_folderid_t folderid, psync_folderid_t localfolderid){ 105 | create_task1(PSYNC_DELREC_LOCAL_FOLDER, syncid, folderid, localfolderid); 106 | } 107 | 108 | void psync_task_rename_local_folder(psync_syncid_t syncid, psync_folderid_t folderid, psync_folderid_t localfolderid, 109 | psync_folderid_t newlocalparentfolderid, const char *newname){ 110 | create_task2(PSYNC_RENAME_LOCAL_FOLDER, syncid, folderid, localfolderid, newlocalparentfolderid, newname); 111 | } 112 | 113 | void psync_task_download_file(psync_syncid_t syncid, psync_fileid_t fileid, psync_folderid_t localfolderid, const char *name){ 114 | create_task3(PSYNC_DOWNLOAD_FILE, syncid, fileid, localfolderid, name); 115 | psync_wake_download(); 116 | psync_status_recalc_to_download(); 117 | psync_send_status_update(); 118 | } 119 | 120 | void psync_task_download_file_silent(psync_syncid_t syncid, psync_fileid_t fileid, psync_folderid_t localfolderid, const char *name){ 121 | create_task3(PSYNC_DOWNLOAD_FILE, syncid, fileid, localfolderid, name); 122 | } 123 | 124 | void psync_task_rename_local_file(psync_syncid_t oldsyncid, psync_syncid_t newsyncid, psync_fileid_t fileid, psync_folderid_t oldlocalfolderid, 125 | psync_folderid_t newlocalfolderid, const char *newname){ 126 | psync_sql_res *res; 127 | res=psync_sql_prep_statement("INSERT INTO task (type, syncid, newsyncid, itemid, localitemid, newitemid, name) VALUES (?, ?, ?, ?, ?, ?, ?)"); 128 | psync_sql_bind_uint(res, 1, PSYNC_RENAME_LOCAL_FILE); 129 | psync_sql_bind_uint(res, 2, oldsyncid); 130 | psync_sql_bind_uint(res, 3, newsyncid); 131 | psync_sql_bind_uint(res, 4, fileid); 132 | psync_sql_bind_uint(res, 5, oldlocalfolderid); 133 | psync_sql_bind_uint(res, 6, newlocalfolderid); 134 | psync_sql_bind_string(res, 7, newname); 135 | psync_sql_run_free(res); 136 | } 137 | 138 | void psync_task_delete_local_file(psync_fileid_t fileid, const char *remotepath){ 139 | create_task4(PSYNC_DELETE_LOCAL_FILE, fileid, remotepath); 140 | } 141 | 142 | void psync_task_delete_local_file_syncid(psync_syncid_t syncid, psync_fileid_t fileid, const char *remotepath){ 143 | create_task6(PSYNC_DELETE_LOCAL_FILE, syncid, fileid, remotepath); 144 | } 145 | 146 | void psync_task_create_remote_folder(psync_syncid_t syncid, psync_folderid_t localfolderid, const char *name){ 147 | create_task3(PSYNC_CREATE_REMOTE_FOLDER, syncid, 0, localfolderid, name); 148 | } 149 | 150 | void psync_task_upload_file(psync_syncid_t syncid, psync_fileid_t localfileid, const char *name){ 151 | create_task3(PSYNC_UPLOAD_FILE, syncid, 0, localfileid, name); 152 | psync_wake_upload(); 153 | psync_status_recalc_to_upload_async(); 154 | } 155 | 156 | void psync_task_upload_file_silent(psync_syncid_t syncid, psync_fileid_t localfileid, const char *name){ 157 | create_task3(PSYNC_UPLOAD_FILE, syncid, 0, localfileid, name); 158 | } 159 | 160 | void psync_task_rename_remote_file(psync_syncid_t oldsyncid, psync_syncid_t newsyncid, psync_fileid_t localfileid, 161 | psync_folderid_t newlocalparentfolderid, const char *newname){ 162 | psync_sql_res *res; 163 | res=psync_sql_prep_statement("INSERT INTO task (type, syncid, newsyncid, localitemid, newitemid, name, itemid) VALUES (?, ?, ?, ?, ?, ?, 0)"); 164 | psync_sql_bind_uint(res, 1, PSYNC_RENAME_REMOTE_FILE); 165 | psync_sql_bind_uint(res, 2, oldsyncid); 166 | psync_sql_bind_uint(res, 3, newsyncid); 167 | psync_sql_bind_uint(res, 4, localfileid); 168 | psync_sql_bind_uint(res, 5, newlocalparentfolderid); 169 | psync_sql_bind_string(res, 6, newname); 170 | psync_sql_run_free(res); 171 | } 172 | 173 | void psync_task_rename_remote_folder(psync_syncid_t oldsyncid, psync_syncid_t newsyncid, psync_fileid_t localfileid, 174 | psync_folderid_t newlocalparentfolderid, const char *newname){ 175 | psync_sql_res *res; 176 | res=psync_sql_prep_statement("INSERT INTO task (type, syncid, newsyncid, localitemid, newitemid, name, itemid) VALUES (?, ?, ?, ?, ?, ?, 0)"); 177 | psync_sql_bind_uint(res, 1, PSYNC_RENAME_REMOTE_FOLDER); 178 | psync_sql_bind_uint(res, 2, oldsyncid); 179 | psync_sql_bind_uint(res, 3, newsyncid); 180 | psync_sql_bind_uint(res, 4, localfileid); 181 | psync_sql_bind_uint(res, 5, newlocalparentfolderid); 182 | psync_sql_bind_string(res, 6, newname); 183 | psync_sql_run_free(res); 184 | } 185 | 186 | void psync_task_delete_remote_file(psync_syncid_t syncid, psync_fileid_t fileid){ 187 | create_task5(PSYNC_DELETE_REMOTE_FILE, syncid, fileid); 188 | } 189 | 190 | void psync_task_delete_remote_folder(psync_syncid_t syncid, psync_folderid_t folderid){ 191 | create_task5(PSYNC_DELREC_REMOTE_FOLDER, syncid, folderid); 192 | } 193 | -------------------------------------------------------------------------------- /ptasks.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2013-2014 Anton Titov. 2 | * Copyright (c) 2013-2014 pCloud Ltd. 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * * Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * * Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * * Neither the name of pCloud Ltd nor the 13 | * names of its contributors may be used to endorse or promote products 14 | * derived from this software without specific prior written permission. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | * DISCLAIMED. IN NO EVENT SHALL pCloud Ltd BE LIABLE FOR ANY 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | #ifndef _PSYNC_TASKS_H 29 | #define _PSYNC_TASKS_H 30 | 31 | #include "pcompiler.h" 32 | #include "psynclib.h" 33 | 34 | #define PSYNC_TASK_DOWNLOAD 0 35 | #define PSYNC_TASK_UPLOAD 1 36 | #define PSYNC_TASK_DWLUPL_MASK 1 37 | 38 | #define PSYNC_TASK_FOLDER 0 39 | #define PSYNC_TASK_FILE 2 40 | 41 | #define PSYNC_TASK_TYPE_OFF 2 42 | 43 | #define PSYNC_TASK_TYPE_CREATE 0 44 | #define PSYNC_TASK_TYPE_DELETE 1 45 | #define PSYNC_TASK_TYPE_DELREC 2 46 | #define PSYNC_TASK_TYPE_RENAME 3 47 | #define PSYNC_TASK_TYPE_COPY 4 48 | 49 | #define PSYNC_CREATE_LOCAL_FOLDER ((PSYNC_TASK_TYPE_CREATE<func(); 74 | e=e->next; 75 | } 76 | pthread_mutex_unlock(&timer_ex_mutex); 77 | psync_cache_clean_all(); 78 | psync_timer_notify_exception(); 79 | } 80 | 81 | static void timer_check_upper_levels(time_t tmdiv, psync_uint_t level, psync_uint_t sh){ 82 | psync_list *l1, *l2, *l; 83 | time_t m; 84 | m=tmdiv%TIMER_ARRAY_SIZE; 85 | if (m==0 && levelrunat>>sh)%TIMER_ARRAY_SIZE], l1); 90 | psync_list_init(&timerlists[level+1][m]); 91 | } 92 | 93 | static void timer_prepare_timers(time_t from, time_t to, psync_list *list){ 94 | time_t i, m; 95 | psync_list *l1, *l2; 96 | for (i=from+1; i<=to; i++){ 97 | m=i%TIMER_ARRAY_SIZE; 98 | if (m==0) 99 | timer_check_upper_levels(i/TIMER_ARRAY_SIZE, 0, 0); 100 | psync_list_for_each_safe(l1, l2, &timerlists[0][m]){ 101 | psync_list_element(l1, psync_timer_structure_t, list)->opts|=PTIMER_IS_RUNNING; 102 | psync_list_add_tail(list, l1); 103 | } 104 | psync_list_init(&timerlists[0][m]); 105 | } 106 | } 107 | 108 | PSYNC_NOINLINE static void timer_process_timers(psync_list *timers){ 109 | psync_timer_t timer; 110 | psync_list *l1, *l2; 111 | psync_list_for_each_element(timer, timers, psync_timer_structure_t, list) 112 | timer->call(timer, timer->param); 113 | pthread_mutex_lock(&timer_mutex); 114 | psync_list_for_each_safe(l1, l2, timers){ 115 | timer=psync_list_element(l1, psync_timer_structure_t, list); 116 | if (!(timer->opts&PTIMER_STOP_AFTER_RUN)){ 117 | timer->opts=0; 118 | psync_list_del(l1); 119 | timer->runat=psync_current_time+timer->numsec; 120 | psync_list_add_tail(&timerlists[timer->level][(timer->runat>>(timer->level*TIMER_ARRAY_SIZE_SHIFT))%TIMER_ARRAY_SIZE], &timer->list); 121 | } 122 | } 123 | pthread_mutex_unlock(&timer_mutex); 124 | psync_list_for_each_element_call(timers, psync_timer_structure_t, list, psync_free); 125 | } 126 | 127 | static void timer_thread(){ 128 | psync_list timers; 129 | time_t lt; 130 | lt=psync_current_time; 131 | while (psync_do_run){ 132 | psync_list_init(&timers); 133 | psync_milisleep(1000); 134 | psync_current_time=psync_time(); 135 | pthread_mutex_lock(&timer_mutex); 136 | timer_prepare_timers(lt, psync_current_time, &timers); 137 | if (nextsecwaiters) 138 | pthread_cond_broadcast(&timer_cond); 139 | pthread_mutex_unlock(&timer_mutex); 140 | if (unlikely(!psync_list_isempty(&timers))) 141 | timer_process_timers(&timers); 142 | if (unlikely(psync_current_time-lt>=20)) 143 | timer_sleep_detected(lt); 144 | else if (unlikely_log(psync_current_time==lt)){ 145 | if (!psync_do_run) 146 | break; 147 | psync_milisleep(1000); 148 | } 149 | lt=psync_current_time; 150 | } 151 | } 152 | 153 | void psync_timer_init(){ 154 | psync_uint_t i, j; 155 | for (i=0; icall=func; 180 | timer->param=param; 181 | n=TIMER_ARRAY_SIZE; 182 | for (i=0; inumsec=numsec; 195 | timer->level=i; 196 | timer->opts=0; 197 | pthread_mutex_lock(&timer_mutex); 198 | timer->runat=psync_current_time+numsec; 199 | psync_list_add_tail(&timerlists[i][(timer->runat>>(i*TIMER_ARRAY_SIZE_SHIFT))%TIMER_ARRAY_SIZE], &timer->list); 200 | pthread_mutex_unlock(&timer_mutex); 201 | return timer; 202 | } 203 | 204 | int psync_timer_stop(psync_timer_t timer){ 205 | int needfree=0; 206 | pthread_mutex_lock(&timer_mutex); 207 | if (timer->opts&PTIMER_IS_RUNNING) 208 | timer->opts|=PTIMER_STOP_AFTER_RUN; 209 | else{ 210 | psync_list_del(&timer->list); 211 | needfree=1; 212 | } 213 | pthread_mutex_unlock(&timer_mutex); 214 | if (needfree){ 215 | psync_free(timer); 216 | return 0; 217 | } 218 | else 219 | return 1; 220 | } 221 | 222 | void psync_timer_exception_handler(psync_exception_callback func){ 223 | struct exception_list *t; 224 | t=psync_new(struct exception_list); 225 | t->next=NULL; 226 | t->func=func; 227 | t->threadid=pthread_self(); 228 | pthread_mutex_lock(&timer_ex_mutex); 229 | t->next=excepions; 230 | excepions=t; 231 | pthread_mutex_unlock(&timer_ex_mutex); 232 | } 233 | 234 | void psync_timer_sleep_handler(psync_exception_callback func){ 235 | struct exception_list *t; 236 | t=psync_new(struct exception_list); 237 | t->next=NULL; 238 | t->func=func; 239 | t->threadid=pthread_self(); 240 | pthread_mutex_lock(&timer_ex_mutex); 241 | t->next=sleeplist; 242 | sleeplist=t; 243 | pthread_mutex_unlock(&timer_ex_mutex); 244 | } 245 | 246 | void psync_timer_do_notify_exception(){ 247 | struct exception_list *e; 248 | pthread_t threadid; 249 | e=excepions; 250 | threadid=pthread_self(); 251 | pthread_mutex_lock(&timer_ex_mutex); 252 | while (e){ 253 | if (!pthread_equal(threadid, e->threadid)) 254 | e->func(); 255 | e=e->next; 256 | } 257 | pthread_mutex_unlock(&timer_ex_mutex); 258 | } 259 | 260 | void psync_timer_wait_next_sec(){ 261 | time_t ctime; 262 | pthread_mutex_lock(&timer_mutex); 263 | ctime=psync_current_time; 264 | do { 265 | nextsecwaiters++; 266 | pthread_cond_wait(&timer_cond, &timer_mutex); 267 | nextsecwaiters--; 268 | } while (ctime==psync_current_time); 269 | pthread_mutex_unlock(&timer_mutex); 270 | } 271 | -------------------------------------------------------------------------------- /ptimer.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2013-2014 Anton Titov. 2 | * Copyright (c) 2013-2014 pCloud Ltd. 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * * Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * * Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * * Neither the name of pCloud Ltd nor the 13 | * names of its contributors may be used to endorse or promote products 14 | * derived from this software without specific prior written permission. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | * DISCLAIMED. IN NO EVENT SHALL pCloud Ltd BE LIABLE FOR ANY 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | #ifndef _PSYNC_TIMER_H 29 | #define _PSYNC_TIMER_H 30 | 31 | #include "pcompiler.h" 32 | #include "plist.h" 33 | #include 34 | 35 | 36 | extern time_t psync_current_time; 37 | 38 | struct _psync_timer_t; 39 | 40 | typedef void (*psync_timer_callback)(struct _psync_timer_t *, void *); 41 | typedef void (*psync_exception_callback)(); 42 | 43 | typedef struct _psync_timer_t { 44 | psync_list list; 45 | psync_timer_callback call; 46 | void *param; 47 | time_t numsec; 48 | time_t runat; 49 | uint32_t level; 50 | uint32_t opts; 51 | } psync_timer_structure_t, *psync_timer_t; 52 | 53 | void psync_timer_init(); 54 | time_t psync_timer_time(); 55 | void psync_timer_wake(); 56 | psync_timer_t psync_timer_register(psync_timer_callback func, time_t numsec, void *param); 57 | int psync_timer_stop(psync_timer_t timer); 58 | void psync_timer_exception_handler(psync_exception_callback func); 59 | void psync_timer_sleep_handler(psync_exception_callback func); 60 | void psync_timer_do_notify_exception(); 61 | void psync_timer_wait_next_sec(); 62 | 63 | #define psync_timer_notify_exception() do {debug(D_NOTICE, "sending exception");psync_timer_do_notify_exception();} while (0) 64 | 65 | #endif 66 | -------------------------------------------------------------------------------- /ptree.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2014 Anton Titov. 2 | * Copyright (c) 2014 pCloud Ltd. 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * * Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * * Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * * Neither the name of pCloud Ltd nor the 13 | * names of its contributors may be used to endorse or promote products 14 | * derived from this software without specific prior written permission. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | * DISCLAIMED. IN NO EVENT SHALL pCloud Ltd BE LIABLE FOR ANY 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | #ifndef _PSYNC_TREE_H 29 | #define _PSYNC_TREE_H 30 | 31 | #include "pcompiler.h" 32 | #include 33 | #include 34 | 35 | typedef struct _psync_tree { 36 | struct _psync_tree *left; 37 | struct _psync_tree *right; 38 | struct _psync_tree *parent; 39 | long int height; 40 | } psync_tree; 41 | 42 | #define PSYNC_TREE_EMPTY NULL 43 | 44 | #define psync_tree_isempty(l) ((l)==NULL) 45 | #define psync_tree_element(a, t, n) ((t *)((char *)(a)-offsetof(t, n))) 46 | #define psync_tree_for_each(a, l) for (a=psync_tree_get_first(l); a!=NULL; a=psync_tree_get_next(a)) 47 | #define psync_tree_for_each_element(a, l, t, n) for (a=psync_tree_element(psync_tree_get_first(l), t, n);\ 48 | &a->n!=NULL;\ 49 | a=psync_tree_element(psync_tree_get_next(&a->n), t, n)) 50 | 51 | #define psync_tree_for_each_element_call(l, t, n, c)\ 52 | do {\ 53 | psync_tree *___tmpa;\ 54 | ___tmpa=psync_tree_get_first(l);\ 55 | while (___tmpa){\ 56 | c(psync_tree_element(___tmpa, t, n));\ 57 | ___tmpa=psync_tree_get_next(___tmpa);\ 58 | }\ 59 | } while (0) 60 | 61 | #define psync_tree_for_each_element_call_safe(l, t, n, c)\ 62 | do {\ 63 | psync_tree *___tmpa, *___tmpb;\ 64 | ___tmpa=psync_tree_get_first_safe(l);\ 65 | while (___tmpa){\ 66 | ___tmpb=psync_tree_get_next_safe(___tmpa);\ 67 | c(psync_tree_element(___tmpa, t, n));\ 68 | ___tmpa=___tmpb;\ 69 | }\ 70 | } while (0) 71 | 72 | 73 | typedef int (*psync_tree_compare)(const psync_tree *, const psync_tree *); 74 | 75 | static inline long int psync_tree_height(psync_tree *tree){ 76 | return tree?tree->height:0; 77 | } 78 | 79 | static inline psync_tree *psync_tree_get_first(psync_tree *tree){ 80 | if (!tree) 81 | return tree; 82 | while (tree->left) 83 | tree=tree->left; 84 | return tree; 85 | } 86 | 87 | static inline psync_tree *psync_tree_get_last(psync_tree *tree){ 88 | if (!tree) 89 | return tree; 90 | while (tree->right) 91 | tree=tree->right; 92 | return tree; 93 | } 94 | 95 | static inline psync_tree *psync_tree_get_next(psync_tree *tree){ 96 | if (tree->right){ 97 | tree=tree->right; 98 | while (tree->left) 99 | tree=tree->left; 100 | return tree; 101 | } 102 | else { 103 | while (tree->parent && tree==tree->parent->right) 104 | tree=tree->parent; 105 | return tree->parent; 106 | } 107 | } 108 | 109 | static inline psync_tree *psync_tree_get_prev(psync_tree *tree){ 110 | if (tree->left){ 111 | tree=tree->left; 112 | while (tree->right) 113 | tree=tree->right; 114 | return tree; 115 | } 116 | else { 117 | while (tree->parent && tree==tree->parent->left) 118 | tree=tree->parent; 119 | return tree->parent; 120 | } 121 | } 122 | 123 | static inline psync_tree *psync_tree_get_first_safe(psync_tree *tree){ 124 | if (!tree) 125 | return tree; 126 | while (1){ 127 | if (tree->left) 128 | tree=tree->left; 129 | else if (tree->right) 130 | tree=tree->right; 131 | else 132 | break; 133 | } 134 | return tree; 135 | } 136 | 137 | static inline psync_tree *psync_tree_get_next_safe(psync_tree *tree){ 138 | if (!tree->parent) 139 | return NULL; 140 | if (tree->parent->right==tree || tree->parent->right==NULL) 141 | return tree->parent; 142 | tree=tree->parent->right; 143 | while (1){ 144 | if (tree->left) 145 | tree=tree->left; 146 | else if (tree->right) 147 | tree=tree->right; 148 | else 149 | break; 150 | } 151 | return tree; 152 | } 153 | 154 | psync_tree *psync_tree_get_add_after(psync_tree *tree, psync_tree *node, psync_tree *newnode); 155 | psync_tree *psync_tree_get_add_before(psync_tree *tree, psync_tree *node, psync_tree *newnode); 156 | psync_tree *psync_tree_get_added_at(psync_tree *tree, psync_tree *parent, psync_tree *newnode); 157 | 158 | psync_tree *psync_tree_get_del(psync_tree *tree, psync_tree *node); 159 | 160 | 161 | static inline psync_tree *psync_tree_get_add(psync_tree *tree, psync_tree *newnode, psync_tree_compare comp){ 162 | psync_tree *el; 163 | if (!tree) 164 | return psync_tree_get_add_after(tree, NULL, newnode); 165 | el=tree; 166 | while (1){ 167 | if (comp(newnode, el)<0){ 168 | if (el->left) 169 | el=el->left; 170 | else 171 | return psync_tree_get_add_before(tree, el, newnode); 172 | } 173 | else{ 174 | if (el->right) 175 | el=el->right; 176 | else 177 | return psync_tree_get_add_after(tree, el, newnode); 178 | } 179 | } 180 | } 181 | 182 | static inline void psync_tree_add_after(psync_tree **tree, psync_tree *node, psync_tree *newnode){ 183 | *tree=psync_tree_get_add_after(*tree, node, newnode); 184 | } 185 | 186 | static inline void psync_tree_add_before(psync_tree **tree, psync_tree *node, psync_tree *newnode){ 187 | *tree=psync_tree_get_add_before(*tree, node, newnode); 188 | } 189 | 190 | static inline void psync_tree_added_at(psync_tree **tree, psync_tree *parent, psync_tree *newnode){ 191 | *tree=psync_tree_get_added_at(*tree, parent, newnode); 192 | } 193 | 194 | static inline void psync_tree_del(psync_tree **tree, psync_tree *node){ 195 | *tree=psync_tree_get_del(*tree, node); 196 | } 197 | 198 | static inline void psync_tree_add(psync_tree **tree, psync_tree *newnode, psync_tree_compare comp){ 199 | *tree=psync_tree_get_add(*tree, newnode, comp); 200 | } 201 | 202 | #endif 203 | -------------------------------------------------------------------------------- /pupload.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2013 Anton Titov. 2 | * Copyright (c) 2013 pCloud Ltd. 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * * Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * * Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * * Neither the name of pCloud Ltd nor the 13 | * names of its contributors may be used to endorse or promote products 14 | * derived from this software without specific prior written permission. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | * DISCLAIMED. IN NO EVENT SHALL pCloud Ltd BE LIABLE FOR ANY 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | #ifndef _PSYNC_UPLOAD_H 29 | #define _PSYNC_UPLOAD_H 30 | 31 | #include "psynclib.h" 32 | 33 | void psync_upload_init(); 34 | void psync_upload_inc_uploads(); 35 | void psync_upload_dec_uploads(); 36 | void psync_upload_dec_uploads_cnt(uint32_t cnt); 37 | void psync_upload_add_bytes_uploaded(uint64_t bytes); 38 | void psync_upload_sub_bytes_uploaded(uint64_t bytes); 39 | void psync_wake_upload(); 40 | void psync_delete_upload_tasks_for_file(psync_fileid_t localfileid); 41 | void psync_stop_sync_upload(psync_syncid_t syncid); 42 | void psync_stop_all_upload(); 43 | 44 | #endif 45 | --------------------------------------------------------------------------------