mirror of
https://github.com/chylex/Nextcloud-Desktop.git
synced 2026-04-03 18:11:32 +02:00
Compare commits
573 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
746c15b4aa | ||
|
|
7e65c9741e | ||
|
|
a50e7c1b48 | ||
|
|
0ae82e2041 | ||
|
|
22af756fe3 | ||
|
|
2f1bec28dd | ||
|
|
022a3fcd92 | ||
|
|
064dcdb25a | ||
|
|
938dce7fa6 | ||
|
|
0151682a53 | ||
|
|
864f2cdc7d | ||
|
|
77ddedc859 | ||
|
|
0c1ab533e6 | ||
|
|
1dd7f736d0 | ||
|
|
571c199db8 | ||
|
|
40715cbc77 | ||
|
|
3d2a2df86f | ||
|
|
86a48b52e9 | ||
|
|
ebe1f986f1 | ||
|
|
dd1152dd4f | ||
|
|
ce9bfd319a | ||
|
|
f591ac6549 | ||
|
|
4fd368c992 | ||
|
|
93f453057b | ||
|
|
5a069d274b | ||
|
|
e275ad3866 | ||
|
|
5813f63df8 | ||
|
|
9a1f8ccf7b | ||
|
|
449c00f019 | ||
|
|
6017eb7ca6 | ||
|
|
f1b2417967 | ||
|
|
181383e5f1 | ||
|
|
c1b9d5c653 | ||
|
|
964c3ac7bf | ||
|
|
6d8afabf41 | ||
|
|
0a7dbeb778 | ||
|
|
3228fde4af | ||
|
|
0582abe8dd | ||
|
|
81f410970f | ||
|
|
e75c5236f2 | ||
|
|
8a671c40d1 | ||
|
|
50ce0f9681 | ||
|
|
a60902b33d | ||
|
|
5220786cf2 | ||
|
|
99cead68f5 | ||
|
|
7a209ba376 | ||
|
|
f9263da3de | ||
|
|
3f724e1c6a | ||
|
|
c9d3f7a0eb | ||
|
|
072af16f3b | ||
|
|
d2b6c626b5 | ||
|
|
115276408a | ||
|
|
9abffdb1a6 | ||
|
|
5b0307446a | ||
|
|
0f20a4f546 | ||
|
|
1b2875c20a | ||
|
|
bbdf7bf955 | ||
|
|
57359968ed | ||
|
|
ea9f302b7a | ||
|
|
ef0a3c212e | ||
|
|
18677dbc3f | ||
|
|
7e8b403116 | ||
|
|
1303379c9e | ||
|
|
b995cd318c | ||
|
|
ed19107161 | ||
|
|
1b67f253dc | ||
|
|
667c835c49 | ||
|
|
5b298abba1 | ||
|
|
4edbeece49 | ||
|
|
97362cff32 | ||
|
|
3db3c7b876 | ||
|
|
8738128504 | ||
|
|
069eaf9170 | ||
|
|
d0b9b002e4 | ||
|
|
bdba56f60b | ||
|
|
7087dbc445 | ||
|
|
7ade4bb6e6 | ||
|
|
86117aed0d | ||
|
|
ed3d9a7479 | ||
|
|
3746a2efff | ||
|
|
9b53cc66e7 | ||
|
|
43fe7b0d55 | ||
|
|
5aa6f81ef3 | ||
|
|
f838f28185 | ||
|
|
e1f8eb5aa5 | ||
|
|
f40a054cb7 | ||
|
|
adfb163593 | ||
|
|
81c768099e | ||
|
|
4bcaebb322 | ||
|
|
8b469d3992 | ||
|
|
bb929db7e6 | ||
|
|
90ee274744 | ||
|
|
9f6e9f8e1b | ||
|
|
943f9f60e3 | ||
|
|
f89bfce068 | ||
|
|
ef44a59bed | ||
|
|
d96139f698 | ||
|
|
de970eb0a5 | ||
|
|
7a28b44128 | ||
|
|
17a2e224c4 | ||
|
|
87386ce001 | ||
|
|
5ed4710d64 | ||
|
|
5493c22584 | ||
|
|
64f4d1b387 | ||
|
|
cdd8c8165b | ||
|
|
16ffd7fbe4 | ||
|
|
ba959f7cf9 | ||
|
|
cf145feed8 | ||
|
|
07f57b1982 | ||
|
|
e62eb62a01 | ||
|
|
574e030caf | ||
|
|
3705a42375 | ||
|
|
a9ffd1d0cf | ||
|
|
f86dd1cbbf | ||
|
|
af066cc733 | ||
|
|
822650719b | ||
|
|
95747fbaea | ||
|
|
321058ef74 | ||
|
|
71c11373d8 | ||
|
|
d5ba288dd5 | ||
|
|
091e9bbd52 | ||
|
|
ce09e11011 | ||
|
|
d7a226e0e6 | ||
|
|
f034bcb9ae | ||
|
|
4c77a04514 | ||
|
|
a50c39cd0c | ||
|
|
370dd99e47 | ||
|
|
f97fbe868f | ||
|
|
2ce6560b6e | ||
|
|
2b4e14c4fc | ||
|
|
1631cfdaf1 | ||
|
|
2e76fe87c2 | ||
|
|
6c44f53645 | ||
|
|
988c162d2f | ||
|
|
3d8d4fecd7 | ||
|
|
f8525fa5a0 | ||
|
|
6e48eb9397 | ||
|
|
88cb047197 | ||
|
|
7f7154ed40 | ||
|
|
a8c1ffc2f4 | ||
|
|
df8b5b1ea6 | ||
|
|
ce50cdecf1 | ||
|
|
77c7439329 | ||
|
|
752112dbaa | ||
|
|
925c6485e6 | ||
|
|
d62deabf9b | ||
|
|
47c23dae30 | ||
|
|
3bf15541c6 | ||
|
|
876de8fd69 | ||
|
|
983f9c5dde | ||
|
|
9193286fc1 | ||
|
|
1b8d11182b | ||
|
|
dcc5c105eb | ||
|
|
64b42333b0 | ||
|
|
3ee729bc4a | ||
|
|
a268b03990 | ||
|
|
6471a45a8a | ||
|
|
7c27638f36 | ||
|
|
0bffdfb256 | ||
|
|
9f0848ba15 | ||
|
|
f159b028b4 | ||
|
|
7e702778a1 | ||
|
|
4489a56c65 | ||
|
|
7f752c7e93 | ||
|
|
b39359c929 | ||
|
|
b42d3ced15 | ||
|
|
1c73a8d4ad | ||
|
|
2d3ea59755 | ||
|
|
b8b064836c | ||
|
|
3ab1330f63 | ||
|
|
ab711ddc36 | ||
|
|
2a1e67e587 | ||
|
|
1d3febe053 | ||
|
|
165e35c750 | ||
|
|
9da261acd8 | ||
|
|
7544f4d367 | ||
|
|
a29a56bce8 | ||
|
|
642c16b09b | ||
|
|
5c92c190f0 | ||
|
|
cc7826e087 | ||
|
|
a154656311 | ||
|
|
9b7a3d00ee | ||
|
|
1d862b77af | ||
|
|
888843e655 | ||
|
|
28970393f6 | ||
|
|
1af7dc952c | ||
|
|
62dcfe85e4 | ||
|
|
f6711b2842 | ||
|
|
f2519e9d87 | ||
|
|
94f380c1f0 | ||
|
|
197d180cb9 | ||
|
|
4be20db670 | ||
|
|
46d6191bc2 | ||
|
|
ee22f377af | ||
|
|
44a04227f1 | ||
|
|
707c6fcc5d | ||
|
|
edb1f61241 | ||
|
|
3fac5f91c8 | ||
|
|
1338c08622 | ||
|
|
0cf8091705 | ||
|
|
521373f075 | ||
|
|
c24732f641 | ||
|
|
655188d7b3 | ||
|
|
77ac092975 | ||
|
|
78e5e4ab66 | ||
|
|
934eda128b | ||
|
|
ece41921ff | ||
|
|
9b71643c1c | ||
|
|
ed48b4bbf2 | ||
|
|
b08284e4cc | ||
|
|
4731b506e5 | ||
|
|
7d3b0fe0c5 | ||
|
|
fa38bf7029 | ||
|
|
bfdf638334 | ||
|
|
e6664c7790 | ||
|
|
a90779910a | ||
|
|
edc7a9596a | ||
|
|
a7a19fad71 | ||
|
|
d143044f4a | ||
|
|
aee7515d42 | ||
|
|
82ab5fdcb9 | ||
|
|
4c6e6f6302 | ||
|
|
0a2791270a | ||
|
|
c920f81562 | ||
|
|
9dcbafc307 | ||
|
|
d836b80153 | ||
|
|
efc4ff4d88 | ||
|
|
dc043b5765 | ||
|
|
ef9a318cd9 | ||
|
|
9f4ffd44d6 | ||
|
|
598bfe6d1a | ||
|
|
5f37c7b1b8 | ||
|
|
8250fb81b3 | ||
|
|
30a14b9f45 | ||
|
|
b0734f2791 | ||
|
|
d66b0910c6 | ||
|
|
09e05392bf | ||
|
|
d3d202de68 | ||
|
|
87010fbe1a | ||
|
|
f302da81b1 | ||
|
|
3af53f5984 | ||
|
|
7c40dc1a9a | ||
|
|
af3af94a01 | ||
|
|
7d79d3d30d | ||
|
|
990e2f0beb | ||
|
|
b34b4e37aa | ||
|
|
02697a7c4d | ||
|
|
4ff39d8114 | ||
|
|
69bdccfd2f | ||
|
|
9f8d867ce2 | ||
|
|
d416c97eac | ||
|
|
1d70426bb7 | ||
|
|
6a2fe6be67 | ||
|
|
8ed0fdcfa5 | ||
|
|
ebf3c78237 | ||
|
|
3d67d203fe | ||
|
|
fc06945b26 | ||
|
|
9cdcc925c1 | ||
|
|
fc2923aa9b | ||
|
|
6d325e6557 | ||
|
|
7d7d03071a | ||
|
|
657f7613a1 | ||
|
|
d35c0f3ade | ||
|
|
069e9526a8 | ||
|
|
5aeee6d1f2 | ||
|
|
a759c93fb6 | ||
|
|
57c59850e1 | ||
|
|
0f7d448058 | ||
|
|
ab8868eacd | ||
|
|
00cd5875c0 | ||
|
|
435e7e3eec | ||
|
|
08dd9796d1 | ||
|
|
4bcd620c29 | ||
|
|
5f60c97f59 | ||
|
|
20e850501d | ||
|
|
462ba7d942 | ||
|
|
cf87fdff7f | ||
|
|
565bb540d6 | ||
|
|
062a0907db | ||
|
|
95726eeab1 | ||
|
|
6c2d286f10 | ||
|
|
6af3e9afc7 | ||
|
|
ead935e0a6 | ||
|
|
eaf5681f61 | ||
|
|
03ef2aadde | ||
|
|
f09076180d | ||
|
|
d5d3c1a23a | ||
|
|
b18f1ad386 | ||
|
|
fc553a8c04 | ||
|
|
cba160706a | ||
|
|
fa453296c9 | ||
|
|
58aaad3fed | ||
|
|
8625ec250b | ||
|
|
d731f4718d | ||
|
|
607e48a68b | ||
|
|
bfe6a50b19 | ||
|
|
ded21c5826 | ||
|
|
9bd6019905 | ||
|
|
dcac2796dd | ||
|
|
ab439f8f0f | ||
|
|
9822002480 | ||
|
|
384a8d0d72 | ||
|
|
70eb688e86 | ||
|
|
4e0b6179f9 | ||
|
|
3acdfc0004 | ||
|
|
a1fc7f0a25 | ||
|
|
5bceb6f787 | ||
|
|
8de9bec122 | ||
|
|
5204a992b2 | ||
|
|
765a18b74a | ||
|
|
350283fe06 | ||
|
|
2ba62b79b4 | ||
|
|
e0b6395d18 | ||
|
|
ba896b0550 | ||
|
|
36a2c861c2 | ||
|
|
7f975e0b2f | ||
|
|
359dd2b986 | ||
|
|
a636fd7801 | ||
|
|
69fcbd3b0d | ||
|
|
d6525a979d | ||
|
|
67f4d0c85b | ||
|
|
54313338cd | ||
|
|
09e6207ce9 | ||
|
|
000e0bb600 | ||
|
|
353f21e856 | ||
|
|
51e961e694 | ||
|
|
de2335c1db | ||
|
|
332c6cf726 | ||
|
|
5481215813 | ||
|
|
086dd07d69 | ||
|
|
dd6b71bad6 | ||
|
|
9af2339596 | ||
|
|
0fcef5f604 | ||
|
|
c41935d49d | ||
|
|
7b84defd56 | ||
|
|
505429b582 | ||
|
|
033fee6f53 | ||
|
|
67ae541e2a | ||
|
|
11bbad79e2 | ||
|
|
6e6f647c63 | ||
|
|
c5100a789b | ||
|
|
2ad7b0aae0 | ||
|
|
588633a0f2 | ||
|
|
d5659442b2 | ||
|
|
c6e5f39f7f | ||
|
|
7bef166d6c | ||
|
|
38344589c4 | ||
|
|
98d7ff5116 | ||
|
|
6c28151e0f | ||
|
|
411cffd3d5 | ||
|
|
1c4af687ea | ||
|
|
2de83b95e3 | ||
|
|
c3d37efa6c | ||
|
|
7c7fad78f7 | ||
|
|
3ac1849963 | ||
|
|
b4f992b944 | ||
|
|
1c8e5ef4ee | ||
|
|
45ec489f71 | ||
|
|
1b5e14fbc5 | ||
|
|
dddec8b250 | ||
|
|
06082b585a | ||
|
|
4bf0a2b188 | ||
|
|
e2fe4972d9 | ||
|
|
efee9c689c | ||
|
|
84b4872938 | ||
|
|
3f9bd1d72a | ||
|
|
1898e32b6a | ||
|
|
9addd9bc27 | ||
|
|
91f416ffc7 | ||
|
|
28559ab657 | ||
|
|
47274f1075 | ||
|
|
384eef4d6d | ||
|
|
ff95cbd04b | ||
|
|
cc5fabdab0 | ||
|
|
ff95e233bc | ||
|
|
f72e1cc837 | ||
|
|
8e6674e784 | ||
|
|
8aace3284f | ||
|
|
922e004fc6 | ||
|
|
2fc61479f7 | ||
|
|
bb9d6b34c7 | ||
|
|
07025c7432 | ||
|
|
b65601aaa4 | ||
|
|
756e1c4a12 | ||
|
|
c5f8a2555d | ||
|
|
a1ab9c84c7 | ||
|
|
e4966ec9d1 | ||
|
|
23f3a6b319 | ||
|
|
ebeb668a62 | ||
|
|
d2e1923694 | ||
|
|
a5ede054d6 | ||
|
|
ba2ff4ec46 | ||
|
|
ca536f467a | ||
|
|
05d3273591 | ||
|
|
39924d79cb | ||
|
|
f7866aabde | ||
|
|
eb59f98ec9 | ||
|
|
c3cee3426e | ||
|
|
f21dd05c2d | ||
|
|
6005b9c16e | ||
|
|
77bf37c6f6 | ||
|
|
8e133dc8ea | ||
|
|
d10aec6055 | ||
|
|
9d1208baa4 | ||
|
|
8e914deb99 | ||
|
|
34dd3b207e | ||
|
|
68e8d659fb | ||
|
|
f79765a536 | ||
|
|
eef57032f8 | ||
|
|
6377dca4b0 | ||
|
|
f05320c32c | ||
|
|
b0f8a24c20 | ||
|
|
c841b9c0c4 | ||
|
|
7b482c0e96 | ||
|
|
bf5091d862 | ||
|
|
5c45ede4a5 | ||
|
|
cabcdd890e | ||
|
|
0a5e691ba3 | ||
|
|
ba300c2fc1 | ||
|
|
c74e7550af | ||
|
|
0f385db314 | ||
|
|
2396831846 | ||
|
|
adb868a63b | ||
|
|
62e95e540b | ||
|
|
d744b5e481 | ||
|
|
f9b82d852c | ||
|
|
33289bde29 | ||
|
|
9053662fe8 | ||
|
|
07904e078a | ||
|
|
aacc278583 | ||
|
|
57aa86910c | ||
|
|
7071c895df | ||
|
|
87f3755b1f | ||
|
|
3f4bcbbd62 | ||
|
|
955b932806 | ||
|
|
e7b6560c39 | ||
|
|
80e583c337 | ||
|
|
bc3d298491 | ||
|
|
28cf9ce1a4 | ||
|
|
d5fd6309ed | ||
|
|
a2467b5dea | ||
|
|
f723d11d90 | ||
|
|
aee4c06b8d | ||
|
|
89a4833cae | ||
|
|
255d255217 | ||
|
|
902de2dc93 | ||
|
|
f7c075099b | ||
|
|
0bbcee7354 | ||
|
|
8a18cf811e | ||
|
|
4e7e25c569 | ||
|
|
c24c97703a | ||
|
|
de84e8012e | ||
|
|
f6ff20ca17 | ||
|
|
b7a85525cd | ||
|
|
bc41e6bc99 | ||
|
|
aa4e90acfc | ||
|
|
4018338725 | ||
|
|
e33c1b2b75 | ||
|
|
75d6c26e2e | ||
|
|
7f2deaf722 | ||
|
|
0c85100c93 | ||
|
|
d617c40ee7 | ||
|
|
8aebbefb28 | ||
|
|
7cab77e879 | ||
|
|
feb49b2768 | ||
|
|
4e25595520 | ||
|
|
4aaa256b11 | ||
|
|
ac393c6374 | ||
|
|
114c8de814 | ||
|
|
5e012366ab | ||
|
|
ed1294d668 | ||
|
|
7f07385fd7 | ||
|
|
ed2316a53f | ||
|
|
e5a8cd4521 | ||
|
|
3f3577d0b1 | ||
|
|
950ffc6418 | ||
|
|
5ce4763868 | ||
|
|
bafc90cfd8 | ||
|
|
b5349b66c6 | ||
|
|
8d2c43a9f0 | ||
|
|
6906b8d30c | ||
|
|
1c8f279214 | ||
|
|
0cc0eed8a8 | ||
|
|
96c535d712 | ||
|
|
5d58a8164c | ||
|
|
71cc74a0d6 | ||
|
|
77d9256e03 | ||
|
|
e7fb84a491 | ||
|
|
a652fec5a0 | ||
|
|
0d34a2bca5 | ||
|
|
a2e8bfd962 | ||
|
|
eff2427a03 | ||
|
|
869793592d | ||
|
|
417dbcc9ac | ||
|
|
3cb6fc82dd | ||
|
|
7d398b20f2 | ||
|
|
b03e49f492 | ||
|
|
3ed5f43e90 | ||
|
|
4630244b51 | ||
|
|
7ec534067e | ||
|
|
c38c3ce6e2 | ||
|
|
aa02ce2481 | ||
|
|
6a55324261 | ||
|
|
f1fa1f125d | ||
|
|
141f005c34 | ||
|
|
e32ca49c31 | ||
|
|
f5e16540a1 | ||
|
|
65ffe53c20 | ||
|
|
06f2989ac8 | ||
|
|
399b08ad40 | ||
|
|
5b561e4462 | ||
|
|
1be322579c | ||
|
|
b7c7c9f3eb | ||
|
|
9237293cc0 | ||
|
|
63083a558b | ||
|
|
d4bd327fef | ||
|
|
2de288c5f3 | ||
|
|
fcc0e89044 | ||
|
|
8267b9e590 | ||
|
|
5a68e5f58d | ||
|
|
496d900fee | ||
|
|
58bda69f8b | ||
|
|
89b5ddec56 | ||
|
|
f7419094f3 | ||
|
|
432f377750 | ||
|
|
c32beb957d | ||
|
|
ee7c8d3c94 | ||
|
|
3a15502a62 | ||
|
|
a51cb0982b | ||
|
|
a39caa1cda | ||
|
|
a4ee8d6f6f | ||
|
|
b35e38f80f | ||
|
|
e34122ad54 | ||
|
|
03824baba4 | ||
|
|
34b86cb0db | ||
|
|
7b6269b4bf | ||
|
|
842c6c0e9e | ||
|
|
a81d7823a9 | ||
|
|
aa26fc1e80 | ||
|
|
beb9752f09 | ||
|
|
a4442ebb40 | ||
|
|
93f31fa9d7 | ||
|
|
f35b1f8a2b | ||
|
|
6db8daabf7 | ||
|
|
7ae40e13ec | ||
|
|
a5379ef2aa | ||
|
|
01c0a3c099 | ||
|
|
9815ccb760 | ||
|
|
814f40c1c7 | ||
|
|
19c128ba12 | ||
|
|
60ca442728 | ||
|
|
3ffd7034c9 | ||
|
|
95469a9886 | ||
|
|
8c9a65635f | ||
|
|
104cf680a6 | ||
|
|
b84253054a | ||
|
|
43345dc236 | ||
|
|
79d14f0760 | ||
|
|
6387777c18 | ||
|
|
1e9c508c92 | ||
|
|
88e9014dad | ||
|
|
313ad56d11 | ||
|
|
8152b7ebcf | ||
|
|
e36d314218 | ||
|
|
593d528b6a | ||
|
|
3649869650 | ||
|
|
41a4f1fc37 | ||
|
|
f67d2e6418 | ||
|
|
9a6275a5e3 | ||
|
|
2d9c0b6c31 | ||
|
|
4e0496f74d | ||
|
|
738f026c41 | ||
|
|
32e205f6ce |
3
.gitmodules
vendored
3
.gitmodules
vendored
@@ -1,3 +1,6 @@
|
||||
[submodule "doc/ocdoc"]
|
||||
path = doc/ocdoc
|
||||
url = https://github.com/owncloud/documentation
|
||||
[submodule "src/3rdparty/qtmacgoodies"]
|
||||
path = src/3rdparty/qtmacgoodies
|
||||
url = git://github.com/shadone/qtmacgoodies.git
|
||||
|
||||
@@ -41,6 +41,7 @@ get_git_head_revision(GIT_REFSPEC GIT_SHA1)
|
||||
# if we cannot get it from git, directly try .tag (packages)
|
||||
# this will work if the tar balls have been properly created
|
||||
# via git-archive.
|
||||
if (GIT_SHA1)
|
||||
if (${GIT_SHA1} STREQUAL "GITDIR-NOTFOUND")
|
||||
file(READ ${CMAKE_SOURCE_DIR}/.tag sha1_candidate)
|
||||
string(REPLACE "\n" "" sha1_candidate ${sha1_candidate})
|
||||
@@ -49,6 +50,7 @@ if (${GIT_SHA1} STREQUAL "GITDIR-NOTFOUND")
|
||||
set (GIT_SHA1 "${sha1_candidate}")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
set(SYSCONFDIR ${SYSCONF_INSTALL_DIR})
|
||||
set(DATADIR ${DATA_INSTALL_DIR})
|
||||
@@ -72,26 +74,55 @@ else()
|
||||
endif()
|
||||
#####
|
||||
|
||||
# this option removes Http authentication, keychain, shibboleth etc and is intended for
|
||||
# external authentication mechanisms
|
||||
option(TOKEN_AUTH_ONLY "TOKEN_AUTH_ONLY" OFF)
|
||||
if(TOKEN_AUTH_ONLY)
|
||||
message("Compiling with token authentication")
|
||||
add_definitions(-DTOKEN_AUTH_ONLY=1)
|
||||
endif()
|
||||
|
||||
# this option creates only libocsync and libowncloudsync
|
||||
option(BUILD_LIBRARIES_ONLY "BUILD_LIBRARIES_ONLY" OFF)
|
||||
|
||||
# When this option is enabled, 5xx errors are not added to the clacklist
|
||||
# Normaly you don't want to enable this option because if a particular file
|
||||
# trigger a bug on the server, you want the file to be blacklisted.
|
||||
option(OWNCLOUD_5XX_NO_BLACKLIST "OWNCLOUD_5XX_NO_BLACKLIST" OFF)
|
||||
if(OWNCLOUD_5XX_NO_BLACKLIST)
|
||||
add_definitions(-DOWNCLOUD_5XX_NO_BLACKLIST=1)
|
||||
endif()
|
||||
|
||||
#### find libs
|
||||
#find_package(Qt4 4.7.0 COMPONENTS QtCore QtGui QtXml QtNetwork QtTest QtWebkit REQUIRED )
|
||||
#if( UNIX AND NOT APPLE ) # Fdo notifications
|
||||
# find_package(Qt4 4.7.0 COMPONENTS QtDBus REQUIRED )
|
||||
#endif()
|
||||
find_package(Neon REQUIRED)
|
||||
find_package(QtKeychain REQUIRED)
|
||||
|
||||
if(NOT TOKEN_AUTH_ONLY)
|
||||
if (Qt5Core_DIR)
|
||||
find_package(Qt5Keychain REQUIRED)
|
||||
else()
|
||||
find_package(QtKeychain REQUIRED)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
Find_package(Sparkle)
|
||||
if(UNIX)
|
||||
find_package(INotify REQUIRED)
|
||||
find_package(INotify REQUIRED)
|
||||
else()
|
||||
find_package(INotify)
|
||||
find_package(INotify)
|
||||
endif()
|
||||
find_package(Sphinx)
|
||||
find_package(PdfLatex)
|
||||
|
||||
set(WITH_QTKEYCHAIN ${QTKEYCHAIN_FOUND})
|
||||
|
||||
|
||||
configure_file(config.h.in ${CMAKE_CURRENT_BINARY_DIR}/config.h)
|
||||
|
||||
configure_file(test/test_journal.db "${CMAKE_BINARY_DIR}/test/test_journal.db" COPYONLY)
|
||||
|
||||
include(OwnCloudCPack.cmake)
|
||||
|
||||
add_definitions(-DUNICODE)
|
||||
|
||||
35
ChangeLog
35
ChangeLog
@@ -1,5 +1,40 @@
|
||||
ChangeLog
|
||||
=========
|
||||
version 1.6.0 (release 2014-05-30 )
|
||||
* Minor GUI improvements
|
||||
* Qt5 compile issues fixed
|
||||
* Ignore sync log file in filewatcher
|
||||
* Install libocsync to private library dir and use rpath to localize
|
||||
* Fix reconnect after server disconnect
|
||||
* Fix "unknown action" display in Activity window
|
||||
* Fix memory leaks
|
||||
* Respect XDG_CONFIG_HOME environment var
|
||||
* Handle empty fileids in the journal correctly
|
||||
* Add abilility to compile libowncloudsync without GUI dependendy
|
||||
* Fix SSL error with previously-expired CAs on Windows
|
||||
* Fix incorrect folder pause state after start
|
||||
* Fix a couple of actual potential crashes
|
||||
* Improve Cookie support (e.g. for cookie-based load-balancers)
|
||||
* Introduce a general timeout of 300s for network operations
|
||||
* Improve error handling, blacklisting
|
||||
* Job-based change propagation, enables faster parallel up/downloads
|
||||
(right now only if no bandwidth limit is set and no proxy is used)
|
||||
* Significantly reduced CPU load when checking for local and remote changes
|
||||
* Speed up file stat code on Windows
|
||||
* Enforce Qt5 for Windows and Mac OS X builds
|
||||
* Improved owncloudcmd: SSL support, documentation
|
||||
* Added advanced logging of operations (file .???.log in sync
|
||||
directory)
|
||||
* Avoid creating a temporary copy of the sync database (.ctmp)
|
||||
* Enable support for TLS 1.2 negotiation on platforms that use
|
||||
Qt 5.2 or later
|
||||
* Forward server exception messages to client error messages
|
||||
* Mac OS X: Support Notification Center in OS X 10.8+
|
||||
* Mac OS X: Use native settings dialog
|
||||
* Mac OS X: Fix UI inconsistencies on Mavericks
|
||||
* Shibboleth: Warn if authenticating with a different user
|
||||
* Remove vio abstraction in csync
|
||||
* Avoid data loss when a client file system is not case sensitive
|
||||
|
||||
version 1.5.3 (release 2014-03-10 )
|
||||
* Fix usage of proxies after first sync run (#1502, #1524, #1459, #1521)
|
||||
|
||||
@@ -17,7 +17,8 @@ It uses OCSync as its syncing backend.
|
||||
|
||||
## Building the source code
|
||||
|
||||
Please refer to [Building the Client](http://doc.owncloud.org/desktop/1.5/building.html)
|
||||
Please refer to doc/building.rst, or
|
||||
[Building the Client](http://doc.owncloud.org/desktop/1.5/building.html)
|
||||
in the ownCloud client manual.
|
||||
|
||||
## Authors
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
set( MIRALL_VERSION_MAJOR 1 )
|
||||
set( MIRALL_VERSION_MINOR 5 )
|
||||
set( MIRALL_VERSION_PATCH 3 )
|
||||
set( MIRALL_VERSION_MINOR 6 )
|
||||
set( MIRALL_VERSION_PATCH 0 )
|
||||
set( MIRALL_SOVERSION 0 )
|
||||
|
||||
if ( NOT DEFINED MIRALL_VERSION_SUFFIX )
|
||||
set( MIRALL_VERSION_SUFFIX ) #e.g. beta1, beta2, rc1
|
||||
set( MIRALL_VERSION_SUFFIX "") #e.g. beta1, beta2, rc1
|
||||
endif( NOT DEFINED MIRALL_VERSION_SUFFIX )
|
||||
|
||||
if( NOT DEFINED MIRALL_VERSION_BUILD )
|
||||
|
||||
@@ -6,12 +6,34 @@ src_dmg="$1"
|
||||
tmp_dmg="writable_$1"
|
||||
signed_dmg="signed_$1"
|
||||
identity="$2"
|
||||
|
||||
QT_FMWKS=`basename ${TMP_APP}/Contents/Frameworks`/Qt*
|
||||
QT_FMWK_VERSION="5"
|
||||
|
||||
fix_frameworks() {
|
||||
TMP_APP=$1
|
||||
QT_FMWK_PATH=$2
|
||||
QT_FMWKS=$3/Qt*.framework
|
||||
|
||||
echo "Patching Qt frameworks..."
|
||||
for FMWK in $QT_FMWKS; do
|
||||
FMWK_NAME=`basename -s .framework $FMWK`
|
||||
FMWK=`basename $FMWK`
|
||||
FMWK_PATH="${TMP_APP}/Contents/Frameworks/${FMWK}"
|
||||
mkdir -p "${FMWK_PATH}/Versions/${QT_FMWK_VERSION}/Resources/"
|
||||
cp -avf "${QT_FMWK_PATH}/${FMWK}/Contents/Info.plist" "${FMWK_PATH}/Versions/${QT_FMWK_VERSION}/Resources"
|
||||
(cd "${FMWK_PATH}" && ln -sf "Versions/${QT_FMWK_VERSION}/Resources" "Resources")
|
||||
perl -pi -e "s/${FMWK_NAME}_debug/${FMWK_NAME}/" "${FMWK_PATH}/Resources/Info.plist"
|
||||
done
|
||||
}
|
||||
|
||||
mount="/Volumes/$(basename "$src_dmg"|sed 's,-\([0-9]\)\(.*\),,')"
|
||||
test -e "$tmp_dmg" && rm -rf "$tmp_dmg"
|
||||
hdiutil convert "$src_dmg" -format UDRW -o "$tmp_dmg"
|
||||
hdiutil attach "$tmp_dmg"
|
||||
pushd "$mount"
|
||||
codesign -s "$identity" "$mount"/*.app
|
||||
fix_frameworks "$mount"/*.app `qmake -query QT_INSTALL_LIBS` "$mount"/*.app/Contents/Frameworks
|
||||
codesign -s "$identity" --deep "$mount"/*.app
|
||||
popd
|
||||
diskutil eject "$mount"
|
||||
test -e "$signed_dmg" && rm -rf "$signed_dmg"
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
[main]
|
||||
host = https://www.transifex.net
|
||||
host = https://www.transifex.com
|
||||
|
||||
[owncloud.mirall-wininstaller]
|
||||
host = https://www.transifex.net
|
||||
host = https://www.transifex.com
|
||||
source_file = pofiles/messages.pot
|
||||
source_lang = en
|
||||
type = PO
|
||||
|
||||
@@ -7,6 +7,7 @@ StrCpy $PageReinstall_NEW_Field_3 "No instal·lar"
|
||||
StrCpy $PageReinstall_NEW_MUI_HEADER_TEXT_TITLE "Ja instal·lat"
|
||||
StrCpy $PageReinstall_NEW_MUI_HEADER_TEXT_SUBTITLE "Trieu la manera com voleu instal·lar ${APPLICATION_NAME}."
|
||||
StrCpy $UNINSTALLER_FINISHED_Detail "Acabat"
|
||||
StrCpy $SectionGroup_Shortcuts "Dreceres"
|
||||
StrCpy $ConfirmEndProcess_MESSAGEBOX_TEXT "Found ${APPLICATION_EXECUTABLE} process(s) which need to be stopped.$\nDo you want the installer to stop these for you?"
|
||||
StrCpy $ConfirmEndProcess_KILLING_PROCESSES_TEXT "Killing ${APPLICATION_EXECUTABLE} processes."
|
||||
StrCpy $PageReinstall_OLD_Field_1 "A newer version of ${APPLICATION_NAME} is already installed! It is not recommended that you install an older version. If you really want to install this older version, it is better to uninstall the current version first. Select the operation you want to perform and click Next to continue."
|
||||
@@ -41,4 +42,3 @@ StrCpy $UAC_INSTALLER_REQUIRE_ADMIN "This installer requires admin access, try a
|
||||
StrCpy $INIT_INSTALLER_RUNNING "The installer is already running."
|
||||
StrCpy $UAC_UNINSTALLER_REQUIRE_ADMIN "This uninstaller requires admin access, try again"
|
||||
StrCpy $INIT_UNINSTALLER_RUNNING "The uninstaller is already running."
|
||||
StrCpy $SectionGroup_Shortcuts "Shortcuts"
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
# Auto-generated - do not modify
|
||||
StrCpy $MUI_FINISHPAGE_SHOWREADME_TEXT_STRING "Zobrazit poznámky k vydání"
|
||||
StrCpy $ConfirmEndProcess_MESSAGEBOX_TEXT "Nalezen proces(y) ${APPLICATION_EXECUTABLE}, které je nutné ukončit .$\nPřejete si, aby je instalátor za vás ukončil?"
|
||||
StrCpy $ConfirmEndProcess_KILLING_PROCESSES_TEXT "Ukončuji procesy ${APPLICATION_EXECUTABLE}."
|
||||
StrCpy $ConfirmEndProcess_KILL_NOT_FOUND_TEXT "Proces k ukončení nebyl nalezen! "
|
||||
StrCpy $PageReinstall_NEW_Field_1 "Starší verze ${APPLICATION_NAME} je nainstalována na tomto systému. Doporučuje se předem tuto verzi odinstalovat. Zvolte operaci, kterou chcete uskutečnit, a klikněte na tlačítko Další pro pokračování."
|
||||
StrCpy $PageReinstall_NEW_Field_2 "Odinstalovat před instalací"
|
||||
@@ -33,12 +35,10 @@ StrCpy $UNINSTALLER_FINISHED_Detail "Dokončeno"
|
||||
StrCpy $UNINSTALL_MESSAGEBOX "Nezdá se, že ${APPLICATION_NAME} je nainstalována ve složce '$INSTDIR'.\nChcete pokračovat (nedoporučuje se)?"
|
||||
StrCpy $UNINSTALL_ABORT "Odinstalace zrušena uživatelem"
|
||||
StrCpy $INIT_NO_QUICK_LAUNCH "Zástupce rychlého spuštění (není k dispozici)"
|
||||
StrCpy $INIT_NO_DESKTOP "Zástupce na ploše (přepíše existující)"
|
||||
StrCpy $UAC_ERROR_ELEVATE "Nelze zvýšit, chyba:"
|
||||
StrCpy $UAC_INSTALLER_REQUIRE_ADMIN "Tento instalátor vyžaduje správcovská oprávnění, opakujte znovu"
|
||||
StrCpy $INIT_INSTALLER_RUNNING "Instalátor je již spuštěn."
|
||||
StrCpy $UAC_UNINSTALLER_REQUIRE_ADMIN "Tento odinstalátor vyžaduje správcovská oprávnění, opakujte znovu"
|
||||
StrCpy $INIT_UNINSTALLER_RUNNING "Odinstalátor je již spuštěn."
|
||||
StrCpy $SectionGroup_Shortcuts "Zástupci"
|
||||
StrCpy $ConfirmEndProcess_MESSAGEBOX_TEXT "Found ${APPLICATION_EXECUTABLE} process(s) which need to be stopped.$\nDo you want the installer to stop these for you?"
|
||||
StrCpy $ConfirmEndProcess_KILLING_PROCESSES_TEXT "Killing ${APPLICATION_EXECUTABLE} processes."
|
||||
StrCpy $INIT_NO_DESKTOP "Desktop Shortcut (overwrites existing)"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Auto-generated - do not modify
|
||||
StrCpy $MUI_FINISHPAGE_SHOWREADME_TEXT_STRING "toon releaseopmerkingen"
|
||||
StrCpy $MUI_FINISHPAGE_SHOWREADME_TEXT_STRING "Toon releaseopmerkingen"
|
||||
StrCpy $ConfirmEndProcess_MESSAGEBOX_TEXT "Gevonden ${APPLICATION_EXECUTABLE} proces(sen) moet worden gestopt.$\nWilt u dat het installatieprogramma dat voor u doet?"
|
||||
StrCpy $ConfirmEndProcess_KILLING_PROCESSES_TEXT "Stoppen ${APPLICATION_EXECUTABLE} processen."
|
||||
StrCpy $ConfirmEndProcess_KILL_NOT_FOUND_TEXT "Het te stoppen proces is niet gevonden!"
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
# Auto-generated - do not modify
|
||||
StrCpy $MUI_FINISHPAGE_SHOWREADME_TEXT_STRING "Näita väljalaske märkmeid"
|
||||
StrCpy $ConfirmEndProcess_MESSAGEBOX_TEXT "Leitud protsess(id) ${processName} mis tuleks peatada. $\nKas soovid, et installer seiskaks need?"
|
||||
StrCpy $ConfirmEndProcess_KILLING_PROCESSES_TEXT "${APPLICATION_EXECUTABLE} protsessi lõpetamine."
|
||||
StrCpy $ConfirmEndProcess_KILL_NOT_FOUND_TEXT "Ei leitud protsessi, mida tappa!"
|
||||
StrCpy $PageReinstall_NEW_Field_1 "Üks vanem versioon ${APPLICATION_NAME} on juba paigaldatud. On soovitav see eemaldada enne uue paigaldamist. Vali tehtav toiming ning kliki Jätka."
|
||||
StrCpy $PageReinstall_NEW_Field_2 "Eemalda enne paigaldamist"
|
||||
@@ -33,12 +35,10 @@ StrCpy $UNINSTALLER_FINISHED_Detail "L
|
||||
StrCpy $UNINSTALL_MESSAGEBOX "Ei leia, et ${APPLICATION_NAME} oleks paigaldatud kataloogi '$INSTDIR'.$\n$\nJätkata sellele vaatamata (pole soovitav)?"
|
||||
StrCpy $UNINSTALL_ABORT "Desinstallimine on kasutaja poolt katkestatud"
|
||||
StrCpy $INIT_NO_QUICK_LAUNCH "Kiirvaliku viit (N/A)"
|
||||
StrCpy $INIT_NO_DESKTOP "Ikoon töölaual (kirjutab olemasoleva üle)"
|
||||
StrCpy $UAC_ERROR_ELEVATE "Ei suuda ülendada õigusi, viga: "
|
||||
StrCpy $UAC_INSTALLER_REQUIRE_ADMIN "See paigaldaja vajab admini ligipääsu, proovi uuesti"
|
||||
StrCpy $INIT_INSTALLER_RUNNING "Paigaldaja on juba käimas."
|
||||
StrCpy $UAC_UNINSTALLER_REQUIRE_ADMIN "See desinstallija vajab admini ligipääsu, proovi uuesti"
|
||||
StrCpy $INIT_UNINSTALLER_RUNNING "See desinstallija on juba käimas"
|
||||
StrCpy $SectionGroup_Shortcuts "Viidad"
|
||||
StrCpy $ConfirmEndProcess_MESSAGEBOX_TEXT "Found ${APPLICATION_EXECUTABLE} process(s) which need to be stopped.$\nDo you want the installer to stop these for you?"
|
||||
StrCpy $ConfirmEndProcess_KILLING_PROCESSES_TEXT "Killing ${APPLICATION_EXECUTABLE} processes."
|
||||
StrCpy $INIT_NO_DESKTOP "Desktop Shortcut (overwrites existing)"
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
# Auto-generated - do not modify
|
||||
StrCpy $MUI_FINISHPAGE_SHOWREADME_TEXT_STRING "Montrer les notes de version"
|
||||
StrCpy $ConfirmEndProcess_MESSAGEBOX_TEXT "Le(s) processus en cours d’exécution ${APPLICATION_EXECUTABLE} doit être stoppé afin de poursuivre.$\nVoulez-vous que le programme d’installation s’en charge pour vous ?"
|
||||
StrCpy $ConfirmEndProcess_KILLING_PROCESSES_TEXT "Fermeture du processus ${APPLICATION_EXECUTABLE}."
|
||||
StrCpy $ConfirmEndProcess_KILL_NOT_FOUND_TEXT "Les processus à stopper n'ont pas été trouvés."
|
||||
StrCpy $PageReinstall_NEW_Field_1 "Une vieille version de ${APPLICATION_NAME} est installée sur votre système. Il est recommandé que vous désinstalliez cette version avant l'installation. Sélectionnez l'opération que vous voulez exécuter et cliquez sur Suivant pour continuer."
|
||||
StrCpy $PageReinstall_NEW_Field_2 "Désinstaller avant d'installer à nouveau"
|
||||
@@ -33,12 +35,10 @@ StrCpy $UNINSTALLER_FINISHED_Detail "Terminé"
|
||||
StrCpy $UNINSTALL_MESSAGEBOX "Il semble que ${APPLICATION_NAME} ne soit pas installée dans le dossier '$INSTDIR'.$\n$\nVoulez-vous poursuivre (non recommandé) ?"
|
||||
StrCpy $UNINSTALL_ABORT "Désinstallation interrompue par l'utilisateur"
|
||||
StrCpy $INIT_NO_QUICK_LAUNCH "Raccourci de lancement rapide (N/A)"
|
||||
StrCpy $INIT_NO_DESKTOP "Raccourci bureau (remplace l’existant)"
|
||||
StrCpy $UAC_ERROR_ELEVATE "Echec d'élévation, erreur :"
|
||||
StrCpy $UAC_INSTALLER_REQUIRE_ADMIN "Cet installateur requiert les droits administrateur, essayez à nouveau"
|
||||
StrCpy $INIT_INSTALLER_RUNNING "Une installation est déjà en cours."
|
||||
StrCpy $UAC_UNINSTALLER_REQUIRE_ADMIN "Ce désinstallateur requiert les droits administrateur, essayez à nouveau"
|
||||
StrCpy $INIT_UNINSTALLER_RUNNING "Une désinstallation est déjà en cours."
|
||||
StrCpy $SectionGroup_Shortcuts "Raccourcis"
|
||||
StrCpy $ConfirmEndProcess_MESSAGEBOX_TEXT "Found ${APPLICATION_EXECUTABLE} process(s) which need to be stopped.$\nDo you want the installer to stop these for you?"
|
||||
StrCpy $ConfirmEndProcess_KILLING_PROCESSES_TEXT "Killing ${APPLICATION_EXECUTABLE} processes."
|
||||
StrCpy $INIT_NO_DESKTOP "Desktop Shortcut (overwrites existing)"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Auto-generated - do not modify
|
||||
StrCpy $MUI_FINISHPAGE_SHOWREADME_TEXT_STRING "Release-Informationen anzeigen"
|
||||
StrCpy $ConfirmEndProcess_MESSAGEBOX_TEXT "${APPLICATION_EXECUTABLE} gefundene Prozess(e), die gestoppt werden müssen.$\nWollen Sie, dass der Installer diese nun für Sie stoppt?"
|
||||
StrCpy $ConfirmEndProcess_MESSAGEBOX_TEXT "${APPLICATION_EXECUTABLE} Prozess(e) gefunden, die gestoppt werden müssen.$\nWollen Sie, dass der Installer diese nun für Sie stoppt?"
|
||||
StrCpy $ConfirmEndProcess_KILLING_PROCESSES_TEXT "Stoppe ${APPLICATION_EXECUTABLE} Prozess(e)."
|
||||
StrCpy $ConfirmEndProcess_KILL_NOT_FOUND_TEXT "Prozess zum Beenden nicht gefunden!"
|
||||
StrCpy $PageReinstall_NEW_Field_1 "Eine ältere Version von ${APPLICATION_NAME} ist auf Ihrem System installiert. Es wird empfohlen, diese Version zunächst zu entfernen. Wählen Sie unter folgenden Vorgehenweisen und wählen Sie $\"Weiter$\"."
|
||||
|
||||
@@ -1,13 +1,15 @@
|
||||
# Auto-generated - do not modify
|
||||
StrCpy $MUI_FINISHPAGE_SHOWREADME_TEXT_STRING "Εμφάνιση σημειώσεων έκδοσης"
|
||||
StrCpy $ConfirmEndProcess_MESSAGEBOX_TEXT "Βρέθηκε η(οι) διεργασία(ες) ${APPLICATION_EXECUTABLE} η(οι) οποία(ες) θα πρέπει να τερματιστεί(ούν).$\nΘα θέλατε να την(τις) τερματίσει ο βοηθός εγκατάστασης για εσάς;"
|
||||
StrCpy $ConfirmEndProcess_KILLING_PROCESSES_TEXT "Τερματισμός διεργασιών ${APPLICATION_EXECUTABLE}."
|
||||
StrCpy $ConfirmEndProcess_KILL_NOT_FOUND_TEXT "Δεν βρέθηκε διεργασία για βίαιο τερματισμό!"
|
||||
StrCpy $PageReinstall_NEW_Field_1 "Μια παλαιότερη έκδοση της ${APPLICATION_NAME} είναι εγκατεστημένη στο σύστημά σας. Είναι προτεινόμενο να απεγκαταστήσετε την τρέχουσα έκδοση πριν την εγκατάσταση. Επιλέξτε τη διαδικασία που επιθυμείτε να πραγματοποιείσετε και πατήστε Επόμενο για να συνεχίσετε."
|
||||
StrCpy $PageReinstall_NEW_Field_1 "Μια παλαιότερη έκδοση της ${APPLICATION_NAME} είναι εγκατεστημένη στο σύστημά σας. Είναι προτεινόμενο να απεγκαταστήσετε την τρέχουσα έκδοση πριν την εγκατάσταση. Επιλέξτε τη διαδικασία που επιθυμείτε να εκτελέσετε και πατήστε Επόμενο για να συνεχίσετε."
|
||||
StrCpy $PageReinstall_NEW_Field_2 "Απεγκατάσταση πριν την εγκατάσταση"
|
||||
StrCpy $PageReinstall_NEW_Field_3 "Να μην απεγκατασταθεί"
|
||||
StrCpy $PageReinstall_NEW_MUI_HEADER_TEXT_TITLE "Ήδη εγκατεστημένο"
|
||||
StrCpy $PageReinstall_NEW_MUI_HEADER_TEXT_TITLE "Ήδη εγκατεστημένη"
|
||||
StrCpy $PageReinstall_NEW_MUI_HEADER_TEXT_SUBTITLE "Επιλέξτε πώς θέλετε να εγκαταστήσετε την ${APPLICATION_NAME}."
|
||||
StrCpy $PageReinstall_OLD_Field_1 "Μια νεώτερη έκδοση της ${APPLICATION_NAME} είναι ήδη εγκατεστημένη! Δεν συνίσταται να εγκαταστείσετε μια παλαιότερη έκδοση. Εάν θέλετε πραγματικά να εγκαταστήσετε αυτή την παλαιότερη έκδοση, είναι καλύτερο να απεγκαταστήσετε την τρέχουσα έκδοση πρώτα. Επιλέξτε τη διαδικασία που επιθυμείτε να πραγματοποιείσετε και επιλέξτε Επόμενο για να συνεχίσετε."
|
||||
StrCpy $PageReinstall_SAME_Field_1 "Η ${APPLICATION_NAME} ${VERSION} είναι ήδη εγκατεστημένη.\n\nΕπιλέξτε τη διαδικασία που επιθυμείτε να πραγματοποιείσετε και επιλέξτε Επόμενο για να συνεχίσετε."
|
||||
StrCpy $PageReinstall_OLD_Field_1 "Μια νεώτερη έκδοση της ${APPLICATION_NAME} είναι ήδη εγκατεστημένη! Δεν συνίσταται να εγκαταστείσετε μια παλαιότερη έκδοση. Εάν θέλετε πραγματικά να εγκαταστήσετε αυτήν την παλαιότερη έκδοση, είναι καλύτερο να απεγκαταστήσετε την τρέχουσα έκδοση πρώτα. Επιλέξτε τη διαδικασία που επιθυμείτε να εκτελέσετε και επιλέξτε Επόμενο για να συνεχίσετε."
|
||||
StrCpy $PageReinstall_SAME_Field_1 "Η ${APPLICATION_NAME} ${VERSION} είναι ήδη εγκατεστημένη.\n\nΕπιλέξτε τη διαδικασία που επιθυμείτε να εκτελέσετε και επιλέξτε Επόμενο για να συνεχίσετε."
|
||||
StrCpy $PageReinstall_SAME_Field_2 "Προσθήκη/ Επανεγκατάσταση συνιστωσών"
|
||||
StrCpy $PageReinstall_SAME_Field_3 "Απεγκατάσταση ${APPLICATION_NAME}"
|
||||
StrCpy $UNINSTALLER_APPDATA_TITLE "Απεγκατάσταση ${APPLICATION_NAME}"
|
||||
@@ -21,24 +23,22 @@ StrCpy $OPTION_SECTION_SC_QUICK_LAUNCH_SECTION "
|
||||
StrCpy $OPTION_SECTION_SC_QUICK_LAUNCH_DetailPrint "Δημιουργία Συντόμευσης Ταχείας Εκκίνησης"
|
||||
StrCpy $OPTION_SECTION_SC_APPLICATION_Desc "Βάση ${APPLICATION_NAME}."
|
||||
StrCpy $OPTION_SECTION_SC_START_MENU_Desc "Συντόμευση ${APPLICATION_NAME}."
|
||||
StrCpy $OPTION_SECTION_SC_DESKTOP_Desc "Συντόμευση στην επιφάνεια εργασίας της "
|
||||
StrCpy $OPTION_SECTION_SC_QUICK_LAUNCH_Desc "Συντόμευση Ταχείας Εκκίνησης της "
|
||||
StrCpy $UNINSTALLER_APPDATA_SUBTITLE "Αφαίρεση του φακέλου δεδομένων της ${APPLICATION_NAME} από τον υπολογιστή σας"
|
||||
StrCpy $OPTION_SECTION_SC_DESKTOP_Desc "Συντόμευση επιφάνειας εργασίας της ${APPLICATION_NAME}."
|
||||
StrCpy $OPTION_SECTION_SC_QUICK_LAUNCH_Desc "Συντόμευση Ταχείας Εκκίνησης της ${APPLICATION_NAME}."
|
||||
StrCpy $UNINSTALLER_APPDATA_SUBTITLE "Αφαίρεση του φακέλου δεδομένων της ${APPLICATION_NAME} από τον υπολογιστή σας."
|
||||
StrCpy $UNINSTALLER_APPDATA_LABEL_1 "Θέλετε να αφαιρέσετε τον φάκελο δεδομένων της ${APPLICATION_NAME};"
|
||||
StrCpy $UNINSTALLER_APPDATA_LABEL_2 "Αφήστε κενό για να διατηρήσετε τον φάκελο δεδομένων για μελλοντική χρήση ή επιλέξτε για να διγράψετε το φάκελο δεδομένων."
|
||||
StrCpy $UNINSTALLER_APPDATA_CHECKBOX "Να διαγραφεί ο φάκελος δεδομένων."
|
||||
StrCpy $UNINSTALLER_APPDATA_CHECKBOX "Ναι, διαγραφή αυτού του φακέλου δεδομένων."
|
||||
StrCpy $UNINSTALLER_FILE_Detail "Εγγραφή Εφαρμογής Απεγκατάστασης"
|
||||
StrCpy $UNINSTALLER_REGISTRY_Detail "Εγγραφή Κλειδιών μητρώου (Registry) της Εφαρμογής Εγκατάστασης"
|
||||
StrCpy $UNINSTALLER_FINISHED_Detail "Ολοκλήρωση"
|
||||
StrCpy $UNINSTALL_MESSAGEBOX "Φαίνεται πως η ${APPLICATION_NAME} είναι εγκατεστημένη στον κατάλογο '$INSTDIR'.$\n$\nΣυνέχιση παρ' όλα αυτά (δεν συνίσταται);"
|
||||
StrCpy $UNINSTALLER_FINISHED_Detail "Ολοκληρώθηκε"
|
||||
StrCpy $UNINSTALL_MESSAGEBOX "Δεν φαίνεται να είναι εγκατεστημένηη η ${APPLICATION_NAME} στον κατάλογο '$INSTDIR'.$\n$\nΣυνέχιση παρ' όλα αυτά (δεν συνίσταται);"
|
||||
StrCpy $UNINSTALL_ABORT "Η απεγκατάσταση ματαιώθηκε από το χρήστη"
|
||||
StrCpy $INIT_NO_QUICK_LAUNCH "Συντόμευση Ταχείας Εκκίνησης (Μ/Δ)"
|
||||
StrCpy $INIT_NO_DESKTOP "Συντόμευση Επιφάνειας Εργασίας (αντικαθιστά υπάρχουσα)"
|
||||
StrCpy $UAC_ERROR_ELEVATE "Αδυναμία ανύψωσης, σφάλμα:"
|
||||
StrCpy $UAC_INSTALLER_REQUIRE_ADMIN "Αυτή η εφαρμογή εγκατάστασης απαιτεί πρόσβαση διαχειριστή, δοκιμάστε ξανά"
|
||||
StrCpy $INIT_INSTALLER_RUNNING "Η εφαρμογή εγκατάστασης λειτουργεί ήδη."
|
||||
StrCpy $UAC_UNINSTALLER_REQUIRE_ADMIN "Αυτή η εφαρμογή απεγκατάστασης απαιτεί πρόσβαση διαχειριστή, δοκιμάστε ξανά"
|
||||
StrCpy $INIT_UNINSTALLER_RUNNING "Η εφαρμογή απεγκατάστασης λειτουργεί ήδη."
|
||||
StrCpy $SectionGroup_Shortcuts "Συντομεύσεις"
|
||||
StrCpy $ConfirmEndProcess_MESSAGEBOX_TEXT "Found ${APPLICATION_EXECUTABLE} process(s) which need to be stopped.$\nDo you want the installer to stop these for you?"
|
||||
StrCpy $ConfirmEndProcess_KILLING_PROCESSES_TEXT "Killing ${APPLICATION_EXECUTABLE} processes."
|
||||
StrCpy $INIT_NO_DESKTOP "Desktop Shortcut (overwrites existing)"
|
||||
|
||||
@@ -1,17 +1,18 @@
|
||||
# Auto-generated - do not modify
|
||||
StrCpy $MUI_FINISHPAGE_SHOWREADME_TEXT_STRING "Kiadási jegyzetek megtekintése"
|
||||
StrCpy $PageReinstall_NEW_Field_2 "Eltávolítás telepítés előtt"
|
||||
StrCpy $PageReinstall_NEW_Field_3 "Ne távolítsa el"
|
||||
StrCpy $PageReinstall_NEW_MUI_HEADER_TEXT_TITLE "Már telepítve"
|
||||
StrCpy $PageReinstall_NEW_MUI_HEADER_TEXT_SUBTITLE "Válaszd ki, hogy szeretnéd telepíteni a következő alkalmazást ${APPLICATION_NAME}."
|
||||
StrCpy $PageReinstall_SAME_Field_2 "Komponens hozzáadása/újratelepítése"
|
||||
StrCpy $PageReinstall_SAME_Field_3 "Eltávolitani ${APPLICATION_NAME}"
|
||||
StrCpy $UNINSTALLER_APPDATA_TITLE "Eltávolitani ${APPLICATION_NAME}"
|
||||
StrCpy $PageReinstall_SAME_Field_3 "${APPLICATION_NAME} eltávolítása"
|
||||
StrCpy $UNINSTALLER_APPDATA_TITLE "${APPLICATION_NAME} eltávolítása"
|
||||
StrCpy $UNINSTALLER_APPDATA_CHECKBOX "Igen, törölje ezt az adatkönyvtárat."
|
||||
StrCpy $UNINSTALLER_FINISHED_Detail "Befejezve"
|
||||
StrCpy $MUI_FINISHPAGE_SHOWREADME_TEXT_STRING "Show release notes"
|
||||
StrCpy $ConfirmEndProcess_MESSAGEBOX_TEXT "Found ${APPLICATION_EXECUTABLE} process(s) which need to be stopped.$\nDo you want the installer to stop these for you?"
|
||||
StrCpy $ConfirmEndProcess_KILLING_PROCESSES_TEXT "Killing ${APPLICATION_EXECUTABLE} processes."
|
||||
StrCpy $ConfirmEndProcess_KILL_NOT_FOUND_TEXT "Process to kill not found!"
|
||||
StrCpy $PageReinstall_NEW_Field_1 "An older version of ${APPLICATION_NAME} is installed on your system. It is recommended that you uninstall the current version before installing. Select the operation you want to perform and click Next to continue."
|
||||
StrCpy $PageReinstall_NEW_Field_2 "Uninstall before installing"
|
||||
StrCpy $PageReinstall_NEW_Field_3 "Do not uninstall"
|
||||
StrCpy $PageReinstall_OLD_Field_1 "A newer version of ${APPLICATION_NAME} is already installed! It is not recommended that you install an older version. If you really want to install this older version, it is better to uninstall the current version first. Select the operation you want to perform and click Next to continue."
|
||||
StrCpy $PageReinstall_SAME_Field_1 "${APPLICATION_NAME} ${VERSION} is already installed.\r\nSelect the operation you want to perform and click Next to continue."
|
||||
StrCpy $PageReinstall_SAME_MUI_HEADER_TEXT_SUBTITLE "Choose the maintenance option to perform."
|
||||
@@ -29,7 +30,6 @@ StrCpy $OPTION_SECTION_SC_QUICK_LAUNCH_Desc "Quick Launch shortcut for ${APPLICA
|
||||
StrCpy $UNINSTALLER_APPDATA_SUBTITLE "Remove ${APPLICATION_NAME}'s data folder from your computer."
|
||||
StrCpy $UNINSTALLER_APPDATA_LABEL_1 "Do you want to delete ${APPLICATION_NAME}'s data folder?"
|
||||
StrCpy $UNINSTALLER_APPDATA_LABEL_2 "Leave unchecked to keep the data folder for later use or check to delete the data folder."
|
||||
StrCpy $UNINSTALLER_APPDATA_CHECKBOX "Yes, delete this data folder."
|
||||
StrCpy $UNINSTALLER_FILE_Detail "Writing Uninstaller"
|
||||
StrCpy $UNINSTALLER_REGISTRY_Detail "Writing Installer Registry Keys"
|
||||
StrCpy $UNINSTALL_MESSAGEBOX "It does not appear that ${APPLICATION_NAME} is installed in the directory '$INSTDIR'.$\r$\nContinue anyway (not recommended)?"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# Auto-generated - do not modify
|
||||
StrCpy $MUI_FINISHPAGE_SHOWREADME_TEXT_STRING "Mostra le note di rilascio"
|
||||
StrCpy $ConfirmEndProcess_MESSAGEBOX_TEXT "Trovati i processi ${APPLICATION_EXECUTABLE} che dovrebbero essere fermati.$\nVuoi che il programma di installazione li fermi per te?"
|
||||
StrCpy $ConfirmEndProcess_KILLING_PROCESSES_TEXT "Sto terminando i processi ${APPLICATION_EXECUTABLE}."
|
||||
StrCpy $ConfirmEndProcess_MESSAGEBOX_TEXT "Trovati ${APPLICATION_EXECUTABLE} processi che dovrebbero essere fermati.$\nVuoi che il programma di installazione li fermi al posto tuo?"
|
||||
StrCpy $ConfirmEndProcess_KILLING_PROCESSES_TEXT "Sto terminando ${APPLICATION_EXECUTABLE} processi."
|
||||
StrCpy $ConfirmEndProcess_KILL_NOT_FOUND_TEXT "Il processo da terminare non è stato trovato!"
|
||||
StrCpy $PageReinstall_NEW_Field_1 "Una versione più datata di ${APPLICATION_NAME} è installata sul tuo sistema. Si consiglia di disinstallare la versione attuale prima di installare. Seleziona l'operazione da eseguire e fai clic su Avanti per continuare."
|
||||
StrCpy $PageReinstall_NEW_Field_2 "Disinstalla prima di installare"
|
||||
@@ -14,9 +14,9 @@ StrCpy $PageReinstall_SAME_Field_2 "Aggiungi/Reinstalla i componenti"
|
||||
StrCpy $PageReinstall_SAME_Field_3 "Disinstalla ${APPLICATION_NAME}"
|
||||
StrCpy $UNINSTALLER_APPDATA_TITLE "Disinstalla ${APPLICATION_NAME}"
|
||||
StrCpy $PageReinstall_SAME_MUI_HEADER_TEXT_SUBTITLE "Scegli l'opzione di manutenzione da eseguire."
|
||||
StrCpy $SEC_APPLICATION_DETAILS "Installazione degli elementi fondamentali di${APPLICATION_NAME}"
|
||||
StrCpy $SEC_APPLICATION_DETAILS "Installazione degli elementi fondamentali di ${APPLICATION_NAME}."
|
||||
StrCpy $OPTION_SECTION_SC_START_MENU_SECTION "Scorciatoia di programma menu Start"
|
||||
StrCpy $OPTION_SECTION_SC_START_MENU_DetailPrint "Aggiunta della scorciatoia per ${APPLICATION_NAME} al menu Start"
|
||||
StrCpy $OPTION_SECTION_SC_START_MENU_DetailPrint "Aggiunta della scorciatoia per ${APPLICATION_NAME} al menu Start."
|
||||
StrCpy $OPTION_SECTION_SC_DESKTOP_SECTION "Scorciatoia del desktop"
|
||||
StrCpy $OPTION_SECTION_SC_DESKTOP_DetailPrint "Creazione delle scorciatoie del desktop"
|
||||
StrCpy $OPTION_SECTION_SC_QUICK_LAUNCH_SECTION "Scorciatoia dell'avvio veloce"
|
||||
@@ -35,7 +35,7 @@ StrCpy $UNINSTALLER_FINISHED_Detail "Completato"
|
||||
StrCpy $UNINSTALL_MESSAGEBOX "Non sembra che ${APPLICATION_NAME} sia installato nella cartella '$INSTDIR'.$\nVuoi continuare comunque (non consigliato)?"
|
||||
StrCpy $UNINSTALL_ABORT "Disinstallazione interrotta dall'utente"
|
||||
StrCpy $INIT_NO_QUICK_LAUNCH "Scorciatoia dell'avvio veloce (N/D)"
|
||||
StrCpy $INIT_NO_DESKTOP "Scorciatoia sul desktop (sovrascrivi se esistente)"
|
||||
StrCpy $INIT_NO_DESKTOP "Scorciatoia del desktop (sovrascrivi se esistente)"
|
||||
StrCpy $UAC_ERROR_ELEVATE "Impossibile elevare, errore:"
|
||||
StrCpy $UAC_INSTALLER_REQUIRE_ADMIN "Il programma di installazione necessita delle credenziali di amministrazione, riprova"
|
||||
StrCpy $INIT_INSTALLER_RUNNING "Il programma di installazione è già in esecuzione."
|
||||
|
||||
@@ -8,8 +8,8 @@ StrCpy $PageReinstall_NEW_Field_2 "
|
||||
StrCpy $PageReinstall_NEW_Field_3 "アンインストールしない"
|
||||
StrCpy $PageReinstall_NEW_MUI_HEADER_TEXT_TITLE "インストール済"
|
||||
StrCpy $PageReinstall_NEW_MUI_HEADER_TEXT_SUBTITLE "${APPLICATION_NAME} のインストール方法を選択する"
|
||||
StrCpy $PageReinstall_OLD_Field_1 "${APPLICATION_NAME} の最新バージョンが既にインストールされています。\n旧バージョンのインストールはお勧めしません。旧バージョンのインストールが本当に必要な場合は、まず最新バージョンをアンインストールしてから、旧バージョンをインストールしてください。\nオペレーションを選択し、次へをクリックする。"
|
||||
StrCpy $PageReinstall_SAME_Field_1 "${APPLICATION_NAME} ${VERSION} は既にインストールされています。\n実行するオペレーションを選択し、次へをクリックする"
|
||||
StrCpy $PageReinstall_OLD_Field_1 "${APPLICATION_NAME} の最新バージョンがすでにインストールされています。\n旧バージョンのインストールはお勧めしません。旧バージョンのインストールが本当に必要な場合は、まず最新バージョンをアンインストールしてから、旧バージョンをインストールしてください。\nオペレーションを選択し、次へをクリックする。"
|
||||
StrCpy $PageReinstall_SAME_Field_1 "${APPLICATION_NAME} ${VERSION} はすでにインストールされています。\n実行するオペレーションを選択し、次へをクリックする"
|
||||
StrCpy $PageReinstall_SAME_Field_2 "追加/再インストールコンポーネント"
|
||||
StrCpy $PageReinstall_SAME_Field_3 "${APPLICATION_NAME} をアンインストール"
|
||||
StrCpy $UNINSTALLER_APPDATA_TITLE "${APPLICATION_NAME} をアンインストール"
|
||||
@@ -35,10 +35,10 @@ StrCpy $UNINSTALLER_FINISHED_Detail "
|
||||
StrCpy $UNINSTALL_MESSAGEBOX "${APPLICATION_NAME} は'$INSTDIR'.$$ ディレクトリにインストールされていません。エラーを無視し、進みますか (非推奨)?"
|
||||
StrCpy $UNINSTALL_ABORT "アンインストールは、ユーザーによって中止されました。"
|
||||
StrCpy $INIT_NO_QUICK_LAUNCH "クイック起動ショートカット(N/A)"
|
||||
StrCpy $INIT_NO_DESKTOP "デスクトップへショートカット作成(既にある場合は上書き)"
|
||||
StrCpy $INIT_NO_DESKTOP "デスクトップにショートカットを作成(すでにある場合は上書き)"
|
||||
StrCpy $UAC_ERROR_ELEVATE "エスカレーション不可です、エラー:"
|
||||
StrCpy $UAC_INSTALLER_REQUIRE_ADMIN "このインストーラーは、管理者権限が必要です。インストールを再試行してください。"
|
||||
StrCpy $INIT_INSTALLER_RUNNING "インストーラーは、既に起動しています。"
|
||||
StrCpy $INIT_INSTALLER_RUNNING "インストーラーは、すでに起動しています。"
|
||||
StrCpy $UAC_UNINSTALLER_REQUIRE_ADMIN "このアンインストーラーは、管理者権限が必要です。アンインストールを再試行してください。"
|
||||
StrCpy $INIT_UNINSTALLER_RUNNING "アンインストーラーは、既に起動しています。"
|
||||
StrCpy $INIT_UNINSTALLER_RUNNING "アンインストーラーは、すでに起動しています。"
|
||||
StrCpy $SectionGroup_Shortcuts "ショートカット"
|
||||
|
||||
@@ -1,44 +1,44 @@
|
||||
# Auto-generated - do not modify
|
||||
StrCpy $MUI_FINISHPAGE_SHOWREADME_TEXT_STRING "Pokaż informacje o wydaniu"
|
||||
StrCpy $ConfirmEndProcess_MESSAGEBOX_TEXT "Proces ${APPLICATION_EXECUTABLE} musi zostać zatrzymany $\nCzy chcesz aby instalator zatrzymał je dla ciebie?"
|
||||
StrCpy $ConfirmEndProcess_KILLING_PROCESSES_TEXT "Zamykam proces ${APPLICATION_EXECUTABLE}."
|
||||
StrCpy $ConfirmEndProcess_KILL_NOT_FOUND_TEXT "Nie znaleziono procesu!"
|
||||
StrCpy $PageReinstall_NEW_Field_1 "W Twoim systemie jest zainstalowana starsza wersja ${APPLICATION_NAME}. Zalecane jest jej usunięcie przed dalszą instalacją. Wybierz operację którą chcesz wykonać i naciśnij przycisk Dalej."
|
||||
StrCpy $PageReinstall_NEW_Field_2 "Odinstaluj przed instalacja"
|
||||
StrCpy $PageReinstall_NEW_Field_3 "Nie usuwaj "
|
||||
StrCpy $PageReinstall_NEW_MUI_HEADER_TEXT_TITLE "Już zainstalowane"
|
||||
StrCpy $PageReinstall_NEW_MUI_HEADER_TEXT_SUBTITLE "Wybierz jak chcesz zainstalować ${APPLICATION_NAME}."
|
||||
StrCpy $PageReinstall_OLD_Field_1 "Zainstalowana jest nowsza wersja ${APPLICATION_NAME}! Niezalecane jest instalowanie starszej wersji. Jeśli naprawdę chcesz zainstalować starszą wersję lepiej najpierw odinstalować obecną aplikację. Wybierz operację którą chcesz wykonać i naciśnij przycisk Dalej."
|
||||
StrCpy $PageReinstall_SAME_Field_1 "${APPLICATION_NAME} ${VERSION} jest już zainstalowany.\nWybierz operację którą chcesz wykonać i naciśnij przycisk Dalej."
|
||||
StrCpy $PageReinstall_SAME_Field_2 "Doda/Przeinstaluj komponenty"
|
||||
StrCpy $PageReinstall_SAME_Field_3 "Odinstaluj ${APPLICATION_NAME}"
|
||||
StrCpy $UNINSTALLER_APPDATA_TITLE "Odinstaluj ${APPLICATION_NAME}"
|
||||
StrCpy $PageReinstall_SAME_MUI_HEADER_TEXT_SUBTITLE "Wybierz sposób utrzymywania."
|
||||
StrCpy $SEC_APPLICATION_DETAILS "Instaluje niezbędne pliki ${APPLICATION_NAME}."
|
||||
StrCpy $OPTION_SECTION_SC_START_MENU_SECTION "Skrót w Menu Start"
|
||||
StrCpy $OPTION_SECTION_SC_START_MENU_DetailPrint "Dodaję skrót ${APPLICATION_NAME} w Menu Start."
|
||||
StrCpy $OPTION_SECTION_SC_DESKTOP_SECTION "Skrót na Pulpicie"
|
||||
StrCpy $OPTION_SECTION_SC_DESKTOP_DetailPrint "Utworzy skrót na Pulpicie"
|
||||
StrCpy $OPTION_SECTION_SC_QUICK_LAUNCH_SECTION "Skrót na Pasku Zadań"
|
||||
StrCpy $OPTION_SECTION_SC_QUICK_LAUNCH_DetailPrint "Tworzę skrót na Pasku Zadań"
|
||||
StrCpy $OPTION_SECTION_SC_APPLICATION_Desc "Niezbędne pliki ${APPLICATION_NAME}."
|
||||
StrCpy $OPTION_SECTION_SC_START_MENU_Desc "Skrót ${APPLICATION_NAME}."
|
||||
StrCpy $OPTION_SECTION_SC_DESKTOP_Desc "Skrót ${APPLICATION_NAME} na pulpicie."
|
||||
StrCpy $OPTION_SECTION_SC_QUICK_LAUNCH_Desc "Skrót ${APPLICATION_NAME} na Pasku Zadań."
|
||||
StrCpy $UNINSTALLER_APPDATA_SUBTITLE "Usuń folder z danymi ${APPLICATION_NAME} z komputera."
|
||||
StrCpy $UNINSTALLER_APPDATA_LABEL_1 "Czy chcesz usunąć folder z danymi ${APPLICATION_NAME}?"
|
||||
StrCpy $UNINSTALLER_APPDATA_LABEL_2 "Zostaw niezaznaczone aby zachować folder z danymi lub zaznacz aby go usunąć."
|
||||
StrCpy $UNINSTALLER_APPDATA_CHECKBOX "Tak, usuń folder z danymi."
|
||||
StrCpy $UNINSTALLER_FILE_Detail "Tworzę dezinstalator"
|
||||
StrCpy $UNINSTALLER_REGISTRY_Detail "Tworzę wpisy w rejestrze"
|
||||
StrCpy $UNINSTALLER_FINISHED_Detail "Zakończony"
|
||||
StrCpy $MUI_FINISHPAGE_SHOWREADME_TEXT_STRING "Show release notes"
|
||||
StrCpy $ConfirmEndProcess_MESSAGEBOX_TEXT "Found ${APPLICATION_EXECUTABLE} process(s) which need to be stopped.$\nDo you want the installer to stop these for you?"
|
||||
StrCpy $ConfirmEndProcess_KILLING_PROCESSES_TEXT "Killing ${APPLICATION_EXECUTABLE} processes."
|
||||
StrCpy $ConfirmEndProcess_KILL_NOT_FOUND_TEXT "Process to kill not found!"
|
||||
StrCpy $PageReinstall_NEW_Field_1 "An older version of ${APPLICATION_NAME} is installed on your system. It is recommended that you uninstall the current version before installing. Select the operation you want to perform and click Next to continue."
|
||||
StrCpy $PageReinstall_NEW_MUI_HEADER_TEXT_SUBTITLE "Choose how you want to install ${APPLICATION_NAME}."
|
||||
StrCpy $PageReinstall_OLD_Field_1 "A newer version of ${APPLICATION_NAME} is already installed! It is not recommended that you install an older version. If you really want to install this older version, it is better to uninstall the current version first. Select the operation you want to perform and click Next to continue."
|
||||
StrCpy $PageReinstall_SAME_Field_1 "${APPLICATION_NAME} ${VERSION} is already installed.\r\nSelect the operation you want to perform and click Next to continue."
|
||||
StrCpy $PageReinstall_SAME_MUI_HEADER_TEXT_SUBTITLE "Choose the maintenance option to perform."
|
||||
StrCpy $SEC_APPLICATION_DETAILS "Installing ${APPLICATION_NAME} essentials."
|
||||
StrCpy $OPTION_SECTION_SC_START_MENU_SECTION "Start Menu Program Shortcut"
|
||||
StrCpy $OPTION_SECTION_SC_START_MENU_DetailPrint "Adding shortcut for ${APPLICATION_NAME} to the Start Menu."
|
||||
StrCpy $OPTION_SECTION_SC_QUICK_LAUNCH_SECTION "Quick Launch Shortcut"
|
||||
StrCpy $OPTION_SECTION_SC_QUICK_LAUNCH_DetailPrint "Creating Quick Launch Shortcut"
|
||||
StrCpy $OPTION_SECTION_SC_APPLICATION_Desc "${APPLICATION_NAME} essentials."
|
||||
StrCpy $OPTION_SECTION_SC_START_MENU_Desc "${APPLICATION_NAME} shortcut."
|
||||
StrCpy $OPTION_SECTION_SC_DESKTOP_Desc "Desktop shortcut for ${APPLICATION_NAME}."
|
||||
StrCpy $OPTION_SECTION_SC_QUICK_LAUNCH_Desc "Quick Launch shortcut for ${APPLICATION_NAME}."
|
||||
StrCpy $UNINSTALLER_APPDATA_SUBTITLE "Remove ${APPLICATION_NAME}'s data folder from your computer."
|
||||
StrCpy $UNINSTALLER_APPDATA_LABEL_1 "Do you want to delete ${APPLICATION_NAME}'s data folder?"
|
||||
StrCpy $UNINSTALLER_APPDATA_LABEL_2 "Leave unchecked to keep the data folder for later use or check to delete the data folder."
|
||||
StrCpy $UNINSTALLER_APPDATA_CHECKBOX "Yes, delete this data folder."
|
||||
StrCpy $UNINSTALLER_FILE_Detail "Writing Uninstaller"
|
||||
StrCpy $UNINSTALLER_REGISTRY_Detail "Writing Installer Registry Keys"
|
||||
StrCpy $UNINSTALL_MESSAGEBOX "It does not appear that ${APPLICATION_NAME} is installed in the directory '$INSTDIR'.$\r$\nContinue anyway (not recommended)?"
|
||||
StrCpy $UNINSTALL_ABORT "Uninstall aborted by user"
|
||||
StrCpy $INIT_NO_QUICK_LAUNCH "Quick Launch Shortcut (N/A)"
|
||||
StrCpy $INIT_NO_DESKTOP "Desktop Shortcut (overwrites existing)"
|
||||
StrCpy $UAC_ERROR_ELEVATE "Unable to elevate, error:"
|
||||
StrCpy $UAC_INSTALLER_REQUIRE_ADMIN "This installer requires admin access, try again"
|
||||
StrCpy $INIT_INSTALLER_RUNNING "The installer is already running."
|
||||
StrCpy $UAC_UNINSTALLER_REQUIRE_ADMIN "This uninstaller requires admin access, try again"
|
||||
StrCpy $INIT_UNINSTALLER_RUNNING "The uninstaller is already running."
|
||||
StrCpy $SectionGroup_Shortcuts "Shortcuts"
|
||||
StrCpy $UNINSTALL_MESSAGEBOX "Nie wygląda na to że ${APPLICATION_NAME} jest zainstalowane w katalogu '$INSTDIR'.$$ Kontynuować mimo tego (nie zalecane)?"
|
||||
StrCpy $UNINSTALL_ABORT "Dezinstalacja przerwana przez użytkownika"
|
||||
StrCpy $INIT_NO_QUICK_LAUNCH "Skrót na Pasku Zadań (NIE DOTYCZY)"
|
||||
StrCpy $INIT_NO_DESKTOP "Skróty na pulpicie (nadpisuje obecne)"
|
||||
StrCpy $UAC_ERROR_ELEVATE "Niemożność podniesienia, błąd:"
|
||||
StrCpy $UAC_INSTALLER_REQUIRE_ADMIN "Ten instalator potrzebuje uprawnień administratora, spróbuj ponownie"
|
||||
StrCpy $INIT_INSTALLER_RUNNING "Instalator już jest uruchomiony."
|
||||
StrCpy $UAC_UNINSTALLER_REQUIRE_ADMIN "Ten dezinstalator potrzebuje uprawnień administratora, spróbuj ponownie"
|
||||
StrCpy $INIT_UNINSTALLER_RUNNING "Dezinstalator już jest uruchomiony."
|
||||
StrCpy $SectionGroup_Shortcuts "Skróty"
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
# Auto-generated - do not modify
|
||||
StrCpy $MUI_FINISHPAGE_SHOWREADME_TEXT_STRING "Mostrar notas de lançamento"
|
||||
StrCpy $ConfirmEndProcess_MESSAGEBOX_TEXT "Encontrados ${APPLICATION_EXECUTABLE} processos que precisam de ser parados.$\nDeseja que o instalador os pare ?"
|
||||
StrCpy $ConfirmEndProcess_KILLING_PROCESSES_TEXT "A terminar ${APPLICATION_EXECUTABLE} processos."
|
||||
StrCpy $ConfirmEndProcess_MESSAGEBOX_TEXT "Encontrados processos ${APPLICATION_EXECUTABLE} que precisam de ser parados.$\nDeseja que o instalador os pare ?"
|
||||
StrCpy $ConfirmEndProcess_KILLING_PROCESSES_TEXT "A terminar processos ${APPLICATION_EXECUTABLE}."
|
||||
StrCpy $ConfirmEndProcess_KILL_NOT_FOUND_TEXT "Processo para terminar não foi encontrado!"
|
||||
StrCpy $PageReinstall_NEW_Field_1 "Está instalada uma versão anterior de ${APPLICATION_NAME} no seu sistema. Recomenda-se que desinstale primeiro a versão atual antes de instalar. Selecione a operação que pretende fazer, e clique Seguinte para continuar."
|
||||
StrCpy $PageReinstall_NEW_Field_2 "Desinstalar antes de instalar"
|
||||
StrCpy $PageReinstall_NEW_Field_3 "Não instalar"
|
||||
StrCpy $PageReinstall_NEW_Field_3 "Não desinstalar"
|
||||
StrCpy $PageReinstall_NEW_MUI_HEADER_TEXT_TITLE "Já instalado"
|
||||
StrCpy $PageReinstall_NEW_MUI_HEADER_TEXT_SUBTITLE "Escolha como pretende instalar ${APPLICATION_NAME}."
|
||||
StrCpy $PageReinstall_OLD_Field_1 "Já esta instalada uma nova versão dfe ${APPLICATION_NAME}! Não se recomenda instalar uma versão anterior. Se quer mesmo instalar esta versão mais antiga, é melhor desinstalar primeiro a versão atual. Selecione a operação que pretende fazer e clique Seguinte para continuar."
|
||||
@@ -26,18 +26,18 @@ StrCpy $OPTION_SECTION_SC_START_MENU_Desc "Atalho de ${APPLICATION_NAME}."
|
||||
StrCpy $OPTION_SECTION_SC_DESKTOP_Desc "Atalho no ambiente de trabalho de ${APPLICATION_NAME}."
|
||||
StrCpy $OPTION_SECTION_SC_QUICK_LAUNCH_Desc "Atalho de início rápido de ${APPLICATION_NAME}."
|
||||
StrCpy $UNINSTALLER_APPDATA_SUBTITLE "Remover a pasta de dados de ${APPLICATION_NAME} do seu computador."
|
||||
StrCpy $UNINSTALLER_APPDATA_LABEL_1 "Deseja apagar a pasta de dados de ${APPLICATION_NAME}?"
|
||||
StrCpy $UNINSTALLER_APPDATA_LABEL_1 "Deseja remover a pasta de dados de ${APPLICATION_NAME}?"
|
||||
StrCpy $UNINSTALLER_APPDATA_LABEL_2 "Não assinale para manter a pasta de dados para uso mais tarde, ou assinale para apagar a pasta de dados."
|
||||
StrCpy $UNINSTALLER_APPDATA_CHECKBOX "Sim, apagar esta pasta de dados."
|
||||
StrCpy $UNINSTALLER_APPDATA_CHECKBOX "Sim, remover esta pasta."
|
||||
StrCpy $UNINSTALLER_FILE_Detail "A escrever o Desinstalador"
|
||||
StrCpy $UNINSTALLER_REGISTRY_Detail "A escrever chaves de registo do instalador"
|
||||
StrCpy $UNINSTALLER_FINISHED_Detail "Acabou"
|
||||
StrCpy $UNINSTALLER_FINISHED_Detail "Terminado"
|
||||
StrCpy $UNINSTALL_MESSAGEBOX "Não parece que ${APPLICATION_NAME} esteja instalado no diretório '$INSTDIR'.$\n$\nContinuar na mesma (não recomendado)?"
|
||||
StrCpy $UNINSTALL_ABORT "Desinstalação abortada pelo utilizador"
|
||||
StrCpy $UNINSTALL_ABORT "Desinstalação cancelada pelo utilizador"
|
||||
StrCpy $INIT_NO_QUICK_LAUNCH "Atalho de Início Rápido (N/A)"
|
||||
StrCpy $INIT_NO_DESKTOP "Atalho do Ambiente de Trabalho (sobrepõe o existente)"
|
||||
StrCpy $UAC_ERROR_ELEVATE "Incapaz de elevar, erro:"
|
||||
StrCpy $UAC_INSTALLER_REQUIRE_ADMIN "Este instalador precisa de acessos de administrador; tente novamente"
|
||||
StrCpy $UAC_INSTALLER_REQUIRE_ADMIN "Este instalador precisa de permissões de administrador, tente novamente"
|
||||
StrCpy $INIT_INSTALLER_RUNNING "O instalador já está a correr."
|
||||
StrCpy $UAC_UNINSTALLER_REQUIRE_ADMIN "Este desinstalador precisa de acesso de administrador; tente novamente"
|
||||
StrCpy $INIT_UNINSTALLER_RUNNING "O desinstalador já está a correr."
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
# Auto-generated - do not modify
|
||||
StrCpy $MUI_FINISHPAGE_SHOWREADME_TEXT_STRING "Показать примечания к выпуску"
|
||||
StrCpy $ConfirmEndProcess_MESSAGEBOX_TEXT "Обнаружены процес(сы) ${APPLICATION_EXECUTABLE}, которые должны быть остановлены.$\nХотите программа установки сделает это самостоятельно?"
|
||||
StrCpy $ConfirmEndProcess_KILLING_PROCESSES_TEXT "Завершение процессов ${APPLICATION_EXECUTABLE}."
|
||||
StrCpy $ConfirmEndProcess_KILL_NOT_FOUND_TEXT "Не найдены процессы, которые нужно завершить!"
|
||||
StrCpy $PageReinstall_NEW_Field_1 "Обнаружена более старая версия ${APPLICATION_NAME}. Рекомендуется удалить её перед установкой. Выберите желаемое действие и нажмите $\"Далее$\"."
|
||||
StrCpy $PageReinstall_NEW_Field_2 "Удалить перед установкой"
|
||||
@@ -33,12 +35,10 @@ StrCpy $UNINSTALLER_FINISHED_Detail "Завершено"
|
||||
StrCpy $UNINSTALL_MESSAGEBOX "Скорее всего, приложение ${APPLICATION_NAME} уже установлено в директорию '$INSTDIR'.\nВсе равно продолжить (не рекомендуется)?"
|
||||
StrCpy $UNINSTALL_ABORT "Удаление отменено пользователем"
|
||||
StrCpy $INIT_NO_QUICK_LAUNCH "Ярлык быстрого запуска (недоступен)"
|
||||
StrCpy $INIT_NO_DESKTOP "Ярлык на рабочем столе (перезаписать существующий)"
|
||||
StrCpy $UAC_ERROR_ELEVATE "Невозможно поднять, ошибка:"
|
||||
StrCpy $UAC_INSTALLER_REQUIRE_ADMIN "Для установки необходимы права администратора, попробуйте ещё раз."
|
||||
StrCpy $INIT_INSTALLER_RUNNING "Установщик уже запущен."
|
||||
StrCpy $UAC_UNINSTALLER_REQUIRE_ADMIN "Этот деинсталятор требует права администратора, попытайтесь ещё"
|
||||
StrCpy $INIT_UNINSTALLER_RUNNING "Программа удаления уже выполняется."
|
||||
StrCpy $SectionGroup_Shortcuts "Ярлыки"
|
||||
StrCpy $ConfirmEndProcess_MESSAGEBOX_TEXT "Found ${APPLICATION_EXECUTABLE} process(s) which need to be stopped.$\nDo you want the installer to stop these for you?"
|
||||
StrCpy $ConfirmEndProcess_KILLING_PROCESSES_TEXT "Killing ${APPLICATION_EXECUTABLE} processes."
|
||||
StrCpy $INIT_NO_DESKTOP "Desktop Shortcut (overwrites existing)"
|
||||
|
||||
44
admin/win/nsi/l10n/SimpChinese.nsh
Normal file
44
admin/win/nsi/l10n/SimpChinese.nsh
Normal file
@@ -0,0 +1,44 @@
|
||||
# Auto-generated - do not modify
|
||||
StrCpy $MUI_FINISHPAGE_SHOWREADME_TEXT_STRING "查看版本日志"
|
||||
StrCpy $ConfirmEndProcess_KILLING_PROCESSES_TEXT "杀死${APPLICATION_EXECUTABLE}进程。"
|
||||
StrCpy $ConfirmEndProcess_KILL_NOT_FOUND_TEXT "未找到要杀死的进程!"
|
||||
StrCpy $PageReinstall_NEW_Field_1 "您的系统已经安装${APPLICATION_NAME}较老版本。建议安装前卸载当前版本。选择将要执行的操作,点击下一步继续。"
|
||||
StrCpy $PageReinstall_NEW_Field_2 "在安装前先卸载"
|
||||
StrCpy $PageReinstall_NEW_Field_3 "不要卸载"
|
||||
StrCpy $PageReinstall_NEW_MUI_HEADER_TEXT_TITLE "已经安装"
|
||||
StrCpy $PageReinstall_NEW_MUI_HEADER_TEXT_SUBTITLE "选择如何安装${APPLICATION_NAME}。"
|
||||
StrCpy $PageReinstall_SAME_Field_2 "添加/重装组件"
|
||||
StrCpy $PageReinstall_SAME_Field_3 "卸载${APPLICATION_NAME}"
|
||||
StrCpy $UNINSTALLER_APPDATA_TITLE "卸载${APPLICATION_NAME}"
|
||||
StrCpy $SEC_APPLICATION_DETAILS "安装${APPLICATION_NAME}基本组件。"
|
||||
StrCpy $OPTION_SECTION_SC_START_MENU_SECTION "开始菜单程序快捷方式"
|
||||
StrCpy $OPTION_SECTION_SC_DESKTOP_SECTION "桌面快捷方式"
|
||||
StrCpy $OPTION_SECTION_SC_DESKTOP_DetailPrint "创建桌面快捷方式"
|
||||
StrCpy $OPTION_SECTION_SC_QUICK_LAUNCH_SECTION "快速启动栏快捷方式"
|
||||
StrCpy $OPTION_SECTION_SC_QUICK_LAUNCH_DetailPrint "创建快速启动栏快捷方式"
|
||||
StrCpy $OPTION_SECTION_SC_APPLICATION_Desc "${APPLICATION_NAME}基本组件。"
|
||||
StrCpy $OPTION_SECTION_SC_START_MENU_Desc "${APPLICATION_NAME}快捷方式。"
|
||||
StrCpy $OPTION_SECTION_SC_DESKTOP_Desc "${APPLICATION_NAME}桌面快捷方式。"
|
||||
StrCpy $OPTION_SECTION_SC_QUICK_LAUNCH_Desc "${APPLICATION_NAME}快速启动栏快捷方式。"
|
||||
StrCpy $UNINSTALLER_APPDATA_CHECKBOX "删除数据文件。"
|
||||
StrCpy $UNINSTALLER_FILE_Detail "覆盖卸载器"
|
||||
StrCpy $UNINSTALLER_FINISHED_Detail "完成"
|
||||
StrCpy $INIT_NO_QUICK_LAUNCH "快速启动栏快捷方式(N/A)"
|
||||
StrCpy $INIT_NO_DESKTOP "桌面快捷方式(覆盖)"
|
||||
StrCpy $SectionGroup_Shortcuts "快捷方式"
|
||||
StrCpy $ConfirmEndProcess_MESSAGEBOX_TEXT "Found ${APPLICATION_EXECUTABLE} process(s) which need to be stopped.$\nDo you want the installer to stop these for you?"
|
||||
StrCpy $PageReinstall_OLD_Field_1 "A newer version of ${APPLICATION_NAME} is already installed! It is not recommended that you install an older version. If you really want to install this older version, it is better to uninstall the current version first. Select the operation you want to perform and click Next to continue."
|
||||
StrCpy $PageReinstall_SAME_Field_1 "${APPLICATION_NAME} ${VERSION} is already installed.\r\nSelect the operation you want to perform and click Next to continue."
|
||||
StrCpy $PageReinstall_SAME_MUI_HEADER_TEXT_SUBTITLE "Choose the maintenance option to perform."
|
||||
StrCpy $OPTION_SECTION_SC_START_MENU_DetailPrint "Adding shortcut for ${APPLICATION_NAME} to the Start Menu."
|
||||
StrCpy $UNINSTALLER_APPDATA_SUBTITLE "Remove ${APPLICATION_NAME}'s data folder from your computer."
|
||||
StrCpy $UNINSTALLER_APPDATA_LABEL_1 "Do you want to delete ${APPLICATION_NAME}'s data folder?"
|
||||
StrCpy $UNINSTALLER_APPDATA_LABEL_2 "Leave unchecked to keep the data folder for later use or check to delete the data folder."
|
||||
StrCpy $UNINSTALLER_REGISTRY_Detail "Writing Installer Registry Keys"
|
||||
StrCpy $UNINSTALL_MESSAGEBOX "It does not appear that ${APPLICATION_NAME} is installed in the directory '$INSTDIR'.$\r$\nContinue anyway (not recommended)?"
|
||||
StrCpy $UNINSTALL_ABORT "Uninstall aborted by user"
|
||||
StrCpy $UAC_ERROR_ELEVATE "Unable to elevate, error:"
|
||||
StrCpy $UAC_INSTALLER_REQUIRE_ADMIN "This installer requires admin access, try again"
|
||||
StrCpy $INIT_INSTALLER_RUNNING "The installer is already running."
|
||||
StrCpy $UAC_UNINSTALLER_REQUIRE_ADMIN "This uninstaller requires admin access, try again"
|
||||
StrCpy $INIT_UNINSTALLER_RUNNING "The uninstaller is already running."
|
||||
@@ -1,5 +1,7 @@
|
||||
# Auto-generated - do not modify
|
||||
StrCpy $MUI_FINISHPAGE_SHOWREADME_TEXT_STRING "Zobrazi<EFBFBD> zoznam zmien"
|
||||
StrCpy $ConfirmEndProcess_MESSAGEBOX_TEXT "Našli sa ${APPLICATION_EXECUTABLE} proces (y), ktoré je potrebné zastavi<76>.$\nChcete, aby ich inštalátor zastavil?"
|
||||
StrCpy $ConfirmEndProcess_KILLING_PROCESSES_TEXT "Ukonèujem ${APPLICATION_EXECUTABLE} procesy."
|
||||
StrCpy $ConfirmEndProcess_KILL_NOT_FOUND_TEXT "Proces ukonèenia nebol nájdený!"
|
||||
StrCpy $PageReinstall_NEW_Field_1 "Staršia verzia ${APPLICATION_NAME} je nainštalovaná vo vašom systéme. Odporúèam vám odinštalova<76> aktuálnu verziu pred inštaláciou. Vyberte operáciu, ktorú chcete vykona<6E>, a kliknite na tlaèidlo Ïalej pre pokraèovanie."
|
||||
StrCpy $PageReinstall_NEW_Field_2 "Odinštalova<EFBFBD> pred inštaláciou"
|
||||
@@ -33,12 +35,10 @@ StrCpy $UNINSTALLER_FINISHED_Detail "Dokon
|
||||
StrCpy $UNINSTALL_MESSAGEBOX "Nezdá sa, že ${APPLICATION_NAME} je nainštalovaný v prieèinku '$INSTDIR'.$\n$\nNapriek tomu pokraèova<76> (neodporúèa sa)?"
|
||||
StrCpy $UNINSTALL_ABORT "Odinštalácia prerušená používate¾om"
|
||||
StrCpy $INIT_NO_QUICK_LAUNCH "Zástupca na paneli úloh (N/A)"
|
||||
StrCpy $INIT_NO_DESKTOP "Zástupca na ploche (prepíše existujúci)"
|
||||
StrCpy $UAC_ERROR_ELEVATE "Nemožno povýši<C5A1>, chyba:"
|
||||
StrCpy $UAC_INSTALLER_REQUIRE_ADMIN "Tento inštalátor vyžaduje admin prístup, skúste to znova"
|
||||
StrCpy $INIT_INSTALLER_RUNNING "Inštalátor je už spustený."
|
||||
StrCpy $UAC_UNINSTALLER_REQUIRE_ADMIN "Tento odinštalátor vyžaduje admin prístup, skúste to znova"
|
||||
StrCpy $INIT_UNINSTALLER_RUNNING "Odinštalátor je už spustený."
|
||||
StrCpy $SectionGroup_Shortcuts "Zástupcovia"
|
||||
StrCpy $ConfirmEndProcess_MESSAGEBOX_TEXT "Found ${APPLICATION_EXECUTABLE} process(s) which need to be stopped.$\nDo you want the installer to stop these for you?"
|
||||
StrCpy $ConfirmEndProcess_KILLING_PROCESSES_TEXT "Killing ${APPLICATION_EXECUTABLE} processes."
|
||||
StrCpy $INIT_NO_DESKTOP "Desktop Shortcut (overwrites existing)"
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
# Auto-generated - do not modify
|
||||
StrCpy $MUI_FINISHPAGE_SHOWREADME_TEXT_STRING "Pokaži opombe k objavi"
|
||||
StrCpy $ConfirmEndProcess_MESSAGEBOX_TEXT "Zaznana so dejavna opravila programa ${APPLICATION_EXECUTABLE}, ki pa morajo biti pred nadaljevanjem zaustavljena.$\nAli želite izvajanje teh dejanj končati?"
|
||||
StrCpy $ConfirmEndProcess_KILLING_PROCESSES_TEXT "Poteka zaustavljanje opravil programa ${APPLICATION_EXECUTABLE}"
|
||||
StrCpy $ConfirmEndProcess_KILL_NOT_FOUND_TEXT "Opravila, določenega za uničenje, ni mogoče najti!"
|
||||
StrCpy $PageReinstall_NEW_Field_1 "Nameščena je starejša različica ${APPLICATION_NAME}. Priporočljivo je najprej odstraniti obstoječo namestitev in šele nato namestiti novo. Izberite ustrezno možnost in kliknite za nadaljevanje."
|
||||
StrCpy $PageReinstall_NEW_Field_2 "Pred namestitvijo je treba obstoječo različico odstraniti"
|
||||
@@ -33,12 +35,10 @@ StrCpy $UNINSTALLER_FINISHED_Detail "Kon
|
||||
StrCpy $UNINSTALL_MESSAGEBOX "Ni videti, da bi bil program ${APPLICATION_NAME} nameščen v mapi '$INSTDIR'.$\n$\nAli želite vseeno nadaljevati (ni priporočeno)?"
|
||||
StrCpy $UNINSTALL_ABORT "Odstranjevanje namestitve je bilo prekinjeno s strani uporabnika"
|
||||
StrCpy $INIT_NO_QUICK_LAUNCH "Bližnjica za hiter dostop (N/A)"
|
||||
StrCpy $INIT_NO_DESKTOP "Bližnjica namizja (obstajajo predmeti za prepis)"
|
||||
StrCpy $UAC_ERROR_ELEVATE "Ni mogoče dvigniti; napaka:"
|
||||
StrCpy $UAC_INSTALLER_REQUIRE_ADMIN "Namestilnik zahteva skrbniška dovoljenja."
|
||||
StrCpy $INIT_INSTALLER_RUNNING "Namestilnik je že zagnan."
|
||||
StrCpy $UAC_UNINSTALLER_REQUIRE_ADMIN "Program za odstranjevanje namestitve zahteva skrbniška dovoljenja."
|
||||
StrCpy $INIT_UNINSTALLER_RUNNING "Program za odstranjevanje namestitve je že zagnan."
|
||||
StrCpy $SectionGroup_Shortcuts "Bližnjice"
|
||||
StrCpy $ConfirmEndProcess_MESSAGEBOX_TEXT "Found ${APPLICATION_EXECUTABLE} process(s) which need to be stopped.$\nDo you want the installer to stop these for you?"
|
||||
StrCpy $ConfirmEndProcess_KILLING_PROCESSES_TEXT "Killing ${APPLICATION_EXECUTABLE} processes."
|
||||
StrCpy $INIT_NO_DESKTOP "Desktop Shortcut (overwrites existing)"
|
||||
|
||||
44
admin/win/nsi/l10n/SpanishInternational.nsh
Normal file
44
admin/win/nsi/l10n/SpanishInternational.nsh
Normal file
@@ -0,0 +1,44 @@
|
||||
# Auto-generated - do not modify
|
||||
StrCpy $MUI_FINISHPAGE_SHOWREADME_TEXT_STRING "Mostrar notas de la versión"
|
||||
StrCpy $ConfirmEndProcess_KILLING_PROCESSES_TEXT "Parando el proceso ${APPLICATION_EXECUTABLE}."
|
||||
StrCpy $ConfirmEndProcess_KILL_NOT_FOUND_TEXT "Proceso a detener no encontrado!"
|
||||
StrCpy $PageReinstall_NEW_Field_1 "Una versión anterior de ${APPLICATION_NAME} esta instalada en el sistema. Es recomendado que quite esta versión antes de instalar. Elija la operación a realizar y seleccione Siguiente para continuar."
|
||||
StrCpy $PageReinstall_NEW_Field_2 "Des-instale antes de Instalar."
|
||||
StrCpy $PageReinstall_NEW_Field_3 "No des-instalar."
|
||||
StrCpy $PageReinstall_NEW_MUI_HEADER_TEXT_TITLE "Actualmente Instalado."
|
||||
StrCpy $PageReinstall_NEW_MUI_HEADER_TEXT_SUBTITLE "Elija como desea instalar ${APPLICATION_NAME}."
|
||||
StrCpy $PageReinstall_OLD_Field_1 "Una versión mas reciente de ${APPLICATION_NAME} esta actualmente instalada! No es recomendado que instale una versión antigua. Si realmente desea instalar esta versión obsoleta, es mejor que des-instale la versión actual primero. Seleccione la operación que desea realizar y presione en Siguiente para continuar. "
|
||||
StrCpy $PageReinstall_SAME_Field_2 "Agregar/Re-Instalar componentes"
|
||||
StrCpy $PageReinstall_SAME_Field_3 "Des-instalar ${APPLICATION_NAME}"
|
||||
StrCpy $UNINSTALLER_APPDATA_TITLE "Des-instalar ${APPLICATION_NAME}"
|
||||
StrCpy $PageReinstall_SAME_MUI_HEADER_TEXT_SUBTITLE "Elija la opción de mantenimiento a realizar."
|
||||
StrCpy $SEC_APPLICATION_DETAILS "Instalar esenciales ${APPLICATION_NAME}."
|
||||
StrCpy $OPTION_SECTION_SC_START_MENU_SECTION "Acceso Directo en Menú de Programas"
|
||||
StrCpy $OPTION_SECTION_SC_START_MENU_DetailPrint "Agregando el Acceso Directo al Menú de Inicio para ${APPLICATION_NAME}."
|
||||
StrCpy $OPTION_SECTION_SC_DESKTOP_SECTION "Acceso directo en Escritorio"
|
||||
StrCpy $OPTION_SECTION_SC_DESKTOP_DetailPrint "Creando Accesos Directos en Escritorio"
|
||||
StrCpy $OPTION_SECTION_SC_START_MENU_Desc "Acceso directo de ${APPLICATION_NAME}"
|
||||
StrCpy $OPTION_SECTION_SC_DESKTOP_Desc "Acceso Directo al Escritorio para ${APPLICATION_NAME}."
|
||||
StrCpy $UNINSTALLER_APPDATA_SUBTITLE "Quitar la carpeta de datos ${APPLICATION_NAME} de la computadora."
|
||||
StrCpy $UNINSTALLER_APPDATA_LABEL_1 "Desea borrar la carpeta de datos de ${APPLICATION_NAME}?"
|
||||
StrCpy $UNINSTALLER_APPDATA_LABEL_2 "Dejar des-tildado para mantener la carpeta de datos para posterior uso o tildar para borrar la carpeta de datos."
|
||||
StrCpy $UNINSTALLER_APPDATA_CHECKBOX "Si, eliminar esta carpeta de datos."
|
||||
StrCpy $UNINSTALLER_FILE_Detail "Escribiendo Des-Instalador."
|
||||
StrCpy $UNINSTALLER_REGISTRY_Detail "Escribiendo claves de Registro del Instalador"
|
||||
StrCpy $UNINSTALLER_FINISHED_Detail "Terminado"
|
||||
StrCpy $UNINSTALL_ABORT "Des-instalación abortada por el usuario"
|
||||
StrCpy $INIT_NO_DESKTOP "Acceso Directo en Escritorio (Sobrescribe existentes)"
|
||||
StrCpy $UAC_INSTALLER_REQUIRE_ADMIN "Este instalador requiere acceso Administrador, intente de nuevo. "
|
||||
StrCpy $INIT_INSTALLER_RUNNING "El instalador ya esta corriendo."
|
||||
StrCpy $UAC_UNINSTALLER_REQUIRE_ADMIN "Este des-instalador requiere acceso administrador, intente de nuevo"
|
||||
StrCpy $INIT_UNINSTALLER_RUNNING "El des-instalador ya esta corriendo"
|
||||
StrCpy $SectionGroup_Shortcuts "Accesos Directos"
|
||||
StrCpy $ConfirmEndProcess_MESSAGEBOX_TEXT "Found ${APPLICATION_EXECUTABLE} process(s) which need to be stopped.$\nDo you want the installer to stop these for you?"
|
||||
StrCpy $PageReinstall_SAME_Field_1 "${APPLICATION_NAME} ${VERSION} is already installed.\r\nSelect the operation you want to perform and click Next to continue."
|
||||
StrCpy $OPTION_SECTION_SC_QUICK_LAUNCH_SECTION "Quick Launch Shortcut"
|
||||
StrCpy $OPTION_SECTION_SC_QUICK_LAUNCH_DetailPrint "Creating Quick Launch Shortcut"
|
||||
StrCpy $OPTION_SECTION_SC_APPLICATION_Desc "${APPLICATION_NAME} essentials."
|
||||
StrCpy $OPTION_SECTION_SC_QUICK_LAUNCH_Desc "Quick Launch shortcut for ${APPLICATION_NAME}."
|
||||
StrCpy $UNINSTALL_MESSAGEBOX "It does not appear that ${APPLICATION_NAME} is installed in the directory '$INSTDIR'.$\r$\nContinue anyway (not recommended)?"
|
||||
StrCpy $INIT_NO_QUICK_LAUNCH "Quick Launch Shortcut (N/A)"
|
||||
StrCpy $UAC_ERROR_ELEVATE "Unable to elevate, error:"
|
||||
44
admin/win/nsi/l10n/Swedish.nsh
Normal file
44
admin/win/nsi/l10n/Swedish.nsh
Normal file
@@ -0,0 +1,44 @@
|
||||
# Auto-generated - do not modify
|
||||
StrCpy $MUI_FINISHPAGE_SHOWREADME_TEXT_STRING "Visa versionsinformationen"
|
||||
StrCpy $ConfirmEndProcess_MESSAGEBOX_TEXT "Hittade ${APPLICATION_EXECUTABLE} process(er) som behöver stoppas.$\nVill du att installationsprogrammet ska stoppa dessa åt dig?"
|
||||
StrCpy $ConfirmEndProcess_KILLING_PROCESSES_TEXT "Dödar ${APPLICATION_EXECUTABLE} processer."
|
||||
StrCpy $ConfirmEndProcess_KILL_NOT_FOUND_TEXT "Processen att döda hittades inte!"
|
||||
StrCpy $PageReinstall_NEW_Field_1 "En tidigare version av ${APPLICATION_NAME} är installerad på ditt system. Det är rekommenderat att du avinstallerar den nuvarande versionen före installation. Välj den åtgärd du vill utföra och klicka Nästa för att fortsätta."
|
||||
StrCpy $PageReinstall_NEW_Field_2 "Avinstallera före installation"
|
||||
StrCpy $PageReinstall_NEW_Field_3 "Avinstallera inte"
|
||||
StrCpy $PageReinstall_NEW_MUI_HEADER_TEXT_TITLE "Redan installerad"
|
||||
StrCpy $PageReinstall_NEW_MUI_HEADER_TEXT_SUBTITLE "Välj hur du vill installera ${APPLICATION_NAME}."
|
||||
StrCpy $PageReinstall_OLD_Field_1 "En nyare version av ${APPLICATION_NAME} är redan installerad! Det rekommenderas inte att du installerar en äldre version. Om du verkligen vill installera denna äldre versionen, är det bättre att du avinstallerar den nuvarande versionen först. Välj den åtgärd du vill utföra och klicka Nästa för att fortsätta."
|
||||
StrCpy $PageReinstall_SAME_Field_1 "${APPLICATION_NAME} ${VERSION} är redan installerad.\nVälj den åtgärd du vill utföra och klicka Nästa för att fortsätta."
|
||||
StrCpy $PageReinstall_SAME_Field_2 "Lägg till/Ominstallera komponenter"
|
||||
StrCpy $PageReinstall_SAME_Field_3 "Avinstallera ${APPLICATION_NAME}"
|
||||
StrCpy $UNINSTALLER_APPDATA_TITLE "Avinstallera ${APPLICATION_NAME}"
|
||||
StrCpy $PageReinstall_SAME_MUI_HEADER_TEXT_SUBTITLE "Välj underhålls alternativ att utföra."
|
||||
StrCpy $SEC_APPLICATION_DETAILS "Installerar ${APPLICATION_NAME} väsentligheter."
|
||||
StrCpy $OPTION_SECTION_SC_START_MENU_SECTION "Start-meny program genväg"
|
||||
StrCpy $OPTION_SECTION_SC_START_MENU_DetailPrint "Lägger till genväg för ${APPLICATION_NAME} till Start-menyn."
|
||||
StrCpy $OPTION_SECTION_SC_DESKTOP_SECTION "Skrivbordsgenväg"
|
||||
StrCpy $OPTION_SECTION_SC_DESKTOP_DetailPrint "Skapar skrivbordsgenvägar"
|
||||
StrCpy $OPTION_SECTION_SC_QUICK_LAUNCH_SECTION "Snabbstartsgenväg"
|
||||
StrCpy $OPTION_SECTION_SC_QUICK_LAUNCH_DetailPrint "Skapar snabbstartsgenväg"
|
||||
StrCpy $OPTION_SECTION_SC_APPLICATION_Desc "${APPLICATION_NAME} väsentligheter."
|
||||
StrCpy $OPTION_SECTION_SC_START_MENU_Desc "${APPLICATION_NAME} genväg."
|
||||
StrCpy $OPTION_SECTION_SC_DESKTOP_Desc "Skrivbordsgenväg för ${APPLICATION_NAME}."
|
||||
StrCpy $OPTION_SECTION_SC_QUICK_LAUNCH_Desc "Snabbstartsgenväg för ${APPLICATION_NAME}."
|
||||
StrCpy $UNINSTALLER_APPDATA_SUBTITLE "Tag bort ${APPLICATION_NAME}s data mapp från din dator."
|
||||
StrCpy $UNINSTALLER_APPDATA_LABEL_1 "Vill du radera ${APPLICATION_NAME}s data mapp?"
|
||||
StrCpy $UNINSTALLER_APPDATA_LABEL_2 "Lämna omarkerad för att behålla data mappen för senare användning eller markera för att radera data mappen.."
|
||||
StrCpy $UNINSTALLER_APPDATA_CHECKBOX "Ja, radera denna data mappen."
|
||||
StrCpy $UNINSTALLER_FILE_Detail "Skriver avinstallationsprogram"
|
||||
StrCpy $UNINSTALLER_REGISTRY_Detail "Skriver installationsprogrammets registernycklar"
|
||||
StrCpy $UNINSTALLER_FINISHED_Detail "Klar"
|
||||
StrCpy $UNINSTALL_MESSAGEBOX "Det verkar inte som ${APPLICATION_NAME} är installerad i katalogen '$INSTDIR'.$\n$\nFortsätt ändå (rekommenderas ej)?"
|
||||
StrCpy $UNINSTALL_ABORT "Avinstallering avbröts av användare"
|
||||
StrCpy $INIT_NO_QUICK_LAUNCH "Snabbstartsgenväg (N/A)"
|
||||
StrCpy $INIT_NO_DESKTOP "Skrivbordsgenväg (skriver över nuvarande)"
|
||||
StrCpy $UAC_ERROR_ELEVATE "Kunde inte få förhöjda rättigheter, fel:"
|
||||
StrCpy $UAC_INSTALLER_REQUIRE_ADMIN "Detta installationsprogram kräver adminstratörs rättigheter, försök igen"
|
||||
StrCpy $INIT_INSTALLER_RUNNING "Installationsprogrammet körs redan."
|
||||
StrCpy $UAC_UNINSTALLER_REQUIRE_ADMIN "Detta avinstallationsprogram kräver administratörs rättigheter, försök igen"
|
||||
StrCpy $INIT_UNINSTALLER_RUNNING "Avinstallationsprogrammet körs redan."
|
||||
StrCpy $SectionGroup_Shortcuts "Genvägar"
|
||||
@@ -9,7 +9,7 @@ StrCpy $PageReinstall_NEW_Field_3 "Kald
|
||||
StrCpy $PageReinstall_NEW_MUI_HEADER_TEXT_TITLE "Zaten Yüklü"
|
||||
StrCpy $PageReinstall_NEW_MUI_HEADER_TEXT_SUBTITLE "${APPLICATION_NAME} uygulamasını nasıl yüklemek istediğinizi seçin."
|
||||
StrCpy $PageReinstall_OLD_Field_1 "${APPLICATION_NAME} uygulamasının daha yeni sürümü zaten yüklü! Daha eski bir sürümünü yüklemeniz önerilmez. Gerçekten bu eski sürümü yüklemek isterseniz, ilk olarak geçerli sürümü kaldırmanız tavsiye edilir. Yapmak istediğiniz işlemi seçin ve devam etmek üzere İleri tıklayın."
|
||||
StrCpy $PageReinstall_SAME_Field_1 "${APPLICATION_NAME} ${VERSION} zaten yüklü.\nYapmak istediğiniz işlemi seçin ve devam etmek için İleri tıklayın."
|
||||
StrCpy $PageReinstall_SAME_Field_1 "${APPLICATION_NAME} ${VERSION} zaten yüklü.\n\nYapmak istediğiniz işlemi seçin ve devam etmek için İleri tıklayın."
|
||||
StrCpy $PageReinstall_SAME_Field_2 "Bileşenleri ekle/yeniden yükle"
|
||||
StrCpy $PageReinstall_SAME_Field_3 "${APPLICATION_NAME} uygulamasını kaldır"
|
||||
StrCpy $UNINSTALLER_APPDATA_TITLE "${APPLICATION_NAME} uygulamasını kaldır"
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
; Auto-generated - do not modify
|
||||
!insertmacro MUI_LANGUAGE "Swedish"
|
||||
!insertmacro MUI_LANGUAGE "Estonian"
|
||||
!insertmacro MUI_LANGUAGE "Turkish"
|
||||
!insertmacro MUI_LANGUAGE "Slovenian"
|
||||
!insertmacro MUI_LANGUAGE "SpanishInternational"
|
||||
!insertmacro MUI_LANGUAGE "Dutch"
|
||||
!insertmacro MUI_LANGUAGE "Hungarian"
|
||||
!insertmacro MUI_LANGUAGE "French"
|
||||
@@ -10,6 +12,7 @@
|
||||
!insertmacro MUI_LANGUAGE "Finnish"
|
||||
!insertmacro MUI_LANGUAGE "Basque"
|
||||
!insertmacro MUI_LANGUAGE "Greek"
|
||||
!insertmacro MUI_LANGUAGE "SimpChinese"
|
||||
!insertmacro MUI_LANGUAGE "PortugueseBR"
|
||||
!insertmacro MUI_LANGUAGE "Italian"
|
||||
!insertmacro MUI_LANGUAGE "Portuguese"
|
||||
|
||||
@@ -66,7 +66,7 @@ macro (KDE4_ADD_APP_ICON appsources pattern)
|
||||
message(STATUS "Unable to find a related icon that matches pattern ${pattern} for variable ${appsources} - application will not have an application icon!")
|
||||
endif(_icons)
|
||||
else(PNG2ICO_EXECUTABLE AND WINDRES_EXECUTABLE)
|
||||
message(FATAL_ERROR "Unable to find the png2ico or windres utilities - application will not have an application icon!")
|
||||
message(WARNING "Unable to find the png2ico or windres utilities - application will not have an application icon!")
|
||||
endif(PNG2ICO_EXECUTABLE AND WINDRES_EXECUTABLE)
|
||||
endif(WIN32)
|
||||
if (APPLE)
|
||||
|
||||
13
cmake/modules/Copyright.txt
Normal file
13
cmake/modules/Copyright.txt
Normal file
@@ -0,0 +1,13 @@
|
||||
CMake - Cross Platform Makefile Generator
|
||||
Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
||||
|
||||
* Neither the names of Kitware, Inc., the Insight Software Consortium, nor the names of their contributors may be used to endorse or promote products derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
@@ -13,17 +13,17 @@ if (UNIX)
|
||||
CACHE PATH "Base directory for files which go to share/"
|
||||
)
|
||||
SET(DATA_INSTALL_PREFIX
|
||||
"${SHARE_INSTALL_PREFIX}/${APPLICATION_SHORT_NAME}"
|
||||
"${SHARE_INSTALL_PREFIX}"
|
||||
CACHE PATH "The parent directory where applications can install their data")
|
||||
|
||||
# The following are directories where stuff will be installed to
|
||||
SET(BIN_INSTALL_DIR
|
||||
"${CMAKE_INSTALL_BINDIR}"
|
||||
CACHE PATH "The ${APPLICATION_SHORT_NAME} binary install dir (default prefix/bin)"
|
||||
CACHE PATH "The ${APPLICATION_SHORTNAME} binary install dir (default prefix/bin)"
|
||||
)
|
||||
SET(SBIN_INSTALL_DIR
|
||||
"${EXEC_INSTALL_PREFIX}/sbin"
|
||||
CACHE PATH "The ${APPLICATION_SHORT_NAME} sbin install dir (default prefix/sbin)"
|
||||
CACHE PATH "The ${APPLICATION_SHORTNAME} sbin install dir (default prefix/sbin)"
|
||||
)
|
||||
SET(LIB_INSTALL_DIR
|
||||
"${CMAKE_INSTALL_LIBDIR}"
|
||||
@@ -33,9 +33,13 @@ if (UNIX)
|
||||
"${EXEC_INSTALL_PREFIX}/libexec"
|
||||
CACHE PATH "The subdirectory relative to the install prefix where libraries will be installed (default is prefix/libexec)"
|
||||
)
|
||||
SET(LIB_PRIVATE_INSTALL_DIR
|
||||
"${LIB_INSTALL_DIR}"
|
||||
CACHE PATH "The subdirectory relative to the install prefix where private libs are installed"
|
||||
)
|
||||
SET(PLUGIN_INSTALL_DIR
|
||||
"${LIB_INSTALL_DIR}/${APPLICATION_SHORT_NAME}"
|
||||
CACHE PATH "The subdirectory relative to the install prefix where plugins will be installed (default is prefix/lib/${APPLICATION_SHORT_NAME})"
|
||||
"${LIB_INSTALL_DIR}"
|
||||
CACHE PATH "The subdirectory relative to the install prefix where plugins will be installed (default is prefix/lib/${APPLICATION_SHORTNAME})"
|
||||
)
|
||||
SET(INCLUDE_INSTALL_DIR
|
||||
"${CMAKE_INSTALL_PREFIX}/include"
|
||||
@@ -44,7 +48,7 @@ if (UNIX)
|
||||
|
||||
SET(DATA_INSTALL_DIR
|
||||
"${DATA_INSTALL_PREFIX}"
|
||||
CACHE PATH "The parent directory where applications can install their data (default prefix/share/${APPLICATION_SHORT_NAME})"
|
||||
CACHE PATH "The parent directory where applications can install their data (default prefix/share/${APPLICATION_SHORTNAME})"
|
||||
)
|
||||
SET(HTML_INSTALL_DIR
|
||||
"${DATA_INSTALL_PREFIX}/doc/HTML"
|
||||
@@ -79,15 +83,15 @@ if (UNIX)
|
||||
|
||||
SET(SYSCONF_INSTALL_DIR
|
||||
"${SYSCONFDIR_INSTALL_PREFIX}/etc"
|
||||
CACHE PATH "The ${APPLICATION_SHORT_NAME} sysconfig install dir (default prefix/etc)"
|
||||
CACHE PATH "The ${APPLICATION_SHORTNAME} sysconfig install dir (default prefix/etc)"
|
||||
)
|
||||
SET(MAN_INSTALL_DIR
|
||||
"${SHARE_INSTALL_PREFIX}/man"
|
||||
CACHE PATH "The ${APPLICATION_SHORT_NAME} man install dir (default prefix/man)"
|
||||
CACHE PATH "The ${APPLICATION_SHORTNAME} man install dir (default prefix/man)"
|
||||
)
|
||||
SET(INFO_INSTALL_DIR
|
||||
"${SHARE_INSTALL_PREFIX}/info"
|
||||
CACHE PATH "The ${APPLICATION_SHORT_NAME} info install dir (default prefix/info)"
|
||||
CACHE PATH "The ${APPLICATION_SHORTNAME} info install dir (default prefix/info)"
|
||||
)
|
||||
endif (UNIX)
|
||||
|
||||
|
||||
381
cmake/modules/DeployQt5.cmake
Normal file
381
cmake/modules/DeployQt5.cmake
Normal file
@@ -0,0 +1,381 @@
|
||||
# - Functions to help assemble a standalone Qt5 executable.
|
||||
# A collection of CMake utility functions useful for deploying
|
||||
# Qt5 executables.
|
||||
#
|
||||
# The following functions are provided by this module:
|
||||
# write_qt5_conf
|
||||
# resolve_qt5_paths
|
||||
# fixup_qt5_executable
|
||||
# install_qt5_plugin_path
|
||||
# install_qt5_plugin
|
||||
# install_qt5_executable
|
||||
# Requires CMake 2.6 or greater because it uses function and
|
||||
# PARENT_SCOPE. Also depends on BundleUtilities.cmake.
|
||||
#
|
||||
# WRITE_QT5_CONF(<qt_conf_dir> <qt_conf_contents>)
|
||||
# Writes a qt.conf file with the <qt_conf_contents> into <qt_conf_dir>.
|
||||
#
|
||||
# RESOLVE_QT5_PATHS(<paths_var> [<executable_path>])
|
||||
# Loop through <paths_var> list and if any don't exist resolve them
|
||||
# relative to the <executable_path> (if supplied) or the CMAKE_INSTALL_PREFIX.
|
||||
#
|
||||
# FIXUP_QT5_EXECUTABLE(<executable> [<qtplugins> <libs> <dirs> <plugins_dir> <request_qt_conf>])
|
||||
# Copies Qt plugins, writes a Qt configuration file (if needed) and fixes up a
|
||||
# Qt5 executable using BundleUtilities so it is standalone and can be
|
||||
# drag-and-drop copied to another machine as long as all of the system
|
||||
# libraries are compatible.
|
||||
#
|
||||
# <executable> should point to the executable to be fixed-up.
|
||||
#
|
||||
# <qtplugins> should contain a list of the names or paths of any Qt plugins
|
||||
# to be installed.
|
||||
#
|
||||
# <libs> will be passed to BundleUtilities and should be a list of any already
|
||||
# installed plugins, libraries or executables to also be fixed-up.
|
||||
#
|
||||
# <dirs> will be passed to BundleUtilities and should contain and directories
|
||||
# to be searched to find library dependencies.
|
||||
#
|
||||
# <plugins_dir> allows an custom plugins directory to be used.
|
||||
#
|
||||
# <request_qt_conf> will force a qt.conf file to be written even if not needed.
|
||||
#
|
||||
# INSTALL_QT5_PLUGIN_PATH(plugin executable copy installed_plugin_path_var <plugins_dir> <component> <configurations>)
|
||||
# Install (or copy) a resolved <plugin> to the default plugins directory
|
||||
# (or <plugins_dir>) relative to <executable> and store the result in
|
||||
# <installed_plugin_path_var>.
|
||||
#
|
||||
# If <copy> is set to TRUE then the plugins will be copied rather than
|
||||
# installed. This is to allow this module to be used at CMake time rather than
|
||||
# install time.
|
||||
#
|
||||
# If <component> is set then anything installed will use this COMPONENT.
|
||||
#
|
||||
# INSTALL_QT5_PLUGIN(plugin executable copy installed_plugin_path_var <plugins_dir> <component>)
|
||||
# Install (or copy) an unresolved <plugin> to the default plugins directory
|
||||
# (or <plugins_dir>) relative to <executable> and store the result in
|
||||
# <installed_plugin_path_var>. See documentation of INSTALL_QT5_PLUGIN_PATH.
|
||||
#
|
||||
# INSTALL_QT5_EXECUTABLE(<executable> [<qtplugins> <libs> <dirs> <plugins_dir> <request_qt_conf> <component>])
|
||||
# Installs Qt plugins, writes a Qt configuration file (if needed) and fixes up
|
||||
# a Qt5 executable using BundleUtilities so it is standalone and can be
|
||||
# drag-and-drop copied to another machine as long as all of the system
|
||||
# libraries are compatible. The executable will be fixed-up at install time.
|
||||
# <component> is the COMPONENT used for bundle fixup and plugin installation.
|
||||
# See documentation of FIXUP_QT5_BUNDLE.
|
||||
|
||||
#=============================================================================
|
||||
# Copyright 2011 Mike McQuaid <m...@mikemcquaid.com>
|
||||
# Copyright 2013 Mihai Moldovan <io...@ionic.de>
|
||||
# CMake - Cross Platform Makefile Generator
|
||||
# Copyright 2000-2011 Kitware, Inc., Insight Software Consortium
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
#
|
||||
# * Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution.
|
||||
#
|
||||
# * Neither the names of Kitware, Inc., the Insight Software Consortium,
|
||||
# nor the names of their contributors may be used to endorse or promote
|
||||
# products derived from this software without specific prior written
|
||||
# permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
# The functions defined in this file depend on the fixup_bundle function
|
||||
# (and others) found in BundleUtilities.cmake
|
||||
|
||||
include(BundleUtilities)
|
||||
set(DeployQt5_cmake_dir "${CMAKE_CURRENT_LIST_DIR}")
|
||||
set(DeployQt5_apple_plugins_dir "PlugIns")
|
||||
|
||||
function(write_qt5_conf qt_conf_dir qt_conf_contents)
|
||||
set(qt_conf_path "${qt_conf_dir}/qt.conf")
|
||||
message(STATUS "Writing ${qt_conf_path}")
|
||||
file(WRITE "${qt_conf_path}" "${qt_conf_contents}")
|
||||
endfunction()
|
||||
|
||||
function(resolve_qt5_paths paths_var)
|
||||
set(executable_path ${ARGV1})
|
||||
|
||||
set(paths_resolved)
|
||||
foreach(path ${${paths_var}})
|
||||
if(EXISTS "${path}")
|
||||
list(APPEND paths_resolved "${path}")
|
||||
else()
|
||||
if(${executable_path})
|
||||
list(APPEND paths_resolved
|
||||
"${executable_path}/${path}")
|
||||
else()
|
||||
list(APPEND paths_resolved
|
||||
"\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${path}")
|
||||
endif()
|
||||
endif()
|
||||
endforeach()
|
||||
set(${paths_var} ${paths_resolved} PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
function(fixup_qt5_executable executable)
|
||||
set(qtplugins ${ARGV1})
|
||||
set(libs ${ARGV2})
|
||||
set(dirs ${ARGV3})
|
||||
set(plugins_dir ${ARGV4})
|
||||
set(request_qt_conf ${ARGV5})
|
||||
|
||||
message(STATUS "fixup_qt5_executable")
|
||||
message(STATUS " executable='${executable}'")
|
||||
message(STATUS " qtplugins='${qtplugins}'")
|
||||
message(STATUS " libs='${libs}'")
|
||||
message(STATUS " dirs='${dirs}'")
|
||||
message(STATUS " plugins_dir='${plugins_dir}'")
|
||||
message(STATUS " request_qt_conf='${request_qt_conf}'")
|
||||
|
||||
if(QT_LIBRARY_DIR)
|
||||
list(APPEND dirs "${QT_LIBRARY_DIR}")
|
||||
endif()
|
||||
if(QT_BINARY_DIR)
|
||||
list(APPEND dirs "${QT_BINARY_DIR}")
|
||||
endif()
|
||||
|
||||
if(APPLE)
|
||||
set(qt_conf_dir "${executable}/Contents/Resources")
|
||||
set(executable_path "${executable}")
|
||||
set(write_qt_conf TRUE)
|
||||
if(NOT plugins_dir)
|
||||
set(plugins_dir "${DeployQt5_apple_plugins_dir}")
|
||||
endif()
|
||||
else()
|
||||
get_filename_component(executable_path "${executable}" PATH)
|
||||
if(NOT executable_path)
|
||||
set(executable_path ".")
|
||||
endif()
|
||||
set(qt_conf_dir "${executable_path}")
|
||||
set(write_qt_conf ${request_qt_conf})
|
||||
endif()
|
||||
|
||||
foreach(plugin ${qtplugins})
|
||||
set(installed_plugin_path "")
|
||||
install_qt5_plugin("${plugin}" "${executable}" 1
|
||||
installed_plugin_path)
|
||||
list(APPEND libs ${installed_plugin_path})
|
||||
endforeach()
|
||||
|
||||
foreach(lib ${libs})
|
||||
if(NOT EXISTS "${lib}")
|
||||
message(FATAL_ERROR "Library does not exist: ${lib}")
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
resolve_qt5_paths(libs "${executable_path}")
|
||||
|
||||
if(write_qt_conf)
|
||||
set(qt_conf_contents "[Paths]\nPlugins = ${plugins_dir}")
|
||||
write_qt5_conf("${qt_conf_dir}" "${qt_conf_contents}")
|
||||
endif()
|
||||
|
||||
fixup_bundle("${executable}" "${libs}" "${dirs}")
|
||||
endfunction()
|
||||
|
||||
function(install_qt5_plugin_path plugin executable copy
|
||||
installed_plugin_path_var)
|
||||
set(plugins_dir ${ARGV4})
|
||||
set(component ${ARGV5})
|
||||
set(configurations ${ARGV6})
|
||||
if(EXISTS "${plugin}")
|
||||
if(APPLE)
|
||||
if(NOT plugins_dir)
|
||||
set(plugins_dir
|
||||
"${DeployQt5_apple_plugins_dir}")
|
||||
endif()
|
||||
set(plugins_path
|
||||
"${executable}/Contents/${plugins_dir}")
|
||||
else()
|
||||
get_filename_component(plugins_path "${executable}"
|
||||
PATH)
|
||||
if(NOT plugins_path)
|
||||
set(plugins_path ".")
|
||||
endif()
|
||||
if(plugins_dir)
|
||||
set(plugins_path
|
||||
"${plugins_path}/${plugins_dir}")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
set(plugin_group "")
|
||||
|
||||
get_filename_component(plugin_path "${plugin}" PATH)
|
||||
get_filename_component(plugin_parent_path "${plugin_path}" PATH)
|
||||
get_filename_component(plugin_parent_dir_name
|
||||
"${plugin_parent_path}" NAME)
|
||||
get_filename_component(plugin_name "${plugin}" NAME)
|
||||
string(TOLOWER "${plugin_parent_dir_name}"
|
||||
plugin_parent_dir_name)
|
||||
|
||||
if("${plugin_parent_dir_name}" STREQUAL "plugins")
|
||||
get_filename_component(plugin_group "${plugin_path}"
|
||||
NAME)
|
||||
set(${plugin_group_var} "${plugin_group}")
|
||||
endif()
|
||||
set(plugins_path "${plugins_path}/${plugin_group}")
|
||||
|
||||
if(${copy})
|
||||
file(MAKE_DIRECTORY "${plugins_path}")
|
||||
file(COPY "${plugin}" DESTINATION "${plugins_path}")
|
||||
else()
|
||||
if(configurations AND (CMAKE_CONFIGURATION_TYPES OR
|
||||
CMAKE_BUILD_TYPE))
|
||||
set(configurations CONFIGURATIONS
|
||||
${configurations})
|
||||
else()
|
||||
unset(configurations)
|
||||
endif()
|
||||
install(FILES "${plugin}" DESTINATION "${plugins_path}"
|
||||
${configurations} ${component})
|
||||
endif()
|
||||
set(${installed_plugin_path_var}
|
||||
"${plugins_path}/${plugin_name}" PARENT_SCOPE)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
function(install_qt5_plugin plugin executable copy installed_plugin_path_var)
|
||||
set(plugins_dir ${ARGV4})
|
||||
set(component ${ARGV5})
|
||||
if(EXISTS "${plugin}")
|
||||
install_qt5_plugin_path("${plugin}" "${executable}" "${copy}"
|
||||
"${installed_plugin_path_var}" "${plugins_dir}" "${component}")
|
||||
else()
|
||||
#string(TOUPPER "QT_${plugin}_PLUGIN" plugin_var)
|
||||
set(plugin_release)
|
||||
set(plugin_debug)
|
||||
set(plugin_tmp_path)
|
||||
set(plugin_find_path "${Qt5Core_DIR}/../../../plugins/")
|
||||
get_filename_component(plugin_find_path "${plugin_find_path}"
|
||||
REALPATH)
|
||||
set(plugin_find_release_filename "lib${plugin}.dylib")
|
||||
set(plugin_find_debug_filename "lib${plugin}_debug.dylib")
|
||||
file(GLOB_RECURSE pluginlist "${plugin_find_path}"
|
||||
"${plugin_find_path}/*/lib*.dylib")
|
||||
foreach(found_plugin ${pluginlist})
|
||||
get_filename_component(curname "${found_plugin}" NAME)
|
||||
if("${curname}" STREQUAL "${plugin_find_release_filename}")
|
||||
set(plugin_tmp_release_path "${found_plugin}")
|
||||
endif()
|
||||
if("${curname}" STREQUAL "${plugin_find_debug_filename}")
|
||||
set(plugin_tmp_debug_path "${found_plugin}")
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
if((NOT DEFINED plugin_tmp_release_path OR NOT EXISTS
|
||||
"${plugin_tmp_release_path}") AND (NOT DEFINED plugin_tmp_debug_PATH OR NOT
|
||||
EXISTS "${plugin_tmp_debug_path}"))
|
||||
message(WARNING "Qt plugin \"${plugin}\" not recognized
|
||||
or found.")
|
||||
endif()
|
||||
|
||||
if(EXISTS "${plugin_tmp_release_path}")
|
||||
set(plugin_release "${plugin_tmp_release_path}")
|
||||
elseif(EXISTS "${plugin_tmp_debug_path}")
|
||||
set(plugin_release "${plugin_tmp_debug_path}")
|
||||
endif()
|
||||
|
||||
if(EXISTS "${plugin_tmp_debug_path}")
|
||||
set(plugin_debug "${plugin_tmp_debug_path}")
|
||||
elseif(EXISTS "${plugin_tmp_release_path}")
|
||||
set(plugin_debug "${plugin_tmp_release_path}")
|
||||
endif()
|
||||
|
||||
if(CMAKE_CONFIGURATION_TYPES OR CMAKE_BUILD_TYPE)
|
||||
install_qt5_plugin_path("${plugin_release}"
|
||||
"${executable}" "${copy}" "${installed_plugin_path_var}_release"
|
||||
"${plugins_dir}" "${component}" "Release|RelWithDebInfo|MinSizeRel")
|
||||
install_qt5_plugin_path("${plugin_debug}"
|
||||
"${executable}" "${copy}" "${installed_plugin_path_var}_debug" "${plugins_dir}"
|
||||
"${component}" "Debug")
|
||||
|
||||
if(CMAKE_BUILD_TYPE MATCHES "^Debug$")
|
||||
set(${installed_plugin_path_var}
|
||||
${${installed_plugin_path_var}_debug})
|
||||
else()
|
||||
set(${installed_plugin_path_var}
|
||||
${${installed_plugin_path_var}_release})
|
||||
endif()
|
||||
else()
|
||||
install_qt5_plugin_path("${plugin_release}"
|
||||
"${executable}" "${copy}" "${installed_plugin_path_var}" "${plugins_dir}"
|
||||
"${component}")
|
||||
endif()
|
||||
endif()
|
||||
set(${installed_plugin_path_var} ${${installed_plugin_path_var}}
|
||||
PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
function(install_qt5_executable executable)
|
||||
set(qtplugins ${ARGV1})
|
||||
set(libs ${ARGV2})
|
||||
set(dirs ${ARGV3})
|
||||
set(plugins_dir ${ARGV4})
|
||||
set(request_qt_conf ${ARGV5})
|
||||
set(component ${ARGV6})
|
||||
if(QT_LIBRARY_DIR)
|
||||
list(APPEND dirs "${QT_LIBRARY_DIR}")
|
||||
endif()
|
||||
if(QT_BINARY_DIR)
|
||||
list(APPEND dirs "${QT_BINARY_DIR}")
|
||||
endif()
|
||||
if(component)
|
||||
set(component COMPONENT ${component})
|
||||
else()
|
||||
unset(component)
|
||||
endif()
|
||||
|
||||
get_filename_component(executable_absolute "${executable}" ABSOLUTE)
|
||||
if(EXISTS "${QT_QTCORE_LIBRARY_RELEASE}")
|
||||
gp_file_type("${executable_absolute}"
|
||||
"${QT_QTCORE_LIBRARY_RELEASE}" qtcore_type)
|
||||
elseif(EXISTS "${QT_QTCORE_LIBRARY_DEBUG}")
|
||||
gp_file_type("${executable_absolute}" "${QT_QTCORE_LIBRARY_DEBUG}"
|
||||
qtcore_type)
|
||||
endif()
|
||||
if(qtcore_type STREQUAL "system")
|
||||
set(qt_plugins_dir "")
|
||||
endif()
|
||||
|
||||
if(QT_IS_STATIC)
|
||||
message(WARNING "Qt built statically: not installing plugins.")
|
||||
else()
|
||||
foreach(plugin ${qtplugins})
|
||||
message(STATUS "trying to install plugin ${plugin}")
|
||||
set(installed_plugin_paths "")
|
||||
install_qt5_plugin("${plugin}" "${executable}" 0
|
||||
installed_plugin_paths "${plugins_dir}" "${component}")
|
||||
list(APPEND libs ${installed_plugin_paths})
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
resolve_qt5_paths(libs "")
|
||||
|
||||
install(CODE
|
||||
"include(\"${DeployQt5_cmake_dir}/DeployQt5.cmake\")
|
||||
set(BU_CHMOD_BUNDLE_ITEMS TRUE)
|
||||
FIXUP_QT5_EXECUTABLE(\"\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${executable}\"
|
||||
\"\" \"${libs}\" \"${dirs}\" \"${plugins_dir}\" \"${request_qt_conf}\")"
|
||||
${component}
|
||||
)
|
||||
endfunction()
|
||||
@@ -31,7 +31,7 @@ HINTS
|
||||
|
||||
find_library(NEON_LIBRARIES
|
||||
NAMES
|
||||
neon
|
||||
neon neon-27
|
||||
HINTS
|
||||
${_NEON_LIBDIR}
|
||||
${CMAKE_INSTALL_LIBDIR}
|
||||
|
||||
29
cmake/modules/FindQt5Keychain.cmake
Normal file
29
cmake/modules/FindQt5Keychain.cmake
Normal file
@@ -0,0 +1,29 @@
|
||||
# - Try to find QtKeychain
|
||||
# Once done this will define
|
||||
# QTKEYCHAIN_FOUND - System has QtKeychain
|
||||
# QTKEYCHAIN_INCLUDE_DIRS - The QtKeychain include directories
|
||||
# QTKEYCHAIN_LIBRARIES - The libraries needed to use QtKeychain
|
||||
# QTKEYCHAIN_DEFINITIONS - Compiler switches required for using LibXml2
|
||||
|
||||
find_path(QTKEYCHAIN_INCLUDE_DIR qt5keychain/keychain.h)
|
||||
|
||||
find_library(QTKEYCHAIN_LIBRARY
|
||||
NAMES
|
||||
qt5keychain
|
||||
lib5qtkeychain
|
||||
PATHS
|
||||
/usr/lib
|
||||
/usr/lib/${CMAKE_ARCH_TRIPLET}
|
||||
/usr/local/lib
|
||||
/opt/local/lib
|
||||
${CMAKE_LIBRARY_PATH}
|
||||
${CMAKE_INSTALL_PREFIX}/lib
|
||||
)
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
# handle the QUIETLY and REQUIRED arguments and set QTKEYCHAIN_FOUND to TRUE
|
||||
# if all listed variables are TRUE
|
||||
find_package_handle_standard_args(Qt5Keychain DEFAULT_MSG
|
||||
QTKEYCHAIN_LIBRARY QTKEYCHAIN_INCLUDE_DIR)
|
||||
|
||||
mark_as_advanced(QTKEYCHAIN_INCLUDE_DIR QTKEYCHAIN_LIBRARY)
|
||||
@@ -1,18 +1,29 @@
|
||||
# - Try to find QtKeyChain
|
||||
# - Try to find QtKeychain
|
||||
# Once done this will define
|
||||
# QTKEYCHAIN_FOUND - System has QtKeyChain
|
||||
# QTKEYCHAIN_INCLUDE_DIRS - The QtKeyChain include directories
|
||||
# QTKEYCHAIN_LIBRARIES - The libraries needed to use QtKeyChain
|
||||
# QTKEYCHAIN_FOUND - System has QtKeychain
|
||||
# QTKEYCHAIN_INCLUDE_DIRS - The QtKeychain include directories
|
||||
# QTKEYCHAIN_LIBRARIES - The libraries needed to use QtKeychain
|
||||
# QTKEYCHAIN_DEFINITIONS - Compiler switches required for using LibXml2
|
||||
|
||||
find_path(QTKEYCHAIN_INCLUDE_DIR qtkeychain/keychain.h)
|
||||
|
||||
find_library(QTKEYCHAIN_LIBRARY NAMES libqtkeychain qtkeychain)
|
||||
find_library(QTKEYCHAIN_LIBRARY
|
||||
NAMES
|
||||
qtkeychain
|
||||
libqtkeychain
|
||||
PATHS
|
||||
/usr/lib
|
||||
/usr/lib/${CMAKE_ARCH_TRIPLET}
|
||||
/usr/local/lib
|
||||
/opt/local/lib
|
||||
${CMAKE_LIBRARY_PATH}
|
||||
${CMAKE_INSTALL_PREFIX}/lib
|
||||
)
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
# handle the QUIETLY and REQUIRED arguments and set QTKEYCHAIN_FOUND to TRUE
|
||||
# if all listed variables are TRUE
|
||||
find_package_handle_standard_args(QtKeyChain DEFAULT_MSG
|
||||
find_package_handle_standard_args(QtKeychain DEFAULT_MSG
|
||||
QTKEYCHAIN_LIBRARY QTKEYCHAIN_INCLUDE_DIR)
|
||||
|
||||
mark_as_advanced(QTKEYCHAIN_INCLUDE_DIR QTKEYCHAIN_LIBRARY )
|
||||
mark_as_advanced(QTKEYCHAIN_INCLUDE_DIR QTKEYCHAIN_LIBRARY)
|
||||
|
||||
@@ -30,7 +30,7 @@ find_path(SQLITE3_INCLUDE_DIR
|
||||
|
||||
find_library(SQLITE3_LIBRARY
|
||||
NAMES
|
||||
sqlite3
|
||||
sqlite3 sqlite3-0
|
||||
PATHS
|
||||
${_SQLITE3_LIBDIR}
|
||||
)
|
||||
|
||||
@@ -1,32 +1,49 @@
|
||||
# - Define GNU standard installation directories
|
||||
#.rst:
|
||||
# GNUInstallDirs
|
||||
# --------------
|
||||
#
|
||||
# Define GNU standard installation directories
|
||||
#
|
||||
# Provides install directory variables as defined for GNU software:
|
||||
# http://www.gnu.org/prep/standards/html_node/Directory-Variables.html
|
||||
#
|
||||
# ::
|
||||
#
|
||||
# http://www.gnu.org/prep/standards/html_node/Directory-Variables.html
|
||||
#
|
||||
# Inclusion of this module defines the following variables:
|
||||
# CMAKE_INSTALL_<dir> - destination for files of a given type
|
||||
# CMAKE_INSTALL_FULL_<dir> - corresponding absolute path
|
||||
#
|
||||
# ::
|
||||
#
|
||||
# CMAKE_INSTALL_<dir> - destination for files of a given type
|
||||
# CMAKE_INSTALL_FULL_<dir> - corresponding absolute path
|
||||
#
|
||||
# where <dir> is one of:
|
||||
# BINDIR - user executables (bin)
|
||||
# SBINDIR - system admin executables (sbin)
|
||||
# LIBEXECDIR - program executables (libexec)
|
||||
# SYSCONFDIR - read-only single-machine data (etc)
|
||||
# SHAREDSTATEDIR - modifiable architecture-independent data (com)
|
||||
# LOCALSTATEDIR - modifiable single-machine data (var)
|
||||
# LIBDIR - object code libraries (lib or lib64)
|
||||
# INCLUDEDIR - C header files (include)
|
||||
# OLDINCLUDEDIR - C header files for non-gcc (/usr/include)
|
||||
# DATAROOTDIR - read-only architecture-independent data root (share)
|
||||
# DATADIR - read-only architecture-independent data (DATAROOTDIR)
|
||||
# INFODIR - info documentation (DATAROOTDIR/info)
|
||||
# LOCALEDIR - locale-dependent data (DATAROOTDIR/locale)
|
||||
# MANDIR - man documentation (DATAROOTDIR/man)
|
||||
# DOCDIR - documentation root (DATAROOTDIR/doc/PROJECT_NAME)
|
||||
# Each CMAKE_INSTALL_<dir> value may be passed to the DESTINATION options of
|
||||
# install() commands for the corresponding file type. If the includer does
|
||||
# not define a value the above-shown default will be used and the value will
|
||||
# appear in the cache for editing by the user.
|
||||
# Each CMAKE_INSTALL_FULL_<dir> value contains an absolute path constructed
|
||||
# from the corresponding destination by prepending (if necessary) the value
|
||||
# of CMAKE_INSTALL_PREFIX.
|
||||
#
|
||||
# ::
|
||||
#
|
||||
# BINDIR - user executables (bin)
|
||||
# SBINDIR - system admin executables (sbin)
|
||||
# LIBEXECDIR - program executables (libexec)
|
||||
# SYSCONFDIR - read-only single-machine data (etc)
|
||||
# SHAREDSTATEDIR - modifiable architecture-independent data (com)
|
||||
# LOCALSTATEDIR - modifiable single-machine data (var)
|
||||
# LIBDIR - object code libraries (lib or lib64 or lib/<multiarch-tuple> on Debian)
|
||||
# INCLUDEDIR - C header files (include)
|
||||
# OLDINCLUDEDIR - C header files for non-gcc (/usr/include)
|
||||
# DATAROOTDIR - read-only architecture-independent data root (share)
|
||||
# DATADIR - read-only architecture-independent data (DATAROOTDIR)
|
||||
# INFODIR - info documentation (DATAROOTDIR/info)
|
||||
# LOCALEDIR - locale-dependent data (DATAROOTDIR/locale)
|
||||
# MANDIR - man documentation (DATAROOTDIR/man)
|
||||
# DOCDIR - documentation root (DATAROOTDIR/doc/PROJECT_NAME)
|
||||
#
|
||||
# Each CMAKE_INSTALL_<dir> value may be passed to the DESTINATION
|
||||
# options of install() commands for the corresponding file type. If the
|
||||
# includer does not define a value the above-shown default will be used
|
||||
# and the value will appear in the cache for editing by the user. Each
|
||||
# CMAKE_INSTALL_FULL_<dir> value contains an absolute path constructed
|
||||
# from the corresponding destination by prepending (if necessary) the
|
||||
# value of CMAKE_INSTALL_PREFIX.
|
||||
|
||||
#=============================================================================
|
||||
# Copyright 2011 Nikita Krupen'ko <krnekit@gmail.com>
|
||||
@@ -68,30 +85,90 @@ if(NOT DEFINED CMAKE_INSTALL_LOCALSTATEDIR)
|
||||
set(CMAKE_INSTALL_LOCALSTATEDIR "var" CACHE PATH "modifiable single-machine data (var)")
|
||||
endif()
|
||||
|
||||
if(NOT DEFINED CMAKE_INSTALL_LIBDIR)
|
||||
# We check if the variable was manually set and not cached, in order to
|
||||
# allow projects to set the values as normal variables before including
|
||||
# GNUInstallDirs to avoid having the entries cached or user-editable. It
|
||||
# replaces the "if(NOT DEFINED CMAKE_INSTALL_XXX)" checks in all the
|
||||
# other cases.
|
||||
# If CMAKE_INSTALL_LIBDIR is defined, if _libdir_set is false, then the
|
||||
# variable is a normal one, otherwise it is a cache one.
|
||||
get_property(_libdir_set CACHE CMAKE_INSTALL_LIBDIR PROPERTY TYPE SET)
|
||||
if(NOT DEFINED CMAKE_INSTALL_LIBDIR OR (_libdir_set
|
||||
AND DEFINED _GNUInstallDirs_LAST_CMAKE_INSTALL_PREFIX
|
||||
AND NOT "${_GNUInstallDirs_LAST_CMAKE_INSTALL_PREFIX}" STREQUAL "${CMAKE_INSTALL_PREFIX}"))
|
||||
# If CMAKE_INSTALL_LIBDIR is not defined, it is always executed.
|
||||
# Otherwise:
|
||||
# * if _libdir_set is false it is not executed (meaning that it is
|
||||
# not a cache variable)
|
||||
# * if _GNUInstallDirs_LAST_CMAKE_INSTALL_PREFIX is not defined it is
|
||||
# not executed
|
||||
# * if _GNUInstallDirs_LAST_CMAKE_INSTALL_PREFIX and
|
||||
# CMAKE_INSTALL_PREFIX are the same string it is not executed.
|
||||
# _GNUInstallDirs_LAST_CMAKE_INSTALL_PREFIX is updated after the
|
||||
# execution, of this part of code, therefore at the next inclusion
|
||||
# of the file, CMAKE_INSTALL_LIBDIR is defined, and the 2 strings
|
||||
# are equal, meaning that the if is not executed the code the
|
||||
# second time.
|
||||
|
||||
set(_LIBDIR_DEFAULT "lib")
|
||||
# Override this default 'lib' with 'lib64' iff:
|
||||
# - we are on Linux system but NOT cross-compiling
|
||||
# - we are NOT on debian
|
||||
# - we are on a 64 bits system
|
||||
# reason is: amd64 ABI: http://www.x86-64.org/documentation/abi.pdf
|
||||
# Note that the future of multi-arch handling may be even
|
||||
# more complicated than that: http://wiki.debian.org/Multiarch
|
||||
if(CMAKE_SYSTEM_NAME MATCHES "Linux"
|
||||
AND NOT CMAKE_CROSSCOMPILING
|
||||
AND NOT EXISTS "/etc/debian_version")
|
||||
if(NOT DEFINED CMAKE_SIZEOF_VOID_P)
|
||||
message(AUTHOR_WARNING
|
||||
"Unable to determine default CMAKE_INSTALL_LIBDIR directory because no target architecture is known. "
|
||||
"Please enable at least one language before including GNUInstallDirs.")
|
||||
else()
|
||||
if("${CMAKE_SIZEOF_VOID_P}" EQUAL "8")
|
||||
set(_LIBDIR_DEFAULT "lib64")
|
||||
# For Debian with multiarch, use 'lib/${CMAKE_LIBRARY_ARCHITECTURE}' if
|
||||
# CMAKE_LIBRARY_ARCHITECTURE is set (which contains e.g. "i386-linux-gnu"
|
||||
# and CMAKE_INSTALL_PREFIX is "/usr"
|
||||
# See http://wiki.debian.org/Multiarch
|
||||
if(DEFINED _GNUInstallDirs_LAST_CMAKE_INSTALL_PREFIX)
|
||||
set(__LAST_LIBDIR_DEFAULT "lib")
|
||||
# __LAST_LIBDIR_DEFAULT is the default value that we compute from
|
||||
# _GNUInstallDirs_LAST_CMAKE_INSTALL_PREFIX, not a cache entry for
|
||||
# the value that was last used as the default.
|
||||
# This value is used to figure out whether the user changed the
|
||||
# CMAKE_INSTALL_LIBDIR value manually, or if the value was the
|
||||
# default one. When CMAKE_INSTALL_PREFIX changes, the value is
|
||||
# updated to the new default, unless the user explicitly changed it.
|
||||
endif()
|
||||
if(CMAKE_SYSTEM_NAME MATCHES "^(Linux|kFreeBSD|GNU)$"
|
||||
AND NOT CMAKE_CROSSCOMPILING)
|
||||
if (EXISTS "/etc/debian_version") # is this a debian system ?
|
||||
if(CMAKE_LIBRARY_ARCHITECTURE)
|
||||
if("${CMAKE_INSTALL_PREFIX}" MATCHES "^/usr/?$")
|
||||
set(_LIBDIR_DEFAULT "lib/${CMAKE_LIBRARY_ARCHITECTURE}")
|
||||
endif()
|
||||
if(DEFINED _GNUInstallDirs_LAST_CMAKE_INSTALL_PREFIX
|
||||
AND "${_GNUInstallDirs_LAST_CMAKE_INSTALL_PREFIX}" MATCHES "^/usr/?$")
|
||||
set(__LAST_LIBDIR_DEFAULT "lib/${CMAKE_LIBRARY_ARCHITECTURE}")
|
||||
endif()
|
||||
endif()
|
||||
else() # not debian, rely on CMAKE_SIZEOF_VOID_P:
|
||||
if(NOT DEFINED CMAKE_SIZEOF_VOID_P)
|
||||
message(AUTHOR_WARNING
|
||||
"Unable to determine default CMAKE_INSTALL_LIBDIR directory because no target architecture is known. "
|
||||
"Please enable at least one language before including GNUInstallDirs.")
|
||||
else()
|
||||
if("${CMAKE_SIZEOF_VOID_P}" EQUAL "8")
|
||||
set(_LIBDIR_DEFAULT "lib64")
|
||||
if(DEFINED _GNUInstallDirs_LAST_CMAKE_INSTALL_PREFIX)
|
||||
set(__LAST_LIBDIR_DEFAULT "lib64")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
set(CMAKE_INSTALL_LIBDIR "${_LIBDIR_DEFAULT}" CACHE PATH "object code libraries (${_LIBDIR_DEFAULT})")
|
||||
if(NOT DEFINED CMAKE_INSTALL_LIBDIR)
|
||||
set(CMAKE_INSTALL_LIBDIR "${_LIBDIR_DEFAULT}" CACHE PATH "object code libraries (${_LIBDIR_DEFAULT})")
|
||||
elseif(DEFINED __LAST_LIBDIR_DEFAULT
|
||||
AND "${__LAST_LIBDIR_DEFAULT}" STREQUAL "${CMAKE_INSTALL_LIBDIR}")
|
||||
set_property(CACHE CMAKE_INSTALL_LIBDIR PROPERTY VALUE "${_LIBDIR_DEFAULT}")
|
||||
endif()
|
||||
endif()
|
||||
# Save for next run
|
||||
set(_GNUInstallDirs_LAST_CMAKE_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}" CACHE INTERNAL "CMAKE_INSTALL_PREFIX during last run")
|
||||
unset(_libdir_set)
|
||||
unset(__LAST_LIBDIR_DEFAULT)
|
||||
|
||||
|
||||
if(NOT DEFINED CMAKE_INSTALL_INCLUDEDIR)
|
||||
set(CMAKE_INSTALL_INCLUDEDIR "include" CACHE PATH "C header files (include)")
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
!define APPLICATION_NAME "@APPLICATION_NAME@"
|
||||
!define APPLICATION_VENDOR "@APPLICATION_VENDOR@"
|
||||
!define APPLICATION_EXECUTABLE "@APPLICATION_EXECUTABLE@.exe"
|
||||
!define APPLICATION_CMD_EXECUTABLE "@APPLICATION_EXECUTABLE@cmd.exe"
|
||||
!define APPLICATION_DOMAIN "@APPLICATION_DOMAIN@"
|
||||
!define APPLICATION_LICENSE "@APPLICATION_LICENSE@"
|
||||
!define WIN_SETUP_BITMAP_PATH "@WIN_SETUP_BITMAP_PATH@"
|
||||
@@ -34,9 +35,10 @@
|
||||
!define BUILD_PATH "@CMAKE_BINARY_DIR@"
|
||||
!define SOURCE_PATH "@CMAKE_SOURCE_DIR@"
|
||||
!define QT_DLL_PATH "${MING_BIN}"
|
||||
!define ACCESSIBLE_DLL_PATH "${MING_LIB}/qt4/plugins/accessible"
|
||||
!define SQLITE_DLL_PATH "${MING_LIB}/qt4/plugins/sqldrivers"
|
||||
!define IMAGEFORMATS_DLL_PATH "${MING_LIB}/qt4/plugins/imageformats"
|
||||
!define ACCESSIBLE_DLL_PATH "${MING_LIB}/qt5/plugins/accessible"
|
||||
!define SQLITE_DLL_PATH "${MING_LIB}/qt5/plugins/sqldrivers"
|
||||
!define IMAGEFORMATS_DLL_PATH "${MING_LIB}/qt5/plugins/imageformats"
|
||||
!define PLATFORMS_DLL_PATH "${MING_LIB}/qt5/plugins/platforms"
|
||||
|
||||
!define CSYNC_LIBRARY_DIR "@CSYNC_LIBRARY_DIR@"
|
||||
!define CSYNC_CONFIG_DIR "@CSYNC_CONFIG_DIR@"
|
||||
@@ -361,25 +363,28 @@ Section "${APPLICATION_NAME}" SEC_APPLICATION
|
||||
|
||||
;Main executable & csync
|
||||
File "${BUILD_PATH}\bin\${APPLICATION_EXECUTABLE}"
|
||||
File "${BUILD_PATH}\bin\${APPLICATION_CMD_EXECUTABLE}"
|
||||
File "${BUILD_PATH}\src\lib${APPLICATION_SHORTNAME}sync.dll"
|
||||
File "${BUILD_PATH}\csync\src\libocsync.dll"
|
||||
|
||||
|
||||
File "${BUILD_PATH}\src\mirall_*.qm"
|
||||
; Make sure only to copy qt, not qt_help, etc
|
||||
File "${MING_SHARE}\qt4\translations\qt_??.qm"
|
||||
File "${MING_SHARE}\qt4\translations\qt_??_??.qm"
|
||||
File "${MING_SHARE}\qt4\translations\qtkeychain_*.qm"
|
||||
File "${MING_SHARE}\qt5\translations\qt_??.qm"
|
||||
File "${MING_SHARE}\qt5\translations\qt_??_??.qm"
|
||||
File "${MING_SHARE}\qt5\translations\qtkeychain_*.qm"
|
||||
|
||||
SetOutPath "$INSTDIR\platforms"
|
||||
File "${PLATFORMS_DLL_PATH}\qwindows.dll"
|
||||
SetOutPath "$INSTDIR\accessible"
|
||||
File "${ACCESSIBLE_DLL_PATH}\qtaccessiblewidgets4.dll"
|
||||
File "${ACCESSIBLE_DLL_PATH}\qtaccessiblewidgets.dll"
|
||||
SetOutPath "$INSTDIR\imageformats"
|
||||
File "${IMAGEFORMATS_DLL_PATH}\qgif4.dll"
|
||||
File "${IMAGEFORMATS_DLL_PATH}\qjpeg4.dll"
|
||||
File "${IMAGEFORMATS_DLL_PATH}\qico4.dll"
|
||||
File "${IMAGEFORMATS_DLL_PATH}\qgif.dll"
|
||||
File "${IMAGEFORMATS_DLL_PATH}\qjpeg.dll"
|
||||
File "${IMAGEFORMATS_DLL_PATH}\qico.dll"
|
||||
|
||||
SetOutPath "$INSTDIR\sqldrivers"
|
||||
File "${SQLITE_DLL_PATH}\qsqlite4.dll"
|
||||
File "${SQLITE_DLL_PATH}\qsqlite.dll"
|
||||
|
||||
SetOutPath "$INSTDIR"
|
||||
;License & release notes.
|
||||
@@ -387,15 +392,39 @@ Section "${APPLICATION_NAME}" SEC_APPLICATION
|
||||
;File /oname=NOTES.txt ${NSI_PATH}\RELEASE_NOTES.txt
|
||||
|
||||
;Qt stuff:
|
||||
File "${QT_DLL_PATH}\QtCore4.dll"
|
||||
File "${QT_DLL_PATH}\QtGui4.dll"
|
||||
File "${QT_DLL_PATH}\QtNetwork4.dll"
|
||||
File "${QT_DLL_PATH}\QtSql4.dll"
|
||||
File "${QT_DLL_PATH}\QtXml4.dll"
|
||||
File "${QT_DLL_PATH}\QtWebKit4.dll"
|
||||
File "${QT_DLL_PATH}\Qt5Core.dll"
|
||||
File "${QT_DLL_PATH}\Qt5Gui.dll"
|
||||
File "${QT_DLL_PATH}\Qt5Network.dll"
|
||||
File "${QT_DLL_PATH}\Qt5OpenGL.dll"
|
||||
File "${QT_DLL_PATH}\Qt5PrintSupport.dll"
|
||||
File "${QT_DLL_PATH}\Qt5Qml.dll"
|
||||
File "${QT_DLL_PATH}\Qt5Quick.dll"
|
||||
File "${QT_DLL_PATH}\Qt5Sensors.dll"
|
||||
File "${QT_DLL_PATH}\Qt5Sql.dll"
|
||||
File "${QT_DLL_PATH}\Qt5WebKit.dll"
|
||||
File "${QT_DLL_PATH}\Qt5WebKitWidgets.dll"
|
||||
File "${QT_DLL_PATH}\Qt5Widgets.dll"
|
||||
File "${QT_DLL_PATH}\Qt5Xml.dll"
|
||||
|
||||
;Qt deps
|
||||
File "${MING_BIN}\libpng15-15.dll"
|
||||
File "${MING_BIN}\icudata51.dll"
|
||||
File "${MING_BIN}\icui18n51.dll"
|
||||
File "${MING_BIN}\icuuc51.dll"
|
||||
File "${MING_BIN}\libEGL.dll"
|
||||
File "${MING_BIN}\libGLESv2.dll"
|
||||
File "${MING_BIN}\libjpeg-8.dll"
|
||||
File "${MING_BIN}\libpcre16-0.dll"
|
||||
File "${MING_BIN}\libpng15-15.dll"
|
||||
File "${MING_BIN}\libproxy.dll"
|
||||
File "${MING_BIN}\libqt5keychain.dll"
|
||||
File "${MING_BIN}\libsqlite3-0.dll"
|
||||
File "${MING_BIN}\libcrypto-10.dll"
|
||||
File "${MING_BIN}\libssl-10.dll"
|
||||
File "${MING_BIN}\libstdc++-6.dll"
|
||||
File "${MING_BIN}\libwebp-4.dll"
|
||||
File "${MING_BIN}\libxslt-1.dll"
|
||||
File "${MING_BIN}\zlib1.dll"
|
||||
|
||||
;QtSql and csync dep
|
||||
File "${MING_BIN}\libsqlite3-0.dll"
|
||||
@@ -414,13 +443,6 @@ Section "${APPLICATION_NAME}" SEC_APPLICATION
|
||||
File "${MING_BIN}\libgcc_s_sjlj-1.dll"
|
||||
File "${MING_BIN}\libstdc++-6.dll"
|
||||
|
||||
; Other
|
||||
;File "${MING_BIN}\libpng15-15.dll"
|
||||
File "${MING_BIN}\libjpeg-8.dll"
|
||||
File "${MING_BIN}\zlib1.dll"
|
||||
File "${MING_BIN}\libcrypto-10.dll"
|
||||
File "${MING_BIN}\libssl-10.dll"
|
||||
|
||||
; CSync configs
|
||||
File "${SOURCE_PATH}/sync-exclude.lst"
|
||||
|
||||
|
||||
@@ -1,76 +1,101 @@
|
||||
include (MacroOptionalFindPackage)
|
||||
include (MacroLogFeature)
|
||||
|
||||
option(BUILD_WITH_QT4 "Build with Qt4 no matter if Qt5 was found" OFF)
|
||||
|
||||
option(BUILD_WITH_QT4 "Build with Qt4 no matter if Qt5 was found" ON)
|
||||
|
||||
if( NOT BUILD_WITH_QT4 )
|
||||
if( BUILD_WITH_QT4 )
|
||||
message(STATUS "Search for Qt5 was disalbed by option BUILD_WITH_QT4")
|
||||
else( BUILD_WITH_QT4 )
|
||||
find_package(Qt5Core QUIET)
|
||||
if( Qt5Core_DIR )
|
||||
find_package(Qt5Widgets QUIET)
|
||||
find_package(Qt5Quick QUIET)
|
||||
find_package(Qt5PrintSupport QUIET)
|
||||
find_package(Qt5WebKit QUIET)
|
||||
find_package(Qt5Location QUIET)
|
||||
find_package(Qt5Network QUIET)
|
||||
find_package(Qt5Sensors QUIET)
|
||||
find_package(Qt5Xml QUIET)
|
||||
# find_package(Qt5WebKitWidgets QUIET)
|
||||
endif( BUILD_WITH_QT4 )
|
||||
|
||||
message(STATUS "Using Qt 5!")
|
||||
if( Qt5Core_FOUND )
|
||||
message(STATUS "Found Qt5 core, checking for further dependencies...")
|
||||
find_package(Qt5Network REQUIRED)
|
||||
find_package(Qt5Xml REQUIRED)
|
||||
if(NOT TOKEN_AUTH_ONLY)
|
||||
find_package(Qt5WebKitWidgets REQUIRED)
|
||||
find_package(Qt5WebKit REQUIRED)
|
||||
find_package(Qt5PrintSupport REQUIRED)
|
||||
find_package(Qt5Quick REQUIRED)
|
||||
find_package(Qt5Widgets REQUIRED)
|
||||
endif()
|
||||
if(APPLE)
|
||||
find_package(Qt5MacExtras REQUIRED)
|
||||
endif(APPLE)
|
||||
else( Qt5Core_FOUND )
|
||||
if(WIN32 OR APPLE)
|
||||
message(FATAL_ERROR "Qt 5 not found, but application depends on Qt5 on Windows and Mac OS X")
|
||||
endif(WIN32 OR APPLE)
|
||||
endif( Qt5Core_FOUND )
|
||||
|
||||
# We need this to find the paths to qdbusxml2cpp and co
|
||||
if (WITH_DBUS)
|
||||
find_package(Qt5DBus REQUIRED)
|
||||
include_directories(${Qt5DBus_INCLUDES})
|
||||
add_definitions(${Qt5DBus_DEFINITIONS})
|
||||
endif (WITH_DBUS)
|
||||
|
||||
include_directories(${Qt5Widgets_INCLUDES})
|
||||
add_definitions(${Qt5Widgets_DEFINITIONS})
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC")
|
||||
if( Qt5Core_FOUND )
|
||||
message(STATUS "Using Qt 5!")
|
||||
|
||||
# We need this to find the paths to qdbusxml2cpp and co
|
||||
if (WITH_DBUS)
|
||||
find_package(Qt5DBus REQUIRED)
|
||||
include_directories(${Qt5DBus_INCLUDES})
|
||||
add_definitions(${Qt5DBus_DEFINITIONS})
|
||||
endif (WITH_DBUS)
|
||||
include_directories(${Qt5Core_INCLUDES})
|
||||
add_definitions(${Qt5Core_DEFINITIONS})
|
||||
if (NOT WIN32) #implied on Win32
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC")
|
||||
endif(NOT WIN32)
|
||||
# set(CMAKE_CXX_FLAGS "${Qt5Widgets_EXECUTABLE_COMPILE_FLAGS}")
|
||||
|
||||
|
||||
macro(qt_wrap_ui)
|
||||
qt5_wrap_ui(${ARGN})
|
||||
endmacro()
|
||||
|
||||
macro(qt_add_resources)
|
||||
qt5_add_resources(${ARGN})
|
||||
endmacro()
|
||||
|
||||
# find_package(Qt5LinguistTools REQUIRED)
|
||||
macro(qt_add_translation)
|
||||
# qt5_add_translation(${ARGN})
|
||||
endmacro()
|
||||
|
||||
macro(qt_add_dbus_interface)
|
||||
qt5_add_dbus_interface(${ARGN})
|
||||
endmacro()
|
||||
|
||||
macro(qt_add_dbus_adaptor)
|
||||
qt5_add_dbus_adaptor(${ARGN})
|
||||
endmacro()
|
||||
|
||||
macro(qt_wrap_cpp)
|
||||
qt5_wrap_cpp(${ARGN})
|
||||
endmacro()
|
||||
|
||||
macro(install_qt_executable)
|
||||
install_qt5_executable(${ARGN})
|
||||
endmacro()
|
||||
|
||||
macro(setup_qt)
|
||||
endmacro()
|
||||
|
||||
set(QT_RCC_EXECUTABLE "${Qt5Core_RCC_EXECUTABLE}")
|
||||
|
||||
#Enable deprecated symbols
|
||||
add_definitions("-DQT_DISABLE_DEPRECATED_BEFORE=0")
|
||||
if(APPLE AND NOT TOKEN_AUTH_ONLY)
|
||||
include_directories(${Qt5MacExtras_INCLUDE_DIRS})
|
||||
add_definitions(${Qt5MacExtras_DEFINITIONS})
|
||||
set (QT_LIBRARIES ${QT_LIBRARIES} ${Qt5MacExtras_LIBRARIES})
|
||||
endif()
|
||||
|
||||
if(NOT BUILD_LIBRARIES_ONLY)
|
||||
macro(qt_wrap_ui)
|
||||
qt5_wrap_ui(${ARGN})
|
||||
endmacro()
|
||||
else()
|
||||
# hack
|
||||
SET(QT_UIC_EXECUTABLE "")
|
||||
endif()
|
||||
if( NOT Qt5Core_DIR )
|
||||
|
||||
macro(qt_add_resources)
|
||||
qt5_add_resources(${ARGN})
|
||||
endmacro()
|
||||
|
||||
find_package(Qt5LinguistTools REQUIRED)
|
||||
macro(qt_add_translation)
|
||||
qt5_add_translation(${ARGN})
|
||||
endmacro()
|
||||
|
||||
macro(qt_add_dbus_interface)
|
||||
qt5_add_dbus_interface(${ARGN})
|
||||
endmacro()
|
||||
|
||||
macro(qt_add_dbus_adaptor)
|
||||
qt5_add_dbus_adaptor(${ARGN})
|
||||
endmacro()
|
||||
|
||||
macro(qt_wrap_cpp)
|
||||
qt5_wrap_cpp(${ARGN})
|
||||
endmacro()
|
||||
|
||||
macro(install_qt_executable)
|
||||
install_qt5_executable(${ARGN})
|
||||
endmacro()
|
||||
|
||||
macro(setup_qt)
|
||||
endmacro()
|
||||
|
||||
set(QT_RCC_EXECUTABLE "${Qt5Core_RCC_EXECUTABLE}")
|
||||
|
||||
#Enable deprecated symbols
|
||||
add_definitions("-DQT_DISABLE_DEPRECATED_BEFORE=0")
|
||||
endif( Qt5Core_FOUND )
|
||||
|
||||
if(NOT Qt5Core_FOUND)
|
||||
message(STATUS "Could not find Qt5, searching for Qt4 instead...")
|
||||
|
||||
set(NEEDED_QT4_COMPONENTS "QtCore" "QtXml" "QtNetwork" "QtGui" "QtWebkit")
|
||||
@@ -78,8 +103,8 @@ if( NOT Qt5Core_DIR )
|
||||
list(APPEND NEEDED_QT4_COMPONENTS "QtTest")
|
||||
endif()
|
||||
|
||||
macro_optional_find_package(Qt4 4.7.0 COMPONENTS ${NEEDED_QT4_COMPONENTS} )
|
||||
macro_log_feature(QT4_FOUND "Qt" "A cross-platform application and UI framework" "http://qt.nokia.com" TRUE "" "If you see this, although libqt4-devel is installed, check whether the \n qtwebkit-devel package and whatever contains QtUiTools is installed too")
|
||||
find_package(Qt4 4.7.0 COMPONENTS ${NEEDED_QT4_COMPONENTS} )
|
||||
macro_log_feature(QT4_FOUND "Qt" "A cross-platform application and UI framework" "http://www.qt-project.org" TRUE "" "If you see this, although libqt4-devel is installed, check whether the \n qtwebkit-devel package and whatever contains QtUiTools is installed too")
|
||||
|
||||
macro(qt5_use_modules)
|
||||
endmacro()
|
||||
|
||||
@@ -32,7 +32,6 @@ set(CSYNC_LIBRARY
|
||||
)
|
||||
|
||||
set(CSYNC_LINK_LIBRARIES
|
||||
${CSYNC_LIBRARY}
|
||||
${CSTDLIB_LIBRARY}
|
||||
${CSYNC_REQUIRED_LIBRARIES}
|
||||
${SQLITE3_LIBRARIES}
|
||||
@@ -45,11 +44,10 @@ if(HAVE_ICONV AND WITH_ICONV)
|
||||
list(APPEND CSYNC_LINK_LIBRARIES ${ICONV_LIBRARIES})
|
||||
endif()
|
||||
|
||||
set(BLACKLIST_ON_ERROR 0 CACHE BOOL
|
||||
"If an errors occurs three times on the same file, do not attempt to process that file any further.")
|
||||
|
||||
if(BLACKLIST_ON_ERROR)
|
||||
add_definitions(-DBLACKLIST_ON_ERROR)
|
||||
# Specific option for builds tied to servers that do not support renaming extensions
|
||||
set(NO_RENAME_EXTENSION 0 CACHE BOOL "Do not issue rename if the extension changes")
|
||||
if(NO_RENAME_EXTENSION)
|
||||
add_definitions(-DNO_RENAME_EXTENSION)
|
||||
endif()
|
||||
|
||||
set(csync_SRCS
|
||||
@@ -57,7 +55,6 @@ set(csync_SRCS
|
||||
csync_exclude.c
|
||||
csync_log.c
|
||||
csync_statedb.c
|
||||
csync_dbtree.c
|
||||
csync_time.c
|
||||
csync_util.c
|
||||
csync_misc.c
|
||||
@@ -68,7 +65,6 @@ set(csync_SRCS
|
||||
csync_rename.cc
|
||||
|
||||
vio/csync_vio.c
|
||||
vio/csync_vio_handle.c
|
||||
vio/csync_vio_file_stat.c
|
||||
vio/csync_vio_local.c
|
||||
|
||||
@@ -100,8 +96,10 @@ include_directories(
|
||||
)
|
||||
|
||||
add_library(${CSYNC_LIBRARY} SHARED ${csync_SRCS})
|
||||
add_library(${CSYNC_LIBRARY}_static STATIC ${csync_SRCS})
|
||||
|
||||
target_link_libraries(${CSYNC_LINK_LIBRARIES})
|
||||
target_link_libraries(${CSYNC_LIBRARY} ${CSYNC_LINK_LIBRARIES})
|
||||
target_link_libraries(${CSYNC_LIBRARY}_static ${CSYNC_LINK_LIBRARIES})
|
||||
|
||||
set_target_properties(
|
||||
${CSYNC_LIBRARY}
|
||||
@@ -111,17 +109,29 @@ set_target_properties(
|
||||
SOVERSION
|
||||
${LIBRARY_SOVERSION}
|
||||
)
|
||||
|
||||
INSTALL(
|
||||
if(BUILD_OWNCLOUD_OSX_BUNDLE)
|
||||
INSTALL(
|
||||
TARGETS
|
||||
${CSYNC_LIBRARY}
|
||||
LIBRARY DESTINATION
|
||||
${LIB_INSTALL_DIR}
|
||||
ARCHIVE DESTINATION
|
||||
${LIB_INSTALL_DIR}
|
||||
RUNTIME DESTINATION
|
||||
${BIN_INSTALL_DIR}
|
||||
)
|
||||
else()
|
||||
INSTALL(
|
||||
TARGETS
|
||||
${CSYNC_LIBRARY}
|
||||
LIBRARY DESTINATION
|
||||
${LIB_INSTALL_DIR}
|
||||
${LIB_INSTALL_DIR}/${APPLICATION_EXECUTABLE}
|
||||
ARCHIVE DESTINATION
|
||||
${LIB_INSTALL_DIR}
|
||||
${LIB_INSTALL_DIR}/${APPLICATION_EXECUTABLE}
|
||||
RUNTIME DESTINATION
|
||||
${BIN_INSTALL_DIR}
|
||||
)
|
||||
${BIN_INSTALL_DIR}/${APPLICATION_EXECUTABLE}
|
||||
)
|
||||
endif()
|
||||
|
||||
# INSTALL(
|
||||
# FILES
|
||||
|
||||
@@ -56,6 +56,11 @@
|
||||
|
||||
#include "csync_log.h"
|
||||
#include "csync_rename.h"
|
||||
#include "c_jhash.h"
|
||||
|
||||
|
||||
// Breaking the abstraction for fun and profit.
|
||||
#include "csync_owncloud.h"
|
||||
|
||||
static int _key_cmp(const void *key, const void *data) {
|
||||
uint64_t a;
|
||||
@@ -124,10 +129,6 @@ int csync_create(CSYNC **csync, const char *local, const char *remote) {
|
||||
}
|
||||
|
||||
ctx->status_code = CSYNC_STATUS_OK;
|
||||
ctx->options.max_depth = MAX_DEPTH;
|
||||
ctx->options.max_time_difference = MAX_TIME_DIFFERENCE;
|
||||
ctx->options.unix_extensions = 0;
|
||||
ctx->options.with_conflict_copys=false;
|
||||
ctx->options.local_only_mode = false;
|
||||
|
||||
ctx->pwd.uid = getuid();
|
||||
@@ -166,7 +167,6 @@ int csync_create(CSYNC **csync, const char *local, const char *remote) {
|
||||
|
||||
int csync_init(CSYNC *ctx) {
|
||||
int rc;
|
||||
time_t timediff = -1;
|
||||
char *config = NULL;
|
||||
|
||||
if (ctx == NULL) {
|
||||
@@ -181,82 +181,22 @@ int csync_init(CSYNC *ctx) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* check for uri */
|
||||
if (csync_fnmatch("owncloud://*", ctx->remote.uri, 0) == 0 && csync_fnmatch("ownclouds://*", ctx->remote.uri, 0) == 0) {
|
||||
ctx->status_code = CSYNC_STATUS_NO_MODULE;
|
||||
rc = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ctx->local.type = LOCAL_REPLICA;
|
||||
|
||||
/* check for uri */
|
||||
if ( !ctx->options.local_only_mode && csync_fnmatch("*://*", ctx->remote.uri, 0) == 0) {
|
||||
size_t len;
|
||||
len = strstr(ctx->remote.uri, "://") - ctx->remote.uri;
|
||||
/* get protocol */
|
||||
if (len > 0) {
|
||||
char *module = NULL;
|
||||
/* module name */
|
||||
module = c_strndup(ctx->remote.uri, len);
|
||||
if (module == NULL) {
|
||||
rc = -1;
|
||||
ctx->status_code = CSYNC_STATUS_MEMORY_ERROR;
|
||||
goto out;
|
||||
}
|
||||
/* load module */
|
||||
retry_vio_init:
|
||||
rc = csync_vio_init(ctx, module, NULL);
|
||||
if (rc < 0) {
|
||||
len = strlen(module);
|
||||
|
||||
if (len > 0 && module[len-1] == 's') {
|
||||
module[len-1] = '\0';
|
||||
goto retry_vio_init;
|
||||
}
|
||||
/* Now vio init finally failed which means a module could not be found. */
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_FATAL,
|
||||
"The csync module %s could not be loaded.", module);
|
||||
SAFE_FREE(module);
|
||||
ctx->status_code = CSYNC_STATUS_NO_MODULE;
|
||||
goto out;
|
||||
}
|
||||
SAFE_FREE(module);
|
||||
if ( !ctx->options.local_only_mode) {
|
||||
owncloud_init(csync_get_userdata(ctx));
|
||||
ctx->remote.type = REMOTE_REPLICA;
|
||||
}
|
||||
} else {
|
||||
ctx->remote.type = LOCAL_REPLICA;
|
||||
}
|
||||
|
||||
if(!ctx->options.local_only_mode) {
|
||||
if(ctx->module.capabilities.time_sync_required) {
|
||||
timediff = csync_timediff(ctx);
|
||||
if (timediff > ctx->options.max_time_difference) {
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_FATAL,
|
||||
"Clock skew detected. The time difference is greater than %d seconds!",
|
||||
ctx->options.max_time_difference);
|
||||
ctx->status_code = CSYNC_STATUS_TIMESKEW;
|
||||
rc = -1;
|
||||
goto out;
|
||||
} else if (timediff < 0) {
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_FATAL, "Synchronisation is not possible!");
|
||||
ctx->status_code = CSYNC_STATUS_TIMESKEW;
|
||||
rc = -1;
|
||||
goto out;
|
||||
}
|
||||
} else {
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "Module does not need time synchronization.");
|
||||
}
|
||||
|
||||
if(ctx->module.capabilities.unix_extensions == -1) { /* detect */
|
||||
if (csync_unix_extensions(ctx) < 0) {
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_FATAL, "Could not detect filesystem type.");
|
||||
ctx->status_code = CSYNC_STATUS_FILESYSTEM_UNKNOWN;
|
||||
rc = -1;
|
||||
goto out;
|
||||
}
|
||||
} else {
|
||||
/* The module specifies the value for the unix_extensions. */
|
||||
ctx->options.unix_extensions = ctx->module.capabilities.unix_extensions;
|
||||
}
|
||||
}
|
||||
|
||||
if (ctx->options.timeout)
|
||||
csync_vio_set_property(ctx, "timeout", &ctx->options.timeout);
|
||||
|
||||
if (c_rbtree_create(&ctx->local.tree, _key_cmp, _data_cmp) < 0) {
|
||||
ctx->status_code = CSYNC_STATUS_TREE_ERROR;
|
||||
rc = -1;
|
||||
@@ -314,6 +254,10 @@ int csync_update(CSYNC *ctx) {
|
||||
|
||||
csync_memstat_check();
|
||||
|
||||
if (!ctx->excludes) {
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG, "No exclude file loaded or defined!");
|
||||
}
|
||||
|
||||
/* update detection for local replica */
|
||||
csync_gettime(&start);
|
||||
ctx->current = LOCAL_REPLICA;
|
||||
@@ -396,7 +340,7 @@ int csync_reconcile(CSYNC *ctx) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Reconciliation for local replica */
|
||||
/* Reconciliation for remote replica */
|
||||
csync_gettime(&start);
|
||||
|
||||
ctx->current = REMOTE_REPLICA;
|
||||
@@ -432,6 +376,8 @@ static int _csync_treewalk_visitor(void *obj, void *data) {
|
||||
c_rbtree_visit_func *visitor = NULL;
|
||||
_csync_treewalk_context *twctx = NULL;
|
||||
TREE_WALK_FILE trav;
|
||||
c_rbtree_t *other_tree = NULL;
|
||||
c_rbnode_t *other_node = NULL;
|
||||
|
||||
cur = (csync_file_stat_t *) obj;
|
||||
ctx = (CSYNC *) data;
|
||||
@@ -440,6 +386,34 @@ static int _csync_treewalk_visitor(void *obj, void *data) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* we need the opposite tree! */
|
||||
switch (ctx->current) {
|
||||
case LOCAL_REPLICA:
|
||||
other_tree = ctx->remote.tree;
|
||||
break;
|
||||
case REMOTE_REPLICA:
|
||||
other_tree = ctx->local.tree;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
other_node = c_rbtree_find(other_tree, &cur->phash);
|
||||
|
||||
if (!other_node) {
|
||||
/* Check the renamed path as well. */
|
||||
int len;
|
||||
uint64_t h = 0;
|
||||
char *renamed_path = csync_rename_adjust_path(ctx, cur->path);
|
||||
|
||||
if (!c_streq(renamed_path, cur->path)) {
|
||||
len = strlen( renamed_path );
|
||||
h = c_jhash64((uint8_t *) renamed_path, len, 0);
|
||||
other_node = c_rbtree_find(other_tree, &h);
|
||||
}
|
||||
SAFE_FREE(renamed_path);
|
||||
}
|
||||
|
||||
if (obj == NULL || data == NULL) {
|
||||
ctx->status_code = CSYNC_STATUS_PARAM_ERROR;
|
||||
return -1;
|
||||
@@ -470,16 +444,33 @@ static int _csync_treewalk_visitor(void *obj, void *data) {
|
||||
trav.rename_path = cur->destpath;
|
||||
trav.etag = cur->etag;
|
||||
trav.file_id = cur->file_id;
|
||||
trav.inode = cur->inode;
|
||||
|
||||
trav.error_status = cur->error_status;
|
||||
trav.should_update_etag = cur->should_update_etag;
|
||||
|
||||
if( other_node ) {
|
||||
csync_file_stat_t *other_stat = (csync_file_stat_t*)other_node->data;
|
||||
trav.other.etag = other_stat->etag;
|
||||
trav.other.file_id = other_stat->file_id;
|
||||
trav.other.instruction = other_stat->instruction;
|
||||
trav.other.modtime = other_stat->modtime;
|
||||
trav.other.size = other_stat->size;
|
||||
} else {
|
||||
trav.other.etag = 0;
|
||||
trav.other.file_id = 0;
|
||||
trav.other.instruction = CSYNC_INSTRUCTION_NONE;
|
||||
trav.other.modtime = 0;
|
||||
trav.other.size = 0;
|
||||
}
|
||||
|
||||
rc = (*visitor)(&trav, twctx->userdata);
|
||||
cur->instruction = trav.instruction;
|
||||
if (trav.etag != cur->etag) {
|
||||
SAFE_FREE(cur->etag);
|
||||
cur->etag = c_strdup(trav.etag);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
ctx->status_code = CSYNC_STATUS_PARAM_ERROR;
|
||||
@@ -535,6 +526,7 @@ int csync_walk_remote_tree(CSYNC *ctx, csync_treewalk_visit_func *visitor, int
|
||||
|
||||
if(ctx != NULL) {
|
||||
ctx->status_code = CSYNC_STATUS_OK;
|
||||
ctx->current = REMOTE_REPLICA;
|
||||
tree = ctx->remote.tree;
|
||||
}
|
||||
|
||||
@@ -553,6 +545,7 @@ int csync_walk_local_tree(CSYNC *ctx, csync_treewalk_visit_func *visitor, int fi
|
||||
|
||||
if (ctx != NULL) {
|
||||
ctx->status_code = CSYNC_STATUS_OK;
|
||||
ctx->current = LOCAL_REPLICA;
|
||||
tree = ctx->local.tree;
|
||||
}
|
||||
|
||||
@@ -618,7 +611,7 @@ int csync_commit(CSYNC *ctx) {
|
||||
ctx->status_code = CSYNC_STATUS_OK;
|
||||
|
||||
if (ctx->statedb.db != NULL
|
||||
&& csync_statedb_close(ctx->statedb.file, ctx->statedb.db, 0) < 0) {
|
||||
&& csync_statedb_close(ctx) < 0) {
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG, "ERR: closing of statedb failed.");
|
||||
rc = -1;
|
||||
}
|
||||
@@ -634,6 +627,8 @@ int csync_commit(CSYNC *ctx) {
|
||||
_csync_clean_ctx(ctx);
|
||||
|
||||
ctx->remote.read_from_db = 0;
|
||||
ctx->read_from_db_disabled = 0;
|
||||
|
||||
|
||||
/* Create new trees */
|
||||
rc = c_rbtree_create(&ctx->local.tree, _key_cmp, _data_cmp);
|
||||
@@ -648,11 +643,6 @@ int csync_commit(CSYNC *ctx) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* reset the progress */
|
||||
ctx->overall_progress.file_count = 0;
|
||||
ctx->overall_progress.current_file_no = 0;
|
||||
ctx->overall_progress.byte_sum = 0;
|
||||
ctx->overall_progress.byte_current = 0;
|
||||
|
||||
ctx->status = CSYNC_STATUS_INIT;
|
||||
SAFE_FREE(ctx->error_string);
|
||||
@@ -673,14 +663,12 @@ int csync_destroy(CSYNC *ctx) {
|
||||
ctx->status_code = CSYNC_STATUS_OK;
|
||||
|
||||
if (ctx->statedb.db != NULL
|
||||
&& csync_statedb_close(ctx->statedb.file, ctx->statedb.db, 0) < 0) {
|
||||
&& csync_statedb_close(ctx) < 0) {
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG, "ERR: closing of statedb failed.");
|
||||
rc = -1;
|
||||
}
|
||||
ctx->statedb.db = NULL;
|
||||
|
||||
csync_vio_shutdown(ctx);
|
||||
|
||||
/* destroy exclude list */
|
||||
csync_exclude_destroy(ctx);
|
||||
|
||||
@@ -853,22 +841,6 @@ CSYNC_STATUS csync_get_status(CSYNC *ctx) {
|
||||
return ctx->status_code;
|
||||
}
|
||||
|
||||
int csync_enable_conflictcopys(CSYNC* ctx){
|
||||
if (ctx == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ctx->status & CSYNC_STATUS_INIT) {
|
||||
fprintf(stderr, "This function must be called before initialization.");
|
||||
ctx->status_code = CSYNC_STATUS_CSYNC_STATUS_ERROR;
|
||||
return -1;
|
||||
}
|
||||
|
||||
ctx->options.with_conflict_copys=true;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int csync_set_local_only(CSYNC *ctx, bool local_only) {
|
||||
if (ctx == NULL) {
|
||||
return -1;
|
||||
@@ -951,27 +923,10 @@ int csync_set_module_property(CSYNC* ctx, const char* key, void* value)
|
||||
return csync_vio_set_property(ctx, key, value);
|
||||
}
|
||||
|
||||
int csync_set_progress_callback(CSYNC* ctx, csync_progress_callback cb)
|
||||
|
||||
int csync_set_read_from_db(CSYNC* ctx, int enabled)
|
||||
{
|
||||
if (ctx == NULL) {
|
||||
return -1;
|
||||
}
|
||||
if (cb == NULL ) {
|
||||
ctx->status_code = CSYNC_STATUS_PARAM_ERROR;
|
||||
return -1;
|
||||
}
|
||||
|
||||
ctx->callbacks.progress_cb = cb;
|
||||
ctx->status_code = CSYNC_STATUS_OK;
|
||||
return 0;
|
||||
|
||||
ctx->read_from_db_disabled = !enabled;
|
||||
return 0;
|
||||
}
|
||||
|
||||
csync_progress_callback csync_get_progress_callback(CSYNC *ctx)
|
||||
{
|
||||
if (ctx == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return ctx->callbacks.progress_cb;
|
||||
}
|
||||
|
||||
@@ -102,7 +102,8 @@ enum csync_status_codes_e {
|
||||
/* Codes for file individual status: */
|
||||
CSYNC_STATUS_INDIVIDUAL_IS_SYMLINK,
|
||||
CSYNC_STATUS_INDIVIDUAL_IGNORE_LIST,
|
||||
CSYNC_STATUS_INDIVIDUAL_IS_INVALID_CHARS
|
||||
CSYNC_STATUS_INDIVIDUAL_IS_INVALID_CHARS,
|
||||
CYSNC_STATUS_FILE_LOCKED_OR_OPEN
|
||||
};
|
||||
|
||||
typedef enum csync_status_codes_e CSYNC_STATUS;
|
||||
@@ -130,10 +131,7 @@ enum csync_instructions_e {
|
||||
CSYNC_INSTRUCTION_IGNORE = 0x00000020, /* The file is ignored (UPDATE|RECONCILE) */
|
||||
CSYNC_INSTRUCTION_SYNC = 0x00000040, /* The file need to be pushed to the other remote (RECONCILE) */
|
||||
CSYNC_INSTRUCTION_STAT_ERROR = 0x00000080,
|
||||
CSYNC_INSTRUCTION_ERROR = 0x00000100,
|
||||
/* instructions for the propagator */
|
||||
CSYNC_INSTRUCTION_DELETED = 0x00000200,
|
||||
CSYNC_INSTRUCTION_UPDATED = 0x00000400
|
||||
CSYNC_INSTRUCTION_ERROR = 0x00000100
|
||||
};
|
||||
|
||||
enum csync_ftw_type_e {
|
||||
@@ -154,26 +152,13 @@ enum csync_notify_type_e {
|
||||
CSYNC_NOTIFY_FINISHED_SYNC_SEQUENCE,
|
||||
CSYNC_NOTIFY_START_DELETE,
|
||||
CSYNC_NOTIFY_END_DELETE,
|
||||
CSYNC_NOTIFY_ERROR
|
||||
CSYNC_NOTIFY_ERROR,
|
||||
CSYNC_NOTIFY_START_LOCAL_UPDATE,
|
||||
CSYNC_NOTIFY_FINISHED_LOCAL_UPDATE,
|
||||
CSYNC_NOTIFY_START_REMOTE_UPDATE,
|
||||
CSYNC_NOTIFY_FINISHED_REMOTE_UPDATE
|
||||
};
|
||||
|
||||
struct csync_progress_s {
|
||||
enum csync_notify_type_e kind;
|
||||
|
||||
/* individual file progress information */
|
||||
const char *path;
|
||||
int64_t curr_bytes;
|
||||
int64_t file_size;
|
||||
|
||||
/* overall progress */
|
||||
int64_t overall_transmission_size;
|
||||
int64_t current_overall_bytes;
|
||||
int64_t overall_file_count;
|
||||
int64_t current_file_no;
|
||||
|
||||
};
|
||||
typedef struct csync_progress_s CSYNC_PROGRESS;
|
||||
|
||||
/**
|
||||
* CSync File Traversal structure.
|
||||
*
|
||||
@@ -185,6 +170,7 @@ typedef struct csync_progress_s CSYNC_PROGRESS;
|
||||
struct csync_tree_walk_file_s {
|
||||
const char *path;
|
||||
int64_t size;
|
||||
int64_t inode;
|
||||
time_t modtime;
|
||||
#ifdef _WIN32
|
||||
uint32_t uid;
|
||||
@@ -203,6 +189,14 @@ struct csync_tree_walk_file_s {
|
||||
const char *rename_path;
|
||||
const char *etag;
|
||||
const char *file_id;
|
||||
struct {
|
||||
int64_t size;
|
||||
time_t modtime;
|
||||
const char *etag;
|
||||
const char *file_id;
|
||||
enum csync_instructions_e instruction;
|
||||
} other;
|
||||
|
||||
CSYNC_STATUS error_status;
|
||||
};
|
||||
typedef struct csync_tree_walk_file_s TREE_WALK_FILE;
|
||||
@@ -496,15 +490,6 @@ int csync_set_log_userdata(void *data);
|
||||
*/
|
||||
const char *csync_get_statedb_file(CSYNC *ctx);
|
||||
|
||||
/**
|
||||
* @brief Enable the creation of backup copys if files are changed on both sides
|
||||
*
|
||||
* @param ctx The csync context.
|
||||
*
|
||||
* @return 0 on success, less than 0 if an error occured.
|
||||
*/
|
||||
int csync_enable_conflictcopys(CSYNC *ctx);
|
||||
|
||||
/**
|
||||
* @brief Flag to tell csync that only a local run is intended. Call before csync_init
|
||||
*
|
||||
@@ -584,25 +569,6 @@ int csync_set_iconv_codec(const char *from);
|
||||
*/
|
||||
int csync_set_module_property(CSYNC *ctx, const char *key, void *value);
|
||||
|
||||
/**
|
||||
* @brief Callback definition for file progress callback.
|
||||
*
|
||||
* @param progress A struct containing progress information.
|
||||
*
|
||||
* @param userdata User defined data for the callback.
|
||||
*/
|
||||
typedef void (*csync_progress_callback)( CSYNC_PROGRESS *progress, void *userdata);
|
||||
|
||||
/**
|
||||
* @brief Set a progress callback.
|
||||
*
|
||||
* This callback reports about up- or download progress of a individual file
|
||||
* as well as overall progress.
|
||||
*/
|
||||
int csync_set_progress_callback( CSYNC *ctx, csync_progress_callback cb);
|
||||
|
||||
csync_progress_callback csync_get_progress_callback(CSYNC *ctx);
|
||||
|
||||
/**
|
||||
* @brief Aborts the current sync run as soon as possible. Can be called from another thread.
|
||||
*
|
||||
@@ -624,6 +590,11 @@ void csync_resume(CSYNC *ctx);
|
||||
*/
|
||||
int csync_abort_requested(CSYNC *ctx);
|
||||
|
||||
/**
|
||||
* Specify if it is allowed to read the remote tree from the DB (default to enabled)
|
||||
*/
|
||||
int csync_set_read_from_db(CSYNC* ctx, int enabled);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,235 +0,0 @@
|
||||
/*
|
||||
* libcsync -- a library to sync a directory with another
|
||||
*
|
||||
* Copyright (c) 2012 by Klaas Freitag <freitag@owncloud.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "config_csync.h"
|
||||
|
||||
#ifndef _GNU_SOURCE
|
||||
#define _GNU_SOURCE
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "csync_dbtree.h"
|
||||
#include "c_lib.h"
|
||||
#include "csync_private.h"
|
||||
#include "csync_statedb.h"
|
||||
#include "csync_util.h"
|
||||
#include "c_macro.h"
|
||||
|
||||
|
||||
#define CSYNC_LOG_CATEGORY_NAME "csync.dbtree"
|
||||
#include "csync_log.h"
|
||||
|
||||
struct dir_listing {
|
||||
c_list_t *list;
|
||||
unsigned int cnt;
|
||||
c_list_t *entry;
|
||||
char *dir;
|
||||
};
|
||||
|
||||
csync_vio_method_handle_t *csync_dbtree_opendir(CSYNC *ctx, const char *name)
|
||||
{
|
||||
|
||||
char *column = NULL;
|
||||
const char *path = NULL;
|
||||
csync_vio_file_stat_t *fs = NULL;
|
||||
unsigned int c = 0;
|
||||
c_strlist_t *list = NULL;
|
||||
struct dir_listing *listing = NULL;
|
||||
|
||||
/* "phash INTEGER(8),"
|
||||
"pathlen INTEGER,"
|
||||
"path VARCHAR(4096),"
|
||||
"inode INTEGER,"
|
||||
"uid INTEGER,"
|
||||
"gid INTEGER,"
|
||||
"mode INTEGER,"
|
||||
"modtime INTEGER(8),"
|
||||
"type INTEGER,"
|
||||
"md5 VARCHAR(32)," // That's the etag
|
||||
*/
|
||||
|
||||
int col_count = 10;
|
||||
if( strlen(name) < strlen(ctx->remote.uri)+1) {
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, "name does not contain remote uri!");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
path = name + strlen(ctx->remote.uri)+1;
|
||||
|
||||
list = csync_statedb_get_below_path(ctx, path);
|
||||
|
||||
if( ! list ) {
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, "Query result list is NULL!");
|
||||
return NULL;
|
||||
}
|
||||
/* list count must be a multiple of col_count */
|
||||
if( list->count % col_count != 0 ) {
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, "Wrong size of query result list");
|
||||
c_strlist_destroy( list );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
listing = c_malloc(sizeof(struct dir_listing));
|
||||
ZERO_STRUCTP(listing);
|
||||
if( listing == NULL ) {
|
||||
c_strlist_destroy( list );
|
||||
errno = ENOMEM;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
listing->dir = c_strdup(path);
|
||||
|
||||
for( c = 0; c < (list->count / col_count); c++) {
|
||||
int base = c*col_count;
|
||||
int cnt = 0;
|
||||
int tpath_len = 0;
|
||||
int type = 0;
|
||||
|
||||
char *tpath = list->vector[base+1];
|
||||
/* check if the result points to a file directly below the search path
|
||||
* by checking if there is another / in the result.
|
||||
* If yes, skip it.
|
||||
* FIXME: Find a better filter solution here.
|
||||
*/
|
||||
tpath += strlen(path)+1; /* jump over the search path */
|
||||
tpath_len = strlen( tpath );
|
||||
while( cnt < tpath_len ) {
|
||||
if(*(tpath+cnt) == '/') {
|
||||
/* CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG, "Skipping entry: %s", list->vector[base+1]); */
|
||||
break;
|
||||
}
|
||||
cnt++;
|
||||
}
|
||||
if( cnt < tpath_len ) continue;
|
||||
|
||||
if (!list->vector[base+8][0])
|
||||
continue; /* If etag is empty, the file was removed on the server */
|
||||
|
||||
fs = csync_vio_file_stat_new();
|
||||
fs->fields = CSYNC_VIO_FILE_STAT_FIELDS_NONE;
|
||||
|
||||
column = list->vector[base+0]; /* phash */
|
||||
|
||||
column = list->vector[base+1]; /* path */
|
||||
fs->name = c_strdup(column+strlen(path)+1);
|
||||
|
||||
column = list->vector[base+2]; /* inode */
|
||||
fs->inode = atoll(column);
|
||||
fs->fields |= CSYNC_VIO_FILE_STAT_FIELDS_INODE;
|
||||
|
||||
column = list->vector[base+3]; /* uid */
|
||||
fs->uid = atoi(column);
|
||||
fs->fields |= CSYNC_VIO_FILE_STAT_FIELDS_UID;
|
||||
|
||||
column = list->vector[base+4]; /* gid */
|
||||
fs->gid = atoi(column);
|
||||
fs->fields |= CSYNC_VIO_FILE_STAT_FIELDS_GID;
|
||||
|
||||
column = list->vector[base+5]; /* mode */
|
||||
fs->mode = atoi(column);
|
||||
// fs->fields |= CSYNC_VIO_FILE_STAT_FIELDS_M;
|
||||
|
||||
column = list->vector[base+6]; /* modtime */
|
||||
fs->mtime = strtoul(column, NULL, 10);
|
||||
fs->fields |= CSYNC_VIO_FILE_STAT_FIELDS_MTIME;
|
||||
|
||||
column = list->vector[base+7]; /* type */
|
||||
type = atoi(column);
|
||||
/* Attention: the type of csync_ftw_type_e which is the source for
|
||||
* the database entry is different from csync_vio_file_type_e which
|
||||
* is the target file type here. Mapping is needed!
|
||||
*/
|
||||
switch( type ) {
|
||||
case CSYNC_FTW_TYPE_DIR:
|
||||
fs->type = CSYNC_VIO_FILE_TYPE_DIRECTORY;
|
||||
break;
|
||||
case CSYNC_FTW_TYPE_FILE:
|
||||
fs->type = CSYNC_VIO_FILE_TYPE_REGULAR;
|
||||
break;
|
||||
case CSYNC_FTW_TYPE_SLINK:
|
||||
fs->type = CSYNC_VIO_FILE_TYPE_SYMBOLIC_LINK;
|
||||
break;
|
||||
default:
|
||||
fs->type = CSYNC_VIO_FILE_TYPE_UNKNOWN;
|
||||
}
|
||||
fs->fields |= CSYNC_VIO_FILE_STAT_FIELDS_TYPE;
|
||||
|
||||
column = list->vector[base+8]; /* etag */
|
||||
fs->etag = c_strdup(column);
|
||||
fs->fields |= CSYNC_VIO_FILE_STAT_FIELDS_ETAG;
|
||||
|
||||
column = list->vector[base+9]; /* file id */
|
||||
csync_vio_file_stat_set_file_id(fs, column);
|
||||
|
||||
/* store into result list. */
|
||||
listing->list = c_list_append( listing->list, fs );
|
||||
listing->cnt++;
|
||||
}
|
||||
|
||||
if(listing->cnt)
|
||||
listing->entry = c_list_first( listing->list );
|
||||
|
||||
c_strlist_destroy( list );
|
||||
|
||||
return listing;
|
||||
}
|
||||
|
||||
int csync_dbtree_closedir(CSYNC *ctx, csync_vio_method_handle_t *dhandle)
|
||||
{
|
||||
struct dir_listing *dl = NULL;
|
||||
int rc = 0;
|
||||
(void) ctx;
|
||||
|
||||
if( dhandle != NULL ) {
|
||||
dl = (struct dir_listing*) dhandle;
|
||||
|
||||
c_list_free(dl->list);
|
||||
SAFE_FREE(dl->dir);
|
||||
SAFE_FREE(dl);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
csync_vio_file_stat_t *csync_dbtree_readdir(CSYNC *ctx, csync_vio_method_handle_t *dhandle)
|
||||
{
|
||||
csync_vio_file_stat_t *fs = NULL;
|
||||
struct dir_listing *dl = NULL;
|
||||
(void) ctx;
|
||||
|
||||
if( dhandle != NULL ) {
|
||||
dl = (struct dir_listing*) dhandle;
|
||||
if( dl->entry != NULL ) {
|
||||
fs = (csync_vio_file_stat_t*) dl->entry->data;
|
||||
|
||||
dl->entry = c_list_next( dl->entry);
|
||||
}
|
||||
}
|
||||
|
||||
return fs;
|
||||
}
|
||||
|
||||
/* vim: set ts=8 sw=2 et cindent: */
|
||||
@@ -1,60 +0,0 @@
|
||||
/*
|
||||
* libcsync -- a library to sync a directory with another
|
||||
*
|
||||
* Copyright (c) 2012 by Klaas Freitag <freitag@owncloud.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file csync_dbtree.h
|
||||
*
|
||||
* @brief Private interface of csync
|
||||
*
|
||||
* @defgroup csyncdbtreeInternals csync statedb internals
|
||||
* @ingroup csyncInternalAPI
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _CSYNC_DBTREE_H
|
||||
#define _CSYNC_DBTREE_H
|
||||
|
||||
#include "c_lib.h"
|
||||
#include "csync_private.h"
|
||||
#include "vio/csync_vio_handle.h"
|
||||
|
||||
/**
|
||||
* @brief Open a directory based on the statedb.
|
||||
*
|
||||
* This function reads the list of files within a directory from statedb and
|
||||
* builds up a list in memory.
|
||||
*
|
||||
* @param ctx The csync context.
|
||||
* @param name The directory name.
|
||||
*
|
||||
* @return 0 on success, less than 0 if an error occured with errno set.
|
||||
*/
|
||||
csync_vio_method_handle_t *csync_dbtree_opendir(CSYNC *ctx, const char *name);
|
||||
|
||||
int csync_dbtree_closedir(CSYNC *ctx, csync_vio_method_handle_t *dhandle);
|
||||
|
||||
csync_vio_file_stat_t *csync_dbtree_readdir(CSYNC *ctx, csync_vio_method_handle_t *dhandle);
|
||||
|
||||
/**
|
||||
* }@
|
||||
*/
|
||||
#endif /* _CSYNC_DBTREE_H */
|
||||
/* vim: set ft=c.doxygen ts=8 sw=2 et cindent: */
|
||||
@@ -144,11 +144,11 @@ CSYNC_EXCLUDE_TYPE csync_excluded(CSYNC *ctx, const char *path, int filetype) {
|
||||
char *bname = NULL;
|
||||
char *dname = NULL;
|
||||
char *prev_dname = NULL;
|
||||
char *conflict = NULL;
|
||||
int rc = -1;
|
||||
CSYNC_EXCLUDE_TYPE match = CSYNC_NOT_EXCLUDED;
|
||||
CSYNC_EXCLUDE_TYPE type = CSYNC_NOT_EXCLUDED;
|
||||
|
||||
if (! ctx->options.unix_extensions) {
|
||||
for (p = path; *p; p++) {
|
||||
switch (*p) {
|
||||
case '\\':
|
||||
@@ -164,7 +164,6 @@ CSYNC_EXCLUDE_TYPE csync_excluded(CSYNC *ctx, const char *path, int filetype) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* split up the path */
|
||||
dname = c_dirname(path);
|
||||
@@ -185,8 +184,35 @@ CSYNC_EXCLUDE_TYPE csync_excluded(CSYNC *ctx, const char *path, int filetype) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
SAFE_FREE(bname);
|
||||
SAFE_FREE(dname);
|
||||
rc = csync_fnmatch(".owncloudsync.log*", bname, 0);
|
||||
if (rc == 0) {
|
||||
match = CSYNC_FILE_SILENTLY_EXCLUDED;
|
||||
SAFE_FREE(bname);
|
||||
SAFE_FREE(dname);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Always ignore conflict files, not only via the exclude list */
|
||||
rc = csync_fnmatch("*_conflict-*", bname, 0);
|
||||
if (rc == 0) {
|
||||
match = CSYNC_FILE_SILENTLY_EXCLUDED;
|
||||
SAFE_FREE(bname);
|
||||
SAFE_FREE(dname);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (getenv("CSYNC_CONFLICT_FILE_USERNAME")) {
|
||||
asprintf(&conflict, "*_conflict_%s-*", getenv("CSYNC_CONFLICT_FILE_USERNAME"));
|
||||
rc = csync_fnmatch(conflict, path, 0);
|
||||
if (rc == 0) {
|
||||
match = CSYNC_FILE_SILENTLY_EXCLUDED;
|
||||
SAFE_FREE(conflict);
|
||||
SAFE_FREE(bname);
|
||||
SAFE_FREE(dname);
|
||||
goto out;
|
||||
}
|
||||
SAFE_FREE(conflict);
|
||||
}
|
||||
|
||||
SAFE_FREE(bname);
|
||||
SAFE_FREE(dname);
|
||||
|
||||
@@ -64,27 +64,6 @@ char *csync_get_user_home_dir(void) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *csync_get_local_username(void) {
|
||||
DWORD size = 0;
|
||||
wchar_t *user;
|
||||
|
||||
/* get the size */
|
||||
GetUserName(NULL, &size);
|
||||
|
||||
user = (wchar_t *) c_malloc(2*size);
|
||||
if (user == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (GetUserName(user, &size)) {
|
||||
char *uuser = c_utf8_from_locale(user);
|
||||
SAFE_FREE(user);
|
||||
return uuser;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#else /* ************* !WIN32 ************ */
|
||||
|
||||
#ifndef NSS_BUFLEN_PASSWD
|
||||
@@ -112,27 +91,6 @@ char *csync_get_user_home_dir(void) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *csync_get_local_username(void) {
|
||||
struct passwd pwd;
|
||||
struct passwd *pwdbuf;
|
||||
char buf[NSS_BUFLEN_PASSWD];
|
||||
char *name;
|
||||
int rc;
|
||||
|
||||
rc = getpwuid_r(getuid(), &pwd, buf, NSS_BUFLEN_PASSWD, &pwdbuf);
|
||||
if (rc != 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
name = c_strdup(pwd.pw_name);
|
||||
|
||||
if (name == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
#endif /* ************* WIN32 ************ */
|
||||
|
||||
#ifdef HAVE_FNMATCH
|
||||
|
||||
@@ -36,7 +36,6 @@
|
||||
#endif
|
||||
|
||||
char *csync_get_user_home_dir(void);
|
||||
char *csync_get_local_username(void);
|
||||
|
||||
int csync_fnmatch(__const char *__pattern, __const char *__name, int __flags);
|
||||
|
||||
@@ -50,20 +49,6 @@ int csync_fnmatch(__const char *__pattern, __const char *__name, int __flags);
|
||||
*/
|
||||
CSYNC_STATUS csync_errno_to_status(int error, CSYNC_STATUS default_status);
|
||||
|
||||
struct csync_hbf_info_s {
|
||||
int start_id;
|
||||
int transfer_id;
|
||||
};
|
||||
typedef struct csync_hbf_info_s csync_hbf_info_t;
|
||||
|
||||
typedef struct {
|
||||
int64_t file_count;
|
||||
int64_t current_file_no;
|
||||
int64_t byte_sum;
|
||||
int64_t byte_current;
|
||||
} csync_overall_progress_t;
|
||||
|
||||
|
||||
char *csync_normalize_etag(const char *);
|
||||
|
||||
#endif /* _CSYNC_MISC_H */
|
||||
|
||||
@@ -60,7 +60,8 @@ struct dav_session_s dav_session; /* The DAV Session, initialised in dav_connect
|
||||
int _connected = 0; /* flag to indicate if a connection exists, ie.
|
||||
the dav_session is valid */
|
||||
|
||||
csync_auth_callback _authcb;
|
||||
|
||||
void *_userdata;
|
||||
long long chunked_total_size = 0;
|
||||
long long chunked_done = 0;
|
||||
|
||||
@@ -122,6 +123,7 @@ static int verify_sslcert(void *userdata, int failures,
|
||||
char buf[MAX(NE_SSL_DIGESTLEN, NE_ABUFSIZ)];
|
||||
int ret = -1;
|
||||
const ne_ssl_certificate *cert = certificate;
|
||||
csync_auth_callback authcb = NULL;
|
||||
|
||||
(void) userdata;
|
||||
memset( problem, 0, LEN );
|
||||
@@ -159,11 +161,14 @@ static int verify_sslcert(void *userdata, int failures,
|
||||
}
|
||||
addSSLWarning( problem, "Do you want to accept the certificate chain anyway?\nAnswer yes to do so and take the risk: ", LEN );
|
||||
|
||||
if( _authcb ){
|
||||
if( dav_session.csync_ctx ) {
|
||||
authcb = csync_get_auth_callback( dav_session.csync_ctx );
|
||||
}
|
||||
if( authcb ){
|
||||
/* call the csync callback */
|
||||
DEBUG_WEBDAV("Call the csync callback for SSL problems");
|
||||
memset( buf, 0, NE_ABUFSIZ );
|
||||
(*_authcb) ( problem, buf, NE_ABUFSIZ-1, 1, 0, NULL );
|
||||
(*authcb) ( problem, buf, NE_ABUFSIZ-1, 1, 0, _userdata );
|
||||
if( buf[0] == 'y' || buf[0] == 'Y') {
|
||||
ret = 0;
|
||||
} else {
|
||||
@@ -183,6 +188,8 @@ static int ne_auth( void *userdata, const char *realm, int attempt,
|
||||
char *username, char *password)
|
||||
{
|
||||
char buf[NE_ABUFSIZ];
|
||||
csync_auth_callback authcb = NULL;
|
||||
int re = attempt;
|
||||
|
||||
(void) userdata;
|
||||
(void) realm;
|
||||
@@ -198,24 +205,29 @@ static int ne_auth( void *userdata, const char *realm, int attempt,
|
||||
if( dav_session.pwd && strlen( dav_session.pwd ) < NE_ABUFSIZ ) {
|
||||
strcpy( password, dav_session.pwd );
|
||||
}
|
||||
} else if( _authcb != NULL ){
|
||||
/* call the csync callback */
|
||||
DEBUG_WEBDAV("Call the csync callback for %s", realm );
|
||||
memset( buf, 0, NE_ABUFSIZ );
|
||||
(*_authcb) ("Enter your username: ", buf, NE_ABUFSIZ-1, 1, 0, NULL );
|
||||
if( strlen(buf) < NE_ABUFSIZ ) {
|
||||
strcpy( username, buf );
|
||||
}
|
||||
memset( buf, 0, NE_ABUFSIZ );
|
||||
(*_authcb) ("Enter your password: ", buf, NE_ABUFSIZ-1, 0, 0, NULL );
|
||||
if( strlen(buf) < NE_ABUFSIZ) {
|
||||
strcpy( password, buf );
|
||||
}
|
||||
} else {
|
||||
DEBUG_WEBDAV("I can not authenticate!");
|
||||
if( dav_session.csync_ctx ) {
|
||||
authcb = csync_get_auth_callback( dav_session.csync_ctx );
|
||||
}
|
||||
if( authcb != NULL ){
|
||||
/* call the csync callback */
|
||||
DEBUG_WEBDAV("Call the csync callback for %s", realm );
|
||||
memset( buf, 0, NE_ABUFSIZ );
|
||||
(*authcb) ("Enter your username: ", buf, NE_ABUFSIZ-1, 1, 0, _userdata );
|
||||
if( strlen(buf) < NE_ABUFSIZ ) {
|
||||
strcpy( username, buf );
|
||||
}
|
||||
memset( buf, 0, NE_ABUFSIZ );
|
||||
(*authcb) ("Enter your password: ", buf, NE_ABUFSIZ-1, 0, 0, _userdata );
|
||||
if( strlen(buf) < NE_ABUFSIZ) {
|
||||
strcpy( password, buf );
|
||||
}
|
||||
} else {
|
||||
re = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return attempt;
|
||||
return re;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -398,6 +410,8 @@ static void pre_send_hook(ne_request *req, void *userdata,
|
||||
|
||||
if(dav_session.session_key) {
|
||||
ne_buffer_concat(header, "Cookie: ", dav_session.session_key, "\r\n", NULL);
|
||||
} else {
|
||||
DEBUG_WEBDAV("csync pre_send_hook We don't have a Auth Cookie (session_key), this is wrong!");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -480,13 +494,13 @@ static int dav_connect(const char *base_url) {
|
||||
DEBUG_WEBDAV("* port %u", port );
|
||||
DEBUG_WEBDAV("* path %s", path );
|
||||
|
||||
if( strcmp( scheme, "owncloud" ) == 0 ) {
|
||||
if( strcmp( scheme, "owncloud" ) == 0 || strcmp( scheme, "http" ) == 0 ) {
|
||||
strcpy( protocol, "http");
|
||||
} else if( strcmp( scheme, "ownclouds" ) == 0 ) {
|
||||
} else if( strcmp( scheme, "ownclouds" ) == 0 || strcmp( scheme, "https") == 0 ) {
|
||||
strcpy( protocol, "https");
|
||||
useSSL = 1;
|
||||
} else {
|
||||
DEBUG_WEBDAV("Invalid scheme %s, go outa here!", scheme );
|
||||
DEBUG_WEBDAV("Invalid scheme %s, go out here!", scheme );
|
||||
rc = -1;
|
||||
goto out;
|
||||
}
|
||||
@@ -497,15 +511,6 @@ static int dav_connect(const char *base_url) {
|
||||
port = ne_uri_defaultport(protocol);
|
||||
}
|
||||
|
||||
#if 0
|
||||
rc = ne_sock_init();
|
||||
DEBUG_WEBDAV("ne_sock_init: %d", rc );
|
||||
if (rc < 0) {
|
||||
rc = -1;
|
||||
goto out;
|
||||
}
|
||||
#endif
|
||||
|
||||
dav_session.ctx = ne_session_create( protocol, host, port);
|
||||
|
||||
if (dav_session.ctx == NULL) {
|
||||
@@ -514,10 +519,10 @@ static int dav_connect(const char *base_url) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (dav_session.read_timeout == 0)
|
||||
dav_session.read_timeout = 300; // set 300 seconds as default.
|
||||
|
||||
ne_set_read_timeout(dav_session.ctx, dav_session.read_timeout);
|
||||
if (dav_session.read_timeout != 0) {
|
||||
ne_set_read_timeout(dav_session.ctx, dav_session.read_timeout);
|
||||
DEBUG_WEBDAV("Timeout set to %u seconds", dav_session.read_timeout );
|
||||
}
|
||||
|
||||
snprintf( uaBuf, sizeof(uaBuf), "Mozilla/5.0 (%s) csyncoC/%s",
|
||||
get_platform(), CSYNC_STRINGIFY( LIBCSYNC_VERSION ));
|
||||
@@ -690,9 +695,6 @@ static struct listdir_context *fetch_resource_list(const char *uri, int depth)
|
||||
req_status->reason_phrase);
|
||||
ret = NE_CONNECT;
|
||||
set_error_message(req_status->reason_phrase);
|
||||
oc_notify_progress( uri, CSYNC_NOTIFY_ERROR,
|
||||
req_status->code,
|
||||
(intptr_t)(req_status->reason_phrase) );
|
||||
}
|
||||
DEBUG_WEBDAV("Simple propfind result code %d.", req_status->code);
|
||||
} else {
|
||||
@@ -786,7 +788,7 @@ static void fill_stat_cache( csync_vio_file_stat_t *lfs ) {
|
||||
/*
|
||||
* file functions
|
||||
*/
|
||||
static int owncloud_stat(const char *uri, csync_vio_file_stat_t *buf) {
|
||||
int owncloud_stat(const char *uri, csync_vio_file_stat_t *buf) {
|
||||
/* get props:
|
||||
* modtime
|
||||
* creattime
|
||||
@@ -798,8 +800,6 @@ static int owncloud_stat(const char *uri, csync_vio_file_stat_t *buf) {
|
||||
int len = 0;
|
||||
errno = 0;
|
||||
|
||||
DEBUG_WEBDAV("owncloud_stat %s called", uri );
|
||||
|
||||
buf->name = c_basename(uri);
|
||||
|
||||
if (buf->name == NULL) {
|
||||
@@ -891,95 +891,19 @@ static int owncloud_stat(const char *uri, csync_vio_file_stat_t *buf) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* capabilities are currently:
|
||||
* bool atomar_copy_support - oC provides atomar copy
|
||||
* bool do_post_copy_stat - oC does not want the post copy check
|
||||
* bool time_sync_required - oC does not require the time sync
|
||||
* int unix_extensions - oC supports unix extensions.
|
||||
* bool propagate_on_fd - oC supports the send_file method.
|
||||
*/
|
||||
static csync_vio_capabilities_t _owncloud_capabilities = { true, false, false, 0, true, false, false };
|
||||
|
||||
static csync_vio_capabilities_t *owncloud_capabilities(void)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
_owncloud_capabilities.unix_extensions = 0;
|
||||
#endif
|
||||
return &_owncloud_capabilities;
|
||||
}
|
||||
|
||||
static const char* owncloud_get_etag( const char *path )
|
||||
{
|
||||
ne_request *req = NULL;
|
||||
const char *header = NULL;
|
||||
char *uri = _cleanPath(path);
|
||||
char *cbuf = NULL;
|
||||
csync_vio_file_stat_t *fs = NULL;
|
||||
bool doHeadRequest = false;
|
||||
|
||||
if (_id_cache.uri && c_streq(path, _id_cache.uri)) {
|
||||
header = _id_cache.id;
|
||||
}
|
||||
|
||||
doHeadRequest= false; /* ownCloud server doesn't have good support for HEAD yet */
|
||||
|
||||
if( !header && doHeadRequest ) {
|
||||
int neon_stat;
|
||||
/* Perform an HEAD request to the resource. HEAD delivers the
|
||||
* ETag header back. */
|
||||
req = ne_request_create(dav_session.ctx, "HEAD", uri);
|
||||
neon_stat = ne_request_dispatch(req);
|
||||
set_errno_from_neon_errcode( neon_stat );
|
||||
|
||||
header = ne_get_response_header(req, "etag");
|
||||
}
|
||||
/* If the request went wrong or the server did not respond correctly
|
||||
* (that can happen for collections) a stat call is done which translates
|
||||
* into a PROPFIND request.
|
||||
*/
|
||||
if( ! header ) {
|
||||
/* ... and do a stat call. */
|
||||
fs = csync_vio_file_stat_new();
|
||||
if(fs == NULL) {
|
||||
DEBUG_WEBDAV( "owncloud_get_etag: memory fault.");
|
||||
errno = ENOMEM;
|
||||
return NULL;
|
||||
}
|
||||
if( owncloud_stat( path, fs ) == 0 ) {
|
||||
header = fs->etag;
|
||||
}
|
||||
}
|
||||
|
||||
/* In case the result is surrounded by "" cut them away. */
|
||||
if( header ) {
|
||||
cbuf = csync_normalize_etag(header);
|
||||
}
|
||||
|
||||
/* fix server problem: If we end up with an empty string, set something strange... */
|
||||
if( c_streq(cbuf, "") || c_streq(cbuf, "\"\"") ) {
|
||||
SAFE_FREE(cbuf);
|
||||
cbuf = c_strdup("empty_etag");
|
||||
}
|
||||
|
||||
DEBUG_WEBDAV("Get file ID for %s: %s", path, cbuf ? cbuf:"<null>");
|
||||
if( fs ) csync_vio_file_stat_destroy(fs);
|
||||
if( req ) ne_request_destroy(req);
|
||||
SAFE_FREE(uri);
|
||||
|
||||
|
||||
return cbuf;
|
||||
}
|
||||
|
||||
/*
|
||||
* directory functions
|
||||
*/
|
||||
static csync_vio_method_handle_t *owncloud_opendir(const char *uri) {
|
||||
csync_vio_handle_t *owncloud_opendir(const char *uri) {
|
||||
struct listdir_context *fetchCtx = NULL;
|
||||
char *curi = NULL;
|
||||
|
||||
DEBUG_WEBDAV("opendir method called on %s", uri );
|
||||
|
||||
dav_connect( uri );
|
||||
if (dav_connect( uri ) < 0) {
|
||||
DEBUG_WEBDAV("connection failed");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
curi = _cleanPath( uri );
|
||||
if (is_first_propfind && !dav_session.no_recursive_propfind) {
|
||||
@@ -1011,21 +935,23 @@ static csync_vio_method_handle_t *owncloud_opendir(const char *uri) {
|
||||
/* no freeing of curi because its part of the fetchCtx and gets freed later */
|
||||
}
|
||||
|
||||
static int owncloud_closedir(csync_vio_method_handle_t *dhandle) {
|
||||
int owncloud_closedir(csync_vio_handle_t *dhandle) {
|
||||
|
||||
struct listdir_context *fetchCtx = dhandle;
|
||||
|
||||
DEBUG_WEBDAV("closedir method called %p!", dhandle);
|
||||
|
||||
free_fetchCtx(fetchCtx);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static csync_vio_file_stat_t *owncloud_readdir(csync_vio_method_handle_t *dhandle) {
|
||||
|
||||
csync_vio_file_stat_t *owncloud_readdir(csync_vio_handle_t *dhandle) {
|
||||
struct listdir_context *fetchCtx = dhandle;
|
||||
|
||||
// DEBUG_WEBDAV("owncloud_readdir" );
|
||||
// DEBUG_WEBDAV("owncloud_readdir %s ", fetchCtx->target);
|
||||
// DEBUG_WEBDAV("owncloud_readdir %d", fetchCtx->result_count );
|
||||
// DEBUG_WEBDAV("owncloud_readdir %p %p", fetchCtx->currResource, fetchCtx->list );
|
||||
|
||||
if( fetchCtx == NULL) {
|
||||
/* DEBUG_WEBDAV("An empty dir or at end"); */
|
||||
return NULL;
|
||||
@@ -1058,17 +984,19 @@ static csync_vio_file_stat_t *owncloud_readdir(csync_vio_method_handle_t *dhandl
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static char *owncloud_error_string()
|
||||
char *owncloud_error_string(void)
|
||||
{
|
||||
return dav_session.error_string;
|
||||
}
|
||||
|
||||
static int owncloud_commit() {
|
||||
int owncloud_commit(void) {
|
||||
|
||||
clean_caches();
|
||||
|
||||
if( dav_session.ctx )
|
||||
ne_session_destroy( dav_session.ctx );
|
||||
if( dav_session.ctx ) {
|
||||
ne_forget_auth(dav_session.ctx);
|
||||
ne_session_destroy( dav_session.ctx );
|
||||
}
|
||||
/* DEBUG_WEBDAV( "********** vio_module_shutdown" ); */
|
||||
|
||||
dav_session.ctx = 0;
|
||||
@@ -1084,7 +1012,7 @@ static int owncloud_commit() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int owncloud_set_property(const char *key, void *data) {
|
||||
int owncloud_set_property(const char *key, void *data) {
|
||||
#define READ_STRING_PROPERTY(P) \
|
||||
if (c_streq(key, #P)) { \
|
||||
SAFE_FREE(dav_session.P); \
|
||||
@@ -1110,10 +1038,6 @@ static int owncloud_set_property(const char *key, void *data) {
|
||||
dav_session.csync_ctx = data;
|
||||
return 0;
|
||||
}
|
||||
if( c_streq(key, "hbf_info")) {
|
||||
dav_session.chunk_info = (csync_hbf_info_t *)(data);
|
||||
return 0;
|
||||
}
|
||||
if( c_streq(key, "get_dav_session")) {
|
||||
/* Give the ne_session to the caller */
|
||||
*(ne_session**)data = dav_session.ctx;
|
||||
@@ -1123,25 +1047,6 @@ static int owncloud_set_property(const char *key, void *data) {
|
||||
dav_session.no_recursive_propfind = *(bool*)(data);
|
||||
return 0;
|
||||
}
|
||||
if( c_streq(key, "hbf_block_size")) {
|
||||
dav_session.hbf_block_size = *(int64_t*)(data);
|
||||
return 0;
|
||||
}
|
||||
if( c_streq(key, "hbf_threshold")) {
|
||||
dav_session.hbf_threshold = *(int64_t*)(data);
|
||||
return 0;
|
||||
}
|
||||
if( c_streq(key, "bandwidth_limit_upload")) {
|
||||
dav_session.bandwidth_limit_upload = *(int*)(data);
|
||||
return 0;
|
||||
}
|
||||
if( c_streq(key, "bandwidth_limit_download")) {
|
||||
dav_session.bandwidth_limit_download = *(int*)(data);
|
||||
return 0;
|
||||
}
|
||||
if( c_streq(key, "overall_progress_data")) {
|
||||
dav_session.overall_progress_data = (csync_overall_progress_t*)(data);
|
||||
}
|
||||
if( c_streq(key, "redirect_callback")) {
|
||||
if (data) {
|
||||
csync_owncloud_redirect_callback_t* cb_wrapper = data;
|
||||
@@ -1155,55 +1060,15 @@ static int owncloud_set_property(const char *key, void *data) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
csync_vio_method_t _method = {
|
||||
.method_table_size = sizeof(csync_vio_method_t),
|
||||
.get_capabilities = owncloud_capabilities,
|
||||
.get_etag = owncloud_get_etag,
|
||||
.open = 0,
|
||||
.creat = 0,
|
||||
.close = 0,
|
||||
.read = 0,
|
||||
.write = 0,
|
||||
.sendfile = 0,
|
||||
.lseek = 0,
|
||||
.opendir = owncloud_opendir,
|
||||
.closedir = owncloud_closedir,
|
||||
.readdir = owncloud_readdir,
|
||||
.mkdir = 0,
|
||||
.rmdir = 0,
|
||||
.stat = owncloud_stat,
|
||||
.rename = 0,
|
||||
.unlink = 0,
|
||||
.chmod = 0,
|
||||
.chown = 0,
|
||||
.utimes = 0,
|
||||
.set_property = owncloud_set_property,
|
||||
.get_error_string = owncloud_error_string,
|
||||
.commit = owncloud_commit
|
||||
void owncloud_init(void *userdata) {
|
||||
|
||||
};
|
||||
|
||||
csync_vio_method_t *vio_module_init(const char *method_name, const char *args,
|
||||
csync_auth_callback cb, void *userdata) {
|
||||
(void) method_name;
|
||||
(void) args;
|
||||
(void) userdata;
|
||||
|
||||
_authcb = cb;
|
||||
_userdata = userdata;
|
||||
_connected = 0; /* triggers dav_connect to go through the whole neon setup */
|
||||
|
||||
memset(&dav_session, 0, sizeof(dav_session));
|
||||
|
||||
/* Disable it, Mirall can enable it for the first sync (= no DB)*/
|
||||
dav_session.no_recursive_propfind = true;
|
||||
|
||||
return &_method;
|
||||
}
|
||||
|
||||
void vio_module_shutdown(csync_vio_method_t *method) {
|
||||
(void) method;
|
||||
|
||||
/* DEBUG_WEBDAV( "********** vio_module_shutdown" ); */
|
||||
}
|
||||
|
||||
/* vim: set ts=4 sw=4 et cindent: */
|
||||
|
||||
@@ -56,7 +56,6 @@
|
||||
#include "c_private.h"
|
||||
#include "httpbf.h"
|
||||
|
||||
#include "vio/csync_vio_module.h"
|
||||
#include "vio/csync_vio_file_stat.h"
|
||||
#include "vio/csync_vio.h"
|
||||
|
||||
@@ -138,17 +137,8 @@ struct dav_session_s {
|
||||
|
||||
CSYNC *csync_ctx;
|
||||
|
||||
csync_hbf_info_t *chunk_info;
|
||||
|
||||
bool no_recursive_propfind;
|
||||
int64_t hbf_block_size;
|
||||
int64_t hbf_threshold;
|
||||
|
||||
/* If 0, it is disabled. If >0, in Byte/seconds. If < 0, in % of the available bandwidth*/
|
||||
int bandwidth_limit_upload;
|
||||
int bandwidth_limit_download;
|
||||
|
||||
csync_overall_progress_t *overall_progress_data;
|
||||
csync_owncloud_redirect_callback_t redir_callback;
|
||||
};
|
||||
extern struct dav_session_s dav_session;
|
||||
@@ -176,6 +166,14 @@ char *_cleanPath( const char* uri );
|
||||
int _stat_perms( int type );
|
||||
csync_vio_file_stat_t *resourceToFileStat( struct resource *res );
|
||||
|
||||
void oc_notify_progress(const char *file, enum csync_notify_type_e kind, int64_t current_size, int64_t full_size);
|
||||
// Public API from vio
|
||||
csync_vio_handle_t *owncloud_opendir(const char *uri);
|
||||
csync_vio_file_stat_t *owncloud_readdir(csync_vio_handle_t *dhandle);
|
||||
int owncloud_closedir(csync_vio_handle_t *dhandle);
|
||||
int owncloud_stat(const char *uri, csync_vio_file_stat_t *buf);
|
||||
int owncloud_commit(void);
|
||||
char *owncloud_error_string(void);
|
||||
void owncloud_init(void *userdata);
|
||||
int owncloud_set_property(const char *key, void *data);
|
||||
|
||||
#endif /* CSYNC_OWNCLOUD_H */
|
||||
|
||||
@@ -273,7 +273,6 @@ void fetch_resource_list_recursive(const char *uri, const char *curi)
|
||||
req_status->reason_phrase);
|
||||
ret = NE_CONNECT;
|
||||
set_error_message(req_status->reason_phrase);
|
||||
oc_notify_progress(uri, CSYNC_NOTIFY_ERROR, req_status->code, (intptr_t)(req_status->reason_phrase));
|
||||
}
|
||||
DEBUG_WEBDAV("Recursive propfind result code %d.", req_status ? req_status->code : 0);
|
||||
} else {
|
||||
|
||||
@@ -339,28 +339,3 @@ int _stat_perms( int type ) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
void oc_notify_progress(const char *file, enum csync_notify_type_e kind, int64_t current_size, int64_t full_size)
|
||||
{
|
||||
csync_progress_callback progress_cb = csync_get_progress_callback(dav_session.csync_ctx);
|
||||
|
||||
csync_overall_progress_t overall_progress;
|
||||
ZERO_STRUCT(overall_progress);
|
||||
|
||||
if( dav_session.overall_progress_data) {
|
||||
overall_progress = *dav_session.overall_progress_data;
|
||||
}
|
||||
|
||||
if (progress_cb) {
|
||||
CSYNC_PROGRESS progress;
|
||||
progress.kind = kind;
|
||||
progress.path = file;
|
||||
progress.curr_bytes = current_size;
|
||||
progress.file_size = full_size;
|
||||
progress.overall_transmission_size = overall_progress.byte_sum;
|
||||
progress.current_overall_bytes = overall_progress.byte_current+current_size;
|
||||
progress.overall_file_count = overall_progress.file_count;
|
||||
progress.current_file_no = overall_progress.current_file_no;
|
||||
|
||||
progress_cb(&progress, csync_get_userdata(dav_session.csync_ctx));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,8 +37,8 @@
|
||||
#include <sqlite3.h>
|
||||
|
||||
#include "config_csync.h"
|
||||
#include "c_lib.h"
|
||||
#include "c_private.h"
|
||||
#include "std/c_lib.h"
|
||||
#include "std/c_private.h"
|
||||
#include "csync.h"
|
||||
#include "csync_misc.h"
|
||||
#include "vio/csync_vio_file_stat.h"
|
||||
@@ -54,7 +54,6 @@
|
||||
#include <sys/iconv.h>
|
||||
#endif
|
||||
|
||||
#include "vio/csync_vio_method.h"
|
||||
#include "csync_macros.h"
|
||||
|
||||
/**
|
||||
@@ -97,7 +96,6 @@ typedef struct csync_file_stat_s csync_file_stat_t;
|
||||
struct csync_s {
|
||||
struct {
|
||||
csync_auth_callback auth_function;
|
||||
csync_progress_callback progress_cb;
|
||||
void *userdata;
|
||||
} callbacks;
|
||||
c_strlist_t *excludes;
|
||||
@@ -107,6 +105,10 @@ struct csync_s {
|
||||
sqlite3 *db;
|
||||
int exists;
|
||||
int disabled;
|
||||
|
||||
sqlite3_stmt* by_hash_stmt;
|
||||
sqlite3_stmt* by_fileid_stmt;
|
||||
sqlite3_stmt* by_inode_stmt;
|
||||
} statedb;
|
||||
|
||||
struct {
|
||||
@@ -127,18 +129,8 @@ struct csync_s {
|
||||
} remote;
|
||||
|
||||
struct {
|
||||
csync_vio_method_t *method;
|
||||
csync_vio_method_finish_fn finish_fn;
|
||||
csync_vio_capabilities_t capabilities;
|
||||
} module;
|
||||
|
||||
struct {
|
||||
int max_depth;
|
||||
int max_time_difference;
|
||||
int sync_symbolic_links;
|
||||
int unix_extensions;
|
||||
char *config_dir;
|
||||
bool with_conflict_copys;
|
||||
bool local_only_mode;
|
||||
int timeout;
|
||||
#if defined(HAVE_ICONV) && defined(WITH_ICONV)
|
||||
@@ -151,10 +143,6 @@ struct csync_s {
|
||||
uid_t euid;
|
||||
} pwd;
|
||||
|
||||
csync_overall_progress_t overall_progress;
|
||||
|
||||
struct csync_progressinfo_s *progress_info;
|
||||
|
||||
/* replica we are currently walking */
|
||||
enum csync_replica_e current;
|
||||
|
||||
@@ -173,6 +161,7 @@ struct csync_s {
|
||||
int status;
|
||||
volatile int abort;
|
||||
void *rename_info;
|
||||
int read_from_db_disabled;
|
||||
};
|
||||
|
||||
|
||||
@@ -222,6 +211,7 @@ struct _csync_treewalk_context_s
|
||||
};
|
||||
typedef struct _csync_treewalk_context_s _csync_treewalk_context;
|
||||
|
||||
|
||||
/**
|
||||
* }@
|
||||
*/
|
||||
|
||||
@@ -35,6 +35,39 @@
|
||||
#define ACCEPTED_TIME_DIFF 5
|
||||
#define ONE_HOUR 3600
|
||||
|
||||
|
||||
/* Check if a file is ignored because one parent is ignored.
|
||||
* return the node of the ignored directoy if it's the case, or NULL if it is not ignored */
|
||||
static c_rbnode_t *_csync_check_ignored(c_rbtree_t *tree, const char *path, int pathlen) {
|
||||
uint64_t h = 0;
|
||||
c_rbnode_t *node = NULL;
|
||||
|
||||
/* compute the size of the parent directory */
|
||||
int parentlen = pathlen - 1;
|
||||
while (parentlen > 0 && path[parentlen] != '/') {
|
||||
parentlen--;
|
||||
}
|
||||
if (parentlen <= 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
h = c_jhash64((uint8_t *) path, parentlen, 0);
|
||||
node = c_rbtree_find(tree, &h);
|
||||
if (node) {
|
||||
csync_file_stat_t *n = (csync_file_stat_t*)node->data;
|
||||
if (n->instruction == CSYNC_INSTRUCTION_IGNORE) {
|
||||
/* Yes, we are ignored */
|
||||
return node;
|
||||
} else {
|
||||
/* Not ignored */
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
/* Try if the parent itself is ignored */
|
||||
return _csync_check_ignored(tree, path, parentlen);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* We merge replicas at the file level. The merged replica contains the
|
||||
* superset of files that are on the local machine and server copies of
|
||||
@@ -86,6 +119,11 @@ static int _csync_merge_algorithm_visitor(void *obj, void *data) {
|
||||
}
|
||||
SAFE_FREE(renamed_path);
|
||||
}
|
||||
if (!node) {
|
||||
/* Check if it is ignored */
|
||||
node = _csync_check_ignored(tree, cur->path, cur->pathlen);
|
||||
/* If it is ignored, other->instruction will be IGNORE so this one will also be ignored */
|
||||
}
|
||||
|
||||
/* file only found on current replica */
|
||||
if (node == NULL) {
|
||||
@@ -101,11 +139,11 @@ static int _csync_merge_algorithm_visitor(void *obj, void *data) {
|
||||
case CSYNC_INSTRUCTION_EVAL_RENAME:
|
||||
if(ctx->current == LOCAL_REPLICA ) {
|
||||
/* use the old name to find the "other" node */
|
||||
tmp = csync_statedb_get_stat_by_inode(ctx->statedb.db, cur->inode);
|
||||
tmp = csync_statedb_get_stat_by_inode(ctx, cur->inode);
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "Finding opposite temp through inode %" PRIu64 ": %s",
|
||||
cur->inode, tmp ? "true":"false");
|
||||
} else if( ctx->current == REMOTE_REPLICA ) {
|
||||
tmp = csync_statedb_get_stat_by_file_id(ctx->statedb.db, cur->file_id);
|
||||
tmp = csync_statedb_get_stat_by_file_id(ctx, cur->file_id);
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "Finding opposite temp through file ID %s: %s",
|
||||
cur->file_id, tmp ? "true":"false");
|
||||
} else {
|
||||
@@ -145,6 +183,7 @@ static int _csync_merge_algorithm_visitor(void *obj, void *data) {
|
||||
if( !c_streq(cur->file_id, "") ) {
|
||||
csync_vio_set_file_id( other->file_id, cur->file_id );
|
||||
}
|
||||
other->inode = cur->inode;
|
||||
cur->instruction = CSYNC_INSTRUCTION_NONE;
|
||||
} else if (other->instruction == CSYNC_INSTRUCTION_REMOVE) {
|
||||
other->instruction = CSYNC_INSTRUCTION_RENAME;
|
||||
@@ -153,7 +192,7 @@ static int _csync_merge_algorithm_visitor(void *obj, void *data) {
|
||||
if( !c_streq(cur->file_id, "") ) {
|
||||
csync_vio_set_file_id( other->file_id, cur->file_id );
|
||||
}
|
||||
|
||||
other->inode = cur->inode;
|
||||
cur->instruction = CSYNC_INSTRUCTION_NONE;
|
||||
} else if (other->instruction == CSYNC_INSTRUCTION_NEW) {
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "OOOO=> NEW detected in other tree!");
|
||||
@@ -185,6 +224,16 @@ static int _csync_merge_algorithm_visitor(void *obj, void *data) {
|
||||
/* file on current replica is changed or new */
|
||||
case CSYNC_INSTRUCTION_EVAL:
|
||||
case CSYNC_INSTRUCTION_NEW:
|
||||
// This operation is usually a no-op and will by default return false
|
||||
if (csync_file_locked_or_open(ctx->local.uri, cur->path)) {
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG, "[Reconciler] IGNORING file %s/%s since it is locked / open", ctx->local.uri, cur->path);
|
||||
cur->instruction = CSYNC_INSTRUCTION_ERROR;
|
||||
if (cur->error_status == CSYNC_STATUS_OK) // don't overwrite error
|
||||
cur->error_status = CYSNC_STATUS_FILE_LOCKED_OR_OPEN;
|
||||
break;
|
||||
} else {
|
||||
//CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG, "[Reconciler] not ignoring file %s/%s", ctx->local.uri, cur->path);
|
||||
}
|
||||
switch (other->instruction) {
|
||||
/* file on other replica is changed or new */
|
||||
case CSYNC_INSTRUCTION_NEW:
|
||||
@@ -197,26 +246,17 @@ static int _csync_merge_algorithm_visitor(void *obj, void *data) {
|
||||
}
|
||||
if (is_equal_files) {
|
||||
/* The files are considered equal. */
|
||||
cur->instruction = CSYNC_INSTRUCTION_UPDATED; /* update the DB */
|
||||
cur->instruction = CSYNC_INSTRUCTION_NONE;
|
||||
other->instruction = CSYNC_INSTRUCTION_NONE;
|
||||
|
||||
if( !cur->etag && other->etag ) cur->etag = c_strdup(other->etag);
|
||||
cur->should_update_etag = true; /* update DB */
|
||||
} else if(ctx->current == REMOTE_REPLICA) {
|
||||
if(ctx->options.with_conflict_copys) {
|
||||
cur->instruction = CSYNC_INSTRUCTION_CONFLICT;
|
||||
other->instruction = CSYNC_INSTRUCTION_NONE;
|
||||
} else {
|
||||
cur->instruction = CSYNC_INSTRUCTION_SYNC;
|
||||
other->instruction = CSYNC_INSTRUCTION_NONE;
|
||||
}
|
||||
} else {
|
||||
if(ctx->options.with_conflict_copys) {
|
||||
cur->instruction = CSYNC_INSTRUCTION_NONE;
|
||||
other->instruction = CSYNC_INSTRUCTION_CONFLICT;
|
||||
} else {
|
||||
cur->instruction = CSYNC_INSTRUCTION_NONE;
|
||||
other->instruction = CSYNC_INSTRUCTION_SYNC;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
@@ -53,19 +53,6 @@ struct csync_rename_s {
|
||||
std::vector<renameop> todo;
|
||||
};
|
||||
|
||||
static int _csync_rename_record(void *obj, void *data) {
|
||||
CSYNC *ctx = reinterpret_cast<CSYNC*>(data);
|
||||
csync_rename_s* d = csync_rename_s::get(ctx);
|
||||
csync_file_stat_t *st = reinterpret_cast<csync_file_stat_t *>(obj);
|
||||
|
||||
if ( st->instruction != CSYNC_INSTRUCTION_RENAME)
|
||||
return 0;
|
||||
|
||||
csync_rename_s::renameop op = { st };
|
||||
d->todo.push_back(op);
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
void csync_rename_destroy(CSYNC* ctx)
|
||||
{
|
||||
|
||||
@@ -48,9 +48,6 @@
|
||||
#include "csync_rename.h"
|
||||
|
||||
#define BUF_SIZE 16
|
||||
#define HASH_QUERY "SELECT * FROM metadata WHERE phash=?1"
|
||||
|
||||
static sqlite3_stmt* _by_hash_stmt = NULL;
|
||||
|
||||
void csync_set_statedb_exists(CSYNC *ctx, int val) {
|
||||
ctx->statedb.exists = val;
|
||||
@@ -190,13 +187,26 @@ static int _csync_statedb_is_empty(sqlite3 *db) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
static void sqlite_profile( void *x, const char* sql, sqlite3_uint64 time)
|
||||
{
|
||||
(void)x;
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG,
|
||||
"_SQL_ %s: %llu", sql, time);
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
int csync_statedb_load(CSYNC *ctx, const char *statedb, sqlite3 **pdb) {
|
||||
int rc = -1;
|
||||
int check_rc = -1;
|
||||
c_strlist_t *result = NULL;
|
||||
char *statedb_tmp = NULL;
|
||||
sqlite3 *db = NULL;
|
||||
|
||||
if( !ctx ) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* csync_statedb_check tries to open the statedb and creates it in case
|
||||
* its not there.
|
||||
*/
|
||||
@@ -208,30 +218,8 @@ int csync_statedb_load(CSYNC *ctx, const char *statedb, sqlite3 **pdb) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* We want a two phase commit for the jounal, so we create a temporary copy
|
||||
* of the database.
|
||||
* The intention is that if something goes wrong we will not loose the
|
||||
* statedb.
|
||||
*/
|
||||
rc = asprintf(&statedb_tmp, "%s.ctmp", statedb);
|
||||
if (rc < 0) {
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_NOTICE, "ERR: could not create statedb name - bail out.");
|
||||
rc = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (c_copy(statedb, statedb_tmp, 0644) < 0) {
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_NOTICE, "ERR: Failed to copy statedb -> statedb_tmp - bail out.");
|
||||
|
||||
rc = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
_csync_win32_hide_file( statedb_tmp );
|
||||
|
||||
/* Open or create the temporary database */
|
||||
if (sqlite3_open(statedb_tmp, &db) != SQLITE_OK) {
|
||||
if (sqlite3_open(statedb, &db) != SQLITE_OK) {
|
||||
const char *errmsg= sqlite3_errmsg(ctx->statedb.db);
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_NOTICE, "ERR: Failed to sqlite3 open statedb - bail out: %s.",
|
||||
errmsg ? errmsg : "<no sqlite3 errormsg>");
|
||||
@@ -239,7 +227,6 @@ int csync_statedb_load(CSYNC *ctx, const char *statedb, sqlite3 **pdb) {
|
||||
rc = -1;
|
||||
goto out;
|
||||
}
|
||||
SAFE_FREE(statedb_tmp);
|
||||
|
||||
/* If check_rc == 1 the database is new and empty as a result. */
|
||||
if ((check_rc == 1) || _csync_statedb_is_empty(db)) {
|
||||
@@ -255,327 +242,299 @@ int csync_statedb_load(CSYNC *ctx, const char *statedb, sqlite3 **pdb) {
|
||||
result = csync_statedb_query(db, "PRAGMA case_sensitive_like = ON;");
|
||||
c_strlist_destroy(result);
|
||||
|
||||
#ifndef NDEBUG
|
||||
sqlite3_profile(db, sqlite_profile, 0 );
|
||||
#endif
|
||||
*pdb = db;
|
||||
|
||||
return 0;
|
||||
out:
|
||||
sqlite3_close(db);
|
||||
SAFE_FREE(statedb_tmp);
|
||||
return rc;
|
||||
}
|
||||
|
||||
int csync_statedb_close(const char *statedb, sqlite3 *db, int jwritten) {
|
||||
char *statedb_tmp = NULL;
|
||||
mbchar_t* wstatedb_tmp = NULL;
|
||||
int csync_statedb_close(CSYNC *ctx) {
|
||||
int rc = 0;
|
||||
|
||||
mbchar_t *mb_statedb = NULL;
|
||||
if (!ctx) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* deallocate query resources */
|
||||
rc = sqlite3_finalize(_by_hash_stmt);
|
||||
_by_hash_stmt = NULL;
|
||||
|
||||
/* close the temporary database */
|
||||
sqlite3_close(db);
|
||||
|
||||
if (asprintf(&statedb_tmp, "%s.ctmp", statedb) < 0) {
|
||||
return -1;
|
||||
if( ctx->statedb.by_hash_stmt ) {
|
||||
rc = sqlite3_finalize(ctx->statedb.by_hash_stmt);
|
||||
ctx->statedb.by_hash_stmt = NULL;
|
||||
}
|
||||
|
||||
/* If we successfully synchronized, overwrite the original statedb */
|
||||
|
||||
/*
|
||||
* Check the integrity of the tmp db. If ok, overwrite the old database with
|
||||
* the tmp db.
|
||||
*/
|
||||
if (jwritten) {
|
||||
/* statedb check returns either
|
||||
* 0 : database exists and is fine
|
||||
* 1 : new database was set up
|
||||
* -1 : error.
|
||||
*/
|
||||
if (_csync_statedb_check(statedb_tmp) >= 0) {
|
||||
/* New statedb is valid. */
|
||||
mb_statedb = c_utf8_to_locale(statedb);
|
||||
|
||||
/* Move the tmp-db to the real one. */
|
||||
if (c_rename(statedb_tmp, statedb) < 0) {
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG,
|
||||
"Renaming tmp db to original db failed. (errno=%d)", errno);
|
||||
rc = -1;
|
||||
} else {
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG,
|
||||
"Successfully moved tmp db to original db.");
|
||||
}
|
||||
} else {
|
||||
mb_statedb = c_utf8_to_locale(statedb_tmp);
|
||||
_tunlink(mb_statedb);
|
||||
|
||||
/* new statedb_tmp is not integer. */
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, " ## csync tmp statedb corrupt. Original one is not replaced. ");
|
||||
rc = -1;
|
||||
}
|
||||
c_free_locale_string(mb_statedb);
|
||||
if( ctx->statedb.by_fileid_stmt ) {
|
||||
rc = sqlite3_finalize(ctx->statedb.by_fileid_stmt);
|
||||
ctx->statedb.by_fileid_stmt = NULL;
|
||||
}
|
||||
|
||||
wstatedb_tmp = c_utf8_to_locale(statedb_tmp);
|
||||
if (wstatedb_tmp) {
|
||||
_tunlink(wstatedb_tmp);
|
||||
c_free_locale_string(wstatedb_tmp);
|
||||
if( ctx->statedb.by_inode_stmt ) {
|
||||
rc = sqlite3_finalize(ctx->statedb.by_inode_stmt);
|
||||
ctx->statedb.by_inode_stmt = NULL;
|
||||
}
|
||||
|
||||
SAFE_FREE(statedb_tmp);
|
||||
sqlite3_close(ctx->statedb.db);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
// This funciton parses a line from the metadata table into the given csync_file_stat
|
||||
// structure which it is also allocating.
|
||||
// Note that this function calls laso sqlite3_step to actually get the info from db and
|
||||
// returns the sqlite return type.
|
||||
static int _csync_file_stat_from_metadata_table( csync_file_stat_t **st, sqlite3_stmt *stmt )
|
||||
{
|
||||
int rc = SQLITE_ERROR;
|
||||
int column_count;
|
||||
int len;
|
||||
|
||||
if( ! stmt ) {
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, "Fatal: Statement is NULL.");
|
||||
return SQLITE_ERROR;
|
||||
}
|
||||
|
||||
column_count = sqlite3_column_count(stmt);
|
||||
|
||||
rc = sqlite3_step(stmt);
|
||||
|
||||
if( rc == SQLITE_ROW ) {
|
||||
if(column_count > 7) {
|
||||
const char *name;
|
||||
|
||||
/* phash, pathlen, path, inode, uid, gid, mode, modtime */
|
||||
len = sqlite3_column_int(stmt, 1);
|
||||
*st = c_malloc(sizeof(csync_file_stat_t) + len + 1);
|
||||
if (*st == NULL) {
|
||||
return SQLITE_NOMEM;
|
||||
}
|
||||
/* clear the whole structure */
|
||||
ZERO_STRUCTP(*st);
|
||||
|
||||
/* The query suceeded so use the phash we pass to the function. */
|
||||
(*st)->phash = sqlite3_column_int64(stmt, 0);
|
||||
|
||||
(*st)->pathlen = sqlite3_column_int(stmt, 1);
|
||||
name = (const char*) sqlite3_column_text(stmt, 2);
|
||||
memcpy((*st)->path, (len ? name : ""), len + 1);
|
||||
(*st)->inode = sqlite3_column_int64(stmt,3);
|
||||
(*st)->uid = sqlite3_column_int(stmt, 4);
|
||||
(*st)->gid = sqlite3_column_int(stmt, 5);
|
||||
(*st)->mode = sqlite3_column_int(stmt, 6);
|
||||
(*st)->modtime = strtoul((char*)sqlite3_column_text(stmt, 7), NULL, 10);
|
||||
|
||||
if(*st && column_count > 8 ) {
|
||||
(*st)->type = sqlite3_column_int(stmt, 8);
|
||||
}
|
||||
|
||||
if(column_count > 9 && sqlite3_column_text(stmt, 9)) {
|
||||
(*st)->etag = c_strdup( (char*) sqlite3_column_text(stmt, 9) );
|
||||
}
|
||||
if(column_count > 10 && sqlite3_column_text(stmt,10)) {
|
||||
csync_vio_set_file_id((*st)->file_id, (char*) sqlite3_column_text(stmt, 10));
|
||||
}
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* caller must free the memory */
|
||||
csync_file_stat_t *csync_statedb_get_stat_by_hash(sqlite3 *db,
|
||||
csync_file_stat_t *csync_statedb_get_stat_by_hash(CSYNC *ctx,
|
||||
uint64_t phash)
|
||||
{
|
||||
csync_file_stat_t *st = NULL;
|
||||
size_t len = 0;
|
||||
int column_count = 0;
|
||||
int rc;
|
||||
|
||||
if( _by_hash_stmt == NULL ) {
|
||||
rc = sqlite3_prepare_v2(db, HASH_QUERY, strlen(HASH_QUERY), &_by_hash_stmt, NULL);
|
||||
if( rc != SQLITE_OK ) {
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, "WRN: Unable to create stmt for hash query.");
|
||||
if( !ctx ) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if( _by_hash_stmt == NULL ) {
|
||||
if( ctx->statedb.by_hash_stmt == NULL ) {
|
||||
const char *hash_query = "SELECT * FROM metadata WHERE phash=?1";
|
||||
|
||||
rc = sqlite3_prepare_v2(ctx->statedb.db, hash_query, strlen(hash_query), &ctx->statedb.by_hash_stmt, NULL);
|
||||
if( rc != SQLITE_OK ) {
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, "WRN: Unable to create stmt for hash query.");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if( ctx->statedb.by_hash_stmt == NULL ) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
column_count = sqlite3_column_count(_by_hash_stmt);
|
||||
sqlite3_bind_int64(ctx->statedb.by_hash_stmt, 1, (long long signed int)phash);
|
||||
|
||||
sqlite3_bind_int64(_by_hash_stmt, 1, (long long signed int)phash);
|
||||
rc = sqlite3_step(_by_hash_stmt);
|
||||
|
||||
if( rc == SQLITE_ROW ) {
|
||||
if(column_count > 7) {
|
||||
/* phash, pathlen, path, inode, uid, gid, mode, modtime */
|
||||
len = sqlite3_column_int(_by_hash_stmt, 1);
|
||||
st = c_malloc(sizeof(csync_file_stat_t) + len + 1);
|
||||
if (st == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
/* clear the whole structure */
|
||||
ZERO_STRUCTP(st);
|
||||
|
||||
/*
|
||||
* FIXME:
|
||||
* We use an INTEGER(8) which is signed to the phash in the sqlite3 db,
|
||||
* but the phash is an uint64_t. So for some values we get a string like
|
||||
* "1.66514565505016e+19". For such a string strtoull() returns 1.
|
||||
* phash = 1
|
||||
*
|
||||
* st->phash = strtoull(result->vector[0], NULL, 10);
|
||||
*/
|
||||
|
||||
/* The query suceeded so use the phash we pass to the function. */
|
||||
st->phash = phash;
|
||||
|
||||
st->pathlen = sqlite3_column_int(_by_hash_stmt, 1);
|
||||
memcpy(st->path, (len ? (char*) sqlite3_column_text(_by_hash_stmt, 2) : ""), len + 1);
|
||||
st->inode = sqlite3_column_int64(_by_hash_stmt,3);
|
||||
st->uid = sqlite3_column_int(_by_hash_stmt, 4);
|
||||
st->gid = sqlite3_column_int(_by_hash_stmt, 5);
|
||||
st->mode = sqlite3_column_int(_by_hash_stmt, 6);
|
||||
st->modtime = strtoul((char*)sqlite3_column_text(_by_hash_stmt, 7), NULL, 10);
|
||||
|
||||
if(st && column_count > 8 ) {
|
||||
st->type = sqlite3_column_int(_by_hash_stmt, 8);
|
||||
}
|
||||
|
||||
if(column_count > 9 && sqlite3_column_text(_by_hash_stmt, 9)) {
|
||||
st->etag = c_strdup( (char*) sqlite3_column_text(_by_hash_stmt, 9) );
|
||||
}
|
||||
if(column_count > 10 && sqlite3_column_text(_by_hash_stmt,10)) {
|
||||
csync_vio_set_file_id(st->file_id, (char*) sqlite3_column_text(_by_hash_stmt, 10));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* SQLITE_DONE says there is no further row. That's not an error. */
|
||||
if (rc != SQLITE_DONE) {
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_WARN, "sqlite hash query fail: %s", sqlite3_errmsg(db));
|
||||
}
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "No result record found for phash = %llu",
|
||||
(long long unsigned int) phash);
|
||||
SAFE_FREE(st);
|
||||
if( _csync_file_stat_from_metadata_table(&st, ctx->statedb.by_hash_stmt) < 0 ) {
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, "WRN: Could not get line from metadata!");
|
||||
}
|
||||
|
||||
sqlite3_reset(_by_hash_stmt);
|
||||
sqlite3_reset(ctx->statedb.by_hash_stmt);
|
||||
|
||||
return st;
|
||||
}
|
||||
|
||||
csync_file_stat_t *csync_statedb_get_stat_by_file_id( sqlite3 *db,
|
||||
const char *file_id ) {
|
||||
csync_file_stat_t *st = NULL;
|
||||
c_strlist_t *result = NULL;
|
||||
char *stmt = NULL;
|
||||
size_t len = 0;
|
||||
csync_file_stat_t *csync_statedb_get_stat_by_file_id(CSYNC *ctx,
|
||||
const char *file_id ) {
|
||||
csync_file_stat_t *st = NULL;
|
||||
int rc = 0;
|
||||
|
||||
if (!file_id) {
|
||||
return 0;
|
||||
}
|
||||
if (c_streq(file_id, "")) {
|
||||
return 0;
|
||||
}
|
||||
stmt = sqlite3_mprintf("SELECT * FROM metadata WHERE fileid='%q'",
|
||||
file_id);
|
||||
if (!file_id) {
|
||||
return 0;
|
||||
}
|
||||
if (c_streq(file_id, "")) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (stmt == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
if( !ctx ) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
result = csync_statedb_query(db, stmt);
|
||||
sqlite3_free(stmt);
|
||||
if (result == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
if( ctx->statedb.by_fileid_stmt == NULL ) {
|
||||
const char *query = "SELECT * FROM metadata WHERE fileid=?1";
|
||||
|
||||
if (result->count <= 6) {
|
||||
c_strlist_destroy(result);
|
||||
return NULL;
|
||||
}
|
||||
rc = sqlite3_prepare_v2(ctx->statedb.db, query, strlen(query), &ctx->statedb.by_fileid_stmt, NULL);
|
||||
if( rc != SQLITE_OK ) {
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, "WRN: Unable to create stmt for file id query.");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* phash, pathlen, path, inode, uid, gid, mode, modtime */
|
||||
len = strlen(result->vector[2]);
|
||||
st = c_malloc(sizeof(csync_file_stat_t) + len + 1);
|
||||
if (st == NULL) {
|
||||
c_strlist_destroy(result);
|
||||
return NULL;
|
||||
}
|
||||
/* clear the whole structure */
|
||||
ZERO_STRUCTP(st);
|
||||
/* bind the query value */
|
||||
sqlite3_bind_text(ctx->statedb.by_fileid_stmt, 1, file_id, -1, SQLITE_STATIC);
|
||||
|
||||
st->phash = atoll(result->vector[0]);
|
||||
st->pathlen = atoi(result->vector[1]);
|
||||
memcpy(st->path, (len ? result->vector[2] : ""), len + 1);
|
||||
st->inode = atoll(result->vector[3]);
|
||||
st->uid = atoi(result->vector[4]);
|
||||
st->gid = atoi(result->vector[5]);
|
||||
st->mode = atoi(result->vector[6]);
|
||||
st->modtime = strtoul(result->vector[7], NULL, 10);
|
||||
st->type = atoi(result->vector[8]);
|
||||
if( result->vector[9] )
|
||||
st->etag = c_strdup(result->vector[9]);
|
||||
|
||||
csync_vio_set_file_id(st->file_id, file_id);
|
||||
|
||||
c_strlist_destroy(result);
|
||||
|
||||
return st;
|
||||
}
|
||||
if( _csync_file_stat_from_metadata_table(&st, ctx->statedb.by_fileid_stmt) < 0 ) {
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, "WRN: Could not get line from metadata!");
|
||||
}
|
||||
// clear the resources used by the statement.
|
||||
sqlite3_reset(ctx->statedb.by_fileid_stmt);
|
||||
|
||||
return st;
|
||||
}
|
||||
|
||||
/* caller must free the memory */
|
||||
csync_file_stat_t *csync_statedb_get_stat_by_inode(sqlite3 *db,
|
||||
uint64_t inode) {
|
||||
csync_file_stat_t *csync_statedb_get_stat_by_inode(CSYNC *ctx,
|
||||
uint64_t inode)
|
||||
{
|
||||
csync_file_stat_t *st = NULL;
|
||||
c_strlist_t *result = NULL;
|
||||
char *stmt = NULL;
|
||||
size_t len = 0;
|
||||
int rc;
|
||||
|
||||
if (!inode) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
stmt = sqlite3_mprintf("SELECT * FROM metadata WHERE inode='%lld'",
|
||||
(long long signed int) inode);
|
||||
if (stmt == NULL) {
|
||||
if( !ctx ) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if( ctx->statedb.by_inode_stmt == NULL ) {
|
||||
const char *inode_query = "SELECT * FROM metadata WHERE inode=?1";
|
||||
|
||||
rc = sqlite3_prepare_v2(ctx->statedb.db, inode_query, strlen(inode_query), &ctx->statedb.by_inode_stmt, NULL);
|
||||
if( rc != SQLITE_OK ) {
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, "WRN: Unable to create stmt for inode query.");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if( ctx->statedb.by_inode_stmt == NULL ) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
result = csync_statedb_query(db, stmt);
|
||||
sqlite3_free(stmt);
|
||||
if (result == NULL) {
|
||||
return NULL;
|
||||
sqlite3_bind_int64(ctx->statedb.by_inode_stmt, 1, (long long signed int)inode);
|
||||
|
||||
if( _csync_file_stat_from_metadata_table(&st, ctx->statedb.by_inode_stmt) < 0 ) {
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, "WRN: Could not get line from metadata by inode!");
|
||||
}
|
||||
|
||||
if (result->count <= 6) {
|
||||
c_strlist_destroy(result);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* phash, pathlen, path, inode, uid, gid, mode, modtime */
|
||||
len = strlen(result->vector[2]);
|
||||
st = c_malloc(sizeof(csync_file_stat_t) + len + 1);
|
||||
if (st == NULL) {
|
||||
c_strlist_destroy(result);
|
||||
return NULL;
|
||||
}
|
||||
/* clear the whole structure */
|
||||
ZERO_STRUCTP(st);
|
||||
|
||||
st->phash = atoll(result->vector[0]);
|
||||
st->pathlen = atoi(result->vector[1]);
|
||||
memcpy(st->path, (len ? result->vector[2] : ""), len + 1);
|
||||
st->inode = atoll(result->vector[3]);
|
||||
st->uid = atoi(result->vector[4]);
|
||||
st->gid = atoi(result->vector[5]);
|
||||
st->mode = atoi(result->vector[6]);
|
||||
st->modtime = strtoul(result->vector[7], NULL, 10);
|
||||
st->type = atoi(result->vector[8]);
|
||||
if( result->vector[9] )
|
||||
st->etag = c_strdup(result->vector[9]);
|
||||
csync_vio_set_file_id( st->file_id, result->vector[10]);
|
||||
|
||||
c_strlist_destroy(result);
|
||||
sqlite3_reset(ctx->statedb.by_inode_stmt);
|
||||
|
||||
return st;
|
||||
}
|
||||
|
||||
/* Get the etag. (it is called unique id for legacy reason
|
||||
* and it is the field md5 in the database for legacy reason */
|
||||
char *csync_statedb_get_uniqId( CSYNC *ctx, uint64_t jHash, csync_vio_file_stat_t *buf ) {
|
||||
/* Get the etag. */
|
||||
char *csync_statedb_get_etag( CSYNC *ctx, uint64_t jHash ) {
|
||||
char *ret = NULL;
|
||||
c_strlist_t *result = NULL;
|
||||
char *stmt = NULL;
|
||||
(void)buf;
|
||||
csync_file_stat_t *fs = NULL;
|
||||
|
||||
if( !ctx ) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if( ! csync_get_statedb_exists(ctx)) return ret;
|
||||
|
||||
stmt = sqlite3_mprintf("SELECT md5, fileid FROM metadata WHERE phash='%lld'", jHash);
|
||||
|
||||
result = csync_statedb_query(ctx->statedb.db, stmt);
|
||||
sqlite3_free(stmt);
|
||||
if (result == NULL) {
|
||||
return NULL;
|
||||
fs = csync_statedb_get_stat_by_hash(ctx, jHash );
|
||||
if( fs ) {
|
||||
if( fs->etag ) {
|
||||
ret = c_strdup(fs->etag);
|
||||
}
|
||||
csync_file_stat_free(fs);
|
||||
}
|
||||
|
||||
if (result->count == 2) {
|
||||
ret = c_strdup( result->vector[0] );
|
||||
csync_vio_file_stat_set_file_id(buf, result->vector[1]);
|
||||
}
|
||||
|
||||
c_strlist_destroy(result);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
c_strlist_t *csync_statedb_get_below_path( CSYNC *ctx, const char *path ) {
|
||||
c_strlist_t *list = NULL;
|
||||
char *stmt = NULL;
|
||||
#define BELOW_PATH_QUERY "SELECT phash, pathlen, path, inode, uid, gid, mode, modtime, type, md5, fileid FROM metadata WHERE path LIKE(?)"
|
||||
|
||||
stmt = sqlite3_mprintf("SELECT phash, path, inode, uid, gid, mode, modtime, type, md5, fileid "
|
||||
"FROM metadata WHERE path LIKE('%q/%%')", path);
|
||||
if (stmt == NULL) {
|
||||
return NULL;
|
||||
int csync_statedb_get_below_path( CSYNC *ctx, const char *path ) {
|
||||
int rc;
|
||||
sqlite3_stmt *stmt = NULL;
|
||||
int64_t cnt = 0;
|
||||
char *likepath;
|
||||
int asp;
|
||||
|
||||
if( !path ) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG, "SQL: %s", stmt);
|
||||
if( !ctx ) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
list = csync_statedb_query( ctx->statedb.db, stmt );
|
||||
rc = sqlite3_prepare_v2(ctx->statedb.db, BELOW_PATH_QUERY, -1, &stmt, NULL);
|
||||
if( rc != SQLITE_OK ) {
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, "WRN: Unable to create stmt for hash query.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
sqlite3_free(stmt);
|
||||
if (stmt == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return list;
|
||||
asp = asprintf( &likepath, "%s/%%%%", path);
|
||||
if (asp < 0) {
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, "asprintf failed!");
|
||||
return -1;
|
||||
}
|
||||
|
||||
sqlite3_bind_text(stmt, 1, likepath, -1, SQLITE_STATIC);
|
||||
|
||||
cnt = 0;
|
||||
|
||||
do {
|
||||
csync_file_stat_t *st = NULL;
|
||||
|
||||
rc = _csync_file_stat_from_metadata_table( &st, stmt);
|
||||
if( st ) {
|
||||
/* store into result list. */
|
||||
if (c_rbtree_insert(ctx->remote.tree, (void *) st) < 0) {
|
||||
SAFE_FREE(st);
|
||||
ctx->status_code = CSYNC_STATUS_TREE_ERROR;
|
||||
break;
|
||||
}
|
||||
cnt++;
|
||||
}
|
||||
} while( rc == SQLITE_ROW );
|
||||
|
||||
if( rc != SQLITE_DONE ) {
|
||||
ctx->status_code = CSYNC_STATUS_TREE_ERROR;
|
||||
} else {
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG, "%ld entries read below path %s from db.", cnt, path);
|
||||
}
|
||||
sqlite3_finalize(stmt);
|
||||
SAFE_FREE(likepath);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* query the statedb, caller must free the memory */
|
||||
|
||||
@@ -33,6 +33,10 @@
|
||||
#ifndef _CSYNC_STATEDB_H
|
||||
#define _CSYNC_STATEDB_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "c_lib.h"
|
||||
#include "csync_private.h"
|
||||
|
||||
@@ -54,16 +58,15 @@ int csync_get_statedb_exists(CSYNC *ctx);
|
||||
*/
|
||||
int csync_statedb_load(CSYNC *ctx, const char *statedb, sqlite3 **pdb);
|
||||
|
||||
int csync_statedb_close(const char *statedb, sqlite3 *db, int jwritten);
|
||||
int csync_statedb_close(CSYNC *ctx);
|
||||
|
||||
csync_file_stat_t *csync_statedb_get_stat_by_hash(sqlite3 *db, uint64_t phash);
|
||||
csync_file_stat_t *csync_statedb_get_stat_by_hash(CSYNC *ctx, uint64_t phash);
|
||||
|
||||
csync_file_stat_t *csync_statedb_get_stat_by_inode(sqlite3 *db, uint64_t inode);
|
||||
csync_file_stat_t *csync_statedb_get_stat_by_inode(CSYNC *ctx, uint64_t inode);
|
||||
|
||||
csync_file_stat_t *csync_statedb_get_stat_by_file_id( sqlite3 *db,
|
||||
const char *file_id );
|
||||
csync_file_stat_t *csync_statedb_get_stat_by_file_id(CSYNC *ctx, const char *file_id);
|
||||
|
||||
char *csync_statedb_get_uniqId(CSYNC *ctx, uint64_t jHash, csync_vio_file_stat_t *buf);
|
||||
char *csync_statedb_get_etag(CSYNC *ctx, uint64_t jHash);
|
||||
|
||||
/**
|
||||
* @brief Query all files metadata inside and below a path.
|
||||
@@ -82,7 +85,7 @@ char *csync_statedb_get_uniqId(CSYNC *ctx, uint64_t jHash, csync_vio_file_stat_t
|
||||
*
|
||||
* @return A stringlist containing a multiple of 9 entries.
|
||||
*/
|
||||
c_strlist_t *csync_statedb_get_below_path(CSYNC *ctx, const char *path);
|
||||
int csync_statedb_get_below_path(CSYNC *ctx, const char *path);
|
||||
|
||||
/**
|
||||
* @brief A generic statedb query.
|
||||
@@ -116,6 +119,10 @@ typedef struct csync_progressinfo_s {
|
||||
char *error_string;
|
||||
} csync_progressinfo_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* }@
|
||||
*/
|
||||
|
||||
@@ -62,115 +62,4 @@ int csync_gettime(struct timespec *tp)
|
||||
|
||||
#undef CSYNC_CLOCK
|
||||
|
||||
/* check time difference between the replicas */
|
||||
time_t csync_timediff(CSYNC *ctx) {
|
||||
time_t timediff = -1;
|
||||
char errbuf[256] = {0};
|
||||
char *luri = NULL;
|
||||
char *ruri = NULL;
|
||||
csync_vio_handle_t *fp = NULL;
|
||||
csync_vio_file_stat_t *st = NULL;
|
||||
csync_vio_handle_t *dp = NULL;
|
||||
|
||||
/* try to open remote dir to get auth */
|
||||
ctx->replica = ctx->remote.type;
|
||||
dp = csync_vio_opendir(ctx, ctx->remote.uri);
|
||||
if (dp == NULL) {
|
||||
/*
|
||||
* To prevent problems especially with pam_csync we shouldn't try to create the
|
||||
* remote directory here. Just fail!
|
||||
*/
|
||||
C_STRERROR(errno, errbuf, sizeof(errbuf));
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_FATAL,
|
||||
"Access dienied to remote uri: %s - %s",
|
||||
ctx->remote.uri,
|
||||
errbuf);
|
||||
ctx->status_code = CSYNC_STATUS_REMOTE_ACCESS_ERROR;
|
||||
return -1;
|
||||
}
|
||||
csync_vio_closedir(ctx, dp);
|
||||
|
||||
if (asprintf(&luri, "%s/.csync_timediff.ctmp", ctx->local.uri) < 0) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (asprintf(&ruri, "%s/.csync_timediff.ctmp", ctx->remote.uri) < 0) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* create temporary file on local */
|
||||
ctx->replica = ctx->local.type;
|
||||
fp = csync_vio_creat(ctx, luri, 0644);
|
||||
if (fp == NULL) {
|
||||
C_STRERROR(errno, errbuf, sizeof(errbuf));
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_FATAL,
|
||||
"Unable to create temporary file: %s - %s",
|
||||
luri,
|
||||
errbuf);
|
||||
ctx->status_code = CSYNC_STATUS_LOCAL_CREATE_ERROR;
|
||||
goto out;
|
||||
}
|
||||
csync_vio_close(ctx, fp);
|
||||
|
||||
/* Get the modification time */
|
||||
st = csync_vio_file_stat_new();
|
||||
if (csync_vio_stat(ctx, luri, st) < 0) {
|
||||
C_STRERROR(errno, errbuf, sizeof(errbuf));
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_FATAL,
|
||||
"Synchronisation is not possible! %s - %s",
|
||||
luri,
|
||||
errbuf);
|
||||
ctx->status_code = CSYNC_STATUS_LOCAL_STAT_ERROR;
|
||||
goto out;
|
||||
}
|
||||
timediff = st->mtime;
|
||||
csync_vio_file_stat_destroy(st);
|
||||
st = NULL;
|
||||
|
||||
/* create temporary file on remote replica */
|
||||
ctx->replica = ctx->remote.type;
|
||||
|
||||
fp = csync_vio_creat(ctx, ruri, 0644);
|
||||
if (fp == NULL) {
|
||||
C_STRERROR(errno, errbuf, sizeof(errbuf));
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_FATAL,
|
||||
"Unable to create temporary file: %s - %s",
|
||||
ruri,
|
||||
errbuf);
|
||||
ctx->status_code = CSYNC_STATUS_REMOTE_CREATE_ERROR;
|
||||
goto out;
|
||||
}
|
||||
csync_vio_close(ctx, fp);
|
||||
|
||||
/* Get the modification time */
|
||||
st = csync_vio_file_stat_new();
|
||||
if (csync_vio_stat(ctx, ruri, st) < 0) {
|
||||
C_STRERROR(errno, errbuf, sizeof(errbuf));
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_FATAL,
|
||||
"Synchronisation is not possible! %s - %s",
|
||||
ruri,
|
||||
errbuf);
|
||||
ctx->status_code = CSYNC_STATUS_REMOTE_STAT_ERROR;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* calc time difference */
|
||||
timediff = llabs(timediff - st->mtime);
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG, "Time difference: %ld seconds", timediff);
|
||||
|
||||
out:
|
||||
csync_vio_file_stat_destroy(st);
|
||||
|
||||
ctx->replica = ctx->local.type;
|
||||
csync_vio_unlink(ctx, luri);
|
||||
SAFE_FREE(luri);
|
||||
|
||||
ctx->replica = ctx->remote.type;
|
||||
csync_vio_unlink(ctx, ruri);
|
||||
SAFE_FREE(ruri);
|
||||
|
||||
return timediff;
|
||||
}
|
||||
|
||||
|
||||
/* vim: set ts=8 sw=2 et cindent: */
|
||||
|
||||
@@ -26,6 +26,5 @@
|
||||
#include "csync_private.h"
|
||||
|
||||
int csync_gettime(struct timespec *tp);
|
||||
time_t csync_timediff(CSYNC *ctx);
|
||||
|
||||
#endif /* _CSYNC_TIME_H */
|
||||
|
||||
@@ -79,6 +79,26 @@ static uint64_t _hash_of_file(CSYNC *ctx, const char *file) {
|
||||
return h;
|
||||
}
|
||||
|
||||
#ifdef NO_RENAME_EXTENSION
|
||||
/* Return true if the two path have the same extension. false otherwise. */
|
||||
static bool _csync_sameextension(const char *p1, const char *p2) {
|
||||
/* Find pointer to the extensions */
|
||||
const char *e1 = strrchr(p1, '.');
|
||||
const char *e2 = strrchr(p2, '.');
|
||||
|
||||
/* If the found extension contains a '/', it is because the . was in the folder name
|
||||
* => no extensions */
|
||||
if (e1 && strchr(e1, '/')) e1 = NULL;
|
||||
if (e2 && strchr(e2, '/')) e2 = NULL;
|
||||
|
||||
/* If none have extension, it is the same extension */
|
||||
if (!e1 && !e2)
|
||||
return true;
|
||||
|
||||
/* c_streq takes care of the rest */
|
||||
return c_streq(e1, e2);
|
||||
}
|
||||
#endif
|
||||
|
||||
static int _csync_detect_update(CSYNC *ctx, const char *file,
|
||||
const csync_vio_file_stat_t *fs, const int type) {
|
||||
@@ -154,8 +174,6 @@ static int _csync_detect_update(CSYNC *ctx, const char *file,
|
||||
ctx->status_code = CSYNC_STATUS_MEMORY_ERROR;
|
||||
return -1;
|
||||
}
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "==> file: %s - hash %llu, mtime: %llu, fileId: %s",
|
||||
path, (unsigned long long ) h, (unsigned long long) fs->mtime, fs->file_id);
|
||||
|
||||
/* Set instruction by default to none */
|
||||
st->instruction = CSYNC_INSTRUCTION_NONE;
|
||||
@@ -170,7 +188,7 @@ static int _csync_detect_update(CSYNC *ctx, const char *file,
|
||||
}
|
||||
|
||||
if (fs->mtime == 0) {
|
||||
tmp = csync_statedb_get_stat_by_hash(ctx->statedb.db, h);
|
||||
tmp = csync_statedb_get_stat_by_hash(ctx, h);
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "file: %s - mtime is zero!", path);
|
||||
if (tmp == NULL) {
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "file: %s - not found in db, IGNORE!", path);
|
||||
@@ -206,7 +224,7 @@ static int _csync_detect_update(CSYNC *ctx, const char *file,
|
||||
* does not change on rename.
|
||||
*/
|
||||
if (csync_get_statedb_exists(ctx)) {
|
||||
tmp = csync_statedb_get_stat_by_hash(ctx->statedb.db, h);
|
||||
tmp = csync_statedb_get_stat_by_hash(ctx, h);
|
||||
|
||||
if(tmp && tmp->phash == h ) { /* there is an entry in the database */
|
||||
/* we have an update! */
|
||||
@@ -237,19 +255,30 @@ static int _csync_detect_update(CSYNC *ctx, const char *file,
|
||||
goto out;
|
||||
}
|
||||
if (type == CSYNC_FTW_TYPE_DIR && ctx->current == REMOTE_REPLICA
|
||||
&& c_streq(fs->file_id, tmp->file_id)) {
|
||||
&& c_streq(fs->file_id, tmp->file_id) && !ctx->read_from_db_disabled) {
|
||||
/* If both etag and file id are equal for a directory, read all contents from
|
||||
* the database. */
|
||||
* the database.
|
||||
* The comparison of file id ensure that we fetch all the file id when upgrading from
|
||||
* owncloud 5 to owncloud 6.
|
||||
*/
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "Reading from database: %s", path);
|
||||
ctx->remote.read_from_db = true;
|
||||
}
|
||||
|
||||
if (!c_streq(fs->file_id, tmp->file_id) && ctx->current == REMOTE_REPLICA) {
|
||||
/* file id has changed. Which means we need to update the DB.
|
||||
* (upgrade from owncloud 5 to owncloud 6 for instence) */
|
||||
st->should_update_etag = true;
|
||||
}
|
||||
st->instruction = CSYNC_INSTRUCTION_NONE;
|
||||
} else {
|
||||
enum csync_vio_file_type_e tmp_vio_type = CSYNC_VIO_FILE_TYPE_UNKNOWN;
|
||||
|
||||
/* check if it's a file and has been renamed */
|
||||
if (ctx->current == LOCAL_REPLICA) {
|
||||
tmp = csync_statedb_get_stat_by_inode(ctx->statedb.db, fs->inode);
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "Checking for rename based on inode # %" PRId64 "", (uint64_t) fs->inode);
|
||||
|
||||
tmp = csync_statedb_get_stat_by_inode(ctx, fs->inode);
|
||||
|
||||
/* translate the file type between the two stat types csync has. */
|
||||
if( tmp && tmp->type == 0 ) {
|
||||
@@ -261,8 +290,12 @@ static int _csync_detect_update(CSYNC *ctx, const char *file,
|
||||
}
|
||||
|
||||
if (tmp && tmp->inode == fs->inode && tmp_vio_type == fs->type
|
||||
&& (tmp->modtime == fs->mtime || fs->type == CSYNC_VIO_FILE_TYPE_DIRECTORY)) {
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "inodes: %" PRId64 " <-> %" PRId64, (uint64_t) tmp->inode, (uint64_t) fs->inode);
|
||||
&& (tmp->modtime == fs->mtime || fs->type == CSYNC_VIO_FILE_TYPE_DIRECTORY)
|
||||
#ifdef NO_RENAME_EXTENSION
|
||||
&& _csync_sameextension(tmp->path, path)
|
||||
#endif
|
||||
) {
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "pot rename detected based on inode # %" PRId64 "", (uint64_t) fs->inode);
|
||||
/* inode found so the file has been renamed */
|
||||
st->instruction = CSYNC_INSTRUCTION_EVAL_RENAME;
|
||||
if (fs->type == CSYNC_VIO_FILE_TYPE_DIRECTORY) {
|
||||
@@ -276,7 +309,7 @@ static int _csync_detect_update(CSYNC *ctx, const char *file,
|
||||
}
|
||||
} else {
|
||||
/* Remote Replica Rename check */
|
||||
tmp = csync_statedb_get_stat_by_file_id(ctx->statedb.db, fs->file_id);
|
||||
tmp = csync_statedb_get_stat_by_file_id(ctx, fs->file_id);
|
||||
if(tmp ) { /* tmp existing at all */
|
||||
if ((tmp->type == CSYNC_FTW_TYPE_DIR && fs->type != CSYNC_VIO_FILE_TYPE_DIRECTORY) ||
|
||||
(tmp->type == CSYNC_FTW_TYPE_FILE && fs->type != CSYNC_VIO_FILE_TYPE_REGULAR)) {
|
||||
@@ -383,11 +416,11 @@ int csync_walker(CSYNC *ctx, const char *file, const csync_vio_file_stat_t *fs,
|
||||
|
||||
switch (flag) {
|
||||
case CSYNC_FTW_FLAG_FILE:
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "file: %s", file);
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "file: %s [file_id=%s]", file, fs->file_id);
|
||||
type = CSYNC_FTW_TYPE_FILE;
|
||||
break;
|
||||
case CSYNC_FTW_FLAG_DIR: /* enter directory */
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "directory: %s", file);
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "directory: %s [file_id=%s]", file, fs->file_id);
|
||||
type = CSYNC_FTW_TYPE_DIR;
|
||||
break;
|
||||
case CSYNC_FTW_FLAG_NSTAT: /* not statable file */
|
||||
@@ -397,7 +430,7 @@ int csync_walker(CSYNC *ctx, const char *file, const csync_vio_file_stat_t *fs,
|
||||
if( h == 0 ) {
|
||||
return 0;
|
||||
}
|
||||
st = csync_statedb_get_stat_by_hash(ctx->statedb.db, h);
|
||||
st = csync_statedb_get_stat_by_hash(ctx, h);
|
||||
if( !st ) {
|
||||
return 0;
|
||||
}
|
||||
@@ -423,10 +456,28 @@ int csync_walker(CSYNC *ctx, const char *file, const csync_vio_file_stat_t *fs,
|
||||
return rc;
|
||||
}
|
||||
|
||||
static bool fill_tree_from_db(CSYNC *ctx, const char *uri)
|
||||
{
|
||||
const char *path = NULL;
|
||||
|
||||
if( strlen(uri) < strlen(ctx->remote.uri)+1) {
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, "name does not contain remote uri!");
|
||||
return false;
|
||||
}
|
||||
|
||||
path = uri + strlen(ctx->remote.uri)+1;
|
||||
|
||||
if( csync_statedb_get_below_path(ctx, path) < 0 ) {
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, "StateDB could not be read!");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* File tree walker */
|
||||
int csync_ftw(CSYNC *ctx, const char *uri, csync_walker_fn fn,
|
||||
unsigned int depth) {
|
||||
char errbuf[256] = {0};
|
||||
char *filename = NULL;
|
||||
char *d_name = NULL;
|
||||
csync_vio_handle_t *dh = NULL;
|
||||
@@ -447,24 +498,32 @@ int csync_ftw(CSYNC *ctx, const char *uri, csync_walker_fn fn,
|
||||
|
||||
read_from_db = ctx->remote.read_from_db;
|
||||
|
||||
if ((dh = csync_vio_opendir(ctx, uri)) == NULL) {
|
||||
int asp = 0;
|
||||
/* permission denied */
|
||||
ctx->status_code = csync_errno_to_status(errno, CSYNC_STATUS_OPENDIR_ERROR);
|
||||
if (errno == EACCES) {
|
||||
return 0;
|
||||
} else if(errno == ENOENT) {
|
||||
asp = asprintf( &ctx->error_string, "%s", uri);
|
||||
if (asp < 0) {
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, "asprintf failed!");
|
||||
// if the etag of this dir is still the same, its content is restored from the
|
||||
// database.
|
||||
if( do_read_from_db ) {
|
||||
if( ! fill_tree_from_db(ctx, uri) ) {
|
||||
errno = ENOENT;
|
||||
ctx->status_code = CSYNC_STATUS_OPENDIR_ERROR;
|
||||
goto error;
|
||||
}
|
||||
} else {
|
||||
C_STRERROR(errno, errbuf, sizeof(errbuf));
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR,
|
||||
"opendir failed for %s - %s (errno %d)",
|
||||
uri, errbuf, errno);
|
||||
}
|
||||
goto error;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if ((dh = csync_vio_opendir(ctx, uri)) == NULL) {
|
||||
int asp = 0;
|
||||
/* permission denied */
|
||||
ctx->status_code = csync_errno_to_status(errno, CSYNC_STATUS_OPENDIR_ERROR);
|
||||
if (errno == EACCES) {
|
||||
return 0;
|
||||
} else if(errno == ENOENT) {
|
||||
asp = asprintf( &ctx->error_string, "%s", uri);
|
||||
if (asp < 0) {
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, "asprintf failed!");
|
||||
}
|
||||
} else {
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, "opendir failed for %s - errno %d", uri, errno);
|
||||
}
|
||||
goto error;
|
||||
}
|
||||
|
||||
while ((dirent = csync_vio_readdir(ctx, dh))) {
|
||||
@@ -528,13 +587,8 @@ int csync_ftw(CSYNC *ctx, const char *uri, csync_walker_fn fn,
|
||||
}
|
||||
|
||||
/* == see if really stat has to be called. */
|
||||
if( do_read_from_db ) {
|
||||
fs = dirent;
|
||||
res = 0;
|
||||
} else {
|
||||
fs = csync_vio_file_stat_new();
|
||||
res = csync_vio_stat(ctx, filename, fs);
|
||||
}
|
||||
fs = csync_vio_file_stat_new();
|
||||
res = csync_vio_stat(ctx, filename, fs);
|
||||
|
||||
if( res == 0) {
|
||||
switch (fs->type) {
|
||||
@@ -564,16 +618,18 @@ int csync_ftw(CSYNC *ctx, const char *uri, csync_walker_fn fn,
|
||||
char *etag = NULL;
|
||||
int len = strlen( path );
|
||||
uint64_t h = c_jhash64((uint8_t *) path, len, 0);
|
||||
etag = csync_statedb_get_uniqId( ctx, h, fs );
|
||||
etag = csync_statedb_get_etag( ctx, h );
|
||||
|
||||
if( etag ) {
|
||||
SAFE_FREE(fs->etag);
|
||||
fs->etag = etag;
|
||||
fs->fields |= CSYNC_VIO_FILE_STAT_FIELDS_ETAG;
|
||||
}
|
||||
if( c_streq(etag, "")) {
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG, "Uniq ID from Database is EMPTY: %s", path);
|
||||
} else {
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG, "Uniq ID from Database: %s -> %s", path, fs->etag ? fs->etag : "<NULL>" );
|
||||
|
||||
if( c_streq(etag, "")) {
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG, "Uniq ID from Database is EMPTY: %s", path);
|
||||
} else {
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG, "Uniq ID from Database: %s -> %s", path, fs->etag ? fs->etag : "<NULL>" );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -587,11 +643,7 @@ int csync_ftw(CSYNC *ctx, const char *uri, csync_walker_fn fn,
|
||||
previous_fs->child_modified = ctx->current_fs->child_modified;
|
||||
}
|
||||
|
||||
if( ! do_read_from_db ) {
|
||||
csync_vio_file_stat_destroy(fs);
|
||||
} else {
|
||||
SAFE_FREE(fs->etag);
|
||||
}
|
||||
csync_vio_file_stat_destroy(fs);
|
||||
|
||||
if (rc < 0) {
|
||||
if (CSYNC_STATUS_IS_OK(ctx->status_code)) {
|
||||
@@ -617,7 +669,8 @@ int csync_ftw(CSYNC *ctx, const char *uri, csync_walker_fn fn,
|
||||
}
|
||||
}
|
||||
|
||||
if (ctx->current_fs && (ctx->current_fs->instruction == CSYNC_INSTRUCTION_EVAL ||
|
||||
if (flag == CSYNC_FTW_FLAG_DIR && ctx->current_fs
|
||||
&& (ctx->current_fs->instruction == CSYNC_INSTRUCTION_EVAL ||
|
||||
ctx->current_fs->instruction == CSYNC_INSTRUCTION_NEW ||
|
||||
ctx->current_fs->instruction == CSYNC_INSTRUCTION_EVAL_RENAME)) {
|
||||
ctx->current_fs->should_update_etag = true;
|
||||
|
||||
@@ -55,8 +55,6 @@ static const _instr_code_struct _instr[] =
|
||||
{ "INSTRUCTION_SYNC", CSYNC_INSTRUCTION_SYNC },
|
||||
{ "INSTRUCTION_STAT_ERR", CSYNC_INSTRUCTION_STAT_ERROR },
|
||||
{ "INSTRUCTION_ERROR", CSYNC_INSTRUCTION_ERROR },
|
||||
{ "INSTRUCTION_DELETED", CSYNC_INSTRUCTION_DELETED },
|
||||
{ "INSTRUCTION_UPDATED", CSYNC_INSTRUCTION_UPDATED },
|
||||
{ NULL, CSYNC_INSTRUCTION_ERROR }
|
||||
};
|
||||
|
||||
@@ -106,40 +104,6 @@ void csync_memstat_check(void) {
|
||||
m.size * 4, m.resident * 4, m.shared * 4);
|
||||
}
|
||||
|
||||
int csync_unix_extensions(CSYNC *ctx) {
|
||||
int rc = -1;
|
||||
char *uri = NULL;
|
||||
csync_vio_handle_t *fp = NULL;
|
||||
|
||||
ctx->options.unix_extensions = 0;
|
||||
|
||||
rc = asprintf(&uri, "%s/csync_unix_extension*test.ctmp", ctx->remote.uri);
|
||||
if (rc < 0) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
ctx->replica = ctx->remote.type;
|
||||
fp = csync_vio_creat(ctx, uri, 0644);
|
||||
if (fp == NULL) {
|
||||
rc = 0;
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_INFO,
|
||||
"Disabled unix filesystem synchronization");
|
||||
goto out;
|
||||
}
|
||||
csync_vio_close(ctx, fp);
|
||||
|
||||
ctx->options.unix_extensions = 1;
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_INFO, "Enabled unix filesystem synchronization");
|
||||
|
||||
rc = 1;
|
||||
|
||||
out:
|
||||
csync_vio_unlink(ctx, uri);
|
||||
SAFE_FREE(uri);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
void csync_win32_set_file_hidden( const char *file, bool h ) {
|
||||
#ifdef _WIN32
|
||||
const mbchar_t *fileName;
|
||||
@@ -216,3 +180,22 @@ csync_vio_file_stat_t *csync_vio_convert_file_stat(csync_file_stat_t *st) {
|
||||
|
||||
return vfs;
|
||||
}
|
||||
|
||||
bool (*csync_file_locked_or_open_ext) (const char*) = 0; // filled in by library user
|
||||
void set_csync_file_locked_or_open_ext(bool (*f) (const char*));
|
||||
void set_csync_file_locked_or_open_ext(bool (*f) (const char*)) {
|
||||
csync_file_locked_or_open_ext = f;
|
||||
}
|
||||
|
||||
bool csync_file_locked_or_open( const char *dir, const char *fname) {
|
||||
char *tmp_uri = NULL;
|
||||
bool ret;
|
||||
if (!csync_file_locked_or_open_ext) {
|
||||
return false;
|
||||
}
|
||||
asprintf(&tmp_uri, "%s/%s", dir, fname);
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG, "csync_file_locked_or_open %s", tmp_uri);
|
||||
ret = csync_file_locked_or_open_ext(tmp_uri);
|
||||
SAFE_FREE(tmp_uri);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -30,11 +30,10 @@ const char *csync_instruction_str(enum csync_instructions_e instr);
|
||||
|
||||
void csync_memstat_check(void);
|
||||
|
||||
int csync_unix_extensions(CSYNC *ctx);
|
||||
|
||||
void csync_win32_set_file_hidden( const char *file, bool hidden );
|
||||
|
||||
/* Convert a csync_file_stat_t to csync_vio_file_stat_t */
|
||||
csync_vio_file_stat_t *csync_vio_convert_file_stat(csync_file_stat_t *st);
|
||||
|
||||
bool csync_file_locked_or_open( const char *dir, const char *fname);
|
||||
#endif /* _CSYNC_UTIL_H */
|
||||
|
||||
@@ -55,9 +55,6 @@
|
||||
/** Get the size of an array */
|
||||
#define ARRAY_SIZE(a) (sizeof(a)/sizeof(a[0]))
|
||||
|
||||
/** Macro to make strerror_r work with -Werror=unused-result */
|
||||
#define C_STRERROR(errno, buf, size) if(strerror_r(errno, buf, size)) {}
|
||||
|
||||
/**
|
||||
* This is a hack to fix warnings. The idea is to use this everywhere that we
|
||||
* get the "discarding const" warning by the compiler. That doesn't actually
|
||||
|
||||
@@ -26,7 +26,6 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#include "csync_private.h"
|
||||
#include "csync_dbtree.h"
|
||||
#include "csync_util.h"
|
||||
#include "vio/csync_vio.h"
|
||||
#include "vio/csync_vio_handle_private.h"
|
||||
@@ -34,356 +33,27 @@
|
||||
#include "csync_statedb.h"
|
||||
#include "std/c_jhash.h"
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include <mach-o/dyld.h>
|
||||
#endif
|
||||
|
||||
#define CSYNC_LOG_CATEGORY_NAME "csync.vio.main"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <wchar.h>
|
||||
#define MODULE_EXTENSION "dll"
|
||||
#else
|
||||
#define MODULE_EXTENSION "so"
|
||||
#endif
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include <mach-o/dyld.h>
|
||||
#endif
|
||||
|
||||
#include "csync_log.h"
|
||||
|
||||
int csync_vio_init(CSYNC *ctx, const char *module, const char *args) {
|
||||
|
||||
csync_vio_method_t *m = NULL;
|
||||
csync_vio_method_init_fn init_fn;
|
||||
|
||||
/* The owncloud module used to be dynamically loaded, but now it's just statically linked */
|
||||
extern csync_vio_method_t *vio_module_init(const char *method_name, const char *config_args, csync_auth_callback cb, void *userdata);
|
||||
extern void vio_module_shutdown(csync_vio_method_t *);
|
||||
init_fn = vio_module_init;
|
||||
ctx->module.finish_fn = vio_module_shutdown;
|
||||
|
||||
/* get the method struct */
|
||||
m = init_fn(module, args, csync_get_auth_callback(ctx), csync_get_userdata(ctx));
|
||||
if (m == NULL) {
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, "module %s returned a NULL method", module);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Useful defaults to the module capabilities */
|
||||
ctx->module.capabilities.atomar_copy_support = false;
|
||||
ctx->module.capabilities.do_post_copy_stat = true;
|
||||
ctx->module.capabilities.time_sync_required = true;
|
||||
ctx->module.capabilities.unix_extensions = -1; /* detect automatically */
|
||||
ctx->module.capabilities.use_send_file_to_propagate = false; /* do use read/write by default */
|
||||
|
||||
/* Load the module capabilities from the module if it implements the it. */
|
||||
if( VIO_METHOD_HAS_FUNC(m, get_capabilities)) {
|
||||
ctx->module.capabilities = *(m->get_capabilities());
|
||||
}
|
||||
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "capabilities: atomar copy support: %s",
|
||||
ctx->module.capabilities.atomar_copy_support ? "yes": "no");
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "capabilities: post copy stat: %s",
|
||||
ctx->module.capabilities.do_post_copy_stat ? "yes": "no");
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "capabilities: time sync required: %s",
|
||||
ctx->module.capabilities.time_sync_required ? "yes": "no");
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "capabilities: unix extensions: %d",
|
||||
ctx->module.capabilities.unix_extensions );
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "capabilities: use send_file: %s",
|
||||
ctx->module.capabilities.use_send_file_to_propagate ? "yes" : "no" );
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "capabilities: get support: %s",
|
||||
ctx->module.capabilities.get_support ? "yes" : "no" );
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "capabilities: put support: %s",
|
||||
ctx->module.capabilities.put_support? "yes" : "no" );
|
||||
|
||||
/* Some basic checks */
|
||||
if (m->method_table_size == 0) {
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, "module %s method table size is 0", module);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (! VIO_METHOD_HAS_FUNC(m, opendir)) {
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, "module %s has no opendir fn", module);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Useful defaults to the module capabilities */
|
||||
ctx->module.capabilities.atomar_copy_support = false;
|
||||
ctx->module.capabilities.put_support = false;
|
||||
ctx->module.capabilities.get_support = false;
|
||||
|
||||
/* Load the module capabilities from the module if it implements the it. */
|
||||
if( VIO_METHOD_HAS_FUNC(m, get_capabilities)) {
|
||||
ctx->module.capabilities = *(m->get_capabilities());
|
||||
} else {
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_WARN, "module %s has no capabilities fn", module);
|
||||
}
|
||||
|
||||
if (! VIO_METHOD_HAS_FUNC(m, get_etag)) {
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_WARN, "module %s has no get_etag fn", module);
|
||||
}
|
||||
|
||||
ctx->module.method = m;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void csync_vio_shutdown(CSYNC *ctx) {
|
||||
/* shutdown the plugin */
|
||||
if (ctx->module.finish_fn != NULL) {
|
||||
(*ctx->module.finish_fn)(ctx->module.method);
|
||||
}
|
||||
|
||||
ctx->module.method = NULL;
|
||||
ctx->module.finish_fn = NULL;
|
||||
}
|
||||
|
||||
csync_vio_handle_t *csync_vio_open(CSYNC *ctx, const char *uri, int flags, mode_t mode) {
|
||||
csync_vio_handle_t *h = NULL;
|
||||
csync_vio_method_handle_t *mh = NULL;
|
||||
|
||||
switch(ctx->replica) {
|
||||
case REMOTE_REPLICA:
|
||||
mh = ctx->module.method->open(uri, flags, mode);
|
||||
break;
|
||||
case LOCAL_REPLICA:
|
||||
mh = csync_vio_local_open(uri, flags, mode);
|
||||
break;
|
||||
default:
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_ALERT, "Invalid replica (%d)", (int)ctx->replica);
|
||||
break;
|
||||
}
|
||||
|
||||
h = csync_vio_handle_new(uri, mh);
|
||||
if (h == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return h;
|
||||
}
|
||||
|
||||
csync_vio_handle_t *csync_vio_creat(CSYNC *ctx, const char *uri, mode_t mode) {
|
||||
csync_vio_handle_t *h = NULL;
|
||||
csync_vio_method_handle_t *mh = NULL;
|
||||
|
||||
switch(ctx->replica) {
|
||||
case REMOTE_REPLICA:
|
||||
mh = ctx->module.method->creat(uri, mode);
|
||||
break;
|
||||
case LOCAL_REPLICA:
|
||||
mh = csync_vio_local_creat(uri, mode);
|
||||
break;
|
||||
default:
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_ALERT, "Invalid replica (%d)", (int)ctx->replica);
|
||||
break;
|
||||
}
|
||||
|
||||
h = csync_vio_handle_new(uri, mh);
|
||||
if (h == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return h;
|
||||
}
|
||||
|
||||
int csync_vio_close(CSYNC *ctx, csync_vio_handle_t *fhandle) {
|
||||
int rc = -1;
|
||||
|
||||
if (fhandle == NULL) {
|
||||
errno = EBADF;
|
||||
return -1;
|
||||
}
|
||||
|
||||
switch(ctx->replica) {
|
||||
case REMOTE_REPLICA:
|
||||
rc = ctx->module.method->close(fhandle->method_handle);
|
||||
break;
|
||||
case LOCAL_REPLICA:
|
||||
rc = csync_vio_local_close(fhandle->method_handle);
|
||||
break;
|
||||
default:
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_ALERT, "Invalid replica (%d)", (int)ctx->replica);
|
||||
break;
|
||||
}
|
||||
|
||||
/* handle->method_handle is free'd by the above close */
|
||||
SAFE_FREE(fhandle->uri);
|
||||
SAFE_FREE(fhandle);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int csync_vio_getfd(csync_vio_handle_t *fhandle) {
|
||||
int fd = -1;
|
||||
|
||||
if (fhandle == NULL) {
|
||||
errno = EBADF;
|
||||
return -1;
|
||||
}
|
||||
|
||||
fd = csync_vio_local_getfd( fhandle );
|
||||
// Return the correct handle here.
|
||||
return fd;
|
||||
|
||||
}
|
||||
|
||||
int csync_vio_put(CSYNC *ctx,
|
||||
csync_vio_handle_t *flocal,
|
||||
csync_vio_handle_t *fremote,
|
||||
csync_file_stat_t *st) {
|
||||
int rc = 0;
|
||||
csync_vio_file_stat_t *vfs = csync_vio_convert_file_stat(st);
|
||||
|
||||
if (flocal == NULL) {
|
||||
rc = -1;
|
||||
}
|
||||
if (vfs == NULL) {
|
||||
rc = -1;
|
||||
}
|
||||
|
||||
if (rc == 0) {
|
||||
rc = ctx->module.method->put(flocal->method_handle,
|
||||
fremote->method_handle,
|
||||
vfs);
|
||||
}
|
||||
csync_vio_file_stat_destroy(vfs);
|
||||
return rc;
|
||||
}
|
||||
|
||||
int csync_vio_get(CSYNC *ctx,
|
||||
csync_vio_handle_t *flocal,
|
||||
csync_vio_handle_t *fremote,
|
||||
csync_file_stat_t *st) {
|
||||
int rc = 0;
|
||||
csync_vio_file_stat_t *vfs = csync_vio_convert_file_stat(st);
|
||||
|
||||
if (flocal == NULL) {
|
||||
rc = -1;
|
||||
}
|
||||
if (vfs == NULL) {
|
||||
rc = -1;
|
||||
}
|
||||
|
||||
if (rc == 0) {
|
||||
rc = ctx->module.method->get(flocal->method_handle,
|
||||
fremote->method_handle,
|
||||
vfs);
|
||||
}
|
||||
csync_vio_file_stat_destroy(vfs);
|
||||
return rc;
|
||||
}
|
||||
|
||||
ssize_t csync_vio_read(CSYNC *ctx, csync_vio_handle_t *fhandle, void *buf, size_t count) {
|
||||
ssize_t rs = 0;
|
||||
|
||||
if (fhandle == NULL) {
|
||||
errno = EBADF;
|
||||
return -1;
|
||||
}
|
||||
|
||||
switch(ctx->replica) {
|
||||
case REMOTE_REPLICA:
|
||||
rs = ctx->module.method->read(fhandle->method_handle, buf, count);
|
||||
break;
|
||||
case LOCAL_REPLICA:
|
||||
rs = csync_vio_local_read(fhandle->method_handle, buf, count);
|
||||
break;
|
||||
default:
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_ALERT, "Invalid replica (%d)", (int)ctx->replica);
|
||||
break;
|
||||
}
|
||||
|
||||
return rs;
|
||||
}
|
||||
|
||||
ssize_t csync_vio_write(CSYNC *ctx, csync_vio_handle_t *fhandle, const void *buf, size_t count) {
|
||||
ssize_t rs = 0;
|
||||
|
||||
if (fhandle == NULL) {
|
||||
errno = EBADF;
|
||||
return -1;
|
||||
}
|
||||
|
||||
switch(ctx->replica) {
|
||||
case REMOTE_REPLICA:
|
||||
rs = ctx->module.method->write(fhandle->method_handle, buf, count);
|
||||
break;
|
||||
case LOCAL_REPLICA:
|
||||
rs = csync_vio_local_write(fhandle->method_handle, buf, count);
|
||||
break;
|
||||
default:
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_ALERT, "Invalid replica (%d)", (int)ctx->replica);
|
||||
break;
|
||||
}
|
||||
|
||||
return rs;
|
||||
}
|
||||
|
||||
int csync_vio_sendfile(CSYNC *ctx, csync_vio_handle_t *sfp, csync_vio_handle_t *dst) {
|
||||
int rc = 0;
|
||||
|
||||
switch(ctx->replica) {
|
||||
case REMOTE_REPLICA:
|
||||
rc = ctx->module.method->sendfile(sfp->method_handle, dst->method_handle);
|
||||
break;
|
||||
case LOCAL_REPLICA:
|
||||
rc = ctx->module.method->sendfile(dst->method_handle, sfp->method_handle);
|
||||
break;
|
||||
default:
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_ALERT, "Invalid replica (%d)", (int)ctx->replica);
|
||||
break;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int64_t csync_vio_lseek(CSYNC *ctx, csync_vio_handle_t *fhandle, int64_t offset, int whence) {
|
||||
int64_t ro = 0;
|
||||
|
||||
switch(ctx->replica) {
|
||||
case REMOTE_REPLICA:
|
||||
ro = ctx->module.method->lseek(fhandle->method_handle, offset, whence);
|
||||
break;
|
||||
case LOCAL_REPLICA:
|
||||
ro = csync_vio_local_lseek(fhandle->method_handle, offset, whence);
|
||||
break;
|
||||
default:
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_ALERT, "Invalid replica (%d)", (int)ctx->replica);
|
||||
break;
|
||||
}
|
||||
|
||||
return ro;
|
||||
}
|
||||
#include "csync_owncloud.h"
|
||||
|
||||
csync_vio_handle_t *csync_vio_opendir(CSYNC *ctx, const char *name) {
|
||||
csync_vio_handle_t *h = NULL;
|
||||
csync_vio_method_handle_t *mh = NULL;
|
||||
|
||||
switch(ctx->replica) {
|
||||
case REMOTE_REPLICA:
|
||||
if(ctx->remote.read_from_db) {
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG, "Reading directory %s from database", name);
|
||||
mh = csync_dbtree_opendir(ctx, name);
|
||||
} else {
|
||||
mh = ctx->module.method->opendir(name);
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_WARN, "Read from db flag is true, should not!" );
|
||||
}
|
||||
return owncloud_opendir(name);
|
||||
break;
|
||||
case LOCAL_REPLICA:
|
||||
mh = csync_vio_local_opendir(name);
|
||||
return csync_vio_local_opendir(name);
|
||||
break;
|
||||
default:
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_ALERT, "Invalid replica (%d)", (int)ctx->replica);
|
||||
break;
|
||||
}
|
||||
|
||||
h = csync_vio_handle_new(name, mh);
|
||||
if (h == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return h;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int csync_vio_closedir(CSYNC *ctx, csync_vio_handle_t *dhandle) {
|
||||
@@ -395,161 +65,54 @@ int csync_vio_closedir(CSYNC *ctx, csync_vio_handle_t *dhandle) {
|
||||
}
|
||||
|
||||
switch(ctx->replica) {
|
||||
case REMOTE_REPLICA:
|
||||
if(ctx->remote.read_from_db) {
|
||||
rc = csync_dbtree_closedir(ctx, dhandle->method_handle);
|
||||
} else {
|
||||
rc = ctx->module.method->closedir(dhandle->method_handle);
|
||||
case REMOTE_REPLICA:
|
||||
if( ctx->remote.read_from_db ) {
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_WARN, "Remote ReadFromDb is true, should not!");
|
||||
}
|
||||
rc = owncloud_closedir(dhandle);
|
||||
break;
|
||||
case LOCAL_REPLICA:
|
||||
rc = csync_vio_local_closedir(dhandle->method_handle);
|
||||
case LOCAL_REPLICA:
|
||||
rc = csync_vio_local_closedir(dhandle);
|
||||
break;
|
||||
default:
|
||||
default:
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_ALERT, "Invalid replica (%d)", (int)ctx->replica);
|
||||
break;
|
||||
}
|
||||
|
||||
SAFE_FREE(dhandle->uri);
|
||||
SAFE_FREE(dhandle);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
csync_vio_file_stat_t *csync_vio_readdir(CSYNC *ctx, csync_vio_handle_t *dhandle) {
|
||||
csync_vio_file_stat_t *fs = NULL;
|
||||
|
||||
switch(ctx->replica) {
|
||||
case REMOTE_REPLICA:
|
||||
if(ctx->remote.read_from_db) {
|
||||
fs = csync_dbtree_readdir(ctx, dhandle->method_handle);
|
||||
} else {
|
||||
fs = ctx->module.method->readdir(dhandle->method_handle);
|
||||
if( ctx->remote.read_from_db ) {
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_WARN, "Remote readfromdb is true, should not!");
|
||||
}
|
||||
return owncloud_readdir(dhandle);
|
||||
break;
|
||||
case LOCAL_REPLICA:
|
||||
fs = csync_vio_local_readdir(dhandle->method_handle);
|
||||
return csync_vio_local_readdir(dhandle);
|
||||
break;
|
||||
default:
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_ALERT, "Invalid replica (%d)", (int)ctx->replica);
|
||||
break;
|
||||
}
|
||||
|
||||
return fs;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int csync_vio_mkdir(CSYNC *ctx, const char *uri, mode_t mode) {
|
||||
int rc = -1;
|
||||
|
||||
switch(ctx->replica) {
|
||||
case REMOTE_REPLICA:
|
||||
rc = ctx->module.method->mkdir(uri, mode);
|
||||
break;
|
||||
case LOCAL_REPLICA:
|
||||
rc = csync_vio_local_mkdir(uri, mode);
|
||||
break;
|
||||
default:
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_ALERT, "Invalid replica (%d)", (int)ctx->replica);
|
||||
break;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int csync_vio_mkdirs(CSYNC *ctx, const char *uri, mode_t mode) {
|
||||
int tmp = 0;
|
||||
char errbuf[256] = {0};
|
||||
csync_vio_file_stat_t *st = NULL;
|
||||
|
||||
if (uri == NULL) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
tmp = strlen(uri);
|
||||
while(tmp > 0 && uri[tmp - 1] == '/') --tmp;
|
||||
while(tmp > 0 && uri[tmp - 1] != '/') --tmp;
|
||||
while(tmp > 0 && uri[tmp - 1] == '/') --tmp;
|
||||
|
||||
if (tmp > 0) {
|
||||
char suburi[tmp + 1];
|
||||
memcpy(suburi, uri, tmp);
|
||||
suburi[tmp] = '\0';
|
||||
|
||||
st = csync_vio_file_stat_new();
|
||||
if (csync_vio_stat(ctx, suburi, st) == 0) {
|
||||
if (! S_ISDIR(st->mode)) {
|
||||
csync_vio_file_stat_destroy(st);
|
||||
errno = ENOTDIR;
|
||||
return -1;
|
||||
}
|
||||
} else if (errno != ENOENT) {
|
||||
C_STRERROR(errno, errbuf, sizeof(errbuf));
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, "csync_vio_mkdirs stat failed: %s",
|
||||
errbuf);
|
||||
csync_vio_file_stat_destroy(st);
|
||||
return -1;
|
||||
} else if (csync_vio_mkdirs(ctx, suburi, mode) < 0) {
|
||||
csync_vio_file_stat_destroy(st);
|
||||
return -1;
|
||||
}
|
||||
csync_vio_file_stat_destroy(st);
|
||||
}
|
||||
|
||||
tmp = csync_vio_mkdir(ctx, uri, mode);
|
||||
if ((tmp < 0) && (errno == EEXIST)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
int csync_vio_rmdir(CSYNC *ctx, const char *uri) {
|
||||
int rc = -1;
|
||||
|
||||
switch(ctx->replica) {
|
||||
case REMOTE_REPLICA:
|
||||
rc = ctx->module.method->rmdir(uri);
|
||||
break;
|
||||
case LOCAL_REPLICA:
|
||||
rc = csync_vio_local_rmdir(uri);
|
||||
break;
|
||||
default:
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_ALERT, "Invalid replica (%d)", (int)ctx->replica);
|
||||
break;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
const char *csync_vio_get_etag(CSYNC *ctx, const char *path)
|
||||
{
|
||||
const char *re = NULL;
|
||||
/* We always use the remote method here. */
|
||||
if(ctx->module.method &&
|
||||
VIO_METHOD_HAS_FUNC(ctx->module.method, get_etag)) {
|
||||
re = ctx->module.method->get_etag(path);
|
||||
}
|
||||
return re;
|
||||
}
|
||||
|
||||
int csync_vio_stat(CSYNC *ctx, const char *uri, csync_vio_file_stat_t *buf) {
|
||||
int rc = -1;
|
||||
|
||||
switch(ctx->replica) {
|
||||
case REMOTE_REPLICA:
|
||||
rc = ctx->module.method->stat(uri, buf);
|
||||
rc = owncloud_stat(uri, buf);
|
||||
break;
|
||||
case LOCAL_REPLICA:
|
||||
rc = csync_vio_local_stat(uri, buf);
|
||||
if (rc < 0) {
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, "Local stat failed, errno %d", errno);
|
||||
}
|
||||
#ifdef _WIN32
|
||||
else {
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG, "Win32: STAT-inode for %s: %llu", uri, buf->inode );
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -558,119 +121,21 @@ int csync_vio_stat(CSYNC *ctx, const char *uri, csync_vio_file_stat_t *buf) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
int csync_vio_rename(CSYNC *ctx, const char *olduri, const char *newuri) {
|
||||
int rc = -1;
|
||||
|
||||
switch(ctx->replica) {
|
||||
case REMOTE_REPLICA:
|
||||
rc = ctx->module.method->rename(olduri, newuri);
|
||||
break;
|
||||
case LOCAL_REPLICA:
|
||||
rc = csync_vio_local_rename(olduri, newuri);
|
||||
break;
|
||||
default:
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_ALERT, "Invalid replica (%d)", (int)ctx->replica);
|
||||
break;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int csync_vio_unlink(CSYNC *ctx, const char *uri) {
|
||||
int rc = -1;
|
||||
|
||||
switch(ctx->replica) {
|
||||
case REMOTE_REPLICA:
|
||||
rc = ctx->module.method->unlink(uri);
|
||||
break;
|
||||
case LOCAL_REPLICA:
|
||||
rc = csync_vio_local_unlink(uri);
|
||||
break;
|
||||
default:
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_ALERT, "Invalid replica (%d)", (int)ctx->replica);
|
||||
break;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int csync_vio_chmod(CSYNC *ctx, const char *uri, mode_t mode) {
|
||||
int rc = -1;
|
||||
|
||||
switch(ctx->replica) {
|
||||
case REMOTE_REPLICA:
|
||||
rc = ctx->module.method->chmod(uri, mode);
|
||||
break;
|
||||
case LOCAL_REPLICA:
|
||||
rc = csync_vio_local_chmod(uri, mode);
|
||||
break;
|
||||
default:
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_ALERT, "Invalid replica (%d)", (int)ctx->replica);
|
||||
break;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int csync_vio_chown(CSYNC *ctx, const char *uri, uid_t owner, gid_t group) {
|
||||
int rc = -1;
|
||||
|
||||
switch(ctx->replica) {
|
||||
case REMOTE_REPLICA:
|
||||
rc = ctx->module.method->chown(uri, owner, group);
|
||||
break;
|
||||
case LOCAL_REPLICA:
|
||||
rc = csync_vio_local_chown(uri, owner, group);
|
||||
break;
|
||||
default:
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_ALERT, "Invalid replica (%d)", (int)ctx->replica);
|
||||
break;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int csync_vio_utimes(CSYNC *ctx, const char *uri, const struct timeval *times) {
|
||||
int rc = -1;
|
||||
|
||||
switch(ctx->replica) {
|
||||
case REMOTE_REPLICA:
|
||||
rc = ctx->module.method->utimes(uri, times);
|
||||
break;
|
||||
case LOCAL_REPLICA:
|
||||
rc = csync_vio_local_utimes(uri, times);
|
||||
break;
|
||||
default:
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_ALERT, "Invalid replica (%d)", (int)ctx->replica);
|
||||
break;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
char *csync_vio_get_status_string(CSYNC *ctx) {
|
||||
if(ctx->error_string) {
|
||||
return ctx->error_string;
|
||||
}
|
||||
if(VIO_METHOD_HAS_FUNC(ctx->module.method, get_error_string)) {
|
||||
return ctx->module.method->get_error_string();
|
||||
}
|
||||
return NULL;
|
||||
if(ctx->error_string) {
|
||||
return ctx->error_string;
|
||||
}
|
||||
return owncloud_error_string();
|
||||
}
|
||||
|
||||
int csync_vio_set_property(CSYNC* ctx, const char* key, void* data) {
|
||||
int rc = -1;
|
||||
if(VIO_METHOD_HAS_FUNC(ctx->module.method, set_property))
|
||||
rc = ctx->module.method->set_property(key, data);
|
||||
return rc;
|
||||
(void) ctx;
|
||||
return owncloud_set_property(key, data);
|
||||
}
|
||||
|
||||
int csync_vio_commit(CSYNC *ctx) {
|
||||
int rc = 0;
|
||||
|
||||
if (VIO_METHOD_HAS_FUNC(ctx->module.method, commit)) {
|
||||
rc = ctx->module.method->commit();
|
||||
}
|
||||
|
||||
return rc;
|
||||
(void) ctx;
|
||||
return owncloud_commit();
|
||||
}
|
||||
|
||||
@@ -33,36 +33,11 @@ typedef struct fhandle_s {
|
||||
int fd;
|
||||
} fhandle_t;
|
||||
|
||||
int csync_vio_init(CSYNC *ctx, const char *module, const char *args);
|
||||
void csync_vio_shutdown(CSYNC *ctx);
|
||||
csync_vio_handle_t *csync_vio_open(CSYNC *ctx, const char *uri, int flags, mode_t mode);
|
||||
csync_vio_handle_t *csync_vio_creat(CSYNC *ctx, const char *uri, mode_t mode);
|
||||
int csync_vio_close(CSYNC *ctx, csync_vio_handle_t *handle);
|
||||
ssize_t csync_vio_read(CSYNC *ctx, csync_vio_handle_t *fhandle, void *buf, size_t count);
|
||||
ssize_t csync_vio_write(CSYNC *ctx, csync_vio_handle_t *fhandle, const void *buf, size_t count);
|
||||
int csync_vio_sendfile(CSYNC *ctx, csync_vio_handle_t *sfp, csync_vio_handle_t *dst);
|
||||
int64_t csync_vio_lseek(CSYNC *ctx, csync_vio_handle_t *fhandle, int64_t offset, int whence);
|
||||
|
||||
int csync_vio_put(CSYNC *ctx, csync_vio_handle_t *flocal, csync_vio_handle_t *fremote, csync_file_stat_t *st);
|
||||
int csync_vio_get(CSYNC *ctx, csync_vio_handle_t *flocal, csync_vio_handle_t *fremote, csync_file_stat_t *st);
|
||||
|
||||
csync_vio_handle_t *csync_vio_opendir(CSYNC *ctx, const char *name);
|
||||
int csync_vio_closedir(CSYNC *ctx, csync_vio_handle_t *dhandle);
|
||||
csync_vio_file_stat_t *csync_vio_readdir(CSYNC *ctx, csync_vio_handle_t *dhandle);
|
||||
|
||||
int csync_vio_mkdir(CSYNC *ctx, const char *uri, mode_t mode);
|
||||
int csync_vio_mkdirs(CSYNC *ctx, const char *uri, mode_t mode);
|
||||
int csync_vio_rmdir(CSYNC *ctx, const char *uri);
|
||||
|
||||
const char *csync_vio_get_etag(CSYNC *ctx, const char *path);
|
||||
int csync_vio_stat(CSYNC *ctx, const char *uri, csync_vio_file_stat_t *buf);
|
||||
int csync_vio_rename(CSYNC *ctx, const char *olduri, const char *newuri);
|
||||
int csync_vio_unlink(CSYNC *ctx, const char *uri);
|
||||
|
||||
int csync_vio_chmod(CSYNC *ctx, const char *uri, mode_t mode);
|
||||
int csync_vio_chown(CSYNC *ctx, const char *uri, uid_t owner, gid_t group);
|
||||
|
||||
int csync_vio_utimes(CSYNC *ctx, const char *uri, const struct timeval *times);
|
||||
|
||||
int csync_vio_set_property(CSYNC *ctx, const char *key, void *data);
|
||||
|
||||
@@ -70,6 +45,4 @@ char *csync_vio_get_status_string(CSYNC *ctx);
|
||||
|
||||
int csync_vio_commit(CSYNC *ctx);
|
||||
|
||||
int csync_vio_getfd(csync_vio_handle_t *fhandle);
|
||||
|
||||
#endif /* _CSYNC_VIO_H */
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
* cannot include csync_private here because
|
||||
* that would cause circular inclusion
|
||||
*/
|
||||
#include "c_private.h"
|
||||
#include "std/c_private.h"
|
||||
#include "csync.h"
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
@@ -1,50 +0,0 @@
|
||||
/*
|
||||
* libcsync -- a library to sync a directory with another
|
||||
*
|
||||
* Copyright (c) 2008-2013 by Andreas Schneider <asn@cryptomilk.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "c_lib.h"
|
||||
|
||||
#include "vio/csync_vio_handle_private.h"
|
||||
|
||||
csync_vio_handle_t *csync_vio_handle_new(const char *uri, csync_vio_method_handle_t *method_handle) {
|
||||
csync_vio_handle_t *new = NULL;
|
||||
|
||||
if (uri == NULL || method_handle == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
new = c_malloc(sizeof(csync_vio_handle_t));
|
||||
if (new == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
new->uri = c_strdup(uri);
|
||||
new->method_handle = method_handle;
|
||||
|
||||
return new;
|
||||
}
|
||||
|
||||
void csync_vio_handle_destroy(csync_vio_handle_t *handle) {
|
||||
if (handle == NULL || handle->uri == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
SAFE_FREE(handle->uri);
|
||||
SAFE_FREE(handle);
|
||||
}
|
||||
@@ -21,7 +21,6 @@
|
||||
#ifndef _CSYNC_VIO_HANDLE_H
|
||||
#define _CSYNC_VIO_HANDLE_H
|
||||
|
||||
typedef void csync_vio_method_handle_t;
|
||||
typedef struct csync_vio_handle_s csync_vio_handle_t;
|
||||
typedef void csync_vio_handle_t;
|
||||
|
||||
#endif /* _CSYNC_VIO_HANDLE_H */
|
||||
|
||||
@@ -23,13 +23,4 @@
|
||||
|
||||
#include "vio/csync_vio_handle.h"
|
||||
|
||||
struct csync_vio_handle_s {
|
||||
char *uri;
|
||||
|
||||
csync_vio_method_handle_t *method_handle;
|
||||
};
|
||||
|
||||
csync_vio_handle_t *csync_vio_handle_new(const char *uri, csync_vio_method_handle_t *method_handle);
|
||||
void csync_vio_handle_destroy(csync_vio_handle_t *handle);
|
||||
|
||||
#endif /* _CSYNC_VIO_HANDLE_PRIVATE_H */
|
||||
|
||||
@@ -41,128 +41,6 @@
|
||||
#include "vio/csync_vio_handle_private.h"
|
||||
|
||||
|
||||
int csync_vio_local_getfd(csync_vio_handle_t *hnd)
|
||||
{
|
||||
fhandle_t *fh;
|
||||
|
||||
if (hnd == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
fh = (struct fhandle_s*)(hnd);
|
||||
|
||||
return fh->fd;
|
||||
}
|
||||
|
||||
/* the url comes in as utf-8 and in windows, it needs to be multibyte. */
|
||||
csync_vio_method_handle_t *csync_vio_local_open(const char *durl, int flags, mode_t mode) {
|
||||
fhandle_t *handle = NULL;
|
||||
int fd = -1;
|
||||
mbchar_t *url = c_utf8_to_locale(durl);
|
||||
|
||||
if ((fd = _topen(url, flags, mode)) < 0) {
|
||||
c_free_locale_string(url);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
handle = c_malloc(sizeof(fhandle_t));
|
||||
if (handle == NULL) {
|
||||
c_free_locale_string(url);
|
||||
close(fd);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
handle->fd = fd;
|
||||
|
||||
c_free_locale_string(url);
|
||||
|
||||
return (csync_vio_method_handle_t *) handle;
|
||||
}
|
||||
|
||||
csync_vio_method_handle_t *csync_vio_local_creat(const char *durl, mode_t mode) {
|
||||
fhandle_t *handle = NULL;
|
||||
int fd = -1;
|
||||
mbchar_t *url = c_utf8_to_locale(durl);
|
||||
|
||||
if(( fd = _tcreat( url, mode)) < 0) {
|
||||
c_free_locale_string(url);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
handle = c_malloc(sizeof(fhandle_t));
|
||||
if (handle == NULL) {
|
||||
c_free_locale_string(url);
|
||||
close(fd);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
handle->fd = fd;
|
||||
c_free_locale_string(url);
|
||||
return (csync_vio_method_handle_t *) handle;
|
||||
}
|
||||
|
||||
int csync_vio_local_close(csync_vio_method_handle_t *fhandle) {
|
||||
int rc = -1;
|
||||
fhandle_t *handle = NULL;
|
||||
|
||||
if (fhandle == NULL) {
|
||||
errno = EBADF;
|
||||
return -1;
|
||||
}
|
||||
|
||||
handle = (fhandle_t *) fhandle;
|
||||
|
||||
rc = close(handle->fd);
|
||||
|
||||
SAFE_FREE(handle);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
ssize_t csync_vio_local_read(csync_vio_method_handle_t *fhandle, void *buf, size_t count) {
|
||||
fhandle_t *handle = NULL;
|
||||
|
||||
if (fhandle == NULL) {
|
||||
errno = EBADF;
|
||||
return (ssize_t) -1;
|
||||
}
|
||||
|
||||
handle = (fhandle_t *) fhandle;
|
||||
|
||||
return read(handle->fd, buf, count);
|
||||
}
|
||||
|
||||
ssize_t csync_vio_local_write(csync_vio_method_handle_t *fhandle, const void *buf, size_t count) {
|
||||
ssize_t n = 0;
|
||||
fhandle_t *handle = NULL;
|
||||
|
||||
if (fhandle == NULL) {
|
||||
errno = EBADF;
|
||||
return (ssize_t) -1;
|
||||
}
|
||||
|
||||
handle = (fhandle_t *) fhandle;
|
||||
|
||||
/* safe_write */
|
||||
do {
|
||||
n = write(handle->fd, buf, count);
|
||||
} while (n < 0 && errno == EINTR);
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
int64_t csync_vio_local_lseek(csync_vio_method_handle_t *fhandle, int64_t offset, int whence) {
|
||||
fhandle_t *handle = NULL;
|
||||
|
||||
if (fhandle == NULL) {
|
||||
return (int64_t) -1;
|
||||
}
|
||||
|
||||
handle = (fhandle_t *) fhandle;
|
||||
|
||||
return lseek(handle->fd, offset, whence);
|
||||
}
|
||||
|
||||
/*
|
||||
* directory functions
|
||||
*/
|
||||
@@ -172,7 +50,7 @@ typedef struct dhandle_s {
|
||||
char *path;
|
||||
} dhandle_t;
|
||||
|
||||
csync_vio_method_handle_t *csync_vio_local_opendir(const char *name) {
|
||||
csync_vio_handle_t *csync_vio_local_opendir(const char *name) {
|
||||
dhandle_t *handle = NULL;
|
||||
mbchar_t *dirname = c_utf8_to_locale(name);
|
||||
|
||||
@@ -192,10 +70,10 @@ csync_vio_method_handle_t *csync_vio_local_opendir(const char *name) {
|
||||
handle->path = c_strdup(name);
|
||||
c_free_locale_string(dirname);
|
||||
|
||||
return (csync_vio_method_handle_t *) handle;
|
||||
return (csync_vio_handle_t *) handle;
|
||||
}
|
||||
|
||||
int csync_vio_local_closedir(csync_vio_method_handle_t *dhandle) {
|
||||
int csync_vio_local_closedir(csync_vio_handle_t *dhandle) {
|
||||
dhandle_t *handle = NULL;
|
||||
int rc = -1;
|
||||
|
||||
@@ -213,7 +91,7 @@ int csync_vio_local_closedir(csync_vio_method_handle_t *dhandle) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
csync_vio_file_stat_t *csync_vio_local_readdir(csync_vio_method_handle_t *dhandle) {
|
||||
csync_vio_file_stat_t *csync_vio_local_readdir(csync_vio_handle_t *dhandle) {
|
||||
struct _tdirent *dirent = NULL;
|
||||
|
||||
dhandle_t *handle = NULL;
|
||||
@@ -272,18 +150,6 @@ err:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int csync_vio_local_mkdir(const char *uri, mode_t mode) {
|
||||
return c_mkdirs(uri, mode);
|
||||
}
|
||||
|
||||
int csync_vio_local_rmdir(const char *uri) {
|
||||
mbchar_t *dirname = c_utf8_to_locale(uri);
|
||||
int re = -1;
|
||||
|
||||
re = _trmdir(dirname);
|
||||
c_free_locale_string(dirname);
|
||||
return re;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
static time_t FileTimeToUnixTime(FILETIME *filetime, DWORD *remainder)
|
||||
@@ -303,13 +169,107 @@ static time_t FileTimeToUnixTime(FILETIME *filetime, DWORD *remainder)
|
||||
return t / 10000000;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
int csync_vio_local_stat(const char *uri, csync_vio_file_stat_t *buf) {
|
||||
HANDLE h, hFind;
|
||||
FILETIME ftCreate, ftAccess, ftWrite;
|
||||
BY_HANDLE_FILE_INFORMATION fileInfo;
|
||||
WIN32_FIND_DATAW FindFileData;
|
||||
ULARGE_INTEGER FileIndex;
|
||||
mbchar_t *wuri = c_utf8_to_locale( uri );
|
||||
|
||||
h = CreateFileW( wuri, 0, FILE_SHARE_READ, NULL, OPEN_EXISTING,
|
||||
FILE_ATTRIBUTE_NORMAL+FILE_FLAG_BACKUP_SEMANTICS, NULL );
|
||||
if( h == INVALID_HANDLE_VALUE ) {
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_CRIT, "CreateFileW failed on %s", uri );
|
||||
errno = GetLastError();
|
||||
c_free_locale_string(wuri);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(!GetFileInformationByHandle( h, &fileInfo ) ) {
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_CRIT, "GetFileInformationByHandle failed on %s", uri );
|
||||
errno = GetLastError();
|
||||
c_free_locale_string(wuri);
|
||||
CloseHandle(h);
|
||||
return -1;
|
||||
}
|
||||
|
||||
buf->flags = CSYNC_VIO_FILE_FLAGS_NONE;
|
||||
do {
|
||||
// Check first if it is a symlink (code from c_islink)
|
||||
if (fileInfo.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
|
||||
hFind = FindFirstFileW(wuri, &FindFileData );
|
||||
if (hFind != INVALID_HANDLE_VALUE) {
|
||||
if( (FindFileData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) &&
|
||||
(FindFileData.dwReserved0 & IO_REPARSE_TAG_SYMLINK) ) {
|
||||
buf->flags = CSYNC_VIO_FILE_FLAGS_SYMLINK;
|
||||
buf->type = CSYNC_VIO_FILE_TYPE_SYMBOLIC_LINK;
|
||||
break;
|
||||
}
|
||||
}
|
||||
FindClose(hFind);
|
||||
}
|
||||
if (fileInfo.dwFileAttributes & FILE_ATTRIBUTE_DEVICE
|
||||
|| fileInfo.dwFileAttributes & FILE_ATTRIBUTE_OFFLINE
|
||||
|| fileInfo.dwFileAttributes & FILE_ATTRIBUTE_TEMPORARY) {
|
||||
buf->type = CSYNC_VIO_FILE_TYPE_UNKNOWN;
|
||||
break;
|
||||
}
|
||||
if (fileInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
|
||||
buf->type = CSYNC_VIO_FILE_TYPE_DIRECTORY;
|
||||
break;
|
||||
}
|
||||
// fallthrough:
|
||||
buf->type = CSYNC_VIO_FILE_TYPE_REGULAR;
|
||||
break;
|
||||
} while (0);
|
||||
buf->fields |= CSYNC_VIO_FILE_STAT_FIELDS_FLAGS;
|
||||
buf->fields |= CSYNC_VIO_FILE_STAT_FIELDS_TYPE;
|
||||
|
||||
buf->mode = 666;
|
||||
buf->fields |= CSYNC_VIO_FILE_STAT_FIELDS_PERMISSIONS;
|
||||
|
||||
buf->device = fileInfo.dwVolumeSerialNumber;
|
||||
buf->fields |= CSYNC_VIO_FILE_STAT_FIELDS_DEVICE;
|
||||
|
||||
/* Get the Windows file id as an inode replacement. */
|
||||
FileIndex.HighPart = fileInfo.nFileIndexHigh;
|
||||
FileIndex.LowPart = fileInfo.nFileIndexLow;
|
||||
FileIndex.QuadPart &= 0x0000FFFFFFFFFFFF;
|
||||
/* printf("Index: %I64i\n", FileIndex.QuadPart); */
|
||||
buf->inode = FileIndex.QuadPart;
|
||||
|
||||
buf->size = (fileInfo.nFileSizeHigh * (int64_t)(MAXDWORD+1)) + fileInfo.nFileSizeLow;
|
||||
buf->fields |= CSYNC_VIO_FILE_STAT_FIELDS_SIZE;
|
||||
|
||||
/* Get the file time with a win32 call rather than through stat. See
|
||||
* http://www.codeproject.com/Articles/1144/Beating-the-Daylight-Savings-Time-bug-and-getting
|
||||
* for deeper explanation.
|
||||
*/
|
||||
if( GetFileTime(h, &ftCreate, &ftAccess, &ftWrite) ) {
|
||||
DWORD rem;
|
||||
buf->atime = FileTimeToUnixTime(&ftAccess, &rem);
|
||||
buf->fields |= CSYNC_VIO_FILE_STAT_FIELDS_ATIME;
|
||||
|
||||
buf->mtime = FileTimeToUnixTime(&ftWrite, &rem);
|
||||
/* CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG, "Local File MTime: %llu", (unsigned long long) buf->mtime ); */
|
||||
buf->fields |= CSYNC_VIO_FILE_STAT_FIELDS_MTIME;
|
||||
|
||||
buf->ctime = FileTimeToUnixTime(&ftCreate, &rem);
|
||||
buf->fields |= CSYNC_VIO_FILE_STAT_FIELDS_CTIME;
|
||||
}
|
||||
|
||||
CloseHandle(h);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
int csync_vio_local_stat(const char *uri, csync_vio_file_stat_t *buf) {
|
||||
csync_stat_t sb;
|
||||
#ifdef _WIN32
|
||||
HANDLE h;
|
||||
#endif
|
||||
|
||||
mbchar_t *wuri = c_utf8_to_locale( uri );
|
||||
|
||||
if( _tstat(wuri, &sb) < 0) {
|
||||
@@ -342,14 +302,12 @@ int csync_vio_local_stat(const char *uri, csync_vio_file_stat_t *buf) {
|
||||
case S_IFREG:
|
||||
buf->type = CSYNC_VIO_FILE_TYPE_REGULAR;
|
||||
break;
|
||||
#ifndef _WIN32
|
||||
case S_IFLNK:
|
||||
buf->type = CSYNC_VIO_FILE_TYPE_SYMBOLIC_LINK;
|
||||
break;
|
||||
case S_IFSOCK:
|
||||
buf->type = CSYNC_VIO_FILE_TYPE_SYMBOLIC_LINK;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
buf->type = CSYNC_VIO_FILE_TYPE_UNKNOWN;
|
||||
break;
|
||||
@@ -371,56 +329,7 @@ int csync_vio_local_stat(const char *uri, csync_vio_file_stat_t *buf) {
|
||||
buf->fields |= CSYNC_VIO_FILE_STAT_FIELDS_DEVICE;
|
||||
|
||||
buf->inode = sb.st_ino;
|
||||
#ifdef _WIN32
|
||||
/* Get the Windows file id as an inode replacement. */
|
||||
h = CreateFileW( wuri, 0, FILE_SHARE_READ, NULL, OPEN_EXISTING,
|
||||
FILE_ATTRIBUTE_NORMAL+FILE_FLAG_BACKUP_SEMANTICS, NULL );
|
||||
if( h == INVALID_HANDLE_VALUE ) {
|
||||
errno = GetLastError();
|
||||
c_free_locale_string(wuri);
|
||||
return -1;
|
||||
|
||||
} else {
|
||||
FILETIME ftCreate, ftAccess, ftWrite;
|
||||
// SYSTEMTIME stUTC;
|
||||
|
||||
BY_HANDLE_FILE_INFORMATION fileInfo;
|
||||
|
||||
if( GetFileInformationByHandle( h, &fileInfo ) ) {
|
||||
ULARGE_INTEGER FileIndex;
|
||||
FileIndex.HighPart = fileInfo.nFileIndexHigh;
|
||||
FileIndex.LowPart = fileInfo.nFileIndexLow;
|
||||
FileIndex.QuadPart &= 0x0000FFFFFFFFFFFF;
|
||||
|
||||
/* printf("Index: %I64i\n", FileIndex.QuadPart); */
|
||||
|
||||
buf->inode = FileIndex.QuadPart;
|
||||
}
|
||||
|
||||
/* Get the file time with a win32 call rather than through stat. See
|
||||
* http://www.codeproject.com/Articles/1144/Beating-the-Daylight-Savings-Time-bug-and-getting
|
||||
* for deeper explanation.
|
||||
*/
|
||||
if( GetFileTime(h, &ftCreate, &ftAccess, &ftWrite) ) {
|
||||
DWORD rem;
|
||||
buf->atime = FileTimeToUnixTime(&ftAccess, &rem);
|
||||
buf->fields |= CSYNC_VIO_FILE_STAT_FIELDS_ATIME;
|
||||
|
||||
buf->mtime = FileTimeToUnixTime(&ftWrite, &rem);
|
||||
/* CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG, "Local File MTime: %llu", (unsigned long long) buf->mtime ); */
|
||||
buf->fields |= CSYNC_VIO_FILE_STAT_FIELDS_MTIME;
|
||||
|
||||
buf->ctime = FileTimeToUnixTime(&ftCreate, &rem);
|
||||
buf->fields |= CSYNC_VIO_FILE_STAT_FIELDS_CTIME;
|
||||
}
|
||||
CloseHandle(h);
|
||||
}
|
||||
|
||||
/* check if it is a symlink on win32 */
|
||||
if (c_islink(uri)) {
|
||||
buf->type = CSYNC_VIO_FILE_TYPE_SYMBOLIC_LINK;
|
||||
}
|
||||
#else /* non windows platforms: */
|
||||
buf->fields |= CSYNC_VIO_FILE_STAT_FIELDS_INODE;
|
||||
|
||||
/* Both values are only initialized to zero as they are not used in csync */
|
||||
/* They are deprecated and will be rmemoved later. */
|
||||
@@ -435,9 +344,6 @@ int csync_vio_local_stat(const char *uri, csync_vio_file_stat_t *buf) {
|
||||
|
||||
buf->ctime = sb.st_ctime;
|
||||
buf->fields |= CSYNC_VIO_FILE_STAT_FIELDS_CTIME;
|
||||
#endif
|
||||
|
||||
buf->fields |= CSYNC_VIO_FILE_STAT_FIELDS_INODE;
|
||||
|
||||
buf->nlink = sb.st_nlink;
|
||||
buf->fields |= CSYNC_VIO_FILE_STAT_FIELDS_LINK_COUNT;
|
||||
@@ -454,36 +360,8 @@ int csync_vio_local_stat(const char *uri, csync_vio_file_stat_t *buf) {
|
||||
c_free_locale_string(wuri);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int csync_vio_local_rename(const char *olduri, const char *newuri) {
|
||||
return c_rename(olduri, newuri);
|
||||
}
|
||||
|
||||
int csync_vio_local_unlink(const char *uri) {
|
||||
mbchar_t *nuri = c_utf8_to_locale(uri);
|
||||
int re = _tunlink( nuri );
|
||||
c_free_locale_string(nuri);
|
||||
return re;
|
||||
}
|
||||
|
||||
int csync_vio_local_chmod(const char *uri, mode_t mode) {
|
||||
mbchar_t *nuri = c_utf8_to_locale(uri);
|
||||
int re = -1;
|
||||
|
||||
re = _tchmod(nuri, mode);
|
||||
c_free_locale_string(nuri);
|
||||
return re;
|
||||
}
|
||||
|
||||
int csync_vio_local_chown(const char *uri, uid_t owner, gid_t group) {
|
||||
#if defined _WIN32
|
||||
(void)uri;
|
||||
(void)owner;
|
||||
(void)group;
|
||||
#endif
|
||||
return _tchown(uri, owner, group);
|
||||
}
|
||||
|
||||
int csync_vio_local_utimes(const char *uri, const struct timeval *times) {
|
||||
return c_utimes(uri, times);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -21,32 +21,12 @@
|
||||
#ifndef _CSYNC_VIO_LOCAL_H
|
||||
#define _CSYNC_VIO_LOCAL_H
|
||||
|
||||
#include "vio/csync_vio_method.h"
|
||||
#include <sys/time.h>
|
||||
|
||||
int csync_vio_local_getfd(csync_vio_handle_t *hnd);
|
||||
|
||||
csync_vio_method_handle_t *csync_vio_local_open(const char *durl, int flags, mode_t mode);
|
||||
csync_vio_method_handle_t *csync_vio_local_creat(const char *durl, mode_t mode);
|
||||
int csync_vio_local_close(csync_vio_method_handle_t *fhandle);
|
||||
ssize_t csync_vio_local_read(csync_vio_method_handle_t *fhandle, void *buf, size_t count);
|
||||
ssize_t csync_vio_local_write(csync_vio_method_handle_t *fhandle, const void *buf, size_t count);
|
||||
int64_t csync_vio_local_lseek(csync_vio_method_handle_t *fhandle, int64_t offset, int whence);
|
||||
|
||||
csync_vio_method_handle_t *csync_vio_local_opendir(const char *name);
|
||||
int csync_vio_local_closedir(csync_vio_method_handle_t *dhandle);
|
||||
csync_vio_file_stat_t *csync_vio_local_readdir(csync_vio_method_handle_t *dhandle);
|
||||
|
||||
int csync_vio_local_mkdir(const char *uri, mode_t mode);
|
||||
int csync_vio_local_rmdir(const char *uri);
|
||||
csync_vio_handle_t *csync_vio_local_opendir(const char *name);
|
||||
int csync_vio_local_closedir(csync_vio_handle_t *dhandle);
|
||||
csync_vio_file_stat_t *csync_vio_local_readdir(csync_vio_handle_t *dhandle);
|
||||
|
||||
int csync_vio_local_stat(const char *uri, csync_vio_file_stat_t *buf);
|
||||
int csync_vio_local_rename(const char *olduri, const char *newuri);
|
||||
int csync_vio_local_unlink(const char *uri);
|
||||
|
||||
int csync_vio_local_chmod(const char *uri, mode_t mode);
|
||||
int csync_vio_local_chown(const char *uri, uid_t owner, gid_t group);
|
||||
|
||||
int csync_vio_local_utimes(const char *uri, const struct timeval *times);
|
||||
|
||||
#endif /* _CSYNC_VIO_LOCAL_H */
|
||||
|
||||
@@ -1,123 +0,0 @@
|
||||
/*
|
||||
* cynapses libc functions
|
||||
*
|
||||
* Copyright (c) 2008-2013 by Andreas Schneider <asn@cryptomilk.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef _CSYNC_VIO_METHOD_H
|
||||
#define _CSYNC_VIO_METHOD_H
|
||||
|
||||
#include <sys/time.h>
|
||||
|
||||
#include "csync.h"
|
||||
#include "vio/csync_vio_file_stat.h"
|
||||
#include "vio/csync_vio_handle.h"
|
||||
|
||||
#define VIO_METHOD_HAS_FUNC(method,func) \
|
||||
(method != NULL && method->func != NULL \
|
||||
&& ((size_t)(((char *)&((method)->func)) - ((char *)(method))) < (method)->method_table_size))
|
||||
|
||||
typedef struct csync_vio_method_s csync_vio_method_t;
|
||||
|
||||
/* module capabilities definition.
|
||||
* remember to set useful defaults in csync_vio.c if you add something here. */
|
||||
struct csync_vio_capabilities_s {
|
||||
bool atomar_copy_support; /* set to true if the backend provides atomar copy */
|
||||
bool do_post_copy_stat; /* true if csync should check the copy afterwards */
|
||||
bool time_sync_required; /* true if local and remote need to be time synced */
|
||||
int unix_extensions; /* -1: do csync detection, 0: no unix extensions,
|
||||
1: extensions available */
|
||||
bool use_send_file_to_propagate; /* if set, the module rather copies files using send_file than read and write */
|
||||
bool get_support;
|
||||
bool put_support;
|
||||
};
|
||||
|
||||
typedef struct csync_vio_capabilities_s csync_vio_capabilities_t;
|
||||
|
||||
typedef csync_vio_method_t *(*csync_vio_method_init_fn)(const char *method_name,
|
||||
const char *config_args, csync_auth_callback cb, void *userdata);
|
||||
typedef void (*csync_vio_method_finish_fn)(csync_vio_method_t *method);
|
||||
|
||||
typedef csync_vio_capabilities_t *(*csync_method_get_capabilities_fn)(void);
|
||||
typedef const char* (*csync_method_get_etag_fn)(const char* path);
|
||||
typedef csync_vio_method_handle_t *(*csync_method_open_fn)(const char *durl, int flags, mode_t mode);
|
||||
typedef csync_vio_method_handle_t *(*csync_method_creat_fn)(const char *durl, mode_t mode);
|
||||
typedef int (*csync_method_close_fn)(csync_vio_method_handle_t *fhandle);
|
||||
typedef ssize_t (*csync_method_read_fn)(csync_vio_method_handle_t *fhandle, void *buf, size_t count);
|
||||
typedef ssize_t (*csync_method_write_fn)(csync_vio_method_handle_t *fhandle, const void *buf, size_t count);
|
||||
typedef int (*csync_method_sendfile_fn)(csync_vio_method_handle_t *src, csync_vio_method_handle_t *dst);
|
||||
typedef int64_t (*csync_method_lseek_fn)(csync_vio_method_handle_t *fhandle, int64_t offset, int whence);
|
||||
|
||||
typedef csync_vio_method_handle_t *(*csync_method_opendir_fn)(const char *name);
|
||||
typedef int (*csync_method_closedir_fn)(csync_vio_method_handle_t *dhandle);
|
||||
typedef csync_vio_file_stat_t *(*csync_method_readdir_fn)(csync_vio_method_handle_t *dhandle);
|
||||
|
||||
typedef int (*csync_method_mkdir_fn)(const char *uri, mode_t mode);
|
||||
typedef int (*csync_method_rmdir_fn)(const char *uri);
|
||||
|
||||
typedef int (*csync_method_stat_fn)(const char *uri, csync_vio_file_stat_t *buf);
|
||||
typedef int (*csync_method_rename_fn)(const char *olduri, const char *newuri);
|
||||
typedef int (*csync_method_unlink_fn)(const char *uri);
|
||||
|
||||
typedef int (*csync_method_chmod_fn)(const char *uri, mode_t mode);
|
||||
typedef int (*csync_method_chown_fn)(const char *uri, uid_t owner, gid_t group);
|
||||
|
||||
typedef int (*csync_method_utimes_fn)(const char *uri, const struct timeval times[2]);
|
||||
|
||||
typedef int (*csync_method_set_property_fn)(const char *key, void *data);
|
||||
|
||||
typedef char* (*csync_method_get_error_string_fn)();
|
||||
|
||||
typedef int (*csync_method_commit_fn)();
|
||||
|
||||
typedef int (*csync_method_get_fn)(csync_vio_method_handle_t *flocal,
|
||||
csync_vio_method_handle_t *fremote,
|
||||
csync_vio_file_stat_t *st);
|
||||
typedef int (*csync_method_put_fn)(csync_vio_method_handle_t *flocal,
|
||||
csync_vio_method_handle_t *fremote,
|
||||
csync_vio_file_stat_t *st);
|
||||
|
||||
struct csync_vio_method_s {
|
||||
size_t method_table_size; /* Used for versioning */
|
||||
csync_method_get_capabilities_fn get_capabilities;
|
||||
csync_method_open_fn open;
|
||||
csync_method_creat_fn creat;
|
||||
csync_method_close_fn close;
|
||||
csync_method_read_fn read;
|
||||
csync_method_write_fn write;
|
||||
csync_method_lseek_fn lseek;
|
||||
csync_method_opendir_fn opendir;
|
||||
csync_method_closedir_fn closedir;
|
||||
csync_method_readdir_fn readdir;
|
||||
csync_method_mkdir_fn mkdir;
|
||||
csync_method_rmdir_fn rmdir;
|
||||
csync_method_stat_fn stat;
|
||||
csync_method_rename_fn rename;
|
||||
csync_method_unlink_fn unlink;
|
||||
csync_method_chmod_fn chmod;
|
||||
csync_method_chown_fn chown;
|
||||
csync_method_utimes_fn utimes;
|
||||
csync_method_set_property_fn set_property;
|
||||
csync_method_get_error_string_fn get_error_string;
|
||||
csync_method_commit_fn commit;
|
||||
csync_method_put_fn put;
|
||||
csync_method_get_fn get;
|
||||
csync_method_get_etag_fn get_etag;
|
||||
csync_method_sendfile_fn sendfile;
|
||||
};
|
||||
|
||||
#endif /* _CSYNC_VIO_H */
|
||||
@@ -1,33 +0,0 @@
|
||||
/*
|
||||
* cynapses libc functions
|
||||
*
|
||||
* Copyright (c) 2008-2013 by Andreas Schneider <asn@cryptomilk.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef _CSYNC_VIO_MODULE_H
|
||||
#define _CSYNC_VIO_MODULE_H
|
||||
|
||||
#include "vio/csync_vio_method.h"
|
||||
|
||||
extern csync_vio_method_t *vio_module_init(const char *method_name,
|
||||
const char *args, csync_auth_callback cb, void *userdata);
|
||||
extern void vio_module_shutdown(csync_vio_method_t *method);
|
||||
|
||||
extern int csync_vio_getfd(csync_vio_handle_t *hnd);
|
||||
|
||||
|
||||
#endif /* _CSYNC_VIO_MODULE_H */
|
||||
@@ -38,7 +38,6 @@ add_cmocka_test(check_csync_create csync_tests/check_csync_create.c ${TEST_TARGE
|
||||
add_cmocka_test(check_csync_log csync_tests/check_csync_log.c ${TEST_TARGET_LIBRARIES})
|
||||
add_cmocka_test(check_csync_exclude csync_tests/check_csync_exclude.c ${TEST_TARGET_LIBRARIES})
|
||||
add_cmocka_test(check_csync_statedb_load csync_tests/check_csync_statedb_load.c ${TEST_TARGET_LIBRARIES})
|
||||
add_cmocka_test(check_csync_time csync_tests/check_csync_time.c ${TEST_TARGET_LIBRARIES})
|
||||
add_cmocka_test(check_csync_util csync_tests/check_csync_util.c ${TEST_TARGET_LIBRARIES})
|
||||
add_cmocka_test(check_csync_misc csync_tests/check_csync_misc.c ${TEST_TARGET_LIBRARIES})
|
||||
|
||||
@@ -47,11 +46,7 @@ add_cmocka_test(check_csync_init csync_tests/check_csync_init.c ${TEST_TARGET_LI
|
||||
add_cmocka_test(check_csync_statedb_query csync_tests/check_csync_statedb_query.c ${TEST_TARGET_LIBRARIES})
|
||||
add_cmocka_test(check_csync_commit csync_tests/check_csync_commit.c ${TEST_TARGET_LIBRARIES})
|
||||
|
||||
# treewalk
|
||||
add_cmocka_test(check_csync_treewalk csync_tests/check_csync_treewalk.c ${TEST_TARGET_LIBRARIES})
|
||||
|
||||
# vio
|
||||
add_cmocka_test(check_vio_handle vio_tests/check_vio_handle.c ${TEST_TARGET_LIBRARIES})
|
||||
add_cmocka_test(check_vio_file_stat vio_tests/check_vio_file_stat.c ${TEST_TARGET_LIBRARIES})
|
||||
add_cmocka_test(check_vio vio_tests/check_vio.c ${TEST_TARGET_LIBRARIES})
|
||||
|
||||
|
||||
@@ -46,9 +46,6 @@ static void check_csync_create(void **state)
|
||||
rc = csync_create(&csync, "/tmp/csync1", "/tmp/csync2");
|
||||
assert_int_equal(rc, 0);
|
||||
|
||||
assert_int_equal(csync->options.max_depth, MAX_DEPTH);
|
||||
assert_int_equal(csync->options.max_time_difference, MAX_TIME_DIFFERENCE);
|
||||
|
||||
snprintf(confdir, sizeof(confdir), "%s/%s", getenv("HOME"), CSYNC_CONF_DIR);
|
||||
assert_string_equal(csync->options.config_dir, confdir);
|
||||
|
||||
|
||||
@@ -26,7 +26,6 @@
|
||||
#include "csync_statedb.c"
|
||||
|
||||
#define TESTDB "/tmp/check_csync1/test.db"
|
||||
#define TESTDBTMP "/tmp/check_csync1/test.db.ctmp"
|
||||
|
||||
static void setup(void **state) {
|
||||
CSYNC *csync;
|
||||
@@ -43,6 +42,7 @@ static void setup(void **state) {
|
||||
|
||||
csync_set_config_dir(csync, "/tmp/check_csync1/");
|
||||
|
||||
csync->statedb.file = c_strdup( TESTDB );
|
||||
*state = csync;
|
||||
}
|
||||
|
||||
@@ -93,19 +93,12 @@ static void check_csync_statedb_check(void **state)
|
||||
static void check_csync_statedb_load(void **state)
|
||||
{
|
||||
CSYNC *csync = *state;
|
||||
csync_stat_t sb;
|
||||
int rc;
|
||||
mbchar_t *testdbtmp = c_utf8_to_locale(TESTDBTMP);
|
||||
assert_non_null( testdbtmp );
|
||||
|
||||
rc = csync_statedb_load(csync, TESTDB, &csync->statedb.db);
|
||||
assert_int_equal(rc, 0);
|
||||
|
||||
rc = _tstat(testdbtmp, &sb);
|
||||
assert_int_equal(rc, 0);
|
||||
|
||||
sqlite3_close(csync->statedb.db);
|
||||
c_free_locale_string(testdbtmp);
|
||||
}
|
||||
|
||||
static void check_csync_statedb_close(void **state)
|
||||
@@ -123,7 +116,7 @@ static void check_csync_statedb_close(void **state)
|
||||
assert_int_equal(rc, 0);
|
||||
modtime = sb.st_mtime;
|
||||
|
||||
rc = csync_statedb_close(TESTDB, csync->statedb.db, 0);
|
||||
rc = csync_statedb_close(csync);
|
||||
assert_int_equal(rc, 0);
|
||||
|
||||
rc = _tstat(testdb, &sb);
|
||||
@@ -140,12 +133,11 @@ static void check_csync_statedb_close(void **state)
|
||||
sleep(1);
|
||||
|
||||
/* statedb written */
|
||||
rc = csync_statedb_close(TESTDB, csync->statedb.db, 1);
|
||||
rc = csync_statedb_close(csync);
|
||||
assert_int_equal(rc, 0);
|
||||
|
||||
rc = _tstat(testdb, &sb);
|
||||
assert_int_equal(rc, 0);
|
||||
assert_true(modtime < sb.st_mtime);
|
||||
|
||||
c_free_locale_string(testdb);
|
||||
}
|
||||
|
||||
@@ -237,32 +237,19 @@ static void check_csync_statedb_get_stat_by_hash_not_found(void **state)
|
||||
CSYNC *csync = *state;
|
||||
csync_file_stat_t *tmp;
|
||||
|
||||
tmp = csync_statedb_get_stat_by_hash(csync->statedb.db, (uint64_t) 666);
|
||||
tmp = csync_statedb_get_stat_by_hash(csync, (uint64_t) 666);
|
||||
assert_null(tmp);
|
||||
|
||||
free(tmp);
|
||||
}
|
||||
|
||||
static void check_csync_statedb_get_stat_by_inode(void **state)
|
||||
{
|
||||
CSYNC *csync = *state;
|
||||
csync_file_stat_t *tmp;
|
||||
|
||||
tmp = csync_statedb_get_stat_by_inode(csync->statedb.db, (ino_t) 23);
|
||||
assert_non_null(tmp);
|
||||
|
||||
assert_int_equal(tmp->phash, 42);
|
||||
assert_int_equal(tmp->inode, 23);
|
||||
|
||||
free(tmp);
|
||||
}
|
||||
|
||||
static void check_csync_statedb_get_stat_by_inode_not_found(void **state)
|
||||
{
|
||||
CSYNC *csync = *state;
|
||||
csync_file_stat_t *tmp;
|
||||
|
||||
tmp = csync_statedb_get_stat_by_inode(csync->statedb.db, (ino_t) 666);
|
||||
tmp = csync_statedb_get_stat_by_inode(csync, (ino_t) 666);
|
||||
assert_null(tmp);
|
||||
}
|
||||
|
||||
@@ -272,14 +259,10 @@ int torture_run_tests(void)
|
||||
unit_test_setup_teardown(check_csync_statedb_query_statement, setup, teardown),
|
||||
unit_test_setup_teardown(check_csync_statedb_create_error, setup, teardown),
|
||||
unit_test_setup_teardown(check_csync_statedb_insert_statement, setup, teardown),
|
||||
/* unit_test_setup_teardown(check_csync_statedb_is_empty, setup, teardown), */
|
||||
/* unit_test_setup_teardown(check_csync_statedb_create_tables, setup, teardown), */
|
||||
unit_test_setup_teardown(check_csync_statedb_drop_tables, setup, teardown),
|
||||
unit_test_setup_teardown(check_csync_statedb_insert_metadata, setup, teardown),
|
||||
unit_test_setup_teardown(check_csync_statedb_write, setup, teardown),
|
||||
/* unit_test_setup_teardown(check_csync_statedb_get_stat_by_hash, setup_db, teardown), */
|
||||
unit_test_setup_teardown(check_csync_statedb_get_stat_by_hash_not_found, setup_db, teardown),
|
||||
/* unit_test_setup_teardown(check_csync_statedb_get_stat_by_inode, setup_db, teardown), */
|
||||
unit_test_setup_teardown(check_csync_statedb_get_stat_by_inode_not_found, setup_db, teardown),
|
||||
};
|
||||
|
||||
|
||||
@@ -1,69 +0,0 @@
|
||||
/*
|
||||
* libcsync -- a library to sync a directory with another
|
||||
*
|
||||
* Copyright (c) 2008-2013 by Andreas Schneider <asn@cryptomilk.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
#include "torture.h"
|
||||
|
||||
#include "csync_time.h"
|
||||
|
||||
static void setup(void **state) {
|
||||
CSYNC *csync;
|
||||
int rc;
|
||||
|
||||
rc = system("mkdir -p /tmp/check_csync1");
|
||||
assert_int_equal(rc, 0);
|
||||
rc = system("mkdir -p /tmp/check_csync2");
|
||||
assert_int_equal(rc, 0);
|
||||
rc = csync_create(&csync, "/tmp/check_csync1", "/tmp/check_csync2");
|
||||
assert_int_equal(rc, 0);
|
||||
|
||||
*state = csync;
|
||||
}
|
||||
|
||||
static void teardown(void **state) {
|
||||
CSYNC *csync = *state;
|
||||
int rc;
|
||||
|
||||
rc = csync_destroy(csync);
|
||||
assert_int_equal(rc, 0);
|
||||
|
||||
rc = system("rm -rf /tmp/check_csync1");
|
||||
assert_int_equal(rc, 0);
|
||||
rc = system("rm -rf /tmp/check_csync2");
|
||||
assert_int_equal(rc, 0);
|
||||
}
|
||||
|
||||
static void check_csync_time(void **state)
|
||||
{
|
||||
CSYNC *csync = *state;
|
||||
/*
|
||||
* The creation should took less than 1 second, so the return
|
||||
* value should be 0.
|
||||
*/
|
||||
assert_int_equal(csync_timediff(csync), 0);
|
||||
}
|
||||
|
||||
int torture_run_tests(void)
|
||||
{
|
||||
const UnitTest tests[] = {
|
||||
unit_test_setup_teardown(check_csync_time, setup, teardown),
|
||||
};
|
||||
|
||||
return run_tests(tests);
|
||||
}
|
||||
|
||||
@@ -1,202 +0,0 @@
|
||||
/*
|
||||
* libcsync -- a library to sync a directory with another
|
||||
*
|
||||
* Copyright (c) 2008-2013 by Andreas Schneider <asn@cryptomilk.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
#include <string.h>
|
||||
|
||||
#include "torture.h"
|
||||
|
||||
#define CSYNC_TEST 1
|
||||
#include "csync_private.h"
|
||||
|
||||
static void setup_local(void **state) {
|
||||
CSYNC *csync;
|
||||
int rc;
|
||||
|
||||
rc = system("mkdir -p /tmp/check_csync1");
|
||||
assert_int_equal(rc, 0);
|
||||
|
||||
rc = system("mkdir -p /tmp/check_csync2");
|
||||
assert_int_equal(rc, 0);
|
||||
|
||||
rc = system("mkdir -p /tmp/check_csync");
|
||||
assert_int_equal(rc, 0);
|
||||
|
||||
rc = system("echo \"This is test data\" > /tmp/check_csync1/testfile1.txt");
|
||||
assert_int_equal(rc, 0);
|
||||
|
||||
rc = system("echo \"This is also test data\" > /tmp/check_csync1/testfile2.txt");
|
||||
assert_int_equal(rc, 0);
|
||||
|
||||
rc = csync_create(&csync, "/tmp/check_csync1", "/tmp/check_csync2");
|
||||
assert_int_equal(rc, 0);
|
||||
|
||||
rc = csync_set_config_dir(csync, "/tmp/check_csync/");
|
||||
assert_int_equal(rc, 0);
|
||||
|
||||
rc = csync_init(csync);
|
||||
assert_int_equal(rc, 0);
|
||||
|
||||
*state = csync;
|
||||
}
|
||||
|
||||
static void teardown_local(void **state) {
|
||||
CSYNC *csync = (CSYNC *)*state;
|
||||
|
||||
csync_destroy(csync);
|
||||
system("rm -rf /tmp/check_csync1");
|
||||
system("rm -rf /tmp/check_csync2");
|
||||
system("rm -rf /tmp/check_csync");
|
||||
}
|
||||
|
||||
static void setup_remote(void **state) {
|
||||
CSYNC *csync = (CSYNC *)*state;
|
||||
int rc;
|
||||
|
||||
rc = system("mkdir -p /tmp/check_csync1");
|
||||
assert_int_equal(rc, 0);
|
||||
|
||||
rc = system("mkdir -p /tmp/check_csync2");
|
||||
assert_int_equal(rc, 0);
|
||||
|
||||
rc = system("echo \"This is test data\" > /tmp/check_csync2/testfile1.txt");
|
||||
assert_int_equal(rc, 0);
|
||||
|
||||
rc = system("echo \"This is also test data\" > /tmp/check_csync2/testfile2.txt");
|
||||
assert_int_equal(rc, 0);
|
||||
|
||||
rc = csync_create(&csync, "/tmp/check_csync1", "/tmp/check_csync2");
|
||||
assert_int_equal(rc, 0);
|
||||
|
||||
rc = csync_set_config_dir(csync, "/tmp/check_csync/");
|
||||
assert_int_equal(rc, 0);
|
||||
|
||||
rc = csync_init(csync);
|
||||
assert_int_equal(rc, 0);
|
||||
|
||||
*state = csync;
|
||||
}
|
||||
|
||||
static void teardown_remote(void **state) {
|
||||
CSYNC *csync = (CSYNC *)*state;
|
||||
|
||||
csync_destroy(csync);
|
||||
system("rm -rf /tmp/check_csync1");
|
||||
system("rm -rf /tmp/check_csync2");
|
||||
}
|
||||
|
||||
static int visitor(TREE_WALK_FILE* file, void *userdata)
|
||||
{
|
||||
int *file_count;
|
||||
|
||||
assert_non_null(userdata);
|
||||
assert_non_null(file);
|
||||
|
||||
file_count = (int *)userdata;
|
||||
|
||||
(*file_count)++;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void check_csync_treewalk_local(void **state)
|
||||
{
|
||||
CSYNC *csync = (CSYNC *)*state;
|
||||
int file_count = 0;
|
||||
int rc;
|
||||
|
||||
csync_set_userdata(csync, (void *)&file_count);
|
||||
|
||||
rc = csync_walk_local_tree(csync, &visitor, 0);
|
||||
assert_int_equal(rc, 0);
|
||||
assert_int_equal(file_count, 0);
|
||||
|
||||
rc = csync_update(csync);
|
||||
assert_int_equal(rc, 0);
|
||||
|
||||
rc = csync_walk_local_tree(csync, &visitor, 0);
|
||||
assert_int_equal(rc, 0);
|
||||
assert_int_equal(file_count, 2);
|
||||
}
|
||||
|
||||
static void check_csync_treewalk_remote(void **state)
|
||||
{
|
||||
CSYNC *csync = (CSYNC *)*state;
|
||||
int file_count = 0;
|
||||
int rc;
|
||||
|
||||
csync_set_userdata(csync, &file_count);
|
||||
|
||||
assert_non_null(csync->remote.tree);
|
||||
|
||||
rc = csync_walk_remote_tree(csync, &visitor, 0);
|
||||
assert_int_equal(rc, 0);
|
||||
assert_int_equal(file_count, 0);
|
||||
|
||||
/* reconcile doesn't update the tree */
|
||||
rc = csync_update(csync);
|
||||
assert_int_equal(rc, 0);
|
||||
|
||||
rc = csync_walk_remote_tree(csync, &visitor, 0);
|
||||
assert_int_equal(rc, 0);
|
||||
|
||||
assert_int_equal(file_count, 2);
|
||||
}
|
||||
|
||||
static void check_csync_treewalk_local_with_filter(void **state)
|
||||
{
|
||||
CSYNC *csync = (CSYNC *)*state;
|
||||
int file_count = 0;
|
||||
int rc;
|
||||
|
||||
csync_set_userdata(csync, &file_count);
|
||||
|
||||
rc = csync_walk_local_tree(csync, &visitor, 0);
|
||||
assert_int_equal(rc, 0);
|
||||
assert_int_equal(file_count, 0);
|
||||
|
||||
rc = csync_update(csync);
|
||||
assert_int_equal(rc, 0);
|
||||
|
||||
rc = csync_walk_local_tree(csync, &visitor, CSYNC_INSTRUCTION_NEW);
|
||||
assert_int_equal(rc, 0);
|
||||
assert_int_equal(file_count, 2 );
|
||||
|
||||
file_count = 0;
|
||||
rc = csync_walk_local_tree(csync,
|
||||
&visitor,
|
||||
CSYNC_INSTRUCTION_NEW|CSYNC_INSTRUCTION_REMOVE);
|
||||
assert_int_equal(rc, 0);
|
||||
assert_int_equal(file_count, 2);
|
||||
|
||||
file_count = 0;
|
||||
rc = csync_walk_local_tree(csync, &visitor, CSYNC_INSTRUCTION_RENAME);
|
||||
assert_int_equal(rc, 0);
|
||||
assert_int_equal(file_count, 0);
|
||||
}
|
||||
|
||||
int torture_run_tests(void)
|
||||
{
|
||||
const UnitTest tests[] = {
|
||||
unit_test_setup_teardown(check_csync_treewalk_local, setup_local, teardown_local ),
|
||||
unit_test_setup_teardown(check_csync_treewalk_remote, setup_remote, teardown_remote),
|
||||
unit_test_setup_teardown(check_csync_treewalk_local_with_filter, setup_local, teardown_local)
|
||||
};
|
||||
|
||||
return run_tests(tests);
|
||||
}
|
||||
@@ -233,8 +233,6 @@ static void check_csync_detect_update_db_none(void **state)
|
||||
st = c_rbtree_node_data(csync->local.tree->root);
|
||||
assert_int_equal(st->instruction, CSYNC_INSTRUCTION_NEW);
|
||||
|
||||
/* set the instruction to UPDATED that it gets written to the statedb */
|
||||
st->instruction = CSYNC_INSTRUCTION_UPDATED;
|
||||
|
||||
/* create a statedb */
|
||||
csync_set_status(csync, 0xFFFF);
|
||||
@@ -262,9 +260,6 @@ static void check_csync_detect_update_db_eval(void **state)
|
||||
st = c_rbtree_node_data(csync->local.tree->root);
|
||||
assert_int_equal(st->instruction, CSYNC_INSTRUCTION_NEW);
|
||||
|
||||
/* set the instruction to UPDATED that it gets written to the statedb */
|
||||
st->instruction = CSYNC_INSTRUCTION_UPDATED;
|
||||
|
||||
/* create a statedb */
|
||||
csync_set_status(csync, 0xFFFF);
|
||||
|
||||
@@ -344,8 +339,6 @@ static void check_csync_detect_update_db_new(void **state)
|
||||
st = c_rbtree_node_data(csync->local.tree->root);
|
||||
assert_int_equal(st->instruction, CSYNC_INSTRUCTION_NEW);
|
||||
|
||||
/* set the instruction to UPDATED that it gets written to the statedb */
|
||||
st->instruction = CSYNC_INSTRUCTION_UPDATED;
|
||||
|
||||
/* create a statedb */
|
||||
csync_set_status(csync, 0xFFFF);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -31,6 +31,10 @@ Before it actually ends, it takes a four seconds break for you to
|
||||
interrupt with Ctrl-C. If you don't do that, it removes all its
|
||||
traces...
|
||||
|
||||
If SSL should be used, SSL must be available to LWP connections. To
|
||||
disable host checking for crappy SSL certs, do
|
||||
export PERL_LWP_SSL_VERIFY_HOSTNAME=0
|
||||
|
||||
Have fun,
|
||||
Klaas Freitag <freitag@owncloud.com>
|
||||
|
||||
|
||||
@@ -24,14 +24,15 @@ package ownCloud::Test;
|
||||
use strict;
|
||||
use Exporter;
|
||||
|
||||
use HTTP::DAV;
|
||||
use HTTP::DAV 0.47;
|
||||
use Data::Dumper;
|
||||
use File::Glob ':glob';
|
||||
use Carp::Assert;
|
||||
use Digest::MD5;
|
||||
use Unicode::Normalize;
|
||||
use LWP::UserAgent;
|
||||
use HTTP::Request::Common;
|
||||
use LWP::Protocol::https;
|
||||
use HTTP::Request::Common qw( POST GET DELETE );
|
||||
use File::Basename;
|
||||
|
||||
use Encode qw(from_to);
|
||||
@@ -45,21 +46,26 @@ use open ':encoding(utf8)';
|
||||
use vars qw( @ISA @EXPORT @EXPORT_OK $d %config);
|
||||
|
||||
our $owncloud = "http://localhost/oc/remote.php/webdav/";
|
||||
our $owncloud_plain; # the server url without the uniq testing dir
|
||||
our $user = "joe";
|
||||
our $passwd = 'XXXXX'; # Mind to be secure.
|
||||
our $ld_libpath = "/home/joe/owncloud.com/buildcsync/modules";
|
||||
our $csync = "/home/joe/owncloud.com/buildcsync/client/ocsync";
|
||||
our $ocs_url;
|
||||
our $share_user;
|
||||
our $share_passwd;
|
||||
our $remoteDir;
|
||||
our $localDir;
|
||||
our $infoCnt = 1;
|
||||
|
||||
our %config;
|
||||
|
||||
@ISA = qw(Exporter);
|
||||
@EXPORT = qw( initTesting createRemoteDir createLocalDir cleanup csync
|
||||
assertLocalDirs assertLocalAndRemoteDir glob_put put_to_dir
|
||||
putToDirLWP localDir remoteDir localCleanup createLocalFile md5OfFile
|
||||
remoteCleanup server initLocalDir initRemoteDir moveRemoteFile
|
||||
printInfo remoteFileId);
|
||||
printInfo remoteFileId createShare removeShare
|
||||
configValue testDirUrl getToFileLWP getToFileCurl);
|
||||
|
||||
sub server
|
||||
{
|
||||
@@ -82,23 +88,38 @@ sub initTesting(;$)
|
||||
{
|
||||
my ($prefix) = @_;
|
||||
|
||||
if( -r "./t1.cfg" ) {
|
||||
my %config = do 't1.cfg';
|
||||
my $cfgFile = "./t1.cfg";
|
||||
$cfgFile = "/etc/ownCloud/t1.cfg" if( -r "/etc/ownCloud/t1.cfg" );
|
||||
|
||||
if( -r "$cfgFile" ) {
|
||||
%config = do $cfgFile;
|
||||
warn "Could not parse t1.cfg: $!\n" unless %config;
|
||||
warn "Could not do t1.cfg: $@\n" if $@;
|
||||
|
||||
$user = $config{user} if( $config{user} );
|
||||
$passwd = $config{passwd} if( $config{passwd} );
|
||||
$owncloud = $config{url} if( $config{url} );
|
||||
$ld_libpath = $config{ld_libpath} if( $config{ld_libpath} );
|
||||
$csync = $config{csync} if( $config{csync} );
|
||||
print "Read t1.cfg: $config{url}\n";
|
||||
$user = $config{user} if( $config{user} );
|
||||
$passwd = $config{passwd} if( $config{passwd} );
|
||||
$owncloud = $config{url} if( $config{url} );
|
||||
$ld_libpath = $config{ld_libpath} if( $config{ld_libpath} );
|
||||
$csync = $config{csync} if( $config{csync} );
|
||||
$ocs_url = $config{ocs_url} if( $config{ocs_url} );
|
||||
$share_user = $config{share_user} if( $config{share_user} );
|
||||
$share_passwd = $config{share_passwd} if( $config{share_passwd} );
|
||||
|
||||
print "Read config from $cfgFile: $config{url}\n";
|
||||
} else {
|
||||
print STDERR "Could not read a config file $cfgFile\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
$owncloud .= "/" unless( $owncloud =~ /\/$/ );
|
||||
|
||||
|
||||
print "Connecting to ownCloud at ". $owncloud ."\n";
|
||||
|
||||
# For SSL set the environment variable needed by the LWP module for SSL
|
||||
if( $owncloud =~ /^https/ ) {
|
||||
$ENV{PERL_LWP_SSL_VERIFY_HOSTNAME} = 0
|
||||
}
|
||||
|
||||
$d = HTTP::DAV->new();
|
||||
|
||||
$d->credentials( -url=> $owncloud, -realm=>"ownCloud",
|
||||
@@ -119,19 +140,38 @@ sub initTesting(;$)
|
||||
printf( "Test directory name is %s\n", $dir );
|
||||
}
|
||||
|
||||
sub configValue($;$)
|
||||
{
|
||||
my ($configName, $default) = @_;
|
||||
|
||||
if( $config{$configName} ) {
|
||||
return $config{$configName} ;
|
||||
} else {
|
||||
return $default;
|
||||
}
|
||||
}
|
||||
|
||||
# Returns the full url to the testing dir, ie.
|
||||
# http://localhost/owncloud/remote.php/webdav/t1-0543
|
||||
sub testDirUrl()
|
||||
{
|
||||
print "WARN: Remote dir still empty, first call initRemoteDir!\n" unless($remoteDir);
|
||||
return $owncloud . $remoteDir;
|
||||
}
|
||||
|
||||
# Call this first to create the unique test dir stored in
|
||||
# the global var $remoteDir;
|
||||
sub initRemoteDir
|
||||
{
|
||||
$d->open( $owncloud );
|
||||
$owncloud .= $remoteDir;
|
||||
|
||||
my $re = $d->mkcol( $owncloud );
|
||||
my $url = testDirUrl();
|
||||
|
||||
my $re = $d->mkcol( $url );
|
||||
if( $re == 0 ) {
|
||||
print "Failed to create test dir $owncloud\n";
|
||||
print "Failed to create test dir $url\n";
|
||||
exit 1;
|
||||
}
|
||||
# $owncloud .= $remoteDir;
|
||||
|
||||
}
|
||||
|
||||
sub initLocalDir
|
||||
@@ -139,21 +179,31 @@ sub initLocalDir
|
||||
mkdir ($localDir, 0777 );
|
||||
}
|
||||
|
||||
sub createRemoteDir(;$)
|
||||
sub createRemoteDir(;$$)
|
||||
{
|
||||
my ($dir) = @_;
|
||||
my ($dir, $optionsRef) = @_;
|
||||
|
||||
my $url = $owncloud . $dir;
|
||||
my $url = testDirUrl() . $dir;
|
||||
|
||||
if( $optionsRef && $optionsRef->{user} && $optionsRef->{passwd} ) {
|
||||
$d->credentials( -url=> $owncloud, -realm=>"ownCloud",
|
||||
-user=> $optionsRef->{user},
|
||||
-pass=> $optionsRef->{passwd} );
|
||||
if( $optionsRef->{url} ) {
|
||||
$url = $optionsRef->{url} . $dir;
|
||||
}
|
||||
}
|
||||
|
||||
$d->open( $owncloud );
|
||||
print $d->message . "\n";
|
||||
|
||||
my $re = $d->mkcol( $url );
|
||||
if( $re == 0 ) {
|
||||
print "Failed to create directory <$url>: $re\n";
|
||||
print "Failed to create directory <$url>: $d->message() \n";
|
||||
exit 1;
|
||||
}
|
||||
$d->open( $url );
|
||||
|
||||
return $re;
|
||||
|
||||
}
|
||||
@@ -186,14 +236,15 @@ sub cleanup()
|
||||
sub remoteCleanup($)
|
||||
{
|
||||
my ($dir) = @_;
|
||||
$d->open( -url => $owncloud . $dir );
|
||||
my $url = testDirUrl().$dir;
|
||||
$d->open( -url => $url );
|
||||
|
||||
print "Cleaning Remote!\n";
|
||||
|
||||
my $re = $d->delete( $owncloud . $dir );
|
||||
my $re = $d->delete( $url );
|
||||
|
||||
if( $re == 0 ) {
|
||||
print "Failed to clenup directory <$owncloud $dir>\n";
|
||||
print "Failed to cleanup directory <$url>\n";
|
||||
}
|
||||
return $re;
|
||||
}
|
||||
@@ -206,14 +257,26 @@ sub localCleanup($)
|
||||
system( "rm -rf $dir" );
|
||||
}
|
||||
|
||||
sub csync( )
|
||||
# parameter: An optional full url to the owncloud sync dir.
|
||||
sub csync( ;$ )
|
||||
{
|
||||
my $url = $owncloud;
|
||||
$url =~ s#^http://##; # Remove the leading http://
|
||||
$url = "owncloud://$user:$passwd@". $url;
|
||||
my ($aurl) = @_;
|
||||
|
||||
my $url = testDirUrl();
|
||||
if( $aurl ) {
|
||||
$url = $aurl;
|
||||
}
|
||||
if( $url =~ /^https:/ ) {
|
||||
$url =~ s#^https://##; # Remove the leading http://
|
||||
$url = "ownclouds://$user:$passwd@". $url;
|
||||
} elsif( $url =~ /^http:/ ) {
|
||||
$url =~ s#^http://##;
|
||||
$url = "owncloud://$user:$passwd@". $url;
|
||||
}
|
||||
|
||||
print "CSync URL: $url\n";
|
||||
|
||||
my $args = ""; # "--exclude-file=exclude.cfg -c";
|
||||
my $args = "--trust"; # Trust crappy SSL certificates
|
||||
my $cmd = "LD_LIBRARY_PATH=$ld_libpath $csync $args $localDir $url";
|
||||
print "Starting: $cmd\n";
|
||||
|
||||
@@ -285,15 +348,24 @@ sub registerSeen($$)
|
||||
$seenRef->{$file} = 1;
|
||||
}
|
||||
|
||||
sub traverse( $$ )
|
||||
sub traverse( $$;$ )
|
||||
{
|
||||
my ($remote, $acceptConflicts) = @_;
|
||||
my ($remote, $acceptConflicts, $aurl) = @_;
|
||||
$remote .= '/' unless $remote =~ /(^|\/)$/;
|
||||
printf("===============> $remote\n");
|
||||
|
||||
my $url = $owncloud . $remote;
|
||||
my $url = testDirUrl() . $remote;
|
||||
if( $aurl ) {
|
||||
$url = $aurl . $remote;
|
||||
}
|
||||
printf("===============> $url\n");
|
||||
my %seen;
|
||||
|
||||
|
||||
$d->credentials( -url=> $owncloud, -realm=>"ownCloud",
|
||||
-user=> $user,
|
||||
-pass=> $passwd );
|
||||
$d->open( $owncloud );
|
||||
|
||||
if( my $r = $d->propfind( -url => $url, -depth => 1 ) ) {
|
||||
|
||||
if( $r->get_resourcelist ) {
|
||||
@@ -304,12 +376,15 @@ sub traverse( $$ )
|
||||
# print "Checking " . $res-> get_uri()->as_string ."\n";
|
||||
print "Traversing into directory: $filename\n";
|
||||
my $dirname = $remote . $filename;
|
||||
traverse( $dirname, $acceptConflicts );
|
||||
registerSeen( \%seen, $localDir . $dirname );
|
||||
traverse( $dirname, $acceptConflicts, $aurl );
|
||||
my $localDirName = $localDir . $dirname;
|
||||
$localDirName =~ s/Shared\///g;
|
||||
registerSeen( \%seen, $localDirName); # . $dirname
|
||||
} else {
|
||||
# Check files here.
|
||||
print "Checking file: $remote$filename\n";
|
||||
my $localFile = $localDir . $remote . $filename;
|
||||
$localFile =~ s/Shared\///g;
|
||||
registerSeen( \%seen, $localFile );
|
||||
# $localFile =~ s/t1-\d+\//t1\//;
|
||||
|
||||
@@ -324,7 +399,8 @@ sub traverse( $$ )
|
||||
# Check the directory contents
|
||||
my $localpath = localDir();
|
||||
$localpath .= $remote if( $remote ne "/" );
|
||||
print "#### localpath = " . $localpath . "\n";
|
||||
$localpath =~ s/Shared\///g;
|
||||
print "#### localpath = " . $localpath . "\n";
|
||||
opendir(my $dh, $localpath ) || die;
|
||||
# print Dumper( %seen );
|
||||
while( readdir $dh ) {
|
||||
@@ -356,20 +432,19 @@ sub traverse( $$ )
|
||||
closedir $dh;
|
||||
}
|
||||
|
||||
sub assertLocalAndRemoteDir( $$ )
|
||||
sub assertLocalAndRemoteDir( $$;$ )
|
||||
{
|
||||
my ($remote, $acceptConflicts ) = @_;
|
||||
# %seen = ();
|
||||
traverse( $remote, $acceptConflicts );
|
||||
my ($remote, $acceptConflicts, $aurl ) = @_;
|
||||
traverse( $remote, $acceptConflicts, $aurl );
|
||||
}
|
||||
|
||||
sub glob_put( $$ )
|
||||
#
|
||||
# the third parameter is an optional hash ref that can contain
|
||||
# the keys user, passwd and url for alternative connection settings
|
||||
#
|
||||
sub glob_put( $$;$ )
|
||||
{
|
||||
my( $globber, $target ) = @_;
|
||||
|
||||
# $target = $owncloud . $target;
|
||||
|
||||
$d->open( $target );
|
||||
my( $globber, $target, $optionsRef ) = @_;
|
||||
|
||||
my @puts = bsd_glob( $globber );
|
||||
foreach my $llfile( @puts ) {
|
||||
@@ -384,7 +459,7 @@ sub glob_put( $$ )
|
||||
$puturl = $target;
|
||||
print " *** Putting $lfile to $puturl\n";
|
||||
# putToDirLWP( $lfile, $puturl );
|
||||
put_to_dir($lfile, $puturl);
|
||||
put_to_dir($lfile, $puturl, $optionsRef);
|
||||
|
||||
# if( ! $d->put( -local=>$lfile, -url=> $puturl ) ) {
|
||||
#print " ### FAILED to put: ". $d->message . '\n';
|
||||
@@ -395,16 +470,26 @@ sub glob_put( $$ )
|
||||
}
|
||||
}
|
||||
|
||||
sub put_to_dir( $$ )
|
||||
sub put_to_dir( $$;$ )
|
||||
{
|
||||
my ($file, $dir) = @_;
|
||||
my ($file, $dir, $optionsRef) = @_;
|
||||
|
||||
$dir .="/" unless $dir =~ /\/$/;
|
||||
my $targetUrl = testDirUrl();
|
||||
|
||||
if( $optionsRef && $optionsRef->{user} && $optionsRef->{passwd} ) {
|
||||
$d->credentials( -url=> $owncloud, -realm=>"ownCloud",
|
||||
-user=> $optionsRef->{user},
|
||||
-pass=> $optionsRef->{passwd} );
|
||||
if( $optionsRef->{url} ) {
|
||||
$targetUrl = $optionsRef->{url};
|
||||
}
|
||||
}
|
||||
$d->open($dir);
|
||||
|
||||
my $filename = $file;
|
||||
$filename =~ s/^.*\///;
|
||||
my $puturl = $owncloud . $dir. $filename;
|
||||
my $puturl = $targetUrl . $dir. $filename;
|
||||
print "put_to_dir puts to $puturl\n";
|
||||
unless ($d->put( -local => $file, -url => $puturl )) {
|
||||
print " ### FAILED to put a single file!\n";
|
||||
@@ -424,7 +509,7 @@ sub putToDirLWP($$)
|
||||
my $basename = basename $filename;
|
||||
|
||||
$dir =~ s/^\.\///;
|
||||
my $puturl = $owncloud . $dir. $basename;
|
||||
my $puturl = testDirUrl() . $dir. $basename;
|
||||
# print "putToDir LWP puts $filename to $puturl\n";
|
||||
die("Could not open $filename: $!") unless( open FILE, "$filename" );
|
||||
binmode FILE, ":utf8";;
|
||||
@@ -445,6 +530,41 @@ sub putToDirLWP($$)
|
||||
}
|
||||
}
|
||||
|
||||
# does a simple GET of a file in the testdir to a local file.
|
||||
|
||||
sub getToFileCurl( $$ )
|
||||
{
|
||||
my ($file, $localFile) = @_;
|
||||
my $geturl = testDirUrl() . $file;
|
||||
print "GETting $geturl to $localFile\n";
|
||||
|
||||
my @args = ("curl", "-k", "-u", "$user:$passwd", "$geturl", "-o", "$localFile");
|
||||
system( @args );
|
||||
}
|
||||
|
||||
# FIXME: This does not work because I can not get an authenticated GET request
|
||||
# that writes its content to a file. Strange.
|
||||
sub getToFileLWP( $$ )
|
||||
{
|
||||
my ($file, $localFile) = @_;
|
||||
my $geturl = testDirUrl() . $file;
|
||||
print "GETting $geturl to $localFile\n";
|
||||
|
||||
my $ua = LWP::UserAgent->new();
|
||||
$ua->agent( "ownCloudTest_$localDir");
|
||||
$ua->credentials( server(), "foo", $user, $passwd);
|
||||
my $req = $ua->get($geturl, ":content_file" => $localFile);
|
||||
# my $req = HTTP::Request->new( GET => $geturl, ':content_file' => $localFile);
|
||||
# $req->authorization_basic("$user", "$passwd");
|
||||
# my $response = $ua->request($req);
|
||||
|
||||
if ($req->is_success()) {
|
||||
print "OK: ", $req->content;
|
||||
} else {
|
||||
die( "HTTP GET failed: " . $req->as_string );
|
||||
}
|
||||
}
|
||||
|
||||
sub createLocalFile( $$ )
|
||||
{
|
||||
my ($fname, $size) = @_;
|
||||
@@ -489,8 +609,8 @@ sub moveRemoteFile($$)
|
||||
{
|
||||
my ($from, $to) = @_;
|
||||
|
||||
my $fromUrl = $owncloud . $from;
|
||||
my $toUrl = $owncloud . $to;
|
||||
my $fromUrl = testDirUrl(). $from;
|
||||
my $toUrl = testDirUrl() . $to;
|
||||
|
||||
$d->move($fromUrl, $toUrl);
|
||||
|
||||
@@ -513,7 +633,7 @@ sub printInfo($)
|
||||
sub remoteFileId($$)
|
||||
{
|
||||
my ($fromDir, $file) = @_;
|
||||
my $fromUrl = $owncloud . $fromDir;
|
||||
my $fromUrl = testDirUrl() . $fromDir;
|
||||
my $id;
|
||||
|
||||
if( my $r = $d->propfind( -url => $fromUrl, -depth => 1 ) ) {
|
||||
@@ -536,4 +656,90 @@ sub remoteFileId($$)
|
||||
return $id;
|
||||
}
|
||||
|
||||
# Creates a read write share from the config file user 'share_user' to the
|
||||
# config file user 'user'
|
||||
# readWrite: permission flag. 31 for all permissions (read/write/create etc)
|
||||
# and 1 for read only
|
||||
sub createShare($$)
|
||||
{
|
||||
my ($dir, $readWrite) = @_;
|
||||
|
||||
my $dd = HTTP::DAV->new();
|
||||
|
||||
$dd->credentials( -url=> $owncloud, -realm=>"ownCloud",
|
||||
-user=> $share_user,
|
||||
-pass=> $share_passwd );
|
||||
$dd->open( $owncloud);
|
||||
|
||||
# create a remote dir
|
||||
my $url = $owncloud . $dir;
|
||||
|
||||
my $re = $dd->mkcol( $url );
|
||||
if( $re == 0 ) {
|
||||
print "Failed to create test dir $url\n";
|
||||
|
||||
}
|
||||
|
||||
my $ua = LWP::UserAgent->new();
|
||||
$ua->agent( "ownCloudTest_sharing");
|
||||
# http://localhost/ocm/ocs/v1.php/apps/files_sharing/api/v1/shares
|
||||
my $puturl = $ocs_url . "apps/files_sharing/api/v1/shares";
|
||||
|
||||
my $string = "path=$dir&shareType=0&shareWith=$user&publicUpload=false&permissions=$readWrite";
|
||||
print ">>>>>>>>>> $string\n";
|
||||
|
||||
my $req = POST $puturl, Content => $string;
|
||||
$req->authorization_basic($share_user, $share_passwd);
|
||||
my $response = $ua->request($req);
|
||||
|
||||
my $id = 0;
|
||||
if ($response->is_success()) {
|
||||
# print "OK: ", $response->content;
|
||||
print $response->decoded_content;
|
||||
if( $response->decoded_content =~ /<id>(\d+)<\/id>/m) {
|
||||
$id = $1;
|
||||
}
|
||||
} else {
|
||||
die( "Create sharing failed: " . $response->as_string );
|
||||
}
|
||||
return $id;
|
||||
}
|
||||
|
||||
sub removeShare($$)
|
||||
{
|
||||
my ($shareId, $dir) = @_;
|
||||
|
||||
my $dd = HTTP::DAV->new();
|
||||
|
||||
$dd->credentials( -url => $owncloud, -realm=>"ownCloud",
|
||||
-user => $share_user,
|
||||
-pass => $share_passwd );
|
||||
$dd->open( $owncloud);
|
||||
|
||||
my $ua = LWP::UserAgent->new();
|
||||
$ua->agent( "ownCloudTest_sharing");
|
||||
# http://localhost/ocm/ocs/v1.php/apps/files_sharing/api/v1/shares
|
||||
my $url = $ocs_url . "apps/files_sharing/api/v1/shares/" . $shareId;
|
||||
|
||||
my $req = DELETE $url;
|
||||
$req->authorization_basic($share_user, $share_passwd);
|
||||
my $response = $ua->request($req);
|
||||
|
||||
if ($response->is_success()) {
|
||||
# print "OK: ", $response->content;
|
||||
print $response->decoded_content;
|
||||
if( $response->decoded_content =~ /<status_code>(\d+)<\/status_code>/m) {
|
||||
my $code = $1;
|
||||
assert( $code == 100 );
|
||||
}
|
||||
} else {
|
||||
die( "Create sharing failed: " . $response->as_string );
|
||||
}
|
||||
|
||||
# remove the share dir
|
||||
my $req = DELETE $owncloud . $dir;
|
||||
$req->authorization_basic($share_user, $share_passwd);
|
||||
my $response = $ua->request($req);
|
||||
}
|
||||
|
||||
#
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
user => "joe",
|
||||
user => "joe",
|
||||
passwd => "secret",
|
||||
url => "http://localhost/ocm/remote.php/webdav/",
|
||||
ld_libpath => "/home/joe/owncloud/csync/csync-build/modules",
|
||||
csync => "/home/joe/owncloud/csync/csync-build/client/csync"
|
||||
csync => "/home/joe/owncloud/csync/csync-build/client/csync",
|
||||
ocs_url => "http://localhost/owncloud/ocs/v1.php/",
|
||||
share_user => "jenny",
|
||||
share_passwd => "also_secret"
|
||||
|
||||
@@ -56,13 +56,13 @@ assertLocalDirs( 'toremote1', localDir().'remoteToLocal1' );
|
||||
|
||||
# Check if the synced files from ownCloud have the same timestamp as the local ones.
|
||||
print "\nNow assert remote 'toremote1' with local " . localDir() . " :\n";
|
||||
assertLocalAndRemoteDir( 'remoteToLocal1', 0);
|
||||
assertLocalAndRemoteDir( '', 0);
|
||||
|
||||
# remove a local file.
|
||||
printInfo( "\nRemove a local file\n" );
|
||||
unlink( localDir() . 'remoteToLocal1/kernelcrash.txt' );
|
||||
unlink( localDir() . 'remoteToLocal1/rtl4/quitte.pdf' );
|
||||
csync();
|
||||
assertLocalAndRemoteDir( 'remoteToLocal1', 0);
|
||||
assertLocalAndRemoteDir( '', 0);
|
||||
|
||||
# add local files to a new dir1
|
||||
printInfo( "Add some more files to local:");
|
||||
@@ -76,34 +76,46 @@ foreach my $file ( <./tolocal1/*> ) {
|
||||
}
|
||||
csync( );
|
||||
print "\nAssert local and remote dirs.\n";
|
||||
assertLocalAndRemoteDir( 'fromLocal1', 0);
|
||||
assertLocalAndRemoteDir( '', 0);
|
||||
|
||||
# move a local file
|
||||
printInfo( "Move a file locally." );
|
||||
move( "$locDir/kramer.jpg", "$locDir/oldtimer.jpg" );
|
||||
csync( );
|
||||
assertLocalAndRemoteDir( 'fromLocal1', 0);
|
||||
assertLocalAndRemoteDir( '', 0);
|
||||
|
||||
# move a local directory.
|
||||
printInfo( "Move a local directory." );
|
||||
move( localDir() . 'remoteToLocal1/rtl1', localDir(). 'remoteToLocal1/rtlX');
|
||||
csync();
|
||||
assertLocalAndRemoteDir( 'fromLocal1', 0);
|
||||
assertLocalAndRemoteDir( '', 0);
|
||||
|
||||
# remove a local dir
|
||||
printInfo( "Remove a local directory.");
|
||||
localCleanup( 'remoteToLocal1/rtlX' );
|
||||
csync();
|
||||
assertLocalAndRemoteDir( 'fromLocal1', 0);
|
||||
assertLocalAndRemoteDir( '', 0);
|
||||
assert( ! -e localDir().'remoteToLocal1/rtlX' );
|
||||
|
||||
# create a false conflict, only the mtimes are changed, by content are equal.
|
||||
printInfo( "Create a false conflict.");
|
||||
my $srcFile = 'toremote1/kernelcrash.txt';
|
||||
put_to_dir( $srcFile, 'remoteToLocal1' );
|
||||
# create twos false conflict, only the mtimes are changed, by content are equal.
|
||||
printInfo( "Create two false conflict.");
|
||||
put_to_dir( 'toremote1/kernelcrash.txt', 'remoteToLocal1' );
|
||||
put_to_dir( 'toremote1/kraft_logo.gif', 'remoteToLocal1' );
|
||||
# don't wait so mtime are likely the same on the client and the server.
|
||||
system( "touch " . localDir() . "remoteToLocal1/kraft_logo.gif" );
|
||||
# wait two second so the mtime are different
|
||||
system( "sleep 2 && touch " . localDir() . "remoteToLocal1/kernelcrash.txt" );
|
||||
|
||||
|
||||
csync( );
|
||||
assertLocalAndRemoteDir( 'fromLocal1', 0);
|
||||
assertLocalAndRemoteDir( '', 0);
|
||||
|
||||
# The previous sync should have updated the etags, and this should NOT be a conflict
|
||||
printInfo( "Update the file again");
|
||||
system("echo more data >> " . localDir() . "remoteToLocal1/kernelcrash.txt");
|
||||
system("echo corruption >> " . localDir() . "remoteToLocal1/kraft_logo.gif");
|
||||
csync( );
|
||||
assertLocalAndRemoteDir( '', 0);
|
||||
|
||||
# create a true conflict.
|
||||
printInfo( "Create a conflict." );
|
||||
@@ -111,13 +123,14 @@ system( "echo \"This is more stuff\" >> /tmp/kernelcrash.txt" );
|
||||
put_to_dir( '/tmp/kernelcrash.txt', 'remoteToLocal1' );
|
||||
system( "sleep 2 && touch " . localDir() . "remoteToLocal1/kernelcrash.txt" );
|
||||
csync();
|
||||
assertLocalAndRemoteDir( 'remoteToLocal1', 1);
|
||||
assertLocalAndRemoteDir( '', 1);
|
||||
|
||||
my $localMD5 = md5OfFile( localDir().'remoteToLocal1/kernelcrash.txt' );
|
||||
my $realMD5 = md5OfFile( '/tmp/kernelcrash.txt' );
|
||||
print "MD5 compare $localMD5 <-> $realMD5\n";
|
||||
assert( $localMD5 eq $realMD5 );
|
||||
assert( glob(localDir().'remoteToLocal1/kernelcrash_conflict-*.txt' ) );
|
||||
system("rm " . localDir().'remoteToLocal1/kernelcrash_conflict-*.txt' );
|
||||
|
||||
|
||||
# prepare test for issue 1329, rtlX need to be modified
|
||||
@@ -125,13 +138,13 @@ assert( glob(localDir().'remoteToLocal1/kernelcrash_conflict-*.txt' ) );
|
||||
printInfo( "Add a local directory");
|
||||
system("cp -r 'toremote1/rtl1/' '" . localDir(). "remoteToLocal1/rtlX'");
|
||||
csync();
|
||||
assertLocalAndRemoteDir( 'fromLocal1', 0);
|
||||
assertLocalAndRemoteDir( '', 0);
|
||||
|
||||
# remove a local dir (still for issue 1329)
|
||||
printInfo( "Remove that directory.");
|
||||
localCleanup( 'remoteToLocal1/rtlX' );
|
||||
csync();
|
||||
assertLocalAndRemoteDir( 'fromLocal1', 0);
|
||||
assertLocalAndRemoteDir( '', 0);
|
||||
assert( ! -e localDir().'remoteToLocal1/rtlX' );
|
||||
|
||||
|
||||
@@ -141,12 +154,10 @@ system("cp -r 'toremote1/rtl1/' '" . localDir(). "remoteToLocal1/rtlX'");
|
||||
assert( -e localDir().'remoteToLocal1/rtlX' );
|
||||
assert( -e localDir().'remoteToLocal1/rtlX/rtl11/file.txt' );
|
||||
csync();
|
||||
assertLocalAndRemoteDir( 'fromLocal1', 0);
|
||||
assertLocalAndRemoteDir( '', 0);
|
||||
assert( -e localDir().'remoteToLocal1/rtlX' );
|
||||
assert( -e localDir().'remoteToLocal1/rtlX/rtl11/file.txt' );
|
||||
|
||||
|
||||
|
||||
# ==================================================================
|
||||
|
||||
cleanup();
|
||||
|
||||
@@ -80,7 +80,6 @@ assert( $inode == $inode2, "Inode has changed!");
|
||||
|
||||
printInfo("Move a file into a sub directory.");
|
||||
# now move the file into a sub directory
|
||||
$inode = getInode('remoteToLocal1/kernel.txt');
|
||||
moveRemoteFile( 'remoteToLocal1/kernel.txt', 'remoteToLocal1/rtl1/');
|
||||
|
||||
csync();
|
||||
@@ -175,6 +174,24 @@ createLocalFile( localDir(). 'remoteToLocal1/rtl2/newRemoteDir/donat.txt', 8021
|
||||
csync();
|
||||
assertLocalAndRemoteDir( 'remoteToLocal1', 1);
|
||||
|
||||
printInfo("simulate a owncloud 5 update by removing all the fileid");
|
||||
## simulate a owncloud 5 update by removing all the fileid
|
||||
system( "sqlite3 " . localDir() . ".csync_journal.db \"UPDATE metadata SET fileid='';\"");
|
||||
#refresh the ids
|
||||
csync();
|
||||
assertLocalAndRemoteDir( 'remoteToLocal1', 1);
|
||||
|
||||
|
||||
printInfo("Move a file from the server");
|
||||
$inode = getInode('remoteToLocal1/rtl2/kb1_local_gone.jpg');
|
||||
moveRemoteFile( 'remoteToLocal1/rtl2/kb1_local_gone.jpg', 'remoteToLocal1/rtl2/kb1_local_gone2.jpg');
|
||||
csync();
|
||||
assertLocalAndRemoteDir( 'remoteToLocal1', 1);
|
||||
$inode2 = getInode('remoteToLocal1/rtl2/kb1_local_gone2.jpg');
|
||||
assert( $inode == $inode2, "Inode has changed 3!");
|
||||
|
||||
|
||||
|
||||
cleanup();
|
||||
|
||||
# --
|
||||
|
||||
@@ -108,6 +108,12 @@ remoteCleanup('test_stat');
|
||||
system( "echo echo hello >> " . localDir() . 'echo.sh' );
|
||||
chmod 0751, localDir() . 'echo.sh';
|
||||
|
||||
#and add a file in anotherdir for the next test
|
||||
mkdir( localDir() . 'anotherdir' );
|
||||
mkdir( localDir() . 'anotherdir/sub' );
|
||||
system( "echo foobar > " . localDir() . 'anotherdir/file1.txt' );
|
||||
system( "echo foobar > " . localDir() . 'anotherdir/sub/file2.txt' );
|
||||
|
||||
csync();
|
||||
assertLocalAndRemoteDir( '', 0 );
|
||||
|
||||
@@ -126,6 +132,24 @@ open(my $fh, "<", localDir() . 'echo.sh');
|
||||
my $perm = (stat $fh)[2] & 07777;
|
||||
assert( $perm eq 0751, "permissions not kept" );
|
||||
|
||||
printInfo("Remove a directory and make it a symlink instead\n");
|
||||
system( "rm -rf " . localDir() . 'anotherdir' );
|
||||
system( "ln -s /bin " . localDir() . 'anotherdir' );
|
||||
# remember the fileid of the file on the server
|
||||
my $oldfileid1 = remoteFileId( 'anotherdir/', 'file1.txt' );
|
||||
my $oldfileid2 = remoteFileId( 'anotherdir/sub', 'file2.txt' );
|
||||
csync();
|
||||
|
||||
#check that the files in ignored directory has NOT been removed
|
||||
my $newfileid1 = remoteFileId( 'anotherdir/', 'file1.txt' );
|
||||
my $newfileid2 = remoteFileId( 'anotherdir/sub', 'file2.txt' );
|
||||
assert( $oldfileid1 eq $newfileid1, "File removed (file1.txt)" );
|
||||
assert( $oldfileid2 eq $newfileid2, "File removed (file2.txt)" );
|
||||
|
||||
printInfo("Now remove the symlink\n");
|
||||
system( "rm -f " . localDir() . 'anotherdir' );
|
||||
csync();
|
||||
assertLocalAndRemoteDir( '', 0 );
|
||||
|
||||
cleanup();
|
||||
|
||||
|
||||
69
csync/tests/ownCloud/t5.pl
Executable file
69
csync/tests/ownCloud/t5.pl
Executable file
@@ -0,0 +1,69 @@
|
||||
#!/usr/bin/perl
|
||||
#
|
||||
# Test script for the ownCloud module of csync.
|
||||
# This script requires a running ownCloud instance accessible via HTTP.
|
||||
# It does quite some fancy tests and asserts the results.
|
||||
#
|
||||
# Copyright (C) by Klaas Freitag <freitag@owncloud.com>
|
||||
#
|
||||
# This library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public
|
||||
# License as published by the Free Software Foundation; either
|
||||
# version 2.1 of the License, or (at your option) any later version.
|
||||
#
|
||||
# This library is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public
|
||||
# License along with this library; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
#
|
||||
|
||||
use lib ".";
|
||||
|
||||
use Carp::Assert;
|
||||
use File::Copy;
|
||||
use ownCloud::Test;
|
||||
|
||||
use strict;
|
||||
|
||||
print "Hello, this is t5, a tester for syncing of files in Shares\n";
|
||||
# stat error occours on windsows when the file is busy for example
|
||||
|
||||
initTesting();
|
||||
|
||||
my $share_dir = "share_source";
|
||||
|
||||
printInfo( "Create a share." );
|
||||
my $shareId = createShare( $share_dir, 31 );
|
||||
print "Created share with id <$shareId>\n";
|
||||
|
||||
assert( $shareId > 0 );
|
||||
|
||||
my $sharee = { user => configValue('share_user'),
|
||||
passwd => configValue('share_passwd'),
|
||||
url => server() };
|
||||
# put a couple of files into the shared directory in the sharer account
|
||||
glob_put( 'sharing/*', $share_dir, $sharee);
|
||||
|
||||
# now user kf has a new directory in shared.
|
||||
|
||||
# call csync, sync local t1 to remote t1
|
||||
printInfo("Initial sync, sync stuff down.");
|
||||
csync( server()."Shared" );
|
||||
assertLocalAndRemoteDir( 'Shared', 0, server() );
|
||||
|
||||
# Local file to a read/write share should be synced up
|
||||
printInfo("Put a file into the share.");
|
||||
createLocalFile( localDir(). $share_dir . "/foobar.txt", 8094 );
|
||||
csync( server()."Shared" );
|
||||
assertLocalAndRemoteDir( 'Shared', 0, server() );
|
||||
|
||||
|
||||
printInfo("Remove a Share.");
|
||||
removeShare($shareId, $share_dir);
|
||||
cleanup();
|
||||
|
||||
# --
|
||||
94
csync/tests/ownCloud/t6.pl
Executable file
94
csync/tests/ownCloud/t6.pl
Executable file
@@ -0,0 +1,94 @@
|
||||
#!/usr/bin/perl
|
||||
#
|
||||
# Test script for the ownCloud module of csync.
|
||||
# This script requires a running ownCloud instance accessible via HTTP.
|
||||
# It does quite some fancy tests and asserts the results.
|
||||
#
|
||||
# Copyright (C) by Klaas Freitag <freitag@owncloud.com>
|
||||
#
|
||||
# This library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public
|
||||
# License as published by the Free Software Foundation; either
|
||||
# version 2.1 of the License, or (at your option) any later version.
|
||||
#
|
||||
# This library is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public
|
||||
# License along with this library; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
#
|
||||
|
||||
use lib ".";
|
||||
|
||||
use Carp::Assert;
|
||||
use File::Copy;
|
||||
use ownCloud::Test;
|
||||
|
||||
use strict;
|
||||
|
||||
print "Hello, this is t6, a tester for csync with ownCloud.\n";
|
||||
|
||||
initTesting();
|
||||
|
||||
sub chunkFileTest( $$ )
|
||||
{
|
||||
my ($name, $size) = @_;
|
||||
|
||||
# Big file chunking
|
||||
createLocalFile( localDir().$name, $size );
|
||||
assert( -e localDir().$name );
|
||||
|
||||
my $bigMd5 = md5OfFile( localDir().$name );
|
||||
|
||||
csync();
|
||||
my $newMd5 = md5OfFile( localDir().$name );
|
||||
assert( $newMd5 eq $bigMd5, "Different MD5 sums!" );
|
||||
|
||||
# download
|
||||
my $ctrlFile = "/tmp/file.download";
|
||||
getToFileCurl( $name, $ctrlFile );
|
||||
|
||||
assert( -e $ctrlFile, "File does not exist!" );
|
||||
|
||||
# assert files
|
||||
my $dlMd5 = md5OfFile( $ctrlFile );
|
||||
assert( $dlMd5 eq $newMd5, "Different MD5 sums 2" );
|
||||
|
||||
unlink( $ctrlFile );
|
||||
}
|
||||
|
||||
printInfo("Big file that needs chunking with default chunk size");
|
||||
chunkFileTest( "BIG.file", 23251233 );
|
||||
|
||||
# Set a custom chunk size in environment.
|
||||
my $ChunkSize = 1*1024*1024;
|
||||
$ENV{'OWNCLOUD_CHUNK_SIZE'} = $ChunkSize;
|
||||
|
||||
printInfo("Big file exactly as big as one chunk size");
|
||||
chunkFileTest( "oneChunkSize.bin", $ChunkSize);
|
||||
|
||||
printInfo("Big file exactly as big as one chunk size minus 1 byte");
|
||||
chunkFileTest( "oneChunkSizeminusone.bin", $ChunkSize-1);
|
||||
|
||||
printInfo("Big file exactly as big as one chunk size plus 1 byte");
|
||||
chunkFileTest( "oneChunkSizeplusone.bin", $ChunkSize+1);
|
||||
|
||||
printInfo("Big file exactly as big as 2*chunk size");
|
||||
chunkFileTest( "twoChunkSize.bin", 2*$ChunkSize);
|
||||
|
||||
printInfo("Big file exactly as big as 2*chunk size minus 1 byte");
|
||||
chunkFileTest( "twoChunkSizeminusone.bin", 2*$ChunkSize-1);
|
||||
|
||||
printInfo("Big file exactly as big as 2*chunk size plus 1 byte");
|
||||
chunkFileTest( "twoChunkSizeplusone.bin", 2*$ChunkSize+1);
|
||||
|
||||
|
||||
# ==================================================================
|
||||
|
||||
cleanup();
|
||||
|
||||
|
||||
# --
|
||||
1
csync/tests/ownCloud/toremote1/My Document.doc
Normal file
1
csync/tests/ownCloud/toremote1/My Document.doc
Normal file
@@ -0,0 +1 @@
|
||||
A nice document.
|
||||
16
csync/tests/ownCloud/toremote1/kernelcrash.txt
Normal file
16
csync/tests/ownCloud/toremote1/kernelcrash.txt
Normal file
@@ -0,0 +1,16 @@
|
||||
freitag@zora:~>
|
||||
Message from syslogd@zora at Sep 20 21:35:41 ...
|
||||
kernel:[ 6702.458047] general protection fault: 0000 [#1] PREEMPT SMP
|
||||
|
||||
Message from syslogd@zora at Sep 20 21:35:41 ...
|
||||
kernel:[ 6702.458060] last sysfs file: /sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:03/ATK0110:00/hwmon/hwmon0/temp1_label
|
||||
|
||||
Message from syslogd@zora at Sep 20 21:35:41 ...
|
||||
kernel:[ 6702.458232] Stack:
|
||||
|
||||
Message from syslogd@zora at Sep 20 21:35:41 ...
|
||||
kernel:[ 6702.458262] Call Trace:
|
||||
|
||||
Message from syslogd@zora at Sep 20 21:35:41 ...
|
||||
kernel:[ 6702.458375] Code: 00 00 80 00 00 00 48 b9 00 00 00 00 80 ff ff ff 4e 8d 34 30 49 21 ce 48 8b 4c 24 38 49 8d 56 ff 48 3b 54 24 48 4c 0f 43 74 24 40 <48> 8b 11 48 85 d2 0f 84 d4 01 00 00 48 b9 fb 0f 00 00 00 c0 ff
|
||||
|
||||
BIN
csync/tests/ownCloud/toremote1/kraft_logo.gif
Normal file
BIN
csync/tests/ownCloud/toremote1/kraft_logo.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 6.9 KiB |
@@ -1 +0,0 @@
|
||||
some content.
|
||||
@@ -103,84 +103,10 @@ static void teardown(void **state) {
|
||||
* Test directory function
|
||||
*/
|
||||
|
||||
static void check_csync_vio_mkdir(void **state)
|
||||
{
|
||||
CSYNC *csync = *state;
|
||||
csync_stat_t sb;
|
||||
int rc;
|
||||
mbchar_t *dir = c_utf8_to_locale(CSYNC_TEST_DIR);
|
||||
|
||||
rc = csync_vio_mkdir(csync, CSYNC_TEST_DIR, MKDIR_MASK);
|
||||
assert_int_equal(rc, 0);
|
||||
|
||||
rc = _tstat(dir, &sb);
|
||||
assert_int_equal(rc, 0);
|
||||
|
||||
_trmdir(dir);
|
||||
c_free_locale_string(dir);
|
||||
}
|
||||
|
||||
static void check_csync_vio_mkdirs(void **state)
|
||||
{
|
||||
CSYNC *csync = *state;
|
||||
csync_stat_t sb;
|
||||
int rc;
|
||||
mbchar_t *dir = c_utf8_to_locale(CSYNC_TEST_DIR);
|
||||
|
||||
rc = csync_vio_mkdirs(csync, CSYNC_TEST_DIRS, MKDIR_MASK);
|
||||
assert_int_equal(rc, 0);
|
||||
|
||||
rc = _tstat(dir, &sb);
|
||||
assert_int_equal(rc, 0);
|
||||
|
||||
_trmdir(dir);
|
||||
c_free_locale_string(dir);
|
||||
}
|
||||
|
||||
static void check_csync_vio_mkdirs_some_exist(void **state)
|
||||
{
|
||||
CSYNC *csync = *state;
|
||||
csync_stat_t sb;
|
||||
mbchar_t *this_dir = c_utf8_to_locale("/tmp/csync_test/this");
|
||||
mbchar_t *stat_dir = c_utf8_to_locale(CSYNC_TEST_DIRS);
|
||||
int rc;
|
||||
|
||||
rc = _tmkdir(this_dir, MKDIR_MASK);
|
||||
assert_int_equal(rc, 0);
|
||||
rc = csync_vio_mkdirs(csync, CSYNC_TEST_DIRS, MKDIR_MASK);
|
||||
assert_int_equal(rc, 0);
|
||||
|
||||
rc = _tstat(stat_dir, &sb);
|
||||
assert_int_equal(rc, 0);
|
||||
|
||||
_trmdir(stat_dir);
|
||||
c_free_locale_string(this_dir);
|
||||
c_free_locale_string(stat_dir);
|
||||
}
|
||||
|
||||
static void check_csync_vio_rmdir(void **state)
|
||||
{
|
||||
CSYNC *csync = *state;
|
||||
csync_stat_t sb;
|
||||
int rc;
|
||||
|
||||
rc = csync_vio_mkdir(csync, CSYNC_TEST_DIR, MKDIR_MASK);
|
||||
assert_int_equal(rc, 0);
|
||||
|
||||
rc = lstat(CSYNC_TEST_DIR, &sb);
|
||||
assert_int_equal(rc, 0);
|
||||
|
||||
rc = csync_vio_rmdir(csync, CSYNC_TEST_DIR);
|
||||
assert_int_equal(rc, 0);
|
||||
|
||||
rc = lstat(CSYNC_TEST_DIR, &sb);
|
||||
assert_int_equal(rc, -1);
|
||||
}
|
||||
|
||||
static void check_csync_vio_opendir(void **state)
|
||||
{
|
||||
CSYNC *csync = *state;
|
||||
csync_vio_method_handle_t *dh;
|
||||
csync_vio_handle_t *dh;
|
||||
int rc;
|
||||
|
||||
dh = csync_vio_opendir(csync, CSYNC_TEST_DIR);
|
||||
@@ -193,7 +119,7 @@ static void check_csync_vio_opendir(void **state)
|
||||
static void check_csync_vio_opendir_perm(void **state)
|
||||
{
|
||||
CSYNC *csync = *state;
|
||||
csync_vio_method_handle_t *dh;
|
||||
csync_vio_handle_t *dh;
|
||||
int rc;
|
||||
mbchar_t *dir = c_utf8_to_locale(CSYNC_TEST_DIR);
|
||||
|
||||
@@ -222,7 +148,7 @@ static void check_csync_vio_closedir_null(void **state)
|
||||
static void check_csync_vio_readdir(void **state)
|
||||
{
|
||||
CSYNC *csync = *state;
|
||||
csync_vio_method_handle_t *dh;
|
||||
csync_vio_handle_t *dh;
|
||||
csync_vio_file_stat_t *dirent;
|
||||
int rc;
|
||||
|
||||
@@ -237,153 +163,6 @@ static void check_csync_vio_readdir(void **state)
|
||||
assert_int_equal(rc, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Test file functions (open, read, write, close ...)
|
||||
*/
|
||||
|
||||
static void check_csync_vio_close_null(void **state)
|
||||
{
|
||||
CSYNC *csync = *state;
|
||||
int rc;
|
||||
|
||||
rc = csync_vio_close(csync, NULL);
|
||||
assert_int_equal(rc, -1);
|
||||
}
|
||||
|
||||
static void check_csync_vio_creat_close(void **state)
|
||||
{
|
||||
CSYNC *csync = *state;
|
||||
csync_vio_method_handle_t *fh;
|
||||
int rc;
|
||||
|
||||
fh = csync_vio_creat(csync, CSYNC_TEST_FILE, 0644);
|
||||
assert_non_null(fh);
|
||||
|
||||
rc = csync_vio_close(csync, fh);
|
||||
assert_int_equal(rc, 0);
|
||||
}
|
||||
|
||||
static void check_csync_vio_open_close(void **state)
|
||||
{
|
||||
CSYNC *csync = *state;
|
||||
csync_vio_method_handle_t *fh;
|
||||
int rc;
|
||||
|
||||
fh = csync_vio_open(csync, CSYNC_TEST_FILE, O_RDONLY, 0644);
|
||||
assert_non_null(fh);
|
||||
|
||||
rc = csync_vio_close(csync, fh);
|
||||
assert_int_equal(rc, 0);
|
||||
}
|
||||
|
||||
static void check_csync_vio_read_null(void **state)
|
||||
{
|
||||
CSYNC *csync = *state;
|
||||
char test[16] = {0};
|
||||
int rc;
|
||||
|
||||
rc = csync_vio_read(csync, NULL, test, 10);
|
||||
assert_int_equal(rc, -1);
|
||||
}
|
||||
|
||||
static void check_csync_vio_read(void **state)
|
||||
{
|
||||
CSYNC *csync = *state;
|
||||
csync_vio_method_handle_t *fh;
|
||||
char test[16] = {0};
|
||||
int rc;
|
||||
|
||||
fh = csync_vio_open(csync, CSYNC_TEST_FILE, O_RDONLY, 0644);
|
||||
assert_non_null(fh);
|
||||
|
||||
rc = csync_vio_read(csync, fh, test, 14);
|
||||
assert_int_equal(rc, 14);
|
||||
|
||||
assert_string_equal(test, "This is a test");
|
||||
|
||||
rc = csync_vio_close(csync, fh);
|
||||
assert_int_equal(rc, 0);
|
||||
}
|
||||
|
||||
static void check_csync_vio_read_0(void **state)
|
||||
{
|
||||
CSYNC *csync = *state;
|
||||
csync_vio_method_handle_t *fh = NULL;
|
||||
char test[16] = {0};
|
||||
int rc;
|
||||
|
||||
fh = csync_vio_open(csync, CSYNC_TEST_FILE, O_RDONLY, 0644);
|
||||
assert_non_null(fh);
|
||||
|
||||
rc = csync_vio_read(csync, fh, test, 0);
|
||||
assert_int_equal(rc, 0);
|
||||
|
||||
assert_true(test[0] == '\0');
|
||||
|
||||
rc = csync_vio_close(csync, fh);
|
||||
assert_int_equal(rc, 0);
|
||||
}
|
||||
|
||||
static void check_csync_vio_write_null(void **state)
|
||||
{
|
||||
CSYNC *csync = *state;
|
||||
char test[16] = {0};
|
||||
int rc;
|
||||
|
||||
rc = csync_vio_write(csync, NULL, test, 10);
|
||||
assert_int_equal(rc, -1);
|
||||
}
|
||||
|
||||
static void check_csync_vio_write(void **state)
|
||||
{
|
||||
CSYNC *csync = *state;
|
||||
csync_vio_method_handle_t *fh;
|
||||
char str[] = "This is a test";
|
||||
char test[16] = {0};
|
||||
int rc;
|
||||
|
||||
fh = csync_vio_creat(csync, CSYNC_TEST_FILE, 0644);
|
||||
assert_non_null(fh);
|
||||
|
||||
rc = csync_vio_write(csync, fh, str, sizeof(str));
|
||||
assert_int_equal(rc, sizeof(str));
|
||||
|
||||
rc = csync_vio_close(csync, fh);
|
||||
assert_int_equal(rc, 0);
|
||||
|
||||
fh = csync_vio_open(csync, CSYNC_TEST_FILE, O_RDONLY, 0644);
|
||||
assert_non_null(fh);
|
||||
|
||||
rc = csync_vio_read(csync, fh, test, 14);
|
||||
assert_int_equal(rc, 14);
|
||||
|
||||
assert_string_equal(test, "This is a test");
|
||||
|
||||
rc = csync_vio_close(csync, fh);
|
||||
assert_int_equal(rc, 0);
|
||||
}
|
||||
|
||||
static void check_csync_vio_lseek(void **state)
|
||||
{
|
||||
CSYNC *csync = *state;
|
||||
csync_vio_method_handle_t *fh;
|
||||
char test[16] = {0};
|
||||
int rc;
|
||||
|
||||
fh = csync_vio_open(csync, CSYNC_TEST_FILE, O_RDONLY, 0644);
|
||||
assert_non_null(fh);
|
||||
|
||||
rc = csync_vio_lseek(csync, fh, 10, SEEK_SET);
|
||||
assert_int_equal(rc, 10);
|
||||
|
||||
rc = csync_vio_read(csync, fh, test, 4);
|
||||
assert_int_equal(rc, 4);
|
||||
|
||||
assert_string_equal(test, "test");
|
||||
|
||||
rc = csync_vio_close(csync, fh);
|
||||
assert_int_equal(rc, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Test for general functions (stat, chmod, chown, ...)
|
||||
@@ -425,148 +204,16 @@ static void check_csync_vio_stat_file(void **state)
|
||||
csync_vio_file_stat_destroy(fs);
|
||||
}
|
||||
|
||||
static void check_csync_vio_rename_dir(void **state)
|
||||
{
|
||||
CSYNC *csync = *state;
|
||||
csync_stat_t sb;
|
||||
int rc;
|
||||
|
||||
mbchar_t *dir = c_utf8_to_locale("test");
|
||||
mbchar_t *dir2 = c_utf8_to_locale("test2");
|
||||
|
||||
assert_non_null(dir);
|
||||
assert_non_null(dir2);
|
||||
|
||||
rc = _tmkdir(dir, MKDIR_MASK);
|
||||
assert_int_equal(rc, 0);
|
||||
|
||||
rc = csync_vio_rename(csync, "test", "test2");
|
||||
assert_int_equal(rc, 0);
|
||||
|
||||
|
||||
rc = _tstat(dir2, &sb);
|
||||
assert_int_equal(rc, 0);
|
||||
|
||||
c_free_locale_string(dir);
|
||||
c_free_locale_string(dir2);
|
||||
}
|
||||
|
||||
static void check_csync_vio_rename_file(void **state)
|
||||
{
|
||||
CSYNC *csync = *state;
|
||||
mbchar_t *file = c_utf8_to_locale(CSYNC_TEST_DIR "file2.txt");
|
||||
csync_stat_t sb;
|
||||
int rc;
|
||||
|
||||
rc = csync_vio_rename(csync, CSYNC_TEST_FILE, CSYNC_TEST_DIR "file2.txt");
|
||||
assert_int_equal(rc, 0);
|
||||
|
||||
rc = _tstat(file, &sb);
|
||||
assert_int_equal(rc, 0);
|
||||
|
||||
c_free_locale_string(file);
|
||||
}
|
||||
|
||||
static void check_csync_vio_unlink(void **state)
|
||||
{
|
||||
CSYNC *csync = *state;
|
||||
csync_stat_t sb;
|
||||
mbchar_t *file = c_utf8_to_locale(CSYNC_TEST_FILE);
|
||||
int rc;
|
||||
|
||||
rc = csync_vio_unlink(csync, CSYNC_TEST_FILE);
|
||||
assert_int_equal(rc, 0);
|
||||
|
||||
rc = _tstat(file, &sb);
|
||||
assert_int_equal(rc, -1);
|
||||
|
||||
c_free_locale_string(file);
|
||||
}
|
||||
|
||||
static void check_csync_vio_chmod(void **state)
|
||||
{
|
||||
CSYNC *csync = *state;
|
||||
int rc;
|
||||
|
||||
rc = csync_vio_chmod(csync, CSYNC_TEST_FILE, 0777);
|
||||
assert_int_equal(rc, 0);
|
||||
}
|
||||
|
||||
#ifndef _WIN32
|
||||
static void check_csync_vio_chown(void **state)
|
||||
{
|
||||
CSYNC *csync = *state;
|
||||
int rc;
|
||||
|
||||
rc = csync_vio_chown(csync, CSYNC_TEST_FILE, getuid(), getgid());
|
||||
assert_int_equal(rc, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void check_csync_vio_utimes(void **state)
|
||||
{
|
||||
CSYNC *csync = *state;
|
||||
csync_stat_t sb;
|
||||
struct timeval times[2];
|
||||
long modtime = 0;
|
||||
mbchar_t *file = c_utf8_to_locale(CSYNC_TEST_FILE);
|
||||
int rc;
|
||||
|
||||
rc = _tstat(file, &sb);
|
||||
assert_int_equal(rc, 0);
|
||||
modtime = sb.st_mtime + 10;
|
||||
|
||||
times[0].tv_sec = modtime;
|
||||
times[0].tv_usec = 0;
|
||||
|
||||
times[1].tv_sec = modtime;
|
||||
times[1].tv_usec = 0;
|
||||
|
||||
rc = csync_vio_utimes(csync, CSYNC_TEST_FILE, times);
|
||||
assert_int_equal(rc, 0);
|
||||
|
||||
rc = _tstat(file, &sb);
|
||||
assert_int_equal(rc, 0);
|
||||
|
||||
assert_int_equal(modtime, sb.st_mtime);
|
||||
|
||||
c_free_locale_string(file);
|
||||
}
|
||||
|
||||
int torture_run_tests(void)
|
||||
{
|
||||
const UnitTest tests[] = {
|
||||
|
||||
unit_test_setup_teardown(check_csync_vio_mkdir, setup, teardown),
|
||||
unit_test_setup_teardown(check_csync_vio_mkdirs, setup, teardown),
|
||||
unit_test_setup_teardown(check_csync_vio_mkdirs_some_exist, setup_dir, teardown),
|
||||
unit_test_setup_teardown(check_csync_vio_rmdir, setup, teardown),
|
||||
unit_test_setup_teardown(check_csync_vio_opendir, setup_dir, teardown),
|
||||
unit_test_setup_teardown(check_csync_vio_opendir_perm, setup, teardown),
|
||||
unit_test(check_csync_vio_closedir_null),
|
||||
unit_test_setup_teardown(check_csync_vio_readdir, setup_dir, teardown),
|
||||
|
||||
unit_test_setup_teardown(check_csync_vio_close_null, setup_dir, teardown),
|
||||
unit_test_setup_teardown(check_csync_vio_creat_close, setup_dir, teardown),
|
||||
unit_test_setup_teardown(check_csync_vio_open_close, setup_file, teardown),
|
||||
unit_test(check_csync_vio_read_null),
|
||||
unit_test_setup_teardown(check_csync_vio_read, setup_file, teardown),
|
||||
unit_test_setup_teardown(check_csync_vio_read_0, setup_file, teardown),
|
||||
unit_test(check_csync_vio_write_null),
|
||||
unit_test_setup_teardown(check_csync_vio_write, setup_dir, teardown),
|
||||
unit_test_setup_teardown(check_csync_vio_lseek, setup_file, teardown),
|
||||
|
||||
unit_test_setup_teardown(check_csync_vio_stat_dir, setup_dir, teardown),
|
||||
unit_test_setup_teardown(check_csync_vio_stat_file, setup_file, teardown),
|
||||
|
||||
unit_test_setup_teardown(check_csync_vio_rename_dir, setup_dir, teardown),
|
||||
unit_test_setup_teardown(check_csync_vio_rename_file, setup_file, teardown),
|
||||
unit_test_setup_teardown(check_csync_vio_unlink, setup_file, teardown),
|
||||
unit_test_setup_teardown(check_csync_vio_chmod, setup_file, teardown),
|
||||
#ifndef _WIN32
|
||||
unit_test_setup_teardown(check_csync_vio_chown, setup_file, teardown),
|
||||
#endif
|
||||
unit_test_setup_teardown(check_csync_vio_utimes, setup_file, teardown),
|
||||
};
|
||||
|
||||
return run_tests(tests);
|
||||
|
||||
@@ -1,74 +0,0 @@
|
||||
/*
|
||||
* libcsync -- a library to sync a directory with another
|
||||
*
|
||||
* Copyright (c) 2008-2013 by Andreas Schneider <asn@cryptomilk.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "torture.h"
|
||||
|
||||
#include "vio/csync_vio_handle.h"
|
||||
#include "vio/csync_vio_handle_private.h"
|
||||
|
||||
static void check_csync_vio_handle_new(void **state)
|
||||
{
|
||||
int *number;
|
||||
csync_vio_handle_t *handle;
|
||||
|
||||
(void) state; /* unused */
|
||||
|
||||
number = malloc(sizeof(int));
|
||||
*number = 42;
|
||||
|
||||
handle = csync_vio_handle_new("/tmp", (csync_vio_method_handle_t *) number);
|
||||
assert_non_null(handle);
|
||||
assert_string_equal(handle->uri, "/tmp");
|
||||
|
||||
free(handle->method_handle);
|
||||
|
||||
csync_vio_handle_destroy(handle);
|
||||
}
|
||||
|
||||
static void check_csync_vio_handle_new_null(void **state)
|
||||
{
|
||||
int *number;
|
||||
csync_vio_handle_t *handle;
|
||||
|
||||
(void) state; /* unused */
|
||||
|
||||
number = malloc(sizeof(int));
|
||||
*number = 42;
|
||||
|
||||
handle = csync_vio_handle_new(NULL, (csync_vio_method_handle_t *) number);
|
||||
assert_null(handle);
|
||||
|
||||
handle = csync_vio_handle_new((char *) "/tmp", NULL);
|
||||
assert_null(handle);
|
||||
|
||||
free(number);
|
||||
}
|
||||
|
||||
int torture_run_tests(void)
|
||||
{
|
||||
const UnitTest tests[] = {
|
||||
unit_test(check_csync_vio_handle_new),
|
||||
unit_test(check_csync_vio_handle_new_null),
|
||||
};
|
||||
|
||||
return run_tests(tests);
|
||||
}
|
||||
|
||||
@@ -12,12 +12,15 @@ if(SPHINX_FOUND)
|
||||
# assets
|
||||
set(LATEX_LOGO "${CMAKE_CURRENT_SOURCE_DIR}/logo-blue.pdf")
|
||||
|
||||
install(DIRECTORY ${SPHINX_HTML_DIR} DESTINATION ${CMAKE_INSTALL_DOCDIR} OPTIONAL)
|
||||
install(DIRECTORY ${SPHINX_MAN_DIR} DESTINATION ${CMAKE_INSTALL_MANDIR} OPTIONAL)
|
||||
install(DIRECTORY ${SPHINX_PDF_DIR} DESTINATION ${CMAKE_INSTALL_DOCDIR} OPTIONAL)
|
||||
install(DIRECTORY ${SPHINX_QCH_DIR} DESTINATION ${CMAKE_INSTALL_DOCDIR} OPTIONAL)
|
||||
|
||||
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/conf.py.in" conf.py @ONLY)
|
||||
|
||||
if(WITH_DOC)
|
||||
add_custom_target(doc ALL DEPENDS doc-html doc-man COMMENT "Building documentation...")
|
||||
install(DIRECTORY ${SPHINX_HTML_DIR} DESTINATION ${CMAKE_INSTALL_DOCDIR})
|
||||
install(DIRECTORY ${SPHINX_MAN_DIR} DESTINATION ${CMAKE_INSTALL_MANDIR})
|
||||
else(WITH_DOC)
|
||||
add_custom_target(doc DEPENDS doc-html doc-man COMMENT "Building documentation...")
|
||||
endif(WITH_DOC)
|
||||
@@ -39,9 +42,6 @@ if(SPHINX_FOUND)
|
||||
add_custom_target(doc-pdf $(MAKE) -C ${SPHINX_PDF_DIR} all-pdf
|
||||
DEPENDS doc-latex )
|
||||
add_dependencies(doc doc-pdf)
|
||||
if (WITH_DOC)
|
||||
install(DIRECTORY ${SPHINX_PDF_DIR} DESTINATION ${CMAKE_INSTALL_DOCDIR})
|
||||
endif (WITH_DOC)
|
||||
endif(PDFLATEX_FOUND)
|
||||
if (EXISTS ${QT_QCOLLECTIONGENERATOR_EXECUTABLE})
|
||||
add_custom_target( doc-qch-sphinx ${SPHINX_EXECUTABLE}
|
||||
@@ -53,9 +53,6 @@ if(SPHINX_FOUND)
|
||||
${SPHINX_QCH_DIR}/*.qhcp
|
||||
DEPENDS doc-qch-sphinx )
|
||||
add_dependencies(doc doc-qch)
|
||||
if (WITH_DOC)
|
||||
install(DIRECTORY ${SPHINX_QCH_DIR} DESTINATION ${CMAKE_INSTALL_DOCDIR})
|
||||
endif (WITH_DOC)
|
||||
endif()
|
||||
add_custom_target( doc-html ${SPHINX_EXECUTABLE}
|
||||
-q -c . -b html
|
||||
|
||||
@@ -12,3 +12,8 @@ Config File
|
||||
-----------
|
||||
.. index:: config file
|
||||
.. include:: conffile.rst
|
||||
|
||||
ownCloud Commandline Client
|
||||
---------------------------
|
||||
.. index:: owncloudcmd
|
||||
.. include:: owncloudcmd.rst
|
||||
|
||||
@@ -41,11 +41,10 @@ its own repository which contains non-standard recipes. Add it with::
|
||||
|
||||
Next, install the missing dependencies::
|
||||
|
||||
brew install $(brew deps ocsync)
|
||||
brew install $(brew deps mirall)
|
||||
|
||||
|
||||
To build mirall and csync, follow the `generic build instructions`_.
|
||||
To build mirall, follow the `generic build instructions`_.
|
||||
|
||||
.. note::
|
||||
You should not call ``make install`` at any time, since the product of the
|
||||
@@ -55,23 +54,23 @@ To build mirall and csync, follow the `generic build instructions`_.
|
||||
Windows (cross-compile)
|
||||
-----------------------
|
||||
|
||||
Due to the amount of dependencies that csync entails, building the client
|
||||
for Windows is **currently only supported on openSUSE**, by using the MinGW
|
||||
Due to the amount of dependencies, building the client for Windows
|
||||
is **currently only supported on openSUSE**, by using the MinGW
|
||||
cross compiler. You can set up openSUSE 12.1, 12.2 or 13.1 in a virtual machine
|
||||
if you do not have it installed already.
|
||||
|
||||
In order to cross-compile, the following repositories need to be added
|
||||
via YaST or ``zypper ar`` (adjust when using openSUSE 12.2 or 13.1)::
|
||||
|
||||
zypper ar http://download.opensuse.org/repositories/windows:/mingw:/win32/openSUSE_12.1/windows:mingw:win32.repo
|
||||
zypper ar http://download.opensuse.org/repositories/windows:/mingw/openSUSE_12.1/windows:mingw.repo
|
||||
zypper ar http://download.opensuse.org/repositories/windows:/mingw:/win32/openSUSE_13.1/windows:mingw:win32.repo
|
||||
zypper ar http://download.opensuse.org/repositories/windows:/mingw/openSUSE_13.1/windows:mingw.repo
|
||||
|
||||
Next, install the cross-compiler packages and the cross-compiled dependencies::
|
||||
|
||||
zypper install cmake make mingw32-cross-binutils mingw32-cross-cpp mingw32-cross-gcc \
|
||||
mingw32-cross-gcc-c++ mingw32-cross-pkg-config mingw32-filesystem \
|
||||
mingw32-headers mingw32-runtime site-config mingw32-libqt4-sql \
|
||||
mingw32-libqt4-sql-sqlite mingw32-libsqlite-devel \
|
||||
mingw32-libqt4-sql-sqlite mingw32-sqlite mingw32-libsqlite-devel \
|
||||
mingw32-dlfcn-devel mingw32-libssh2-devel kdewin-png2ico \
|
||||
mingw32-libqt4 mingw32-libqt4-devel mingw32-libgcrypt \
|
||||
mingw32-libgnutls mingw32-libneon-openssl mingw32-libneon-devel \
|
||||
@@ -99,12 +98,9 @@ You will also need to manually download and install the following files with
|
||||
Now, follow the `generic build instructions`_, but pay attention to
|
||||
the following differences:
|
||||
|
||||
1. For building ``libocsync``, you need to use ``mingw32-cmake`` instead
|
||||
of cmake.
|
||||
2. for building ``mirall``, you need to use ``cmake`` again, but make sure
|
||||
to append the following parameter::
|
||||
3. Also, you need to specify *absolute pathes* for ``CSYNC_LIBRARY_PATH``
|
||||
and ``CSYNC_LIBRARY_PATH`` when running ``cmake`` on mirall.
|
||||
For building for windows a special toolchain file has to be specified.
|
||||
That makes cmake finding the platform specific tools. This parameter
|
||||
has to be added to the call to cmake:
|
||||
|
||||
``-DCMAKE_TOOLCHAIN_FILE=../mirall/admin/win/Toolchain-mingw32-openSUSE.cmake``
|
||||
|
||||
@@ -115,50 +111,25 @@ Generic Build Instructions
|
||||
--------------------------
|
||||
.. _`generic build instructions`
|
||||
|
||||
The ownCloud Client requires Mirall and CSync_. Mirall is the GUI frontend,
|
||||
while CSync is responsible for handling the actual synchronization process.
|
||||
Compared to previous versions building of Mirall has become more easy.
|
||||
CSync, which is the sync engine library of Mirall, is now part of the
|
||||
Mirall source repository, not, like it was before, a separate module.
|
||||
|
||||
At the moment, ownCloud Client requires a forked version of CSync. Both
|
||||
CMake and Mirall can be downloaded at ownCloud's `Client Download Page`_.
|
||||
Mirall can be downloaded at ownCloud's `Client Download Page`_.
|
||||
|
||||
If you want to build the leading edge version of the client, you should
|
||||
use the latest versions of Mirall and CSync via Git_, like so::
|
||||
use the latest versions of Mirall via Git_, like so::
|
||||
|
||||
git clone git://git.csync.org/users/owncloud/csync.git ocsync
|
||||
git clone git://github.com/owncloud/mirall.git
|
||||
|
||||
Next, create build directories::
|
||||
|
||||
mkdir ocsync-build
|
||||
mkdir mirall-build
|
||||
|
||||
This guide assumes that all directories are residing next to each other.
|
||||
Next, make sure to check out the branch called 'ocsync' in the newly checked out
|
||||
`ocsync` directory::
|
||||
|
||||
cd ocsync
|
||||
git checkout ocsync
|
||||
|
||||
The first package to build is CSync::
|
||||
|
||||
cd ocsync-build
|
||||
cmake -DCMAKE_BUILD_TYPE="Debug" ../ocsync
|
||||
make
|
||||
|
||||
You probably have to satisfy some dependencies. Make sure to install all the
|
||||
needed development packages. You will need ``sqlite3`` as well as ``neon`` for
|
||||
the ownCloud module. Take special care about ``neon``. If that is missing, the
|
||||
cmake run will succeed but silently not build the ownCloud module.
|
||||
|
||||
``libssh`` and ``libsmbclient`` are optional and not required for the client
|
||||
to work. If you want to install the client, run ``make install`` as a final step.
|
||||
|
||||
Next, we build mirall::
|
||||
Now build mirall::
|
||||
|
||||
cd ../mirall-build
|
||||
cmake -DCMAKE_BUILD_TYPE="Debug" ../mirall \
|
||||
-DCSYNC_BUILD_PATH=/path/to/ocsync-build \
|
||||
-DCSYNC_INCLUDE_PATH=/path/to/ocsync/src
|
||||
cmake -DCMAKE_BUILD_TYPE="Debug" ../mirall
|
||||
|
||||
Note that it is important to use absolute pathes for the include- and library
|
||||
directories. If this succeeds, call ``make``. The owncloud binary should appear
|
||||
@@ -171,9 +142,10 @@ To build an installer/app bundle (requires the mingw32-cross-nsis packages on Wi
|
||||
|
||||
Known cmake parameters:
|
||||
|
||||
* QTKEYCHAIN_LIBRARY=/path/to/qtkeychain.dylib -DQTKEYCHAIN_INCLUDE_DIR=/path/to/qtkeychain/: Use QtKeychain for stored credentials. When compiling with Qt5, the library is called qt5keychain.dylib. You need to compile QtKeychain with the same Qt version.
|
||||
* WITH_DOC=TRUE: create doc and manpages via running ``make``; also adds install statements to be able to install it via ``make install``.
|
||||
* BUILD_WITH_QT4=OFF and CMAKE_PREFIX_PATH=/path/to/Qt5.2.0/5.2.0/yourarch/lib/cmake/ : Build with Qt5 instead of Qt4
|
||||
* QTKEYCHAIN_LIBRARY=/path/to/qtkeychain.dylib : Use QtKeychain for stored credentials
|
||||
* CMAKE_PREFIX_PATH=/path/to/Qt5.2.0/5.2.0/yourarch/lib/cmake/ : to build with Qt5
|
||||
* BUILD_WITH_QT4=ON : to build with Qt4 even if Qt5 is found
|
||||
|
||||
.. _`ownCloud repository from OBS`: http://software.opensuse.org/download/package?project=isv:ownCloud:devel&package=owncloud-client
|
||||
.. _CSync: http://www.csync.org
|
||||
@@ -181,3 +153,4 @@ Known cmake parameters:
|
||||
.. _Git: http://git-scm.com
|
||||
.. _MacPorts: http://www.macports.org
|
||||
.. _Homebrew: http://mxcl.github.com/homebrew/
|
||||
.. _QtKeychain https://github.com/frankosterfeld/qtkeychain
|
||||
|
||||
16
doc/faq.rst
Normal file
16
doc/faq.rst
Normal file
@@ -0,0 +1,16 @@
|
||||
FAQ
|
||||
===
|
||||
|
||||
Some files are continuously uploaded to the server even when they are not modified
|
||||
----------------------------------------------------------------------------------
|
||||
|
||||
It is possible that another program is changing the modification date of the file.
|
||||
|
||||
If the file is a ``.eml`` file, Windows automatically change all file all the time unless you remove
|
||||
``\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\PropertySystem\PropertyHandlers`` from
|
||||
the windows registry.
|
||||
See http://petersteier.wordpress.com/2011/10/22/windows-indexer-changes-modification-dates-of-eml-files/
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -15,5 +15,6 @@ Contents
|
||||
building
|
||||
architecture
|
||||
troubleshooting
|
||||
faq
|
||||
glossary
|
||||
|
||||
|
||||
@@ -19,11 +19,43 @@ used for the same purpose in earlier releases.
|
||||
A sync run will sync a single local directory with a WebDAV share on a
|
||||
remote ownCloud server.
|
||||
|
||||
To invoke the command line client, provide the local and the remote repository:
|
||||
The first parameter is the local directory. The second parameter is
|
||||
the server URL.
|
||||
|
||||
.. note:: Prior to 1.6, the tool only accepted ``owncloud://`` or ``ownclouds://``
|
||||
in place of ``http://`` and ``https://`` as a scheme. See ``Examples``
|
||||
for details.
|
||||
|
||||
OPTIONS
|
||||
=======
|
||||
``--confdir`` `PATH`
|
||||
The configuration dir where `csync.conf` is located
|
||||
|
||||
``--silent``
|
||||
Don't give verbose log output
|
||||
|
||||
``--httpproxy http://[user@pass:]<server>:<port>``
|
||||
Use ``server`` as HTTP proxy
|
||||
|
||||
Example
|
||||
=======
|
||||
To sync the ownCloud directory ``Music`` to the local directory ``media/music``
|
||||
through a proxy listening on port ``8080`` on the gateway machine ``192.168.178.1``,
|
||||
the command line would be::
|
||||
|
||||
$ owncloudcmd --httpproxy http://192.168.178.1:8080 \
|
||||
$HOME/media/music \
|
||||
https://server/owncloud/remote.php/webdav/Music
|
||||
|
||||
|
||||
Using the legacy scheme, it would look like this::
|
||||
|
||||
$ owncloudcmd --httpproxy http://192.168.178.1:8080 \
|
||||
$HOME/media/music \
|
||||
ownclouds://server/owncloud/remote.php/webdav/Music
|
||||
|
||||
|
||||
BUGS
|
||||
====
|
||||
Please report bugs at https://github.com/owncloud/mirall/issues.
|
||||
|
||||
64
doc/owncloudcmd.rst
Normal file
64
doc/owncloudcmd.rst
Normal file
@@ -0,0 +1,64 @@
|
||||
The ownCloud Client packages come with a command line client which
|
||||
can be used to synchronize ownCloud files to client machines. The
|
||||
command line client is called ``owncloudcmd``.
|
||||
|
||||
owncloudcmd performs a single sync run and then exits.
|
||||
That means that it processes the differences between client- and
|
||||
server directory and propagates the files to get both repositories
|
||||
on the same status. Contrary to the GUI based client, it does not
|
||||
repeat syncs on its own. It does also not monitor for file system
|
||||
changes.
|
||||
|
||||
To invoke the command line client, the user has to provide the local
|
||||
and the remote repository urls::
|
||||
|
||||
owncloudcmd [OPTIONS...] sourcedir owncloudurl
|
||||
|
||||
where ``sourcedir`` is the local directory and ``owncloudurl`` is
|
||||
the server url.
|
||||
|
||||
.. note:: Prior to 1.6, the tool only accepted ``owncloud://`` or
|
||||
``ownclouds://`` in place of ``http://`` and ``https://``
|
||||
as a scheme. See ``Examples`` for details.
|
||||
|
||||
These are other comand line switches supported by owncloudcmd:
|
||||
|
||||
``--silent``
|
||||
Don't give verbose log output
|
||||
|
||||
``--confdir`` `PATH`
|
||||
Fetch or store configuration in this custom config directory
|
||||
|
||||
``--httpproxy http://[user@pass:]<server>:<port>``
|
||||
Use ``server`` as HTTP proxy
|
||||
|
||||
Credential Handling
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
By default, owncloudcmd reads the client configuration and uses the credentials
|
||||
of the GUI sync client. If no client was configured or to use a different user
|
||||
to sync, the user password setting can be specified with the usual URL pattern,
|
||||
for example::
|
||||
|
||||
https://user:secret@192.168.178.2/remote.php/webdav
|
||||
|
||||
|
||||
Example
|
||||
~~~~~~~
|
||||
|
||||
To sync the ownCloud directory ``Music`` to the local directory ``media/music``
|
||||
through a proxy listening on port ``8080`` on the gateway machine ``192.168.178.1``,
|
||||
the command line would be::
|
||||
|
||||
$ owncloudcmd --httpproxy http://192.168.178.1:8080 \
|
||||
$HOME/media/music \
|
||||
https://server/owncloud/remote.php/webdav/Music
|
||||
|
||||
|
||||
Using the legacy scheme, it would look like this::
|
||||
|
||||
$ owncloudcmd --httpproxy http://192.168.178.1:8080 \
|
||||
$HOME/media/music \
|
||||
ownclouds://server/owncloud/remote.php/webdav/Music
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user